/* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.activiti.kickstart.service;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.activiti.engine.HistoryService;
import org.activiti.engine.RepositoryService;
import org.activiti.engine.repository.ProcessDefinition;
import org.activiti.kickstart.bpmn20.model.BaseElement;
import org.activiti.kickstart.bpmn20.model.Definitions;
import org.activiti.kickstart.bpmn20.model.FlowElement;
import org.activiti.kickstart.bpmn20.model.activity.Task;
import org.activiti.kickstart.bpmn20.model.activity.resource.ActivityResource;
import org.activiti.kickstart.bpmn20.model.activity.resource.HumanPerformer;
import org.activiti.kickstart.bpmn20.model.activity.resource.PotentialOwner;
import org.activiti.kickstart.bpmn20.model.activity.type.ScriptTask;
import org.activiti.kickstart.bpmn20.model.activity.type.ServiceTask;
import org.activiti.kickstart.bpmn20.model.activity.type.UserTask;
import org.activiti.kickstart.bpmn20.model.connector.SequenceFlow;
import org.activiti.kickstart.bpmn20.model.extension.AbstractExtensionElement;
import org.activiti.kickstart.bpmn20.model.extension.activiti.ActivitFieldExtensionElement;
import org.activiti.kickstart.bpmn20.model.extension.activiti.ActivitiFormProperty;
import org.activiti.kickstart.bpmn20.model.gateway.ParallelGateway;
import org.activiti.kickstart.dto.KickstartForm;
import org.activiti.kickstart.dto.KickstartFormProperty;
import org.activiti.kickstart.dto.KickstartMailTask;
import org.activiti.kickstart.dto.KickstartScriptTask;
import org.activiti.kickstart.dto.KickstartServiceTask;
import org.activiti.kickstart.dto.KickstartTask;
import org.activiti.kickstart.dto.KickstartUserTask;
import org.activiti.kickstart.dto.KickstartWorkflow;
import org.activiti.kickstart.dto.KickstartWorkflowInfo;
/**
*
* @author jbarrez
*/
public class TransformationServiceImpl implements TransformationService {
protected RepositoryService repositoryService;
protected HistoryService historyService;
protected FormTransformationService formTransformationService;
public FormTransformationService getFormTransformationService() {
return formTransformationService;
}
public void setFormTransformationService(FormTransformationService formTransformationService) {
this.formTransformationService = formTransformationService;
}
public RepositoryService getRepositoryService() {
return repositoryService;
}
public void setRepositoryService(RepositoryService repositoryService) {
this.repositoryService = repositoryService;
}
public HistoryService getHistoryService() {
return historyService;
}
public void setHistoryService(HistoryService historyService) {
this.historyService = historyService;
}
// -------------------------------------------------------------------------------
// BPMN 2.0 --> KICKSTART INTERNAL CLASSES ---------------------------------------
// -------------------------------------------------------------------------------
public List<KickstartWorkflowInfo> convertToWorkflowInfoList(List<ProcessDefinition> processDefinitions, boolean includeCounts) {
List<KickstartWorkflowInfo> infoList = new ArrayList<KickstartWorkflowInfo>();
for (ProcessDefinition processDefinition : processDefinitions) {
KickstartWorkflowInfo workflowInfo = new KickstartWorkflowInfo();
workflowInfo.setId(processDefinition.getId());
workflowInfo.setKey(processDefinition.getKey());
workflowInfo.setName(processDefinition.getName());
workflowInfo.setVersion(processDefinition.getVersion());
workflowInfo.setDeploymentId(processDefinition.getDeploymentId());
Date deploymentTime = repositoryService.createDeploymentQuery()
.deploymentId(processDefinition.getDeploymentId())
.singleResult().getDeploymentTime();
workflowInfo.setCreateTime(deploymentTime);
if (includeCounts) {
workflowInfo.setNrOfRuntimeInstances(historyService
.createHistoricProcessInstanceQuery()
.processDefinitionId(processDefinition.getId())
.unfinished().count());
workflowInfo.setNrOfHistoricInstances(historyService
.createHistoricProcessInstanceQuery()
.processDefinitionId(processDefinition.getId()).finished()
.count());
}
infoList.add(workflowInfo);
}
return infoList;
}
public KickstartWorkflow convertToKickstartWorkflow(Definitions definitions) {
KickstartWorkflow adhocWorkflow = new KickstartWorkflow();
for (BaseElement baseElement : definitions.getRootElement()) {
if (baseElement instanceof org.activiti.kickstart.bpmn20.model.Process) {
org.activiti.kickstart.bpmn20.model.Process process = (org.activiti.kickstart.bpmn20.model.Process) baseElement;
// Process name and description
adhocWorkflow.setName(process.getName());
if (!process.getDocumentation().isEmpty()) {
adhocWorkflow.setDescription(process.getDocumentation().get(0).getText());
}
// user tasks
Map<String, Task> tasks = new HashMap<String, Task>();
Map<String, ParallelGateway> gateways = new HashMap<String, ParallelGateway>();
Map<String, List<SequenceFlow>> sequenceFlows = new HashMap<String, List<SequenceFlow>>();
for (FlowElement flowElement : process.getFlowElement()) {
if (flowElement instanceof Task) {
tasks.put(flowElement.getId(), (Task) flowElement);
}
if (flowElement instanceof ParallelGateway) {
gateways.put(flowElement.getId(),(ParallelGateway) flowElement);
}
if (flowElement instanceof SequenceFlow) {
SequenceFlow sequenceFlow = (SequenceFlow) flowElement;
String sourceRef = sequenceFlow.getSourceRef().getId();
if (!sequenceFlows.containsKey(sourceRef)) {
sequenceFlows.put(sourceRef, new ArrayList<SequenceFlow>());
}
sequenceFlows.get(sourceRef).add(sequenceFlow);
}
}
// Follow sequence flow to discover sequence of tasks
SequenceFlow currentSequenceFlow = sequenceFlows.get(KickstartWorkflow.START_NAME).get(0); // Can be only one
while (!currentSequenceFlow.getTargetRef().getId().equals(KickstartWorkflow.END_NAME)) {
String targetRef = currentSequenceFlow.getTargetRef().getId();
KickstartTask taskDto = null;
if (tasks.containsKey(targetRef)) {
taskDto = convertToKickstartTask((Task) currentSequenceFlow.getTargetRef());
currentSequenceFlow = sequenceFlows.get(currentSequenceFlow.getTargetRef().getId()).get(0); // Can be only one
adhocWorkflow.addTask(taskDto);
} else if (gateways.containsKey(targetRef)) {
Task task = null;
for (int i = 0; i < sequenceFlows.get(targetRef).size(); i++) {
SequenceFlow seqFlowOutOfGateway = sequenceFlows.get(targetRef).get(i);
task = (Task) seqFlowOutOfGateway.getTargetRef();
taskDto = convertToKickstartTask(task);
if (i > 0) {
taskDto.setStartWithPrevious(true);
}
adhocWorkflow.addTask(taskDto);
}
String parallelJoinId = sequenceFlows.get(task.getId()).get(0).getTargetRef().getId(); // any seqflow is ok
currentSequenceFlow = sequenceFlows.get(parallelJoinId).get(0); // can be only one
}
} // end while
}
}
return adhocWorkflow;
}
public KickstartTask convertToKickstartTask(final Task task) {
KickstartTask taskDto = null;
if (task instanceof UserTask) {
taskDto = convertToKickstartUserTask((UserTask) task);
} else if (task instanceof ServiceTask) {
if (((ServiceTask) task).getType() != null && ((ServiceTask) task).getType().equals("mail")) {
taskDto = convertToKickstartMailTask((ServiceTask) task);
} else {
taskDto = convertToKickstartServiceTask((ServiceTask) task);
}
} else if (task instanceof ScriptTask) {
taskDto = convertToKickstartScriptTask((ScriptTask) task);
}
handleGeneralTaskDtoProperties(taskDto, task);
return taskDto;
}
private void handleGeneralTaskDtoProperties(KickstartTask baseTaskDto, Task task) {
// task id
baseTaskDto.setId(task.getId());
// task name
baseTaskDto.setName(task.getName());
// TODO: Disabled until I figure out how I can do CDATE with JaxB
// task description
if (!task.getDocumentation().isEmpty()) {
baseTaskDto.setDescription(task.getDocumentation().get(0).getText());
}
}
public KickstartUserTask convertToKickstartUserTask(final UserTask userTask) {
KickstartUserTask task = new KickstartUserTask();
// Assignment
for (ActivityResource activityResource : userTask.getActivityResource()) {
if (activityResource instanceof PotentialOwner) {
PotentialOwner potentialOwner = (PotentialOwner) activityResource;
List<String> content = potentialOwner
.getResourceAssignmentExpression().getExpression()
.getContent();
if (!content.isEmpty()) {
task.setGroups(content.get(0));
}
} else if (activityResource instanceof HumanPerformer) {
HumanPerformer humanPerformer = (HumanPerformer) activityResource;
List<String> content = humanPerformer
.getResourceAssignmentExpression().getExpression()
.getContent();
if (!content.isEmpty()) {
task.setAssignee(content.get(0));
}
}
}
// Task form
List<KickstartFormProperty> formPropertyDtos = new ArrayList<KickstartFormProperty>();
if (userTask.getExtensionElements() != null) {
for (AbstractExtensionElement extensionElement : userTask.getExtensionElements().getAllElementOfType(ActivitiFormProperty.class)) {
ActivitiFormProperty formProperty = (ActivitiFormProperty) extensionElement;
KickstartFormProperty formPropertyDto = new KickstartFormProperty();
formPropertyDto.setProperty(formProperty.getName());
String formType = formProperty.getType();
String type = "text";
if ("date".equals(formType)) {
type = "date";
} else if ("long".equals(formType)) {
type = "number";
}
formPropertyDto.setType(type);
formPropertyDto.setRequired("true".equals(formProperty.getRequired()));
formPropertyDtos.add(formPropertyDto);
}
}
if (formPropertyDtos.size() > 0) {
KickstartForm formDto = new KickstartForm();
formDto.setFormProperties(formPropertyDtos);
task.setForm(formDto);
}
return task;
}
public KickstartServiceTask convertToKickstartServiceTask(final ServiceTask serviceTask) {
KickstartServiceTask task = new KickstartServiceTask();
task.setClassName(serviceTask.getClassName());
task.setExpression(serviceTask.getExpression());
task.setDelegateExpression(serviceTask.getDelegateExpression());
return task;
}
public KickstartMailTask convertToKickstartMailTask(final ServiceTask serviceTask) {
KickstartMailTask task = new KickstartMailTask();
List<AbstractExtensionElement> extensionElements = serviceTask.getExtensionElements().getAny();
for (AbstractExtensionElement abstractExtensionElement : extensionElements) {
ActivitFieldExtensionElement field = (ActivitFieldExtensionElement) abstractExtensionElement;
String fieldName = field.getName();
if (fieldName.equals("to")) {
task.getTo().setStringValue(field.getStringValue());
task.getTo().setExpression(field.getExpression());
} else if (fieldName.equals("from")) {
task.getFrom().setStringValue(field.getStringValue());
task.getFrom().setExpression(field.getExpression());
} else if (fieldName.equals("subject")) {
task.getSubject().setStringValue(field.getStringValue());
task.getSubject().setExpression(field.getExpression());
} else if (fieldName.equals("cc")) {
task.getCc().setStringValue(field.getStringValue());
task.getCc().setExpression(field.getExpression());
} else if (fieldName.equals("bcc")) {
task.getBcc().setStringValue(field.getStringValue());
task.getBcc().setExpression(field.getExpression());
} else if (fieldName.equals("html")) {
task.getHtml().setStringValue(field.getStringValue());
task.getHtml().setExpression(field.getExpression());
} else if (fieldName.equals("text")) {
task.getText().setStringValue(field.getStringValue());
task.getText().setExpression(field.getExpression());
}
}
return task;
}
public KickstartScriptTask convertToKickstartScriptTask(final ScriptTask serviceTask) {
KickstartScriptTask task = new KickstartScriptTask();
task.setScriptFormat(serviceTask.getScriptFormat());
task.setResultVariableName(serviceTask.getResultVariableName());
task.setScript(serviceTask.getScript());
return task;
}
}