Package org.jbpm.bpmn2.xml

Source Code of org.jbpm.bpmn2.xml.ProcessHandler

/**
* Copyright 2010 JBoss Inc
*
* 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.jbpm.bpmn2.xml;

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

import org.drools.definition.process.Node;
import org.drools.definition.process.NodeContainer;
import org.drools.xml.BaseAbstractHandler;
import org.drools.xml.ExtensibleXmlParser;
import org.drools.xml.Handler;
import org.jbpm.bpmn2.core.DataStore;
import org.jbpm.bpmn2.core.Definitions;
import org.jbpm.bpmn2.core.Error;
import org.jbpm.bpmn2.core.Escalation;
import org.jbpm.bpmn2.core.Interface;
import org.jbpm.bpmn2.core.ItemDefinition;
import org.jbpm.bpmn2.core.Lane;
import org.jbpm.bpmn2.core.Message;
import org.jbpm.bpmn2.core.SequenceFlow;
import org.jbpm.compiler.xml.ProcessBuildData;
import org.jbpm.process.core.context.exception.ActionExceptionHandler;
import org.jbpm.process.core.context.exception.ExceptionScope;
import org.jbpm.process.core.context.swimlane.Swimlane;
import org.jbpm.process.core.event.EventTypeFilter;
import org.jbpm.process.core.timer.Timer;
import org.jbpm.ruleflow.core.RuleFlowProcess;
import org.jbpm.workflow.core.Connection;
import org.jbpm.workflow.core.Constraint;
import org.jbpm.workflow.core.impl.ConnectionImpl;
import org.jbpm.workflow.core.impl.ConnectionRef;
import org.jbpm.workflow.core.impl.ConstraintImpl;
import org.jbpm.workflow.core.impl.DroolsConsequenceAction;
import org.jbpm.workflow.core.impl.NodeImpl;
import org.jbpm.workflow.core.node.CompositeContextNode;
import org.jbpm.workflow.core.node.EventNode;
import org.jbpm.workflow.core.node.HumanTaskNode;
import org.jbpm.workflow.core.node.Split;
import org.jbpm.workflow.core.node.StateNode;
import org.xml.sax.Attributes;
import org.xml.sax.SAXException;

public class ProcessHandler extends BaseAbstractHandler implements Handler {
 
  public static final String CONNECTIONS = "BPMN.Connections";

  @SuppressWarnings("unchecked")
  public ProcessHandler() {
    if ((this.validParents == null) && (this.validPeers == null)) {
      this.validParents = new HashSet();
      this.validParents.add(Definitions.class);

      this.validPeers = new HashSet();
      this.validPeers.add(null);
            this.validPeers.add(ItemDefinition.class);
            this.validPeers.add(Message.class);
            this.validPeers.add(Interface.class);
            this.validPeers.add(Escalation.class);
            this.validPeers.add(Error.class);
            this.validPeers.add(DataStore.class);
            this.validPeers.add(RuleFlowProcess.class);

      this.allowNesting = false;
    }
  }

  public Object start(final String uri, final String localName,
                  final Attributes attrs, final ExtensibleXmlParser parser)
      throws SAXException {
    parser.startElementBuilder(localName, attrs);

    String id = attrs.getValue("id");
    String name = attrs.getValue("name");
    String packageName = attrs.getValue("http://www.jboss.org/drools", "packageName");
    String dynamic = attrs.getValue("http://www.jboss.org/drools", "adHoc");
    String version = attrs.getValue("http://www.jboss.org/drools", "version");

    RuleFlowProcess process = new RuleFlowProcess();
    process.setAutoComplete(true);
    process.setId(id);
    if (name == null) {
        name = id;
    }
    process.setName(name);
    process.setType("RuleFlow");
    if (packageName == null) {
      packageName = "org.drools.bpmn2";
    }
    process.setPackageName(packageName);
    if ("true".equals(dynamic)) {
      process.setDynamic(true);
      process.setAutoComplete(false);
    }
    if (version != null) {
      process.setVersion(version);
    }

    ((ProcessBuildData) parser.getData()).addProcess(process);
    // register the definitions object as metadata of process.
    process.setMetaData("Definitions", parser.getParent());
    return process;
  }

  @SuppressWarnings("unchecked")
  public Object end(final String uri, final String localName,
                final ExtensibleXmlParser parser) throws SAXException {
    parser.endElementBuilder();
    RuleFlowProcess process = (RuleFlowProcess) parser.getCurrent();
    List<SequenceFlow> connections = (List<SequenceFlow>)
      process.getMetaData(CONNECTIONS);
    linkConnections(process, connections);
    linkBoundaryEvents(process);
        List<Lane> lanes = (List<Lane>)
            process.getMetaData(LaneHandler.LANES);
        assignLanes(process, lanes);
        postProcessNodes(process);
    return process;
  }

  public Class<?> generateNodeFor() {
    return org.drools.definition.process.Process.class;
  }
 
  public static void linkConnections(NodeContainer nodeContainer, List<SequenceFlow> connections) {
    if (connections != null) {
      for (SequenceFlow connection: connections) {
        String sourceRef = connection.getSourceRef();
        String targetRef = connection.getTargetRef();
        Node source = null;
        Node target = null;
        try {
            // remove starting _
            sourceRef = sourceRef.substring(1);
            // remove ids of parent nodes
            sourceRef = sourceRef.substring(sourceRef.lastIndexOf("-") + 1);
            source = nodeContainer.getNode(new Integer(sourceRef));
        } catch (NumberFormatException e) {
            // try looking for a node with same "UniqueId" (in metadata)
            for (Node node: nodeContainer.getNodes()) {
                if (connection.getSourceRef().equals(node.getMetaData().get("UniqueId"))) {
                    source = node;
                    break;
                }
            }
                    if (source == null) {
                        throw new IllegalArgumentException("Could not find source node for connection:" + connection.getSourceRef());
                    }
        }
        try {
            // remove starting _
            targetRef = targetRef.substring(1);
                // remove ids of parent nodes
            targetRef = targetRef.substring(targetRef.lastIndexOf("-") + 1);
            target = nodeContainer.getNode(new Integer(targetRef));
        } catch (NumberFormatException e) {
            // try looking for a node with same "UniqueId" (in metadata)
                    for (Node node: nodeContainer.getNodes()) {
                        if (connection.getTargetRef().equals(node.getMetaData().get("UniqueId"))) {
                            target = node;
                            break;
                        }
                    }
                    if (target == null) {
                        throw new IllegalArgumentException("Could not find target node for connection:" + connection.getTargetRef());
                    }
        }
        Connection result = new ConnectionImpl(
          source, NodeImpl.CONNECTION_DEFAULT_TYPE,
          target, NodeImpl.CONNECTION_DEFAULT_TYPE);
        result.setMetaData("bendpoints", connection.getBendpoints());
        result.setMetaData("UniqueId", connection.getId());
        if (source instanceof Split) {
          Split split = (Split) source;
          Constraint constraint = new ConstraintImpl();
          String defaultConnection = (String) split.getMetaData("Default");
          if (defaultConnection != null && defaultConnection.equals(connection.getId())) {
            constraint.setDefault(true);
          }
          if (connection.getName() != null) {
            constraint.setName(connection.getName());
          } else {
            constraint.setName("");
          }
          if (connection.getType() != null) {
            constraint.setType(connection.getType());
          } else {
            constraint.setType("code");
          }
          if (connection.getLanguage() != null) {
            constraint.setDialect(connection.getLanguage());
          }
          if (connection.getExpression() != null) {
            constraint.setConstraint(connection.getExpression());
          }
          constraint.setPriority(connection.getPriority());
          split.addConstraint(
            new ConnectionRef(target.getId(), NodeImpl.CONNECTION_DEFAULT_TYPE),
            constraint);
        }
      }
    }
  }
 
    public static void linkBoundaryEvents(NodeContainer nodeContainer) {
        for (Node node: nodeContainer.getNodes()) {
            if (node instanceof EventNode) {
                String attachedTo = (String) node.getMetaData().get("AttachedTo");
                if (attachedTo != null) {
                  String type = ((EventTypeFilter)
                        ((EventNode) node).getEventFilters().get(0)).getType();
                    Node attachedNode = null;
                    try {
                        // remove starting _
                        String attachedToString = attachedTo.substring(1);
                        // remove ids of parent nodes
                        attachedToString = attachedToString.substring(attachedToString.lastIndexOf("-") + 1);
                        attachedNode = nodeContainer.getNode(new Integer(attachedToString));
                    } catch (NumberFormatException e) {
                        // try looking for a node with same "UniqueId" (in metadata)
                        for (Node subnode: nodeContainer.getNodes()) {
                            if (attachedTo.equals(subnode.getMetaData().get("UniqueId"))) {
                                attachedNode = subnode;
                                break;
                            }
                        }
                        if (attachedNode == null) {
                            throw new IllegalArgumentException("Could not find node to attach to: " + attachedTo);
                        }
                    }
                    if (type.startsWith("Escalation-")) {
                        boolean cancelActivity = (Boolean) node.getMetaData().get("CancelActivity");
                        CompositeContextNode compositeNode = (CompositeContextNode) attachedNode;
                        ExceptionScope exceptionScope = (ExceptionScope)
                            compositeNode.getDefaultContext(ExceptionScope.EXCEPTION_SCOPE);
                        if (exceptionScope == null) {
                            exceptionScope = new ExceptionScope();
                            compositeNode.addContext(exceptionScope);
                            compositeNode.setDefaultContext(exceptionScope);
                        }
                        String escalationCode = (String) node.getMetaData().get("EscalationEvent");
                        ActionExceptionHandler exceptionHandler = new ActionExceptionHandler();
                        exceptionHandler.setAction(new DroolsConsequenceAction("java",
                            (cancelActivity ? "((org.jbpm.workflow.instance.NodeInstance) kcontext.getNodeInstance()).cancel();" : "") +
                            "kcontext.getProcessInstance().signalEvent(\"Escalation-" + attachedTo + "-" + escalationCode + "\", null);"));
                        exceptionScope.setExceptionHandler(escalationCode, exceptionHandler);
                    } else if (type.startsWith("Error-")) {
                        CompositeContextNode compositeNode = (CompositeContextNode) attachedNode;
                        ExceptionScope exceptionScope = (ExceptionScope)
                            compositeNode.getDefaultContext(ExceptionScope.EXCEPTION_SCOPE);
                        if (exceptionScope == null) {
                            exceptionScope = new ExceptionScope();
                            compositeNode.addContext(exceptionScope);
                            compositeNode.setDefaultContext(exceptionScope);
                        }
                        String errorCode = (String) node.getMetaData().get("ErrorEvent");
                        ActionExceptionHandler exceptionHandler = new ActionExceptionHandler();
                        exceptionHandler.setAction(new DroolsConsequenceAction("java",
                            "((org.jbpm.workflow.instance.NodeInstance) kcontext.getNodeInstance()).cancel();" +
                            "kcontext.getProcessInstance().signalEvent(\"Error-" + attachedTo + "-" + errorCode + "\", null);"));
                        exceptionScope.setExceptionHandler(errorCode, exceptionHandler);
                    } else if (type.startsWith("Timer-")) {
                        boolean cancelActivity = (Boolean) node.getMetaData().get("CancelActivity");
                        CompositeContextNode compositeNode = (CompositeContextNode) attachedNode;
                        String timeDuration = (String) node.getMetaData().get("TimeDuration");
                        String timeCycle = (String) node.getMetaData().get("TimeCycle");
                        Timer timer = new Timer();
                        if (timeDuration != null) {
                          timer.setDelay(timeDuration);
                            compositeNode.addTimer(timer, new DroolsConsequenceAction("java",
                                (cancelActivity ? "((org.jbpm.workflow.instance.NodeInstance) kcontext.getNodeInstance()).cancel();" : "") +
                                "kcontext.getProcessInstance().signalEvent(\"Timer-" + attachedTo + "-" + timeDuration + "\", null);"));
                        } else if (timeCycle != null) {
                          int index = timeCycle.indexOf("###");
                          if (index != -1) {
                            String period = timeCycle.substring(index + 3);
                            timeCycle = timeCycle.substring(0, index);
                                timer.setPeriod(period);
                          }
                          timer.setDelay(timeCycle);
                            compositeNode.addTimer(timer, new DroolsConsequenceAction("java",
                                (cancelActivity ? "((org.jbpm.workflow.instance.NodeInstance) kcontext.getNodeInstance()).cancel();" : "") +
                                "kcontext.getProcessInstance().signalEvent(\"Timer-" + attachedTo + "-" + timeCycle + (timer.getPeriod() == null ? "" : "###" + timer.getPeriod()) + "\", null);"));
                        }
                    } else if (type.startsWith("Compensate-")) {
                      String uniqueId = (String) node.getMetaData().get("UniqueId");
                      String eventType = "Compensate-" + uniqueId;
                      ((EventTypeFilter) ((EventNode) node).getEventFilters().get(0)).setType(eventType);
                    }
                }
            }
        }
    }
   
  private void assignLanes(RuleFlowProcess process, List<Lane> lanes) {
      List<String> laneNames = new ArrayList<String>();
      Map<String, String> laneMapping = new HashMap<String, String>();
      if (lanes != null) {
          for (Lane lane: lanes) {
              String name = lane.getName();
              if (name != null) {
                  Swimlane swimlane = new Swimlane();
                  swimlane.setName(name);
                  process.getSwimlaneContext().addSwimlane(swimlane);
                  laneNames.add(name);
                  for (String flowElementRef: lane.getFlowElements()) {
                      laneMapping.put(flowElementRef, name);
                  }
              }
          }
      }
      assignLanes(process, laneMapping);
  }
 
    private void postProcessNodes(NodeContainer container) {
        for (Node node: container.getNodes()) {
            if (node instanceof StateNode) {
                StateNode stateNode = (StateNode) node;
                String condition = (String) stateNode.getMetaData("Condition");
                Constraint constraint = new ConstraintImpl();
                constraint.setConstraint(condition);
                constraint.setType("rule");
                for (org.drools.definition.process.Connection connection: stateNode.getDefaultOutgoingConnections()) {
                    stateNode.setConstraint(connection, constraint);
                }
            } else if (node instanceof NodeContainer) {
                postProcessNodes((NodeContainer) node);
            }
        }
    }
   
  private void assignLanes(NodeContainer nodeContainer, Map<String, String> laneMapping) {
      for (Node node: nodeContainer.getNodes()) {
          String lane = null;
          String uniqueId = (String) node.getMetaData().get("UniqueId");
          if (uniqueId != null) {
              lane = laneMapping.get(uniqueId);
          } else {
              lane = laneMapping.get(XmlBPMNProcessDumper.getUniqueNodeId(node));
          }
          if (lane != null) {
              ((NodeImpl) node).setMetaData("Lane", lane);
              if (node instanceof HumanTaskNode) {
                  ((HumanTaskNode) node).setSwimlane(lane);
              }
          }
          if (node instanceof NodeContainer) {
              assignLanes((NodeContainer) node, laneMapping);
          }
      }
  }

}
TOP

Related Classes of org.jbpm.bpmn2.xml.ProcessHandler

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.