Query model API: How do I generically generate a query
I am writing code that creates and/or updates work items from data records sent from an external software system. Because of a problem with the precision of dates when using the API that utilizes Term and AttributeExpression objects, we were told to use the internal query model API.
The code I am writing needs to create and/or update an RTC work item from the data passed from an external software package. The input data contains work item records encoded in xml. Each work item property value to be updated is contained in the input xml along with the RTC field name. What I need to know is if there is a way I can take this information and create search predicates to use in a query for a work item.
The code below is the code I am currently using to create the search predicates, but this will not work for custom attributes and, as you can see, there are query paths I have not yet figured out how to model. I'd like to find a more generic way of creating the search predicates without having to know the details of the query models used to create the query. I have dug extensively through the API and forums and can not figure out how to do this. Can you point me in the right direction?
Note: I am using the ItemQueryIterator<IWorkItemHandle>( auditableClient, itemQuery, new Object ) to execute the query.
The code I am writing needs to create and/or update an RTC work item from the data passed from an external software package. The input data contains work item records encoded in xml. Each work item property value to be updated is contained in the input xml along with the RTC field name. What I need to know is if there is a way I can take this information and create search predicates to use in a query for a work item.
The code below is the code I am currently using to create the search predicates, but this will not work for custom attributes and, as you can see, there are query paths I have not yet figured out how to model. I'd like to find a more generic way of creating the search predicates without having to know the details of the query models used to create the query. I have dug extensively through the API and forums and can not figure out how to do this. Can you point me in the right direction?
protected IPredicate createWorkItemQueryFilter( ArtifactRecordField field )
throws TeamRepositoryException
{
IPredicate fieldSrchPredicate = null;
IAuditableClient auditableClient = (IAuditableClient)getRepository()
.getClientLibrary( IAuditableClient.class );
IQueryableAttributeFactory factory = QueryableAttributes
.getFactory( IWorkItem.ITEM_TYPE );
IQueryableAttribute fieldAttr = factory.findAttribute(
getProjectArea(), field.getName(), auditableClient, null );
if (fieldAttr.getIdentifier().equals(
IWorkItem.APPROVAL_DESCRIPTORS_PROPERTY ))
{
// TODO: Implement this
throw new UnsupportedOperationException( "Creation of "
+ IWorkItem.APPROVAL_DESCRIPTORS_PROPERTY
+ " property filter not yet implemented." );
}
else if (fieldAttr.getIdentifier()
.equals( IWorkItem.APPROVALS_PROPERTY ))
{
// TODO: Implement this
throw new UnsupportedOperationException( "Creation of "
+ IWorkItem.APPROVALS_PROPERTY
+ " property filter not yet implemented." );
}
else if (fieldAttr.getIdentifier().equals( IWorkItem.CATEGORY_PROPERTY ))
{
ICategoryHandle categoryHandle = toCategory( field
.getAllValuesAsString() );
fieldSrchPredicate = WorkItemQueryModel.ROOT.category()._eq(
categoryHandle );
}
else if (fieldAttr.getIdentifier().equals( IWorkItem.COMMENTS_PROPERTY ))
{
// TODO: Implement this
throw new UnsupportedOperationException( "Creation of "
+ IWorkItem.COMMENTS_PROPERTY
+ " property filter not yet implemented." );
}
else if (fieldAttr.getIdentifier().equals(
IWorkItem.CREATION_DATE_PROPERTY ))
{
Timestamp creationDate = toTimestamp( field.getAllValuesAsString() );
fieldSrchPredicate = WorkItemQueryModel.ROOT.creationDate()._eq(
creationDate );
}
else if (fieldAttr.getIdentifier().equals( IWorkItem.CREATOR_PROPERTY ))
{
IContributorHandle creator = toContributor( field
.getAllValuesAsString() );
fieldSrchPredicate = WorkItemQueryModel.ROOT.creator()._eq( creator );
}
else if (fieldAttr.getIdentifier().equals( IWorkItem.DUE_DATE_PROPERTY ))
{
Timestamp dueDate = toTimestamp( field.getAllValuesAsString() );
fieldSrchPredicate = WorkItemQueryModel.ROOT.dueDate()._eq( dueDate );
}
else if (fieldAttr.getIdentifier().equals( IWorkItem.DURATION_PROPERTY ))
{
Integer duration = Integer.valueOf( field.getAllValuesAsString() );
fieldSrchPredicate = WorkItemQueryModel.ROOT.duration()._eq(
duration );
}
else if (fieldAttr.getIdentifier().equals( IWorkItem.FOUND_IN_PROPERTY ))
{
// TODO: Implement this
throw new UnsupportedOperationException( "Creation of "
+ IWorkItem.FOUND_IN_PROPERTY
+ " property filter not yet implemented." );
}
else if (fieldAttr.getIdentifier().equals( IWorkItem.DURATION_PROPERTY ))
{
Integer duration = Integer.valueOf( field.getAllValuesAsString() );
fieldSrchPredicate = WorkItemQueryModel.ROOT.duration()._eq(
duration );
}
else if (fieldAttr.getIdentifier().equals( IWorkItem.ID_PROPERTY ))
{
Integer id = Integer.valueOf( field.getAllValuesAsString() );
fieldSrchPredicate = WorkItemQueryModel.ROOT.id()._eq( id );
}
else if (fieldAttr.getIdentifier().equals( IWorkItem.ID_PROPERTY ))
{
Integer id = Integer.valueOf( field.getAllValuesAsString() );
fieldSrchPredicate = WorkItemQueryModel.ROOT.id()._eq( id );
}
else if (fieldAttr.getIdentifier().equals( IWorkItem.OWNER_PROPERTY ))
{
IContributorHandle contributorHandle = toContributor( field
.getAllValuesAsString() );
fieldSrchPredicate = WorkItemQueryModel.ROOT.owner()._eq(
contributorHandle );
}
else if (fieldAttr.getIdentifier().equals( IWorkItem.PRIORITY_PROPERTY ))
{
fieldSrchPredicate = WorkItemQueryModel.ROOT.internalPriority()._eq(
field.getAllValuesAsString() );
}
else if (fieldAttr.getIdentifier().equals(
IWorkItem.PROJECT_AREA_PROPERTY ))
{
IProjectAreaHandle projectAreaHandle = toProjectArea( field
.getAllValuesAsString() );
fieldSrchPredicate = WorkItemQueryModel.ROOT.projectArea()._eq(
projectAreaHandle );
}
else if (fieldAttr.getIdentifier().equals(
IWorkItem.RESOLUTION_DATE_PROPERTY ))
{
Timestamp resolutionDate = toTimestamp( field.getAllValuesAsString() );
fieldSrchPredicate = WorkItemQueryModel.ROOT.resolutionDate()._eq(
resolutionDate );
}
else if (fieldAttr.getIdentifier().equals(
IWorkItem.RESOLUTION_PROPERTY ))
{
// TODO: Does this need to be processed differently?????
fieldSrchPredicate = WorkItemQueryModel.ROOT.internalResolution()
._eq( field.getAllValuesAsString() );
}
else if (fieldAttr.getIdentifier().equals( IWorkItem.RESOLVER_PROPERTY ))
{
IContributorHandle resolver = toContributor( field
.getAllValuesAsString() );
fieldSrchPredicate = WorkItemQueryModel.ROOT.resolver()._eq(
resolver );
}
else if (fieldAttr.getIdentifier().equals( IWorkItem.SEVERITY_PROPERTY ))
{
fieldSrchPredicate = WorkItemQueryModel.ROOT.internalSeverity()._eq(
field.getAllValuesAsString() );
}
else if (fieldAttr.getIdentifier().equals( IWorkItem.STATE_PROPERTY ))
{
// Does this need to be processed differently????? i.e. if the
// value is a state transition string
fieldSrchPredicate = WorkItemQueryModel.ROOT.internalState()._eq(
field.getAllValuesAsString() );
}
else if (fieldAttr.getIdentifier().equals(
IWorkItem.SUBSCRIPTIONS_PROPERTY ))
{
// TODO: Implement this
throw new UnsupportedOperationException( "Creation of "
+ IWorkItem.SUBSCRIPTIONS_PROPERTY
+ " property filter not yet implemented." );
}
else if (fieldAttr.getIdentifier().equals( IWorkItem.SUMMARY_PROPERTY ))
{
fieldSrchPredicate = WorkItemQueryModel.ROOT.summary()._eq(
field.getAllValuesAsString() );
}
else if (fieldAttr.getIdentifier().equals( IWorkItem.TAGS_PROPERTY ))
{
fieldSrchPredicate = WorkItemQueryModel.ROOT.internalTags()._eq(
field.getAllValuesAsString() );
}
else if (fieldAttr.getIdentifier().equals( IWorkItem.TARGET_PROPERTY ))
{
// TODO: Implement this
throw new UnsupportedOperationException( "Creation of "
+ IWorkItem.TARGET_PROPERTY
+ " property filter not yet implemented." );
}
else if (fieldAttr.getIdentifier().equals( IItem.CONTEXT_ID_PROPERTY ))
{
UUID contextId = UUID.valueOf( field.getAllValuesAsString() );
fieldSrchPredicate = WorkItemQueryModel.ROOT.contextId()._eq(
contextId );
}
else if (fieldAttr.getIdentifier().equals( IItem.ITEM_ID_PROPERTY ))
{
UUID itemId = UUID.valueOf( field.getAllValuesAsString() );
fieldSrchPredicate = WorkItemQueryModel.ROOT.itemId()._eq( itemId );
}
else if (fieldAttr.getIdentifier().equals( IItem.MODIFIED_BY_PROPERTY ))
{
IContributorHandle modifiedBy = toContributor( field
.getAllValuesAsString() );
fieldSrchPredicate = WorkItemQueryModel.ROOT.modifiedBy()._eq(
modifiedBy );
}
else if (fieldAttr.getIdentifier().equals( IItem.MODIFIED_PROPERTY ))
{
Timestamp modified = toTimestamp( field.getAllValuesAsString() );
fieldSrchPredicate = WorkItemQueryModel.ROOT.modified()._eq(
modified );
}
else if (fieldAttr.getIdentifier().equals( IItem.STATE_ID_PROPERTY ))
{
UUID stateId = UUID.valueOf( field.getAllValuesAsString() );
fieldSrchPredicate = WorkItemQueryModel.ROOT.stateId()._eq( stateId );
}
else if (fieldAttr.isStateExtension())
{
// TODO: Implement this
throw new UnsupportedOperationException(
"Creation of property filter for state extension not yet implemented." );
}
return fieldSrchPredicate;
}
2 answers
The code below is the code I am currently using to create the search
predicates, but this will not work for custom attributes and, as you
can see, there are query paths I have not yet figured out how to
model. I'd like to find a more generic way of creating the search
predicates without having to know the details of the query models
used to create the query. I have dug extensively through the API and
forums and can not figure out how to do this. Can you point me in the
right direction?
You may want to take a look at IDynamicQueryModel, where the String
attribute identifier can be used to get at the fields and references. When
you look the the class ASTTransformer, you see an example of how it can be
used.
If the date operator issue is the only thing that blocks you from using
the work item query api, you may also want to consider to write our own
AttributeOperation which does the simple timestamp comparison.
--
Regards,
Patrick
Jazz Work Item Team
If the date operator issue is the only thing that blocks you from using
the work item query api, you may also want to consider to write our own
AttributeOperation which does the simple timestamp comparison.
I don't think an end user can do this, can they? AttributeOperation is an abstract class that only has private constructors (thus it cannot be extended) and all of the pre-made instances (like AFTER) are marked as final and thus cannot be extended either.