Merged BRANCHES/DEV/BELARUS/HEAD-2010_07_09 to HEAD (with modifications)

21156: Implemented GET /api/task-instances/{task_instance_id}

git-svn-id: https://svn.alfresco.com/repos/alfresco-enterprise/alfresco/HEAD/root@21181 c4b6b30b-aa2e-2d43-bbcb-ca4b014f7261
This commit is contained in:
Gavin Cornwell
2010-07-14 22:20:54 +00:00
parent 5f41d9783f
commit 9bec2b070b
9 changed files with 462 additions and 52 deletions

View File

@@ -0,0 +1,8 @@
<webscript>
<shortname>Gets Workflow Task Instance</shortname>
<description>Gets the details of a task.</description>
<url>/api/task-instances/{task_instance_id}</url>
<format default="json"/>
<authentication>user</authentication>
<transaction allow="readonly">required</transaction>
</webscript>

View File

@@ -0,0 +1,6 @@
<#-- Workflow Task Instance in details -->
<#import "task.lib.ftl" as taskLib />
{
"data": <@taskLib.taskJSON task=workflowTask detailed=true/>
}

View File

@@ -5,7 +5,7 @@
"data": "data":
[ [
<#list taskInstances as task> <#list taskInstances as task>
<@taskLib.taskJSON task=task /> <@taskLib.taskJSON task=task detailed=false />
<#if task_has_next>,</#if> <#if task_has_next>,</#if>
</#list> </#list>
] ]

View File

@@ -1,5 +1,6 @@
<#-- Renders a task instance. --> <#-- Renders a task instance. -->
<#macro taskJSON task > <#macro taskJSON task detailed=false>
<#escape x as jsonUtils.encodeJSONString(x)>
{ {
"id": "${task.id}", "id": "${task.id}",
"url": "${task.url}", "url": "${task.url}",
@@ -21,11 +22,48 @@
</#if> </#if>
"properties": "properties":
<@propertiesJSON properties=task.properties /> <@propertiesJSON properties=task.properties />
<#if detailed>,
"path": "${task.path}",
"definition":
{
"id": "${task.definition.id}",
"url": "${task.definition.url}",
"type":
{
"name": "${shortQName(task.definition.type.name?string)}",
"title": "${task.definition.type.title}",
"description": "${task.definition.type.description}",
"url": "${task.definition.type.url}"
},
"node":
{
"name": "${task.definition.node.name}",
"title": "${task.definition.node.title}",
"description": "${task.definition.node.description}",
"isTaskNode": ${task.definition.node.isTaskNode?string},
"transitions":
[
<#list task.definition.node.transitions as transition>
{
"id": "${transition.id}",
"title": "${transition.title}",
"description": "${transition.description}",
"isDefault": ${transition.isDefault?string},
"isHidden": ${transition.isHidden?string}
} }
<#if transition_has_next>,</#if>
</#list>
]
}
}
</#if>
}
</#escape>
</#macro> </#macro>
<#-- Renders a map of properties --> <#-- Renders a map of properties -->
<#macro propertiesJSON properties> <#macro propertiesJSON properties>
<#escape x as jsonUtils.encodeJSONString(x)>
{ {
<#list properties?keys as key> <#list properties?keys as key>
"${key}": "${key}":
@@ -50,4 +88,5 @@
<#if (key_has_next)>,</#if> <#if (key_has_next)>,</#if>
</#list> </#list>
} }
</#escape>
</#macro> </#macro>

View File

@@ -789,6 +789,11 @@
parent="abstractWorkflowWebScript"> parent="abstractWorkflowWebScript">
</bean> </bean>
<!-- Gets the details of a task -->
<bean id="webscript.org.alfresco.repository.workflow.task-instance.get"
class="org.alfresco.repo.web.scripts.workflow.TaskInstanceGet"
parent="abstractWorkflowWebScript"></bean>
<!-- Lists all workflow definitions --> <!-- Lists all workflow definitions -->
<bean id="webscript.org.alfresco.repository.workflow.workflow-definitions.get" <bean id="webscript.org.alfresco.repository.workflow.workflow-definitions.get"
class="org.alfresco.repo.web.scripts.workflow.WorkflowDefinitionsGet" class="org.alfresco.repo.web.scripts.workflow.WorkflowDefinitionsGet"

View File

@@ -0,0 +1,59 @@
/*
* Copyright (C) 2005-2010 Alfresco Software Limited.
*
* This file is part of Alfresco
*
* Alfresco is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Alfresco is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with Alfresco. If not, see <http://www.gnu.org/licenses/>.
*/
package org.alfresco.repo.web.scripts.workflow;
import java.util.HashMap;
import java.util.Map;
import javax.servlet.http.HttpServletResponse;
import org.alfresco.service.cmr.workflow.WorkflowTask;
import org.springframework.extensions.webscripts.Cache;
import org.springframework.extensions.webscripts.Status;
import org.springframework.extensions.webscripts.WebScriptException;
import org.springframework.extensions.webscripts.WebScriptRequest;
/**
* @author unknown
*
*/
public class TaskInstanceGet extends AbstractWorkflowWebscript
{
@Override
protected Map<String, Object> buildModel(WorkflowModelBuilder modelBuilder, WebScriptRequest req, Status status, Cache cache)
{
Map<String, String> params = req.getServiceMatch().getTemplateVars();
String taskId = params.get("task_instance_id");
WorkflowTask workflowTask = workflowService.getTaskById(taskId);
if (workflowTask == null)
{
throw new WebScriptException(HttpServletResponse.SC_NOT_FOUND, "Unable to find workflow task with id: " + taskId);
}
Map<String, Object> model = new HashMap<String, Object>();
model.put("workflowTask", modelBuilder.buildDetailed(workflowTask));
return model;
}
}

View File

@@ -32,12 +32,16 @@ import org.alfresco.model.ContentModel;
import org.alfresco.repo.workflow.WorkflowModel; import org.alfresco.repo.workflow.WorkflowModel;
import org.alfresco.service.cmr.dictionary.AssociationDefinition; import org.alfresco.service.cmr.dictionary.AssociationDefinition;
import org.alfresco.service.cmr.dictionary.PropertyDefinition; import org.alfresco.service.cmr.dictionary.PropertyDefinition;
import org.alfresco.service.cmr.dictionary.TypeDefinition;
import org.alfresco.service.cmr.repository.NodeRef; import org.alfresco.service.cmr.repository.NodeRef;
import org.alfresco.service.cmr.repository.NodeService; import org.alfresco.service.cmr.repository.NodeService;
import org.alfresco.service.cmr.repository.datatype.DefaultTypeConverter; import org.alfresco.service.cmr.repository.datatype.DefaultTypeConverter;
import org.alfresco.service.cmr.security.PersonService; import org.alfresco.service.cmr.security.PersonService;
import org.alfresco.service.cmr.workflow.WorkflowDefinition; import org.alfresco.service.cmr.workflow.WorkflowDefinition;
import org.alfresco.service.cmr.workflow.WorkflowNode;
import org.alfresco.service.cmr.workflow.WorkflowTask; import org.alfresco.service.cmr.workflow.WorkflowTask;
import org.alfresco.service.cmr.workflow.WorkflowTaskDefinition;
import org.alfresco.service.cmr.workflow.WorkflowTransition;
import org.alfresco.service.namespace.NamespaceException; import org.alfresco.service.namespace.NamespaceException;
import org.alfresco.service.namespace.NamespaceService; import org.alfresco.service.namespace.NamespaceService;
import org.alfresco.service.namespace.QName; import org.alfresco.service.namespace.QName;
@@ -62,6 +66,30 @@ public class WorkflowModelBuilder
public static final String TASK_URL = "url"; public static final String TASK_URL = "url";
public static final String TASK_IS_POOLED = "isPooled"; public static final String TASK_IS_POOLED = "isPooled";
public static final String TASK_ID = "id"; public static final String TASK_ID = "id";
public static final String TASK_PATH = "path";
public static final String TASK_DEFINITION = "definition";
public static final String TASK_DEFINITION_ID = "id";
public static final String TASK_DEFINITION_URL = "url";
public static final String TASK_DEFINITION_TYPE = "type";
public static final String TASK_DEFINITION_NODE = "node";
public static final String TYPE_DEFINITION_NAME = "name";
public static final String TYPE_DEFINITION_TITLE = "title";
public static final String TYPE_DEFINITION_DESCRIPTION = "description";
public static final String TYPE_DEFINITION_URL = "url";
public static final String WORKFLOW_NODE_NAME = "name";
public static final String WORKFLOW_NODE_TITLE = "title";
public static final String WORKFLOW_NODE_DESCRIPTION = "description";
public static final String WORKFLOW_NODE_IS_TASK_NODE = "isTaskNode";
public static final String WORKFLOW_NODE_TRANSITIONS = "transitions";
public static final String WORKFLOW_NODE_TRANSITION_ID = "id";
public static final String WORKFLOW_NODE_TRANSITION_TITLE = "title";
public static final String WORKFLOW_NODE_TRANSITION_DESCRIPTION = "description";
public static final String WORKFLOW_NODE_TRANSITION_IS_DEFAULT = "isDefault";
public static final String WORKFLOW_NODE_TRANSITION_IS_HIDDEN = "isHidden";
public static final String WORKFLOW_DEFINITION_ID = "id"; public static final String WORKFLOW_DEFINITION_ID = "id";
public static final String WORKFLOW_DEFINITION_URL = "url"; public static final String WORKFLOW_DEFINITION_URL = "url";
@@ -107,6 +135,23 @@ public class WorkflowModelBuilder
return model; return model;
} }
/**
* Returns a detailed representation of a {@link WorkflowTask}.
* @param workflowTask The task to be represented.
* @return
*/
public Map<String, Object> buildDetailed(WorkflowTask workflowTask)
{
Map<String, Object> model = buildSimple(workflowTask, null);
model.put(TASK_PATH, getUrl(workflowTask) + "/paths/" + workflowTask.path.id);
// definition part
model.put(TASK_DEFINITION, buildTaskDefinition(workflowTask.definition, workflowTask));
return model;
}
/** /**
* Returns a simple representation of a {@link WorkflowDefinition}. * Returns a simple representation of a {@link WorkflowDefinition}.
* *
@@ -166,10 +211,7 @@ public class WorkflowModelBuilder
private Object convertValue(Object value) private Object convertValue(Object value)
{ {
if(value == null if (value == null || value instanceof Boolean || value instanceof Number || value instanceof String)
|| value instanceof Boolean
|| value instanceof Number
|| value instanceof String)
{ {
return value; return value;
} }
@@ -196,7 +238,8 @@ public class WorkflowModelBuilder
{ {
QName qKey = QName.createQName(prefixedName, namespaceService); QName qKey = QName.createQName(prefixedName, namespaceService);
qKeys.add(qKey); qKeys.add(qKey);
} catch(NamespaceException e) }
catch (NamespaceException e)
{ {
throw new AlfrescoRuntimeException("Invalid property key: " + key, e); throw new AlfrescoRuntimeException("Invalid property key: " + key, e);
} }
@@ -221,6 +264,61 @@ public class WorkflowModelBuilder
return model; return model;
} }
private Map<String, Object> buildTaskDefinition(WorkflowTaskDefinition workflowTaskDefinition, WorkflowTask workflowTask)
{
Map<String, Object> model = new HashMap<String, Object>();
model.put(TASK_DEFINITION_ID, workflowTaskDefinition.id);
model.put(TASK_DEFINITION_URL, getUrl(workflowTaskDefinition));
model.put(TASK_DEFINITION_TYPE, buildTypeDefinition(workflowTaskDefinition.metadata));
model.put(TASK_DEFINITION_NODE, buildWorkflowNode(workflowTaskDefinition.node, workflowTask));
return model;
}
private Map<String, Object> buildTypeDefinition(TypeDefinition typeDefinition)
{
Map<String, Object> model = new HashMap<String, Object>();
model.put(TYPE_DEFINITION_NAME, typeDefinition.getName());
model.put(TYPE_DEFINITION_TITLE, typeDefinition.getTitle());
model.put(TYPE_DEFINITION_DESCRIPTION, typeDefinition.getDescription());
model.put(TYPE_DEFINITION_URL, getUrl(typeDefinition));
return model;
}
private Map<String, Object> buildWorkflowNode(WorkflowNode workflowNode, WorkflowTask workflowTask)
{
Map<String, Object> model = new HashMap<String, Object>();
model.put(WORKFLOW_NODE_NAME, workflowNode.name);
model.put(WORKFLOW_NODE_TITLE, workflowNode.title);
model.put(WORKFLOW_NODE_DESCRIPTION, workflowNode.description);
model.put(WORKFLOW_NODE_IS_TASK_NODE, workflowNode.isTaskNode);
List<Map<String, Object>> results = new ArrayList<Map<String, Object>>();
Object hiddenTransitions = workflowTask.properties.get(WorkflowModel.PROP_HIDDEN_TRANSITIONS);
for (WorkflowTransition workflowTransition : workflowNode.transitions)
{
Map<String, Object> transitionMap = new HashMap<String, Object>();
transitionMap.put(WORKFLOW_NODE_TRANSITION_ID, workflowTransition.id);
transitionMap.put(WORKFLOW_NODE_TRANSITION_TITLE, workflowTransition.title);
transitionMap.put(WORKFLOW_NODE_TRANSITION_DESCRIPTION, workflowTransition.description);
transitionMap.put(WORKFLOW_NODE_TRANSITION_IS_DEFAULT, workflowTransition.isDefault);
transitionMap.put(WORKFLOW_NODE_TRANSITION_IS_HIDDEN, (hiddenTransitions == null ? false : hiddenTransitions.toString().contains(workflowTransition.id)));
results.add(transitionMap);
}
model.put(WORKFLOW_NODE_TRANSITIONS, results);
return model;
}
// private String getURl(WorkflowPath path) // private String getURl(WorkflowPath path)
// { // {
// StringBuilder builder = new StringBuilder("api/workflow-instances/"); // StringBuilder builder = new StringBuilder("api/workflow-instances/");
@@ -240,4 +338,14 @@ public class WorkflowModelBuilder
return "api/workflow-definitions/" + workflowDefinition.id; return "api/workflow-definitions/" + workflowDefinition.id;
} }
private String getUrl(WorkflowTaskDefinition workflowTaskDefinition)
{
return "api/task-definitions/" + workflowTaskDefinition.id;
}
private String getUrl(TypeDefinition typeDefinition)
{
return "api/classes/" + typeDefinition.getName().toPrefixString().replace(PREFIX_SEPARATOR, "_");
}
} }

View File

@@ -26,6 +26,7 @@ import java.util.ArrayList;
import java.util.Arrays; import java.util.Arrays;
import java.util.Date; import java.util.Date;
import java.util.HashMap; import java.util.HashMap;
import java.util.List;
import java.util.Map; import java.util.Map;
import junit.framework.TestCase; import junit.framework.TestCase;
@@ -38,9 +39,12 @@ import org.alfresco.service.cmr.repository.NodeService;
import org.alfresco.service.cmr.repository.StoreRef; import org.alfresco.service.cmr.repository.StoreRef;
import org.alfresco.service.cmr.security.PersonService; import org.alfresco.service.cmr.security.PersonService;
import org.alfresco.service.cmr.workflow.WorkflowDefinition; import org.alfresco.service.cmr.workflow.WorkflowDefinition;
import org.alfresco.service.cmr.workflow.WorkflowNode;
import org.alfresco.service.cmr.workflow.WorkflowPath;
import org.alfresco.service.cmr.workflow.WorkflowTask; import org.alfresco.service.cmr.workflow.WorkflowTask;
import org.alfresco.service.cmr.workflow.WorkflowTaskDefinition; import org.alfresco.service.cmr.workflow.WorkflowTaskDefinition;
import org.alfresco.service.cmr.workflow.WorkflowTaskState; import org.alfresco.service.cmr.workflow.WorkflowTaskState;
import org.alfresco.service.cmr.workflow.WorkflowTransition;
import org.alfresco.service.namespace.NamespaceService; import org.alfresco.service.namespace.NamespaceService;
import org.alfresco.service.namespace.NamespaceServiceMemoryImpl; import org.alfresco.service.namespace.NamespaceServiceMemoryImpl;
import org.alfresco.service.namespace.QName; import org.alfresco.service.namespace.QName;
@@ -135,11 +139,98 @@ public class WorkflowModelBuilderTest extends TestCase
assertEquals("foo bar", props.get("test_string")); assertEquals("foo bar", props.get("test_string"));
} }
@SuppressWarnings("unchecked")
public void testBuildWorkflowTaskDetailed() throws Exception
{
WorkflowTask workflowTask = new WorkflowTask();
workflowTask.id = "testId$1";
workflowTask.name = "Task Name";
workflowTask.title = "Task Title";
workflowTask.description = "The Description";
workflowTask.state = WorkflowTaskState.IN_PROGRESS;
workflowTask.path = new WorkflowPath();
workflowTask.path.id = "pathId$1";
workflowTask.definition = new WorkflowTaskDefinition();
workflowTask.definition.id = "The Definition Id";
workflowTask.definition.metadata = mock(TypeDefinition.class);
when(workflowTask.definition.metadata.getName()).thenReturn(QName.createQName("The Type Name"));
when(workflowTask.definition.metadata.getTitle()).thenReturn("The Type Title");
when(workflowTask.definition.metadata.getDescription()).thenReturn("The Type Description");
WorkflowNode workflowNode = new WorkflowNode();
workflowNode.name = "The Node Name";
workflowNode.title = "The Node Title";
workflowNode.description = "The Node Description";
workflowNode.isTaskNode = true;
WorkflowTransition workflowTransition = new WorkflowTransition();
workflowTransition.id = "The Transition Id";
workflowTransition.title = "The Transition Title";
workflowTransition.description = "The Transition Description";
workflowTransition.isDefault = true;
workflowNode.transitions = new WorkflowTransition[] { workflowTransition };
workflowTask.definition.node = workflowNode;
workflowTask.properties = new HashMap<QName, Serializable>();
workflowTask.properties.put(ContentModel.PROP_OWNER, userName);
Map<String, Object> model = builder.buildDetailed(workflowTask);
Object id = model.get(WorkflowModelBuilder.TASK_ID);
assertEquals(workflowTask.id, id);
Object url = model.get(WorkflowModelBuilder.TASK_URL);
assertEquals("api/task-instances/" + workflowTask.id, url);
assertEquals(workflowTask.name, model.get(WorkflowModelBuilder.TASK_NAME));
assertEquals(workflowTask.title, model.get(WorkflowModelBuilder.TASK_TITLE));
assertEquals(workflowTask.description, model.get(WorkflowModelBuilder.TASK_DESCRIPTION));
assertEquals(workflowTask.state.name(), model.get(WorkflowModelBuilder.TASK_STATE));
assertEquals(workflowTask.definition.metadata.getTitle(), model.get(WorkflowModelBuilder.TASK_TYPE_DEFINITION_TITLE));
assertEquals(false, model.get(WorkflowModelBuilder.TASK_IS_POOLED));
Map<String, Object> owner = (Map<String, Object>) model.get(WorkflowModelBuilder.TASK_OWNER);
assertEquals(userName, owner.get(WorkflowModelBuilder.PERSON_USER_NAME));
assertEquals(firstName, owner.get(WorkflowModelBuilder.PERSON_FIRST_NAME));
assertEquals(lastName, owner.get(WorkflowModelBuilder.PERSON_LAST_NAME));
Map<String, Object> props = (Map<String, Object>) model.get(WorkflowModelBuilder.TASK_PROPERTIES);
assertEquals(workflowTask.properties.size(), props.size());
Map<String, Object> definition = (Map<String, Object>) model.get(WorkflowModelBuilder.TASK_DEFINITION);
assertEquals(workflowTask.definition.id, definition.get(WorkflowModelBuilder.TASK_DEFINITION_ID));
Map<String, Object> type = (Map<String, Object>) definition.get(WorkflowModelBuilder.TASK_DEFINITION_TYPE);
assertEquals(workflowTask.definition.metadata.getName(), type.get(WorkflowModelBuilder.TYPE_DEFINITION_NAME));
assertEquals(workflowTask.definition.metadata.getTitle(), type.get(WorkflowModelBuilder.TYPE_DEFINITION_TITLE));
assertEquals(workflowTask.definition.metadata.getDescription(), type.get(WorkflowModelBuilder.TYPE_DEFINITION_DESCRIPTION));
Map<String, Object> node = (Map<String, Object>) definition.get(WorkflowModelBuilder.TASK_DEFINITION_NODE);
assertEquals(workflowTask.definition.node.name, node.get(WorkflowModelBuilder.WORKFLOW_NODE_NAME));
assertEquals(workflowTask.definition.node.title, node.get(WorkflowModelBuilder.WORKFLOW_NODE_TITLE));
assertEquals(workflowTask.definition.node.description, node.get(WorkflowModelBuilder.WORKFLOW_NODE_DESCRIPTION));
assertEquals(workflowTask.definition.node.isTaskNode, node.get(WorkflowModelBuilder.WORKFLOW_NODE_IS_TASK_NODE));
List<Map<String, Object>> transitions = (List<Map<String, Object>>) node.get(WorkflowModelBuilder.WORKFLOW_NODE_TRANSITIONS);
int i = 0;
for (Map<String, Object> transition : transitions)
{
assertEquals(workflowTask.definition.node.transitions[i].id, transition.get(WorkflowModelBuilder.WORKFLOW_NODE_TRANSITION_ID));
assertEquals(workflowTask.definition.node.transitions[i].title, transition.get(WorkflowModelBuilder.WORKFLOW_NODE_TRANSITION_TITLE));
assertEquals(workflowTask.definition.node.transitions[i].description, transition.get(WorkflowModelBuilder.WORKFLOW_NODE_TRANSITION_DESCRIPTION));
assertEquals(workflowTask.definition.node.transitions[i].isDefault, transition.get(WorkflowModelBuilder.WORKFLOW_NODE_TRANSITION_IS_DEFAULT));
assertEquals(false, transition.get(WorkflowModelBuilder.WORKFLOW_NODE_TRANSITION_IS_HIDDEN));
i++;
}
}
public void testBuildWorkflowDefinition() throws Exception public void testBuildWorkflowDefinition() throws Exception
{ {
WorkflowTaskDefinition workflowTaskDefinition = new WorkflowTaskDefinition(); WorkflowTaskDefinition workflowTaskDefinition = new WorkflowTaskDefinition();
WorkflowDefinition workflowDefinition = new WorkflowDefinition( WorkflowDefinition workflowDefinition = new WorkflowDefinition("The Id", "The Name", "The Version", "The Title", "The Description", workflowTaskDefinition);
"The Id", "The Name", "The Version", "The Title", "The Description", workflowTaskDefinition);
Map<String, Object> model = builder.buildSimple(workflowDefinition); Map<String, Object> model = builder.buildSimple(workflowDefinition);
assertEquals(workflowDefinition.id, model.get(WorkflowModelBuilder.WORKFLOW_DEFINITION_ID)); assertEquals(workflowDefinition.id, model.get(WorkflowModelBuilder.WORKFLOW_DEFINITION_ID));

View File

@@ -27,15 +27,19 @@ import java.util.Map;
import org.alfresco.repo.security.person.TestPersonManager; import org.alfresco.repo.security.person.TestPersonManager;
import org.alfresco.repo.web.scripts.BaseWebScriptTest; import org.alfresco.repo.web.scripts.BaseWebScriptTest;
import org.alfresco.repo.workflow.WorkflowModel; import org.alfresco.repo.workflow.WorkflowModel;
import org.alfresco.service.cmr.dictionary.TypeDefinition;
import org.alfresco.service.cmr.repository.NodeRef; import org.alfresco.service.cmr.repository.NodeRef;
import org.alfresco.service.cmr.repository.NodeService; import org.alfresco.service.cmr.repository.NodeService;
import org.alfresco.service.cmr.security.MutableAuthenticationService; import org.alfresco.service.cmr.security.MutableAuthenticationService;
import org.alfresco.service.cmr.security.PersonService; import org.alfresco.service.cmr.security.PersonService;
import org.alfresco.service.cmr.workflow.WorkflowDefinition; import org.alfresco.service.cmr.workflow.WorkflowDefinition;
import org.alfresco.service.cmr.workflow.WorkflowNode;
import org.alfresco.service.cmr.workflow.WorkflowPath; import org.alfresco.service.cmr.workflow.WorkflowPath;
import org.alfresco.service.cmr.workflow.WorkflowService; import org.alfresco.service.cmr.workflow.WorkflowService;
import org.alfresco.service.cmr.workflow.WorkflowTask; import org.alfresco.service.cmr.workflow.WorkflowTask;
import org.alfresco.service.cmr.workflow.WorkflowTaskDefinition;
import org.alfresco.service.cmr.workflow.WorkflowTaskState; import org.alfresco.service.cmr.workflow.WorkflowTaskState;
import org.alfresco.service.cmr.workflow.WorkflowTransition;
import org.alfresco.service.namespace.QName; import org.alfresco.service.namespace.QName;
import org.alfresco.util.GUID; import org.alfresco.util.GUID;
import org.json.JSONArray; import org.json.JSONArray;
@@ -53,7 +57,7 @@ public class WorkflowRestApiTest extends BaseWebScriptTest
{ {
private final static String USER1 = "Bob" + GUID.generate(); private final static String USER1 = "Bob" + GUID.generate();
private final static String USER2 = "Jane" + GUID.generate(); private final static String USER2 = "Jane" + GUID.generate();
private static final String URL_TASKS = "api/task-instance"; private static final String URL_TASKS = "api/task-instances";
private static final String URL_WORKFLOW_DEFINITIONS = "api/workflow-definitions"; private static final String URL_WORKFLOW_DEFINITIONS = "api/workflow-definitions";
private TestPersonManager personManager; private TestPersonManager personManager;
@@ -100,7 +104,7 @@ public class WorkflowRestApiTest extends BaseWebScriptTest
assertTrue(results.length() == tasks.size()); assertTrue(results.length() == tasks.size());
JSONObject result = results.getJSONObject(0); JSONObject result = results.getJSONObject(0);
String expUrl = "api/task-instance/"+task.id; String expUrl = "api/task-instances/" + task.id;
assertEquals(expUrl, result.getString("url")); assertEquals(expUrl, result.getString("url"));
assertEquals(task.name, result.getString("name")); assertEquals(task.name, result.getString("name"));
assertEquals(task.title, result.getString("title")); assertEquals(task.title, result.getString("title"));
@@ -119,6 +123,96 @@ public class WorkflowRestApiTest extends BaseWebScriptTest
//TODO Add more tests to check property filtering and pooled actors. //TODO Add more tests to check property filtering and pooled actors.
} }
public void testTaskInstanceGet() throws Exception
{
//Start workflow as USER1 and assign task to USER2.
personManager.setUser(USER1);
WorkflowDefinition adhocDef = workflowService.getDefinitionByName("jbpm$wf:adhoc");
Map<QName, Serializable> params = new HashMap<QName, Serializable>();
params.put(WorkflowModel.ASSOC_ASSIGNEE, personManager.get(USER2));
params.put(WorkflowModel.PROP_DUE_DATE, new Date());
params.put(WorkflowModel.PROP_PRIORITY, 1);
params.put(WorkflowModel.ASSOC_PACKAGE, packageRef);
WorkflowPath adhocPath = workflowService.startWorkflow(adhocDef.id, params);
WorkflowTask startTask = workflowService.getTasksForWorkflowPath(adhocPath.id).get(0);
Response response = sendRequest(new GetRequest(URL_TASKS + "/" + startTask.id), 200);
assertEquals(Status.STATUS_OK, response.getStatus());
String jsonStr = response.getContentAsString();
JSONObject json = new JSONObject(jsonStr);
JSONObject result = json.getJSONObject("data");
assertNotNull(result);
assertEquals(startTask.id, result.getString("id"));
assertEquals(URL_TASKS + "/" + startTask.id, result.getString("url"));
assertEquals(startTask.name, result.getString("name"));
assertEquals(startTask.title, result.getString("title"));
assertEquals(startTask.description, result.getString("description"));
assertEquals(startTask.state.name(), result.getString("state"));
assertEquals(URL_TASKS + "/" + startTask.id + "/paths/" + adhocPath.id, result.getString("path"));
assertEquals(false, result.getBoolean("isPooled"));
JSONObject owner = result.getJSONObject("owner");
assertEquals(USER1, owner.getString("userName"));
assertEquals(personManager.getFirstName(USER1), owner.getString("firstName"));
assertEquals(personManager.getLastName(USER1), owner.getString("lastName"));
JSONObject properties = result.getJSONObject("properties");
assertNotNull(properties);
JSONObject definition = result.getJSONObject("definition");
WorkflowTaskDefinition startDefinitiont = startTask.definition;
assertNotNull(definition);
assertEquals(startDefinitiont.id, definition.getString("id"));
assertTrue(definition.has("url"));
JSONObject type = definition.getJSONObject("type");
TypeDefinition startType = startDefinitiont.metadata;
assertNotNull(type);
assertEquals(startType.getName().toPrefixString(), type.getString("name"));
assertEquals(startType.getTitle(), type.getString("title"));
assertEquals(startType.getDescription(), type.getString("description"));
assertTrue(type.has("url"));
JSONObject node = definition.getJSONObject("node");
WorkflowNode startNode = startDefinitiont.node;
assertNotNull(node);
assertEquals(startNode.name, node.getString("name"));
assertEquals(startNode.title, node.getString("title"));
assertEquals(startNode.description, node.getString("description"));
assertEquals(startNode.isTaskNode, node.getBoolean("isTaskNode"));
JSONArray transitions = node.getJSONArray("transitions");
WorkflowTransition[] startTransitions = startNode.transitions;
assertNotNull(transitions);
assertEquals(startTransitions.length, transitions.length());
for (int i = 0; i < transitions.length(); i++)
{
JSONObject transition = transitions.getJSONObject(i);
WorkflowTransition startTransition = startTransitions[i];
assertNotNull(transition);
assertEquals(startTransition.id, transition.getString("id"));
assertEquals(startTransition.title, transition.getString("title"));
assertEquals(startTransition.description, transition.getString("description"));
assertEquals(startTransition.isDefault, transition.getBoolean("isDefault"));
assertTrue(transition.has("isHidden"));
}
}
public void testWorkflowDefinitionsGet() throws Exception public void testWorkflowDefinitionsGet() throws Exception
{ {
Response response = sendRequest(new GetRequest(URL_WORKFLOW_DEFINITIONS), 200); Response response = sendRequest(new GetRequest(URL_WORKFLOW_DEFINITIONS), 200);
@@ -137,7 +231,7 @@ public class WorkflowRestApiTest extends BaseWebScriptTest
assertTrue(workflowDefinitionJSON.has("url")); assertTrue(workflowDefinitionJSON.has("url"));
String url = workflowDefinitionJSON.getString("url"); String url = workflowDefinitionJSON.getString("url");
assertTrue(url.length() > 0); assertTrue(url.length() > 0);
assertTrue(url.startsWith("api/workflow-definition/")); assertTrue(url.startsWith("api/workflow-definitions/"));
assertTrue(workflowDefinitionJSON.has("name")); assertTrue(workflowDefinitionJSON.has("name"));
assertTrue(workflowDefinitionJSON.getString("name").length() > 0); assertTrue(workflowDefinitionJSON.getString("name").length() > 0);