What other options do I have to setWorkflowAction other than relying on WorkitemOperation?
The javadoc API says:
commit(WorkItemWorkingCopy[] workingCopies, org.eclipse.core.runtime.IProgressMonitor monitor)
Commits the operation for the given working copies.
But I don't see any examples in the Jazz biosphere that actually use it. I'm having a problem where my code to update a workitem runs with (apparently) no issue, but I'm not seeing the updates reflected on the work items.
Specifically, I'm trying to extend WorkItemOperation to change the status of a custom work item type. I can change other fields using the same code but when I try to change the workflow action, it doesn't work. Here is what I'm using:
public class UpdateWorkItemStatus implements WorkitemResultProcessor {
private static Logger log = LoggerFactory
.getLogger(UpdateWorkItemStatus.class.getName());
String newaction ="";
IProgressMonitor monitor = null;
IProjectArea project_area = null;
public UpdateWorkItemStatus(IProjectArea pa,String statusaction,IProgressMonitor mon){
project_area = pa;
monitor = mon;
newaction = statusaction;
mon.subTask("Preparing to update");
}
public IProgressMonitor getMonitor() {
return monitor;
}
public String getNewaction() {
return newaction;
}
public void execute(IWorkItemHandle wh) throws RtcException {
StatusAssign chgstatus = new StatusAssign(newaction);
try {
log.trace("Creating StatusAssign object to update status");
chgstatus.run(wh,monitor);
} catch (TeamRepositoryException e) {
throw new RtcException("Problem setting status to '"+getNewaction()+"': "+e.getMessage());
}
}
class StatusAssign extends WorkItemOperation {
String newstatus_action = "";
public StatusAssign(String action) {
super("Updating workitem...", IWorkItem.FULL_PROFILE);
newstatus_action = action;
}
public StatusAssign(String name, ItemProfile profile) {
super(name, profile);
}
@Override
protected void execute(WorkItemWorkingCopy workingCopy,IProgressMonitor monitor) throws TeamRepositoryException {
String msg = String.format("Updating workitem %s: setting status to '%s'",workingCopy.getWorkItem().getId(),newstatus_action);
monitor.subTask(msg);
log.debug("Current workflow action is {}",workingCopy.getWorkflowAction());
// this workflow action does not stick
workingCopy.setWorkflowAction(newstatus_action);
// this part works
Timestamp testdate = new Timestamp(new Date().getTime());
workingCopy.getWorkItem().setDueDate(testdate);
// this part works, too
workingCopy.getWorkItem().setTarget(IterationHelper.getIteration(
(ITeamRepository) project_area.getOrigin(), (IProjectArea) project_area.getFullState()
, "HP MBE O 2013 11 04"));
}
}
}
Because it hasn't been working, I've been doing more and more arcane things trying to get it to work, including the forbidden setState2 and now wondering what the commit is for. If the problem is that I'm doing something wrong, then my original question is wrong!
Any ideas?
- Andy
Accepted answer
Won't fit in a comment. This would be another approach:
private static String changeStatus(ITeamRepository repo,
Integer workItemId, Boolean buildStatus, String actionOK,
String actionKO, IProgressMonitor monitor)
throws TeamRepositoryException {
IWorkItemClient workItemClient = (IWorkItemClient) repo
.getClientLibrary(IWorkItemClient.class);
IWorkItemCommon workItemCommon = (IWorkItemCommon) repo
.getClientLibrary(IWorkItemCommon.class);
IWorkItem wi = workItemClient.findWorkItemById(workItemId,
IWorkItem.FULL_PROFILE, monitor);
if (null == wi) {
return ("work item " + workItemId + " cannot be found");
}
IDetailedStatus status = null;
String actionName = buildStatus ? actionOK : actionKO;
IWorkItemWorkingCopyManager copyManager = workItemClient
.getWorkItemWorkingCopyManager();
try {
copyManager.connect(wi, IWorkItem.FULL_PROFILE, monitor);
WorkItemWorkingCopy wc = copyManager.getWorkingCopy(wi);
// wc.getWorkItem().getsetState2(arg0)
IWorkflowInfo wfInfo = (IWorkflowInfo) workItemClient
.findWorkflowInfo(wi, monitor);
Identifier[] actionList = wfInfo.getActionIds(wi
.getState2());
String actionId = null;
for (int i = 0; i < actionList.length; i++) {
Identifier action = actionList[i];
String name = wfInfo.getActionName(action);
if (name != null) {
if (name.equals(actionName)) {
actionId = action.getStringIdentifier();
break;
}
}
}
if (null == actionId) {
wc.setWorkflowAction(null);
} else {
wc.setWorkflowAction(actionId);
// wc.setWorkflowAction(null);
}
status = wc.save(monitor);
if (status.getCode() != org.eclipse.core.runtime.IStatus.OK) {
return "Error: " + status.getDetails();
}
} catch (Exception e) {
return "Unexpected error: " + e.getMessage();
} finally {
copyManager.disconnect(wi);
}
return null;
}
Comments
1 vote
showing 5 of 10
show 5 more comments
3 other answers
Updated WorkitemOperation that finds the correct action identifier based on the passed name. Not using the path as Ralph mentions above, just brute force:
@Override
protected void execute(WorkItemWorkingCopy workingCopy,IProgressMonitor monitor) throws TeamRepositoryException {
String msg = String.format("Updating workitem %s: setting status to '%s'",workingCopy.getWorkItem().getId(),newstatus_action);
monitor.subTask(msg);
log.debug("Current workflow action is {}",workingCopy.getWorkflowAction());
ITeamRepository repo = (ITeamRepository) workingCopy.getWorkItem().getOrigin();
IWorkItemClient client = (IWorkItemClient) repo.getClientLibrary(IWorkItemClient.class);
IWorkflowInfo wf = client.findWorkflowInfo(workingCopy.getWorkItem(), monitor);
Identifier<IWorkflowAction>[] actionList = wf.getActionIds(workingCopy.getWorkItem().getState2());
String actionId = null;
for (int i = 0; i < actionList.length; i++) {
Identifier<IWorkflowAction> action = actionList[i];
String action_name = wf.getActionName(action);
if (action_name != null) {
if (action_name.equals(newstatus_action)) {
actionId = action.getStringIdentifier();
break;
}
} else {
log.error("identifier for action {} was null",newstatus_action);
}
}
workingCopy.setWorkflowAction(actionId);
}
}
Andy, looking at it, the commit operation basically is one of the last steps in the WorkItemOperation and it saves the work item working-copies. That is about it.
If you want to change the state of the work item,you can provide the work item with a workflowAction ( .setWorkFlowAction). See http://rsjazz.wordpress.com/2012/11/26/manipulating-work-item-states/ for more details. There is a deprecated method .setState2() on IWorkItem that you could use to directly set a state. However, that is a bit unsafe, because you could trigger a state change that does not exist and it might also avoid all the behavior defined related to the workflow.
If you want to change the state of the work item,you can provide the work item with a workflowAction ( .setWorkFlowAction). See http://rsjazz.wordpress.com/2012/11/26/manipulating-work-item-states/ for more details. There is a deprecated method .setState2() on IWorkItem that you could use to directly set a state. However, that is a bit unsafe, because you could trigger a state change that does not exist and it might also avoid all the behavior defined related to the workflow.
Comments
Andy, it would help if you describe what and where (client API/Server API) you are trying to use the API.
I only implicitly use that API. On the client I usually use a WorkItemOperation that overwrites some method as described for example here: https://rsjazz.wordpress.com/2012/08/01/uploading-attachments-to-work-items/ or here https://jazz.net/wiki/bin/view/Main/ProgrammaticWorkItemCreation. I think that eventually uses the commit() method.
In the server API I use typically saveWorkItem2() or saveWorkItem3() as described in e.g. this blog: https://rsjazz.wordpress.com/2012/07/31/rtc-update-parent-duration-estimation-and-effort-participant/
I only implicitly use that API. On the client I usually use a WorkItemOperation that overwrites some method as described for example here: https://rsjazz.wordpress.com/2012/08/01/uploading-attachments-to-work-items/ or here https://jazz.net/wiki/bin/view/Main/ProgrammaticWorkItemCreation. I think that eventually uses the commit() method.
In the server API I use typically saveWorkItem2() or saveWorkItem3() as described in e.g. this blog: https://rsjazz.wordpress.com/2012/07/31/rtc-update-parent-duration-estimation-and-effort-participant/
Comments
Aradhya K
JAZZ DEVELOPER Jan 08 '14, 12:29 a.m.Andy Jewell
Jan 10 '14, 1:36 p.m.