/** * 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.client.impl; import java.io.BufferedInputStream; import java.io.IOException; import java.io.InputStream; import java.util.Iterator; import java.util.Map; import java.util.Map.Entry; import java.util.Properties; import org.fireflow.client.WorkflowStatement; import org.fireflow.engine.entity.repository.ProcessDescriptor; import org.fireflow.engine.entity.repository.ProcessKey; import org.fireflow.engine.entity.repository.impl.ProcessDescriptorImpl; import org.fireflow.engine.entity.runtime.ActivityInstance; import org.fireflow.engine.entity.runtime.ProcessInstance; import org.fireflow.engine.entity.runtime.Scope; import org.fireflow.engine.entity.runtime.WorkItem; import org.fireflow.engine.exception.EngineException; import org.fireflow.engine.exception.InvalidOperationException; import org.fireflow.engine.exception.WorkflowProcessNotFoundException; import org.fireflow.engine.invocation.AssignmentHandler; import org.fireflow.engine.invocation.impl.DynamicAssignmentHandler; import org.fireflow.engine.invocation.impl.ReassignmentHandler; import org.fireflow.model.InvalidModelException; import org.fireflow.server.WorkflowEngineService; import org.fireflow.server.support.MapConvertor; import org.fireflow.server.support.ObjectWrapper; import org.fireflow.server.support.PropertiesConvertor; import org.fireflow.server.support.ScopeBean; import org.firesoa.common.util.JavaDataTypeConvertor; import org.firesoa.common.util.Utils; /** * * @author 非也 nychen2000@163.com * Fire Workflow 官方网站:www.firesoa.com 或者 www.fireflow.org * */ public class WorkflowStatementRemoteImpl implements WorkflowStatement { protected WorkflowEngineService workflowServer = null; protected String processType = null; protected WorkflowSessionRemoteImpl remoteSession = null; public WorkflowStatementRemoteImpl(WorkflowSessionRemoteImpl session,String processType){ remoteSession = session; this.processType = processType; } public WorkflowEngineService getWorkflowServer() { return workflowServer; } public void setWorkflowServer(WorkflowEngineService workflowServer) { this.workflowServer = workflowServer; } /* (non-Javadoc) * @see org.fireflow.engine.WorkflowStatement#getProcessType() */ public String getProcessType() { return processType; } // /* (non-Javadoc) // * @see org.fireflow.engine.WorkflowStatement#getCurrentProcessInstance() // */ // @Override // public ProcessInstance getCurrentProcessInstance() { // return null; // } // // /* (non-Javadoc) // * @see org.fireflow.engine.WorkflowStatement#getCurrentActivityInstance() // */ // @Override // public ActivityInstance getCurrentActivityInstance() { // return null; // } // // /* (non-Javadoc) // * @see org.fireflow.engine.WorkflowStatement#getLatestCreatedWorkItems() // */ // @Override // public List<WorkItem> getLatestCreatedWorkItems() { // return null; // } /* (non-Javadoc) * @see org.fireflow.engine.WorkflowStatement#setDynamicAssignmentHandler(java.lang.String, org.fireflow.engine.invocation.AssignmentHandler) */ // @Override // public WorkflowStatement setDynamicAssignmentHandler(String activityId, // AssignmentHandler dynamicAssignmentHandler) { // return null; // } // /* (non-Javadoc) // * @see org.fireflow.engine.WorkflowStatement#setAttribute(java.lang.String, java.lang.Object) // */ // @Override // public WorkflowStatement setAttribute(String name, Object attr) { // return null; // } /* (non-Javadoc) * @see org.fireflow.engine.WorkflowStatement#startProcess(java.lang.String, int, java.lang.String, java.util.Map) */ public ProcessInstance startProcess(String workflowProcessId, int version, String bizId, Map<String, Object> variables) throws InvalidModelException, WorkflowProcessNotFoundException, InvalidOperationException { if (!checkVariableMap(variables))return null; MapConvertor mapConvertor = new MapConvertor(); mapConvertor.putAll(variables,MapConvertor.MAP_TYPE_VARIABLE); return this.workflowServer.startProcess2(this.remoteSession.getSessionId(), workflowProcessId,version,bizId,mapConvertor); } /* (non-Javadoc) * @see org.fireflow.engine.WorkflowStatement#startProcess(java.lang.String, int, java.lang.String, java.lang.String, java.util.Map) */ public ProcessInstance startProcess(String workflowProcessId, int version, String subProcessId, String bizId, Map<String, Object> variables) throws InvalidModelException, WorkflowProcessNotFoundException, InvalidOperationException { if (!checkVariableMap(variables))return null; MapConvertor mapConvertor = new MapConvertor(); mapConvertor.putAll(variables,MapConvertor.MAP_TYPE_VARIABLE); return this.workflowServer.startProcess4(this.remoteSession.getSessionId(), workflowProcessId,version,subProcessId,bizId,mapConvertor); } /* (non-Javadoc) * @see org.fireflow.engine.WorkflowStatement#startProcess(java.lang.String, java.lang.String, java.lang.String, java.util.Map) */ public ProcessInstance startProcess(String workflowProcessId, String subProcessId, String bizId, Map<String, Object> variables) throws InvalidModelException, WorkflowProcessNotFoundException, InvalidOperationException { if (!checkVariableMap(variables))return null; MapConvertor mapConvertor = new MapConvertor(); mapConvertor.putAll(variables,MapConvertor.MAP_TYPE_VARIABLE); return this.workflowServer.startProcess3(this.remoteSession.getSessionId(), workflowProcessId,subProcessId,bizId,mapConvertor); } /* (non-Javadoc) * @see org.fireflow.engine.WorkflowStatement#startProcess(java.lang.String, java.lang.String, java.util.Map) */ public ProcessInstance startProcess(String workflowProcessId, String bizId, Map<String, Object> variables) throws InvalidModelException, WorkflowProcessNotFoundException, InvalidOperationException { if (!checkVariableMap(variables))return null; MapConvertor mapConvertor = new MapConvertor(); mapConvertor.putAll(variables,MapConvertor.MAP_TYPE_VARIABLE); return this.workflowServer.startProcess1(this.remoteSession.getSessionId(), workflowProcessId,bizId,mapConvertor); } /* (non-Javadoc) * @see org.fireflow.engine.WorkflowStatement#startProcess(java.lang.Object, java.lang.String, java.util.Map) */ public ProcessInstance startProcess(Object process, String bizId, Map<String, Object> variables) throws InvalidModelException, WorkflowProcessNotFoundException, InvalidOperationException { throw new UnsupportedOperationException("远程接口不支持该方法,只能为流程库中已经存在的流程创建实例"); } /* (non-Javadoc) * @see org.fireflow.engine.WorkflowStatement#createProcessInstance(java.lang.String) */ public ProcessInstance createProcessInstance(String workflowProcessId) throws InvalidModelException, WorkflowProcessNotFoundException { return workflowServer.createProcessInstance1(remoteSession.getSessionId(), workflowProcessId); } /* (non-Javadoc) * @see org.fireflow.engine.WorkflowStatement#createProcessInstance(java.lang.Object) */ public ProcessInstance createProcessInstance(Object process) throws InvalidModelException { throw new UnsupportedOperationException("远程接口不支持该方法,只能为流程库中已经存在的流程创建实例"); } /* (non-Javadoc) * @see org.fireflow.engine.WorkflowStatement#createProcessInstance(java.lang.String, int) */ public ProcessInstance createProcessInstance(String workflowProcessId, int version) throws InvalidModelException, WorkflowProcessNotFoundException { return workflowServer.createProcessInstance2(remoteSession.getSessionId(), workflowProcessId,version); } /* (non-Javadoc) * @see org.fireflow.engine.WorkflowStatement#createProcessInstance(java.lang.String, int, java.lang.String) */ public ProcessInstance createProcessInstance(String workflowProcessId, int version, String subProcessId) throws InvalidModelException, WorkflowProcessNotFoundException { return workflowServer.createProcessInstance4(remoteSession.getSessionId(), workflowProcessId,version,subProcessId); } /* (non-Javadoc) * @see org.fireflow.engine.WorkflowStatement#createProcessInstance(java.lang.String, java.lang.String) */ public ProcessInstance createProcessInstance(String workflowProcessId, String subProcessId) throws InvalidModelException, WorkflowProcessNotFoundException { return workflowServer.createProcessInstance3(remoteSession.getSessionId(), workflowProcessId,subProcessId); } /* (non-Javadoc) * @see org.fireflow.engine.WorkflowStatement#runProcessInstance(java.lang.String, java.lang.String, java.util.Map) */ public ProcessInstance runProcessInstance(String processInstanceId, String bizId, Map<String, Object> variables) { //远程接口只能传递简单类型的流程参数(包括java.util.Date) if (!checkVariableMap(variables))return null; MapConvertor mapConvertor = new MapConvertor(); mapConvertor.putAll(variables,MapConvertor.MAP_TYPE_VARIABLE); return workflowServer.runProcessInstance(remoteSession.getSessionId(),processInstanceId,bizId, mapConvertor); } /** * 检查流程参数是否为简单类型 * @param variables * @return */ private boolean checkVariableMap(Map<String,Object> variables){ if (variables==null)return true; Iterator<Entry<String,Object>> entries = variables.entrySet().iterator(); if (entries!=null){ while (entries.hasNext()){ Map.Entry<String, Object> entry = entries.next(); Object value = entry.getValue(); if (value!=null){ if (!JavaDataTypeConvertor.isPrimaryObject(value)){ throw new EngineException("远程接口只能传递简单类型的流程变量(含java.util.Date,不含byte),而你传入了"+ entry.getKey()+"="+value.toString()+",值对象类型是"+value.getClass().getName()); } } } } return true; } /* (non-Javadoc) * @see org.fireflow.engine.WorkflowStatement#abortProcessInstance(java.lang.String, java.lang.String) */ public ProcessInstance abortProcessInstance(String processInstanceId, String note) throws InvalidOperationException { return this.workflowServer.abortProcessInstance(this.remoteSession.getSessionId(), processInstanceId,note); } /* (non-Javadoc) * @see org.fireflow.engine.WorkflowStatement#suspendProcessInstance(java.lang.String, java.lang.String) */ public ProcessInstance suspendProcessInstance(String processInstanceId, String note) throws InvalidOperationException { return this.workflowServer.suspendProcessInstance(this.remoteSession.getSessionId(), processInstanceId,note); } /* (non-Javadoc) * @see org.fireflow.engine.WorkflowStatement#restoreProcessInstance(java.lang.String, java.lang.String) */ public ProcessInstance restoreProcessInstance(String processInstanceId, String note) throws InvalidOperationException { return this.workflowServer.restoreProcessInstance(this.remoteSession.getSessionId(), processInstanceId,note); } /* (non-Javadoc) * @see org.fireflow.engine.WorkflowStatement#suspendActivityInstance(java.lang.String, java.lang.String) */ public ActivityInstance suspendActivityInstance(String activityInstanceId, String note) throws InvalidOperationException { return this.workflowServer.suspendActivityInstance(this.remoteSession.getSessionId(), activityInstanceId,note); } /* (non-Javadoc) * @see org.fireflow.engine.WorkflowStatement#restoreActivityInstance(java.lang.String, java.lang.String) */ public ActivityInstance restoreActivityInstance(String activityInstanceId, String note) throws InvalidOperationException { return this.workflowServer.restoreActivityInstance(this.remoteSession.getSessionId(), activityInstanceId,note); } /* (non-Javadoc) * @see org.fireflow.engine.WorkflowStatement#abortActivityInstance(java.lang.String, java.lang.String) */ public ActivityInstance abortActivityInstance(String activityInstanceId, String note) throws InvalidOperationException { return this.workflowServer.abortActivityInstance(this.remoteSession.getSessionId(), activityInstanceId,note); } /* (non-Javadoc) * @see org.fireflow.engine.WorkflowStatement#claimWorkItem(java.lang.String) */ public WorkItem claimWorkItem(String workItemId) throws InvalidOperationException { return this.workflowServer.claimWorkItem(this.remoteSession.getSessionId(), workItemId); } /* (non-Javadoc) * @see org.fireflow.engine.WorkflowStatement#disclaimWorkItem(java.lang.String, java.util.Map) */ public WorkItem disclaimWorkItem(String workItemId, String attachmentId, String attachmentType, String note) throws InvalidOperationException { return this.workflowServer.disclaimWorkItem(this.remoteSession.getSessionId(), workItemId,attachmentId,attachmentType,note); } /* (non-Javadoc) * @see org.fireflow.engine.WorkflowStatement#withdrawWorkItem(java.lang.String) */ public WorkItem withdrawWorkItem(String workItemId) throws InvalidOperationException { return this.workflowServer.withdrawWorkItem(this.remoteSession.getSessionId(), workItemId); } /* (non-Javadoc) * @see org.fireflow.engine.WorkflowStatement#completeWorkItem(java.lang.String, java.util.Map) */ public WorkItem completeWorkItem(String workItemId, String attachmentId, String attachmentType, String note) throws InvalidOperationException { return this.workflowServer.completeWorkItem1(this.remoteSession.getSessionId(), workItemId,attachmentId,attachmentType,note); } /* (non-Javadoc) * @see org.fireflow.engine.WorkflowStatement#completeWorkItem(java.lang.String, java.util.Map, java.util.Map) */ public WorkItem completeWorkItem(String workItemId, Map<String, AssignmentHandler> assignmentStrategy, String attachmentId, String attachmentType, String note) throws InvalidOperationException { if(!checkAssignmentStrategy(assignmentStrategy)) return null; MapConvertor mapConvertor = new MapConvertor(); mapConvertor.putAll(assignmentStrategy, MapConvertor.MAP_TYPE_ASSIGNMENT_HANDLER); return this.workflowServer.completeWorkItem2(this.remoteSession.getSessionId(), workItemId,mapConvertor,attachmentId,attachmentType,note); } /** * 远程接口的动态指定操作者只能使用DynamicAssignmentHandler,其他自行扩展的AssignmentHandler不能使用。 * 因为无法通过webservice进行传输。 * @param assitnmentStrategy * @return */ private boolean checkAssignmentStrategy(Map<String, AssignmentHandler> assitnmentStrategy){ Iterator<Entry<String,AssignmentHandler>> iterator = assitnmentStrategy.entrySet().iterator(); while (iterator.hasNext()){ Entry<String,AssignmentHandler> entry = iterator.next(); String key = entry.getKey(); AssignmentHandler value = entry.getValue(); if (value==null){ throw new EngineException("参数assignmentStrategy中的AssignmentHandler不能为null"); } String className = DynamicAssignmentHandler.class.getName(); if (!className.equals(value.getClass().getName())){ throw new EngineException("参数assignmentStrategy中的AssignmentHandler只能是"+ className+"的实例,而传入参数中含有"+value.getClass().getName()+"实例"); } } return true; } /* (non-Javadoc) * @see org.fireflow.engine.WorkflowStatement#completeWorkItemAndJumpTo(java.lang.String, java.lang.String, java.util.Map) */ public WorkItem completeWorkItemAndJumpTo(String workItemId, String targetActivityId, String attachmentId, String attachmentType, String note) throws InvalidOperationException { return this.workflowServer.completeWorkItemAndJumpTo1(this.remoteSession.getSessionId(), workItemId,targetActivityId,attachmentId,attachmentType,note); } /* (non-Javadoc) * @see org.fireflow.engine.WorkflowStatement#completeWorkItemAndJumpTo(java.lang.String, java.lang.String, java.util.Map, java.util.Map) */ public WorkItem completeWorkItemAndJumpTo(String workItemId, String targetActivityId, Map<String, AssignmentHandler> assignmentStrategy, String attachmentId, String attachmentType, String note) throws InvalidOperationException { if(!checkAssignmentStrategy(assignmentStrategy)) return null; MapConvertor mapConvertor = new MapConvertor(); mapConvertor.putAll(assignmentStrategy, MapConvertor.MAP_TYPE_ASSIGNMENT_HANDLER); return this.workflowServer.completeWorkItemAndJumpTo2(this.remoteSession.getSessionId(), workItemId,targetActivityId,mapConvertor,attachmentId,attachmentType,note); } /* (non-Javadoc) * @see org.fireflow.engine.WorkflowStatement#reassignWorkItemTo(java.lang.String, org.fireflow.engine.invocation.AssignmentHandler, java.util.Map) */ public WorkItem reassignWorkItemTo(String workItemId, ReassignmentHandler reassignHandler, String attachmentId, String attachmentType, String note) throws InvalidOperationException { return this.workflowServer.reassignWorkItemTo( this.remoteSession.getSessionId(),workItemId, reassignHandler,attachmentId, attachmentType, note); } /* (non-Javadoc) * @see org.fireflow.engine.WorkflowStatement#uploadProcessObject(java.lang.Object, boolean, java.util.Map) */ public ProcessDescriptor uploadProcessObject(Object processObject, int version) throws InvalidModelException { throw new UnsupportedOperationException("远程接口不支持该方法,请先将流程对象转换成Xml或者InputStream,然后调用uploadProcessStream(String processXml...)或者uploadProcessStream(InputStream inStream...)"); } /* (non-Javadoc) * @see org.fireflow.engine.WorkflowStatement#uploadProcessStream(java.io.InputStream, boolean, java.util.Map) */ public ProcessDescriptor uploadProcessStream(InputStream stream, int version) throws InvalidModelException { InputStream inStream = stream; if (!stream.markSupported()){ inStream = new BufferedInputStream(stream) ; } try { String charset = Utils.findXmlCharset(inStream); String processXml = Utils.inputStream2String(inStream, charset); return this.uploadProcessXml(processXml, version); } catch (IOException e) { throw new InvalidModelException(e); } } public ProcessDescriptor uploadProcessXml(String processXml,int version)throws InvalidModelException{ return this.workflowServer.uploadProcessXml(this.remoteSession.getSessionId(), processXml,version); } public void updateProcessDescriptor(ProcessDescriptor processDescriptor){ this.workflowServer.updateProcessDescriptor(this.remoteSession.getSessionId(),(ProcessDescriptorImpl)processDescriptor); } /* (non-Javadoc) * @see org.fireflow.engine.WorkflowStatement#uploadServicesStream(java.io.InputStream, java.lang.Boolean, java.util.Map) */ /* public List<ServiceDescriptor> uploadServicesStream(InputStream inStream, Boolean publishState, Map<ServiceDescriptorProperty, Object> metadata) throws InvalidModelException { throw new UnsupportedOperationException("远程接口暂不支持该方法"); } */ /* (non-Javadoc) * @see org.fireflow.engine.WorkflowStatement#uploadResourcesStream(java.io.InputStream, java.lang.Boolean, java.util.Map) */ /* public List<ResourceDescriptor> uploadResourcesStream(InputStream inStream, Boolean publishState, Map<ResourceDescriptorProperty, Object> metadata) throws InvalidModelException { throw new UnsupportedOperationException("远程接口暂不支持该方法"); } */ /* (non-Javadoc) * @see org.fireflow.engine.WorkflowStatement#getVariableValue(org.fireflow.engine.entity.runtime.Scope, java.lang.String) */ public Object getVariableValue(Scope scope, String name) { if (scope==null || name==null)return null; ScopeBean bean = ScopeBean.fromScopeObject(scope); ObjectWrapper objWrapper = this.workflowServer.getVariableValue(this.remoteSession.getSessionId(), bean,name); if (objWrapper!=null){ return objWrapper.getOriginalValue(); } return null; } /* (non-Javadoc) * @see org.fireflow.engine.WorkflowStatement#setVariableValue(org.fireflow.engine.entity.runtime.Scope, java.lang.String, java.lang.Object) */ public void setVariableValue(Scope scope, String name, Object value) throws InvalidOperationException { if (!JavaDataTypeConvertor.isPrimaryObject(value)){ throw new InvalidOperationException("远程接口只能设置基本数据类型的流程变量(含java.util.Date,不含byte);而当前设置数据类型是"+ value.getClass().getName()); } if (scope==null){ throw new InvalidOperationException("scope参数不能为null"); } ScopeBean bean = ScopeBean.fromScopeObject(scope); ObjectWrapper objWrapper = new ObjectWrapper(); objWrapper.setOriginalValue(value); this.workflowServer.setVariableValue1(this.remoteSession.getSessionId(), bean,name,objWrapper); } /* (non-Javadoc) * @see org.fireflow.engine.WorkflowStatement#setVariableValue(org.fireflow.engine.entity.runtime.Scope, java.lang.String, java.lang.Object, java.util.Map) */ public void setVariableValue(Scope scope, String name, Object value, Properties headers) throws InvalidOperationException { if (!JavaDataTypeConvertor.isPrimaryObject(value)){ throw new InvalidOperationException("远程接口只能设置基本数据类型的流程变量(含java.util.Date,不含byte);而当前设置数据类型是"+ value.getClass().getName()); } if (scope==null){ throw new InvalidOperationException("scope参数不能为null"); } ScopeBean bean = ScopeBean.fromScopeObject(scope); ObjectWrapper objWrapper = new ObjectWrapper(); objWrapper.setOriginalValue(value); PropertiesConvertor propConvertor = new PropertiesConvertor(); propConvertor.putAll(headers); this.workflowServer.setVariableValue2(this.remoteSession.getSessionId(), bean, name, objWrapper,propConvertor); } /* (non-Javadoc) * @see org.fireflow.engine.WorkflowStatement#getVariableValues(org.fireflow.engine.entity.runtime.Scope) */ public Map<String, Object> getVariableValues(Scope scope) { if (scope==null)return null; ScopeBean bean = ScopeBean.fromScopeObject(scope); MapConvertor convertor = this.workflowServer.getVariableValues(this.remoteSession.getSessionId(), bean); if (convertor!=null){ return convertor.getMap(); }else{ return null; } } /* (non-Javadoc) * @see org.fireflow.engine.WorkflowStatement#getWorkflowProcess(org.fireflow.engine.entity.repository.ProcessKey) */ public Object getWorkflowProcess(ProcessKey key) throws InvalidModelException { throw new UnsupportedOperationException("远程接口不支持该方法"); } public String getWorkflowProcessXml(ProcessKey key) { return this.workflowServer.getWorkflowProcessXml(this.remoteSession.getSessionId(), key.getProcessId(), key.getVersion(), key.getProcessType()); } public Object getWorkflowDefinitionElement(Scope scope)throws InvalidModelException{ throw new UnsupportedOperationException("远程接口不支持该方法"); } }