How to get the file path of a changed file in RTC with JAVA?
Hello everyone,
I try to fetch the code to get the full path of a file that got edited in a change set linked to a work item. What I currently try to achieve is that I dont only get the filename, but also the full path.
My customized code (from rsjazz) looks like this:
public void getConnectedFiles(IWorkspaceManager workspaceManager, IWorkItemClient workItemClient, ILinkManager linkManager, IItemManager itemManager, int workItemID){
try{
IWorkItem workItem = workItemClient.findWorkItemById(workItemID, IWorkItem.FULL_PROFILE,
new SysoutProgressMonitor());
logInfo("[" + workItem.getId() + "] " + workItem.getHTMLSummary().getPlainText());
// Find all of the change sets using the link manager to find a
// special kind of
// link that crosses between work items and source control change
// sets using its ID.
IItemReference workItemReference = linkManager.referenceFactory().createReferenceToItem(workItem);
ILinkCollection linkCollection = linkManager
.findLinksByTarget(ILinkConstants.CHANGESET_WORKITEM_LINKTYPE_ID, workItemReference,
new SysoutProgressMonitor())
.getAllLinksFromHereOn();
logInfo("LinkCollection received ...");
if (linkCollection.isEmpty()) {
logInfo("Work item has no change sets.");
} else {
// read the list of changes
List<IChangeSetHandle> changeSetHandles = new ArrayList<IChangeSetHandle>();
for (ILink link : linkCollection) {
// Change set links should be item references
IChangeSetHandle changeSetHandle = (IChangeSetHandle) link.getSourceRef().resolve();
changeSetHandles.add(changeSetHandle);
@SuppressWarnings("unchecked")
List<IChangeSet> changeSets = itemManager.fetchCompleteItems(changeSetHandles, IItemManager.DEFAULT,
new SysoutProgressMonitor());
Set<String> changedFilesAndFolders = new TreeSet<String>();
// Set<String> changedFilesAndFoldersPath = new TreeSet<String>();
for (IChangeSet cs : changeSets) {
for (Object o : cs.changes()) {
IChange change = (IChange) o;
if (change.kind() != IChange.DELETE) {
IVersionableHandle after = change.afterState();
// Although versionable handles are item
// handles, you cannot use the item
// manager to fetch the versionable from the
// handle. Instead, you use the
// versionable manager to do this.
IVersionable afterVersionable = workspaceManager.versionableManager()
.fetchCompleteState(after, new SysoutProgressMonitor());
// TODO: read path, other MetaData ...
changedFilesAndFolders.add(afterVersionable.getName());
// changedFilesAndFoldersPath.add(afterVersionable.getParent().toString());
As you can see, I try to get the path in the last line, but it only generates some cryptic code.
What can I do?
Accepted answer
String filePath = "";
for (IWorkspaceHandle wHandle : wHandles) {
IWorkspace workspace = (IWorkspace) repo.itemManager().fetchCompleteItem(wHandle, IItemManager.DEFAULT, null);
IWorkspaceConnection wsConn = wm.getWorkspaceConnection(workspace, null);
// previously I had retrieved the component associated to the versionable
IComponent component = rawFilesHash.get(versionableHandle);
IConfiguration configuration = wsConn.configuration(component);
List<IVersionableHandle> versionableHandleList = new ArrayList<IVersionableHandle>();
versionableHandleList.add(versionableHandle);
List<?> ancestorReports = configuration.locateAncestors(versionableHandleList, monitor);
IAncestorReport iAncestorReport = (IAncestorReport) ancestorReports.get(0);
List<INameItemPair> reportList = iAncestorReport.getNameItemPairs();
for (INameItemPair iNameItemPair : reportList){
String temp = iNameItemPair.getName();
if (temp != null) {
filePath += "/" + temp ;
}
}
if (!filePath.isEmpty()) {
break;
}
}
Comments
4 other answers
Hello,
I got empty name pairs because I was in the wrong workspace. I found a way to easily get the corresponding workspace to a changeset, and now it builds the filepath for me! I attached my working code, I hope it can help other people with the same problem.
public static String pathFinder(ITeamRepository repo, IWorkspaceManager wm, IChangeSet cs, IVersionableHandle vh)
throws TeamRepositoryException {
String filePath = "";
IWorkspaceConnection wsc = workspaceConnectionFinder(repo, wm, cs);
IComponentHandle component = cs.getComponent();
IConfiguration config = wsc.configuration(component);
List<iversionablehandle> versionableHandleList = new ArrayList<iversionablehandle>();
versionableHandleList.add(vh); // ok
List<IAncestorReport> ancestorReports = config.locateAncestors(versionableHandleList,
new SysoutProgressMonitor());
IAncestorReport iAncestorReport = ancestorReports.get(0);
List<INameItemPair> reportList = iAncestorReport.getNameItemPairs();
for (INameItemPair iNameItemPair : reportList) {
String temp = iNameItemPair.getName();
if (temp != null) {
filePath += "/" + temp;
}
}
return filePath;
}
public static IWorkspaceConnection workspaceConnectionFinder(ITeamRepository repo, IWorkspaceManager wm, IChangeSet cs)
throws TeamRepositoryException {
IWorkspaceSearchCriteria wsSearchCriteria = WorkspaceSearchCriteria.FACTORY.newInstance();
wsSearchCriteria.setKind(IWorkspaceSearchCriteria.ALL);
List<IWorkspaceHandle> workspaceHandles = wm.findWorkspacesContainingChangeset(cs, wsSearchCriteria,
Integer.MAX_VALUE, new SysoutProgressMonitor());
IWorkspaceConnection wsc = wm.getWorkspaceConnection(workspaceHandles.get(0), new SysoutProgressMonitor());
return wsc;
}
Hi Benjamin,
some time ago I had your same need, so I developed a server-side extension that gets the paths of the files in a change set.
I hope that this code snippet can help you (I tested it on version 5.0.2):
List changes = (List)changeSet.changes();
for (Iterator changesIterator = changes.iterator(); changesIterator.hasNext();) {
boolean modifiedElement = false;
boolean addedElement = false;
boolean deletedElement = false;
IChange change = (IChange)changesIterator.next();
IVersionableHandle changeObj = null;
Integer changeKind = change.kind();
switch (changeKind) {
case 1: {
// added
addedElement = true;
changeObj = change.afterState();
};
break;
case 2: {
// modified
modifiedElement = true;
changeObj = change.afterState();
};
break;
case 16: {
// deleted
deletedElement = true;
changeObj = change.beforeState();
};
default: {
};
break;
}
// file path, starting from the component root
String elementPath = "";
ServiceConfigurationProvider configProvider = ServiceConfigurationProvider.FACTORY.create(findStreamFromEnvironment(deliveryTargetName, repositoryProgressMonitorHandle), changeSet.getComponent());
List nameItemPairs = null;
if (modifiedElement) {
IAncestorReport reports[] = scmService.configurationLocateAncestors(configProvider, new IVersionableHandle[] {changeObj}, null, repositoryProgressMonitorHandle);
nameItemPairs = reports[0].getNameItemPairs();
}
if (addedElement) {
IAncestorReport reports[] = scmService.configurationLocateAncestors(configProvider, new IVersionableHandle[] {changeObj}, null, repositoryProgressMonitorHandle);
nameItemPairs = reports[0].getNameItemPairs();
}
if (deletedElement) {
IAncestorReport reports[] = scmService.configurationDetermineAncestorsInHistory(configProvider, new IVersionableHandle[] {changeObj}, null, repositoryProgressMonitorHandle);
nameItemPairs = reports[0].getNameItemPairs();
}
if (nameItemPairs.isEmpty()) {
IAncestorReport reports[] = scmService.configurationDetermineAncestorsInHistory(configProvider, new IVersionableHandle[] {changeObj}, null, repositoryProgressMonitorHandle);
nameItemPairs = reports[0].getNameItemPairs();
}
for (Iterator iterator = nameItemPairs.iterator(); iterator.hasNext();) {
INameItemPair nameItemPair = (INameItemPair)iterator.next();
String pathPiece = nameItemPair.getName();
if (pathPiece != null) {
elementPath = elementPath.concat("/" + pathPiece);
}
}
if (elementPath.isEmpty()) {
elementPath = "<file another="" by="" change="" removed="" set="">";
}
}
Comments
As far as I know, the path information RTC stores in SCM is only relative to the component. It is impossible to get an absolute path, unless the file is loaded onto disc somewhere.
Comments
Luca Martinucci
Feb 28 '17, 5:45 a.m.Luca Martinucci
Mar 13 '17, 11:33 a.m.