org.fireflow.engine.invocation.impl.AbsServiceInvoker.java Source code

Java tutorial

Introduction

Here is the source code for org.fireflow.engine.invocation.impl.AbsServiceInvoker.java

Source

/**
 * Copyright 2007-2010 ?
 * All rights reserved. 
 * 
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License 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 General Public License
 * along with this program. If not, see http://www.gnu.org/licenses. *
 */
package org.fireflow.engine.invocation.impl;

import java.lang.reflect.InvocationTargetException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.script.ScriptException;
import javax.xml.namespace.QName;
import javax.xml.parsers.ParserConfigurationException;

import org.apache.commons.beanutils.MethodUtils;
import org.apache.ws.commons.schema.XmlSchemaCollection;
import org.fireflow.client.WorkflowSession;
import org.fireflow.client.impl.WorkflowSessionLocalImpl;
import org.fireflow.engine.context.RuntimeContext;
import org.fireflow.engine.entity.runtime.ActivityInstance;
import org.fireflow.engine.entity.runtime.ProcessInstance;
import org.fireflow.engine.exception.ServiceInvocationException;
import org.fireflow.engine.invocation.ServiceInvoker;
import org.fireflow.engine.modules.process.ProcessUtil;
import org.fireflow.engine.modules.script.ScriptContextVariableNames;
import org.fireflow.engine.modules.script.ScriptEngineHelper;
import org.fireflow.model.binding.Assignment;
import org.fireflow.model.binding.ResourceBinding;
import org.fireflow.model.binding.ServiceBinding;
import org.fireflow.model.data.Expression;
import org.fireflow.model.servicedef.ServiceDef;
import org.firesoa.common.schema.DOMInitializer;
import org.firesoa.common.schema.NameSpaces;
import org.w3c.dom.Document;

/**
 * 
 * 
 * @author ?
 * @version 2.0
 */
public abstract class AbsServiceInvoker implements ServiceInvoker {
    //   DocumentFactory docFactory = DocumentFactory.getInstance();

    /*
     * (non-Javadoc)
     * 
     * @see
     * org.fireflow.engine.service.ServiceExecutor#complete(org.fireflow.engine
     * .WorkflowSession, org.fireflow.engine.entity.runtime.ActivityInstance,
     * java.lang.Object)
     */
    //   public void onServiceCompleted(WorkflowSession session,
    //         ActivityInstance activityInstance) {
    //      RuntimeContext ctx = ((WorkflowSessionLocalImpl) session)
    //            .getRuntimeContext();
    //      ActivityInstanceManager activityInstanceMgr = ctx.getEngineModule(
    //            ActivityInstanceManager.class,
    //            activityInstance.getProcessType());
    //
    //      activityInstanceMgr.onServiceCompleted(session, activityInstance);
    //
    //   }

    public int determineActivityCloseStrategy(WorkflowSession session, ActivityInstance activityInstance,
            Object theActivity, ServiceBinding serviceBinding) {
        return ServiceInvoker.CLOSE_ACTIVITY;
    }

    public boolean invoke(WorkflowSession session, ActivityInstance activityInstance, ServiceBinding serviceBinding,
            ResourceBinding resourceBinding, Object theActivity) throws ServiceInvocationException {
        try {
            WorkflowSessionLocalImpl sessionLocalImpl = (WorkflowSessionLocalImpl) session;
            RuntimeContext runtimeContext = sessionLocalImpl.getRuntimeContext();

            ProcessInstance processInstance = sessionLocalImpl.getCurrentProcessInstance();

            ProcessUtil processUtil = runtimeContext.getEngineModule(ProcessUtil.class,
                    activityInstance.getProcessType());
            ServiceDef svc = processUtil.getServiceDef(activityInstance, theActivity,
                    serviceBinding.getServiceId());
            if (svc == null) {
                ServiceInvocationException ex = new ServiceInvocationException(
                        "Id" + serviceBinding.getServiceId() + "?");
                ex.setErrorCode(ServiceInvocationException.SERVICE_DEF_NOT_FOUND);
                ex.setActivityInstance(activityInstance);
                throw ex;
            }

            // 1?Service Object
            Object serviceObject = this.getServiceObject(runtimeContext, session, activityInstance, serviceBinding,
                    svc, theActivity);

            if (serviceObject == null) {
                ServiceInvocationException ex = new ServiceInvocationException(
                        "? service objectService[name=" + svc.getName() + ",displayName="
                                + svc.getDisplayName() + "]");
                ex.setErrorCode(ServiceInvocationException.SERVICE_OBJECT_NOT_FOUND);
                ex.setActivityInstance(activityInstance);
                throw new ServiceInvocationException();
            }

            // 2??Method
            String methodName = this.getOperationName(runtimeContext, session, activityInstance, serviceBinding);

            if (methodName == null || methodName.trim().equals("")) {
                ServiceInvocationException ex = new ServiceInvocationException("???"
                        + serviceBinding.getOperationName() + "Service[name=" + svc.getName()
                        + ",displayName=" + svc.getDisplayName() + "]");
                ex.setErrorCode(ServiceInvocationException.OPERATION_NOT_FOUND);
                ex.setActivityInstance(activityInstance);
                throw new ServiceInvocationException();
            }

            // 3???
            Object[] params = resolveInputParams(runtimeContext, session, processInstance, activityInstance,
                    serviceBinding, svc);

            // 4??
            Class[] parameterTypes = this.getParameterTypes(serviceObject.getClass(), methodName, params);

            // 5?
            Object result = MethodUtils.invokeMethod(serviceObject, methodName, params, parameterTypes);

            // 6??
            assignOutputToVariable(runtimeContext, session, processInstance, activityInstance, serviceBinding,
                    result);

            return true;
        } catch (ServiceInvocationException e) {
            if (e.getActivityInstance() == null) {
                e.setActivityInstance(activityInstance);
            }
            throw e;
        } catch (ScriptException e) {
            ServiceInvocationException ex = new ServiceInvocationException(e);
            ex.setErrorCode(findRootCause(e).getClass().getName());
            ex.setActivityInstance(activityInstance);
            throw ex;
        } catch (SecurityException e) {
            ServiceInvocationException ex = new ServiceInvocationException(e);
            ex.setErrorCode(findRootCause(e).getClass().getName());
            ex.setActivityInstance(activityInstance);
            throw ex;
        } catch (NoSuchMethodException e) {
            ServiceInvocationException ex = new ServiceInvocationException(e);
            ex.setErrorCode(findRootCause(e).getClass().getName());
            ex.setActivityInstance(activityInstance);
            throw ex;
        } catch (IllegalArgumentException e) {
            ServiceInvocationException ex = new ServiceInvocationException(e);
            ex.setErrorCode(findRootCause(e).getClass().getName());
            ex.setActivityInstance(activityInstance);
            throw ex;
        } catch (IllegalAccessException e) {
            ServiceInvocationException ex = new ServiceInvocationException(e);
            ex.setErrorCode(findRootCause(e).getClass().getName());
            ex.setActivityInstance(activityInstance);
            throw ex;
        } catch (InvocationTargetException e) {
            ServiceInvocationException ex = new ServiceInvocationException(e);
            ex.setErrorCode(findRootCause(e).getClass().getName());
            ex.setActivityInstance(activityInstance);
            throw ex;
        } catch (Exception e) {
            ServiceInvocationException ex = new ServiceInvocationException(e);
            ex.setErrorCode(findRootCause(e).getClass().getName());
            ex.setActivityInstance(activityInstance);
            throw ex;
        }

    }

    private Throwable findRootCause(Throwable e) {

        if (e.getCause() == null) {
            return e;
        }
        return findRootCause(e.getCause());
    }

    protected abstract Object getServiceObject(RuntimeContext runtimeContext, WorkflowSession session,
            ActivityInstance activityInstance, ServiceBinding serviceBinding, ServiceDef serviceDef,
            Object activity) throws ServiceInvocationException;

    public static Map<String, Object> resolveInputAssignments(RuntimeContext runtimeContext,
            WorkflowSession session, ProcessInstance processInstance, ActivityInstance activityInstance,
            ServiceBinding serviceBinding, ServiceDef service) throws ScriptException {
        List<Assignment> inputAssignmentList = serviceBinding.getInputAssignments();
        //      OperationDef operation = serviceBinding.getOperation();
        //      List<Input> inputs = operation.getInputs();

        Map<String, Object> contextVars = ScriptEngineHelper.fulfillScriptContext(session, runtimeContext,
                processInstance, activityInstance);

        //?xmlinputxmlorg.w3c.dom.Document
        Map<String, Object> inputsContext = new HashMap<String, Object>();
        for (Assignment assignment : inputAssignmentList) {
            Expression toExpression = assignment.getTo();
            if (toExpression.getName() == null || toExpression.getName().trim().equals("")) {
                throw new ScriptException(
                        "The name of the assignment's To-Expression can NOT be empty. More information : the body of the To-Expression is '"
                                + toExpression.getBody() + "';the activity id is " + activityInstance.getNodeId());
            }
            if (toExpression.getDataType() != null
                    && !NameSpaces.JAVA.getUri().equals(toExpression.getDataType().getNamespaceURI())
                    && inputsContext.get(toExpression.getName()) == null) {
                Document doc = initDocument(service.getXmlSchemaCollection(), toExpression.getDataType());
                inputsContext.put(toExpression.getName(), doc);
            }
        }
        contextVars.put(ScriptContextVariableNames.INPUTS, inputsContext);

        Map<String, Object> inputParamValues = ScriptEngineHelper.resolveInputParameters(runtimeContext,
                serviceBinding.getInputAssignments(), contextVars);

        return inputParamValues;
    }

    protected Object[] resolveInputParams(RuntimeContext runtimeContext, WorkflowSession session,
            ProcessInstance processInstance, ActivityInstance activityInstance, ServiceBinding serviceBinding,
            ServiceDef service) throws ScriptException {

        Map<String, Object> inputParamValues = resolveInputAssignments(runtimeContext, session, processInstance,
                activityInstance, serviceBinding, service);
        List<Assignment> inputAssignmentList = serviceBinding.getInputAssignments();
        //      OperationDef operation = null;
        //      List<Input> inputs = operation.getInputs();

        List<Object> args = new ArrayList<Object>();
        for (Assignment assignment : inputAssignmentList) {
            Expression toExpression = assignment.getTo();
            if (inputParamValues != null && inputParamValues.containsKey(toExpression.getName())) {
                Object paramValue = inputParamValues.get(toExpression.getName());
                args.add(paramValue);
            } else {
                args.add(null);
                //TODO ?????
                //?java??
                //            String defaultValueAsString = _input.getDefaultValueAsString();
                //            if (StringUtils.isEmpty(defaultValueAsString)){
                //               args.add(null);
                //            }else {
                //               Object obj = JavaDataTypeConvertor.dataTypeConvert(_input.getDataType(), defaultValueAsString, _input.getDataPattern());
                //               args.add(obj);
                //            }
            }

        }
        return args.toArray();
    }

    protected void assignOutputToVariable(RuntimeContext runtimeContext, WorkflowSession session,
            ProcessInstance processInstance, ActivityInstance activityInstance, ServiceBinding serviceBinding,
            Object result) throws ScriptException {
        //      OperationDef operation = serviceBinding.getOperation();
        List<Assignment> outputAssignments = serviceBinding.getOutputAssignments();
        if (outputAssignments == null || outputAssignments.size() == 0)
            return;//?

        Map<String, Object> scriptContext = new HashMap<String, Object>();
        Map<String, Object> outputsResults = new HashMap<String, Object>();

        Assignment assignment = outputAssignments.get(0);
        Expression fromExp = assignment.getFrom();
        outputsResults.put(fromExp.getName(), result);
        scriptContext.put(ScriptContextVariableNames.OUTPUTS, outputsResults);

        //System.out.println("=========="+outputsResults);

        ScriptEngineHelper.assignOutputToVariable(session, runtimeContext, processInstance, activityInstance,
                outputAssignments, scriptContext);
    }

    /**
     * ?Schemaorg.w3c.dom.Document;
     * TODO SchemaChoice????
     * @param xmlSchemaCollection
     * @param elementQName
     * @return
     */
    protected static Document initDocument(XmlSchemaCollection xmlSchemaCollection, QName rootElementQName)
            throws ScriptException {
        try {
            Document doc = DOMInitializer.generateDocument(xmlSchemaCollection, rootElementQName);

            return doc;
        } catch (ParserConfigurationException e) {
            throw new ScriptException(e);
        }
    }

    //   protected org.dom4j.QName javaxQName4Dom4JQName(javax.xml.namespace.QName qNameIn){
    //      org.dom4j.Namespace ns = new org.dom4j.Namespace(qNameIn.getPrefix(),qNameIn.getNamespaceURI());
    //      org.dom4j.QName qName = new org.dom4j.QName(qNameIn.getLocalPart(),ns);
    //      return qName;
    //   }

    protected String getOperationName(RuntimeContext runtimeContext, WorkflowSession session,
            ActivityInstance activityInstance, ServiceBinding serviceBinding) throws ServiceInvocationException {
        return serviceBinding.getOperationName();
    }

    protected abstract Class[] getParameterTypes(Class serviceClass, String methodName, Object[] params)
            throws ServiceInvocationException;
}