It's all about the answers!

Ask a question

Operation Advisor - Custom Precondition for Work Items


Phillip Piper (15812424) | asked Sep 29 '11, 3:58 p.m.
edited Aug 03 '12, 7:28 p.m. by Jared Burns (4.4k29)
I am just starting with extending our RTC server. I downloaded the SDK and started reviewing the following links:
https://jazz.net/wiki/bin/view/Main/CustomPreconditionFollowup
https://jazz.net/library/article/495/

What I would like to do is require that change sets have been delivered prior to transitioning a work item to a specific state. I thought this could be achieved via an extension to the com.ibm.team.workitem.operation.workItemSave operation ID.

There are aspects of this that I'd like to model off existing preconditions. Is there a way to pull the existing precondition code to review? I am not sure if they are in the source that comes with the SDK or where it would be located.

Also, is there any article that discusses custom preconditions which modify the UI? I'd like people to be able to select states similar to the "Prevent Editing" precondition.

Finally, on another note, it might be nice if RTC provided a plug-in template which could be used for different ways to extend it.

Anyway, I'll take any assistance from anybody that has coded up their own custom preconditions. Thanks in advance.

Accepted answer


permanent link
sam detweiler (12.4k6175200) | answered Nov 16 '11, 10:42 a.m.
edited Mar 23 '15, 8:07 a.m.
here is my complete, and operating PreCondition OperationAdvisor..

this enforces 'Depends On' links to actually DEPEND on the remote end item being resolved.. This works on 3.0 ifix1 and 3.0.1 and thru 5.2 in binary form.

package xxxxx;; // set your package name

import org.eclipse.core.runtime.IProgressMonitor;

import com.ibm.team.links.common.IReference;
import com.ibm.team.process.common.IProcessConfigurationElement;
import com.ibm.team.process.common.advice.AdvisableOperation;
import com.ibm.team.process.common.advice.IAdvisorInfo;
import com.ibm.team.process.common.advice.IAdvisorInfoCollector;
import com.ibm.team.process.common.advice.runtime.IOperationAdvisor;
import com.ibm.team.repository.common.IAuditable;
import com.ibm.team.repository.common.TeamRepositoryException;
import com.ibm.team.repository.service.AbstractService;
import com.ibm.team.workitem.common.IAuditableCommon;
import com.ibm.team.workitem.common.ISaveParameter;
import com.ibm.team.workitem.common.internal.workflow.WorkflowManager;
import com.ibm.team.workitem.common.model.IWorkItem;
import com.ibm.team.workitem.common.model.IWorkItemHandle;
import com.ibm.team.workitem.common.model.WorkItemEndPoints;
import com.ibm.team.workitem.common.workflow.IWorkflowInfo;

@SuppressWarnings("restriction")
public class WorkItemFailAdvisor extends AbstractService implements IOperationAdvisor{

private static boolean Debug = false;

public void run(AdvisableOperation operation, IProcessConfigurationElement advisorConfiguration, IAdvisorInfoCollector collector, IProgressMonitor monitor) throws TeamRepositoryException
{
if(Debug) System.out.println("in operation advisor");
// get the operation data
Object data= operation.getOperationData();

// is this a 'save' operation?
if (data instanceof ISaveParameter)
{
// get the affected object
IAuditable auditable = ((ISaveParameter) data).getNewState();

// if this is a workitem
if (auditable instanceof IWorkItem)
{
// get the worker objects
IAuditableCommon iac = ((ISaveParameter) data).getSaveOperationParameter().getAuditableCommon();
WorkflowManager wfm = new WorkflowManager(iac);

// reference the right object type (cast)
IWorkItem workItem = (IWorkItem) auditable;
// get the workflow this workitem is in, so we can get the labels of the states
IWorkflowInfo x =wfm.getWorkflowInfo(workItem, monitor);

if(Debug) System.out.println("the workitem state is "+ workItem.getState2().getStringIdentifier()+ "=" +x.getStateName(workItem.getState2()) );
// if this workitem is going into resolved state (we are checking 'proposed new' state
// can't use 'Resolved', as Storys have 'Done' state
if(x.stateGroupContains(IWorkflowInfo.CLOSED_STATES, workItem.getState2()))
{
// loop thru this workitems dependencies
for(IReference ir: ((ISaveParameter) data).getNewReferences().getReferences(WorkItemEndPoints.DEPENDS_ON_WORK_ITEM))
{
if(ir.isItemReference())
{
// get the item, and it SHOULD always be a workitem
IWorkItem r = iac.resolveAuditable((IWorkItemHandle)ir.resolve(),IWorkItem.FULL_PROFILE, null);

// get the workflow this workitem is in..
IWorkflowInfo y =wfm.getWorkflowInfo(r, monitor);

if(Debug) System.out.println("the target workitem state is "+r.getState2().getStringIdentifier()+"="+y.getStateName(r.getState2()));
// get to see if this referenced workitem is resolved
if(!y.stateGroupContains(IWorkflowInfo.CLOSED_STATES, r.getState2()))
{
// if not resolved, then we can't resolve this one
IAdvisorInfo info = collector.createProblemInfo("Dependency not resolved", "Workitem "+ r.getId()+ " is not Resolved", "error");
// tell the caller to post an error, and reject the action
collector.addInfo(info);
}
}
}
}
}
}
}
}
Ralph Schoon selected this answer as the correct answer

Comments
1
Ralph Schoon commented Aug 02 '12, 7:43 a.m.
FORUM ADMINISTRATOR / FORUM MODERATOR / JAZZ DEVELOPER

Sam, one observation. You always want to add extends AbstractService to the class.


sam detweiler commented Aug 03 '12, 5:56 p.m.

good catch thanks, fixed here.. this was a cut/paste from some workshop sample I think.


Ralph Schoon commented Aug 03 '12, 7:07 p.m. | edited Aug 03 '12, 7:07 p.m.
FORUM ADMINISTRATOR / FORUM MODERATOR / JAZZ DEVELOPER

@sam, it is a great plasure to work with you and your contributions anre just extraordinary. Thank you so much! I had the same C&P issue and it got me into a lot of trouble. 8-)


sam detweiler commented Oct 11 '12, 2:35 p.m.

hey, we found a bug.. this advisor only works if the terminal state of the other workitem is 'Resolved'.. Stories terminate in 'Done'.. so, I gotta update the code..


sam detweiler commented Nov 17 '12, 11:45 p.m.

I updated the code to resolve the bug when the end of the links closed state was not 'resolved' (but done or complete).. this also handles if the target was invalidated.


Binoy D'costa commented Nov 05 '14, 11:15 a.m.

Hi Sam,

In your code you have the dependsOn workitem end point: WorkItemEndPoints.DEPENDS_ON_WORK_ITEM. What would be the end points for other link types? how can i find out?

Thanks,
Binoy


sam detweiler commented Nov 05 '14, 11:23 a.m. | edited Nov 05 '14, 11:57 a.m.

If you are using Eclipse, then create a new line, type WorkItemEndPoints
then hit the dot/period, and a popup should list all the other items on that class


assuming of course you have the libraries setup properly for jazz application development

showing 5 of 7 show 2 more comments

13 other answers



permanent link
Phillip Piper (15812424) | answered Sep 30 '11, 10:02 a.m.
I think I figured out some of this based on the video in Part 1 at this link:
https://jazz.net/wiki/bin/view/Main/RTCSDK20_ProcessPreConditionExample

This was extremely helpful to me in terms of finding how to search the source, etc. It may have been obvious to everyone else but it wasn't to me since I only found binaries when I looked at the SDK on the file system.

I was able to locate the existing precondition source code. This information also seemed to be missing from the other articles I saw.

I think it would be extremely helpful to merge and streamline the precondition articles or setup. It seems like each article has its own environment setup instructions along with the SDK having their own as well. I've had to read a number of articles and have had trouble determining which steps I need to follow.

permanent link
Ralph Schoon (56.3k23642) | answered Oct 07 '11, 12:57 p.m.
FORUM ADMINISTRATOR / FORUM MODERATOR / JAZZ DEVELOPER
Hi Philip,

you might also want to have a look at the Extensions workshop in the library. It is for 3.0 and I am in the process of upgrading it, but it is still helpfull to understand the setup for development.

permanent link
Phillip Piper (15812424) | answered Oct 10 '11, 10:02 a.m.
Hi Philip,

you might also want to have a look at the Extensions workshop in the library. It is for 3.0 and I am in the process of upgrading it, but it is still helpfull to understand the setup for development.


Ralph, thanks. I take a look in the coming days here and see if I am still having problems.

permanent link
Phillip Piper (15812424) | answered Nov 16 '11, 10:30 a.m.
Ralph,

Thanks so much for this information. I reviewed the extensions workshop and I found a lot of helpful information. I think it's the most comprehensive thing I've read so far.

Just some feedback:
1. I think this path is helpful at the conclusion of the workshop to include additional sample code that can be downloaded for review. Something like a series of example preconditions and followups for a few common classes you may be using with a paragraph description of each. No need to step through everything but at least it provides an additional template to start from.
2. I am not sure I understand how I can determine exactly what services I require for what I want to do.

My struggle is that currently I want to do something which I believe is probably fairly simple but I get stuck on a few questions.

To be more specific, we currently require an associated work item to deliver a change set. Now I want to create another condition that further verifies the type and state of that associated work item before you can deliver.
However, I am not sure of what applies from the workshop because:
1. I am not sure what services I require
2. I don't know #1 partly because the lab covered a different operationID and because it was a followup not a precondition

I think any examples for deliver (server) preconditions may be helpful to me here as a result.

permanent link
Ralph Schoon (56.3k23642) | answered Nov 16 '11, 11:32 a.m.
FORUM ADMINISTRATOR / FORUM MODERATOR / JAZZ DEVELOPER
Hi Sam,

I ruthlessly stole your code and intent to incorporate it in my set of example trophies, if that is OK with you. I will put your name in as author.

Phillip,

there are several examples in the WiKi: https://jazz.net/wiki/bin/view/Main/RtcSdk20 they are hard to find.

I agree, it would be great to have all these examples. It comes down to be get clearance to publish code and resources to create, collect and worse maintain it.

The workshop has been updated recently.
The services, you need at least

com.ibm.team.repository.service.IRepositoryItemService
com.ibm.team.scm.common.IScmService


I think it does not matter if pre- or postcondition as long as the required interface is similar.

permanent link
sam detweiler (12.4k6175200) | answered Nov 16 '11, 11:51 a.m.
no problem.. don't care about attribution.. just trying to help others as they have helped me

I also submitted this to enhancement 182769.. build it, ship it and let users select it.. vs having to write code.

https://jazz.net/jazz/resource/itemName/com.ibm.team.workitem.WorkItem/182769

Sam

permanent link
Ralph Schoon (56.3k23642) | answered Nov 16 '11, 11:55 a.m.
FORUM ADMINISTRATOR / FORUM MODERATOR / JAZZ DEVELOPER
Same here Sam. Most of my material is also from helping people.

I hope we can pull more material together to provide more workshop material. It is just a matter of how much time I can spend.

Thanks so much for contributing!

permanent link
Phillip Piper (15812424) | answered Nov 16 '11, 12:43 p.m.
Same here Sam. Most of my material is also from helping people.

I hope we can pull more material together to provide more workshop material. It is just a matter of how much time I can spend.

Thanks so much for contributing!


Thanks Sam and Ralph. I will follow up with any preconditions I am able to write as well to help others.

Thanks again for updating the extensions workshop. I really thought it was well done.

permanent link
Phillip Piper (15812424) | answered Nov 19 '11, 4:34 p.m.
So one challenge I am having is in creating the Aspect Editor.

I keep getting null returned for this call:
PlatformUI.getWorkbench().getActiveWorkbenchWindow().run(true, true, new RunnableWithProgress() {....

Is there any reason for why this happens or how to avoid? I am following the pattern in the getWorkItemsType call of the 3.0.1 Extensions Workshop labs which is consistent with what I see in the out of the box preconditions.

Thanks.

Your answer


Register or to post your answer.