/** * Copyright 2007-2010 非也 * All rights reserved. * * This library is free software; you can redistribute it and/or modify it under the * terms of the GNU Lesser General Public License v3 as published by the Free Software * Foundation. * * This program 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 General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License along * with this library; if not, see http://www.gnu.org/licenses/lgpl.html. * */ package org.fireflow.pdl.fpdl.test.service.call; import java.util.List; import javax.xml.namespace.QName; import org.fireflow.FireWorkflowJunitEnviroment; import org.fireflow.client.WorkflowQuery; import org.fireflow.client.WorkflowSession; import org.fireflow.client.WorkflowSessionFactory; import org.fireflow.client.WorkflowStatement; import org.fireflow.client.query.Restrictions; import org.fireflow.engine.entity.runtime.ProcessInstance; import org.fireflow.engine.entity.runtime.Variable; import org.fireflow.engine.entity.runtime.VariableProperty; import org.fireflow.engine.exception.InvalidOperationException; import org.fireflow.engine.exception.WorkflowProcessNotFoundException; import org.fireflow.engine.modules.ousystem.impl.FireWorkflowSystem; import org.fireflow.engine.modules.script.ScriptContextVariableNames; import org.fireflow.model.InvalidModelException; import org.fireflow.model.binding.impl.AssignmentImpl; import org.fireflow.model.binding.impl.ServiceBindingImpl; import org.fireflow.model.data.impl.ExpressionImpl; import org.fireflow.model.data.impl.InputImpl; import org.fireflow.model.data.impl.OutputImpl; import org.fireflow.model.data.impl.PropertyImpl; import org.fireflow.model.misc.Duration; import org.fireflow.model.servicedef.impl.CommonInterfaceDef; import org.fireflow.model.servicedef.impl.OperationDefImpl; import org.fireflow.pdl.fpdl.misc.FpdlConstants; import org.fireflow.pdl.fpdl.process.SubProcess; import org.fireflow.pdl.fpdl.process.WorkflowProcess; import org.fireflow.pdl.fpdl.process.impl.ActivityImpl; import org.fireflow.pdl.fpdl.process.impl.EndNodeImpl; import org.fireflow.pdl.fpdl.process.impl.StartNodeImpl; import org.fireflow.pdl.fpdl.process.impl.SubProcessImpl; import org.fireflow.pdl.fpdl.process.impl.TransitionImpl; import org.fireflow.pdl.fpdl.process.impl.WorkflowProcessImpl; import org.fireflow.service.call.CallServiceDef; import org.firesoa.common.schema.NameSpaces; import org.junit.Assert; import org.junit.Test; import org.springframework.transaction.TransactionStatus; import org.springframework.transaction.support.TransactionCallback; /** * 调用同一WorkflowProcess中的subflow * @author 非也 nychen2000@163.com * Fire Workflow 官方网站:www.firesoa.com 或者 www.fireflow.org * */ public class CallSubflowTest1 extends FireWorkflowJunitEnviroment{ protected static final String processName = "TheCallSubflowProcess"; protected static final String processDisplayName = "调用本流程内部的subflow"; protected static final String description = "调用本流程内部的subflow"; protected static final String bizId = "biz_123"; @Test public void testStartProcess(){ final WorkflowSession session = WorkflowSessionFactory.createWorkflowSession(fireflowRuntimeContext,FireWorkflowSystem.getInstance()); final WorkflowStatement stmt = session.createWorkflowStatement(FpdlConstants.PROCESS_TYPE_FPDL20); transactionTemplate.execute(new TransactionCallback(){ public Object doInTransaction(TransactionStatus arg0) { //构建流程定义 WorkflowProcess process = getWorkflowProcess(); //启动流程 try { ProcessInstance processInstance = stmt.startProcess(process, bizId, null); if (processInstance!=null){ processInstanceId = processInstance.getId(); } } catch (InvalidModelException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (WorkflowProcessNotFoundException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (InvalidOperationException e) { // TODO Auto-generated catch block e.printStackTrace(); } return null; } }); assertResult(session); } public void assertResult(WorkflowSession session) { super.assertResult(session); //主流程变量 WorkflowQuery<Variable> varQuery = session.createWorkflowQuery(Variable.class); varQuery.add(Restrictions.eq(VariableProperty.PROCESS_ELEMENT_ID, processName+WorkflowProcess.ID_SEPARATOR+WorkflowProcess.MAIN_PROCESS_NAME)) .add(Restrictions.eq(VariableProperty.NAME, "response1")); Variable var = varQuery.unique(); Assert.assertNotNull(var); Assert.assertEquals("It is OK", var.getPayload()); varQuery.reset(); varQuery.add(Restrictions.eq(VariableProperty.PROCESS_ELEMENT_ID, processName+WorkflowProcess.ID_SEPARATOR+WorkflowProcess.MAIN_PROCESS_NAME)) .add(Restrictions.eq(VariableProperty.NAME, "response2")); var = varQuery.unique(); Assert.assertNotNull(var); Assert.assertEquals(10, var.getPayload()); //子流程变量 varQuery.reset(); varQuery.add(Restrictions.eq(VariableProperty.PROCESS_ELEMENT_ID, processName+WorkflowProcess.ID_SEPARATOR+"subflow2")) .add(Restrictions.eq(VariableProperty.NAME, "id")); var = varQuery.unique(); Assert.assertNotNull(var); Assert.assertEquals(bizId, var.getPayload()); varQuery.reset(); varQuery.add(Restrictions.eq(VariableProperty.PROCESS_ELEMENT_ID, processName+WorkflowProcess.ID_SEPARATOR+"subflow2")) .add(Restrictions.eq(VariableProperty.NAME, "result")); var = varQuery.unique(); Assert.assertNotNull(var); Assert.assertEquals("This is the result!", var.getPayload()); } /* * * 主流程:Start-->Activity1(call subflow)-->End * * 子流程: Start-->Activity2-->End * * @see org.fireflow.FireWorkflowJunitEnviroment#createWorkflowProcess() */ @Override public WorkflowProcess createWorkflowProcess() { WorkflowProcessImpl process = new WorkflowProcessImpl(processName,processDisplayName); process.setDescription(description); //一、创建主流程 SubProcess mainflow = process.getMainSubProcess(); PropertyImpl property = new PropertyImpl(mainflow,"id");//流程变量x property.setDataType(new QName(NameSpaces.JAVA.getUri(),"java.lang.String")); property.setInitialValueAsString(bizId); mainflow.getProperties().add(property); property = new PropertyImpl(mainflow,"response1");//流程变量x property.setDataType(new QName(NameSpaces.JAVA.getUri(),"java.lang.String")); property.setInitialValueAsString("OK"); mainflow.getProperties().add(property); property = new PropertyImpl(mainflow,"response2");//流程变量x property.setDataType(new QName(NameSpaces.JAVA.getUri(),"java.lang.Integer")); property.setInitialValueAsString("1"); mainflow.getProperties().add(property); mainflow.setDuration(new Duration(5,Duration.MINUTE)); StartNodeImpl startNode = new StartNodeImpl(process.getMainSubProcess(),"Start"); ActivityImpl activity = new ActivityImpl(process.getMainSubProcess(),"Activity1"); activity.setDuration(new Duration(6,Duration.DAY)); property = new PropertyImpl(activity,"approveResult");//流程变量x property.setDataType(new QName(NameSpaces.JAVA.getUri(),"java.lang.String")); property.setInitialValueAsString("This is the result!"); activity.getProperties().add(property); EndNodeImpl endNode = new EndNodeImpl(process.getMainSubProcess(),"End"); mainflow.setEntry(startNode); mainflow.getStartNodes().add(startNode); mainflow.getActivities().add(activity); mainflow.getEndNodes().add(endNode); TransitionImpl transition1 = new TransitionImpl(process.getMainSubProcess(),"start2activity"); transition1.setFromNode(startNode); transition1.setToNode(activity); startNode.getLeavingTransitions().add(transition1); activity.getEnteringTransitions().add(transition1); TransitionImpl transition2 = new TransitionImpl(process.getMainSubProcess(),"activity2end"); transition2.setFromNode(activity); transition2.setToNode(endNode); activity.getLeavingTransitions().add(transition2); endNode.getEnteringTransitions().add(transition2); mainflow.getTransitions().add(transition1); mainflow.getTransitions().add(transition2); //二、创建子流程 SubProcess subflow2 = new SubProcessImpl(process,"subflow2"); process.addSubProcess(subflow2); PropertyImpl property4Subflow2 = new PropertyImpl(subflow2,"id");//流程变量x property4Subflow2.setDataType(new QName(NameSpaces.JAVA.getUri(),"java.lang.String")); property4Subflow2.setInitialValueAsString(""); subflow2.getProperties().add(property4Subflow2); property4Subflow2 = new PropertyImpl(subflow2,"result");//流程变量x property4Subflow2.setDataType(new QName(NameSpaces.JAVA.getUri(),"java.lang.String")); property4Subflow2.setInitialValueAsString("OK"); subflow2.getProperties().add(property4Subflow2); property4Subflow2 = new PropertyImpl(subflow2,"reply1");//流程变量x property4Subflow2.setDataType(new QName(NameSpaces.JAVA.getUri(),"java.lang.String")); property4Subflow2.setInitialValueAsString("It is OK"); subflow2.getProperties().add(property4Subflow2); property4Subflow2 = new PropertyImpl(subflow2,"reply2");//流程变量x property4Subflow2.setDataType(new QName(NameSpaces.JAVA.getUri(),"java.lang.Integer")); property4Subflow2.setInitialValueAsString("10"); subflow2.getProperties().add(property4Subflow2); subflow2.setDuration(new Duration(5,Duration.MINUTE)); StartNodeImpl startNode2 = new StartNodeImpl(subflow2,"Start2"); ActivityImpl activity2 = new ActivityImpl(subflow2,"Activity2"); activity2.setDuration(new Duration(6,Duration.DAY)); EndNodeImpl endNode2 = new EndNodeImpl(subflow2,"End2"); subflow2.setEntry(startNode2); subflow2.getStartNodes().add(startNode2); subflow2.getActivities().add(activity2); subflow2.getEndNodes().add(endNode2); TransitionImpl transition1_subflow2 = new TransitionImpl(subflow2,"start2activity"); transition1_subflow2.setFromNode(startNode2); transition1_subflow2.setToNode(activity2); startNode2.getLeavingTransitions().add(transition1_subflow2); activity2.getEnteringTransitions().add(transition1_subflow2); TransitionImpl transition2_subflow2 = new TransitionImpl(subflow2,"activity2end"); transition2_subflow2.setFromNode(activity2); transition2_subflow2.setToNode(endNode2); activity2.getLeavingTransitions().add(transition2_subflow2); endNode2.getEnteringTransitions().add(transition2_subflow2); subflow2.getTransitions().add(transition1_subflow2); subflow2.getTransitions().add(transition2_subflow2); //三、创建SubflowService 并绑定到activity1 CallServiceDef subflowService = new CallServiceDef(); subflowService.setName("call_subflow2"); subflowService.setTargetNamespaceUri("http://CallSubflowTest1"); subflowService.setProcessId(this.processName); subflowService.setSubProcessId(subflow2.getId()); CommonInterfaceDef commonInterface = new CommonInterfaceDef(); commonInterface.setName("call_subflow2_interface"); subflowService.setInterface(commonInterface); OperationDefImpl op = new OperationDefImpl(); op.setOperationName("callSubflow"); commonInterface.getOperations().add(op); InputImpl input = new InputImpl(); input.setName("id"); input.setDataType(new QName(NameSpaces.JAVA.getUri(),"java.lang.String")); op.getInputs().add(input); input = new InputImpl(); input.setName("result"); input.setDataType(new QName(NameSpaces.JAVA.getUri(),"java.lang.String")); op.getInputs().add(input); OutputImpl output = new OutputImpl(); output.setName("reply1"); output.setDataType(new QName(NameSpaces.JAVA.getUri(),"java.lang.String")); op.getOutputs().add(output); output = new OutputImpl(); output.setName("reply2"); output.setDataType(new QName(NameSpaces.JAVA.getUri(),"java.lang.Integer")); op.getOutputs().add(output); //绑定 ServiceBindingImpl svcBinding = new ServiceBindingImpl(); // svcBinding.setService(subflowService); svcBinding.setServiceId(subflowService.getId()); // svcBinding.setOperation(op); svcBinding.setOperationName(op.getOperationName()); //io输入映射 // processVars.id-->inputs.id AssignmentImpl assignment = new AssignmentImpl(); ExpressionImpl from = new ExpressionImpl(); from.setBody(ScriptContextVariableNames.PROCESS_VARIABLES+"/id"); from.setLanguage("XPATH"); from.getNamespaceMap().put("ns0",subflowService.getTargetNamespaceUri()); assignment.setFrom(from); ExpressionImpl to = new ExpressionImpl(); to.setBody(ScriptContextVariableNames.INPUTS+"/"+"id"); to.setLanguage("XPATH"); to.setName("id"); assignment.setTo(to); svcBinding.getInputAssignments().add(assignment); // activityVars.approveResult-->inputs.result assignment = new AssignmentImpl(); from = new ExpressionImpl(); from.setBody(ScriptContextVariableNames.ACTIVITY_VARIABLES+"/"+"approveResult"); from.setLanguage("XPATH"); from.getNamespaceMap().put("ns0",subflowService.getTargetNamespaceUri()); assignment.setFrom(from); to = new ExpressionImpl(); to.setBody(ScriptContextVariableNames.INPUTS+"/result"); to.setLanguage("XPATH"); to.setName("result"); assignment.setTo(to); svcBinding.getInputAssignments().add(assignment); //io输出映射 // output.reply1-->processVars.response1 assignment = new AssignmentImpl(); from = new ExpressionImpl(); from.setBody(ScriptContextVariableNames.OUTPUTS+"/reply1"); from.setLanguage("XPATH"); assignment.setFrom(from); to = new ExpressionImpl(); to.setBody(ScriptContextVariableNames.PROCESS_VARIABLES+"/response1"); to.setName("response1"); to.setLanguage("XPATH"); to.getNamespaceMap().put("ns0", subflowService.getTargetNamespaceUri()); assignment.setTo(to); svcBinding.getOutputAssignments().add(assignment); // output.reply2-->processVars.response2 assignment = new AssignmentImpl(); from = new ExpressionImpl(); from.setBody(ScriptContextVariableNames.OUTPUTS+"/reply2"); from.setLanguage("XPATH"); assignment.setFrom(from); to = new ExpressionImpl(); to.setBody(ScriptContextVariableNames.PROCESS_VARIABLES+"/response2"); to.setLanguage("XPATH"); to.setName("response2"); to.getNamespaceMap().put("ns0", subflowService.getTargetNamespaceUri()); assignment.setTo(to); svcBinding.getOutputAssignments().add(assignment); //设置到activity和workflowprocess process.addService(subflowService); activity.setServiceBinding(svcBinding); return process; } }