/* 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.workflow.simple.converter.step; import java.util.ArrayList; import java.util.List; import org.activiti.bpmn.model.FlowElement; import org.activiti.bpmn.model.ParallelGateway; import org.activiti.workflow.simple.converter.WorkflowDefinitionConversion; import org.activiti.workflow.simple.converter.WorkflowDefinitionConversionFactory; import org.activiti.workflow.simple.definition.ListStepDefinition; import org.activiti.workflow.simple.definition.ParallelStepsDefinition; import org.activiti.workflow.simple.definition.StepDefinition; /** * {@link StepDefinitionConverter} for converting a {@link ParallelStepsDefinition} to the following BPMN 2.0 structure: * * __ t1___ * | | * + -- ...---+- * | | * - txxx--- * * @author Joram Barrez */ public class ParallelStepsDefinitionConverter extends BaseStepDefinitionConverter<ParallelStepsDefinition, ParallelGateway> { private static final long serialVersionUID = 1L; private static final String PARALLEL_GATEWAY_PREFIX = "parallelGateway"; public Class< ? extends StepDefinition> getHandledClass() { return ParallelStepsDefinition.class; } protected ParallelGateway createProcessArtifact(ParallelStepsDefinition parallelStepsDefinition, WorkflowDefinitionConversion conversion) { // First parallel gateway ParallelGateway forkGateway = createParallelGateway(conversion); // Sequence flow from last activity to first gateway addSequenceFlow(conversion, conversion.getLastActivityId(), forkGateway.getId()); conversion.setLastActivityId(forkGateway.getId()); // Convert all other steps, disabling activity id updates which makes all // generated steps have a sequence flow to the first gateway WorkflowDefinitionConversionFactory conversionFactory = conversion.getConversionFactory(); List<FlowElement> endElements = new ArrayList<FlowElement>(); for (ListStepDefinition<ParallelStepsDefinition> stepListDefinition : parallelStepsDefinition.getStepList()) { for (int i = 0; i < stepListDefinition.getSteps().size(); i++) { if (i == 0) { conversion.setSequenceflowGenerationEnabled(false); } else { conversion.setSequenceflowGenerationEnabled(true); } StepDefinition step = stepListDefinition.getSteps().get(i); FlowElement flowElement = (FlowElement) conversionFactory.getStepConverterFor(step).convertStepDefinition(step, conversion); if (i == 0) { addSequenceFlow(conversion, forkGateway.getId(), flowElement.getId()); } if ((i + 1) == stepListDefinition.getSteps().size()) { endElements.add(flowElement); } } } conversion.setSequenceflowGenerationEnabled(false); // Second parallel gateway ParallelGateway joinGateway = createParallelGateway(conversion); conversion.setLastActivityId(joinGateway.getId()); conversion.setSequenceflowGenerationEnabled(true); // Create sequence flow from all generated steps to the second gateway for (FlowElement endElement : endElements) { addSequenceFlow(conversion, endElement.getId(), joinGateway.getId()); } return forkGateway; } protected ParallelGateway createParallelGateway(WorkflowDefinitionConversion conversion) { ParallelGateway parallelGateway = new ParallelGateway(); parallelGateway.setId(conversion.getUniqueNumberedId(PARALLEL_GATEWAY_PREFIX)); conversion.getProcess().addFlowElement(parallelGateway); return parallelGateway; } }