It's all about the answers!

Ask a question

Fetching Parent workItem using Plain Java API


2
1
Imran Akbar (56278) | asked Jan 16 '12, 5:23 a.m.
I am trying to fetch Parent of a Work Item through Plain Java Client Code, I have a code which returns the Child WI in a link, but looking for a code which will return parent WI.

Code:
IReference reference = referenceFactory.createReferenceToItem(workItem
.getItemHandle());
ILinkQueryPage page;

page = linkManager.findLinksByTarget(
"com.ibm.team.workitem.linktype.parentworkitem", reference, monitor);

ILinkCollection linkCollection = page.getLinks();

return linkCollection.getLinksById("com.ibm.team.workitem.linktype.parentworkitem");


Lets know the changes required on the above code to fetch parent Item.

9 answers



permanent link
Nick Edgar (6.5k711) | answered Jan 25 '12, 10:15 a.m.
JAZZ DEVELOPER
In the original code, you could use findLinksBySource instead of findLinksByTarget. The link type id is the same. You could use the constant com.ibm.team.workitem.common.model.WorkItemLinkTypes.PARENT_WORK_ITEM for the link type. It's a bit of a misnomer: the link type should really be called parent/child. The source end of the link is the child work item, the target end is the parent work item. Using findLinksByTarget, you were saying: "find the parent/child work item links whose parent end is X".

Comments
Albert Yao commented Nov 19 '13, 10:01 a.m.

Hi, Nick, could you give some standard sample code in your answer or comments?
The source code could be more direct and intuitionistic.


permanent link
Sola Otudeko (4511516) | answered Jan 23 '12, 6:21 a.m.
I do same in server-side but I can't imagine the code is too different:

// get the parent link

List<IReference> references= saveParameter.getNewReferences().getReferences(WorkItemEndPoints.PARENT_WORK_ITEM);

for (IReference reference: references){
// there'll only be 1 item in the list. extract the work item number
String comment = reference.getComment();
workItemID = comment.substring(0, comment.indexOf(":"));
}

...findWorkItemById(workItemID ....)


Comments
Albert Yao commented Nov 19 '13, 9:43 a.m.

It's self-contradictory: the " PARENT_WORK_ITEM " is one and only, but you use list and references, that's very strange.
Could use reference to "PARENT_WORK_ITEM" directly?


permanent link
Nick Edgar (6.5k711) | answered Jan 25 '12, 10:10 a.m.
JAZZ DEVELOPER
Rather than pulling the work item number out of the link's comment, it would be better to check reference.isItemReference(), cast down to IItemReference if so, and use IItemReference.getReferencedItem() to obtain the item handle directly (cast down to IWorkItemHandle). This avoids a round trip to look up the work item by id.

Comments
Albert Yao commented Nov 19 '13, 10:54 a.m.

Hi, Nick, do you mean these:

List<IReference> references= saveParameter.getNewReferences().getReferences(WorkItemEndPoints.PARENT_WORK_ITEM);
for (IReference reference: references)
{
    if (reference.isItemReference())
    {
        IItemHandle referencedItem = ((IItemReference) reference).getReferencedItem();
    }
}


permanent link
Audrey Wang (4123) | answered Feb 09 '12, 5:33 p.m.
We currently have defined a custom link relationship &quot;sysroute&quot;, this link is similar to the parent/child link in that one workitem can &quot;sysroute to&quot; multiple workitems while it can only be &quot;sysrouted from&quot; a single workitem. We sometimes need to know whether the link already exists to determine whether to create the link or not.

We are planning to call
 linkService.findLinks&#40;&quot;com.ibm.sport.rtc.repository.common.linkTypes.sysroutelink&quot; , 

newAparReference&#41;;

however findLinks is documented as a &quot;long operation&quot; and must not be called from a responsive thread. We would be calling it from our work item save participant. So our questions are:

1. is there a &quot;short&quot; api we can use instead to find links?
2. if not, do we need to spawn a background thread for this and what are the consequences?
3. is there a way for RTC to return an error or failure in the case when we attempt to create this custom link between WIs if the same link type already exist between these WIs?

permanent link
Nick Edgar (6.5k711) | answered Feb 10 '12, 9:59 a.m.
JAZZ DEVELOPER
Assuming this is a server-side participant, it's called expecting it to be a long-op.
IOperationParticipant.run takes an IProgressMonitor, indicating it's a long-op.
The advisor should check the monitor occasionally for cancellation, and throw OperationCanceledException too. Doing this may also work to cancel out if the link already exists (or you could just make it a no-op). Otherwise, your only recourse is to throw TeamRepositoryException, but that will present as an error as opposed to a normal contingency.

You may also want to make your links query more specific, i.e. check just source or target endpoints, rather than both.

permanent link
Audrey Wang (4123) | answered Feb 10 '12, 2:15 p.m.
Nick, thank you for your response.

Yes we are a server-side participant. But the client is forced to wait for our participant to finish before their Save action is complete, so I would think it's on a &quot;responsive thread&quot;.

For us, it's definitely a no-op if the link already exists, we are trying to make sure that as we create WIs, appropriate links are also created between WIs to represent existing relationships.

I'm not sure what you mean by
make your links query more specific, i.e. check just source or target endpoints, rather than both.
do you think that query for just source or target endpoints rather than both would be faster? As I said this link is similar to the parent/child link in that a WI can be on either end of the link, so simply finding that there is a link for the target endpoint is not sufficient to prove that it is THE link, we would need to look at the source endpoint to see whether it's the correct link.

Thanks,
Audrey

permanent link
Nick Edgar (6.5k711) | answered Feb 10 '12, 8:48 p.m.
JAZZ DEVELOPER
Hi Audrey,

If it's already gone to the server for the work item save, it's already a long op, so tacking on an extra query and item save shouldn't make a big difference. You definitely don't want to do a -very- long operation like calling out to some external system, because the advisors/participants are called within the main transaction for the operation.

In our APIs, the clear distinction between short ops and long ops is primarily there to ensure you don't do long-ops on the UI thread (and we check for this client-side and log it if you do). In this case, the work item editor is already doing a long-op for the save.

As for the links query, you say:
&quot;simply finding that there is a link for the target endpoint is not sufficient to prove that it is THE link, we would need to look at the source endpoint to see whether it's the correct link.&quot;
which really confirms my point. If you search for work item type + reference, it queries for both endpoints (both source and target). If you only care when it matches the source, it would be more efficient to use the corresponding query method, e.g. com.ibm.team.links.common.internal.IBaseLinkService.findAuditableLinksByNamesBySource(String[], IReference)
(IBaseLinkService is the parent type of ILinkService).

permanent link
Audrey Wang (4123) | answered Feb 14 '12, 3:07 p.m.
Hi Nick,

In our work item save participant, it is possible that we would be searching multiple work items for these custom links, and add the link if it does not already exist. This is because we are replicating the relationship which exists outside of RTC. It's possible, although not likely, to be looping through 10 to 20 work items searching for existence of the link. If each findLinks() is a long running method, how should our code check the Monitor for cancellation? Does the findLinks() method check for cancellation or should we wrap the call in a separate thread and occasionally check for cancellation until the call returns?

Regarding the method com.ibm.team.links.common.internal.IBaseLinkService.findAuditableLinksByNamesBySource(String[], IReference), it looks like an internal method, is it recommended to use? How would I get IBaseLinkService object? And how is this method different from com.ibm.team.links.service.ILinkServiceLibrary.findLinks(String[] linkTypeIds, IReference endpoint) ?

Thanks,
Audrey

permanent link
Nick Edgar (6.5k711) | answered Feb 14 '12, 9:54 p.m.
JAZZ DEVELOPER
Audrey, ILinkServiceLibrary is the correct interface to use -- my mistake. IBaseLinkService is the superinterface of ILinkService (from which the ILinkServiceLibrary is obtained) and its methods are used in the implementation of ILinkServiceLibrary, but they shouldn't be used directly by others. I love it when API interfaces extend internal ones ;).

If you need to check links to multiple items, it would likely be more efficient to do this all in one go rather than iterating. See:
com.ibm.team.links.service.ILinkServiceLibrary.findLinksBySource(String[], IReference[])
com.ibm.team.links.service.ILinkServiceLibrary.findLinksByTarget(String[], IReference[])

If this doesn't work, and you do need to iterate, then just check IProgressMonitor.isCanceled() on each iteration, and throw OperationCanceledException if true.

The ILinkServiceLibrary methods themselves don't take a progress monitor, so aren't cancelable.

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.