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

org.ow2.cmi.ejb2_1.rpc.EJBHomeInvocationHandler 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: EJBHomeInvocationHandler.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.EJBMetaData;
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.EJBHomeHandle;
import org.ow2.cmi.ejb2_1.spec.JMetaData;
import org.ow2.cmi.reference.CMIReference;
import org.ow2.cmi.reference.CMIReferenceable;
import org.ow2.cmi.reference.ObjectNotFoundException;
import org.ow2.cmi.rpc.CMIInvocationHandler;
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 home 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 EJBHomeInvocationHandler extends CMIInvocationHandler {

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

    /**
     * Logger.
     */
    private static transient Log logger = LogFactory.getLog(EJBHomeInvocationHandler.class);

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

    /**
     * Remote interface.
     */
    private transient Class remoteClass;

    /**
     * Keep in cache the metadata.
     */
    private transient EJBMetaData ejbMetaData = null;

    /**
     * Build a new EJB2 Invocation Handler for the home interface.
     * @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
     */
    public EJBHomeInvocationHandler(
            final ClassLoader classLoader,
            final ClusterViewManager clusterViewManager,
            final String objectName,
            final String protocolName,
            final Class homeClass) {
        super(clusterViewManager, objectName, protocolName, false, homeClass);
        this.classLoader = classLoader;
        try {
            remoteClass = clusterViewManager.getRemoteClass(objectName);
        } catch (ObjectNotFoundException e) {
            throw new EJBInvocationHandlerException("Cannot get the remote class for " + objectName, e);
        }
    }

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

    /**
     * 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("create")) {
                EJBObjectInvocationHandler ejbObjectInvocationHandler = new EJBObjectInvocationHandler(
                        classLoader, clusterViewManager, objectName, protocolName, itf, remoteClass, (EJBHome) proxy);
                Object cmiProxy = Proxy.newProxyInstance(
                        classLoader, new Class[] {remoteClass, CMIProxy.class}, ejbObjectInvocationHandler);
                return cmiProxy;
            } else if(methodName.equals("getEJBMetaData")) {
                if(ejbMetaData == null) {
                    boolean isSession = true;
                    boolean isStatelessSession = true;
                    Class primaryKeyClass = null;
                    ejbMetaData = new JMetaData(
                            (EJBHome) proxy, itf, remoteClass, isSession, isStatelessSession, primaryKeyClass);
                }
                return ejbMetaData;
            } else if(methodName.equals("remove")) {
                return null;
            } else {
                throw new NoSuchMethodException(method.toString());
            }
        } 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);
        }
    }

    @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(remoteClass == null) {
                remoteClass = clusterViewManager.getRemoteClass(objectName);
            }
        } catch(Exception e) {
            logger.error("Cannot init the EJBHome proxy", e);
            throw new EJBInvocationHandlerException("Cannot init the EJBHome proxy", e);
        }
    }

    @Override
    protected String getHandleMethodName() {
        return "getHomeHandle";
    }

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

    @Override
    protected CMIReferenceable getCMIReferenceable(
            final CMIReference cmiReference) throws Exception {
        // Do nothing
        return null;
    }

    @Override
    protected void onExceptionHook(final String objectName,
            final CMIReferenceable cmiReferenceable) {
        // Do nothing
    }

    @Override
    protected void onFinallyHook(final String objectName,
            final CMIReferenceable cmiReferenceable) {
        // Do nothing
    }
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy