Viewing Folder Trees in history

Post your questions regarding using the Vault and Fortress API in your programs.

Moderator: SourceGear

Post Reply
javaguy
Posts: 10
Joined: Wed May 20, 2009 10:21 am

Viewing Folder Trees in history

Post by javaguy » Wed May 20, 2009 10:30 am

Hi,

I am writing a small app using your JAVA API and using the C# and the Command Line APIs for testing

I want to view (not retrieve) the files and the folders as they existed at a point in time (Folder Tree as of a version).

I can do this in the GUI (see attached screenshot).
1) View->Show History
2) Click "View Folder History by Version"
3) Click OK
4) Select a version and hit "View Tree"

Is there an equivalent of this view from any of your API calls? I cannot seem to find one.

Thank you,

Javaguy
Attachments
sgvaultfoldertree.PNG
sgvaultfoldertree.PNG (15.97 KiB) Viewed 18247 times

shannon

Re: Viewing Folder Trees in history

Post by shannon » Wed May 20, 2009 11:13 am

The visual things aren't provided in the api. However, I can help you re-create it if you'd like. It's sort of complicated from the java api....I'll need to add a function to ServerOperations for this to even be possible (there's a ref parameter in the function you'll need to call, so it doesn't work to call it directly). Are you working with the latest version? You're using Vault, correct?

javaguy
Posts: 10
Joined: Wed May 20, 2009 10:21 am

Re: Viewing Folder Trees in history

Post by javaguy » Wed May 20, 2009 11:28 am

Hi Shannon

I am using vault 4.1.4.

What I have right now is:

Code: Select all

private static List<Folder> buildTree(String root) {
		List<Folder> allFolders = new ArrayList<Folder>();		
		VaultClientFolder vcfolder = ServerOperations.ProcessCommandListFolder(root, false);
		VaultClientFolderColl  coll = vcfolder.get_Folders();
		int count =  coll.get_Count();
		for(int i =0; i< count;i++)
		{
			VaultClientFolder curVCF =(VaultClientFolder)coll.get_Item(i);		
			Folder temp = new Folder(curVCF.get_Name(), curVCF.get_FullPath(), curVCF.get_Version());
			// This is the recursive call to get the children folders
			temp.setChildren(buildTree(curVCF.get_FullPath()));
			// This sets The members.
			temp.setMembers(getMembers(temp.getPath()));
			allFolders.add(temp);
		}
		return allFolders;
	}
This builds a tree based on the root version which contains all the Folders and Members it has as children, but only at the current version. I would like to do the same thing except like this:

Code: Select all

	private static List<Folder> buildTree(String root, long version) {
		VaultClientFolder vcfolder = ServerOperations.ProcessCommandListFolder(root, false, version);
		VaultClientFolderColl  coll = vcfolder.get_Folders();
		...
	}
I don't need the visual aspect, just the access to the list which contains the child/parent relationships from a historical point of view.

Hopefully this makes sense.

Any suggestions/help are greatly appreciated!

Regards,

Javaguy

shannon

Re: Viewing Folder Trees in history

Post by shannon » Wed May 20, 2009 12:14 pm

Ok, I'm adding the method you'll need to ServerOperations. Send me an email (shannon at sourcegear dot com) so that I can give you a link to download a pre-release build when I have it ready in a few hours.

shannon

Re: Viewing Folder Trees in history

Post by shannon » Wed May 20, 2009 3:21 pm

Just to update on the details I've given Javaguy by email:

The code to do this:
VaultFolderDelta vfd = ServerOperations.ProcessCommandGetBranchStructure(repID, fullPath, objID, version, true);
VaultClientFile vcf = new VaultClientFile(vfd, null);

ServerOperations.ProcessCommandGetBranchStructure will be available in versions 4.1.5 or 5.0 (versions 1.1.5 or 2.0 for Fortress).

javaguy
Posts: 10
Joined: Wed May 20, 2009 10:21 am

Re: Viewing Folder Trees in history

Post by javaguy » Thu May 21, 2009 5:30 am

Hi Shannon,

This seems to work perfectly except for the children.
The way I see it I can get to the children of this using:

Code: Select all

VaultFolderDelta[] vfdarray= vfd.get_Folders();
However VaultFodlerDelta.get_FullPath() doesn't seem to exist
so, using your example I tried this:

Code: Select all

VaultClientFolder vcf = new VaultClientFolder(vfdarray[i]); //where vfdarray[i] is an instance of VaultFolderDelta from the above statement.
vcf.get_FullPath()
The full path is always returned as null.

Since my method is recursive, I always need to find the fullpath of the children I am currently at. Note that I can get the correct version of the child folder (vfdarray[#].get_Version()) as of the version of the parent I request, just not the path of that child. (vfdarray[#].get_Name() also works)

This code should show what I mean:

Code: Select all

int count =  vfdarray.length;
for(int i =0; i< count;i++)
{
	System.out.print("\tFolder: " + vfdarray[i].get_Name());	
	System.out.print(", Version: " + vfdarray[i].get_Version());
	VaultClientFolder vcf = new VaultClientFolder(vfdarray[0]);
	System.out.println(", Path: " + vcf.get_FullPath());
}
A second thing I noticed, but haven't done much research into yet is that I cannot seem to find the objID of a deleted object.
For instance if I have an object that does exist currently at top version, I can do this:

Code: Select all

VaultClientFolder vcfolder = ServerOperations.ProcessCommandListFolder(root, false);
vcfolder.get_ID();
However, if the object has been deleted the first line above throws: Exception in thread "main" System.Exception: No object was found at the repository path

I am sure this is expected, however since your constructor for ProcessCommandGetBranchStructure requires objID, it seems you have a way of getting an ID of a deleted object. I haven't looked at this enough to see if I am just plain missing something, but if someone knows off the top of their head, that'd be great.

Thanks again!

Edit note: I changed VaultClientFile to VaultClientFolder. This was just a silly mistake, the problem remains the same however.

shannon

Re: Viewing Folder Trees in history

Post by shannon » Thu May 21, 2009 8:32 am

Ok, first thing, you shouldn't be accessing the children of the root through the VaultFolderDelta object, you should use the VaultClientFolder that was created using that delta.

Use VaultClientFolder.get_Folders() and VaultClientFolder.get_Files()

Sorry if I wasn't clear on that part.

Note that get_FullPath() may only give you a relative path, beginning at whatever root folder you chose.

You're going to have to explain to me what exactly you're trying to do with deleted objects before I can help. We don't ever use this in conjunction with deleted objects....not to mean that I won't help, just that it's uncharted territory basically.

javaguy
Posts: 10
Joined: Wed May 20, 2009 10:21 am

Re: Viewing Folder Trees in history

Post by javaguy » Thu May 21, 2009 9:13 am

shannon wrote: you shouldn't be accessing the children of the root through the VaultFolderDelta object, you should use the VaultClientFolder that was created using that delta.
> You are 100% correct. This was my misunderstanding and after I changed that it works. I was reading too much into what the contents of the VaultFolderDelta were. Apologies.
shannon wrote:Note that get_FullPath() may only give you a relative path, beginning at whatever root folder you chose.
> I noticed this, and should have a workaround for what I need.
shannon wrote:You're going to have to explain to me what exactly you're trying to do with deleted objects before I can help. We don't ever use this in conjunction with deleted objects....not to mean that I won't help, just that it's uncharted territory basically.
> I think the best way is with an example.
I wrote a recursive method which will display all the members as they exist in a repository with the version number beside them as it exists "now". If you look at my 2nd post I gave a code snippet of how this was built.

Once I print the data out I get:

Code: Select all

-> vaulttest (11)
	- fraction_decimal.html (1)
	- index.html (2)
	- welcome.html (3)
	- menu.html (2)
	-> stock (2)
		- stock.html (1)
		-> js (1)
			- stock.js (1)
I would like to be able to do the same "As Of" any revision.
What I have now is

Code: Select all

private static List<Folder> buildTreeVer(String root, long version) {
	List<Folder> allFolders = new ArrayList<Folder>();		
	VaultClientFolder vcfolder = ServerOperations.ProcessCommandListFolder(root, false);
	VaultFolderDelta vfd = ServerOperations.ProcessCommandGetBranchStructure(ServerOperations.GetRepositoryId("Initial Repository"), root, vcfolder.get_ID(), version, true);
	VaultClientFolder vcf = new VaultClientFolder(vfd, null);
	VaultClientFolderColl  coll = vcf.get_Folders();

	int count =  coll.get_Count();
	for(int i =0; i< count;i++)
	{
		VaultClientFolder curVCF = (VaultClientFolder)coll.get_Item(i);
		Folder temp = new Folder(curVCF.get_Name(), curVCF.get_FullPath(), curVCF.get_Version());
		// This is the recursive call to get the children folders
		temp.setChildren(buildTreeVer(curVCF.get_FullPath(), curVCF.get_Version()));
		// This sets The members.
		temp.setMembers(getMembers(temp.getPath()));
		allFolders.add(temp);
	}
	return allFolders;
}
Basically the exact same method except that I know what to get the path "As Of" a certain version.

So in my example above. I have a child folder of $/vaulttest called $/images which I deleted at version 7, so it doesn't appear (notice the only child folder is $/vaultest/stock appears) since the top version is now 11.

If I now call the above method like this buildTreeVer("$/vaulttest", 5);
I would like to see:

Code: Select all

-> vaulttest (5)
	- fraction_decimal.html (1)
	- index.html (1)
	- welcome.html (2)
	- menu.html (1)
 	-> images(2)
 		- myimage.gif(1)
	-> stock (2)
		- stock.html (1)
		-> js (1)
			- stock.js (1)
Since at version 5 of $/vaulttest the child folder $/vaulttest/images existed at version 2 with one child file myimage.gif at version 1.

This actually works exactly as expected for all folders that still exist at head version. (ie. for stock which exists in both version 5 and 11), but for /images which only exists at version 7 and below, I get the Exception I mentioned in my previous post.

The exception occurs on this line: "ServerOperations.ProcessCommandListFolder(root, false);" which I only have in there because I need the ObjID for the constructor you gave me, and I haven't yet found another way of finding an ObjID without that call.

What I think it boils down to is: How do I get the ObjID for a member that is deleted at head version, but has previously existed?

Apologies for the novel, but I think this explains my intent in full.

shannon

Re: Viewing Folder Trees in history

Post by shannon » Thu May 21, 2009 9:56 am

No apologies needed, I got the info I asked for :) The more I understand, the less likely I am to lead you down a path that won't work.

This is the magic method you're looking for:
VaultDeletedObject[] objs = ServerOperations.client.get_ClientInstance().ListDeletedObjects(path, false);

I think you'll want to pass the path to the parent of the item you're looking for. Then just cycle over the array to find the right object and use VaultDeletedObject.get_ID().

javaguy
Posts: 10
Joined: Wed May 20, 2009 10:21 am

Re: Viewing Folder Trees in history

Post by javaguy » Fri May 22, 2009 4:11 am

Shannon,

Thank you for your continued help! This method does exactly what is needed.

The last problem I haven't figured out is the "re-adding" of something that has been deleted.

So I have added a file "$/vaultest/folder/file" made some revisions and deleted it (say at revision 4)

Is there a way to "re-add" this to the repository using the API? I don't see this in the GUI Client or in the API.

In fact when I add a file with the same name as a deleted file in the GUI it doesn't seem to pick up that it is used to be there with the same name. Perhaps this is the way the product works, apologies if it is, as I am new to this and I couldn't find documentation that stated this either way.

Thanks,

shannon

Re: Viewing Folder Trees in history

Post by shannon » Fri May 22, 2009 8:25 am

There's code to perform an Undelete in this post here: http://support.sourcegear.com/viewtopic ... ete#p43290
The code is C#, but it's not hard to follow.

As for the GUI client behavior, I'm not sure what you expected to see, but I'll try and explain a little. When you delete an item, Vault still knows about it as a deleted object so that you can get it back (undelete it from the properties dialog of it's parent usually), but that item no longer exists in the tree. That's why ProcessCommandListFolder doesn't work on that path, it's searching the current tree and that path isn't there. When you add a new item with that name to the same location, we're going to treat it just like any other new add. If you want to continue on with the old object, you should undelete it in the GUI client....then if you need to, you can modify the contents and check it in.

javaguy
Posts: 10
Joined: Wed May 20, 2009 10:21 am

Re: Viewing Folder Trees in history

Post by javaguy » Fri May 22, 2009 9:04 am

I was searching for "readd", instead of undelete. Ignore my comments about the GUI, I was just mentioning that I didn't see this functionality there.

I implemented the method

Code: Select all

		ChangeSetItemColl items = new ChangeSetItemColl();
		VaultDeletedObject[] deletedObjects =  ServerOperations.client.get_ClientInstance().ListDeletedObjects("$/", true);   
		
        for (VaultDeletedObject d : deletedObjects)
        {
           ChangeSetItem_Undelete item = null;
           if (d != null)
           {
        	   item = new ChangeSetItem_Undelete(VaultDateTime.get_Now(), "", "", d.get_ID(), d.get_FullPath(), d.get_DeletionID()); 
        	   System.out.println("Undeleting: "+ d.get_ID() + ", " + d.get_FullPath() + ", " + d.get_DeletionID());
        	   items.Add(item);
           }            
        }
        //ServerOperations.client.get_ClientInstance().c
        boolean retVal = ServerOperations.client.get_ClientInstance().Commit(items);
        System.out.println("Success: " + retVal);
But my Success always shows false, and the members do not appear. The println does show all the deleted objects, so I assume it is a problem specifically with the way I am using Commit. I looked at the API definition(s) in C# and it wasn't obvious to me what i could change in the commit to test various combinations. Is there a way to see *why* something failed to commit?

shannon

Re: Viewing Folder Trees in history

Post by shannon » Fri May 22, 2009 9:22 am

If any one of those objects exists in the repository (i.e. was re-added) your commit will fail, but all the operations should be pended.

You can listen for progress messages:
ServerOperations.client.get_ClientInstance().EventEngine.addListener((Object)new ConsoleOutput(), "VaultClientOperationsLib.MessageEvent");
ServerOperations.client.get_ClientInstance().EventEngine.addListener((Object)new ConsoleOutput(), "VaultClientOperationsLib.BulkMessageEvent");

MessageEvent has one ProgressMessage object (MessageEvent.Message) and BulkMessageEvent has an ArrayList of ProgressMessage objects....you'll want to handle these events and print out each ProgressMessage.getMessage()

Post Reply