It's all about the answers!

Ask a question

How to fetch workitem Approvals through Jazz API


0
1
Kelvin Lui (51299) | asked Jan 19 '12, 11:31 a.m.
Hi,

I developed a java client to retrieve a workitem base on several criteria.

Now I tried to retrieve the Approvals associated with this workitem and retrieve the Reviewer/submitter of the Approvals:

IApprovals approvals = searchWorkItem.getApprovals();
java.util.List<IApproval> approval = approvals.getContents() ;

From the JavaDoc the object com.ibm.team.workitem.common.model.IApprovals has the following method:

IContributorHandle getApprover() -> Returns the contributor that is asked for approval.
IApprovalDescriptor getDescriptor() -> Returns the approval descriptor this approval belongs to.

I tried to retrieve both IContributorHandle and IApprovalDescriptor objects but have no luck here.

Could someone please help here?

Thanks.

13 answers



permanent link
Nick Edgar (6.5k711) | answered Jan 20 '12, 10:50 a.m.
JAZZ DEVELOPER
Kelvin and I sorted this out over chat (and I asked that API usage questions be posted in the Extending RTC forum).

Need to use ITeamRepository.itemManager() to get the IItemManager, and use its fetch methods to fetch the contributor items, given the contributor handles.

One potential gotcha to be aware of with the IItemManager fetch methods. The single-item fetch methods throw an exception (ItemNotFoundException) if the item no longer exists (or can't be seen by the user). The multi-fetch methods return null in the resulting list, so need to check for that. The safer one to use is com.ibm.team.repository.client.IItemManager.fetchCompleteItemsPermissionAware(List, int, IProgressMonitor), since the resulting fetch result object has them partitioned into fetched, missing, and permission denied, so avoids the risk of nulls.

permanent link
Kelvin Lui (51299) | answered Feb 03 '12, 5:01 p.m.
Nick,

I looked up on Java Doc IItemManager.fetchCompleteItemsPermissionAware requires three parameters:

IFetchResult fetchCompleteItemsPermissionAware(java.util.List itemHandles,
int flags,
IProgressMonitor monitor)

I have the following question:

1. Do you refer itemHandles as IContributorHandle that I retrieved from method IApproval.getApprover()?

IApprovals approvals = searchWorkItem.getApprovals();
java.util.List<IApproval> approval = approvals.getContents() ;
IApproval temp = approval.get(0);
IContributorHandle contributorimpl = temp.getApprover();

2. Any recommended value for the flags parameters? - here is the description from JavaDoc: bit-wise OR of the constants declared on this interface; specify (@link #DEFAULT IItemManager.DEFAULT} to get a shared item (recommended) that tracks the current state of the item; specify (@link #REFRESH IItemManager.REFRESH} to ensure that the shared item is up-to-date; specify (@link #UNSHARED IItemManager.UNSHARED} to return the current state of the item not as a shared item (and without affecting the shared item if one exists)

3. IItemManager.fetchCompleteItemsPermissionAware returns IFetchResult (List). I assume to call the method IFetchResult.getRetrievedItems() to get the object com.ibm.team.repository.common.model.impl.ContributorImpl

and thus getting the approver's name.

Please correct me if my understanding is incorrect.

Thanks.

permanent link
Nick Edgar (6.5k711) | answered Feb 03 '12, 5:19 p.m.
JAZZ DEVELOPER
Hi Kelvin, yes that's all correct.

You also probably want to iterate over all the approvals and collect all the contributor handles, and fetch them all in one call to fetchCompleteItemsPermissionAware, to reduce the number of round trips to the server.

This is a very common pattern in Jazz:
- get an IXYZHandle (or array or list of them) from somewhere
- collect as many of these as you're dealing with at the time, to reduce round trips to the server and/or database
- fetch the items using one of the IItemManager (client-side) or IRepositoryItemService (server-side) methods
- it returns the fetched IXYZ items

permanent link
Kelvin Lui (51299) | answered Feb 16 '12, 11:30 a.m.
Hi Nick,

I tried the following code. I think itemManager.fetchCompleteItemsPermissionAware returns the list.

And looks like IFetchResult.getRetrievedItems() also returns a list.

When I tried to retrieve an object for the List and cast it to object com.ibm.team.repository.common.model.impl.ContributorImpl, I got the follow exception:

Exception in thread "main" java.lang.ClassCastException: $Proxy10 incompatible with com.ibm.team.repository.common.model.impl.ContributorImpl
at com.ibm.websphere.rtc.workItem.RTCManager.getWorkItemNumberFromAPARNumber(RTCManager.java:464)
at com.ibm.websphere.rtc.workItem.RTCManager.queryDefectbyAPARNumber(RTCManager.java:493)
at com.ibm.websphere.rtc.workItem.TestClass_RTCManager.queryDefect(TestClass_RTCManager.java:36)
at com.ibm.websphere.rtc.workItem.TestClass_RTCManager.main(TestClass_RTCManager.java:60)

Could you please shed some light here? Thanks.


Here is the code snippet:


List <IContributorHandle> temp21 = new ArrayList<IContributorHandle>();

for (int i=0; i < approval.size(); i++){
IApproval temp = approval.get(i);
IContributorHandle contributorimpl = temp.getApprover();
System.out.println ("contributorimpl: " + contributorimpl.toString());
temp21.add(0, contributorimpl);
}

IItemManager itemManager = teamRepository.itemManager();
IFetchResult temp100 = itemManager.fetchCompleteItemsPermissionAware(temp21, 0, monitor);
List <com> temp200 = null;
temp200 = temp100.getRetrievedItems();

if (temp200!=null){
System.out.println ("temp200 is not null");

for (int i=0; i < temp200.size(); i++){
com.ibm.team.repository.common.model.impl.ContributorImpl _contributorimpl = (com.ibm.team.repository.common.model.impl.ContributorImpl) temp200.get(i);
System.out.println("_contributorimpl: "+ _contributorimpl.getEmailAddress());
}

}else {
System.out.println ("temp200 is null");
}

permanent link
Nick Edgar (6.5k711) | answered Feb 16 '12, 9:44 p.m.
JAZZ DEVELOPER
The pattern in Jazz/RTC programming for fetching items is:
- get an IXYZHandle object
- fetch it, usually via IItemManager.fetch*
- get the items from the result and cast them to IXYZ

Here, you're casting down to XYZImpl, which is casting down too far.
Try casting down to IContributor (fully qualified name: com.ibm.team.repository.common.IContributor) instead.

The reason it's failing is because, although the underlying concrete item class is ContributorImpl, the item is wrapped in a dynamic proxy that implements IContributor but does not implement or extend ContributorImpl.

In general, if you're referring to types with 'internal' in the package name, that's a sign that you've strayed away from the public API.

permanent link
Kelvin Lui (51299) | answered Mar 05 '12, 3:00 p.m.
Thanks Nick. Any idea what would be the steps/APIs to fetch children/related work Item associated with the parent work Item? I looked up on the IWorkItem but have no luck there.

Thanks.

permanent link
Kelvin Lui (51299) | answered Mar 05 '12, 3:10 p.m.
Sorry another question that I have is:

How to fetch change set associated with the workitem? Basically I want to identify the list of file per change set delivered by specific workitem.

Thanks.

permanent link
Nick Edgar (6.5k711) | answered Mar 05 '12, 4:18 p.m.
JAZZ DEVELOPER
Hi Kelvin,

Child/related work items are represented as links. See the methods on com.ibm.team.links.client.ILinkManager and search the forums for examples (actually, API questions like this should really go in the Extending Team Concert forum).

For getting a summary of the contents of a change set, you can fetch the IChangeSet items from the IChangeSetHandle handles using the pattern above, which will let you list the individual IChange's to items in the change set. These only carry the simple item name, though, not the path. To get the paths, you need to use com.ibm.team.filesystem.client.IFileSystemView.interpretChanges(List, IProgressMonitor) to get the corresponding IChangeSetSummary's.
See https://jazz.net/forums/viewtopic.php?t=21533 for details.

permanent link
Kelvin Lui (51299) | answered Mar 06 '12, 1:07 p.m.
Nick, thanks.

I searched on the forum by using the key term "ILinkManager". There are 16 docs returned and most of them referring on "creating the new link".

There is one doc to show how to retrieve change set assoicated to work item:
https://jazz.net/forums/viewtopic.php?t=839&highlight=ilinkmanager&sid=c47e9624773867c04d37488bd6b457c5

From the doc:

ILinkManager linkManager = (ILinkManager) repository.getClientLibrary(ILinkManager.class);
IReferenceFactory referenceFactory = linkManager.referenceFactory();
IReference workItemReference = referenceFactory.createReferenceToItem(workItem.getItemHandle());


//Find all ILinks which attach a change set to the work item.
ILinkQueryPage linkQueryPage = null;
try {

linkQueryPage = linkManager.findLinksByTarget("com.ibm.team.filesystem.workitems.change_set", workItemReference, monitor);
} catch (TeamRepositoryException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
ILinkCollection linkCollection = linkQueryPage.getAllLinksFromHereOn();

//Put the ILinks in a list.
List<ILink> linksById = (List<ILink>)linkCollection.getLinksById("com.ibm.team.filesystem.workitems.change_set");

List<ILink> changeSetLinks = linksById;
System.out.println("********************"+ linksById.size()); //ALWAYS getting size 0
List<IReference> changeSetReferences = new ArrayList<IReference>();
for (ILink link : changeSetLinks) {
IChangeSetHandle changeSetHandle = (IChangeSetHandle)link.getSourceRef().resolve();
ItemId<IChangeSet> changeSetItemId = ChangeSetUtil.getChangeSet(changeSetHandle);


From the java doc the method findLinksByTarget can look up any link type associated with the workitem (link to change-set or link to other workitem).

I assume the same code snippet above can retrieve the link to other workitem to identify the Link type and id. For example:
"com.ibm.team.filesystem.workitems.change_set"

If my assumption is correct what would be the link type name, which returns the ILink objects.


According to the same forum page would it be one of the following type.

Could you please confirm if my understanding is correct or not?

Thanks.

public static final String RELATED_WORK_ITEM= "com.ibm.team.workitem.linktype.relatedworkitem"; //$NON-NLS-1$
public static final String DUPLICATE_WORK_ITEM= "com.ibm.team.workitem.linktype.duplicateworkitem"; //$NON-NLS-1$
public static final String COPIED_WORK_ITEM= "com.ibm.team.workitem.linktype.copiedworkitem"; //$NON-NLS-1$
public static final String RELATED_ARTIFACT= "com.ibm.team.workitem.linktype.relatedartifact"; //$NON-NLS-1$
public static final String ATTACHMENT= "com.ibm.team.workitem.linktype.attachment"; //$NON-NLS-1$
public static final String BLOCKS_WORK_ITEM= "com.ibm.team.workitem.linktype.blocksworkitem"; //$NON-NLS-1$
public static final String PARENT_WORK_ITEM= "com.ibm.team.workitem.linktype.parentworkitem"; //$NON-NLS-1$

permanent link
Nick Edgar (6.5k711) | answered Mar 09 '12, 3:32 p.m.
JAZZ DEVELOPER
I'm not sure I understand the question:
> If my assumption is correct what would be the link type name, which returns the ILink objects.

The ILinkManager.find* methods can be used to find any kind of links between two items. ILink is the type of object returned in all cases. An ILink represents a link between a source reference and a target reference, where a reference (IReference) may be either an item reference (item handle) to an item in the same repostiory, or an URI reference (arbitrary URL, sometimes used to refer to items in other repositories).

In the case of the "com.ibm.team.filesystem.workitems.change_set" link type id, the source reference is a change set handle (IChangeSetHandle) and the target is a work item handle (IWorkItemHandle).

To search for change sets associated with a given work item, you'd use findLinksByTarget. To search for work items associated with a given change set, you'd use findLinksBySource.

To get the resulting item handles from the ILinks in the result, use:

IReference ref = link.getSourceReference(); // or getTargetReference()
if (ref.isItemReference()) {
IItemReference itemRef = (IItemReference) ref;
IItemHandle itemHandle = itemRef.getReferencedItem();
}


Then cast the itemHandle down to IChangeSetHandle or IWorkItemHandle as appropriate.

Your answer


Register or to post your answer.


Dashboards and work items are no longer publicly available, so some links may be invalid. We now provide similar information through other means. Learn more here.