It's all about the answers!

Ask a question

How to get a WorkingCopy of a hierarchy


Susan Hanson (1.6k2201194) | asked Jun 13 '14, 9:06 a.m.
I am working on re-creating a team hierarchy from one project area to another.

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



permanent link
sam detweiler (12.5k6195201) | answered Jun 13 '14, 9:36 a.m.
edited Jun 18 '14, 8:08 a.m.
here is some code I have for that  copy team area from src project (and server maybe) to dest project (and server maybe)

<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
Susan Hanson commented Jun 13 '14, 9:41 p.m.

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


sam detweiler commented Jun 14 '14, 7:41 a.m. | edited Jun 14 '14, 7:51 a.m.

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.


Susan Hanson commented Jun 16 '14, 9:28 a.m.

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.


sam detweiler commented Jun 16 '14, 9:45 a.m.

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.


Susan Hanson commented Jun 16 '14, 10:24 a.m.

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.


sam detweiler commented Jun 16 '14, 10:39 a.m.

see my answer below

showing 5 of 6 show 1 more comments

permanent link
Ralph Schoon (63.6k33646) | answered Jun 13 '14, 9:21 a.m.
FORUM ADMINISTRATOR / FORUM MODERATOR / JAZZ DEVELOPER
Please have a look into the snippets that come with the Plain Java Client Libraries. There is some explanation here too: https://rsjazz.wordpress.com/2013/09/18/deploying-templates-and-creating-projects-using-the-plain-java-clients-library/

The code looks funny.....

Comments
sam detweiler commented Jun 16 '14, 9:42 a.m. | edited Jun 16 '14, 9:46 a.m.
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.

permanent link
sam detweiler (12.5k6195201) | answered Jun 16 '14, 10:33 a.m.
edited Jun 17 '14, 9:19 a.m.
this should be the new code.. (tested on same repo) (my code assumes different rtc repos all the time)

                    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
Susan Hanson commented Jun 17 '14, 8:09 a.m.

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


sam detweiler commented Jun 17 '14, 9:14 a.m.

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.


sam detweiler commented Jun 18 '14, 8:06 a.m. | edited Jun 18 '14, 8:09 a.m.

Susan, did this work for you? I updated the code in the 1st answer as well.

Your answer


Register or to post your answer.


Dashboards and work items are no longer publicly available, so some links may be invalid. We now provide similar information through other means. Learn more here.