All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.drools.bpmn2.legacy.beta1.XmlBPMNProcessDumper Maven / Gradle / Ivy

There is a newer version: 5.1.1
Show newest version
/**
 * 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.drools.bpmn2.legacy.beta1;

import java.util.ArrayList;
import java.util.Collection;
import java.util.List;

import org.drools.bpmn2.xpath.XPathDialect;
import org.drools.compiler.xml.XmlDumper;
import org.drools.definition.process.Connection;
import org.drools.definition.process.Node;
import org.drools.definition.process.NodeContainer;
import org.drools.definition.process.WorkflowProcess;
import org.drools.process.core.ContextContainer;
import org.drools.process.core.Work;
import org.drools.process.core.context.swimlane.Swimlane;
import org.drools.process.core.context.swimlane.SwimlaneContext;
import org.drools.process.core.context.variable.Variable;
import org.drools.process.core.context.variable.VariableScope;
import org.drools.process.core.datatype.impl.type.ObjectDataType;
import org.drools.process.core.event.EventTypeFilter;
import org.drools.rule.builder.dialect.java.JavaDialect;
import org.drools.workflow.core.Constraint;
import org.drools.workflow.core.node.ActionNode;
import org.drools.workflow.core.node.CompositeNode;
import org.drools.workflow.core.node.EndNode;
import org.drools.workflow.core.node.EventNode;
import org.drools.workflow.core.node.EventTrigger;
import org.drools.workflow.core.node.FaultNode;
import org.drools.workflow.core.node.ForEachNode;
import org.drools.workflow.core.node.HumanTaskNode;
import org.drools.workflow.core.node.Join;
import org.drools.workflow.core.node.RuleSetNode;
import org.drools.workflow.core.node.Split;
import org.drools.workflow.core.node.StartNode;
import org.drools.workflow.core.node.SubProcessNode;
import org.drools.workflow.core.node.TimerNode;
import org.drools.workflow.core.node.Trigger;
import org.drools.workflow.core.node.WorkItemNode;
import org.drools.xml.Handler;
import org.drools.xml.SemanticModule;

public class XmlBPMNProcessDumper {
	
	public static final String JAVA_LANGUAGE = "http://www.java.com/java";
	public static final String RULE_LANGUAGE = "http://www.jboss.org/drools/rule";
    public static final String XPATH_LANGUAGE = "http://www.w3.org/1999/XPath";
    
	public static XmlBPMNProcessDumper INSTANCE = new XmlBPMNProcessDumper();
	
    private final static String EOL = System.getProperty( "line.separator" );
    
    private SemanticModule semanticModule;
    
    private XmlBPMNProcessDumper() {
    	semanticModule = new BPMNSemanticModule();
    }
    
    public String dump(WorkflowProcess process) {
        return dump(process, true);
    }
    
    public String dump(WorkflowProcess process, boolean includeMeta) {
        StringBuilder xmlDump = new StringBuilder();
        visitProcess(process, xmlDump, includeMeta);
        return xmlDump.toString();
    }
    
    protected void visitProcess(WorkflowProcess process, StringBuilder xmlDump, boolean includeMeta) {
        String targetNamespace = (String) process.getMetaData("TargetNamespace");
        if (targetNamespace == null) {
        	targetNamespace = "http://www.jboss.org/drools";
        }
    	xmlDump.append(
    		" " + EOL +
            "" + EOL + EOL);

    	// item definitions
    	VariableScope variableScope = (VariableScope)
    		((org.drools.process.core.Process) process).getDefaultContext(VariableScope.VARIABLE_SCOPE);
    	visitVariableScope(variableScope, "_", xmlDump);
    	visitSubVariableScopes(process.getNodes(), xmlDump);
        
	    xmlDump.append(
    		"  " + EOL + EOL);

	    visitInterfaces(process, xmlDump);
	       
	    // the process itself
		xmlDump.append("  " + EOL + EOL);
        visitLanes(process, xmlDump);
        visitHeader(process, xmlDump, includeMeta);
        visitNodes(process, xmlDump, includeMeta);
        visitConnections(process.getNodes(), xmlDump, includeMeta);
        xmlDump.append("  " + EOL + EOL);
        
        if (includeMeta) {
        	xmlDump.append(
    			"  " + EOL +
    			"    " + EOL);
        	for (Node node: process.getNodes()) {
        		String nodeType = null;
                Integer x = (Integer) node.getMetaData("x");
                Integer y = (Integer) node.getMetaData("y");
                Integer width = (Integer) node.getMetaData("width");
                Integer height = (Integer) node.getMetaData("height");
        		if (node instanceof StartNode || node instanceof EndNode || node instanceof EventNode || node instanceof FaultNode) {
        			nodeType = "event";
        			int offsetX = (int) ((width - 30) / 2);
        			width = 30;
        	        x = x + offsetX;
        	        int offsetY = (int) ((height - 30) / 2);
        	        y = y + offsetY;
        	        height = 30;
        		} else if (node instanceof ActionNode || node instanceof RuleSetNode || node instanceof TimerNode) {
        			nodeType = "activity";
        		} else if (node instanceof Join || node instanceof Split) {
        			nodeType = "gateway";
        			int offsetX = (int) ((width - 40) / 2);
        			width = 40;
        	        x = x + offsetX;
        	        int offsetY = (int) ((height - 40) / 2);
        	        y = y + offsetY;
        	        height = 40;
        		} else if (node instanceof SubProcessNode) {
        			nodeType = "calledSubprocess";
        		} else if (node instanceof CompositeNode) {
        			nodeType = "subprocess";
        		} else if (node instanceof WorkItemNode) {
        			nodeType = "activity";
        		}
    			xmlDump.append(
					"      " + EOL);
        	}
        	xmlDump.append(
    			"    " + EOL);
        	visitConnectionsDi(process.getNodes(), xmlDump);
        	xmlDump.append(
        		"  " + EOL + EOL);
        }
        
        xmlDump.append("");
    }
    
    private void visitVariableScope(VariableScope variableScope, String prefix, StringBuilder xmlDump) {
        if (variableScope != null && !variableScope.getVariables().isEmpty()) {
            for (Variable variable: variableScope.getVariables()) {
                xmlDump.append(
                    "  " + EOL);
            }
            xmlDump.append(EOL);
        }
    }
    
    private void visitSubVariableScopes(Node[] nodes, StringBuilder xmlDump) {
        for (Node node: nodes) {
            if (node instanceof ContextContainer) {
                VariableScope variableScope = (VariableScope) 
                    ((ContextContainer) node).getDefaultContext(VariableScope.VARIABLE_SCOPE);
                if (variableScope != null) {
                    visitVariableScope(variableScope, XmlBPMNProcessDumper.getUniqueNodeId(node) + "-", xmlDump);
                }
            }
            if (node instanceof NodeContainer) {
                visitSubVariableScopes(((NodeContainer) node).getNodes(), xmlDump);
            }
        }
    }
    
    private void visitLanes(WorkflowProcess process, StringBuilder xmlDump) {
        // lanes
        Collection swimlanes = ((SwimlaneContext)
            ((org.drools.workflow.core.WorkflowProcess) process)
                .getDefaultContext(SwimlaneContext.SWIMLANE_SCOPE)).getSwimlanes();
        if (!swimlanes.isEmpty()) {
            xmlDump.append("    " + EOL);
            for (Swimlane swimlane: swimlanes) {
                xmlDump.append("      " + EOL);
                visitLane(process, swimlane.getName(), xmlDump);
                xmlDump.append("      " + EOL);
            }
            xmlDump.append("    " + EOL);
        }
    }
    
    private void visitLane(NodeContainer container, String lane, StringBuilder xmlDump) {
        for (Node node: container.getNodes()) {
            if (node instanceof HumanTaskNode) {
                String swimlane = ((HumanTaskNode) node).getSwimlane();
                if (lane.equals(swimlane)) {
                    xmlDump.append("        " + XmlBPMNProcessDumper.getUniqueNodeId(node) + "" + EOL);
                }
            } else {
                String swimlane = (String) node.getMetaData("Lane");
                if (lane.equals(swimlane)) {
                    xmlDump.append("        " + XmlBPMNProcessDumper.getUniqueNodeId(node) + "" + EOL);
                }
            }
            if (node instanceof NodeContainer) {
                visitLane((NodeContainer) node, lane, xmlDump);
            }
        }
    }
    
    protected void visitHeader(WorkflowProcess process, StringBuilder xmlDump, boolean includeMeta) {
    	// TODO: imports, function imports
    	// TODO: globals
        // TODO: swimlanes
    	// TODO: exception handlers
        VariableScope variableScope = (VariableScope)
        	((org.drools.process.core.Process) process).getDefaultContext(VariableScope.VARIABLE_SCOPE);
        if (variableScope != null) {
            visitVariables(variableScope.getVariables(), xmlDump);
        }
    }
    
    public static void visitVariables(List variables, StringBuilder xmlDump) {
    	if (!variables.isEmpty()) {
            xmlDump.append("    " + EOL);
            for (Variable variable: variables) {
                if (variable.getMetaData("DataObject") == null) {
                    xmlDump.append("    " + EOL);
                }
            }
            for (Variable variable: variables) {
                if (variable.getMetaData("DataObject") != null) {
                    xmlDump.append("    " + EOL);
                }
            }
            xmlDump.append(EOL);
    	}
    }
    
    protected void visitInterfaces(WorkflowProcess process, StringBuilder xmlDump) {
        for (Node node: process.getNodes()) {
            if (node instanceof WorkItemNode) {
                Work work = ((WorkItemNode) node).getWork();
                if (work != null) {
                    if ("Service Task".equals(work.getName())) {
                        String interfaceName = (String) work.getParameter("Interface");
                        if (interfaceName == null) {
                            interfaceName = "";
                        }
                        String operationName = (String) work.getParameter("Operation");
                        if (operationName == null) {
                            operationName = "";
                        }
                        String parameterType = (String) work.getParameter("ParameterType");
                        if (parameterType == null) {
                            parameterType = "";
                        }
                        xmlDump.append(
                            "  " + EOL +
                            "  " + EOL +
                            "  " + EOL +
                            "    " + EOL + 
                            "      " + getUniqueNodeId(node) + "_InMessage" + EOL +
                            "    " + EOL +
                            "  " + EOL + EOL);
                    } else if ("Send Task".equals(work.getName())) {
                        String messageType = (String) work.getParameter("MessageType");
                        if (messageType == null) {
                            messageType = "";
                        }
                        xmlDump.append(
                            "  " + EOL +
                            "  " + EOL + EOL);
                    } else if ("Receive Task".equals(work.getName())) {
                        String messageType = (String) work.getParameter("MessageType");
                        if (messageType == null) {
                            messageType = "";
                        }
                        xmlDump.append(
                            "  " + EOL +
                            "  " + EOL + EOL);
                    }
                }
            } else if (node instanceof EndNode) {
                String messageType = (String) node.getMetaData("MessageType");
                if (messageType != null) {
                    xmlDump.append(
                        "  " + EOL +
                        "  " + EOL + EOL);
                }
            } else if (node instanceof ActionNode) {
                String messageType = (String) node.getMetaData("MessageType");
                if (messageType != null) {
                    xmlDump.append(
                        "  " + EOL +
                        "  " + EOL + EOL);
                }
            } else if (node instanceof EventNode) {
                String messageRef = ((EventTypeFilter) ((EventNode) node).getEventFilters().get(0)).getType();
                messageRef = messageRef.substring(8);
                String messageType = (String) node.getMetaData("MessageType");
                xmlDump.append(
                    "  " + EOL +
                    "  " + EOL + EOL);
            } else if (node instanceof StartNode) {
                StartNode startNode = (StartNode) node;
                if (startNode.getTriggers() != null && !startNode.getTriggers().isEmpty()) {
                    Trigger trigger = startNode.getTriggers().get(0);
                    if (trigger instanceof EventTrigger) {
                        String eventType = ((EventTypeFilter) ((EventTrigger) trigger).getEventFilters().get(0)).getType();
                        if (eventType.startsWith("Message-")) {
                            eventType = eventType.substring(8);
                            String messageType = (String) node.getMetaData("MessageType");
                            xmlDump.append(
                                "  " + EOL +
                                "  " + EOL + EOL);
                        }
                    }
                }
            } else if (node instanceof ForEachNode) {
            	ForEachNode forEachNode = (ForEachNode) node;
                xmlDump.append(
                    "  " + EOL + EOL);
            } 
        }
    }
    
    private void visitNodes(WorkflowProcess process, StringBuilder xmlDump, boolean includeMeta) {
    	xmlDump.append("    " + EOL);
        for (Node node: process.getNodes()) {
            visitNode(node, xmlDump, includeMeta);
        }
        xmlDump.append(EOL);
    }
    
    public void visitNode(Node node, StringBuilder xmlDump, boolean includeMeta) {
     	Handler handler = semanticModule.getHandlerByClass(node.getClass());
        if (handler != null) {
        	((AbstractNodeHandler) handler).writeNode((org.drools.workflow.core.Node) node, xmlDump, includeMeta);
        } else {
        	throw new IllegalArgumentException(
                "Unknown node type: " + node);
        }
    }
    
    private void visitConnections(Node[] nodes, StringBuilder xmlDump, boolean includeMeta) {
    	xmlDump.append("    " + EOL);
        List connections = new ArrayList();
        for (Node node: nodes) {
            for (List connectionList: node.getIncomingConnections().values()) {
                connections.addAll(connectionList);
            }
        }
        for (Connection connection: connections) {
            visitConnection(connection, xmlDump, includeMeta);
        }
        xmlDump.append(EOL);
    }
    
    public void visitConnection(Connection connection, StringBuilder xmlDump, boolean includeMeta) {
        xmlDump.append("    " + EOL +
    					"      ");
        		} else {
                    if (constraint.getName() != null && constraint.getName().trim().length() > 0) {
            			xmlDump.append("name=\"" + XmlDumper.replaceIllegalChars(constraint.getName()) + "\" ");
            		}
            		xmlDump.append(">" + EOL +
    				"      " + XmlDumper.replaceIllegalChars(constraintString) + "");
        		}
        		xmlDump.append(EOL
    		        + "    " + EOL);
        	} else {
            	xmlDump.append("/>" + EOL);
            }
        } else {
        	xmlDump.append("/>" + EOL);
        }
    }
    
    public static String getUniqueNodeId(Node node) {
    	String result = (String) node.getMetaData("UniqueId");
    	if (result != null) {
    		return result;
    	}
    	result = node.getId() + "";
    	NodeContainer nodeContainer = node.getNodeContainer();
    	while (nodeContainer instanceof CompositeNode) {
    		CompositeNode composite = (CompositeNode) nodeContainer;
    		result = composite.getId() + "-" + result;
    		nodeContainer = composite.getNodeContainer();
    	}
    	return "_" + result;
    }
    
    private void visitConnectionsDi(Node[] nodes, StringBuilder xmlDump) {
        List connections = new ArrayList();
        for (Node node: nodes) {
            for (List connectionList: node.getIncomingConnections().values()) {
                connections.addAll(connectionList);
            }
            if (node instanceof CompositeNode) {
            	visitConnectionsDi(((CompositeNode) node).getNodes(), xmlDump);
            }
        }
        for (Connection connection: connections) {
            String bendpoints = (String) connection.getMetaData("bendpoints");
            xmlDump.append(
        		"    " + EOL);
            } else {
            	xmlDump.append(">" + EOL);
            	bendpoints = bendpoints.substring(1, bendpoints.length() - 1);
            	String[] points = bendpoints.split(";");
            	for (String point: points) {
            		String[] coords = point.split(",");
            		if (coords.length == 2) {
            			xmlDump.append(
        					"      " + EOL);
            		}
            	}
            	xmlDump.append(
            		"    " + EOL);
            }
        }
    }
    
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy