Operation Advisor - Custom Precondition for Work Items
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.
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
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.
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);
}
}
}
}
}
}
}
}
Comments
1 vote
showing 5 of 7
show 2 more comments
13 other answers
What do you mean when you say "I keep getting null returned for this call"? Do you mean you get NullPointerException exception? If so, can you please provide the exception stack? Or, did you see any error log in the console?
I know nothing about the Extensions Workshop. I am just trying to figure our the problem from the basic technical view.
I get a pop-up error box when trying to use the UI config for the precondition in the operation behavior editor that gives a NullPointerException. And when I debugged it looks like either the getWorkbench() or getActiveWorkbenchWindow() returned null. I googled and it looks like it's possible to for the latter call to return null. Every other precondition editor I looked at had it coded the same way.
Eventually, in my attempts to figure this out, it went away but I am not sure why. I never changed that code either. It was quite strange.
2. I am not sure I understand how I can determine exactly what services I require for what I want to do.
FWIW when writing future extensions, I've posted the following on my blog about one approach to figuring out which services you require: http://ryehle.wordpress.com/2011/11/21/finding-the-right-service-api-for-your-process-extension/
Thanks Robin! I'll check this out because I have a few more extensions to write after working my way through this one which is almost complete.
2. I am not sure I understand how I can determine exactly what services I require for what I want to do.
FWIW when writing future extensions, I've posted the following on my blog about one approach to figuring out which services you require: http://ryehle.wordpress.com/2011/11/21/finding-the-right-service-api-for-your-process-extension/
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.
What do you mean when you say "I keep getting null returned for this call"? Do you mean you get NullPointerException exception? If so, can you please provide the exception stack? Or, did you see any error log in the console?
I know nothing about the Extensions Workshop. I am just trying to figure our the problem from the basic technical view.
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.
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.
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.
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
I think it does not matter if pre- or postcondition as long as the required interface is similar.
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.
page 1of 1 pagesof 2 pages