All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.ow2.cmi.ejb2_1.rpc.EJBObjectInvocationHandler Maven / Gradle / Ivy

/**
 * CMI : Cluster Method Invocation
 * Copyright (C) 2007,2008 Bull S.A.S.
 * Contact: [email protected]
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * This library 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
 * Lesser 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, write to the Free Software
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA
 * --------------------------------------------------------------------------
 * $Id: EJBObjectInvocationHandler.java 2122 2008-09-27 09:41:35Z loris $
 * --------------------------------------------------------------------------
 */

package org.ow2.cmi.ejb2_1.rpc;

import java.lang.reflect.Method;
import java.lang.reflect.Proxy;

import javax.ejb.EJBException;
import javax.ejb.EJBHome;
import javax.ejb.EJBObject;

import net.jcip.annotations.ThreadSafe;

import org.ow2.cmi.controller.common.ClusterViewManager;
import org.ow2.cmi.ejb2_1.pool.EJBObjectFactory;
import org.ow2.cmi.ejb2_1.spec.EJBObjectHandle;
import org.ow2.cmi.reference.CMIReference;
import org.ow2.cmi.reference.CMIReferenceable;
import org.ow2.cmi.rpc.CMIInvocationHandlerByPool;
import org.ow2.cmi.rpc.CMIProxy;
import org.ow2.util.log.Log;
import org.ow2.util.log.LogFactory;
import org.ow2.util.pool.api.IPoolConfiguration;
import org.ow2.util.pool.api.Pool;
import org.ow2.util.pool.impl.JPool;

/**
 * This class intercepts the invocations on the remote interface of a stateless ejb2.
 * It is created by {@link org.ow2.cmi.rpc.CMIProxyFactory#newCMIProxy(ClusterViewManager, String, String)}.
 * @author The new CMI team
 * @see org.ow2.cmi.rpc.CMIProxyFactory
 */
@ThreadSafe
public class EJBObjectInvocationHandler extends CMIInvocationHandlerByPool {

    /**
     * Id for serializable class.
     */
    private static final long serialVersionUID = 7543664459135220878L;

    /**
     * Logger.
     */
    private static final Log LOGGER = LogFactory.getLog(EJBObjectInvocationHandler.class);

    /**
     * The classloader to use.
     */
    private transient ClassLoader classLoader;

    /**
     * Home interface.
     */
    private transient Class homeClass;

    /**
     * Home proxy.
     */
    private transient EJBHome ejbHomeProxy;

    /**
     * Build a new EJB2 Invocation Handler for the remote interface of a stateless.
     * @param classLoader the classloader to use (when the smart factory is used, it is the smart classloader)
     * @param clusterViewManager A manager of the cluster view
     * @param objectName a name of the object
     * @param protocolName a protocol to perform the invocation
     * @param homeClass a home interface
     * @param remoteClass a remote interface
     * @param ejbHomeProxy a home proxy
     */
    public EJBObjectInvocationHandler(
            final ClassLoader classLoader,
            final ClusterViewManager clusterViewManager,
            final String objectName,
            final String protocolName,
            final Class homeClass,
            final Class remoteClass,
            final EJBHome ejbHomeProxy) {
        super(clusterViewManager, objectName, protocolName, false, remoteClass);
        this.classLoader = classLoader;
        this.homeClass = homeClass;
        this.ejbHomeProxy = ejbHomeProxy;
    }

    /**
     * Returns a string representation for a proxy that uses this invocation
     * handler.
     **/
    @Override
    protected String proxyToString(final Object proxy) {
        return "EJBObjectProxy["
        + super.proxyToString(proxy)
        + ", homeClass:" + homeClass.getName()
        + ", ejbHomeProxy:" + ejbHomeProxy
        + "]";
    }

    /**
     * Handles remote methods.
     **/
    @Override
    protected Object invokeRemoteMethod(final Object proxy, final Method method, final Object... args)
    throws EJBInvocationHandlerException, Throwable {

        String methodName = method.getName();

        // Use the same classloader that during the creation of this object
        ClassLoader oldClassLoader = Thread.currentThread().getContextClassLoader();
        Thread.currentThread().setContextClassLoader(classLoader);
        setClassLoader(oldClassLoader);
        try {
            if(methodName.equals("getEJBHome")) {
                return ejbHomeProxy;
            } else if(methodName.equals("isIdentical")) {
                EJBObject ejbObject = (EJBObject) args[0];
                return homeClass.equals(ejbObject.getEJBHome().getEJBMetaData().getHomeInterfaceClass());
            } else if(methodName.equals("remove")) {
                // Do nothing
                return null;
            }
            return super.invokeRemoteMethod(proxy, method, args);
        } catch(Exception e) {
            if(e instanceof EJBException) {
                throw e;
            }
            LOGGER.error("Error when invoking {0}", method, e);
            throw new EJBInvocationHandlerException("Error when invoking " + method, e);
        } finally {
            Thread.currentThread().setContextClassLoader(oldClassLoader);
        }
    }

    @SuppressWarnings("unchecked")
    @Override
    protected void checkInitialized() throws EJBInvocationHandlerException {
        try {
            synchronized(clusterViewManager){
                // The first time, create a pool to share stubs for EJBObject
                if(clusterViewManager.getPool(objectName) == null) {
                    LOGGER.debug("First lookup on {0}: creation of the pool for its stubs for EJBObject", objectName);
                    Pool, CMIReference> pool =
                        new JPool, CMIReference>(
                                new EJBObjectFactory(clusterViewManager));
                    IPoolConfiguration poolConfiguration = clusterViewManager.getPoolConfiguration(objectName);
                    if(poolConfiguration != null) {
                        pool.setPoolConfiguration(poolConfiguration);
                    }
                    clusterViewManager.setPool(objectName, pool);
                }
            }
            if(classLoader == null) {
                classLoader = Thread.currentThread().getContextClassLoader();
            }
            if(homeClass == null) {
                homeClass = (Class) clusterViewManager.getInterface(objectName);
            }
            if(ejbHomeProxy == null) {
                EJBHomeInvocationHandler ejbHomeInvocationHandler =
                    new EJBHomeInvocationHandler(classLoader, clusterViewManager, objectName, protocolName, homeClass);
                ejbHomeProxy = (EJBHome) Proxy.newProxyInstance(
                        classLoader,  new Class[] {homeClass, CMIProxy.class}, ejbHomeInvocationHandler);
            }
        } catch (Exception e) {
            LOGGER.error("Cannot init the EJBObject proxy", e);
            throw new EJBInvocationHandlerException("Cannot init the EJBObject proxy", e);
        }
    }

    @Override
    protected EJBObjectHandle getHandle(final CMIProxy cmiProxy) {
        if(cmiProxyHandle == null) {
            cmiProxyHandle = new EJBObjectHandle(objectName, itf.getName(), (EJBObject) cmiProxy);
        }
        return (EJBObjectHandle) cmiProxyHandle;
    }

}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy