/** * 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.guvnor.server.builder; import java.util.ArrayList; import java.util.Collection; import java.util.List; import org.drools.definition.process.Connection; import org.drools.definition.process.Node; import org.drools.guvnor.client.rpc.RuleFlowContentModel; import org.drools.guvnor.client.rulefloweditor.ElementContainerTransferNode; import org.drools.guvnor.client.rulefloweditor.HumanTaskTransferNode; import org.drools.guvnor.client.rulefloweditor.SplitNode; import org.drools.guvnor.client.rulefloweditor.SplitTransferNode; import org.drools.guvnor.client.rulefloweditor.TransferConnection; import org.drools.guvnor.client.rulefloweditor.TransferNode; import org.drools.guvnor.client.rulefloweditor.WorkItemTransferNode; import org.drools.process.core.Work; import org.jbpm.ruleflow.core.RuleFlowProcess; import org.jbpm.workflow.core.Constraint; import org.jbpm.workflow.core.impl.ConnectionRef; import org.jbpm.workflow.core.node.ActionNode; import org.jbpm.workflow.core.node.CompositeNode; import org.jbpm.workflow.core.node.EndNode; import org.jbpm.workflow.core.node.EventNode; import org.jbpm.workflow.core.node.FaultNode; import org.jbpm.workflow.core.node.ForEachNode; import org.jbpm.workflow.core.node.HumanTaskNode; import org.jbpm.workflow.core.node.Join; import org.jbpm.workflow.core.node.MilestoneNode; import org.jbpm.workflow.core.node.RuleSetNode; import org.jbpm.workflow.core.node.Split; import org.jbpm.workflow.core.node.StartNode; import org.jbpm.workflow.core.node.SubProcessNode; import org.jbpm.workflow.core.node.TimerNode; import org.jbpm.workflow.core.node.WorkItemNode; public class RuleFlowContentModelBuilder { public static RuleFlowContentModel createModel(RuleFlowProcess process) { RuleFlowContentModel model = new RuleFlowContentModel(); Collection<TransferNode> transferNodes = createNodesAndConnections( process.getNodes(), model ); model.getNodes().addAll( transferNodes ); return model; } /** * Creates transfer nodes from RuleFlowProcess nodes. * * @param nodes from the rule flow XML. * @param model RuleFlowContentModel that contains the transfer nodes for client side. */ private static List<TransferNode> createNodesAndConnections(Node[] nodes, RuleFlowContentModel model) { List<TransferNode> transferNodes = new ArrayList<TransferNode>(); for ( int i = 0; i < nodes.length; i++ ) { Node node = nodes[i]; TransferNode.Type type = getType( node ); TransferNode tn = null; if ( type == TransferNode.Type.WORK_ITEM ) { tn = createWorkItemTransfernode( (WorkItemNode) node ); } else if ( type == TransferNode.Type.HUMANTASK ) { tn = createHumanTaskTransferNode( (HumanTaskNode) node ); } else if ( type == TransferNode.Type.SPLIT ) { tn = createSplitNode( (Split) node ); } else if ( type == TransferNode.Type.FOR_EACH ) { tn = createRuleFlowContentModelTransferNode( ((ForEachNode) node).getNodes() ); } else if ( type == TransferNode.Type.COMPOSITE ) { tn = createRuleFlowContentModelTransferNode( ((CompositeNode) node).getNodes() ); } else { tn = new TransferNode(); } /* * Creates connections for from and to this node. */ createConnections( model, node ); tn.setId( node.getId() ); //Guard needed to Migrate v4 ruleflows to v5 Integer x = (Integer) node.getMetaData( "x" ); if ( x != null ) { tn.setX( x ); } // Guard needed to Migrate v4 ruleflows to v5 Integer y = (Integer) node.getMetaData( "y" ); if ( y != null ) { tn.setY( y ); } Integer height = (Integer) node.getMetaData( "height" ); if ( height != null ) { tn.setHeight( height ); } Integer width = (Integer) node.getMetaData( "width" ); if ( width != null ) { tn.setWidth( width ); } tn.setName( node.getName() ); tn.setType( type ); transferNodes.add( tn ); } return transferNodes; } private static ElementContainerTransferNode createRuleFlowContentModelTransferNode(Node[] nodes) { ElementContainerTransferNode fetn = new ElementContainerTransferNode(); RuleFlowContentModel model = new RuleFlowContentModel(); List<TransferNode> transferNodes = createNodesAndConnections( nodes, model ); model.setNodes( transferNodes ); fetn.setContentModel( model ); return fetn; } /** * Checks this node for out and in going connections and creates a transfer object from them. * * @param model * @param node */ private static void createConnections(RuleFlowContentModel model, Node node) { for ( List<Connection> inConnections : node.getIncomingConnections().values() ) { for ( Connection connection : inConnections ) { // if ( !"DROOLS_DEFAULT".equals( connection.getFromType() ) && !"DROOLS_DEFAULT".equals( connection.getToType() ) ) { createConnection( model, connection ); // } } } for ( List<Connection> outConnections : node.getOutgoingConnections().values() ) { for ( Connection connection : outConnections ) { // if ( !"DROOLS_DEFAULT".equals( connection.getFromType() ) && !"DROOLS_DEFAULT".equals( connection.getToType() ) ) { createConnection( model, connection ); // } } } } /** * Creates a single connection to be transferred. * * @param model * @param connection */ private static void createConnection(RuleFlowContentModel model, Connection connection) { TransferConnection tc = new TransferConnection(); tc.setFromId( connection.getFrom().getId() ); tc.setToId( connection.getTo().getId() ); model.getConnections().add( tc ); } private static TransferNode createHumanTaskTransferNode(HumanTaskNode node) { HumanTaskTransferNode httn = new HumanTaskTransferNode(); Work work = node.getWork(); if ( work != null ) { for ( String key : work.getParameters().keySet() ) { Object o = work.getParameters().get( key ); String value; if ( o == null ) { value = ""; } else { value = o.toString(); } httn.getParameters().put( key, value ); } } return httn; } private static SplitTransferNode createSplitNode(Split s) { SplitTransferNode sn = new SplitTransferNode(); sn.setSplitType( SplitTransferNode.Type.getType( s.getType() ) ); for ( ConnectionRef connection : s.getConstraints().keySet() ) { SplitNode.ConnectionRef ref = new SplitNode.ConnectionRef(); ref.setNodeId( connection.getNodeId() ); ref.setToType( connection.getToType() ); SplitNode.Constraint constraint = getConstraint( s.getConstraints().get( connection ) ); sn.getConstraints().put( ref, constraint ); } return sn; } private static WorkItemTransferNode createWorkItemTransfernode(WorkItemNode node) { WorkItemTransferNode tn = new WorkItemTransferNode(); Work work = node.getWork(); if ( work != null ) { tn.setWorkName( work.getName() ); for ( String key : work.getParameters().keySet() ) { Object o = work.getParameters().get( key ); String value; if ( o == null ) { value = ""; } else { value = o.toString(); } tn.getParameters().put( key, value ); } } return tn; } private static org.drools.guvnor.client.rulefloweditor.SplitNode.Constraint getConstraint(Constraint constraint) { SplitNode.Constraint c = new SplitNode.Constraint(); c.setConstraint( constraint.getConstraint() ); c.setDialect( constraint.getDialect() ); c.setName( constraint.getName() ); c.setPriority( constraint.getPriority() ); c.setType( constraint.getType() ); return c; } private static TransferNode.Type getType(Node node) { if ( node instanceof StartNode ) { return TransferNode.Type.START; } else if ( node instanceof EndNode ) { return TransferNode.Type.END; } else if ( node instanceof ActionNode ) { return TransferNode.Type.ACTION_NODE; } else if ( node instanceof RuleSetNode ) { return TransferNode.Type.RULESET; } else if ( node instanceof SubProcessNode ) { return TransferNode.Type.SUB_PROCESS; } else if ( node instanceof ForEachNode ) { return TransferNode.Type.FOR_EACH; } else if ( node instanceof CompositeNode ) { return TransferNode.Type.COMPOSITE; } else if ( node instanceof Join ) { return TransferNode.Type.JOIN; } else if ( node instanceof Split ) { return TransferNode.Type.SPLIT; } else if ( node instanceof MilestoneNode ) { return TransferNode.Type.MILESTONE; } else if ( node instanceof TimerNode ) { return TransferNode.Type.TIMER; } else if ( node instanceof HumanTaskNode ) { return TransferNode.Type.HUMANTASK; } else if ( node instanceof WorkItemNode ) { return TransferNode.Type.WORK_ITEM; } else if ( node instanceof FaultNode ) { return TransferNode.Type.FAULT; } else if ( node instanceof EventNode ) { return TransferNode.Type.EVENT; } throw new IllegalArgumentException( "Unkown node type " + node ); } }