您的位置:首页 > 其它

Activiti之流程图查看

2016-03-23 00:00 579 查看
摘要: Activiti之流程图查看

本文将介绍怎么在自己的系统内显示activiti的流程图,示例代码是从官方demo里提取的一部分流程图展示的代码,这里是结合springmvc来实现的,大家可以从官方代码里提取,也可以参照本博文来直接使用。

1、代码目录结构



2、代码详情

JacksonConfiguration.java

[code=language-java]import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import com.fasterxml.jackson.databind.ObjectMapper;

/**
* @author Joram Barrez
*/
@Configuration
public class JacksonConfiguration
{

@Bean()
public ObjectMapper objectMapper()
{
// To avoid instantiating and configuring the mapper everywhere
ObjectMapper mapper = new ObjectMapper();
return mapper;
}

}

BaseProcessDefinitionDiagramLayoutResource.java

[code=language-java]import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.activiti.engine.ActivitiException;
import org.activiti.engine.ActivitiObjectNotFoundException;
import org.activiti.engine.HistoryService;
import org.activiti.engine.RepositoryService;
import org.activiti.engine.RuntimeService;
import org.activiti.engine.history.HistoricActivityInstance;
import org.activiti.engine.impl.bpmn.behavior.BoundaryEventActivityBehavior;
import org.activiti.engine.impl.bpmn.behavior.CallActivityBehavior;
import org.activiti.engine.impl.bpmn.parser.BpmnParse;
import org.activiti.engine.impl.bpmn.parser.ErrorEventDefinition;
import org.activiti.engine.impl.bpmn.parser.EventSubscriptionDeclaration;
import org.activiti.engine.impl.jobexecutor.TimerDeclarationImpl;
import org.activiti.engine.impl.persistence.entity.ExecutionEntity;
import org.activiti.engine.impl.persistence.entity.ProcessDefinitionEntity;
import org.activiti.engine.impl.pvm.PvmTransition;
import org.activiti.engine.impl.pvm.delegate.ActivityBehavior;
import org.activiti.engine.impl.pvm.process.ActivityImpl;
import org.activiti.engine.impl.pvm.process.Lane;
import org.activiti.engine.impl.pvm.process.LaneSet;
import org.activiti.engine.impl.pvm.process.ParticipantProcess;
import org.activiti.engine.impl.pvm.process.TransitionImpl;
import org.activiti.engine.repository.ProcessDefinition;
import org.activiti.engine.runtime.Execution;
import org.activiti.engine.runtime.ProcessInstance;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;

import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.node.ArrayNode;
import com.fasterxml.jackson.databind.node.ObjectNode;

public class BaseProcessDefinitionDiagramLayoutResource
{

@Autowired
private RuntimeService		runtimeService;

@Autowired
private RepositoryService	repositoryService;

@Autowired
private HistoryService		historyService;

public ObjectNode getDiagramNode(String processInstanceId, String processDefinitionId)
{

List<String> highLightedFlows = Collections.<String> emptyList();
List<String> highLightedActivities = Collections.<String> emptyList();

Map<String, ObjectNode> subProcessInstanceMap = new HashMap<String, ObjectNode>();

ProcessInstance processInstance = null;
if (processInstanceId != null)
{
processInstance = runtimeService.createProcessInstanceQuery().processInstanceId(processInstanceId)
.singleResult();
if (processInstance == null)
{
throw new ActivitiObjectNotFoundException("Process instance could not be found");
}
processDefinitionId = processInstance.getProcessDefinitionId();

List<ProcessInstance> subProcessInstances = runtimeService.createProcessInstanceQuery()
.superProcessInstanceId(processInstanceId).list();

for (ProcessInstance subProcessInstance : subProcessInstances)
{
String subDefId = subProcessInstance.getProcessDefinitionId();

String superExecutionId = ((ExecutionEntity) subProcessInstance).getSuperExecutionId();
ProcessDefinitionEntity subDef = (ProcessDefinitionEntity) repositoryService
.getProcessDefinition(subDefId);

ObjectNode processInstanceJSON = new ObjectMapper().createObjectNode();
processInstanceJSON.put("processInstanceId", subProcessInstance.getId());
processInstanceJSON.put("superExecutionId", superExecutionId);
processInstanceJSON.put("processDefinitionId", subDef.getId());
processInstanceJSON.put("processDefinitionKey", subDef.getKey());
processInstanceJSON.put("processDefinitionName", subDef.getName());

subProcessInstanceMap.put(superExecutionId, processInstanceJSON);
}
}

if (processDefinitionId == null)
{
throw new ActivitiObjectNotFoundException("No process definition id provided");
}

ProcessDefinitionEntity processDefinition = (ProcessDefinitionEntity) repositoryService
.getProcessDefinition(processDefinitionId);

if (processDefinition == null)
{
throw new ActivitiException("Process definition " + processDefinitionId + " could not be found");
}

ObjectNode responseJSON = new ObjectMapper().createObjectNode();

// Process definition
JsonNode pdrJSON = getProcessDefinitionResponse(processDefinition);

if (pdrJSON != null)
{
responseJSON.put("processDefinition", pdrJSON);
}

// Highlighted activities
if (processInstance != null)
{
ArrayNode activityArray = new ObjectMapper().createArrayNode();
ArrayNode flowsArray = new ObjectMapper().createArrayNode();

highLightedActivities = runtimeService.getActiveActivityIds(processInstanceId);
highLightedFlows = getHighLightedFlows(processInstanceId, processDefinition);

for (String activityName : highLightedActivities)
{
activityArray.add(activityName);
}

for (String flow : highLightedFlows)
flowsArray.add(flow);

responseJSON.put("highLightedActivities", activityArray);
responseJSON.put("highLightedFlows", flowsArray);
}

// Pool shape, if process is participant in collaboration
if (processDefinition.getParticipantProcess() != null)
{
ParticipantProcess pProc = processDefinition.getParticipantProcess();

ObjectNode participantProcessJSON = new ObjectMapper().createObjectNode();
participantProcessJSON.put("id", pProc.getId());
if (StringUtils.isNotEmpty(pProc.getName()))
{
participantProcessJSON.put("name", pProc.getName());
}
else
{
participantProcessJSON.put("name", "");
}
participantProcessJSON.put("x", pProc.getX());
participantProcessJSON.put("y", pProc.getY());
participantProcessJSON.put("width", pProc.getWidth());
participantProcessJSON.put("height", pProc.getHeight());

responseJSON.put("participantProcess", participantProcessJSON);
}

// Draw lanes

if (processDefinition.getLaneSets() != null && !processDefinition.getLaneSets().isEmpty())
{
ArrayNode laneSetArray = new ObjectMapper().createArrayNode();
for (LaneSet laneSet : processDefinition.getLaneSets())
{
ArrayNode laneArray = new ObjectMapper().createArrayNode();
if (laneSet.getLanes() != null && !laneSet.getLanes().isEmpty())
{
for (Lane lane : laneSet.getLanes())
{
ObjectNode laneJSON = new ObjectMapper().createObjectNode();
laneJSON.put("id", lane.getId());
if (StringUtils.isNotEmpty(lane.getName()))
{
laneJSON.put("name", lane.getName());
}
else
{
laneJSON.put("name", "");
}
laneJSON.put("x", lane.getX());
laneJSON.put("y", lane.getY());
laneJSON.put("width", lane.getWidth());
laneJSON.put("height", lane.getHeight());

List<String> flowNodeIds = lane.getFlowNodeIds();
ArrayNode flowNodeIdsArray = new ObjectMapper().createArrayNode();
for (String flowNodeId : flowNodeIds)
{
flowNodeIdsArray.add(flowNodeId);
}
laneJSON.put("flowNodeIds", flowNodeIdsArray);

laneArray.add(laneJSON);
}
}
ObjectNode laneSetJSON = new ObjectMapper().createObjectNode();
laneSetJSON.put("id", laneSet.getId());
if (StringUtils.isNotEmpty(laneSet.getName()))
{
laneSetJSON.put("name", laneSet.getName());
}
else
{
laneSetJSON.put("name", "");
}
laneSetJSON.put("lanes", laneArray);

laneSetArray.add(laneSetJSON);
}

if (laneSetArray.size() > 0)
responseJSON.put("laneSets", laneSetArray);
}

ArrayNode sequenceFlowArray = new ObjectMapper().createArrayNode();
ArrayNode activityArray = new ObjectMapper().createArrayNode();

// Activities and their sequence-flows

for (ActivityImpl activity : processDefinition.getActivities())
{
getActivity(processInstanceId, activity, activityArray, sequenceFlowArray, processInstance,
highLightedFlows, subProcessInstanceMap);
}

responseJSON.put("activities", activityArray);
responseJSON.put("sequenceFlows", sequenceFlowArray);

return responseJSON;
}

private List<String> getHighLightedFlows(String processInstanceId, ProcessDefinitionEntity processDefinition)
{

List<String> highLightedFlows = new ArrayList<String>();
List<HistoricActivityInstance> historicActivityInstances = historyService.createHistoricActivityInstanceQuery()
.processInstanceId(processInstanceId).orderByHistoricActivityInstanceStartTime().asc().list();

List<String> historicActivityInstanceList = new ArrayList<String>();
for (HistoricActivityInstance hai : historicActivityInstances)
{
historicActivityInstanceList.add(hai.getActivityId());
}

// add current activities to list
List<String> highLightedActivities = runtimeService.getActiveActivityIds(processInstanceId);
historicActivityInstanceList.addAll(highLightedActivities);

// activities and their sequence-flows
for (ActivityImpl activity : processDefinition.getActivities())
{
int index = historicActivityInstanceList.indexOf(activity.getId());

if (index >= 0 && index + 1 < historicActivityInstanceList.size())
{
List<PvmTransition> pvmTransitionList = activity.getOutgoingTransitions();
for (PvmTransition pvmTransition : pvmTransitionList)
{
String destinationFlowId = pvmTransition.getDestination().getId();
if (destinationFlowId.equals(historicActivityInstanceList.get(index + 1)))
{
highLightedFlows.add(pvmTransition.getId());
}
}
}
}
return highLightedFlows;
}

@SuppressWarnings("unchecked")
private void getActivity(String processInstanceId, ActivityImpl activity, ArrayNode activityArray,
ArrayNode sequenceFlowArray, ProcessInstance processInstance, List<String> highLightedFlows,
Map<String, ObjectNode> subProcessInstanceMap)
{

ObjectNode activityJSON = new ObjectMapper().createObjectNode();

// Gather info on the multi instance marker
String multiInstance = (String) activity.getProperty("multiInstance");
if (multiInstance != null)
{
if (!"sequential".equals(multiInstance))
{
multiInstance = "parallel";
}
}

ActivityBehavior activityBehavior = activity.getActivityBehavior();
// Gather info on the collapsed marker
Boolean collapsed = (activityBehavior instanceof CallActivityBehavior);
Boolean expanded = (Boolean) activity.getProperty(BpmnParse.PROPERTYNAME_ISEXPANDED);
if (expanded != null)
{
collapsed = !expanded;
}

Boolean isInterrupting = null;
if (activityBehavior instanceof BoundaryEventActivityBehavior)
{
isInterrupting = ((BoundaryEventActivityBehavior) activityBehavior).isInterrupting();
}

// Outgoing transitions of activity
for (PvmTransition sequenceFlow : activity.getOutgoingTransitions())
{
String flowName = (String) sequenceFlow.getProperty("name");
boolean isHighLighted = (highLightedFlows.contains(sequenceFlow.getId()));
boolean isConditional = sequenceFlow.getProperty(BpmnParse.PROPERTYNAME_CONDITION) != null
&& !((String) activity.getProperty("type")).toLowerCase().contains("gateway");
boolean isDefault = sequenceFlow.getId().equals(activity.getProperty("default"))
&& ((String) activity.getProperty("type")).toLowerCase().contains("gateway");

List<Integer> waypoints = ((TransitionImpl) sequenceFlow).getWaypoints();
ArrayNode xPointArray = new ObjectMapper().createArrayNode();
ArrayNode yPointArray = new ObjectMapper().createArrayNode();
for (int i = 0; i < waypoints.size(); i += 2)
{ // waypoints.size()
// minimally 4: x1, y1,
// x2, y2
xPointArray.add(waypoints.get(i));
yPointArray.add(waypoints.get(i + 1));
}

ObjectNode flowJSON = new ObjectMapper().createObjectNode();
flowJSON.put("id", sequenceFlow.getId());
flowJSON.put("name", flowName);
flowJSON.put("flow", "(" + sequenceFlow.getSource().getId() + ")--" + sequenceFlow.getId() + "-->("
+ sequenceFlow.getDestination().getId() + ")");

if (isConditional)
flowJSON.put("isConditional", isConditional);
if (isDefault)
flowJSON.put("isDefault", isDefault);
if (isHighLighted)
flowJSON.put("isHighLighted", isHighLighted);

flowJSON.put("xPointArray", xPointArray);
flowJSON.put("yPointArray", yPointArray);

sequenceFlowArray.add(flowJSON);
}

// Nested activities (boundary events)
ArrayNode nestedActivityArray = new ObjectMapper().createArrayNode();
for (ActivityImpl nestedActivity : activity.getActivities())
{
nestedActivityArray.add(nestedActivity.getId());
}

Map<String, Object> properties = activity.getProperties();
ObjectNode propertiesJSON = new ObjectMapper().createObjectNode();
for (String key : properties.keySet())
{
Object prop = properties.get(key);
if (prop instanceof String)
propertiesJSON.put(key, (String) properties.get(key));
else if (prop instanceof Integer)
propertiesJSON.put(key, (Integer) properties.get(key));
else if (prop instanceof Boolean)
propertiesJSON.put(key, (Boolean) properties.get(key));
else if ("initial".equals(key))
{
ActivityImpl act = (ActivityImpl) properties.get(key);
propertiesJSON.put(key, act.getId());
}
else if ("timerDeclarations".equals(key))
{
ArrayList<TimerDeclarationImpl> timerDeclarations = (ArrayList<TimerDeclarationImpl>) properties
.get(key);
ArrayNode timerDeclarationArray = new ObjectMapper().createArrayNode();

if (timerDeclarations != null)
for (TimerDeclarationImpl timerDeclaration : timerDeclarations)
{
ObjectNode timerDeclarationJSON = new ObjectMapper().createObjectNode();

timerDeclarationJSON.put("isExclusive", timerDeclaration.isExclusive());
if (timerDeclaration.getRepeat() != null)
timerDeclarationJSON.put("repeat", timerDeclaration.getRepeat());

timerDeclarationJSON.put("retries", String.valueOf(timerDeclaration.getRetries()));
timerDeclarationJSON.put("type", timerDeclaration.getJobHandlerType());
timerDeclarationJSON.put("configuration", timerDeclaration.getJobHandlerConfiguration());
// timerDeclarationJSON.put("expression",
// timerDeclaration.getDescription());

timerDeclarationArray.add(timerDeclarationJSON);
}
if (timerDeclarationArray.size() > 0)
propertiesJSON.put(key, timerDeclarationArray);
// TODO: implement getting description
}
else if ("eventDefinitions".equals(key))
{
ArrayList<EventSubscriptionDeclaration> eventDefinitions = (ArrayList<EventSubscriptionDeclaration>) properties
.get(key);
ArrayNode eventDefinitionsArray = new ObjectMapper().createArrayNode();

if (eventDefinitions != null)
{
for (EventSubscriptionDeclaration eventDefinition : eventDefinitions)
{
ObjectNode eventDefinitionJSON = new ObjectMapper().createObjectNode();

if (eventDefinition.getActivityId() != null)
eventDefinitionJSON.put("activityId", eventDefinition.getActivityId());

eventDefinitionJSON.put("eventName", eventDefinition.getEventName());
eventDefinitionJSON.put("eventType", eventDefinition.getEventType());
eventDefinitionJSON.put("isAsync", eventDefinition.isAsync());
eventDefinitionJSON.put("isStartEvent", eventDefinition.isStartEvent());
eventDefinitionsArray.add(eventDefinitionJSON);
}
}

if (eventDefinitionsArray.size() > 0)
propertiesJSON.put(key, eventDefinitionsArray);

// TODO: implement it
}
else if ("errorEventDefinitions".equals(key))
{
ArrayList<ErrorEventDefinition> errorEventDefinitions = (ArrayList<ErrorEventDefinition>) properties
.get(key);
ArrayNode errorEventDefinitionsArray = new ObjectMapper().createArrayNode();

if (errorEventDefinitions != null)
{
for (ErrorEventDefinition errorEventDefinition : errorEventDefinitions)
{
ObjectNode errorEventDefinitionJSON = new ObjectMapper().createObjectNode();

if (errorEventDefinition.getErrorCode() != null)
errorEventDefinitionJSON.put("errorCode", errorEventDefinition.getErrorCode());
else
errorEventDefinitionJSON.putNull("errorCode");

errorEventDefinitionJSON.put("handlerActivityId", errorEventDefinition.getHandlerActivityId());

errorEventDefinitionsArray.add(errorEventDefinitionJSON);
}
}

if (errorEventDefinitionsArray.size() > 0)
propertiesJSON.put(key, errorEventDefinitionsArray);
}

}

if ("callActivity".equals(properties.get("type")))
{
CallActivityBehavior callActivityBehavior = null;

if (activityBehavior instanceof CallActivityBehavior)
{
callActivityBehavior = (CallActivityBehavior) activityBehavior;
}

if (callActivityBehavior != null)
{
propertiesJSON.put("processDefinitonKey", callActivityBehavior.getProcessDefinitonKey());

// get processDefinitonId from execution or get last
// processDefinitonId
// by key
ArrayNode processInstanceArray = new ObjectMapper().createArrayNode();
if (processInstance != null)
{
List<Execution> executionList = runtimeService.createExecutionQuery()
.processInstanceId(processInstanceId).activityId(activity.getId()).list();
if (!executionList.isEmpty())
{
for (Execution execution : executionList)
{
ObjectNode processInstanceJSON = subProcessInstanceMap.get(execution.getId());
processInstanceArray.add(processInstanceJSON);
}
}
}

// If active activities nas no instance of this callActivity
// then add
// last definition
if (processInstanceArray.size() == 0
&& StringUtils.isNotEmpty(callActivityBehavior.getProcessDefinitonKey()))
{
// Get last definition by key
ProcessDefinition lastProcessDefinition = repositoryService.createProcessDefinitionQuery()
.processDefinitionKey(callActivityBehavior.getProcessDefinitonKey()).latestVersion()
.singleResult();

if (lastProcessDefinition != null)
{
ObjectNode processInstanceJSON = new ObjectMapper().createObjectNode();
processInstanceJSON.put("processDefinitionId", lastProcessDefinition.getId());
processInstanceJSON.put("processDefinitionKey", lastProcessDefinition.getKey());
processInstanceJSON.put("processDefinitionName", lastProcessDefinition.getName());
processInstanceArray.add(processInstanceJSON);
}
}

if (processInstanceArray.size() > 0)
{
propertiesJSON.put("processDefinitons", processInstanceArray);
}
}
}

activityJSON.put("activityId", activity.getId());
activityJSON.put("properties", propertiesJSON);
if (multiInstance != null)
activityJSON.put("multiInstance", multiInstance);
if (collapsed)
activityJSON.put("collapsed", collapsed);
if (nestedActivityArray.size() > 0)
activityJSON.put("nestedActivities", nestedActivityArray);
if (isInterrupting != null)
activityJSON.put("isInterrupting", isInterrupting);

activityJSON.put("x", activity.getX());
activityJSON.put("y", activity.getY());
activityJSON.put("width", activity.getWidth());
activityJSON.put("height", activity.getHeight());

activityArray.add(activityJSON);

// Nested activities (boundary events)
for (ActivityImpl nestedActivity : activity.getActivities())
{
getActivity(processInstanceId, nestedActivity, activityArray, sequenceFlowArray, processInstance,
highLightedFlows, subProcessInstanceMap);
}
}

private JsonNode getProcessDefinitionResponse(ProcessDefinitionEntity processDefinition)
{
ObjectMapper mapper = new ObjectMapper();
ObjectNode pdrJSON = mapper.createObjectNode();
pdrJSON.put("id", processDefinition.getId());
pdrJSON.put("name", processDefinition.getName());
pdrJSON.put("key", processDefinition.getKey());
pdrJSON.put("version", processDefinition.getVersion());
pdrJSON.put("deploymentId", processDefinition.getDeploymentId());
pdrJSON.put("isGraphicNotationDefined", isGraphicNotationDefined(processDefinition));
return pdrJSON;
}

private boolean isGraphicNotationDefined(ProcessDefinitionEntity processDefinition)
{
return ((ProcessDefinitionEntity) repositoryService.getProcessDefinition(processDefinition.getId()))
.isGraphicalNotationDefined();
}
}

ProcessInstanceDiagramLayoutResource.java

[code=language-java]import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

import com.fasterxml.jackson.databind.node.ObjectNode;

@RestController
public class ProcessInstanceDiagramLayoutResource extends BaseProcessDefinitionDiagramLayoutResource
{

@RequestMapping(value = "/process-instance/diagram-layout.do", method = RequestMethod.GET, produces = "application/json")
public ObjectNode getDiagram(@RequestParam("processInstanceId") String processInstanceId)
{
return getDiagramNode(processInstanceId, null);
}
}

ProcessInstanceHighlightsResource.java

[code=language-java]import java.util.ArrayList;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;

import org.activiti.engine.HistoryService;
import org.activiti.engine.RepositoryService;
import org.activiti.engine.RuntimeService;
import org.activiti.engine.history.HistoricActivityInstance;
import org.activiti.engine.history.HistoricProcessInstance;
import org.activiti.engine.impl.persistence.entity.ProcessDefinitionEntity;
import org.activiti.engine.impl.pvm.PvmTransition;
import org.activiti.engine.impl.pvm.process.ActivityImpl;
import org.activiti.engine.runtime.ProcessInstance;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.node.ArrayNode;
import com.fasterxml.jackson.databind.node.ObjectNode;

@RestController
public class ProcessInstanceHighlightsResource
{

@Autowired
private RuntimeService		runtimeService;

@Autowired
private RepositoryService	repositoryService;

@Autowired
private HistoryService		historyService;

protected ObjectMapper		objectMapper	= new ObjectMapper();

@RequestMapping(value = "/process-instance/highlights.do", method = RequestMethod.GET, produces = "application/json")
public ObjectNode getHighlighted(@RequestParam("processInstanceId") String processInstanceId)
{
ObjectNode responseJSON = objectMapper.createObjectNode();
responseJSON.put("processInstanceId", processInstanceId);
ArrayNode activitiesArray = objectMapper.createArrayNode();
ArrayNode flowsArray = objectMapper.createArrayNode();
try
{
ProcessInstance processInstance = runtimeService.createProcessInstanceQuery()
.processInstanceId(processInstanceId).singleResult();
ProcessDefinitionEntity processDefinition = new ProcessDefinitionEntity();
if (null == processInstance)
{
HistoricProcessInstance historicProcessInstance = historyService.createHistoricProcessInstanceQuery()
.processInstanceId(processInstanceId).singleResult();
processDefinition = (ProcessDefinitionEntity) repositoryService
.getProcessDefinition(historicProcessInstance.getProcessDefinitionId());
responseJSON.put("processDefinitionId", historicProcessInstance.getProcessDefinitionId());
List<HistoricActivityInstance> historicActivityInstances = historyService
.createHistoricActivityInstanceQuery().processInstanceId(processInstanceId).list();
for (HistoricActivityInstance historicActivityInstance : historicActivityInstances)
{
activitiesArray.add(historicActivityInstance.getActivityId());
}
}
else
{
processDefinition = (ProcessDefinitionEntity) repositoryService
.getProcessDefinition(processInstance.getProcessDefinitionId());
responseJSON.put("processDefinitionId", processInstance.getProcessDefinitionId());
List<String> highLightedActivities = runtimeService.getActiveActivityIds(processInstanceId);
for (String activityId : highLightedActivities)
{
activitiesArray.add(activityId);
}
}
List<String> highLightedFlows = getHighLightedFlows(processDefinition, processInstanceId);
for (String flow : highLightedFlows)
{
flowsArray.add(flow);
}
}
catch (Exception e)
{
e.printStackTrace();
}
responseJSON.put("activities", activitiesArray);
responseJSON.put("flows", flowsArray);
return responseJSON;
}

/**
* getHighLightedFlows
*
* @param processDefinition
* @param processInstanceId
* @return
*/
private List<String> getHighLightedFlows(ProcessDefinitionEntity processDefinition, String processInstanceId)
{

List<String> highLightedFlows = new ArrayList<String>();

List<HistoricActivityInstance> historicActivityInstances = historyService.createHistoricActivityInstanceQuery()
.processInstanceId(processInstanceId)
// order by startime asc is not correct. use default order is
// correct.
// .orderByHistoricActivityInstanceStartTime().asc()/*.orderByActivityId().asc()*/
.list();

LinkedList<HistoricActivityInstance> hisActInstList = new LinkedList<HistoricActivityInstance>();
hisActInstList.addAll(historicActivityInstances);

getHighlightedFlows(processDefinition.getActivities(), hisActInstList, highLightedFlows);

return highLightedFlows;
}

/**
* getHighlightedFlows code logic: 1. Loop all activities by id asc order;
* 2. Check each activity's outgoing transitions and eventBoundery outgoing
* transitions, if outgoing transitions's destination.id is in other
* executed activityIds, add this transition to highLightedFlows List; 3.
* But if activity is not a parallelGateway or inclusiveGateway, only choose
* the earliest flow.
*
* @param activityList
* @param hisActInstList
* @param highLightedFlows
*/
private void getHighlightedFlows(List<ActivityImpl> activityList,
LinkedList<HistoricActivityInstance> hisActInstList, List<String> highLightedFlows)
{

// check out startEvents in activityList
List<ActivityImpl> startEventActList = new ArrayList<ActivityImpl>();
Map<String, ActivityImpl> activityMap = new HashMap<String, ActivityImpl>(activityList.size());
for (ActivityImpl activity : activityList)
{

activityMap.put(activity.getId(), activity);

String actType = (String) activity.getProperty("type");
if (actType != null && actType.toLowerCase().indexOf("startevent") >= 0)
{
startEventActList.add(activity);
}
}

// These codes is used to avoid a bug:
// ACT-1728 If the process instance was started by a callActivity, it
// will be not have the startEvent activity in ACT_HI_ACTINST table
// Code logic:
// Check the first activity if it is a startEvent, if not check out the
// startEvent's highlight outgoing flow.
HistoricActivityInstance firstHistActInst = hisActInstList.getFirst();
String firstActType = (String) firstHistActInst.getActivityType();
if (firstActType != null && firstActType.toLowerCase().indexOf("startevent") < 0)
{
PvmTransition startTrans = getStartTransaction(startEventActList, firstHistActInst);
if (startTrans != null)
{
highLightedFlows.add(startTrans.getId());
}
}

while (!hisActInstList.isEmpty())
{
HistoricActivityInstance histActInst = hisActInstList.removeFirst();
ActivityImpl activity = activityMap.get(histActInst.getActivityId());
if (activity != null)
{
boolean isParallel = false;
String type = histActInst.getActivityType();
if ("parallelGateway".equals(type) || "inclusiveGateway".equals(type))
{
isParallel = true;
}
else if ("subProcess".equals(histActInst.getActivityType()))
{
getHighlightedFlows(activity.getActivities(), hisActInstList, highLightedFlows);
}

List<PvmTransition> allOutgoingTrans = new ArrayList<PvmTransition>();
allOutgoingTrans.addAll(activity.getOutgoingTransitions());
allOutgoingTrans.addAll(getBoundaryEventOutgoingTransitions(activity));
List<String> activityHighLightedFlowIds = getHighlightedFlows(allOutgoingTrans, hisActInstList,
isParallel);
highLightedFlows.addAll(activityHighLightedFlowIds);
}
}
}

/**
* Check out the outgoing transition connected to firstActInst from
* startEventActList
*
* @param startEventActList
* @param firstActInst
* @return
*/
private PvmTransition getStartTransaction(List<ActivityImpl> startEventActList,
HistoricActivityInstance firstActInst)
{
for (ActivityImpl startEventAct : startEventActList)
{
for (PvmTransition trans : startEventAct.getOutgoingTransitions())
{
if (trans.getDestination().getId().equals(firstActInst.getActivityId()))
{
return trans;
}
}
}
return null;
}

/**
* getBoundaryEventOutgoingTransitions
*
* @param activity
* @return
*/
private List<PvmTransition> getBoundaryEventOutgoingTransitions(ActivityImpl activity)
{
List<PvmTransition> boundaryTrans = new ArrayList<PvmTransition>();
for (ActivityImpl subActivity : activity.getActivities())
{
String type = (String) subActivity.getProperty("type");
if (type != null && type.toLowerCase().indexOf("boundary") >= 0)
{
boundaryTrans.addAll(subActivity.getOutgoingTransitions());
}
}
return boundaryTrans;
}

/**
* find out single activity's highlighted flowIds
*
* @param activity
* @param hisActInstList
* @param isExclusive if true only return one flowId(Such as
*            exclusiveGateway, BoundaryEvent On Task)
* @return
*/
private List<String> getHighlightedFlows(List<PvmTransition> pvmTransitionList,
LinkedList<HistoricActivityInstance> hisActInstList, boolean isParallel)
{

List<String> highLightedFlowIds = new ArrayList<String>();

PvmTransition earliestTrans = null;
HistoricActivityInstance earliestHisActInst = null;

for (PvmTransition pvmTransition : pvmTransitionList)
{

String destActId = pvmTransition.getDestination().getId();
HistoricActivityInstance destHisActInst = findHisActInst(hisActInstList, destActId);
if (destHisActInst != null)
{
if (isParallel)
{
highLightedFlowIds.add(pvmTransition.getId());
}
else if (earliestHisActInst == null
|| (earliestHisActInst.getId().compareTo(destHisActInst.getId()) > 0))
{
earliestTrans = pvmTransition;
earliestHisActInst = destHisActInst;
}
}
}

if ((!isParallel) && earliestTrans != null)
{
highLightedFlowIds.add(earliestTrans.getId());
}

return highLightedFlowIds;
}

private HistoricActivityInstance findHisActInst(LinkedList<HistoricActivityInstance> hisActInstList, String actId)
{
for (HistoricActivityInstance hisActInst : hisActInstList)
{
if (hisActInst.getActivityId().equals(actId))
{
return hisActInst;
}
}
return null;
}
}

DispatcherServletConfiguration.java

[code=language-java]import java.util.List;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.env.Environment;
import org.springframework.http.converter.HttpMessageConverter;
import org.springframework.http.converter.json.MappingJackson2HttpMessageConverter;
import org.springframework.scheduling.annotation.EnableAsync;
import org.springframework.web.servlet.config.annotation.ContentNegotiationConfigurer;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurationSupport;
import org.springframework.web.servlet.i18n.LocaleChangeInterceptor;
import org.springframework.web.servlet.i18n.SessionLocaleResolver;
import org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping;

import com.fasterxml.jackson.databind.ObjectMapper;

@Configuration
@ComponentScan({ "org.activiti.rest.editor", "org.activiti.rest.diagram" })
@EnableAsync
public class DispatcherServletConfiguration extends WebMvcConfigurationSupport
{

private final Logger	log	= LoggerFactory.getLogger(DispatcherServletConfiguration.class);

@Autowired
private ObjectMapper	objectMapper;

@Autowired
private Environment		environment;

@Bean
public SessionLocaleResolver localeResolver()
{
return new SessionLocaleResolver();
}

@Bean
public LocaleChangeInterceptor localeChangeInterceptor()
{
log.debug("Configuring localeChangeInterceptor");
LocaleChangeInterceptor localeChangeInterceptor = new LocaleChangeInterceptor();
localeChangeInterceptor.setParamName("language");
return localeChangeInterceptor;
}

@Bean
public RequestMappingHandlerMapping requestMappingHandlerMapping()
{
log.debug("Creating requestMappingHandlerMapping");
RequestMappingHandlerMapping requestMappingHandlerMapping = new RequestMappingHandlerMapping();
requestMappingHandlerMapping.setUseSuffixPatternMatch(false);
Object[] interceptors = { localeChangeInterceptor() };
requestMappingHandlerMapping.setInterceptors(interceptors);
return requestMappingHandlerMapping;
}

@Override
public void configureMessageConverters(List<HttpMessageConverter<?>> converters)
{
addDefaultHttpMessageConverters(converters);
for (HttpMessageConverter<?> converter : converters)
{
if (converter instanceof MappingJackson2HttpMessageConverter)
{
MappingJackson2HttpMessageConverter jackson2HttpMessageConverter = (MappingJackson2HttpMessageConverter) converter;
jackson2HttpMessageConverter.setObjectMapper(objectMapper);
break;
}
}
}

@Override
protected void configureContentNegotiation(ContentNegotiationConfigurer configurer)
{
configurer.favorPathExtension(false);
}

}

FilterServletOutputStream.java

[code=language-java]import java.io.DataOutputStream;
import java.io.IOException;
import java.io.OutputStream;

import javax.servlet.ServletOutputStream;
import javax.servlet.WriteListener;

public class FilterServletOutputStream extends ServletOutputStream
{

private DataOutputStream	stream;
//private WriteListener		writeListener;

public FilterServletOutputStream(OutputStream output)
{
stream = new DataOutputStream(output);
}

public void write(int b) throws IOException
{
stream.write(b);
}

public void write(byte[] b) throws IOException
{
stream.write(b);
}

public void write(byte[] b, int off, int len) throws IOException
{
stream.write(b, off, len);
}

@Override
public void setWriteListener(WriteListener writeListener)
{
//this.writeListener = writeListener;
}

@Override
public boolean isReady()
{
return true;
}
}

GenericResponseWrapper.java

[code=plain]import java.io.ByteArrayOutputStream;
import java.io.PrintWriter;

import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpServletResponseWrapper;

public class GenericResponseWrapper extends HttpServletResponseWrapper
{
private ByteArrayOutputStream	output;
private int						contentLength;
private String					contentType;

public GenericResponseWrapper(HttpServletResponse response)
{
super(response);
output = new ByteArrayOutputStream();
}

public byte[] getData()
{
return output.toByteArray();
}

public ServletOutputStream getOutputStream()
{
return new FilterServletOutputStream(output);
}

public PrintWriter getWriter()
{
return new PrintWriter(getOutputStream(), true);
}

public void setContentLength(int length)
{
this.contentLength = length;
super.setContentLength(length);
}

public int getContentLength()
{
return contentLength;
}

public void setContentType(String type)
{
this.contentType = type;
super.setContentType(type);
}

public String getContentType()
{
return contentType;
}
}

JsonpCallbackFilter.java

[code=language-java]import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.util.Map;

import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public class JsonpCallbackFilter implements Filter
{

private static Logger	log	= LoggerFactory.getLogger(JsonpCallbackFilter.class);

public void init(FilterConfig fConfig) throws ServletException
{
}

public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException,
ServletException
{
HttpServletRequest httpRequest = (HttpServletRequest) request;
HttpServletResponse httpResponse = (HttpServletResponse) response;

Map<String, String[]> parms = httpRequest.getParameterMap();

if (parms.containsKey("callback"))
{
if (log.isDebugEnabled())
log.debug("Wrapping response with JSONP callback '" + parms.get("callback")[0] + "'");

OutputStream out = httpResponse.getOutputStream();

GenericResponseWrapper wrapper = new GenericResponseWrapper(httpResponse);

chain.doFilter(request, wrapper);

// handles the content-size truncation
ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
outputStream.write(new String(parms.get("callback")[0] + "(").getBytes());
outputStream.write(wrapper.getData());
outputStream.write(new String(");").getBytes());
byte jsonpResponse[] = outputStream.toByteArray();

wrapper.setContentType("text/javascript;charset=UTF-8");
wrapper.setContentLength(jsonpResponse.length);

out.write(jsonpResponse);

out.close();

}
else
{
chain.doFilter(request, response);
}
}

public void destroy()
{
}
}

3,前端页面



这个也是从官方demo拷贝出来的,这里单独把这个文件夹打包出来,大家也可以从官方demo里提取。

4,如何显示

访问:http://localhost:8080/demo/diagram-viewer/index.html?processDefinitionId=project_approve:123:317507&processInstanceId=325001

其中对应的参数填写自己的流程定义ID和实例ID

5,显示效果

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: