Package org.activiti.workflow.simple.converter.listener

Source Code of org.activiti.workflow.simple.converter.listener.DefaultWorkflowDefinitionConversionListener

/* 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.listener;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;

import org.activiti.bpmn.model.EndEvent;
import org.activiti.bpmn.model.FlowElement;
import org.activiti.bpmn.model.FlowNode;
import org.activiti.bpmn.model.Process;
import org.activiti.bpmn.model.SequenceFlow;
import org.activiti.bpmn.model.StartEvent;
import org.activiti.workflow.simple.converter.ConversionConstants;
import org.activiti.workflow.simple.converter.WorkflowDefinitionConversion;
import org.activiti.workflow.simple.converter.WorkflowDefinitionConversionFactory;
import org.activiti.workflow.simple.definition.WorkflowDefinition;

/**
* Default listener for {@link WorkflowDefinitionConversion} lifecycle events.
*
* When added to a {@link WorkflowDefinitionConversionFactory}, this class will
* make sure a start event and end event is created for the {@link Process}.
* Further, it will generate a correct incoming and outgoing sequence flow list
* for each {@link Process} element, as required by some toolings (eg Modeler).
*
* @author Joram Barrez
*/
public class DefaultWorkflowDefinitionConversionListener implements WorkflowDefinitionConversionListener {

  private static final long serialVersionUID = -145978383684020118L;

  private static final String START_EVENT_ID = "start";

  private static final String END_EVENT_ID = "end";

  public void beforeStepsConversion(WorkflowDefinitionConversion conversion) {
    initializeProcess(conversion);
  }

  protected void initializeProcess(WorkflowDefinitionConversion conversion) {
    WorkflowDefinition workflowDefinition = conversion.getWorkflowDefinition();

    // Create new process
    Process process = conversion.getProcess();
    process.setId(generateProcessId(workflowDefinition));
    process.setName(workflowDefinition.getName());
    process.setDocumentation(workflowDefinition.getDescription());
   
    if (workflowDefinition.getCategory() != null) {
      conversion.getBpmnModel().setTargetNamespace(workflowDefinition.getCategory());
    }

    conversion.setProcess(process);

    // Add start-event
    StartEvent startEvent = new StartEvent();
    startEvent.setId(START_EVENT_ID);
   
    if(workflowDefinition.getStartFormDefinition() != null && workflowDefinition.getStartFormDefinition().getFormKey() != null) {
      startEvent.setFormKey(workflowDefinition.getStartFormDefinition().getFormKey());
    }
   
    process.addFlowElement(startEvent);
    conversion.setLastActivityId(startEvent.getId());
  }

  /**
   * @param workflowDefinition
   * @return process definition id that is randomized, to avoid name clashes
   *         (eg. amongst differnt tenants)
   */
  protected String generateProcessId(WorkflowDefinition workflowDefinition) {
    String processId = null;
    if(workflowDefinition.getId() != null) {
      processId = workflowDefinition.getId();
    } else {
      // Revert to using the name of the process
      if(workflowDefinition.getName() != null) {
        processId = workflowDefinition.getName().replace(" ", "_");
      }
    }
    return processId;
  }

  public void afterStepsConversion(WorkflowDefinitionConversion conversion) {
    // Add end-event to process
    Process process = conversion.getProcess();

    EndEvent endEvent = new EndEvent();
    endEvent.setId(END_EVENT_ID);
    process.addFlowElement(endEvent);

    // Sequence flow from last created activity to end
    SequenceFlow sequenceFlow = new SequenceFlow();
    sequenceFlow.setId(conversion.getUniqueNumberedId(ConversionConstants.DEFAULT_SEQUENCEFLOW_PREFIX));
    sequenceFlow.setSourceRef(conversion.getLastActivityId());
    sequenceFlow.setTargetRef(END_EVENT_ID);
    process.addFlowElement(sequenceFlow);

    // To make the generated workflow compatible with some tools (eg the
    // Modeler, but also others),
    // We must add the ingoing and outgoing sequence flow to each of the flow
    // nodes
    SequenceFlowMapping sequenceFlowMapping = generateSequenceflowMappings(process);

    for (FlowNode flowNode : process.findFlowElementsOfType(FlowNode.class)) {
      List<SequenceFlow> incomingSequenceFlow = sequenceFlowMapping.getIncomingSequenceFlowMapping().get(flowNode.getId());
      if (incomingSequenceFlow != null) {
        flowNode.setIncomingFlows(incomingSequenceFlow);
      }

      List<SequenceFlow> outgoingSequenceFlow = sequenceFlowMapping.getOutgoingSequenceFlowMapping().get(flowNode.getId());
      if (outgoingSequenceFlow != null) {
        flowNode.setOutgoingFlows(outgoingSequenceFlow);
      }
    }
  }

  protected SequenceFlowMapping generateSequenceflowMappings(Process process) {
    HashMap<String, List<SequenceFlow>> incomingSequenceFlowMapping = new HashMap<String, List<SequenceFlow>>();
    HashMap<String, List<SequenceFlow>> outgoingSequenceFlowMapping = new HashMap<String, List<SequenceFlow>>();

    for (FlowElement flowElement : process.findFlowElementsOfType(SequenceFlow.class)) {
      SequenceFlow sequenceFlow = (SequenceFlow) flowElement;
      String srcId = sequenceFlow.getSourceRef();
      String targetId = sequenceFlow.getTargetRef();

      if (outgoingSequenceFlowMapping.get(srcId) == null) {
        outgoingSequenceFlowMapping.put(srcId, new ArrayList<SequenceFlow>());
      }
      outgoingSequenceFlowMapping.get(srcId).add(sequenceFlow);

      if (incomingSequenceFlowMapping.get(targetId) == null) {
        incomingSequenceFlowMapping.put(targetId, new ArrayList<SequenceFlow>());
      }
      incomingSequenceFlowMapping.get(targetId).add(sequenceFlow);
    }

    SequenceFlowMapping mapping = new SequenceFlowMapping();
    mapping.setIncomingSequenceFlowMapping(incomingSequenceFlowMapping);
    mapping.setOutgoingSequenceFlowMapping(outgoingSequenceFlowMapping);
    return mapping;
  }

  static class SequenceFlowMapping {

    protected HashMap<String, List<SequenceFlow>> incomingSequenceFlowMapping;
    protected HashMap<String, List<SequenceFlow>> outgoingSequenceFlowMapping;

    public HashMap<String, List<SequenceFlow>> getIncomingSequenceFlowMapping() {
      return incomingSequenceFlowMapping;
    }

    public void setIncomingSequenceFlowMapping(HashMap<String, List<SequenceFlow>> incomingSequenceFlowMapping) {
      if (incomingSequenceFlowMapping != null) {
        this.incomingSequenceFlowMapping = incomingSequenceFlowMapping;
      } else {
        this.incomingSequenceFlowMapping = new HashMap<String, List<SequenceFlow>>();
      }
    }

    public HashMap<String, List<SequenceFlow>> getOutgoingSequenceFlowMapping() {
      return outgoingSequenceFlowMapping;
    }

    public void setOutgoingSequenceFlowMapping(HashMap<String, List<SequenceFlow>> outgoingSequenceFlowMapping) {
      if (outgoingSequenceFlowMapping != null) {
        this.outgoingSequenceFlowMapping = outgoingSequenceFlowMapping;
      } else {
        this.outgoingSequenceFlowMapping = new HashMap<String, List<SequenceFlow>>();
      }
    }

  }

}
TOP

Related Classes of org.activiti.workflow.simple.converter.listener.DefaultWorkflowDefinitionConversionListener

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.