Status History Presentation for RTC


Rational Team Concert (RTC) has a built-in feature to view the history of a work item. But especially for work items with many changes, it is hard to follow the Status of a work item over time. That’s why Lukas created the amazing Status History Presentation for RTC and published it in the DACH Jazz Community project. It shows all Status changes since the creation of the work item in form of a timeline in the RTC work item Web UI.

Follow the instructions in the Status History Presentation for RTC project to download and install the editor presentation server extension. The Open Source project also serves as a great example for how to write a custom editor presentation.

After installing this extension plug-in into your RTC instance (server side), you will be able to add a “Status History” presentation on your work item editors (WEB only). You can add this  presentation to a work item editor section for example the Quick Info section. Once the presentation is available it will

  • Show all state changes in a timeline
  • Show who did the state change
  • Show the number of days a work item was or is in a state
  • A Rich Hover shows additional information about the changes made together with the state change

Many thanks to the DACH Jazz Community for sharing their amazing work.

Advertisements
Posted in Jazz, RTC Extensibility | Tagged , , , | Leave a comment

Adding a check-in participant to Rational Team Concert source control


Rational Team Concert 6.0.4 tries to make the check-in operation available to advisors and follow up actions.

Michael Valenta recently published an article on Adding a check-in participant to Rational Team Concert source control. on Jazz.net which provides details about this.

If you are interested in advisors and follow up actions, especially for SCM, this is an important article. Have a look and give him a thumbs up.

Please make sure to check with the links in the next section if you are just starting with the RTC Java API.

Just starting with extending RTC?

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.

 

Posted in Jazz, RTC, RTC Extensibility | Tagged , , , , | Leave a comment

Jazz Community Contributions


The Jazz Community starts sharing their tools here: http://jazz-community.org/. The code for their tools can be found here.

There is a very active Jazz user community of members of several companies in Europe that are heavily using the Jazz products such as Rational Team Concert, Rational Quality Manager and Doors Next Generation.

The community members try to meet to share their experience with using, administrating and running the Jazz tools in their environments. It became clear that the different companies and community members face similar challenges and that it would be beneficial if they could share tools they created to make running such an environment easier.

The community has now started sharing their tools in this community project and in this code repository.

JazzCommunity2017-05-12_11-34-52

Some of the tools have already been shared on other sites. I have linked the ones I am aware of to the Interesting links page in the ‘Extensions Provided by the Community’ section. These are the ones I am aware of (and the code for some of them is already available in the community repository):

I am looking forward to see more community created tools soon. Visit the community to find out what they have to offer. The code for their tools can be found here.

Last but not least, a special thanks to Dani for getting this awesome user groups started and for the members of said community for their spirit, engagement and willingness to contribute and help each other. You know whom I address here!

Posted in automation, CLM, Doors Next Generation, extending, Jazz, RTC, RTC Automation, RTC Extensibility, RTC Process Customization, Upgrade | Tagged , , , , | 7 Comments

Managing Contributor Licenses using the Java API


The question how to manage licenses using the plain java client libraries came up recently. There used to be a blog post in the internet that explained it, but that has been taken down. Questions on Jazz.net are not very clear for this, so I dug into the API myself. Here is the result.

License

The post contains published code, so 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. I found a section relevant to source code at the and of the license. Please also remember, as stated in the disclaimer, that this code comes with the usual lack of promise or guarantee. Enjoy!

Just starting with extending RTC?

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.

Solution

The service to access and assign licenses is the class com.ibm.team.repository.common.ILicenseAdminService.

Note that this class is not available as a client library such as other common and client services. The way to get this class in a client extension or a plain java API base application looks as follows:

ILicenseAdminService licenseAdminService = (ILicenseAdminService) ((IClientLibraryContext) teamRepository).getServiceInterface(ILicenseAdminService.class);

To access the class in a server extension like a pre-condition/advisor or a follow up action/participant is however using the typical com.ibm.team.repository.service.AbstractService.getService(Class) that is usually used e.g.:

ILicenseAdminService licenseService = getService(ILicenseAdminService.class);

The licensing code should work against each of the CLM applications JTS, CCM, QM, RM and should work for any available license.

This code can be used to print the license information for the available license types:

	IContributorLicenseType[] Licensetypes = licenseAdminService.getLicenseTypes();

	for (IContributorLicenseType iContributorLicenseType : Licensetypes) {
		System.out.println("License Type: ");
		System.out.println("License Type ID: " + iContributorLicenseType.getId());
		System.out.println("License Type Name: " + iContributorLicenseType.getName());
		System.out.println("License Type Description: " + iContributorLicenseType.getDescription());
		System.out.println("License Type ProductName: "	+ iContributorLicenseType.getProductName());
	}

The resulting list of licenses would look like below.

License Type: 
License Type ID: com.ibm.team.clm.stakeholder
License Type Name: Stakeholder
License Type Description: Diese Stakeholder-Lizenz ist zur Unterstützung von peripheren Benutzern gedacht, z. B. von externen Kunden, von Mitarbeitern der Benutzerunterstützung oder von Benutzern, die Arbeitselemente modifizieren und den Projektfortschritt beobachten müssen. Ein Benutzer mit zugewiesener Clientzugriffslizenz für Stakeholder hat Lese- und Schreibzugriff auf Change Management sowie Lesezugriff auf Berichte und Planungsfunktionen, sofern rollenbasierte Prozessberechtigungen keine diesbezüglichen Einschränkungen beinhalten. Floating-Lizenzen werden dynamisch von einem Lizenzserver zugewiesen. Ein Benutzer mit zugewiesener Floating-Lizenz kann in den Pool der Benutzer aufgenommen werden, die die verfügbaren, auf dem Lizenzserver installierten Floating-Lizenzen gemeinsam nutzen. Führt ein solcher Benutzer eine Operation aus, für die diese Lizenz erforderlich ist, wird ihm vom Lizenzserver dynamisch eine Floating-Clientzugriffslizenz zugewiesen, wenn eine solche verfügbar ist. 
License Type ProductName: Rational solution for Collaborative Lifecycle Management
License Type: 
License Type ID: com.ibm.team.clm.practitioner
License Type Name: Practitioner
License Type Description: Diese Lizenz 'CLM Practitioner' ist für Anwender bestimmt, die aktiv an Projekten der Rational-Lösung für Collaborative Lifecycle Management mitwirken. Ein Benutzer mit zugewiesener Clientzugriffslizenz 'CLM Practitioner' hat vollen Lese- und Schreibzugriff auf das Änderungsmanagement, auf die Anpassung von Berichten, auf die Planung, auf das Softwarekonfigurationsmanagement, auf die Automation (Buildsystem), auf bestimmte Erweiterungen für IBM Unternehmensplattformen, auf Funktionen für Anforderungsdefinition und -management sowie Qualitätsmanagement und Lesezugriff auf Funktionen des Designmanagements, sofern rollenbasierte Prozessberechtigungen keine diesbezüglichen Einschränkungen beinhalten.
License Type ProductName: Rational solution for Collaborative Lifecycle Management
License Type: 
License Type ID: com.ibm.team.rrc.reviewer
License Type Name: Contributor
License Type Description: Diese Mitarbeiterlizenz ist für professionelle Teammitglieder bestimmt, die keine Entwickler sind, aber aktiv am Projekt beteiligt sind. Ein Benutzer mit zugewiesener Clientzugriffslizenz für Mitarbeiter hat vollen Lese- und Schreibzugriff auf das Änderungsmanagement, auf die Anpassung von Berichten und auf die Planung. Diese Lizenz ermöglicht außerdem den Lesezugriff auf Funktionen des Anforderungsmanagements, des Softwarekonfigurationsmanagements, der Automation (Buildsystem), des Testmanagements und des Designmanagements, sofern rollenbasierte Prozessberechtigungen keine diesbezüglichen Einschränkungen beinhalten.
License Type ProductName: Rational DOORS Next Generation
License Type ID: com.ibm.team.rtc.contributor
License Type Name: Contributor
License Type Description: Diese Mitarbeiterlizenz ist für professionelle Teammitglieder bestimmt, die keine Entwickler sind, aber aktiv am Projekt beteiligt sind. Ein Benutzer mit zugewiesener Clientzugriffslizenz für Mitarbeiter hat vollen Lese- und Schreibzugriff auf das Änderungsmanagement, auf die Anpassung von Berichten und auf die Planung. Diese Lizenz ermöglicht außerdem den Lesezugriff auf das Softwarekonfigurationsmanagement, auf die Automation (Build-System), auf das Anforderungsmanagement, das Testmanagement und das Designmanagement, sofern rollenbasierte Prozessberechtigungen keine diesbezüglichen Einschränkungen beinhalten.
License Type ProductName: Rational Team Concert
License Type: 
License Type ID: com.ibm.team.rtc.stakeholder
License Type Name: Stakeholder
License Type Description: Diese Stakeholder-Lizenz ist zur Unterstützung von peripheren Benutzern gedacht, z. B. von externen Kunden, von Mitarbeitern der Benutzerunterstützung oder von Benutzern, die Arbeitselemente modifizieren und den Projektfortschritt beobachten müssen. Ein Benutzer mit zugewiesener Clientzugriffslizenz für Stakeholder hat Lese- und Schreibzugriff auf Change Management sowie Lesezugriff auf Berichte und Planungsfunktionen, sofern rollenbasierte Prozessberechtigungen keine diesbezüglichen Einschränkungen beinhalten.
License Type ProductName: Rational Team Concert
License Type: 
License Type ID: com.ibm.team.rtc.buildsystem
License Type Name: Build System
License Type Description: Die Clientzugriffslizenz 'Build System' kann nur einer Benutzer-ID zugewiesen werden, die von einem automatisierten Build-System verwendet wird. Damit haben Einheiten des Build-Systems Lesezugriff auf das gesamte Leistungsspektrum sowie Schreibzugriff auf alle Leistungsmerkmale, sofern rollenbasierte Prozessberechtigungen keine diesbezüglichen Einschränkungen beinhalten.
License Type ProductName: Rational Team Concert
License Type: 
License Type ID: com.ibm.team.rtc.developer
License Type Name: Developer
License Type Description: Diese Lizenz ist für professionelle Entwickler bestimmt, die aktiv am Projekt beteiligt sind. Ein Benutzer mit zugewiesener Clientzugriffslizenz für Entwickler hat vollen Lese- und Schreibzugriff auf das Änderungsmanagement, auf die Anpassung von Berichten, auf die Planung, auf das Softwarekonfigurationsmanagement und auf die Automation (Buildsystem). Diese Lizenz ermöglicht außerdem den Lesezugriff auf das Anforderungsmanagement, das Testmanagement und das Designmanagement, sofern rollenbasierte Prozessberechtigungen keine diesbezüglichen Einschränkungen beinhalten.
License Type ProductName: Rational Team Concert
License Type: 
License Type ID: com.ibm.team.clm.contributor
License Type Name: Contributor
License Type Description: Diese Mitarbeiterlizenz ist für professionelle Teammitglieder bestimmt, die keine Entwickler sind, aber aktiv am Projekt beteiligt sind. Ein Benutzer mit zugewiesener Clientzugriffslizenz für Mitarbeiter hat vollen Lese- und Schreibzugriff auf das Änderungsmanagement, auf die Anpassung von Berichten und auf die Planung. Diese Lizenz ermöglicht außerdem den Lesezugriff auf das Softwarekonfigurationsmanagement, auf die Automation (Buildsystem), auf das Anforderungsmanagement, das Testmanagement und das Designmanagement, sofern rollenbasierte Prozessberechtigungen keine diesbezüglichen Einschränkungen beinhalten. Floating-Lizenzen werden dynamisch von einem Lizenzserver zugewiesen. Ein Benutzer mit zugewiesener Floating-Lizenz kann in den Pool der Benutzer aufgenommen werden, die die verfügbaren, auf dem Lizenzserver installierten Floating-Lizenzen gemeinsam nutzen. Führt ein solcher Benutzer eine Operation aus, für die diese Lizenz erforderlich ist, wird ihm vom Lizenzserver dynamisch eine Floating-Clientzugriffslizenz zugewiesen, wenn eine solche verfügbar ist. 
License Type ProductName: Rational solution for Collaborative Lifecycle Management

The license type ID can be used to assign a license to the user.

	IContributor licenseContributor = teamRepository.contributorManager().fetchContributorByUserId(licenseUser, monitor);
	licenseAdminService.assignLicenseWithResult(licenseContributor,	licenseID);

For Example for user “bob” and the license type ID “com.ibm.team.rtc.developer”:

	IContributor licenseContributor = teamRepository.contributorManager().fetchContributorByUserId("bob", monitor);
	licenseAdminService.assignLicenseWithResult(licenseContributor,	"com.ibm.team.rtc.developer");

To remove a license use the code below and provide the license type ID

	IContributor licenseContributor = teamRepository.contributorManager().fetchContributorByUserId(licenseUser, monitor);
	licenseAdminService.assignLicenseWithResult(licenseContributor,	licenseID);

	licenseAdminService.unassignLicense(licenseContributor, licenseID);

Assigning licenses in a batch file

Using a plain java API application is not the only way to assign licenses. It is also possible to use the repo tools to do that. I use the following batch file to assign licenses to the users created for the JKE Banking sample life cycle project that I use to explore CLM.

echo on
set SERVERFOLDER="C:\CLM2016\6.0.3\JazzTeamServer\server"
set REPOSITORY="https://clm.example.com:9443/jts"
set USERID="myadmin"
set PASSWORD="myadmin"


rem primary users
call %SERVERFOLDER%\repotools-jts -createUser userId=bob licenseId=com.ibm.team.rrc.author repositoryURL=%REPOSITORY% adminUserId=%USERID% adminPassword=%PASSWORD%
call %SERVERFOLDER%\repotools-jts -createUser userId=marco licenseId=com.ibm.rqm.tester repositoryURL=%REPOSITORY% adminUserId=%USERID% adminPassword=%PASSWORD%
call %SERVERFOLDER%\repotools-jts -createUser userId=marco licenseId=com.ibm.team.rtc.developer repositoryURL=%REPOSITORY% adminUserId=%USERID% adminPassword=%PASSWORD%
call %SERVERFOLDER%\repotools-jts -createUser userId=deb licenseId=com.ibm.team.rtc.developer repositoryURL=%REPOSITORY% adminUserId=%USERID% adminPassword=%PASSWORD%
call %SERVERFOLDER%\repotools-jts -createUser userId=tanuj licenseId=com.ibm.rqm.tester repositoryURL=%REPOSITORY% adminUserId=%USERID% adminPassword=%PASSWORD%
call %SERVERFOLDER%\repotools-jts -createUser userId=rebecca licenseId=com.ibm.team.rtc.developer repositoryURL=%REPOSITORY% adminUserId=%USERID% adminPassword=%PASSWORD%

rem Build user
call %SERVERFOLDER%\repotools-jts -createUser userId=build licenseId=com.ibm.team.rtc.buildsystem repositoryURL=%REPOSITORY% adminUserId=%USERID% adminPassword=%PASSWORD%

rem secondary users
call %SERVERFOLDER%\repotools-jts -createUser userId=ursula licenseId=com.ibm.team.rrc.author repositoryURL=%REPOSITORY% adminUserId=%USERID% adminPassword=%PASSWORD%
call %SERVERFOLDER%\repotools-jts -createUser userId=curtis licenseId=com.ibm.rqm.viewer repositoryURL=%REPOSITORY% adminUserId=%USERID% adminPassword=%PASSWORD%
call %SERVERFOLDER%\repotools-jts -createUser userId=tammy licenseId=com.ibm.rqm.tester repositoryURL=%REPOSITORY% adminUserId=%USERID% adminPassword=%PASSWORD%
call %SERVERFOLDER%\repotools-jts -createUser userId=sally licenseId=com.ibm.team.rrc.author repositoryURL=%REPOSITORY% adminUserId=%USERID% adminPassword=%PASSWORD%
rem Design Manager License 
rem %SERVERFOLDER%\repotools-jts -createUser userId=al licenseId= repositoryURL=%REPOSITORY% adminUserId=%USERID% adminPassword=%PASSWORD%
pause

This works very well, except that it takes a long time to run since each repotools command has to individually log in.

Download and Compatibility

This code has been used with RTC 6.0 and is prepared to be used with RTC 6.0.x with no changes and it is pretty safe to assume, that the code will work with newer versions of RTC. It should however run with any version of RTC that has the specific API already implemented. The code shown below should work with almost all versions of RTC.

The post shows client, common API that are available in the RTC Server SDK and the RTC Plain Java Client Libraries.

You can download the Eclipse project with the application to print and assign a license to a user here.

You can download the batch file to assign the licenses for the JKE Banking Example in a zip archive here.

Related posts

Summary

The code above can be used to assign and remove licenses from users in RTC and CLM. An alternative method is using the repotools. as always I hope that this helps users out there with their tasks.

Posted in Jazz, RTC, RTC Automation, RTC Extensibility | Tagged , , , | Leave a comment

The Work Item Command Line is now Open Source


To allow customers to use and share the WorkItem Command Line freely, it has now been released under the MIT License.

Access the Source Code

The code is available in the Jazz Community.

OpenSourceGitHub

License

Released under the MIT License. See the License.txt and the license headers in the individual files.

 

Changes

The current version uploaded there contains the capabilities described in The RTC Work Item Command Line on Bluemix.

Additional Download

You can also download the latest version 4.0 here:

Please note, there might be restrictions to access Dropbox and therefore the code in your company or download location.

Usage and install

Please see the posts A RTC WorkItem Command Line Version 3.0.

For the general setup follow the description in A RTC WorkItem Command Line Version 2.

For usage follow the description in A RTC WorkItem Command Line Version 2 and in A RTC WorkItem Command Line Version 2.1. Check the README.txt which is included in the downloads.

Summary

The work item command line is now available on IBM Bluemix Dev Ops Services and can be accessed and worked on there.

Posted in Jazz, RTC, RTC Automation, RTC Extensibility | Tagged , , | 2 Comments

Updated RTC Extensions Workshop for RTC 6.0.3


I have finished updating the RTC Extensions Workshop a while ago. Unfortunately, due to heavy maintenance work on Jazz.net, I was not able to publish the files for download yet.

Until the update is published on Jazz.net, please find the files in the download section of The RTC SDK is about to change in 6.0.3

Posted in Jazz | Leave a comment

Query Models or how to find stuff with the RTC Java API


Although I have done my share using and blogging about the API there are still a lot of uncharted areas. How can I use the RTC API to find a user by the name? This is a question that came up recently in the forum and is one of many questions, I did not have a good answer until today.

While writing my last post, for whatever reason I started thinking about this question. I decided to have a quick peek and try to find out. As a result this blog post describes how questions like that can be approached with the RTC Java API.

The Problem

The API provided for objects such as contributors, build results and a lot more model elements used in the RTC application is not necessarily the API a human would expect. This is because the API is written to make it easy to develop the tool and not to make it easy for a human to access data. So a question “How do I find a user by the name” is not necessarily something the RTC API would be optimized for.

If a user logs into RTC, they provide the ID and not the name. After login the user ID is available in the API and that is the glue used for almost all internal computation. The user name is usually nothing of interest to the API. However there are cases, for example integration scenarios, where questions like this might be of interest. So how does RTC solve this under the covers?

Work Item Queries

Please don’t confuse the Query Models in this post with work item queries and work item expressions. To search for work items see

License

The post contains published code, so 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. I found a section relevant to source code at the and of the license. Please also remember, as stated in the disclaimer, that this code comes with the usual lack of promise or guarantee. Enjoy!

Just starting with extending RTC?

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.

Compatibility

This code has been used with RTC 6.0 and is prepared to be used with RTC 6.0.x with no changes and it is pretty safe to assume, that the code will work with newer versions of RTC. It should however run with any version of RTC that has the specific API already implemented. The code shown below should work with almost all versions of RTC.

The post shows client, common and server API that are available in the RTC Server SDK and the RTC Plain Java Client Libraries.

Download

You can download the Eclipse project with the examples.  Please note, there might be restrictions to access Dropbox and therefore the code in your company or download location.

Solution

RTC works against a database. Some domains such as work items and SCM provide higher level query mechanisms to support user configurable queries in the UI to find stuff. Other domains do not.  But under the cover, the RTC API provides query mechanisms to query the database for data and to manage result sets.

The RTC API provides a common query service and  query models to be able to define and run queries for a wide variety of RTC objects.  The query service and the query models are common API and can be used in Java client applications, Eclipse client extensions as well as in RTC Server extensions.

Although there are questions and examples in the forums and there are some examples like this wiki page and somewhat hidden in this article (section Querying for Items), there is no good description how this works on a broader level. Needless to say that there is no description how to find the entry points into the API either. This post tries to help as good as possible.

How to find the query models

The best way to approach this is to setup a RTC Development environment by following the getting started post. Thsi means follow Setting up Rational Team Concert for API Development and the Extensions workshop and perform at least lab 1. Now you have an Eclipse with a RTC SDK set up that provides you with searchable example code. Without this environment, it is pretty pointless to try to approach this API.

You can use the naming conventions used while developing RTC to search for the query models. In the Plug-in Development Perspective select the menu Search>Java. Type *QueryModel as search string. Select declarations and the other choices shown below, then click Search.

searchquerymodel

Be patient while the SDK is searched. Dependent on the version of RTC you should finally see a search view similar to the one below.

searchquerymodelresult

Note that more than 960 query modes are found. There might be some duplicates and some might be totally uninteresting but there is obviously an enormous potential to access data in RTC.

If you know the model element interface you are interested in, for example an IBuildResult,you can use these approaches to find the related query model.

You can try to use the Eclipse content assist capability of the Plugin Development Environment (PDE) to find the related query model. Type in the name of the model element without the leading I and append QueryModel to it. To find the query model for IBuildResult, type BuildResultQueryModel. While you type use Ctrl+Space for content assist. The PDE should find the query model class.

contentassistpde

You can also use the search approach from earlier to search for the specific class BuildResultQueryModel with or without using the asterisk.

specificsearch

That way the Eclipse client, if set up correctly, allows to find the query model for the model element interfaces you are interested in.

What is provided by the query models?

The query models allow to define queries, to find model elements related to the query model. The query model provides comparisons, Boolean operations on properties specific to the model elements, sort and filter operations. The queries can be constructed and called with parameters. The queries can then be run using a query service and return a result set that can be further processed.

Example 1: Find the build results related to a specific build definition that are tagged with a specific tag.

Example 2: Find a Contributor by user name.

The entry point of a query model is the ROOT entry of the query model. It allows to instantiate queries against the query model and defines the interfaces available for the specific query model. These interfaces also specify which properties an object has, how to access them and the Boolean and other operations available to operate on this model element.

The image below shows the query model root BuildResultQueryModel.ROOT. It returns an implementation class. The BuildResultQueryModel interface also extends interfaces BaseBuildResultQueryModel and ISingleItemQueryModel.

querymodelroot

The interface BaseBuildResultQueryModel defines which properties the model element IBuildResult exposes in queries.

buildresultquerymodel

ISingleItemQueryModel defines operators such as equals or contained in providing a IPredicate interface.

isingleitemquerymodel

The IPredicate interface provides the interfaces to create the Boolean operations and, or, not.

ipredicate

Given this pattern, it is possible to create complex expressions.

Using the query models

Using the Query mechanism typically works in the following steps.
Create a query for the QueryModel for the model element (example [ModelElementName]=BuildResult.

IItemQuery query = IItemQuery.FACTORY.newInstance([ModelElementName]QueryModel.ROOT);

Create a predicate to filter the results based on some properties. This specific example uses a parameter of type string that gets a value passed. Instead of the paramter, it would also be possible to hard code a string here.

IPredicate predicate = [ModelElementName]QueryModel.ROOT.property()._eq(query.newStringArg());

Use the predicate from the step before as filter for the query.

IItemQuery filtered = (IItemQuery) query.filter(predicate);

Finally use the query service to run the query. Here a parameter of type string is passed to the query. Result sets can be big, so the last parameter is used to pass how many results should be retrieved.

IItemQueryPage page = queryService.queryItems(filtered, new Object[] { "Jerry Jazz"}, 1 );

All this can be as compact as in the following example.

IItemQueryPage page = queryService.queryItems(IItemQuery.FACTORY.newInstance(IterationPlanRecordQueryModel.ROOT), IQueryService.EMPTY_PARAMETERS, IQueryService.DATA_QUERY_MAX_PAGE_SIZE);

Get contributor by user name

Lets look at how the code for this forum question.: “How can I get the contributor for a user if I have the user name and not the ID?”. The code is inspired by very similar code that is used for the RTC Jabber integration.

We are looking for an IContributor. So the looking for the query model seems to be ContributorQueryModel.

First the code creates the query for the ContributorQueryModel. Then it creates a predicate to filter out a contributor with a specified name. The predicate uses an argument for the user name instead of providing the user name already here as string. The predicate is set as filter.

This is plain java client library code. There is no direct access to the com.ibm.team.repository.common.service.IQueryService. To get the IQueryService the code uses a trick. the IQueryService is available from the Implementation Class for ITeamRepository.  The teamRepository object is casted to com.ibm.team.repository.client.internal.TeamRepository. This makes the usage of QueryModels unsupported due to using unsupported internal code.

The IQueryService is indirectly available in some client libraries as well.

ITeamBuildClient buildClient = (ITeamBuildClient) teamRepository.getClientLibrary(ITeamBuildClient.class);
IItemQueryPage queryPage = buildClient.queryItems(query, parameters, IQueryService.ITEM_QUERY_MAX_PAGE_SIZE, monitor);

Once the QueryService is available the query is executed. In the example the user name is passed as a new parameter to the query. The result expects no more than one result.

The paged result is retrieved as list of handles and further processed.

// Create a query for the ContributorQueryModel
final IItemQuery query = IItemQuery.FACTORY.newInstance(ContributorQueryModel.ROOT);
// Create a predicate with a parameter to search for name property  
final IPredicate predicate = ContributorQueryModel.ROOT.name()._eq(query.newStringArg());
// Use the predicate as query filter 
final IItemQuery filtered = (IItemQuery) query.filter(predicate);
// Get the query service. This is a cast to an internal class. Note TeamRepository and not ITeamRepository is casted.
final IQueryService qs = ((TeamRepository) teamRepository).getQueryService();
// Run this ItemQuery. Note, there are also other types of queries qs.queryData(dataQuery, parameters, pageSize)
final IItemQueryPage page = qs.queryItems(filtered, new Object[] { findUserByName }, 1 /* IQueryService.DATA_QUERY_MAX_PAGE_SIZE */);
// Get the item handles if any
final List<?> handles = page.getItemHandles();
System.out.println("Hits: " + handles.size());
if (!handles.isEmpty()) {
	System.out.println("Found user.");
	// Resolve and print the information to the contributor object.
	final IContributorHandle handle = (IContributorHandle) handles.get(0);

Please note that there are various operations available to create the predicate and that the predicate can actually more complex. The code above uses the method

_eq()

to check for an equal string. In this case the match has to be exact.

Another option would be to search with ignore case option. This can be done using the following predicate definition:

final IPredicate predicate = ContributorQueryModel.ROOT.name()._ignoreCaseLike(query.newStringArg());

The complete code can be found below and is available for download. The downloadable code contains the example to search for the user by exact (case sensitive) user name and an example to search for the contributor by e-mai with a case insensitive match.

If the QueryUserByName example class is called with the required parameters like.

"https://clm.example.com:9443/ccm" "myadmin" "myadmin" "John Doe"

the result looks like this, provided the user exists, of course.

executionresult

Differences in the Server API

Server extensions must extend com.ibm.team.repository.service.AbstractService. This allows to use com.ibm.team.repository.service.AbstractService.getService(Class) to get the IQueryService in a server Extension like this:

IQueryService queryService = this.getService(IQueryService.class);

The rest of the API is as described above.

Dynamic Query  Model

There is also a dynamic query model based on the IItemType. It can be created as shown below.

IDynamicItemQueryModel dynamicQueryModel = IBuildResult.ITEM_TYPE.getQueryModel();

From the documentation in the code:

Generally, static query models should be used whenever they are visible and the types/properties are known at compile time. Note also that there are no API contracts regarding dynamic APIs – model objects may change shape, queryable properties, etc.”

So use the static version as described above.

Interesting examples in the SDK

Search for “Owned By” is in com.ibm.team.repository.client.tests.query.ExistsPredicateQueryTests.testExistsPredicateUsingLinks()

The full example code

Please find below the complete code for the RTC Plain Java Client Library version to find a contributor by its user name.

/*******************************************************************************
 * Licensed Materials - Property of IBM
 * (c) Copyright IBM Corporation 2017. All Rights Reserved. 
 *
 * Note to U.S. Government Users Restricted Rights:  Use, duplication or 
 * disclosure restricted by GSA ADP Schedule Contract with IBM Corp.
 *******************************************************************************/
package com.ibm.team.workitem.ide.ui.example;

import java.util.List;

import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.NullProgressMonitor;

import com.ibm.team.repository.client.IItemManager;
import com.ibm.team.repository.client.ITeamRepository;
import com.ibm.team.repository.client.ITeamRepository.ILoginHandler;
import com.ibm.team.repository.client.ITeamRepository.ILoginHandler.ILoginInfo;
import com.ibm.team.repository.client.TeamPlatform;
import com.ibm.team.repository.client.internal.TeamRepository;
import com.ibm.team.repository.common.IContributor;
import com.ibm.team.repository.common.IContributorHandle;
import com.ibm.team.repository.common.TeamRepositoryException;
import com.ibm.team.repository.common.model.query.BaseContributorQueryModel.ContributorQueryModel;
import com.ibm.team.repository.common.query.IItemQuery;
import com.ibm.team.repository.common.query.IItemQueryPage;
import com.ibm.team.repository.common.query.ast.IPredicate;
import com.ibm.team.repository.common.service.IQueryService;

/**
 * Uses the ContributorQueryModel to search for a user by the user name 
 * and not the ID.
 * 
 * 
 * Example code, see
 * https://jazz.net/wiki/bin/view/Main/ProgrammaticWorkItemCreation.
 */
public class QueryUserByName {

	private static class LoginHandler implements ILoginHandler, ILoginInfo {

		private String fUserId;
		private String fPassword;

		private LoginHandler(String userId, String password) {
			fUserId = userId;
			fPassword = password;
		}

		public String getUserId() {
			return fUserId;
		}

		public String getPassword() {
			return fPassword;
		}

		public ILoginInfo challenge(ITeamRepository repository) {
			return this;
		}
	}

	public static void main(String[] args) {

		boolean result;
		TeamPlatform.startup();
		try {
			result = run(args);
		} catch (TeamRepositoryException x) {
			x.printStackTrace();
			result = false;
		} finally {
			TeamPlatform.shutdown();
		}

		if (!result)
			System.exit(1);
	}

	private static boolean run(String[] args) throws TeamRepositoryException {

		if (args.length != 4) {
			System.out
					.println("Usage: QueryContributorByName [repositoryURI] [userId] [password] [NameOfUserToSearch]");
			return false;
		}

		IProgressMonitor monitor = new NullProgressMonitor();
		final String repositoryURI = args[0];
		final String userId = args[1];
		final String password = args[2];
		final String findUserByName = args[3];
		ITeamRepository teamRepository = TeamPlatform
				.getTeamRepositoryService().getTeamRepository(repositoryURI);
		teamRepository.registerLoginHandler(new LoginHandler(userId, password));
		teamRepository.login(monitor);

		/***
		 * There is a wide variety of query models available for several domains that allow to query 
		 * the elements and filter the results.
		 *
		 * For some examples on the topic
		 * @see https://jazz.net/wiki/bin/view/Main/QueryDevGuide#ExampleOne
		 * @see https://jazz.net/library/article/1229
		 */

		// Create a query for the ContributorQueryModel
		final IItemQuery query = IItemQuery.FACTORY.newInstance(ContributorQueryModel.ROOT);
		// Create a predicate with a parameter to search for name property  
		final IPredicate predicate = ContributorQueryModel.ROOT.name()._eq(query.newStringArg());
		// Use the predicate as query filter 
		final IItemQuery filtered = (IItemQuery) query.filter(predicate);
		// Get the query service. This is a cast to an internal class. Note TeamRepository and not ITeamRepository is casted.
		final IQueryService qs = ((TeamRepository) teamRepository).getQueryService();
		// Run this ItemQuery. Note, there are also other types of queries qs.queryData(dataQuery, parameters, pageSize)
		final IItemQueryPage page = qs.queryItems(filtered, new Object[] { findUserByName }, 1 /* IQueryService.DATA_QUERY_MAX_PAGE_SIZE */);
		// Get the item handles if any
		final List<?> handles = page.getItemHandles();
		System.out.println("Hits: " + handles.size());
		if (!handles.isEmpty()) {
			System.out.println("Found user.");
			// Resolve and print the information to the contributor object.
			final IContributorHandle handle = (IContributorHandle) handles.get(0);
			IContributor foundContributor = (IContributor) teamRepository.itemManager().fetchCompleteItem(handle, IItemManager.DEFAULT, monitor);
			System.out.println("UUID: " + foundContributor.getItemId());
			System.out.println("ID: " + foundContributor.getUserId());
			System.out.println("Name: " + foundContributor.getName());
			System.out.println("E-Mail: " + foundContributor.getEmailAddress());
			System.out.println("Archived: " + foundContributor.isArchived());
		}			
		teamRepository.logout();
		return true;
	}
}

Summary

As always I hope this helps someone out there with running RTC. Please keep in mind that this is as usual a collection of very basic examples with no or very limited testing and error handling. Please see the links in the getting started section for more examples, especially if you are just getting started with the RTC APIs.

Posted in Jazz, RTC, RTC Automation, RTC Extensibility | Tagged , , , , , , | 2 Comments