[
Date Prev][
Date Next][
Thread Prev][
Thread Next][
Date Index][
Thread Index]
[
List Home]
RE: [platform-vcm-dev] Team + Refactoring (cont.)
|
I ran into similar issues recently, while adapting Stellation to
respond to Eclipse resource updates.
A ResourceDelta "represents changes that have occurred between two
states of the resource tree." It is certainly true that rename/move/delete
is not a content operation as far as individual files are concerned, but
rename/move/delete does change the state (and arguably, content) of the
resource tree per se. Maybe the term "delta notification" is a bit
misleading (since it suggests a file content change), but I can't think of a
better term offhand.
The MoveDeleteHook is invoked once for each affected resource.
(Moving 20 files results in 20 MDHook invocations.)
This can be inconvenient, because there's no easy way to know which
MoveDeleteHook invocation is the final one within a single transactional
change (e.g. when moving a set of .java files to a different package).
The ResourceDelta mechanism generates a single event containing all
changes for a particular operation on the resource tree. I found this very
convenient for automatically updating a Stellation branch image to reflect
resource changes: on receiving each ResourceChange event, I use a single
IResourceDeltaVisitor instance to collect and filter all the resource tree
changes, do a consistency check, and then assemble a set of Stellation
change commands. Not surprisingly, it's much faster to update a Stellation
image in batch mode than it was when I processed resource tree changes one
resource at a time.
I agree that the MoveDeleteHook is the right place if you want to
potentially veto a resource tree change, or if some kind of special
file-system-level action is needed (assuming that the regular IResourceTree
operations, e.g. standardMoveFile, standardDeleteFolder, don't do the right
thing for a given provider). However, I don't agree that all
move/rename/delete processing should be handled here; the ResourceDelta
mechanism (whether misnamed or not), is better suited for processing
resource tree changes which are transactional in nature.
That said, David Corbin raised an issue which hasn't really been addressed:
If the decision to veto or allow a given resource content change depends
on some larger context (e.g. whether the change is part of a move operation),
and the necessary context information is not available until *after* the
content
change has occurred, there's a problem.
Since validateEdit is invoked before the MoveDeleteHook is called - the
provider doesn't have the necessary context to make the right decision, in
this case.
Several possible approaches come to mind:
a) do the move first and change the resource contents (package declaration)
only after moving the resource to the target location.
b) Add events to mark the start and end of various transactions. Some
useful event
pairs might include Begin/EndRefactor, Begin/EndMoveDelete.
With approach a), validateEdit would never be called if the move was vetoed,
and the provider could potentially associate the move with the subsequent
edit (perhaps not easily...). With approach b), the transactional nature of
a set of changes is clear ... but the provider might still see validateEdit
before the corresponding MoveDeleteHook invocation, so the problem remains.
Thus, if b) is implemented, a) should also be implemented.
Another approach might be to provide more complete information to
validateEdit -- not 'context', since that's a UIContext for dialog support,
etc., but something like validateEdit(...., int refactoringFlags), where
refactoringFlags specifies whether the content change is related to
refactoring, and if so whether it's a simple package rename, a method
import/export or something else. Of course, this assumes the affected
resource is a Java file -- HTML, XML and C++ source could all have different
sets of valid refactoring flags, if any. That seems complicated/unworkable.
Another possibility: validateEdit( IFile[] files, Object context, IFile[]
targets), where targets[], if non-null, signals that the edit is part of a
move/rename, and gives the target pathname for each member of files[].
The simplest solution seems to be to reverse the order of move and edit
operations, when refactoring. This avoids changing APIs, and decouples
providers from the need to know about refactoring. It would also be useful
to demarcate resource tree and refactoring transactions with Begin/End event
pairs.
Comments?
Best,
Jim
At 04:19 PM 6/21/02 -0400, Clemm, Geoff wrote:
The first part of Kevin's explanation made sense to me,
i.e. ValidateEdit is only for content changes, and therefore
is not called on rename/move/delete, but is called if the
rename/move resulted in a content change, at which time
ValidateEdit should be invoked. (I.e. if ValidateEdit is
being called on rename/move/delete, it should be called
on the folders involved, but not calling it at all on rename/
move/delete is fine).
The second part of the explanation did raise a question ...
the move/rename/delete hook certainly is the right place to
handle move/rename/delete processing. But why is "delta notification"
relevant here, since delta's are about content, and
rename/move/delete are namespace operations, not content
operations?
Cheers,
Geoff
-----Original Message-----
From: Kevin McGuire [mailto:Kevin_McGuire@xxxxxxx]
Sent: Friday, June 21, 2002 3:12 PM
To: platform-vcm-dev@xxxxxxxxxxx
Subject: RE: [platform-vcm-dev] Team + Refactoring (cont.)
No, this isn't a bug:
ValidateEdit() is unrelated to namespace operations. Its only called when
content changes are about to occur. I believe what's happening in the case
cited is that when you rename a Java file, Java refactoring kicks in and
renames the class declaration to match the filename. Thus you are getting
the validateEdit() notification from the Java refactoring engine who is
being a good citizen. The context is null presumably because they don't
have access to the shell at the point in their code where they need to call
validateEdit().
You can't rely on validateEdit() for rename/move/delete -- if you do the
same steps with a non-java file you won't get notified via this. You can
find out about move/rename/delete either via delta notification, or via the
move/rename/delete hook in the provider (depending on whether you require
veto or extra work to occur).
If this doesn't match what you are seeing let me know.
Cheers,
Kevin
"Clemm, Geoff"
<gclemm@xxxxxxxxxxxx> To:
platform-vcm-dev@xxxxxxxxxxx
Sent by: cc:
platform-vcm-dev-admin@ Subject: RE:
[platform-vcm-dev] Team + Refactoring (cont.)
eclipse.org
06/20/2002 11:29 PM
This is a significant bug. A move/rename is not a modification
to the file being moved, it is a modification to the directory/folder
that originally contained the file, and a modification to the
directory/folder that will contain the file.
So MOVE(/a/b, /c/d) should result in an IFileModification to
/a and an IFileModification to /b, not to /a/b or to /c/d.
Similarly, a DELETE(/a/b) should result in an IFileModification
to /a, not to /a/b.
On the other hand, a COPY(/a/b, /c/d) should result in an
IFileModification to /c/d.
Cheers,
Geoff
-----Original Message-----
From: David Corbin [mailto:dcorbin@xxxxxxxx]
Sent: Thursday, June 20, 2002 6:44 PM
To: platform-vcm-dev@xxxxxxxxxxx
Subject: [platform-vcm-dev] Team + Refactoring (cont.)
When a Java file is renamed, I'm getting a call to
IFileModification.validateEdit with a null context. This is problematic
for us. We really need to know that it is being moved before it is
being edited.
I'm not (personally) familiary with IFileModification, but is there any
way for us get the move first before the edit attempt, or for the
validateEdit to provide context that tells us this is being called as
apart of a rename/move?
_________________________________________________
Jim Wright
Stellation Project (Advanced Programming Tools Group)
IBM T.J. Watson Research Center