It's all about the answers!

Ask a question

copy plans in project to a different project, help


sam detweiler (12.5k6195201) | asked Mar 04 '14, 7:17 a.m.
edited Mar 04 '14, 11:36 p.m. by Sreerupa Sen (1.0k4)
in our project copy utility, I support copying plans from one project to another.  One area not copied is the plan views.

(maybe called Plan Modes).

anyone played with accessing these thru a plainjava application? I don't want to 'present' them, just copy their data to
another plan.

I 'think' based on looking at the plan editor code, I need access to the IterationPlanData object, which can be retrieved thru the IIterationPlan.  but attemping this on a Release Backlog plan

IterationPlanData prodpd= ((IterationPlanClient)prodplanClient).fetchIterationPlanData((IIterationPlanRecordHandle) prodipr.getItemHandle(), new mylog());

gets me a fatal exception error

Reference problem: Unable to find IPlanCheckDescription with id com.ibm.team.apt.plancheck.requiredAttribute.

Comments
Ralph Schoon commented Mar 05 '14, 5:59 a.m.
FORUM ADMINISTRATOR / FORUM MODERATOR / JAZZ DEVELOPER

Unfortunately I never tried that. You are in an area that is mostly internal API today.

3 answers



permanent link
Dimitrios Dentsas (7348) | answered Mar 12 '14, 6:53 a.m.
edited May 07 '14, 12:24 p.m.
Hi Sam,

did you resolve your Exception Error? I can't tell you about the Plain Java API but with the RTC SDK the following can be used  (may also work with the Plain API).


// The iteration plan record of the target plan you created


IIterationPlanRecord iterationPlanRecord = ...;

List<ISharedPlanMode> sharedPlanModes = new ArrayList<ISharedPlanMode>();

// IterationPlanData of the target plan record
IterationPlanData data = fPlanClient.fetchIterationPlanData((IIterationPlanRecordHandle)iterationPlanRecord.getItemHandle(), monitor);

// Get the XML structure of the sharedPlanMode object from source plan you want to copy
XMLMemento mementoOutput= XMLMemento.createWriteRoot(IStore.ROOT);
ConfigurationElementFactory.serializeIntoConfigData(sourceSharedPlanMode.getDescription(), mementoOutput);

// Create the target sharedPlanMode from the XML memento
ISharedPlanMode targetSharedPlanMode = createSharedPlanMode(data, mementoOutput);
// add it to the list of plan modes
sharedPlanModes.add(targetSharedPlanMode );

// Create the plan modes in the target plan
fPlanClient.saveSharedPlanModeDescription(sharedPlanModes, monitor).get(0);


and the createSharedPlanMode method could looks like this:

private ISharedPlanMode createSharedPlanMode(IterationPlanData data, XMLMemento memento) {


        ResolvedPlanMode planMode = data.getPlanModes().get(data.getPlanModes().size()-1);

       
        ISharedPlanMode sharedPlanModeCopy= (ISharedPlanMode) planMode.getSharedPlanMode().getWorkingCopy();
        ISharedPlanMode sharedPlanMode = (ISharedPlanMode) ISharedPlanMode.ITEM_TYPE.createItem(planMode.getSharedPlanMode());
        try {
            sharedPlanMode.setDescription(((XMLMemento)memento).asXMLString());
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        sharedPlanMode.setOwner(data.getOwner());
        sharedPlanMode.setPlan(sharedPlanModeCopy.getPlan());
       
        return sharedPlanMode;
       
    }

Comments
sam detweiler commented Mar 12 '14, 7:06 a.m.

I have not solved my problem, but thank you SO much.. I will report back as soon as I can..


sam detweiler commented Mar 12 '14, 9:24 a.m.

I have started integrating you code into my app.. I have some questions/comments


1.  as written you function can only work on the same system, not across systems
    (only one plan client handle, plan owner not checked across system, target plan loaded from source system. 
           sharedPlanMode.setOwner(data.getOwner()); 
        sharedPlanMode.setPlan(sharedPlanModeCopy.getPlan());
2.  it looks like you only copy 1 plan view.. do u assume only one needs to be copied. 
     there is no loop around sharedPlanModes.add(targetSharedPlanMode );
3. in the subroutine, I do not undestand
    ResolvedPlanMode planMode = data.getPlanModes().get(data.getPlanModes().size()-1);

why get only the last planmode everytime?




Dimitrios Dentsas commented Mar 12 '14, 10:39 a.m.

Hi Sam,
1. My code from above is modified a little bit for simplicity. What I am really doing is exporting/importing plans and their planmodes to/from XML files that can be imported to remote systems, that's why you don't see the connection in code.

2. As in 1. I left the loop out for simplicity :). It loops around the referenced planmodes from the XML structure I'm reading in and creates multiple targetSharedPlanModes.

3. That's a tricky one. As far as I can tell, the data.getPlanModes list is not merely a collection of the different planmodes but also of their different versions in time of which all entries except the last one are marked as "dirty" because they are not the latest. When I am not fetching the last entry it throws an exception warning me of stale data.

I am getting this last entry in order to instantiate a new ISharedPlanMode from it. Maybe there is a better way, but this is how I got it working quickly.


sam detweiler commented Mar 12 '14, 10:52 a.m.

 yes, indeed 3 depends on info I wouldn't have guessed


but then I don't see the rest of the views.. only 1. 
if PlanData.getPlanModes() returns the iterations of a view. 


Dimitrios Dentsas commented Mar 12 '14, 11:13 a.m.

Did you try this out only with newly created plans, or with existing ones (for which you already tampered with the views).

I think for new plans it just shows the first iteration and for views that already have a modified version of planmodes it shows more than one.


sam detweiler commented Mar 12 '14, 11:40 a.m.

the source project has a number of custom views, which may have multiple iterations, no way of knowing


I still have the exception trying to load the plandata for the newly created plan. 

last thing I did 
            DTO_IterationPlanSaveResult saveResult = planService.save(project, plan, wiki);
            if (saveResult.isSetIterationPlanRecord() == false)
            {
                System.out.println("Saving failed!");
            }
            else
            {
            newplanRecord=saveResult.getIterationPlanRecord();
            }
and fetch on the newplanRecord fails


Dimitrios Dentsas commented Mar 12 '14, 1:33 p.m.
Hmm, I tried creating a Release Plan with your method and it works for me. However I am creating a new IIterationPlanRecord every time.

It would be interesting to see how the IIterationPlanRecord you are trying to save using the planService looks like. Is it fetched from some origin or newly created? Judging from your original answer there seems to be some plancheck reference that cannot be found. Does this plan come with customized plan views?


Another possibility could be a difference of the client/server services we are using. I am working with the SDK and fetching e.g. my IterationPlanClient from 
com.ibm.team.apt.internal.client.*. I am not sure how different it is in the Plain API.



sam detweiler commented Mar 12 '14, 2:05 p.m. | edited Mar 12 '14, 2:38 p.m.

my code posted below. this is an arbitrary plan or arbitrary age, in an arbitrary RTC system  (first was 3.01, second is 4.0.1, others to come)   end system is 4.0.4


the IIterationPlanClient.class will load as a client lib
the IterationPlanClient.class will not load as a client lib.

so this means there is only 1. 

the plan classes are not supplied with the plain java libs.. only in the SDK (as they are not published yet)  so, there is only one set. 

showing 5 of 8 show 3 more comments

permanent link
sam detweiler (12.5k6195201) | answered Mar 12 '14, 2:00 p.m.
edited Mar 12 '14, 4:26 p.m.
 here is my plan  copy code, objective is live, across systems.(source/prod and target/dev, need to cleanup the names all over)

            IIterationPlanClient prodplanClient = (IIterationPlanClient) productionServer
                    .getClientLibrary(IIterationPlanClient.class);

            IIterationPlanClient devplanClient = (IIterationPlanClient) devServer
                    .getClientLibrary(IIterationPlanClient.class);

                // get all the iterationplans (at the repository, not project)!
                List<IIterationPlanRecordHandle> prodphandles = ((IterationPlanClient) prodplanClient)
                        .fetchAllIterationPlans(ItemProfile.ITERATION_DEFAULT, null);
                List<IIterationPlanRecord> proditall = productionServer.itemManager().fetchCompleteItems(prodphandles,
                        IItemManager.REFRESH, null);
                // get all the iterationplans (at the repository, not project)!
                List<IIterationPlanRecordHandle> devphandles = ((IterationPlanClient) devplanClient)
                        .fetchAllIterationPlans(ItemProfile.ITERATION_DEFAULT, null);
                List<IIterationPlanRecord> devitall = devServer.itemManager().fetchCompleteItems(devphandles,
                        IItemManager.REFRESH, null);                

                System.out.println(" there are " + prodphandles.size() + " plans available and " + proditall.size()
                        + " records on the source server");

                System.out.println(" there are " + devphandles.size() + " plans available and " + devitall.size()
                        + " records on the target server");
                // loop thru the developement lines to find the right iteration
                // on the source system
                for (IDevelopmentLineHandle dlh : iprja_prod.getDevelopmentLines())
                {
                    IDevelopmentLine dl = (IDevelopmentLine) prodauditableClient.fetchCurrentAuditable(dlh,
                            ItemProfile.createFullProfile(IDevelopmentLine.ITEM_TYPE), null);
                    if (!dl.isArchived())
                    {
                        // loop thru all the plan records
                        for (IIterationPlanRecord ipr : proditall)
                        {
                            // get the process area owner
                            IProcessArea ipa = (IProcessArea) prodauditableClient.resolveAuditable(ipr.getOwner(),
                                    ItemProfile.createFullProfile(IProcessArea.ITEM_TYPE), null);

                            // make sure this plan is for this project
                            if (ipa.getProjectArea().sameItemId(iprja_prod))
                            {
                                // get the iteration record
                                IIteration prodipriteration = (IIteration) prodauditableClient.fetchCurrentAuditable(
                                        ipr.getIteration(), ItemProfile.createFullProfile(IIteration.ITEM_TYPE), null);
                                // don't copy for archived iterations
                                if (!prodipriteration.isArchived())
                                {
                                    // make sure this plan is for this timeline
                                    if (dl.sameItemId(prodipriteration.getDevelopmentLine()))
                                    {
                                        @SuppressWarnings("deprecation")
                                        IProcessAreaHandle planteam = ipr.getTeamArea();
                                        String teamname = "undefined";
                                        IProcessArea iprta = iprja_dev;
                                // if there is a team area
                                        if (planteam != null)
                                        {
                                            try
                                            {
                                            // find it here ont he target system
                                                iprta = findDevTeamArea(ipa.getName(), iprja_dev, devauditableClient);
                                                teamname = iprta.getName();
                                                planteam = iprta;
                                            }
                                            catch (Exception ex)
                                            {
                                            // oops use the default
                                                teamname = "undefined";
                                                iprta = iprja_dev;
                                                //continue;
                                            }
                                        }
                                        else
                                        {
                                        // use the project area
                                            teamname = iprja_dev.getName();
                                            planteam = iprja_dev;

                                        }

                                        IIterationHandle devipriteration = null;
                                        for (IDevelopmentLineHandle devlh : iprja_dev.getDevelopmentLines())
                                        {
                                            // get the production object details
                                            IDevelopmentLine idvl = (IDevelopmentLine) devauditableClient
                                                    .fetchCurrentAuditable(devlh,
                                                            ItemProfile.createFullProfile(IDevelopmentLine.ITEM_TYPE),
                                                            null);
                                            // get the iteration on the target system
                                            devipriteration = findDevIteration(devauditableClient,
                                                    idvl.getIterations(), prodipriteration.getId());
                                            if (devipriteration != null) 
                                            break;
                                        }
                                        // if we found the target system iteration
                                        if (devipriteration != null)
                                        {
                                        // and the plan doesn't already exist
                                            if(!planAlreadyExists(ipr.getName(), devipriteration, devitall,planteam))
                                            {
                                            // tell the user
                                                System.out.println("new Plan = '" + ipr.getName() + "' connects team '"
                                                        + teamname

                                                        + "' and iteration '" + prodipriteration.getName() + "' plan type="
                                                        + ipr.getPlanType());
                                                // create the plan
                                           IIterationPlanRecord targetPlan=createPlan(
                                                   devauditableClient,
                                                   iprja_dev,
                                                   ipr.getName(),
                                                   devipriteration,
                                                   ipr.getPlanType(),
                                                   planteam,
                                                   getContent(ipr.getAuxiliaryData(), prodauditableClient
                                                           .getTeamRepository().contentManager()), devauditableClient
                                                           .getTeamRepository().loggedInContributor());
                                           if(targetPlan!=null)
                                           {
                                            CopyPlanViews(ipr, targetPlan,(IterationPlanClient)prodplanClient,(IterationPlanClient)devplanClient );
                                           }
                                            }
                                            else
                                            System.out.println("Plan already exists ="+ipr.getName()+" iteration="+prodipriteration.getName());
                                        }
                                    }
                                }
                            }
                        }
                    }
                }

    public static IIterationPlanRecord createPlan(IAuditableClient devauditableClient, IProjectArea project, String planName,
            IIterationHandle planIteration, String planType, IItemHandle planTeam, String planinfo, IContributor creator)
    {

    IIterationPlanRecord newplanRecord=null;
        // get classes for plan creation
        IAuditableCommon audit = (IAuditableCommon) devauditableClient.getTeamRepository().getClientLibrary(
                IAuditableCommon.class);
        IIterationPlanService planService = (IIterationPlanService) ((IClientLibraryContext) devauditableClient
                .getTeamRepository()).getServiceInterface(IIterationPlanService.class);
        
        // create necessary plan items
        IIterationPlanRecord plan = (IIterationPlanRecord) IIterationPlanRecord.ITEM_TYPE.createItem();

        IWikiPage wiki = (IWikiPage) IWikiPage.ITEM_TYPE.createItem();

        // setup plan values
        plan.setName(planName);
        plan.setIteration(planIteration);
        plan.setPlanType(planType);
        plan.setOwner((IProcessAreaHandle) planTeam);

        // setup wiki page
        wiki.setName("entry " + planName);
        wiki.setWikiID(IIterationPlanRecord.OVERVIEW_PAGE_ID);
        wiki.setCreator(creator);
        wiki.setOwner(plan);

        String encoding = "UTF8";
        String xmlText = "<p>test</p>";
        byte[] bytes;
        try
        {
            InputStream inputStream = null;
            if (planinfo != null)
            {
                bytes = planinfo.getBytes(encoding);

                inputStream = new ByteArrayInputStream(bytes);

                plan.setAuxiliaryData(audit.storeContent(IContent.CONTENT_TYPE_TEXT, encoding, inputStream,
                        bytes.length, null));
            }

            bytes = xmlText.getBytes(encoding);

            inputStream = new ByteArrayInputStream(bytes);

            wiki.setContent(audit.storeContent(IContent.CONTENT_TYPE_TEXT, encoding, inputStream, bytes.length, null));
            // save plan
            DTO_IterationPlanSaveResult saveResult = planService.save(project, plan, wiki);
            if (saveResult.isSetIterationPlanRecord() == false)
            {
                System.out.println("Saving failed!");
            }
            else
            {
            newplanRecord=saveResult.getIterationPlanRecord();
            }
        }
        catch (Exception e)
        {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        return newplanRecord;

    }

and the new copy plan views code, based on your contribution

the lines marked xxxx are the ones that blow up. 
the copied plan shows up on the target system project in the right place with the right structure..

    private static void CopyPlanViews(IIterationPlanRecord sourcePlan,IIterationPlanRecord targetPlan , IterationPlanClient prodplanClient,  IterationPlanClient devplanClient)
    {
    // storage for the new plan views to be added to the target plan
    List<ISharedPlanMode> targetsharedPlanModes = new ArrayList<ISharedPlanMode>();
    try
    {    
    // plan data for the target plan
xxxx     IterationPlanData targetPlandata = devplanClient.fetchIterationPlanData((IIterationPlanRecordHandle)targetPlan.getItemHandle(), null);

    // IterationPlanData of the source plan record
xxxx     IterationPlanData sourcePlandata = prodplanClient.fetchIterationPlanData((IIterationPlanRecordHandle)sourcePlan.getItemHandle(), null);

    // loop thru the views
    for(ResolvedPlanMode sourceResolvedPlanMode:sourcePlandata.getPlanModes())
    {    

    // Get the XML structure of the sharedPlanMode object from source plan you want to copy
    XMLMemento mementoOutput= XMLMemento.createWriteRoot(IStore.ROOT);
    ConfigurationElementFactory.serializeIntoConfigData(sourceResolvedPlanMode.getDescription(), mementoOutput);
    // Create the target sharedPlanMode from the XML memento
    ISharedPlanMode targetSharedPlanMode = createSharedPlanMode( targetPlandata, mementoOutput);
    // add it to the list of plan modes
    targetsharedPlanModes.add(targetSharedPlanMode );
    }
   
    // Create the plan modes in the target plan
    devplanClient.saveSharedPlanModeDescription(targetsharedPlanModes, null);
      
    }
    catch(Exception ex)
    {
    System.out.println("Plan data exception ="+ex.getMessage());
    }
    }
    private static ISharedPlanMode createSharedPlanMode(IterationPlanData targetPlanData, XMLMemento memento) 
    {
    // get the plan view
        ResolvedPlanMode planMode = targetPlanData.getPlanModes().get(targetPlanData.getPlanModes().size()-1);
        // get the working copy
        ISharedPlanMode sharedPlanModeCopy= (ISharedPlanMode) planMode.getSharedPlanMode().getWorkingCopy();
        // reate a new view object
        ISharedPlanMode sharedPlanMode = (ISharedPlanMode) ISharedPlanMode.ITEM_TYPE.createItem(planMode.getSharedPlanMode());
        try 
        {
        // set its description (must be the format) 
            sharedPlanMode.setDescription(((XMLMemento)memento).asXMLString());
        } catch (IOException e) 
        {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        // set the view owner same as the plan
        sharedPlanMode.setOwner(targetPlanData.getOwner());
        // set the plan name 
        sharedPlanMode.setPlan(sharedPlanModeCopy.getPlan());
        // return new object to caller
        return sharedPlanMode;
    }  

Comments
Dimitrios Dentsas commented Mar 12 '14, 2:59 p.m. | edited Mar 12 '14, 3:18 p.m.
First point I noticed:

Your createPlan method code is almost identical to mine. What I don't have and what throws an exception for me as well when I try to fetch the IterationPlanData is the plan.setAuxiliaryData part. What does it do?


Can you comment that out and try to fetch the IterationPlanData again right after the plan has been saved?

Edit1: What was also important for me was to not provide null as ProgressMonitor parameter for the fetchIterationPlanData method but something like NullProgressMonitor.
Edit2: Ok, so based on what you have provided and my suggestion I was able to transfer the plan views between two plans in the same ProjectArea.


sam detweiler commented Mar 12 '14, 3:42 p.m. | edited Mar 12 '14, 3:43 p.m.
no idea what the setauxdata does, but assumed it was important!..

I get null pointer exception  loading the plan data after commenting that out




permanent link
Dimitrios Dentsas (7348) | answered Mar 12 '14, 4:07 p.m.
edited Mar 12 '14, 4:13 p.m.
This is how I am calling your code with setauxdata commented out, sourceRepo = targetRepo and providing "new NullProgressMonitor()" instead of null for the fetchIterationPlanData method:

private IAuditableClient fAuditableClient;
private ImportPlanConfigurationPage fMainPage;
private IProjectAreaHandle fProjectAreaHandle;
private ITeamRepository fTeamRepository;
private IProcessItemService fProcessItemService;
private IterationPlanClient fPlanClient;

// skip irrelevant parts

fProjectAreaHandle = ...; // You have to provide this
fTeamRepository = (ITeamRepository) fProjectAreaHandle.getOrigin();
fAuditableClient = (IAuditableClient) fTeamRepository
.getClientLibrary(IAuditableClient.class);
fProcessItemService = (IProcessItemService) fTeamRepository
.getClientLibrary(IProcessItemService.class);
fPlanClient = (IterationPlanClient) PlanningClientPlugin.getIterationPlanClient(fTeamRepository);
try {
IProjectArea projectArea = (IProjectArea) fTeamRepository.itemManager().fetchCompleteItem(
fProjectAreaHandle, IItemManager.DEFAULT, null);
IContributor contributor = (IContributor) fTeamRepository.itemManager().fetchCompleteItem(
fAuditableClient.getUser(), IItemManager.DEFAULT, null);
                         // getPlannedForIteration and getTeamArea are just convinience methods you can exchange                                 //them with whatever you have for providing Iteration and ProcessArea/TeamArea
IIterationPlanRecord planRecord = createPlan(fAuditableClient, projectArea,  "TestPlan3", getPlannedForIteration(projectArea.getName(), "Implementation"),
PlanTypeIds.PROJECT_RELEASE_PLAN_ID, getTeamArea(fProjectAreaHandle, "TeamAreaC", ITeamArea.class), "abc",
contributor);
IIterationPlanRecord planRecord2 = createPlan(fAuditableClient, projectArea,  "TestPlan4", getPlannedForIteration(projectArea.getName(), "Implementation"),
PlanTypeIds.ITERATION_PLAN_ID, getTeamArea(fProjectAreaHandle, "TeamAreaB", ITeamArea.class), "abc",
contributor);
CopyPlanViews(planRecord, planRecord2, fPlanClient, fPlanClient);
} catch (TeamRepositoryException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}

Comments
sam detweiler commented Mar 12 '14, 4:17 p.m.
well, isn't that interesting..  I just commented out the plan.setauxdata in createPlan(). 

I noticed the code I posted has an empty exception handler in the copyplanviews

            catch(Exception ex)
            {
                    
            }

change to
            catch(Exception ex)
            {
                    System.out.println("Plan data exception ="+ex.getMessage());
            }

sam detweiler commented Mar 19 '14, 9:18 a.m.
a little more info..  
// IterationPlanData of the source plan record
IterationPlanData sourcePlandata = prodplanClient.fetchIterationPlanData((IIterationPlanRecordHandle)sourcePlan.getItemHandle(), null);

MUST have a non-null monitor... else u get null pointer exception
you MUST have the IScriptEngine class accessible

but still I get exception

Plan data exception =Reference problem: Unable to find IPlanModeDescription with id com.ibm.team.apt.viewmodes.internal.backlog.product.

so I am missing some data I think

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.