private static Map<Transition, String> TRANSITION_TARGETS = new HashMap<Transition, String>();
@Override
public ProcessDefinition parseXML(Document document) {
TRANSITION_TARGETS.clear();
ProcessDefinition definition = create(document.getDocumentElement(), null);
NodeList swimlanes = document.getElementsByTagName(SWIMLANE_NODE);
for (int i = 0; i < swimlanes.getLength(); i++) {
Node node = swimlanes.item(i);
create(node, definition);
}
NodeList startStates = document.getElementsByTagName(START_STATE_NODE);
if (startStates.getLength() == 1) {
Node node = startStates.item(0);
StartState startState = create(node, definition);
NodeList stateChilds = node.getChildNodes();
for (int j = 0; j < stateChilds.getLength(); j++) {
Node stateNodeChild = stateChilds.item(j);
if (TASK_NODE.equals(stateNodeChild.getNodeName())) {
String swimlaneName = getAttribute(stateNodeChild, SWIMLANE_NODE);
Swimlane swimlane = definition.getSwimlaneByName(swimlaneName);
startState.setSwimlane(swimlane);
}
}
}
NodeList actionNodeNodes = document.getElementsByTagName(ACTION_NODE_NODE);
for (int i = 0; i < actionNodeNodes.getLength(); i++) {
Node node = actionNodeNodes.item(i);
ActionNode actionNode = create(node, definition);
NodeList aaa = node.getChildNodes();
for (int k = 0; k < aaa.getLength(); k++) {
Node a = aaa.item(k);
if (EVENT_NODE.equals(a.getNodeName())) {
String eventType = getAttribute(a, "type");
NodeList actionNodes = a.getChildNodes();
for (int l = 0; l < actionNodes.getLength(); l++) {
Node aa = actionNodes.item(l);
if (ACTION_NODE.equals(aa.getNodeName())) {
parseAction(aa, actionNode, eventType);
}
}
}
}
}
NodeList states = document.getElementsByTagName(TASK_STATE_NODE);
for (int i = 0; i < states.getLength(); i++) {
Node node = states.item(i);
NodeList nodeList = node.getChildNodes();
int transitionsCount = 0;
boolean hasTimeOutTransition = false;
for (int j = 0; j < nodeList.getLength(); j++) {
Node childNode = nodeList.item(j);
if (TRANSITION_NODE.equals(childNode.getNodeName())) {
String transitionName = getAttribute(childNode, NAME_ATTR);
if (PluginConstants.TIMER_TRANSITION_NAME.equals(transitionName)) {
hasTimeOutTransition = true;
}
transitionsCount++;
}
}
GraphElement state;
if (transitionsCount == 1 && hasTimeOutTransition) {
state = create(node, definition, "waitState");
} else {
state = create(node, definition);
}
// TODO use SAX parser instead
NodeList stateChilds = node.getChildNodes();
for (int j = 0; j < stateChilds.getLength(); j++) {
Node stateNodeChild = stateChilds.item(j);
if (TASK_NODE.equals(stateNodeChild.getNodeName())) {
String swimlaneName = getAttribute(stateNodeChild, SWIMLANE_NODE);
if (swimlaneName != null && state instanceof SwimlanedNode) {
Swimlane swimlane = definition.getSwimlaneByName(swimlaneName);
((SwimlanedNode) state).setSwimlane(swimlane);
String reassign = getAttribute(stateNodeChild, REASSIGN_ATTR);
if (reassign != null) {
boolean forceReassign = Boolean.parseBoolean(reassign);
((State) state).setReassignmentEnabled(forceReassign);
}
}
NodeList aaa = stateNodeChild.getChildNodes();
for (int k = 0; k < aaa.getLength(); k++) {
Node a = aaa.item(k);
if (EVENT_NODE.equals(a.getNodeName())) {
String eventType = getAttribute(a, "type");
NodeList actionNodes = a.getChildNodes();
for (int l = 0; l < actionNodes.getLength(); l++) {
Node aa = actionNodes.item(l);
if (ACTION_NODE.equals(aa.getNodeName())) {
parseAction(aa, state, eventType);
}
}
}
}
}
if (TIMER_NODE.equals(stateNodeChild.getNodeName())) {
String dueDate = getAttribute(stateNodeChild, DUEDATE_ATTR);
((ITimed) state).setDueDate(dueDate);
NodeList actionNodes = stateNodeChild.getChildNodes();
for (int l = 0; l < actionNodes.getLength(); l++) {
Node aa = actionNodes.item(l);
if (ACTION_NODE.equals(aa.getNodeName())) {
TimerAction timerAction = new TimerAction(null);
timerAction.setDelegationClassName(getAttribute(aa, CLASS_ATTR));
timerAction.setDelegationConfiguration(getTextContent(aa));
timerAction.setRepeat(getAttribute(stateNodeChild, REPEAT_ATTR));
((ITimed) state).setTimerAction(timerAction);
}
}
}
}
}
NodeList mailNodes = document.getElementsByTagName(MAIL_NODE);
for (int i = 0; i < mailNodes.getLength(); i++) {
Node node = mailNodes.item(i);
MailNode mailNode = create(node, definition);
mailNode.setRecipient(getAttribute(node, "to"));
NodeList mailNodeChilds = node.getChildNodes();
for (int j = 0; j < mailNodeChilds.getLength(); j++) {
Node mailNodeChild = mailNodeChilds.item(i);
if ("body".equals(mailNodeChild.getNodeName())) {
mailNode.setMailBody(getTextContent(mailNodeChild));
}
if ("subject".equals(mailNodeChild.getNodeName())) {
mailNode.setSubject(getTextContent(mailNodeChild));
}
}
}
NodeList forks = document.getElementsByTagName(FORK_NODE);
for (int i = 0; i < forks.getLength(); i++) {
Node node = forks.item(i);
create(node, definition);
}
NodeList joins = document.getElementsByTagName(JOIN_NODE);
for (int i = 0; i < joins.getLength(); i++) {
Node node = joins.item(i);
create(node, definition);
}
NodeList decisions = document.getElementsByTagName(DECISION_NODE);
for (int i = 0; i < decisions.getLength(); i++) {
Node node = decisions.item(i);
create(node, definition);
}
NodeList processStates = document.getElementsByTagName(PROCESS_STATE_NODE);
for (int i = 0; i < processStates.getLength(); i++) {
Node node = processStates.item(i);
Subprocess subprocess = create(node, definition);
List<VariableMapping> variablesList = new ArrayList<VariableMapping>();
NodeList nodeList = node.getChildNodes();
for (int j = 0; j < nodeList.getLength(); j++) {
Node childNode = nodeList.item(j);
if (SUB_PROCESS_NODE.equals(childNode.getNodeName())) {
subprocess.setSubProcessName(getAttribute(childNode, NAME_ATTR));
}
if (VARIABLE_NODE.equals(childNode.getNodeName())) {
VariableMapping variable = new VariableMapping();
variable.setProcessVariable(getAttribute(childNode, NAME_ATTR));
variable.setSubprocessVariable(getAttribute(childNode, MAPPED_NAME_ATTR));
variable.setUsage(getAttribute(childNode, ACCESS_ATTR));
variablesList.add(variable);
}
}
subprocess.setVariablesList(variablesList);
}
NodeList multiInstanceStates = document.getElementsByTagName(MULTI_INSTANCE_STATE_NODE);
for (int i = 0; i < multiInstanceStates.getLength(); i++) {
Node node = multiInstanceStates.item(i);
MultiInstance multiInstance = create(node, definition);
List<VariableMapping> variablesList = new ArrayList<VariableMapping>();
NodeList nodeList = node.getChildNodes();
for (int j = 0; j < nodeList.getLength(); j++) {
Node childNode = nodeList.item(j);
if (SUB_PROCESS_NODE.equals(childNode.getNodeName())) {
multiInstance.setSubProcessName(getAttribute(childNode, NAME_ATTR));
}
if (VARIABLE_NODE.equals(childNode.getNodeName())) {
VariableMapping variable = new VariableMapping();
variable.setProcessVariable(getAttribute(childNode, NAME_ATTR));
variable.setSubprocessVariable(getAttribute(childNode, MAPPED_NAME_ATTR));
variable.setUsage(getAttribute(childNode, ACCESS_ATTR));
variablesList.add(variable);
}
}
multiInstance.setVariablesList(variablesList);
}
NodeList endStates = document.getElementsByTagName(END_STATE_NODE);
for (int i = 0; i < endStates.getLength(); i++) {
Node node = endStates.item(i);
create(node, definition);
}
List<Transition> tmpTransitions = new ArrayList<Transition>(TRANSITION_TARGETS.keySet());
for (Transition transition : tmpTransitions) {
String targetName = TRANSITION_TARGETS.remove(transition);
org.jbpm.ui.common.model.Node target = definition.getNodeByNameNotNull(targetName);
transition.setTarget(target);
}
return definition;
}