How to get a WorkingCopy of a hierarchy
![](http://jazz.net/_images/myphoto/66e177e2048ef539f521aa8ee20ae030.jpg)
I have gotten down to getting an IWorkingCopyManager as well as creating a new ITeamAreaHandle and getting the ITeamAreaHierarchy from the project area.
However, I am getting the ImmutablePropertyException on the teamHierarchy.addRoot(teamAreaHandle, timeline).
I assume this is because I have the hierarchy and not a hierarchyWorkingCopy (if one exists).
Has anyone done this that they could share a snippet?
Susan
3 answers
![](http://jazz.net/_images/myphoto/66e177e2048ef539f521aa8ee20ae030.jpg)
<code>
// note, this function ASSUMES it has the destination projectarea working copy on input
ITeamAreaHierarchy srchierarchy = iprja_src.getTeamAreaHierarchy();
ITeamAreaHierarchy desthierarchy = iprja_dest.getTeamAreaHierarchy();
// allocate work area for list of changed/created timelines and
// iterations
// will be used to update the repository all at once when we are
// done.
ArrayList<IProcessItem> newitemlist = new ArrayList<IProcessItem>();
// add the project to the list
newitemlist.add((new IProcessItem[]
{ iprja_dest })[0]);
// loop thru the team areas
for (ITeamAreaHandle baseteam : new ArrayList<ITeamAreaHandle>(srchierarchy.getRoots()))
{
processchildTeamAreas(newitemlist, srcauditableClient, destauditableClient, iprja_src, iprja_dest,
srchierarchy, desthierarchy, baseteam, null);
}
// allocate space for the array
IProcessItem[] ilist = new IProcessItem[newitemlist.size()];
// build the array
ilist = newitemlist.toArray(ilist);
// save all the new/modified objects to the repository
try
{
destprocessItemClient.save(ilist, null);
}
catch (Exception ex)
{
if (!ex.getMessage().contains("Cannot have two team areas with the name"))
System.out.println("Exception=" + ex.getMessage());
}
/////
private static void processchildTeamAreas(ArrayList<IProcessItem> newitemlist,
IAuditableClient srcauditableClient, IAuditableClient destauditableClient, IProjectArea srcproject,
IProjectArea destproject, ITeamAreaHierarchy srchierarchy, ITeamAreaHierarchy desthierarchy,
ITeamAreaHandle baseteam, ITeamAreaHandle parent)
{
try
{
// get the full object to see the name field
IDevelopmentLine srcdevline = (IDevelopmentLine) srcauditableClient.fetchCurrentAuditable(
srchierarchy.getDevelopmentLine(baseteam),
ItemProfile.createFullProfile(IDevelopmentLine.ITEM_TYPE), null);
// get the full object to see the name field
ITeamArea srcteamarea = (ITeamArea) srcauditableClient.fetchCurrentAuditable(baseteam,
ItemProfile.createFullProfile(ITeamArea.ITEM_TYPE), null);
// don't copy archived team areas
if(!srcteamarea.isArchived())
{
System.out.println("src timeline and team area = '"+srcdevline.getId()+"' and '"+srcteamarea.getName()+"'");
ITeamArea destTeamArea = (ITeamArea) ITeamArea.ITEM_TYPE.createItem();
destTeamArea.setName(srcteamarea.getName());
destTeamArea.setProcessName(srcteamarea.getProcessName());
destTeamArea.setProcessSummary(srcteamarea.getProcessSummary());
destTeamArea.setProjectArea(destproject);
destTeamArea.getDescription().setSummary(srcteamarea.getDescription().getSummary()); //new
destTeamArea.getDescription().setDetails(copycontent(srcteamarea.getDescription().getDetails(),((ITeamRepository)srcproject.getOrigin()).contentManager())); //new
// add the new team area to the list of modified objects
newitemlist.add((new IProcessItem[]
{ destTeamArea })[0]);
// find the matching development line on the target system
IDevelopmentLineHandle destline = getmatchingDevline(srcdevline.getName(), destproject, destauditableClient);
if (destline != null)
{
// desthierarchy.setDevelopmentLine(destTeamArea, destline);
// is this a root timeline?
if (parent == null)
{
// use it.
// desthierarchy.setDevelopmentLine(destTeamArea, destline);
desthierarchy.addRoot(destTeamArea, destline);
}
// nope add us to the parent
else
desthierarchy.addChild(parent, destTeamArea);
// get the list of members in the src team area
for (IContributorHandle srcteammember : srcteamarea.getMembers())
{
// get the full object to see the name field
IContributor srcmember = (IContributor) srcauditableClient.fetchCurrentAuditable(srcteammember,
ItemProfile.createFullProfile(IContributor.ITEM_TYPE), null);
// find the matching dest system user
try
{
IContributorHandle destuser = destauditableClient.getTeamRepository().contributorManager()
.fetchContributorByUserId(srcmember.getEmailAddress(), null);
// if found, add to the team area
destTeamArea.addMember(destuser);
RolePersistence.setPersistedRoleData(destTeamArea.getTeamData(), destuser,
RolePersistence.getPersistentRoleData(srcteamarea.getTeamData(), srcteammember));
}
catch (Exception ex)
{
System.out.println("unable to find user with email="+srcmember.getEmailAddress());
}
}
}
if (srchierarchy.getChildren(baseteam).size() > 0)
{
// loop thru the list of team areas
for (ITeamAreaHandle childteam: (ITeamAreaHandle[])srchierarchy.getChildren(baseteam).toArray(new ITeamAreaHandle[1]))
{
// process for any children, recursively
processchildTeamAreas(newitemlist, srcauditableClient, destauditableClient, srcproject,
destproject, srchierarchy, desthierarchy, childteam, destTeamArea);
}
}
}
}
catch (TeamRepositoryException e1)
{
// TODO Auto-generated catch block
e1.printStackTrace();
}
}
private static IContent copycontent(IContent in, IContentManager icm)
{
IContent out = null;
// get the content of the content object.
try
{
if (in != null)
{
IAuditableCommon auditable = (IAuditableCommon) destauditableClient.getTeamRepository().getClientLibrary(
IAuditableCommon.class);
// make an output stream for the content manager
OutputStream os = new ByteArrayOutputStream();
// get the content of the content object.
icm.retrieveContent(in, os, null);
// extract the bytes, need the object twice
byte[] bytes = os.toString().getBytes(in.getCharacterEncoding());
// make a content object on the destination system
out=auditable.storeContent(in.getContentType(), in.getCharacterEncoding(), new ByteArrayInputStream(bytes),
bytes.length, null);
}
}
catch (Exception e)
{
e.printStackTrace();
}
return out;
}
private static IDevelopmentLineHandle getmatchingDevline(String prodname, IProjectArea destproject,
IAuditableClient destauditableClient)
{
IDevelopmentLineHandle foundline = null;
// loop thru the list of timelines
for (IDevelopmentLineHandle destlineh: destproject.getDevelopmentLines())
{
try
{
// get the full profile, so we can get the name field
IDevelopmentLine destline = (IDevelopmentLine) destauditableClient.fetchCurrentAuditable(destlineh,
ItemProfile.createFullProfile(IDevelopmentLine.ITEM_TYPE), null);
// if the target project timeline name matches the one in
// the prod team area
if (destline.getName().equalsIgnoreCase(prodname))
{
foundline = destlineh;
break;
}
}
catch (TeamRepositoryException e)
{
// TODO Auto-generated catch block
e.printStackTrace();
}
}
return foundline;
}
</code>
Comments
![](http://jazz.net/_images/myphoto/66e177e2048ef539f521aa8ee20ae030.jpg)
Thanks Sam .. this works fine ... however, I don't see that the Summary and Description of the team area is being duplicated over.
I attempted to add something in the block with
destTeamArea.setName(srcteamarea.getName());
destTeamArea.setProcessName(srcteamarea.getProcessName());
...
but while I can get the description using srcteamarea.getDescription(); I didnt' see a setDescription() on the destTeamArea object. Is that correct? Is there any way to do this? We use the Description field for ALOT of things, so I really need to find a way to get that over as well.
Susan
![](http://jazz.net/_images/myphoto/d0f7b0b7bfc90721959d790b8a9bf79f.jpg)
yeh, I didn't find it either. and getDescription() returns an IDescription object, not String.
there must be a way however as the UI does it.. I looked thru the code for the team area editor, but its as obtuse as ever.
the TeamArea object has setDescDetails, and setDescSummary,
which match the fields in the IDescription object.
![](http://jazz.net/_images/myphoto/66e177e2048ef539f521aa8ee20ae030.jpg)
So I don't have any type of setDesc* methods on the ITeamArea that I can see in my eclipse, perhaps those were added more recently than 4.0.5?
As well, I have this working (NICE!) with the exception of the Description and Summary, which I'm looking into more.
![](http://jazz.net/_images/myphoto/d0f7b0b7bfc90721959d790b8a9bf79f.jpg)
note that I said 'TeamArea' NOT ITeamArea..
the interface, ITeamArea, does not have methods
the implementation class, TeamArea, does
I think its moot now, as the IDescription object can be accessed to set the fields and
on (process/team) area save its values are used.
![](http://jazz.net/_images/myphoto/66e177e2048ef539f521aa8ee20ae030.jpg)
Well, except that so far, I can getDescription() to get the IDescription object, but again, I can't set the values that I want, nor can I seem to set the description back into the team area.
![](http://jazz.net/_images/myphoto/d0f7b0b7bfc90721959d790b8a9bf79f.jpg)
see my answer below
![](http://jazz.net/_images/myphoto/66e177e2048ef539f521aa8ee20ae030.jpg)
The code looks funny.....
Comments
![](http://jazz.net/_images/myphoto/d0f7b0b7bfc90721959d790b8a9bf79f.jpg)
if (area == null) { System.out.println("Trying to create Project Area: " + projectName); area = service.createProjectArea(); area.setName(projectName); area.setProcessDefinition(processDefinition); IDescription description = area.getDescription(); description.setSummary("Project to be used running the RTC Extension Workshop"); area = (IProjectArea) service.save(area, monitor); some apis are by value (get/set) and some are by reference.(access thru )
there is NO indication that the IDescription object is by reference
how does get/setSummary relate to the IDescription object Summary field?
as setSummary is not deprecated.
![](http://jazz.net/_images/myphoto/66e177e2048ef539f521aa8ee20ae030.jpg)
destTeamArea.setName(srcteamarea.getName());
destTeamArea.setProcessName(srcteamarea.getProcessName());
destTeamArea.setProcessSummary(srcteamarea.getProcessSummary());
destTeamArea.setProjectArea(destproject);
destTeamArea.getDescription().setSummary(srcteamarea.getDescription().getSummary()); //new
destTeamArea.getDescription().setDetails(copycontent(srcteamarea.getDescription().getDetails(),((ITeamRepository)srcproject.getOrigin()).contentManager())); //new
////
worker function
private static IContent copycontent(IContent in, IContentManager icm)
{
IContent out = null;
// get the content of the content object.
try
{
if (in != null)
{
IAuditableCommon auditable = (IAuditableCommon) destauditableClient.getTeamRepository().getClientLibrary(
IAuditableCommon.class);
// make an output stream for the content manager
OutputStream os = new ByteArrayOutputStream();
// get the content of the content object.
icm.retrieveContent(in, os, null);
// extract the bytes, need the object twice
byte[] bytes = os.toString().getBytes(in.getCharacterEncoding());
// make a content object on the destination system
out=auditable.storeContent(in.getContentType(), in.getCharacterEncoding(), new ByteArrayInputStream(bytes),
bytes.length, null);
}
}
catch (Exception e)
{
e.printStackTrace();
}
return out;
}
Comments
![](http://jazz.net/_images/myphoto/66e177e2048ef539f521aa8ee20ae030.jpg)
Yea, I had went down this path a few days ago already. At the same place I create the TeamArea and set it's name, I attempted to set the Summary and Details from the srcteamarea:
IDescription x = srcteamarea.getDescription();
IDescription y = destTeamArea.getDescription();
y.setSummary(x.getSummary());
y.setDetails(x.getDetails());
I'm on the same server, so I just did a straight setSummary() and setDetails() from the Summary and Details directly in the srcteamarea. However, the setDetails() call gets
com.ibm.team.repository.common.internal.ImmutablePropertyException
![](http://jazz.net/_images/myphoto/d0f7b0b7bfc90721959d790b8a9bf79f.jpg)
the code above worked perfectly, copy team area from project a to project b, including the description.
you of course have to have the working copy of the destination project area.
![](http://jazz.net/_images/myphoto/d0f7b0b7bfc90721959d790b8a9bf79f.jpg)
Susan, did this work for you? I updated the code in the 1st answer as well.