⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 jpdlxmlreader.java

📁 jBpm是一个灵活可扩展的工作流管理系统。作为jBpm运行时server输入的业务流程使用简单强大的语言表达并打包在流程档案中
💻 JAVA
📖 第 1 页 / 共 2 页
字号:
/*
 * JBoss, Home of Professional Open Source
 * Copyright 2005, JBoss Inc., and individual contributors as indicated
 * by the @authors tag. See the copyright.txt in the distribution for a
 * full listing of individual contributors.
 *
 * This is free software; you can redistribute it and/or modify it
 * under the terms of the GNU Lesser General Public License as
 * published by the Free Software Foundation; either version 2.1 of
 * the License, or (at your option) any later version.
 *
 * This software is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this software; if not, write to the Free
 * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
 * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
 */
package org.jbpm.jpdl.xml;

import java.io.IOException;
import java.io.InputStream;
import java.io.Reader;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Iterator;
import java.util.List;
import java.util.StringTokenizer;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.dom4j.Document;
import org.dom4j.Element;
import org.jbpm.context.def.VariableAccess;
import org.jbpm.graph.action.ActionTypes;
import org.jbpm.graph.def.Action;
import org.jbpm.graph.def.Event;
import org.jbpm.graph.def.ExceptionHandler;
import org.jbpm.graph.def.GraphElement;
import org.jbpm.graph.def.Node;
import org.jbpm.graph.def.NodeCollection;
import org.jbpm.graph.def.ProcessDefinition;
import org.jbpm.graph.def.Transition;
import org.jbpm.graph.node.NodeTypes;
import org.jbpm.graph.node.StartState;
import org.jbpm.graph.node.TaskNode;
import org.jbpm.instantiation.Delegation;
import org.jbpm.jpdl.JpdlException;
import org.jbpm.scheduler.def.CancelTimerAction;
import org.jbpm.scheduler.def.CreateTimerAction;
import org.jbpm.taskmgmt.def.Swimlane;
import org.jbpm.taskmgmt.def.Task;
import org.jbpm.taskmgmt.def.TaskController;
import org.jbpm.taskmgmt.def.TaskMgmtDefinition;
import org.xml.sax.InputSource;

public class JpdlXmlReader implements ProblemListener {
  
  private static final long serialVersionUID = 1L;

  protected InputSource inputSource = null;
  protected List problems = new ArrayList();
  protected ProblemListener problemListener = null;
  protected ProcessDefinition processDefinition = null;
  protected Collection unresolvedTransitionDestinations = null;
  protected Collection unresolvedActionReferences = null;
  
  public JpdlXmlReader(InputSource inputSource) {
    this.inputSource = inputSource;
  }
  
  public JpdlXmlReader(InputSource inputSource, ProblemListener problemListener) {
    this.inputSource = inputSource;
    this.problemListener = problemListener;
  }
  
  public JpdlXmlReader(Reader reader) {
    this(new InputSource(reader));
  }

  public void close() throws IOException {
    InputStream byteStream = inputSource.getByteStream();
    if (byteStream != null) 
      byteStream.close();
    else {
      Reader charStream = inputSource.getCharacterStream();
      if (charStream != null)
        charStream.close();
    }
  }

  /**
   * @deprecated Originally, this class extended java.io.Reader. This method
   *  is reminiscent of those days.
   */
  public int read(char[] cbuf, int off, int len) throws IOException {
    return 0;
  }

  public ProcessDefinition getProcessDefinition() {
    return processDefinition;
  }

  public void addProblem(Problem problem) {
    problems.add(problem);
    if (problemListener!=null) problemListener.addProblem(problem);
  }
  
  public void addError(String description) {
    log.error("invalid process xml: "+description);
    addProblem(new Problem(Problem.LEVEL_ERROR, description));
  }

  public void addError(String description, Throwable exception) {
    log.error("invalid process xml: "+description, exception);
    addProblem(new Problem(Problem.LEVEL_ERROR, description, exception));
  }

  public void addWarning(String description) {
    log.warn("process xml warning: "+description);
    addProblem(new Problem(Problem.LEVEL_WARNING, description));
  }

  public ProcessDefinition readProcessDefinition() {
    // create a new definition
    processDefinition = ProcessDefinition.createNewProcessDefinition();

    // initialize lists
    problems = new ArrayList();
    unresolvedTransitionDestinations = new ArrayList();
    unresolvedActionReferences = new ArrayList();	
		
    try {
      // parse the document into a dom tree
      Document document = JpdlParser.parse(inputSource, this);
      Element root = document.getRootElement();
            
      // read the process name
      parseProcessDefinitionAttributes(root);

      // first pass: read most content
      readSwimlanes(root);
      readActions(root, null, null);
      readNodes(root, processDefinition);
      readEvents(root, processDefinition);
      readExceptionHandlers(root, processDefinition);
      readTasks(root, null);

      // second pass processing
      resolveTransitionDestinations();
      resolveActionReferences();
      verifySwimlaneAssignments();

    } catch (Exception e) {
      log.error("couldn't parse process definition", e);
      addProblem(new Problem(Problem.LEVEL_ERROR, "couldn't parse process definition", e));
    }
    
    if (Problem.containsProblemsOfLevel(problems, Problem.LEVEL_ERROR)) {
      throw new JpdlException(problems);
    }

    return processDefinition;
  }

  protected void parseProcessDefinitionAttributes(Element root) {
    processDefinition.setName(root.attributeValue("name"));
  }
  
  protected void readSwimlanes(Element processDefinitionElement) {
    Iterator iter = processDefinitionElement.elementIterator("swimlane");
    TaskMgmtDefinition taskMgmtDefinition = processDefinition.getTaskMgmtDefinition();
    while (iter.hasNext()) {
      Element swimlaneElement = (Element) iter.next();
      String swimlaneName = swimlaneElement.attributeValue("name");
      if (swimlaneName==null) {
        addWarning("there's a swimlane without a name");
      } else {
        Swimlane swimlane = new Swimlane(swimlaneName);
        Element assignmentElement = swimlaneElement.element("assignment");

        if (assignmentElement!=null) {
          
          if ( (assignmentElement.attribute("actor-id")!=null)
              || (assignmentElement.attribute("pooled-actors")!=null)
            ) {
            swimlane.setActorIdExpression(assignmentElement.attributeValue("actor-id"));
            swimlane.setPooledActorsExpression(assignmentElement.attributeValue("pooled-actors"));
           
          } else {
            Delegation assignmentDelegation = readAssignmentDelegation(assignmentElement);
            swimlane.setAssignmentDelegation(assignmentDelegation);
          }
        } else {
          Task startTask = taskMgmtDefinition.getStartTask();
          if ( (startTask==null)
               || (startTask.getSwimlane()!=swimlane)
             ) {
            addWarning("swimlane '"+swimlaneName+"' does not have an assignment");
          }
        }
        taskMgmtDefinition.addSwimlane(swimlane);
      }
    }
  }

  public void readNodes(Element element, NodeCollection nodeCollection) {
    Iterator nodeElementIter = element.elementIterator();
    while (nodeElementIter.hasNext()) {
      Element nodeElement = (Element) nodeElementIter.next();
      String nodeName = nodeElement.getName();
      // get the node type
      Class nodeType = NodeTypes.getNodeType(nodeName);
      if (nodeType!=null) {

        Node node = null;
        try {
          // create a new instance
          node = (Node) nodeType.newInstance();
        } catch (Exception e) {
          log.error("couldn't instantiate node '"+nodeName+"', of type '"+nodeType.getName()+"'", e);
        }
        
        node.setProcessDefinition(processDefinition);
        
        // check for duplicate start-states
        if ( (node instanceof StartState)
             && (processDefinition.getStartState()!=null)
           ) {
          addError("max one start-state allowed in a process");
          
        } else {
          // read the common node parts of the element
          readNode(nodeElement, node, nodeCollection);
        
          // if the node is parsable 
          // (meaning: if the node has special configuration to parse, other then the 
          //  common node data)
          node.read(nodeElement, this);
        }
      }
    }
  }

  public void readTasks(Element element, TaskNode taskNode) {
    List elements = element.elements("task");
    TaskMgmtDefinition tmd = (TaskMgmtDefinition) processDefinition.getDefinition(TaskMgmtDefinition.class); 
    if (elements.size()>0) {
      if (tmd==null) {
        tmd = new TaskMgmtDefinition();
      }
      processDefinition.addDefinition(tmd);
      
      Iterator iter = elements.iterator();
      while (iter.hasNext()) {
        Element taskElement = (Element) iter.next();
        readTask(taskElement, tmd, taskNode);
      }
    }
  }

  public Task readTask(Element taskElement, TaskMgmtDefinition taskMgmtDefinition, TaskNode taskNode) {
    Task task = new Task();
    task.setProcessDefinition(processDefinition);
    
    // get the task name
    String name = taskElement.attributeValue("name");
    if (name!=null) {
      task.setName(name);
      taskMgmtDefinition.addTask(task);
    } else if (taskNode!=null) {
      task.setName(taskNode.getName());
      taskMgmtDefinition.addTask(task);
    }
    
    // parse common subelements
    readTaskTimers(taskElement, task);
    readEvents(taskElement, task);
    readExceptionHandlers(taskElement, task);

    // description and duration
    task.setDescription(taskElement.attributeValue("description"));
    String duedateText = taskElement.attributeValue("duedate");
    if (duedateText==null) {
      duedateText = taskElement.attributeValue("dueDate");
    }
    task.setDueDate(duedateText);
    String priorityText = taskElement.attributeValue("priority");
    if (priorityText!=null) {
      task.setPriority(Task.parsePriority(priorityText));
    }
    
    // if this task is in the context of a taskNode, associate them
    if (taskNode!=null) {
      taskNode.addTask(task);
    }

    // blocking
    String blockingText = taskElement.attributeValue("blocking");
    if (blockingText!=null) {
      if ( ("true".equalsIgnoreCase(blockingText))
           || ("yes".equalsIgnoreCase(blockingText))
           || ("on".equalsIgnoreCase(blockingText)) ) {
        task.setBlocking(true);
      }
    }
    
    // signalling
    String signallingText = taskElement.attributeValue("signalling");
    if (signallingText!=null) {
      if ( ("false".equalsIgnoreCase(signallingText))
           || ("no".equalsIgnoreCase(signallingText))
           || ("off".equalsIgnoreCase(signallingText)) ) {
        task.setSignalling(false);
      }
    }
    
    // assignment
    String swimlaneName = taskElement.attributeValue("swimlane");
    Element assignmentElement = taskElement.element("assignment");

    // if there is a swimlane attribute specified
    if (swimlaneName!=null) {
      Swimlane swimlane = taskMgmtDefinition.getSwimlane(swimlaneName);
      if (swimlane==null) {
        addWarning("task references unknown swimlane '"+swimlaneName+"':"+taskElement.asXML());
      } else {
        task.setSwimlane(swimlane);
      }

    // else if there is a direct assignment specified
    } else if (assignmentElement!=null) {
      if ( (assignmentElement.attribute("actor-id")!=null)
           || (assignmentElement.attribute("pooled-actors")!=null)
         ) {
        task.setActorIdExpression(assignmentElement.attributeValue("actor-id"));
        task.setPooledActorsExpression(assignmentElement.attributeValue("pooled-actors"));
        
      } else {
        Delegation assignmentDelegation = readAssignmentDelegation(assignmentElement);
        task.setAssignmentDelegation(assignmentDelegation);
      }

    // if no assignment or swimlane is specified
    } else {
      // the user has to manage assignment manually, so we better warn him/her.
      addWarning("warning: no swimlane or assignment specified for task '"+taskElement.asXML()+"'");
    }
    
    // task controller
    Element taskControllerElement = taskElement.element("controller");
    if (taskControllerElement!=null) {
      task.setTaskController(readTaskController(taskControllerElement));
    }
    
    return task;
  }

  protected Delegation readAssignmentDelegation(Element assignmentElement) {
    Delegation assignmentDelegation = new Delegation();
    String expression = assignmentElement.attributeValue("expression");
    String actorId = assignmentElement.attributeValue("actor-id");
    String pooledActors = assignmentElement.attributeValue("pooled-actors");
    
    if (expression!=null){
        assignmentDelegation.setProcessDefinition(processDefinition);

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -