It's all about the answers!

Ask a question

Using IVersionable "user properties" with the scm java api - fetching previous versions


Morten Madsen (3032641) | asked Aug 17 '12, 5:26 a.m.
edited Aug 20 '12, 4:38 a.m.
Hi, I'm trying to use the SCM user properties as a form of mini-baseline. We have the challenge that we have a lot of folders (10k+) and each of these folders is a package with an ID and a version.

This means that potentially I wanted to run with v1.0 of pack1 and v1.3 of pack3 in a configuration to be deployed. So normal components and baselines will not work in this case, because I'll then have 10k+ components which will eventually mess up my RTC system.

So, I'm using the Java API to change the "version" of a package by changing the user property:

private void updatePackageVersion(IFolder folder, String newVersion, IChangeSetHandle cs1, IWorkspaceConnection wsCon, IProgressMonitor monitor) throws TeamRepositoryException
{        
        folder = (IFolder) folder.getWorkingCopy();
        monitor.subTask("Updating package version ["+getPackageVersion(folder)+"] -> ["+newVersion+"]");        folder.setUserProperty(USER_PROP_PACK_VER, newVersion);
        wsCon.commit(cs1, Collections.singletonList(wsCon.configurationOpFactory().save(folder)), monitor);
}

And that actually works fine. Now my question is.

1. Is there any way to search for items based on the user properties? I can see that IWorkspaceManager.findItems is deprecated, so I guess this does not apply anymore.

2. I guess I then have to fetch the most recent Versionable and then roll back through the earlier versions until I hit a version with an appropriate user property set. Can anyone comment on this, or maybe suggest a code snippet or strategy for doing this?

Any comments or help will be greatly appreciated!

/Morten.

2 answers



permanent link
Morten Madsen (3032641) | answered Aug 20 '12, 4:36 a.m.
Ok so I found out, that you can fetch the previous version of a IVersionable (file or folder) this way:

private IVersionableHandle findItemPreviousState(IWorkspaceConnection sourceWs, IComponentHandle compHandle, IVersionable version, IProgressMonitor monitor, ITeamRepository repo) throws TeamRepositoryException
{
    // getting history for component
    IChangeHistory ch = sourceWs.changeHistory(compHandle);
    monitor.subTask("Searching for changesets with item ["+version.getItemId()+"] in it");
    List changes = ch.getHistoryFor((IVersionableHandle) version, Integer.MAX_VALUE, true, monitor); // 
    monitor.subTask("found ["+changes.size()+"] change sets");
    
    for (Object o : changes)
    {
        IChangeSetHandle csh = ((IChangeHistoryEntryChange)o).changeSet();
        IChangeSet cs = (IChangeSet) repo.itemManager().fetchCompleteItem(csh, ItemManager.DEFAULT, monitor);
        monitor.subTask("scanning change set ["+cs.getItemId()+", ("+cs.getComment()+")] for item state ["+version.getStateId()+"]");
        for (Object co : cs.changes())
        {
            IChange change = (IChange) co;
            // if the "after" state of this change matches my current item, then this change must contain the previous version in "before"
            if (change.afterState() != null && change.afterState().getStateId().equals(version.getStateId()))
            {
                
                System.out.println("item = ["+change.item().getStateId()+"]");
                if (change.beforeState() != null) System.out.println("Before ["+change.beforeState().getStateId()+"]");
                
                System.out.println("Afterstate = ["+change.afterState().getStateId()+"]");
                
                System.out.println("Item found in change set");
                
                return change.beforeState();
            }
        }
    }
    
    return null; // no results found
}

I had trouble with this because I thought, that a IVersionable.getItemId() was the unique identifier for the current version of the file. But it's not. It's only the UUID for the element in all versions. To get the unique ID for the current version of the file, I had to use IVersionable.getStateId().

Hope anybody can use this.





Comments
Morten Madsen commented Aug 20 '12, 5:14 a.m.

Hmm, it seems like I was too fast. IConfiguration.fetchCompleteItem() does not look at the stateId of the IVersionableHandle you pass to it. It will only load the most recent version of the Versionable.

So how do I load a previous version? I have the IVersionableHandle, and the state UUID, how do I access the file contents and User Properties?


permanent link
Morten Madsen (3032641) | answered Aug 20 '12, 5:46 a.m.
Ha haaaa, nailed it :-)


IVersionableManager verManager = SCMPlatform.getWorkspaceManager(sourceWs.teamRepository()).versionableManager();

IVersionable versionable = verManager.fetchCompleteState(versionableHandle, monitor);
This works. And you can get the user properties from the previous version!

Your answer


Register or to post your answer.