How do I find "moved from" location for a moved/reparented item using RTC-4 Java API?
This is a restatement of "How do I find move from location using RTC-4 Java API" that i posted Nov 14, 2012. I tried to update the original, but could not get the update to save.
All of these scenarios used RAD-8 with the Eclipse RTC-4 Extension (Plug-In), and a Java program using the RTC Java API IConfiguration.determineAncestorsInHistory to examine the repository’s record of changes to the item. The Jazz server is on zLinux. The RTC client is on Win-7.
Add an item.
After the add, the Change Explorer view shows the location (path) of the added item, and it’s name. Double clicking the item shows that it did not exist before the add, but does after the add.
The Java program found a change of type ADD. The change had no before state, and the after state info agreed with Change Explorer’s info concerning location and name info.
Rename an item.
After the rename, the Change Explorer view shows the location (path) of the renamed item, and it’s new name. The new name has a parenthesized note stating that it was “moved”, and the note’s text shows the original location and the old name. Double clicking the item shows that it existed both before and after rename.
The Java program found a change of type RENAME. The change had both before and after states. The before state info agreed with Change Explorer’s parenthesized note concerning location and name info.
Modify an item (change its content).
After the modification, the Change Explorer view shows the location (path) of the modified item, and it’s name. Double clicking the item shows that it existed both before and after the modification.
The Java program found a change of type MODIFY. The change had both before and after states. The before state and after state info agreed with Change Explorer location and name.
Delete an item.
After the delete, the Change Explorer view shows the location (path) of the deleted item, and it’s name. Double clicking the item shows that it existed before the delete, but not after.
The Java program found a change of type DELETE. The change had a before state, but no after state. The before state info agreed with Change Explorer location and name.
Move (Reparent) an item.
After the move, the Change Explorer view shows the new location (path) of the modified item, and it’s name. The name has a parenthesized note stating that it was moved, and the note’s text shows the old location and the name. Double clicking the item shows that it existed both before and after rename.
The Java program found a change of type MODIFY REPARENT. The change had both before and after states. The before state info did not agree with Change Explorer’s parenthesized note concerning location and name info. The before state and after state both showed the new location.
The Java program also drilled down to found the original change that added the moved item. It found a change of type ADD. The change had no before state. The after state info showed the item’s post-rename location instead of the location to which the item was originally added.
Using the RTC-4 Java API, how do I find the “moved from” info that is shown in the Change Explorer view for a Move (Reparent)?
------------------
Sample that was requested
Change Explorer
Messaging/Java Source/com/timeinc/tcs/TestFolder
.jazzignore (moved from Messaging/Java Source/com/timeinc/tcs/messaging/.jazzignore)
Change Set "Try reparent without modify" moved .jazzignore from "Messaging/Java Source/com/timeinc/tcs/messaging/" to "Messaging/Java Source/com/timeinc/tcs/TestFolder/". It's beforeState shows TestFolder which is wrong.
Change Set "2012-04-25-RTC-Pilot-Project-RADx-to-RAD7-Experiment" added .jazzignore to "Messaging/Java Source/com/timeinc/tcs/messaging/". It's afterState shows TestFolder, which is wrong.
Output from code
findItemPreviousState: searching for changesets with item [[UUID _CaZk1Y-eEeGWK5ltQ6NI5g]] [.jazzignore] in it
findItemPreviousState: found [2] change sets
findItemPreviousState: change set [[UUID _59Xf8inhEeK9bb-eGBmn3Q], (Try reparent without modify)] for item state [[UUID _Cgp94o-eEeGJ2Nzkoe8eeg]]
findItemPreviousState: change set changes: 1
findItemPreviousState: change.beforeState():com.ibm.team.filesystem.common.internal.impl.FileItemHandleImpl@57885788 (stateId: [UUID _Cgp94o-eEeGJ2Nzkoe8eeg], itemId: [UUID _CaZk1Y-eEeGWK5ltQ6NI5g], origin: <unset>, immutable: <unset>)
findItemPreviousState: change.beforeState().getStateId()[UUID _Cgp94o-eEeGJ2Nzkoe8eeg]
findItemPreviousState: change.beforeState().getItemId() [UUID _CaZk1Y-eEeGWK5ltQ6NI5g]
findItemPreviousState: versionable.getItemId() [UUID _CaZk1Y-eEeGWK5ltQ6NI5g]
getVersionables2: kind: 10 ... MODIFY REPARENT
getVersionables2: change.beforeState():com.ibm.team.filesystem.common.internal.impl.FileItemHandleImpl@75627562 (stateId: [UUID _Cgp94o-eEeGJ2Nzkoe8eeg], itemId: [UUID _CaZk1Y-eEeGWK5ltQ6NI5g], origin: <unset>, immutable: <unset>)
getVersionables2: change.beforeState().getStateId()[UUID _Cgp94o-eEeGJ2Nzkoe8eeg]
getVersionables2: change.beforeState().getItemId() [UUID _CaZk1Y-eEeGWK5ltQ6NI5g]
getVersionables2: ancestors: 1
getVersionables2: versionable ancestors path: \Messaging\Java Source\com\timeinc\tcs\TestFolder\.jazzignore
getVersionables2: ancestors in history: 1
getVersionables2: versionable ancestors in history path: \Messaging\Java Source\com\timeinc\tcs\TestFolder\.jazzignore
findItemPreviousState: change.afterState():com.ibm.team.filesystem.common.internal.impl.FileItemHandleImpl@79067906 (stateId: [UUID _6BubhCnhEeK9bb-eGBmn3Q], itemId: [UUID _CaZk1Y-eEeGWK5ltQ6NI5g], origin: <unset>, immutable: <unset>)
findItemPreviousState: change.afterState().getStateId() [UUID _6BubhCnhEeK9bb-eGBmn3Q]
findItemPreviousState: change.afterState().getItemId() [UUID _CaZk1Y-eEeGWK5ltQ6NI5g]
findItemPreviousState: versionable.getItemId() [UUID _CaZk1Y-eEeGWK5ltQ6NI5g]
getVersionables2: kind: 10 ... MODIFY REPARENT
getVersionables2: change.afterState():com.ibm.team.filesystem.common.internal.impl.FileItemHandleImpl@26582658 (stateId: [UUID _6BubhCnhEeK9bb-eGBmn3Q], itemId: [UUID _CaZk1Y-eEeGWK5ltQ6NI5g], origin: <unset>, immutable: <unset>)
getVersionables2: change.afterState().getStateId()[UUID _6BubhCnhEeK9bb-eGBmn3Q]
getVersionables2: change.afterState().getItemId() [UUID _CaZk1Y-eEeGWK5ltQ6NI5g]
getVersionables2: ancestors: 1
getVersionables2: versionable ancestors path: \Messaging\Java Source\com\timeinc\tcs\TestFolder\.jazzignore
getVersionables2: ancestors in history: 1
getVersionables2: versionable ancestors in history path: \Messaging\Java Source\com\timeinc\tcs\TestFolder\.jazzignore
findItemPreviousState: change set [[UUID _CgjQIY-eEeGJ2Nzkoe8eeg], ([emsrv] 2012-04-25-RTC-Pilot-Project-RADx-to-RAD7-Experiment)] for item state [[UUID _Cgp94o-eEeGJ2Nzkoe8eeg]]
findItemPreviousState: change set changes: 24
...
... omitted lines
...
findItemPreviousState: change.afterState():com.ibm.team.scm.common.internal.impl.FolderHandleImpl@2590259 (stateId: [UUID _CgovsI-eEeGJ2Nzkoe8eeg], itemId: [UUID _CaZk0o-eEeGWK5ltQ6NI5g], origin: <unset>, immutable: <unset>)
findItemPreviousState: change.afterState().getStateId() [UUID _CgovsI-eEeGJ2Nzkoe8eeg]
findItemPreviousState: change.afterState().getItemId() [UUID _CaZk0o-eEeGWK5ltQ6NI5g]
findItemPreviousState: versionable.getItemId() [UUID _CaZk1Y-eEeGWK5ltQ6NI5g]
getVersionables2: kind: 1 ... ADD
getVersionables2: change.afterState():com.ibm.team.filesystem.common.internal.impl.FileItemHandleImpl@25392539 (stateId: [UUID _Cgp94o-eEeGJ2Nzkoe8eeg], itemId: [UUID _CaZk1Y-eEeGWK5ltQ6NI5g], origin: <unset>, immutable: <unset>)
getVersionables2: change.afterState().getStateId()[UUID _Cgp94o-eEeGJ2Nzkoe8eeg]
getVersionables2: change.afterState().getItemId() [UUID _CaZk1Y-eEeGWK5ltQ6NI5g]
getVersionables2: ancestors: 1
getVersionables2: versionable ancestors path: \Messaging\Java Source\com\timeinc\tcs\TestFolder\.jazzignore
getVersionables2: ancestors in history: 1
getVersionables2: versionable ancestors in history path: \Messaging\Java Source\com\timeinc\tcs\TestFolder\.jazzignore
findItemPreviousState: change.afterState():com.ibm.team.scm.common.internal.impl.FolderHandleImpl@158c158c (stateId: [UUID _Cgp95Y-eEeGJ2Nzkoe8eeg], itemId: [UUID _CaZk1I-eEeGWK5ltQ6NI5g], origin: <unset>, immutable: <unset>)
findItemPreviousState: change.afterState().getStateId() [UUID _Cgp95Y-eEeGJ2Nzkoe8eeg]
findItemPreviousState: change.afterState().getItemId() [UUID _CaZk1I-eEeGWK5ltQ6NI5g]
findItemPreviousState: versionable.getItemId() [UUID _CaZk1Y-eEeGWK5ltQ6NI5g]
...
... omitted lines
...
Code sample
public static void findItemPreviousState(IWorkspaceConnection workspace, IComponent component, IVersionable versionable,
IVersionableManager verManager, IConfiguration iconfig) throws TeamRepositoryException {
// getting history for component
IChangeHistory ch = workspace.changeHistory(component);
System.out.println("\n findItemPreviousState: searching for changesets with item ["+versionable.getItemId()+"] ["+versionable.getName()+"] in it");
List changes = ch.getHistoryFor((IVersionableHandle) versionable, Integer.MAX_VALUE, true, monitor);
System.out.println(" findItemPreviousState: found ["+changes.size()+"] change sets");
for (Object o : changes) {
IChangeSetHandle csh = ((IChangeHistoryEntryChange)o).changeSet();
IChangeSet cs = (IChangeSet) teamRepository.itemManager().fetchCompleteItem(csh, IItemManager.DEFAULT, monitor);
System.out.println("\n findItemPreviousState: change set ["+cs.getItemId()+", ("+cs.getComment()+")] for item state ["+versionable.getStateId()+"]");
System.out.println(" findItemPreviousState: change set changes: "+cs.changes().size());
for (Object co : cs.changes()) {
IChange change = (IChange) co;
if (change.beforeState() != null) {
//if (versionable.getItemId().equals(change.beforeState().getItemId()) ) {
System.out.println(" findItemPreviousState: change.beforeState():" + change.beforeState());
System.out.println(" findItemPreviousState: change.beforeState().getStateId()" + change.beforeState().getStateId());
System.out.println(" findItemPreviousState: change.beforeState().getItemId() " + change.beforeState().getItemId());
System.out.println(" findItemPreviousState: versionable.getItemId() " + versionable.getItemId());
getVersionables2(iconfig, change, "before");
//}
}
if (change.afterState() != null) {
//if (versionable.getItemId().equals(change.afterState().getItemId()) ) {
System.out.println("\n findItemPreviousState: change.afterState():" + change.afterState());
System.out.println(" findItemPreviousState: change.afterState().getStateId() " + change.afterState().getStateId());
System.out.println(" findItemPreviousState: change.afterState().getItemId() " + change.afterState().getItemId());
System.out.println(" findItemPreviousState: versionable.getItemId() " + versionable.getItemId());
getVersionables2(iconfig, change, "after");
//}
}
}
}
return;
}
public static void getVersionables2(IConfiguration iconfig, IChange change, String state) throws TeamRepositoryException {
String kind = "\n getVersionables2: kind: "+change.kind()+" ...";
if (change.kind() == 0) kind = kind + " NONE";
if (((change.kind() & IChange.MODIFY) == IChange.MODIFY)) kind = kind + " MODIFY";
if (((change.kind() & IChange.RENAME) == IChange.RENAME)) kind = kind + " RENAME";
if (((change.kind() & IChange.ADD) == IChange.ADD)) kind = kind + " ADD";
if (((change.kind() & IChange.DELETE) == IChange.DELETE)) kind = kind + " DELETE";
if (((change.kind() & IChange.REPARENT) == IChange.REPARENT)) kind = kind + " REPARENT";
System.out.println (kind);
IVersionableHandle versionableHandle = null;
if (state.equals("after")) {
versionableHandle = change.afterState();
System.out.println(" getVersionables2: change.afterState():" + change.afterState());
System.out.println(" getVersionables2: change.afterState().getStateId()" + change.afterState().getStateId());
System.out.println(" getVersionables2: change.afterState().getItemId() " + change.afterState().getItemId());
}
else {
versionableHandle = change.beforeState();
System.out.println(" getVersionables2: change.beforeState():" + change.beforeState());
System.out.println(" getVersionables2: change.beforeState().getStateId()" + change.beforeState().getStateId());
System.out.println(" getVersionables2: change.beforeState().getItemId() " + change.beforeState().getItemId());
}
List filesToSearch = new ArrayList();
filesToSearch.add(versionableHandle);
List ancestor = iconfig.locateAncestors(filesToSearch,monitor);
String path1 = "";
System.out.println(" getVersionables2: ancestors: "+ancestor.size());
for(Object ancestorObj:ancestor) {
IAncestorReport ancestorImpl = (IAncestorReport)ancestorObj;
for(Object nameItemPairObj:ancestorImpl.getNameItemPairs()) {
NameItemPairImpl nameItemPair = (NameItemPairImpl)nameItemPairObj;
Object item = SCMPlatform.getWorkspaceManager(teamRepository).versionableManager().fetchCompleteState(nameItemPair.getItem(),null);
String pathName = "";
if(item instanceof IFolder) {
pathName = ((IFolder)item).getName();
}
else if(item instanceof IFileItem) {
pathName = ((IFileItem)item).getName();
}
if(!pathName.equals("")) path1 = path1 + "\\" + pathName;
}
}
System.out.println(" getVersionables2: versionable ancestors path: "+ path1);
//test test test start
ancestor = iconfig.determineAncestorsInHistory(filesToSearch,monitor);
System.out.println(" getVersionables2: ancestors in history: "+ancestor.size());
path1 = "";
for(Object ancestorObj:ancestor) {
IAncestorReport ancestorImpl = (IAncestorReport)ancestorObj;
for(Object nameItemPairObj:ancestorImpl.getNameItemPairs()) {
NameItemPairImpl nameItemPair = (NameItemPairImpl)nameItemPairObj;
if (nameItemPair.getItem().getStateId() != null) {
Object item = SCMPlatform.getWorkspaceManager(teamRepository).versionableManager().fetchCompleteState(nameItemPair.getItem(),null);
String pathName = "";
if(item instanceof IFolder) {
pathName = ((IFolder)item).getName();
}
else if(item instanceof IFileItem) {
pathName = ((IFileItem)item).getName();
}
if(!pathName.equals("")) path1 = path1 + "\\" + pathName;
//System.out.println(".................. path1: "+ path1);
}
else {
path1 = path1 + "\\" + nameItemPair.getName();
}
}
}
System.out.println(" getVersionables2: versionable ancestors in history path: "+ path1);
}
3 answers
Remy Suen’s suggestion, along with experimentation and the info at “https://jazz.net/forum/questions/85248/using-iversionable-user-properties-with-the-scm-java-api-fetching-previous-versions” got me what I was looking for. I ran reparent, delete, modify, and add changes through to validate the code. Thanks.
1) Change Set: Test of change set traversal
component: Messaging_comp [UUID _CEzIQI-eEeGJ2Nzkoe8eeg]
changes: 5
1)kind: 10 ... MODIFY REPARENT
change beforeState Id: [UUID _CgovvY-eEeGJ2Nzkoe8eeg]
getParent3: change beforeState Id: [UUID _CgovvY-eEeGJ2Nzkoe8eeg]
getParent3: path: \Messaging\Java Source\com\timeinc\tcs\messaging\CICSSystem.java
change afterState Id: [UUID _JGXrJShQEeK9bb-eGBmn3Q]
getParent3: change afterState Id: [UUID _JGXrJShQEeK9bb-eGBmn3Q]
getParent3: path: \Messaging\Java Source\com\timeinc\tcs\TestFolder\CICSSystem.java
2)kind: 2 ... MODIFY
change beforeState Id: [UUID _CgpWx4-eEeGJ2Nzkoe8eeg]
getParent3: change beforeState Id: [UUID _CgpWx4-eEeGJ2Nzkoe8eeg]
getParent3: path: \Messaging\Java Source\com\timeinc\tcs\model\Magazine.java
change afterState Id: [UUID _JGXrFChQEeK9bb-eGBmn3Q]
getParent3: change afterState Id: [UUID _JGXrFChQEeK9bb-eGBmn3Q]
getParent3: path: \Messaging\Java Source\com\timeinc\tcs\model\Magazine.java
3)kind: 16 ... DELETE
change beforeState Id: [UUID _Cgqk-Y-eEeGJ2Nzkoe8eeg]
getParent3: change beforeState Id: [UUID _Cgqk-Y-eEeGJ2Nzkoe8eeg]
getParent3: path: \Messaging\Java Source\com\timeinc\tcs\messaging\EnumerationImpl.java
4)kind: 2 ... MODIFY
change beforeState Id: [UUID _Cgqk8o-eEeGJ2Nzkoe8eeg]
getParent3: change beforeState Id: [UUID _Cgqk8o-eEeGJ2Nzkoe8eeg]
getParent3: path: \Messaging\Java Source\com\timeinc\tcs\messaging\ValueSetImpl.java
change afterState Id: [UUID _JGXrGyhQEeK9bb-eGBmn3Q]
getParent3: change afterState Id: [UUID _JGXrGyhQEeK9bb-eGBmn3Q]
getParent3: path: \Messaging\Java Source\com\timeinc\tcs\messaging\ValueSetImpl.java
5)kind: 1 ... ADD
change afterState Id: [UUID _JGXrHihQEeK9bb-eGBmn3Q]
getParent3: change afterState Id: [UUID _JGXrHihQEeK9bb-eGBmn3Q]
getParent3: path: \Messaging\Java Source\com\timeinc\tcs\TestFolder
“workspace” is an IWorkspaceConnection to a stream.
“iconfig” is an IConfiguration of the component for a workspace change set
“change” is an IChange of a change found in the change set
public static void getParent3(IChange change, IConfiguration iconfig, String state) throws TeamRepositoryException {
//https://jazz.net/forum/questions/85248/using-iversionable-user-properties-with-the-scm-java-api-fetching-previous-versions
// The above link is where I got more info for getting past the problem where I could only get the current state.
IVersionableManager verManager = SCMPlatform.getWorkspaceManager(workspace.teamRepository()).versionableManager();
IVersionableHandle versionableHandle = null;
if (state.equals("before")) {
System.out.println(" getParent3: change beforeState Id: "+change.beforeState().getStateId());
versionableHandle = change.beforeState();
}
if (state.equals("after")) {
System.out.println(" getParent3: change afterState Id: "+change.afterState().getStateId());
versionableHandle = change.afterState();
}
String path = "";
IVersionable currentItem = null;
//You cannot use iconfig.fetchCompleteItem (versionableHandle, monitor) on the file because
// IConfiguration always returns after state (it does not honor state Ids).
currentItem = verManager.fetchCompleteState(versionableHandle, monitor);
try {
while (versionableHandle != null) {
final String name = currentItem.getName();
if (name != null & name.length () > 0) {
path = name + "\\" + path;
}
versionableHandle = currentItem.getParent();
if (versionableHandle != null) {
//You have to switch from verManager.fetchCompleteState(versionableHandle, monitor) to
// iconfig.fetchCompleteItem (versionableHandle, monitor) to avoid null state for folders.
currentItem = iconfig.fetchCompleteItem (versionableHandle, monitor);
}
}
path = path.substring(0,path.length()-1);
System.out.println(" getParent3: path: "+ "\\" + path);
}
catch (Exception e) {
System.out.println(" getParent3: Exception: "+ e.getMessage());
}
return;
}
Comments
Tim Mok
JAZZ DEVELOPER Dec 08 '15, 4:55 p.m.Can you provide a sample piece of code that you're using to get the before state's parent?
mark byrd
Dec 12 '12, 9:47 a.m.IE would not let me edit the post. I had to use Chrome.
Remy Suen
Dec 12 '12, 11:41 a.m.I tried running your code and appeared to get the same result that you did. I am not sure if those methods on IConfiguration are supposed to honour state ids or not.
Perhaps you could use IVersionable's getParent() method as a temporary workaround.
Tim Mok
JAZZ DEVELOPER Dec 12 '12, 11:51 a.m.The calls on IConfiguration return IAncestorReport that includes a list of INameItemPair. Casting to the internal NameItemPairImpl is bad form. INameItemPair is API and is safer to use as you move forward through releases.
INameItemPair also has the item's name (as the object name implies). Is there a reason you don't use the value there and decide to fetch the versionable to get the name?
mark byrd
Dec 19 '12, 3:19 p.m.