I was interested in how to read the data from a Project and Team Area. This post shows my progress so far.
The purpose of the endeavor really is to be able to create a new project area from a certain template project area, copying over all information. I am not even nearly there yet. However Jian’s question on Jazz.net indicates that what I found so far might be interesting anyhow. If you are just starting with extending Rational Team Concert, start reading this and the linked posts to get some guidance on how to set up your environment.
License and how to get started with the RTC API’S
As always, our lawyers reminded me to state that the code in this post is derived from examples from Jazz.net as well as the RTC SDK. The usage of code from that example source code is governed by this license. Therefore this code is governed by this license, which basically means you can use it for internal usage, but not sell. Please also remember, as stated in the disclaimer, that this code comes with the usual lack of promise or guarantee. Enjoy!
If you just get started with extending Rational Team Concert, or create API based automation, start with the post Learning To Fly: Getting Started with the RTC Java API’s and follow the linked resources.
You should be able to use the following code in this environment and get your own automation or extension working.
To keep it simple this example is, as many others in this blog, based on the Jazz Team Wiki entry on Programmatic Work Item Creation and the Plain Java Client Library Snippets. The example in this blog shows RTC Client API.
Download
You can download the code from here.
* Update *
The code to launch the methods is included in the download. It can also be found in several of the older posts, for example in Uploading Attachments to Work Items in the main() and the run() methods.
As a general statement, you should use the Java API to access the process information and not try to read the XML of the process directly. Please be aware that only the API documented in the Plain Java Client Library JavaDoc documentation is public API. You might end up using internal API and that is subject to change. Even for the public API there is no guarantee that it won’t change as far as I know.
You can access similar information by using the Generate Runtime Report on the project area’s context menu as shown below.
This code also works for
- Rational Quality Manager (use the URL https://%5Bserver%5D:%5Bport%5D/qm)
- Rational Requirement Composer (use the URL https://%5Bserver%5D:%5Bport%5D/jts)
Finding a Project Area
The code provided either iterates over all project areas of a repository, or it finds the project area with a given name. Once it has located the project area, it calls the method analyzeProjectArea(teamRepository, projectArea)
that takes care for the details.
The code needs some data. You can call it by providing the RepositoryURI, the user and password and optional a project area name like in the examples below.
- “https://clm.example.com:9443/ccm” “ralph” “ralph”
- “https://clm.example.com:9443/ccm” “ralph” “ralph” “JKE Banking (Change Management)”
Here the interesting code in the main method.
if (projectAreaName == null) { // For all project areas IProcessItemService itemService = (IProcessItemService) teamRepository .getClientLibrary(IProcessItemService.class); List pAreas = itemService.findAllProjectAreas(null, null); for (Iterator iterator = pAreas.iterator(); iterator.hasNext();) { IProjectArea projectArea = (IProjectArea) iterator.next(); analyzeProjectArea(teamRepository, projectArea); } } else { // For a specific project area IProcessClientService processClient = (IProcessClientService) teamRepository .getClientLibrary(IProcessClientService.class); URI uri = URI.create(projectAreaName.replaceAll(" ", "%20")); IProjectArea projectArea = (IProjectArea) processClient.findProcessArea(uri, null, null); if (projectArea == null) { System.out.println("Project area not found."); return false; } analyzeProjectArea(teamRepository, projectArea); }
Analyzing The Project Area
The code below is called and prints the process area description and the contributors for the project area and then iterates the team area hierarchy doing the same.
/** * Analyze a project area * * @param teamRepository * @param projectArea * @throws TeamRepositoryException */ public static void analyzeProjectArea(ITeamRepository teamRepository, IProjectArea projectArea) throws TeamRepositoryException { printProcessAreaDescription(teamRepository, projectArea); dumpContributors(teamRepository, projectArea); List teamAreas = projectArea.getTeamAreas(); for (Iterator iterator = teamAreas.iterator(); iterator.hasNext();) { ITeamAreaHandle handle = (ITeamAreaHandle) iterator.next(); ITeamArea teamArea = (ITeamArea) teamRepository.itemManager() .fetchCompleteItem(handle, IItemManager.DEFAULT, null); printProcessAreaDescription(teamRepository, teamArea); dumpContributors(teamRepository, teamArea); } }
Printing the Process Area Description
This method prints the process are description that is not accessible as a string but as content attached to the process area.
/** * Print the description of the process area * * @param teamRepository * @param pa * @throws TeamRepositoryException */ public static void printProcessAreaDescription(ITeamRepository teamRepository, IProcessArea pa) throws TeamRepositoryException { IDescription desc = pa.getDescription(); IContent content = desc.getDetails(); String description = ""; if (content != null) { ByteArrayOutputStream stream = new ByteArrayOutputStream(); teamRepository.contentManager().retrieveContent(content, stream, null); try { description = stream.toString(content.getCharacterEncoding()); } catch (UnsupportedEncodingException exception) { description = stream.toString(); } } String summary = desc.getSummary(); System.out.println(summary + "\n\nDescription:\n" + description); }
Printing the Administrators and Team Members of a Process Area
This operation prints the contributors associated to the process area. It separates the administrators and the team members.
/** * Iterate over the contributors of the process area and print them sorted * as admins and as team members * * @param teamRepository * @param processArea * @throws TeamRepositoryException */ private static void dumpContributors(ITeamRepository teamRepository, IProcessArea processArea) throws TeamRepositoryException { System.out.println("Process Area: " + processArea.getName()); System.out.println("Administrators"); dumpContributors(teamRepository, processArea, processArea.getAdministrators()); System.out.println("Team Members"); dumpContributors(teamRepository, processArea, processArea.getMembers()); }
It uses the following code to iterate a list of contributors and print the information.
/** * @param teamRepository * @param processArea * @param contributors * @throws TeamRepositoryException */ private static void dumpContributors(ITeamRepository teamRepository, IProcessArea processArea, IContributorHandle[] contributors) throws TeamRepositoryException { for (int i = 0; i < contributors.length; i++) { IContributorHandle handle = (IContributorHandle) contributors[i]; dumpContributor(teamRepository, processArea, handle); } }
This code finally does the printing of the details of the contributor.
/** * Dump the details of the contributors * * @param teamRepository * @param processArea * @param handle * @throws TeamRepositoryException */ private static void dumpContributor(ITeamRepository teamRepository, IProcessArea processArea, IContributorHandle handle) throws TeamRepositoryException { IContributor contributor = (IContributor) teamRepository.itemManager() .fetchCompleteItem(handle, IItemManager.DEFAULT, null); System.out.print(": " + contributor.getUserId() + "\t" + contributor.getName() + "\t" + contributor.getEmailAddress() + "\t"); IProcessItemService processService = (IProcessItemService) teamRepository .getClientLibrary(IProcessItemService.class); IClientProcess process = processService.getClientProcess(processArea, null); IRole[] contributorRoles = process.getContributorRoles(contributor, processArea, null); for (int j = 0; j < contributorRoles.length; j++) { IRole role = (IRole) contributorRoles[j]; System.out.print(role.getId() + " "); } System.out.println(); }
* Update *
I just realized that using IRole there is no way to access the role name. Sometimes along the way the interface probably needed to be made richer and to not break the older version, an additional interface IRole2 was introduced. This code provides with the additional information.
for (int j = 0; j < contributorRoles.length; j++) { IRole role = (IRole) contributorRoles[j]; IRole2 role2 = (IRole2) role; System.out.print(role.getId() + "[" + role2.getRoleName() +" " + role2.getRoleLabel() + "] "); }
Get The Latest Data
The API caches Data. If you want to make sure that the data is refreshed, use IItemManager.REFRESH
instead of IItemManager.DEFAULT
in the code above.
Only Analyze the Process Areas of One User
This code, result of this question on jazz.net, shows how to get only the process areas a certain user is member of in a repository:
IContributor user = teamRepository.loggedInContributor(); // If having an ID for the user as string //IContributor user = teamRepository.contributorManager().fetchContributorByUserId(user) IProcessItemService processItemService = (IProcessItemService) teamRepository .getClientLibrary(IProcessItemService.class); List processAreasOfUser= processItemService.findProcessAreas(user, null, IProcessClientService.ALL_PROPERTIES , monitor);
Summary
Using the API as described above allows you to run automation against project areas. although this describes client API, the server API is similar enough and allows you to do similar things for example to extend this example to iterate the team hierarchy.
I hope that these code examples will help users out there that have a need for more automation.
IITemManager.REFRESH works!
Thanks Ralph Schoon! You really helped me a lot.
– Jian
Great to hear you got it working!
IProcessItemService itemService = (IProcessItemService) teamRepository
.getClientLibrary(IProcessItemService.class);
In the statement above: “teamRepository” gives an error: ‘teamRepository’ cannot be resolved. How is this object initialized?
I am thinking it should be something along the lines of ITeamRepository teamRepository = “….”
Please help. Thanks in advance.
The whole code is available from a link in the post. Please look into that.
The basic code is also, as mentioned available in:
“To keep it simple this example is again based on the wiki entry on Programmatic Work Item Creation. The API used in the following example is client API.” the link is in the post.
I updated the post to make this clearer.
Hi,
I downloaded the code and I am trying to run it; where in the code do I type in the parameters (repository address, username, password, and project name)? I am trying to run it, but all it outputs is :
Usage: PlainJavaClient
Usage: PlainJavaClient
Please let me know. thanks!
Please read the post, it explains the parameters to pass.
You pass the parameters as arguments in the run configuration or on the command line.
Hi Ralph,
regarding analyzing a project area I’d like to also get the information about whether a shared process is used and if so which one. So far, I’m not able to find the correct API calls for querying that. Could you point me in the right direction?
Thanks for this and your very helpful articles in general!
Manuel
I believe it is internal API. Here the code I have found:
/**
* Set a project Area to share its process
*
* @param thisProjectArea
*/
private static void setProcessToSahred(IProjectArea thisProjectArea) {
((ProjectArea) thisProjectArea).setIsProcessProvider(true);
}
/**
* Share the process on another project area
*
* @param thisProjectArea
* @param projectAreaSharingItsProcess
*/
private static void setShareProcess(IProjectArea thisProjectArea,
IProjectArea projectAreaSharingItsProcess) {
((ProjectArea) thisProjectArea)
.setProcessProvider(projectAreaSharingItsProcess);
;
}
Thank you for the fast reply!!
Looks, like I gave up searching too early…
Here’s the answer to my question:
https://jazz.net/forum/questions/147231/rtc-java-api-how-to-get-process-sharing-information-from-project-area
Hello Ralph,
This is a nice post to start!
We have a scenario where we have multiple roles in our process, as far as we know when a user has more than one role then there is a conflict between “required attribute for type and state” and “read only attribute for type an state”.
Now we have decided to prioritise the roles based on state transition which i think is quite possible, but there seems to be a blocker. When an existing workitem is loaded then is there any triggering point in RTC so that it would re-prioritize the roles of the authenticated user based on the state the workitem is.
Thanks in Advance.
Abhishek Kumar
This comes to my attention over and over. The only valid answer I know so far is that you should create your own advisor that implements the method for required and read only attributes. You can look into the code in the SDK and create your own logic around it.
Hello Ralph,
How to get all project areas using server api’s.
and We have a scenario where we have to create a workitem form one project area that automatically create workitem in another project area, how to do this using server api’s, please help me with this.
Thanks in advance.
Manju
You can use IProcessService pService = getService(IProcessService.class);
pService.findProcessAreas(user, projectAreaHandle, properties);
I have not found a call to get all project areas in the server API yet.
Hi,
Is there the way to get the permission and operation per each role ? e.g. create query, modify work item.
Regards,
Pumtat
I am sure this is possible, because the server and client uses this information, but I don’t have code for that.
Hi Pumtat,
This is an old subject but I would like to know whether you found a solution to get the permissions per each role ?
Many thanks for your feedback,
Fabien
Hi Ralph,
Does this code print user’s role assignment per project/team or it concatenates all roles within the project’s hierarchy and prints them repeatedly for a member? For example, if a member is assigned the scrum master role at the project level and a team member role at the team level, would it show scrum master + team member for both project and team OR will it show scrum master for the project and team member for the team?
Hi,
this is example code made so that users that need such kind of stuff can grab it and do whatever they want to do with it.
If I follow the code correctly it will,
1. show the admins and members for the project area.
Show the users in the project area with all their roles at that level
For all team areas
Show the users in the team area with all their roles at that level
I would suggest testing what it does and if that is what you want. The code should be downloadable.