/** * Copyright 1996-2014 FoxBPM ORG. * * 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. * * @author kenshin */ package org.foxbpm.kernel; import java.util.ArrayList; import java.util.List; import java.util.Stack; import org.foxbpm.kernel.behavior.KernelFlowNodeBehavior; import org.foxbpm.kernel.behavior.KernelSequenceFlowBehavior; import org.foxbpm.kernel.event.KernelListener; import org.foxbpm.kernel.process.KernelProcessDefinition; import org.foxbpm.kernel.process.impl.KernelBaseElementImpl; import org.foxbpm.kernel.process.impl.KernelFlowElementsContainerImpl; import org.foxbpm.kernel.process.impl.KernelFlowNodeImpl; import org.foxbpm.kernel.process.impl.KernelProcessDefinitionImpl; import org.foxbpm.kernel.process.impl.KernelSequenceFlowImpl; public class ProcessDefinitionBuilder { protected KernelProcessDefinitionImpl processDefinition; protected Stack<KernelFlowElementsContainerImpl> containerStack = new Stack<KernelFlowElementsContainerImpl>(); protected KernelBaseElementImpl processElement = processDefinition; protected KernelSequenceFlowImpl sequenceFlow; protected List<Object[]> unresolvedSequenceFlows = new ArrayList<Object[]>(); public ProcessDefinitionBuilder() { this(null); } public ProcessDefinitionBuilder(String processDefinitionId) { processDefinition = createProcessDefinition(processDefinitionId); containerStack.push(processDefinition); } protected KernelProcessDefinitionImpl createProcessDefinition(String processDefinitionId) { return new KernelProcessDefinitionImpl(processDefinitionId); } public ProcessDefinitionBuilder createFlowNode(String id) { createFlowNode(id, null); return this; } public ProcessDefinitionBuilder createFlowNode(String id, String name) { KernelFlowNodeImpl flowNode = containerStack.peek().createFlowNode(id); flowNode.setName(name); containerStack.push(flowNode); processElement = flowNode; sequenceFlow = null; return this; } public ProcessDefinitionBuilder endFlowNode() { containerStack.pop(); processElement = containerStack.peek(); sequenceFlow = null; return this; } public ProcessDefinitionBuilder initial() { processDefinition.setInitial(getFlowNode()); return this; } public ProcessDefinitionBuilder startSequenceFlow(String destinationFlowNodeId) { return startSequenceFlow(destinationFlowNodeId, null); } public ProcessDefinitionBuilder startSequenceFlow(String targetFlowNodeId, String sequenceFlowId) { if (targetFlowNodeId == null) { throw new KernelException("线条目标节点为空!"); } KernelFlowNodeImpl flowNode = getFlowNode(); sequenceFlow = flowNode.createOutgoingSequenceFlow(sequenceFlowId); unresolvedSequenceFlows.add(new Object[]{sequenceFlow, targetFlowNodeId}); processElement = sequenceFlow; return this; } public ProcessDefinitionBuilder endSequenceFlow() { processElement = containerStack.peek(); sequenceFlow = null; return this; } public ProcessDefinitionBuilder sequenceFlow(String targetFlowNodeId) { return sequenceFlow(targetFlowNodeId, null); } public ProcessDefinitionBuilder sequenceFlow(String targetFlowNodeId, String sequenceFlowId) { return sequenceFlow(targetFlowNodeId, sequenceFlowId, null); } public ProcessDefinitionBuilder sequenceFlow(String targetFlowNodeId, String sequenceFlowId, String sequenceFlowName) { return sequenceFlow(targetFlowNodeId,sequenceFlowId,sequenceFlowName,null); } public ProcessDefinitionBuilder sequenceFlow(String targetFlowNodeId, String sequenceFlowId, String sequenceFlowName , KernelSequenceFlowBehavior sequenceFlowBehavior){ startSequenceFlow(targetFlowNodeId, sequenceFlowId); sequenceFlow.setName(sequenceFlowName); if(sequenceFlowBehavior != null){ sequenceFlow.setSequenceFlowBehavior(sequenceFlowBehavior); } endSequenceFlow(); return this; } public ProcessDefinitionBuilder behavior(KernelFlowNodeBehavior flowNodeBehaviour) { getFlowNode().setFlowNodeBehavior(flowNodeBehaviour); return this; } public ProcessDefinitionBuilder property(String name, Object value) { processElement.setProperty(name, value); return this; } public KernelProcessDefinition buildProcessDefinition() { KernelSequenceFlowImpl sequenceFlow = null; String targetFlowNodeName = null; KernelFlowNodeImpl destination = null; for (Object[] unresolvedSequenceFlow : unresolvedSequenceFlows) { sequenceFlow = (KernelSequenceFlowImpl) unresolvedSequenceFlow[0]; targetFlowNodeName = (String) unresolvedSequenceFlow[1]; destination = processDefinition.findFlowNode(targetFlowNodeName); if (destination == null) { throw new RuntimeException("target '" + targetFlowNodeName + "' not found. (referenced from sequenceFlow in '" + sequenceFlow.getSourceRef().getId() + "')"); } sequenceFlow.setTargetRef(destination); } return processDefinition; } public KernelFlowNodeImpl getFlowNode() { return (KernelFlowNodeImpl) containerStack.peek(); } public ProcessDefinitionBuilder scope() { getFlowNode().setScope(true); return this; } public ProcessDefinitionBuilder executionListener(KernelListener kernelListener) { if (sequenceFlow != null) { sequenceFlow.addKernelListener(kernelListener); } else { throw new KernelException("该事件只能用于线条对象。"); } return this; } public ProcessDefinitionBuilder executionListener(String eventName, KernelListener kernelListener) { if (sequenceFlow == null) { containerStack.peek().addKernelListener(eventName, kernelListener); } else { throw new KernelException("该事件只能作用于非线条元素。"); } return this; } public KernelProcessDefinitionImpl getProcessDefinition() { return processDefinition; } public KernelBaseElementImpl getProcessElement() { return processElement; } }