Package de.danet.an.workflow.tools

Source Code of de.danet.an.workflow.tools.EJBInvoker

/*
* This file is part of the WfMOpen project.
* Copyright (C) 2001-2007 Danet GmbH (www.danet.de), BU BTS.
* 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; either version 2 of the License, or
* (at your option) any later version.
*
* 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, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
*
* $Id: EJBInvoker.java 2550 2007-10-22 14:00:54Z  $
*
* $Log$
* Revision 1.1  2007/03/22 13:50:44  schnelle
* Initial release.
*
*/
package de.danet.an.workflow.tools;

import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.rmi.RemoteException;
import java.util.HashMap;
import java.util.Map;

import javax.ejb.EJBHome;
import javax.ejb.EJBMetaData;
import javax.ejb.EJBObject;
import javax.naming.NamingException;

import de.danet.an.util.EJBUtil;
import de.danet.an.workflow.api.Activity;
import de.danet.an.workflow.api.FormalParameter;
import de.danet.an.workflow.api.SAXEventBuffer;
import de.danet.an.workflow.spis.aii.ApplicationNotStoppedException;
import de.danet.an.workflow.spis.aii.CannotExecuteException;
import de.danet.an.workflow.spis.aii.ResultProvider;
import de.danet.an.workflow.spis.aii.ToolAgent;
import de.danet.an.workflow.util.XPDLUtil;

/**
* This class provides a facility to call EJBs.
*
* @author Dirk Schnelle
*
*/
public class EJBInvoker implements ToolAgent, ResultProvider {
    private static final org.apache.commons.logging.Log logger
        = org.apache.commons.logging.LogFactory.getLog(EJBInvoker.class);

    /** The result container. */
    private ThreadLocal result = new ThreadLocal ();
   
    /* (non-Javadoc)
     * Comment copied from interface or super class.
     */
    public void invoke(Activity activity, FormalParameter[] formalParameters,
            Map actualParameters) throws RemoteException,
            CannotExecuteException {
        int len = formalParameters.length;
        if (len < 3) {
            throw new CannotExecuteException("Too few arguments. "
                    + "At least JndiName, HomeClass, and Method are required!");
        }
       
        String jndiName
            = (String) actualParameters.get(formalParameters[0].id());
        String homeClassName
            = (String) actualParameters.get(formalParameters[1].id());
        String methodName
            = (String) actualParameters.get(formalParameters[2].id());
       
        int numArgs = len - 3;
        String returnParam = null;
        if (len > 3) {
            FormalParameter.Mode lastParamMode
                = formalParameters[len - 1].mode();
            if ((lastParamMode == FormalParameter.Mode.OUT)
                    || (lastParamMode == FormalParameter.Mode.INOUT)) {
                returnParam = formalParameters[len - 1].id();
               
                numArgs --;
            }
        }
       
        Object[] args = new Object[numArgs];
        Class[] sig = new Class[numArgs];
       
        parseArguments(formalParameters, actualParameters, numArgs, args, sig);

        Class homeClass;
        try {
            ClassLoader cl = Thread.currentThread().getContextClassLoader();
            homeClass = cl.loadClass(homeClassName);
        } catch (ClassNotFoundException e) {
            throw new CannotExecuteException("cannot load HomeClass '"
                    + homeClassName + "'");
        }

        if (logger.isDebugEnabled()) {
            String str = getDebugMethodCall(formalParameters, jndiName,
                    homeClassName, methodName, numArgs, args, sig);
           
            logger.debug(str);
        }
       
        Object callResult;
        try {
            callResult = callEJB(jndiName, homeClass, methodName, sig, args);
        } catch (NamingException e) {
            throw new CannotExecuteException(e.getMessage(), e);
        } catch (IllegalArgumentException e) {
            throw new CannotExecuteException(e.getMessage(), e);
        } catch (IllegalAccessException e) {
            throw new CannotExecuteException(e.getMessage(), e);
        } catch (InvocationTargetException e) {
            throw new CannotExecuteException(e.getMessage(), e);
        } catch (NoSuchMethodException e) {
            throw new CannotExecuteException(e.getMessage(), e);
        }
       
        if (returnParam != null) {
            Map resData = new HashMap ();
           
            resData.put(returnParam, callResult);
           
            result.set(resData);
        }
    }

    /**
     * Parses the given arguments to create the signature and the arguments
     * for the method call.
     * @param formalParameters formal parameters of the tool
     * @param actualParameters values for the parameters
     * @param numArgs number of arguments
     * @param args values for the method call (must be of size
     *          <code>numArgs</code>
     * @param sig signature of the method (must be of size
     *          <code>numArgs</code>
     * @throws CannotExecuteException
     *        Unknown parameter type.
     */
    private void parseArguments(FormalParameter[] formalParameters,
            Map actualParameters, int numArgs, Object[] args, Class[] sig)
        throws CannotExecuteException {
        for (int i=0; i<numArgs; i++) {
            String id = formalParameters[i+3].id();
            args[i] = actualParameters.get(id);
            Object type = formalParameters[i+3].type();
            if (type.equals(Long.class)) {
                sig[i] = long.class;
            } else if (type.equals(Boolean.class)) {
                    sig[i] = boolean.class;
            } else if (type.equals(Double.class)) {
                sig[i] = double.class;
            } else if (XPDLUtil.isXMLType(type)) {
                if (args[i] instanceof SAXEventBuffer) {
                    sig[i] = SAXEventBuffer.class;
                } else if (args[i] instanceof org.w3c.dom.DocumentFragment) {
                    sig[i] = org.w3c.dom.DocumentFragment.class;
                } else if (args[i] instanceof org.jdom.Element) {
                    sig[i] = org.jdom.Element.class;
                } else {
                    String msg = "Got argument of XML type, but cannot"
                      + " recognize value's class: " + args[i].getClass();
                    throw new CannotExecuteException (msg);
                }
            } else {
                sig[i] = (Class) type;
            }
        }
    }

    /**
     * Create a human readable output of the method call.
     * @param formalParameters
     * @param jndiName
     * @param homeClassName
     * @param methodName
     * @param numArgs
     * @param args
     * @param sig
     * @return
     */
    private String getDebugMethodCall(FormalParameter[] formalParameters,
            String jndiName, String homeClassName, String methodName,
            int numArgs, Object[] args, Class[] sig) {
        StringBuffer str = new StringBuffer();
       
        str.append("calling ");
        str.append(homeClassName);
        str.append(" (");
        str.append(jndiName);
        str.append(") ");
        str.append(methodName);
        str.append("(");
        for (int i=0; i<numArgs; i++) {
            if (XPDLUtil.isXMLType(formalParameters[i+3].type())) {
                str.append("XML");
            } else {
                if (sig[i].equals(String.class)) {
                    str.append("\"");
                }
                str.append(args[i]);
                if (sig[i].equals(String.class)) {
                    str.append("\"");
                }
            }
            if (i != numArgs - 1) {
                str.append(", ");
            }
        }
        str.append(")");
       
        return str.toString();
    }

    /**
     * Call the EJB.
     * @param jndiName the JNDI name of the EJB
     * @param homeClass the home class of the EJB
     * @param method the name of the method to call.
     * @param sig the signature of the method to call
     * @param args the arguments to provide in the call
     * @return Result of invocation.
     * @throws NamingException
     *         JNDI name could not be resolved.
     * @throws RemoteException
     *         Error accessing the EJB
     * @throws IllegalArgumentException
     *         Error in the signature.
     * @throws IllegalAccessException
     *         Method is not accessible.
     * @throws InvocationTargetException
     *         Error in method call.
     * @throws NoSuchMethodException
     *         Method is unknown.
     */
    private Object callEJB(String jndiName, Class homeClass, String method,
            Class[] sig, Object[] args) throws NamingException, RemoteException,
            IllegalArgumentException, IllegalAccessException,
            InvocationTargetException, NoSuchMethodException {
        EJBHome home = EJBUtil.lookupEJBHome(homeClass, jndiName);
        EJBMetaData md = home.getEJBMetaData();
        EJBObject remote = (EJBObject)
        invoke(homeClass, home, "create", null, null);
        Class remoteClass = md.getRemoteInterfaceClass();

        return invoke(remoteClass, remote, method, sig, args);
    }

    /**
     * Convenience method to call a method on the given object.
     * @param clazz The class of the object.
     * @param obj the object.
     * @param methodName the name of the method to call.
     * @param sig the signature of the method.
     * @param args the arguments to provide.
     * @return result of the method call.
     * @throws IllegalArgumentException
     * @throws IllegalAccessException
     * @throws InvocationTargetException
     * @throws NoSuchMethodException
     */
    private Object invoke(Class clazz, Object obj, String methodName,
            Class[] sig, Object[] args) throws IllegalArgumentException,
            IllegalAccessException, InvocationTargetException,
            NoSuchMethodException {
        Method method = clazz.getMethod(methodName, sig);
       
        return method.invoke(obj, args);
    }    
   
    /* (non-Javadoc)
     * Comment copied from interface or super class.
     */
    public void terminate(Activity activity)
            throws ApplicationNotStoppedException, RemoteException {
        throw new ApplicationNotStoppedException
            ("Terminate not implemented for EJBTool.");
    }

    /* (non-Javadoc)
     * Comment copied from interface or super class.
     */
    public Object result() {
        Object res = result.get();
       
        result.set (null);
       
        return res;
    }
}
TOP

Related Classes of de.danet.an.workflow.tools.EJBInvoker

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.