Server side implementation of ACTVT 93: The Share client exposes the diagram associated with a workflow (ALF-8634).

WorkflowService Java API now has a hasWorkflowImage() method which is used in the existing workflow instance REST API to determine whether to return a URL to the diagram ("diagramUrl" property) in the response. A new REST API has also been added (/api/workflow-instances/<id>/diagram) to allow retrieval of the PNG image data.

git-svn-id: https://svn.alfresco.com/repos/alfresco-enterprise/alfresco/HEAD/root@28485 c4b6b30b-aa2e-2d43-bbcb-ca4b014f7261
This commit is contained in:
Gavin Cornwell
2011-06-20 16:01:32 +00:00
parent afd5a78131
commit 5daf79d986
6 changed files with 131 additions and 0 deletions

View File

@@ -0,0 +1,15 @@
<webscript>
<shortname>Get Workflow Instance Diagram</shortname>
<description>Streams an image representing the current state of a workflow instance, if one is present</description>
<url>/api/workflow-instances/{workflow_instance_id}/diagram</url>
<format default="">argument</format>
<authentication>user</authentication>
<transaction allow="readonly">required</transaction>
<lifecycle>public_api</lifecycle>
<args>
<arg>
<shortname>workflow_instance_id</shortname>
<description>The id of workflow process instance to retrieve a diagram for.</description>
</arg>
</args>
</webscript>

View File

@@ -44,6 +44,7 @@
"lastName": string "lastName": string
}, },
"definitionUrl": string, "definitionUrl": string,
"diagramUrl": string,
"startTaskInstanceId": string, "startTaskInstanceId": string,
"definition": "definition":
{ {

View File

@@ -125,6 +125,7 @@
null, null,
</#if> </#if>
"definitionUrl": "${workflowInstance.definitionUrl}"<#if detailed>, "definitionUrl": "${workflowInstance.definitionUrl}"<#if detailed>,
"diagramUrl": <#if workflowInstance.diagramUrl??>"${workflowInstance.diagramUrl}"<#else>null</#if>,
"startTaskInstanceId": "${workflowInstance.startTaskInstanceId}", "startTaskInstanceId": "${workflowInstance.startTaskInstanceId}",
"definition": "definition":
<@workflowDefinitionJSON workflowDefinition=workflowInstance.definition detailed=true/> <@workflowDefinitionJSON workflowDefinition=workflowInstance.definition detailed=true/>

View File

@@ -1046,6 +1046,13 @@
<bean id="webscript.org.alfresco.repository.workflow.workflow-instance.get" <bean id="webscript.org.alfresco.repository.workflow.workflow-instance.get"
class="org.alfresco.repo.web.scripts.workflow.WorkflowInstanceGet" class="org.alfresco.repo.web.scripts.workflow.WorkflowInstanceGet"
parent="abstractWorkflowWebScript"></bean> parent="abstractWorkflowWebScript"></bean>
<!-- Retrieves the diagram for a specific workflow instance -->
<bean id="webscript.org.alfresco.repository.workflow.workflow-instance-diagram.get"
class="org.alfresco.repo.web.scripts.workflow.WorkflowInstanceDiagramGet"
parent="webscript">
<property name="workflowService" ref="WorkflowService" />
</bean>
<!-- Retrieves all workflow instances. --> <!-- Retrieves all workflow instances. -->
<bean id="webscript.org.alfresco.repository.workflow.workflow-instances.get" <bean id="webscript.org.alfresco.repository.workflow.workflow-instances.get"

View File

@@ -0,0 +1,96 @@
/*
* 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.io.IOException;
import java.io.InputStream;
import java.util.Map;
import javax.servlet.http.HttpServletResponse;
import org.alfresco.repo.content.MimetypeMap;
import org.alfresco.service.cmr.workflow.WorkflowInstance;
import org.alfresco.service.cmr.workflow.WorkflowService;
import org.springframework.extensions.webscripts.AbstractWebScript;
import org.springframework.extensions.webscripts.Cache;
import org.springframework.extensions.webscripts.WebScriptException;
import org.springframework.extensions.webscripts.WebScriptRequest;
import org.springframework.extensions.webscripts.WebScriptResponse;
import org.springframework.util.FileCopyUtils;
/**
* Java backed implementation for REST API to retrieve a diagram of a workflow instance.
*
* @author Gavin Cornwell
* @since 4.0
*/
public class WorkflowInstanceDiagramGet extends AbstractWebScript
{
protected WorkflowService workflowService;
public void setWorkflowService(WorkflowService workflowService)
{
this.workflowService = workflowService;
}
@Override
public void execute(WebScriptRequest req, WebScriptResponse res) throws IOException
{
Map<String, String> params = req.getServiceMatch().getTemplateVars();
// getting workflow instance id from request parameters
String workflowInstanceId = params.get("workflow_instance_id");
WorkflowInstance workflowInstance = workflowService.getWorkflowById(workflowInstanceId);
// workflow instance was not found -> return 404
if (workflowInstance == null)
{
throw new WebScriptException(HttpServletResponse.SC_NOT_FOUND, "Unable to find workflow instance with id: " + workflowInstanceId);
}
// check whether there is a diagram available
if (!workflowService.hasWorkflowImage(workflowInstanceId))
{
throw new WebScriptException(HttpServletResponse.SC_NOT_FOUND, "Unable to find diagram for workflow instance with id: " + workflowInstanceId);
}
// set mimetype for the content and the character encoding + length for the stream
res.setContentType(MimetypeMap.MIMETYPE_IMAGE_PNG);
// set caching (never cache)
Cache cache = new Cache();
cache.setNeverCache(true);
cache.setMustRevalidate(true);
cache.setMaxAge(0L);
res.setCache(cache);
// stream image back to client
InputStream imageData = workflowService.getWorkflowImage(workflowInstanceId);
try
{
FileCopyUtils.copy(imageData, res.getOutputStream()); // both streams are closed
}
catch (IOException e)
{
throw new WebScriptException(HttpServletResponse.SC_INTERNAL_SERVER_ERROR, "Error occurred streaming diagram for workflow instance with id '" +
workflowInstanceId + "' " + e.getMessage());
}
}
}

View File

@@ -108,6 +108,7 @@ public class WorkflowModelBuilder
public static final String TASK_WORKFLOW_INSTANCE_DEFINITION = "definition"; public static final String TASK_WORKFLOW_INSTANCE_DEFINITION = "definition";
public static final String TASK_WORKFLOW_INSTANCE_TASKS = "tasks"; public static final String TASK_WORKFLOW_INSTANCE_TASKS = "tasks";
public static final String TASK_WORKFLOW_INSTANCE_DEFINITION_URL = "definitionUrl"; public static final String TASK_WORKFLOW_INSTANCE_DEFINITION_URL = "definitionUrl";
public static final String TASK_WORKFLOW_INSTANCE_DIAGRAM_URL = "diagramUrl";
public static final String TASK_WORKFLOW_INSTANCE_INITIATOR_USERNAME = "userName"; public static final String TASK_WORKFLOW_INSTANCE_INITIATOR_USERNAME = "userName";
public static final String TASK_WORKFLOW_INSTANCE_INITIATOR_FIRSTNAME = "firstName"; public static final String TASK_WORKFLOW_INSTANCE_INITIATOR_FIRSTNAME = "firstName";
@@ -297,6 +298,11 @@ public class WorkflowModelBuilder
startTaskId = startTask.getId(); startTaskId = startTask.getId();
} }
if (workflowService.hasWorkflowImage(workflowInstance.getId()))
{
model.put(TASK_WORKFLOW_INSTANCE_DIAGRAM_URL, getDiagramUrl(workflowInstance));
}
model.put(TASK_WORKFLOW_INSTANCE_START_TASK_INSTANCE_ID, startTaskId); model.put(TASK_WORKFLOW_INSTANCE_START_TASK_INSTANCE_ID, startTaskId);
model.put(TASK_WORKFLOW_INSTANCE_DEFINITION, buildDetailed(workflowInstance.getDefinition())); model.put(TASK_WORKFLOW_INSTANCE_DEFINITION, buildDetailed(workflowInstance.getDefinition()));
@@ -626,6 +632,11 @@ public class WorkflowModelBuilder
{ {
return "api/workflow-instances/" + workflowInstance.getId(); return "api/workflow-instances/" + workflowInstance.getId();
} }
private String getDiagramUrl(WorkflowInstance workflowInstance)
{
return "api/workflow-instances/" + workflowInstance.getId() + "/diagram";
}
private String getAvatarUrl(NodeRef avatarRef) private String getAvatarUrl(NodeRef avatarRef)
{ {