📄 jpdlxmlreader.java
字号:
/*
* 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 + -