Programmatic query to represent WI with attribute set to value among multiple values
I have written code to query for work items containing certain values in specific attributes.
The work item type has custom attribute "Profile/Edition/Delivery Vehicle" and the query wants to look for WIs where this attribute's value can be any of these values:
- Liberty
- Open Liberty
- Migration Toolkit
- Eclipse Toolkit/WDT
(My screenshot can make crystal clear what I'm trying to say in words, but this forum is not allowing me to attach an image.)
My code that tries to mimic this is like so (understand that I've omitted other expressions in order to simplify this post):
Term workItems = new Term(Operator.AND);
IAttribute profileEditionAttr = repo.findAttribute("profileOrEdition");
IQueryableAttribute profileEditionQueryable = repo.findQueryableAttribute("profileOrEdition");
Identifier<? extends ILiteral> liberty = repo.findLiteralByName("Liberty", profileEditionAttr);
AttributeExpression libertyExpression = new AttributeExpression(profileEditionQueryable,
AttributeOperation.EQUALS,
liberty);
Identifier<? extends ILiteral> openLiberty = repo.findLiteralByName("Open Liberty", profileEditionAttr);
AttributeExpression olExpression = new AttributeExpression(profileEditionQueryable,
AttributeOperation.EQUALS,
openLiberty);
Identifier<? extends ILiteral> wdt = repo.findLiteralByName("Eclipse Tools/WDT", profileEditionAttr);
AttributeExpression wdtExpression = new AttributeExpression(profileEditionQueryable,
AttributeOperation.EQUALS,
wdt);
Identifier<? extends ILiteral> migration = repo.findLiteralByName("Migration Toolkit", profileEditionAttr);
AttributeExpression migrationExpression = new AttributeExpression(profileEditionQueryable,
AttributeOperation.EQUALS,
migration);
// TODO: Only one expression for profileEdition works
// Adding all four results in empty query.
workItems .add(libertyExpression);
workItems .add(olExpression);
workItems .add(wdtExpression);
workItems .add(migrationExpression);
/ Sort by id /
SortCriteria byId = new SortCriteria(repo.findQueryableAttribute(IWorkItem.ID_PROPERTY), true);
/ Create statement /
Statement s = new Statement(new SelectClause(), newItemsToBridgeToGHE, new SortCriteria[] { byId });
// Blah blah, execute query and etc
The query will return zero results if I add all those expressions to the Term object. However, if I add only one of those--like, libertyExpression, which represents the value of "Liberty" for that attribute--the query returns the expected work items.
Again, I want to query for WIs that can have any one of those values for "Profile/Edition." If I can accomplish that very simple goal with a query created in browser client, surely this must be possible through the APIs, correct?
And note that I am also having the same problem with built-in attribute "Planned For."
Accepted answer
This code works for me. It basically creates an expression "Priority High" one expression "Priority Medium", then it creates a Term for Priority High or Medium.
It creates an expression for "In Project Area" and "Is Type". Then it creates a final term
InProjectArea AND isType AND isPriorityHighOrMedium by adding the Term it constructed in the beginning.
I did only a quick test, but it returned the number of objects I expected as I made this up.
IAuditableCommon auditableCommon = (IAuditableCommon) teamRepository .getClientLibrary(IAuditableCommon.class);
IWorkItemCommon workitenCommon = (IWorkItemCommon) teamRepository .getClientLibrary(IWorkItemCommon.class);IQueryableAttribute queryablePrio = QueryableAttributes.getFactory( IWorkItem.ITEM_TYPE).findAttribute(projectArea, IWorkItem.PRIORITY_PROPERTY, auditableCommon, monitor); IAttribute prioAttrib = workitenCommon.findAttribute(projectArea, IWorkItem.PRIORITY_PROPERTY, monitor); // Prio High or Medium Identifier<? extends ILiteral> high = getLiteralEqualsString("High", workitenCommon, prioAttrib); Expression isHigh = new AttributeExpression(queryablePrio, AttributeOperation.EQUALS, high); Identifier<!--? extends ILiteral--><? extends ILiteral> med = getLiteralEqualsString("Medium", workitenCommon, prioAttrib); Expression isMed = new AttributeExpression(queryablePrio, AttributeOperation.EQUALS, med); Term priorityHighOrMedium = new Term(Term.Operator.OR); priorityHighOrMedium.add(isHigh); priorityHighOrMedium.add(isMed); // Project Area And Type IQueryableAttribute queryProjectArea = QueryableAttributes.getFactory( IWorkItem.ITEM_TYPE).findAttribute(projectArea, IWorkItem.PROJECT_AREA_PROPERTY, auditableCommon, monitor); Expression inProjectArea = new AttributeExpression(queryProjectArea, AttributeOperation.EQUALS, projectArea); IQueryableAttribute type = QueryableAttributes.getFactory( IWorkItem.ITEM_TYPE).findAttribute(projectArea, IWorkItem.TYPE_PROPERTY, auditableCommon, monitor); Expression isType = new AttributeExpression(type, AttributeOperation.EQUALS, workitemTypeID); Term typeinProjectArea = new Term(Term.Operator.AND); typeinProjectArea.add(inProjectArea); typeinProjectArea.add(isType); // Add Medium Or High typeinProjectArea.add(priorityHighOrMedium);
Comments
So, after another revision pass of my code, using the above code snippet provided by Ralph as a model to use, the programmatic query now works properly. To re-iterate, problem was not the usage of an internal utility class to get the proper Identifier object representing the enumeration value (or whatever you call it). That remains the same. The key was in creating separate Term objects with Operator.OR that represents that WI can have one of specified values for "Profile/Edition" and any of etc values for "Planned For." Then adding those two Term objects to the Term object created with Operator. AND.
Thank you!
2 other answers
Does it succeed if you try
Comments
No, it doesn't work. :(
I get this error:
org.eclipse.core.runtime.AssertionFailedException: assertion failed:
AND operation does not seem to make sense as the attribute can always ever only be one of the four values. The AssertionFaliedException truly has more information. Maybe investigate what it is trying to tell you. Likely something wrong with the code.
I have explained what I have tried here: https://rsjazz.wordpress.com/2012/11/19/using-expressions-for-automation/
You are using your own utility classes, so there is no way anyone out here is going to be able to help. Have you considered to talk to others in your internal community, should you be aware of anyone?
Comments
I'm using a custom utility class to get the Identifier, yes, true, but that's it. I don't see how that makes much difference--since I can confirm that when I use only one and any one of expression to add to the Term object, the query works (it returns expected work items having that value for the attribute).
No one in my "internal community" knows the answer--which is why I came here. I am using RTC client APIs, which I thought was the within the purvue of this forum?
Didn't say it was off topic. Did say I don't recognize your code. Custom code, so no way to test it without rewriting it.
Also an AND operation if you want to query for value A OR value B OR value C does not make sense. An assertion failed happens somewhere and usually provides a bit more information.
So pretty much no information anyone could work on.