It's all about the answers!

Ask a question

How do I find the original pathname of a moved file?


0
1
Ernest Crvich (19211816) | asked Dec 07 '15, 8:23 p.m.
converted to question Dec 08 '15, 4:58 p.m. by Geoffrey Clemm (29.6k23035)
The code in https://jazz.net/forum/questions/94927 doesn't seem to work if the original directory the file was renamed from no longer exists.

e.g., start with directories foo and bar.  Assume you have this file:

foo/fubar.java

Drag fubar.java from foo into bar to move it (IChange.REPARENT operation).  Then delete the empty foo directory. Check these changes in.  Your changeset will contain a delete of foo and a move of fubar.java.

Now using the API, with the IChangeSet you get the IChange for the file fubar.java and get beforeState().  With this returned object, I cannot find any way to get the old path, either using the IConfiguration for the component, or IVersionableManager.

IConfiguration.fetchCompleteItem() throws an ItemNotFoundException when you pass it the fileItem's getParent() returned object, claiming it doesn't exist in the configuration.

If you instead use IVersionableManager.fetchCompleteState() on the getParent() object, it claims that the state does not exist.

Is there no way to get the previous (deleted) path when you only have the IChange object of the file to use?

2 answers



permanent link
Geoffrey Clemm (29.6k23035) | answered Dec 08 '15, 5:05 p.m.
FORUM ADMINISTRATOR / FORUM MODERATOR / JAZZ DEVELOPER
edited Dec 09 '15, 1:25 a.m.
The short answer is "no". 
The explanation is that a file-move change set in RTC does not remember the "previous" path (it only remembers the "previous" parent directory item-uuid, and the name the moved file had in that parent directory).    When you accept a "file move" change set into a workspace, it moves that file from wherever that previous parent directory currently exist in that workspace.   The previous pathname of a file in the workspace where the move change set was originally created is not considered interesting, and is not stored in the file-move change set.

Comments
Ernest Crvich commented Dec 08 '15, 7:00 p.m. | edited Dec 09 '15, 12:55 a.m.

It's pretty interesting/important information to us.  For our builds (on zOS), we store part information (which includes the full path, since as you know files with the same name can exist in multiple directories) in a driver database.  When a user moves or renames a part in RTC, that needs to be processed in zOS as a two-part delete-and-create action to work properly (the zOS mechanisms do not offer true renames/moves).  i.e., the old pathname is marked as inactive/deleted, and the new pathname is added as a new file.  It is not the same thing to either (1) treat the scenario as a delta (since the new pathname never existed before), or (2) treat the scenario as just a create (since the old pathname will still exist in the driver).

Certainly RTC does have this information, because the RTC GUI can show me the old path...the API is apparently just not making things intuitive to retrieve that info (e.g., the fact that IConfiguration ignores the IVersionable state).  Would it be feasible to somehow retrieve a part's full history in order to track down the previous path?  Or would IConfiguration and IVersionableManager still thwart me even then?


Geoffrey Clemm commented Dec 09 '15, 1:37 a.m. | edited Dec 09 '15, 1:38 a.m.
FORUM ADMINISTRATOR / FORUM MODERATOR / JAZZ DEVELOPER

Whether or not "RTC does have this information" it depends on what you mean by "this information".   If you mean "the previous pathname of the file in the workspace at the time it was moved", then no, it does not have that information.   If you mean "the information needed to implement your use case", then I believe the answer is "yes".  In particular, what the RTC knows (and what the RTC GUI can show you) is the path to the previous parent directory in whatever workspace you are currently looking at, and for your use case, I believe that is the path that matters.   In particular, suppose you accept a change set into a workspace where that previous parent directory has been moved somewhere else.   In that workspace, the previous pathname in the workspace in which the move change set was created is not relevant ... the pathname of that directory in your current workspace is what matters (since that is where you will find the file to be made inactive/deleted).   So what you should be looking for is the API that will get you the previous parent item-id from the move operation, and then looking up the pathname of the previous parent item-id in your current workspace.


permanent link
Ernest Crvich (19211816) | answered Dec 09 '15, 7:21 p.m.
Ok, finally figured it out.  The quick-and-dirty gist of it is below. The goofy thing is that determineAncestorsInHistory() does not work on the beforeState versionable, only on its stateless parent object.  And config.locateAncestors() does not work with either.  Makes no sense to me, but it's working now, so thanks for the hints, Geoff.

IConfiguration config;
IChange change; // the move/rename change
IVersionable beforeState = versionableManager.fetchCompleteState( change.beforeState() );
IFolderHandle parent = beforeState.getParent();
try {
// for normal cases where the parent folder still exists...
config.fetchCompleteItem( parent, ... );
// etc.
}
catch (ItemNotFoundException e)
{
  List<IVersionableHandle> fileAsList; // container for parent item
  fileAsList.add( parent );
  IAncestorReport ancestors = config.determineAncestorsInHistory( fileAsList, monitor );
// get the name/item pairs and cobble together the path from that
}

Comments
Geoff Alexander commented Jan 29, 10:04 a.m. | edited Jan 29, 10:08 a.m.

Ernest, Thanks for the answer.  If I understand correctly, this requires one call to IVersionableManager.fetchCompleteState followed by multiple calls to IConfiguration.fetchCompleteItem (once for each parent folder until ItemNotFoundException is thrown).  When ItemNotFoundException is thrown, an additional call to IConfiguration.determineAncestorsInHistory is needed.  Since each of the calls required server access, this can take quite a bit of time, especially for files with deep paths such Java source (Java packages can have deep directory structures).

Is there a faster way to get the path of a moved file?  And is a there way I can get the path multiple moved files at once so as to further reduce calls to the server?

Your answer


Register or to post your answer.