/* 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; } }