Using Expressions for Automation


If there is no query available to drive automation, it is possible to create your own expressions and use them to automate tasks. The expressions can be used similar to queries as described in Using Work Item Queries for Automation. As far as I can tell expressions are actually the fundamental mechanism that is used to create queries.

This post shows basic mechanisms to create expressions and to run them to get the result set back. 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 and Common API.

Creating an Expression
An Expression can be composed of multiple Expressions in Terms. A Term represents a Boolean operation across multiple expressions. Because I haven’t used expressions all that much I can’t describe all possible ways to use them, however, I would assume that it would be possible to create own logic for Expressions. The example below is an expression that looks for work items that are owned by a specific project area and have a specific Type (that matches an ID provided as string).

IAuditableCommon auditableCommon = (IAuditableCommon) teamRepository.getClientLibrary(IAuditableCommon.class);
IQueryableAttribute attribute = QueryableAttributes.getFactory(
	IWorkItem.ITEM_TYPE).findAttribute(projectArea,
	IWorkItem.PROJECT_AREA_PROPERTY, auditableCommon, monitor);
IQueryableAttribute type = QueryableAttributes.getFactory(
	IWorkItem.ITEM_TYPE).findAttribute(projectArea,
	IWorkItem.TYPE_PROPERTY, auditableCommon, monitor);

Expression inProjectArea = new AttributeExpression(attribute,
	AttributeOperation.EQUALS, projectArea);
Expression isType = new AttributeExpression(type,
	AttributeOperation.EQUALS, workitemTypeID);
Term typeinProjectArea= new Term(Term.Operator.AND);
typeinProjectArea.add(inProjectArea);
typeinProjectArea.add(isType);

Create a Query from an Expression

It is possible to create a query from an expression and use this as described in the post Using Work Item Queries for Automation. I have not yet found the code to save the query so that it can be used later, but this is really also not the aim of this post.

IQueryCommon queryCommon = (IQueryCommon) teamRepository.getClientLibrary(IQueryCommon.class);
IQueryDescriptor descriptor = queryCommon.createQuery(projectArea, "MyQuery", "MyQuery", typeinProjectArea);

Getting the Result Set of an Expression

It is possible to get at the result set of an expression and process it. The code below shows how. All statements about query result set size limits and running resolved and unresolved from Using Work Item Queries for Automation apply here as well.

The first method gets the result set resolved to the item profile provided.

public static IQueryResult<IResolvedResult> resultsResolvedByExpression(
		ITeamRepository teamRepository, IProjectArea projectArea,
		Expression expression, ItemProfile profile)
		throws TeamRepositoryException {
	IWorkItemClient workItemClient = (IWorkItemClient) teamRepository
			.getClientLibrary(IWorkItemClient.class);
	IQueryClient queryClient = workItemClient.getQueryClient();
	IQueryResult<IResolvedResult> results = queryClient
			.getResolvedExpressionResults(projectArea, expression, profile);
	return results;
}

The second method gets the unresolved result set.

public static IQueryResult resultsUnresolvedByExpression(
		ITeamRepository teamRepository, IProjectArea projectArea,
		Expression expression) throws TeamRepositoryException {
	IWorkItemClient workItemClient = (IWorkItemClient) teamRepository
			.getClientLibrary(IWorkItemClient.class);
	IQueryClient queryClient = workItemClient.getQueryClient();
	IQueryResult results = queryClient.getExpressionResults(
			projectArea, expression);
	return results;
}

Both methods are very similar to the code in Using Work Item Queries for Automation and the result sets can essentially be used the same way.

Handling Work Item States

You can use states and state groups in expressions. I found all these examples on the forum. The expression below shows the open states.

	IQueryableAttribute stateAttribute = QueryableAttributes.getFactory(
			IWorkItem.ITEM_TYPE).findAttribute(projectArea,
			IWorkItem.STATE_PROPERTY, auditableCommon, monitor);

	Expression openStates = new VariableAttributeExpression(stateAttribute,
			AttributeOperation.EQUALS, new StatusVariable(
					IWorkflowInfo.OPEN_STATES));

Sorting Results

You can use sort criteria to create a statement that has an expression as described above and add sort criteria. The criteria below sorts by work Item ID ascending.

	SortCriteria[] sortCriteria = new SortCriteria[] { new SortCriteria(
		IWorkItem.ID_PROPERTY, true) };
	Statement statement = new Statement(new SelectClause(),
		typeinProjectArea, sortCriteria);

The Wiki Page QueryDevGuide shows more example code.

As always I hope the code provided helps some RTC user to solve a problem and save some time.

Advertisements

About rsjazz

Hi, my name is Ralph. I work for IBM and help colleagues and customers with adopting the Jazz technologies.
This entry was posted in Jazz, RTC, RTC Extensibility and tagged , , , . Bookmark the permalink.

25 Responses to Using Expressions for Automation

  1. Pingback: Using an Expression to Synchronize Attributes for Work Items of a Specific Type | rsjazz

  2. KK says:

    Hi Ralph,

    Great post. Would it be possible to tell me how I could create query which filters by “ID”

    Ex: I want to Query “Task” by “ID”

    IS this possible with the Expressions?..

    Thanks in advance
    KK

  3. rsjazz says:

    This is possible. If you follow the pattern of the expressions, this code does look for the ID (provided as a string workitemID). Since the ID is an integer type attribute, the string is converted to an int value.

    IQueryableAttribute idAttribute = QueryableAttributes.getFactory(
    IWorkItem.ITEM_TYPE).findAttribute(projectArea,
    IWorkItem.ID_PROPERTY, auditableCommon, monitor);
    Expression hasID = new AttributeExpression(idAttribute,
    AttributeOperation.EQUALS, new Integer(workitemID).intValue());

    • KK says:

      Thanks Ralph for taking time in answering.

      Works great. Wish there were clear documentation like CQ/CC API’s

    • sud_bits says:

      Hi Ralph,
      Thanks for sharing all the information, it helped a lot to folks like me.
      Question: I’m trying to fetch work-items based on ID and download the attachments and do some further processing, I achieved that with single ID, can you suggest how can I get multiple items at a time like ID is one of ( 123,456,789, …… ). I will then store them in some Data structure and download the attachments one by one ( Or is it possible to download all attachments for all ID’s at once as well, just a thought ?? )
      I do not want to put this in a loop for one ID at a time to avoid unnecessary calls to RTC. As of now I have put it in a loop for the # of ID’s and it is working fine, but I wish I could enhance my code.
      Thanks a lot !!!

  4. KK says:

    Hi Ralph, Sorry one more question..How can query custom attributes using the above query? Obviously they are’t part of the IWorkItem

  5. rsjazz says:

    I would suggest to really look at the Java Calls. That easily reveals you basically need to pass the ID of the attribute to create an attribute expression. It does not matter if the attribute is built in. Here an example:

    IQueryableAttribute customAttribute = QueryableAttributes.getFactory(
    IWorkItem.ITEM_TYPE).findAttribute(projectArea,
    “com.company.wi.attrib.estimatedeffort”, auditableCommon, monitor);
    Expression contains = new AttributeExpression(customAttribute,
    AttributeOperation.CONTAINING, “1234”);

    Term findItem = new Term(Term.Operator.AND);
    findItem.add(contains);

  6. KK says:

    I think I got a hang of this..using findAttribute(..). For whatever reason it didn’t work initially. Thanks

  7. Nilesh Patil says:

    Hi Ralph,
    Is it possible to query RTC like ascending order or Descending order? If yes can you forward sample snippet for. it will be very helpful

  8. Mac says:

    Hi, I’ve been following a lot this site lately and I found something that is not covered (or found to be covered) in here or in the jazz forums/query dev guide: how to query work items with attachments programmatically? I have not found anything in the IWorkItem interface to point me out to anything that can say ‘Attachments’. Maybe using the IAttachment interface in the Queryable attribute, but I’m getting errors trying to use anything there.

    I know that the attribute expression should be something like this:
    AttributeExpression attachmentsExpression = new AttributeExpression(
    attachmentsAttribute, AttributeOperation.EXISTS);

    But the attachmentsAttribute (IQueryableAttribute) is incomplete. Have you tried to query work items with attachments before using the java plain APIs?

    Maybe the solution is easier than it looks like but wanted to check with you, in case this is a corner case not covered by the APIs.

    • rsjazz says:

      Mac, I have not tried to query for attachments and I am not sure it can be done. I’d suggest to search the SDK for the code you created above and try to find places where this is used.

  9. sherry says:

    Hi,
    Have you figured out the way to save the query?

  10. Bastian W. says:

    Hi Ralph,
    thank you for your great post. I use your code in my actual application to list all WorkItems for each single project area. After listing the workItems, i have sort them (modified_property):

    Expression expression = new AttributeExpression(attribute, AttributeOperation.EQUALS, projectArea);
    SortCriteria[] sortCriteria= new SortCriteria[] { new SortCriteria(IWorkItem.MODIFIED_PROPERTY, true)};
    Statement statement = new Statement(new SelectClause(), (Expression)term, sortCriteria);
    IQueryResult<IResolvedResult> results = queryClient.getResolvedExpressionResults(projectArea, statement, IWorkItem.FULL_PROFILE);

    Because my query is about all workitems and if the projectarea have maybe a few thousands of items later, i want to create another expression to limit the query. What i mean is to append a second expression like the code below:

    Expression expression2 = new AttributeExpression(attribute, AttributeOperation.EQUALS, actualDate -2 months); //only a query about the last 60 days
    Term term = new Term(Operator.AND);
    term.add(expression);
    term.add(expression2);
    Statement statement = new Statement(new SelectClause(), (Expression)term, sortCriteria);
    IQueryResult<IResolvedResult> results = queryClient.getResolvedExpressionResults(projectArea, statement, IWorkItem.FULL_PROFILE);

    Another Idea is to limit the query only to 30 WorkItems, but i don’t know how.

    Best regards!

    • rsjazz says:

      One thing to consider, there is a maximum limit of items and you can set the result size limit.

      Another consideration might be to add more qualifications to the expression to limit the results you get in the first place.

      There is only so much you can do in these cases.

  11. Srilakshmi says:

    Hi Rsjazz,
    I am first time working with RTC and
    I am querying the defects from RTC project area but I am getting the 0 records

    below is my code,

    IAuditableClient auditableClient = (IAuditableClient) repository.getClientLibrary(IAuditableClient.class);

    IQueryClient queryClient = (IQueryClient) repository.getClientLibrary(IQueryClient.class);

    IQueryableAttribute attribute = QueryableAttributes.getFactory(IWorkItem.ITEM_TYPE).findAttribute(currProject, IWorkItem.PROJECT_AREA_PROPERTY, auditableClient, null);

    IAttributeVariable variable = new WorkItemTypeVariable(“defect”);

    System.out.println(variable.getDisplayName());

    Expression expression = new AttributeExpression(attribute, AttributeOperation.EQUALS, variable);

    IQueryResult<IResolvedResult> results = queryClient.getResolvedExpressionResults(currProject, expression, IWorkItem.FULL_PROFILE);

    System.out.println(results.getResultSize(monitor).getTotal());

    Please help me, what I did the wrong in above code.

    Thanks in advance.

  12. Gan Ainm says:

    Hi Ralph,
    using the query editor in the Eclipse Client UI it is pretty straightforward to create a query for a given workitem type that has links to change sets (click “Type is X” and “Change sets exist”).

    The first part is like the “isType” Expression instance in your example above.
    However, what is the corresponding IQueryableAttribute (if at all) and Expression for the change set links? I found the fields EXISTS and LINK_EXISTS in class AttributeOperation, but how do I get the IQueryableAttribute for the operation?
    Cheers
    Gan

    • rsjazz says:

      I don’t usually know those details and have to search for them like everyone else. Searching through who implements IQueryableAttribute I found com.ibm.team.workitem.common.expression.IQueryableLinkAttribute

      If you search for IQueryableLinkAttribute and how it is used, you might find it out. Sometimes you have to experiment a bit.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s