Is it possible to migrate an RTC Project Area to a different Process Parent programmatically?
Accepted answer
| this only does one project at a time, or ALL that have a parent (use * as the current project name)
but you could modify it to take a list, or discover which one need to be modified, or.. many other ways..
uses the client api
parms are server userid password project_name_to_change new_parent_project_name
package com.sd.tools;
import java.io.ByteArrayOutputStream;
import java.io.FileOutputStream;
import java.io.OutputStream;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import org.eclipse.core.runtime.IProgressMonitor;
import com.ibm.team.repository.client.IContentManager;
import com.ibm.team.repository.client.IItemManager;
import com.ibm.team.repository.client.ITeamRepository;
import com.ibm.team.repository.client.TeamPlatform;
import com.ibm.team.repository.common.IContent;
import com.ibm.team.repository.common.TeamRepositoryException;
import com.ibm.team.process.client.*;
import com.ibm.team.process.common.IProjectArea;
import com.ibm.team.process.common.IProjectAreaHandle;
import com.ibm.team.process.internal.common.impl.ProjectAreaImpl;
@SuppressWarnings("restriction")
public class GetProjectSource
{
/**
* key used to store project process configuration source
*/
static String keyname = "com.ibm.team.internal.process.compiled.xml";
public static void main(String[] args)
{
String url = null; // repository address
String userid = null; // userid
String password = null; // password
String ProjectType = null; // * or name of project
String newProjectParent = null; // name of new process parent project,
// optional
if (args.length < 4)
{
System.out.println("Parameters are" +
"URL of repository\n" +
"Userid of Admin user\n" +
"Password of Admin user\n"+
"project scope\n" +
" * for all projects (save all project source)\n" +
" specific Name of project to locate\n" +
"\n" +
"optional:\n" +
" new parent project name"
);
return;
}
url = args[0];
userid = args[1];
password = args[2];
// under eclipse * parm sends in junk
ProjectType = args[3].equalsIgnoreCase("foo") ? "*" : args[3];
newProjectParent = args[4];
// startup the teamplatform runtime, if not already
if (!TeamPlatform.isStarted())
TeamPlatform.startup();
try
{
// create required Monitor
SysoutProgressMonitor sPm = new SysoutProgressMonitor();
// login
if (login(url, userid, password, sPm) != null)
{
// get the repository object where we are connecting
ITeamRepository repo = getRepository(url);
// get the list of projects
// * means all
// specific name means only that one.. case sensitive I think
List<IProjectArea> projectList = getProjectArea(repo, sPm,
ProjectType);
System.out.println(" there are " + projectList.size()
+ " projects");
// loop thru the list of projects, if any
for (int i = 0; i < projectList.size(); i++)
{
// get the project area
IProjectArea ip = projectList.get(i);
//IDevelopmentLineHandle[] idl =ip.getDevelopmentLines();
// IIterationTypeHandle[] iii = ip.getIterationTypes();
System.out.println("\nproject name = " + ip.getName());
//IDevelopmentLine ixl =(IDevelopmentLine) idl[0].getFullState();
//IIterationHandle iih = ixl.getCurrentIteration();
//IIteration iif = (IIteration) iih.getFullState();
//IIterationHandle[] iip = ixl.getIterations();
// get the process data
@SuppressWarnings("unchecked")
Map<Object, Object> pd = ip.getProcessData();
// get the content Manager
IContentManager icm = repo.contentManager();
// get the process config content object
IContent processSource = (IContent) pd.get(keyname);
if (processSource != null)
{
System.out.println("have xml source");
saveXMLSource(ip, processSource, icm, sPm);
}
IProjectArea ipi = (IProjectArea) ip.getWorkingCopy();
// call the internal only method to get the parent process
// provider.. if any
IProjectAreaHandle iparenthandle = ((ProjectAreaImpl) ipi)
.getProcessProvider();
// if there was a parent
if (iparenthandle != null)
{
// get it
IProjectArea parentProject = (IProjectArea) (repo
.itemManager().fetchCompleteItem(iparenthandle,
IItemManager.DEFAULT, sPm));
System.out.println("have parent project name = "
+ parentProject.getName());
// if we are changing the parent
if (newProjectParent != null)
{
// find the new one
List<IProjectArea> plist = getProjectArea(repo,
sPm, newProjectParent);
// if we found it
if (plist.size() > 0)
{
// get its handle
IProjectAreaHandle newParentHandle = (IProjectAreaHandle) plist
.get(0);
// always checking
if (newParentHandle != null)
{
// set the provider field
((ProjectAreaImpl) ipi)
.setProcessProvider(newParentHandle);
// save the project area
getProcessItemService(repo).save(
(IProjectArea) ipi, sPm);
}
}
}
}
}
}
else
{
System.out.println("unable to logon to " + url + " as "
+ userid);
}
}
catch (Exception ex)
{
System.out.println("exception=" + ex.toString());
}
}
// save the process source for the project
private static void saveXMLSource(IProjectArea ip, IContent ic,
IContentManager icm, SysoutProgressMonitor sPm)
{
// make an output stream for the content manager
OutputStream os = new ByteArrayOutputStream();
// get the content of the content object.
try
{
icm.retrieveContent(ic, os, sPm);
// write xml content to file
// project name + data name
FileOutputStream fo = new FileOutputStream(ip.getName() + "."
+ keyname);
// write
fo.write(os.toString().getBytes(), 0, os.toString().length());
// close
fo.close();
}
catch (Exception e)
{
e.printStackTrace();
}
}
// login to the repository
public static ITeamRepository login(String url, final String userid,
final String password, IProgressMonitor monitor)
throws TeamRepositoryException
{
getRepository(url).registerLoginHandler(
new ITeamRepository.ILoginHandler()
{
public ILoginInfo challenge(ITeamRepository repository)
{
return new ILoginInfo()
{
public String getUserId()
{
return userid;
}
public String getPassword()
{
return password;
}
};
}
});
monitor.subTask("Contacting " + url);
getRepository(url).login(monitor);
monitor.subTask("Connected");
return getRepository(url);
}
// worker function repository
private static ITeamRepository repo1 = null;
private static ITeamRepository getRepository(String url)
{
if (repo1 == null)
{
repo1 = TeamPlatform.getTeamRepositoryService().getTeamRepository(
url);
}
return repo1;
}
// worker function process item service
private static IProcessItemService processitemservice = null;
private static IProcessItemService getProcessItemService(
ITeamRepository repo)
{
if (processitemservice == null)
{
processitemservice = (IProcessItemService) repo
.getClientLibrary(IProcessItemService.class);
}
return processitemservice;
}
public static List<IProjectArea> getProjectArea(ITeamRepository repo,
IProgressMonitor monitor, String projectAreaName)
throws TeamRepositoryException
{
List<IProjectArea> projectareaonly = new ArrayList<IProjectArea>();
@SuppressWarnings("unchecked")
// get all the projects in this repository
List<IProjectArea> projectAreas = getProcessItemService(repo)
.findAllProjectAreas(null, monitor);
// if Not ALL projects
if (!projectAreaName.equalsIgnoreCase("*"))
{
for (int i = 0; i < projectAreas.size(); i++)
{
// get next preoject from array
IProjectArea projectArea = projectAreas.get(i);
// if the names are equal, case sensitive
if (projectArea.getName().equals(projectAreaName))
{
// return this one project to the caller
System.out.println("Found " + projectAreaName);
projectareaonly.add(projectArea);
break;
}
else if (i + 1 == projectAreas.size())
{
System.out.println("Failed to find requested project '"
+ projectAreaName + "'");
}
}
return projectareaonly;
}
else
projectareaonly = projectAreas;
return projectareaonly;
}
}
3 other answers
this is currently not possible or at least very hard to do.
You would have to:
- Identify the changes between the old template and the new template in the process XML
- Identify the customizations you did in the current process XML.
- Merge the changes you found in 1 into the process XML without affecting your customizations.
I would consider this very hard.
I believe if you upgrade a server, the most essential changes needed are done to your process in project areas.
APIs relevant to templates can be seen in the Process Component Scope page.
Comments
Hi Jim,
Note: Apparently Sefa meant "process parent", not "process template". I've updated the question to fix the terminology.
For details, see: https://www-01.ibm.com/support/knowledgecenter/SSCP65_5.0.0/com.ibm.jazz.platform.doc/topics/c_sharing_project_area_process.html?lang=en
Comments
that is what he said he wanted to do
"We want to have a master process template an share it with other project areas. Once we have an updated master process template we want to project areas to point to the new updated master process template."
he wanted a way to change the parent (master) project pointer in batch instead of manually.
The original question was about migrating to a newer version of the "process template". A lot of folks (not you :-) confuse the "process template" of a project area (i.e. the template that initialized the project area), with the "parent (master) project area" of the project area, so I just wanted to make sure that this question doesn't confuse anyone. Since Seva accepted your answer, it must have been a terminology glitch in the original question, so I'll go ahead and update the question (to match your correct answer :-).