dain        2006/02/01 06:50:08

  Modified:    modules/core/src/java/org/openejb/proxy BaseEJB.java
                        ContainerHandler.java EJBInterceptor.java
                        EJBMethodInterceptor.java EJBProxyFactory.java
                        ProxyInfo.java ProxyMemento.java
                        SessionEJBHome.java
  Log:

  Major refactor
  Split container into an object to represent a deployed ejb and a set of 
shared containers which process invocations
  Introduced interface between CMP container and CMP engine
  
  Revision  Changes    Path
  1.7       +4 -4      
openejb/modules/core/src/java/org/openejb/proxy/BaseEJB.java
  
  Index: BaseEJB.java
  ===================================================================
  RCS file: 
/home/projects/openejb/scm/openejb/modules/core/src/java/org/openejb/proxy/BaseEJB.java,v
  retrieving revision 1.6
  retrieving revision 1.7
  diff -u -r1.6 -r1.7
  --- BaseEJB.java      1 Jul 2005 19:34:36 -0000       1.6
  +++ BaseEJB.java      1 Feb 2006 11:50:08 -0000       1.7
  @@ -92,7 +92,7 @@
   
   import javax.ejb.EJBException;
   
  -import org.openejb.ContainerNotFoundException;
  +import org.openejb.DeploymentNotFoundException;
   
   
   /**
  @@ -110,7 +110,7 @@
        public ProxyInfo getProxyInfo() {
            try {
                return ejbHandler.getProxyInfo();
  -         } catch (ContainerNotFoundException e) {
  +         } catch (DeploymentNotFoundException e) {
                throw new EJBException("Container not found " + e.getMessage());
            }
        }
  
  
  
  1.5       +8 -10     
openejb/modules/core/src/java/org/openejb/proxy/ContainerHandler.java
  
  Index: ContainerHandler.java
  ===================================================================
  RCS file: 
/home/projects/openejb/scm/openejb/modules/core/src/java/org/openejb/proxy/ContainerHandler.java,v
  retrieving revision 1.4
  retrieving revision 1.5
  diff -u -r1.4 -r1.5
  --- ContainerHandler.java     6 Apr 2004 19:11:58 -0000       1.4
  +++ ContainerHandler.java     1 Feb 2006 11:50:08 -0000       1.5
  @@ -45,21 +45,19 @@
   package org.openejb.proxy;

   

   import org.apache.geronimo.core.service.InvocationResult;

  -

  -import org.openejb.EJBContainer;

  -import org.openejb.EJBInvocation;

  +import org.openejb.EjbDeployment;

  +import org.openejb.EjbInvocation;

   

   public class ContainerHandler implements EJBInterceptor {

  +    private EjbDeployment container;

   

  -    EJBContainer container;

  -    

  -    public ContainerHandler(EJBContainer container){

  +    public ContainerHandler(EjbDeployment container){

           this.container = container;

       }

   

  -    

  -    public InvocationResult invoke(EJBInvocation ejbInvocation) throws 
Throwable{

  +

  +    public InvocationResult invoke(EjbInvocation ejbInvocation) throws 
Throwable{

           return container.invoke(ejbInvocation);

       }

  -    

  +

   }

  
  
  
  1.4       +3 -3      
openejb/modules/core/src/java/org/openejb/proxy/EJBInterceptor.java
  
  Index: EJBInterceptor.java
  ===================================================================
  RCS file: 
/home/projects/openejb/scm/openejb/modules/core/src/java/org/openejb/proxy/EJBInterceptor.java,v
  retrieving revision 1.3
  retrieving revision 1.4
  diff -u -r1.3 -r1.4
  --- EJBInterceptor.java       21 Mar 2004 21:26:35 -0000      1.3
  +++ EJBInterceptor.java       1 Feb 2006 11:50:08 -0000       1.4
  @@ -45,8 +45,8 @@
   package org.openejb.proxy;

   

   import org.apache.geronimo.core.service.InvocationResult;

  -import org.openejb.EJBInvocation;

  +import org.openejb.EjbInvocation;

   

   public interface EJBInterceptor {

  -    public InvocationResult invoke(EJBInvocation ejbInvocation) throws 
Throwable;

  +    public InvocationResult invoke(EjbInvocation ejbInvocation) throws 
Throwable;

   }

  
  
  
  1.14      +16 -14    
openejb/modules/core/src/java/org/openejb/proxy/EJBMethodInterceptor.java
  
  Index: EJBMethodInterceptor.java
  ===================================================================
  RCS file: 
/home/projects/openejb/scm/openejb/modules/core/src/java/org/openejb/proxy/EJBMethodInterceptor.java,v
  retrieving revision 1.13
  retrieving revision 1.14
  diff -u -r1.13 -r1.14
  --- EJBMethodInterceptor.java 1 Jul 2005 19:34:36 -0000       1.13
  +++ EJBMethodInterceptor.java 1 Feb 2006 11:50:08 -0000       1.14
  @@ -13,12 +13,12 @@
   import net.sf.cglib.proxy.MethodInterceptor;
   import net.sf.cglib.proxy.MethodProxy;
   import org.apache.geronimo.core.service.InvocationResult;
  -import org.openejb.ContainerNotFoundException;
  +import org.openejb.DeploymentNotFoundException;
   import org.openejb.EJBComponentType;
  -import org.openejb.EJBContainer;
  +import org.openejb.RpcEjbDeployment;
   import org.openejb.EJBInterfaceType;
  -import org.openejb.EJBInvocation;
  -import org.openejb.EJBInvocationImpl;
  +import org.openejb.EjbInvocation;
  +import org.openejb.EjbInvocationImpl;
   
   public class EJBMethodInterceptor implements MethodInterceptor, Serializable 
{
       /**
  @@ -39,7 +39,7 @@
       /**
        * The container we are invokeing
        */
  -    private transient EJBContainer container;
  +    private transient RpcEjbDeployment container;
   
       /**
        * Map from interface method ids to vop ids.
  @@ -71,11 +71,11 @@
        */
       private transient boolean crossClassLoader;
   
  -    public EJBMethodInterceptor(EJBProxyFactory proxyFactory, 
EJBInterfaceType type, EJBContainer container, int[] operationMap) {
  +    public EJBMethodInterceptor(EJBProxyFactory proxyFactory, 
EJBInterfaceType type, RpcEjbDeployment container, int[] operationMap) {
           this(proxyFactory, type, container, operationMap, null);
       }
   
  -    public EJBMethodInterceptor(EJBProxyFactory proxyFactory, 
EJBInterfaceType type, EJBContainer container, int[] operationMap, Object 
primaryKey) {
  +    public EJBMethodInterceptor(EJBProxyFactory proxyFactory, 
EJBInterfaceType type, RpcEjbDeployment container, int[] operationMap, Object 
primaryKey) {
           this.proxyFactory = proxyFactory;
           this.interfaceType = type;
           this.container = container;
  @@ -100,7 +100,7 @@
           return proxyFactory;
       }
   
  -    public ProxyInfo getProxyInfo() throws ContainerNotFoundException {
  +    public ProxyInfo getProxyInfo() throws DeploymentNotFoundException {
           if (proxyInfo == null) {
               loadContainerInfo();
           }
  @@ -112,7 +112,7 @@
       }
   
       public Object intercept(Object proxy, Method method, Object[] args, 
MethodProxy methodProxy) throws Throwable {
  -        EJBInvocation invocation = createEJBInvocation(method, methodProxy, 
args);
  +        EjbInvocation invocation = createEJBInvocation(method, methodProxy, 
args);
           if (invocation == null) {
               return null;
           }
  @@ -161,12 +161,12 @@
           }
       }
   
  -    private EJBInvocation createEJBInvocation(Method method, MethodProxy 
methodProxy, Object[] args) throws Throwable {
  +    private EjbInvocation createEJBInvocation(Method method, MethodProxy 
methodProxy, Object[] args) throws Throwable {
           // fault in the operation map if we don't have it yet
           if (operationMap == null) {
               try {
                   loadContainerInfo();
  -            } catch (ContainerNotFoundException e) {
  +            } catch (DeploymentNotFoundException e) {
                   if (!interfaceType.isLocal()) {
                       throw new NoSuchObjectException(e.getMessage());
                   } else {
  @@ -185,7 +185,9 @@
           }
   
           int methodIndex = operationMap[methodProxy.getSuperIndex()];
  -        if (methodIndex < 0) throw new AssertionError("Unknown method: 
method=" + method);
  +        if (methodIndex < 0) {
  +            throw new AssertionError("Unknown method: method=" + method);
  +        }
           if ((interfaceType == EJBInterfaceType.HOME || interfaceType == 
EJBInterfaceType.LOCALHOME) && method.getName().equals("remove")) {
   
               if (args.length != 1) {
  @@ -200,7 +202,7 @@
               }
           }
   
  -        return new EJBInvocationImpl(interfaceType, id, methodIndex, args);
  +        return new EjbInvocationImpl(interfaceType, id, methodIndex, args);
       }
   
       private void copyArgsToTargetCL(Object[] args) throws IOException, 
ClassNotFoundException {
  @@ -244,7 +246,7 @@
           }
       }
   
  -    private void loadContainerInfo() throws ContainerNotFoundException {
  +    private void loadContainerInfo() throws DeploymentNotFoundException {
           container = proxyFactory.getContainer();
           operationMap = proxyFactory.getOperationMap(interfaceType);
   
  
  
  
  1.17      +1 -1      
openejb/modules/core/src/java/org/openejb/proxy/EJBProxyFactory.java
  
  Index: EJBProxyFactory.java
  ===================================================================
  RCS file: 
/home/projects/openejb/scm/openejb/modules/core/src/java/org/openejb/proxy/EJBProxyFactory.java,v
  retrieving revision 1.16
  retrieving revision 1.17
  diff -u -r1.16 -r1.17
  --- EJBProxyFactory.java      31 Aug 2005 23:54:03 -0000      1.16
  +++ EJBProxyFactory.java      1 Feb 2006 11:50:08 -0000       1.17
  @@ -1 +1 @@
  -/**
 * Redistribution and use of this software and associated documentation
 * ("Software"), with or without modification, are permitted provided
 * that the following conditions are met:
 *
 * 1. Redistributions of source code must retain copyright
 *    statements and notices.  Redistributions must also contain a
 *    copy of this document.
 *
 * 2. Redistributions in binary form must reproduce the
 *    above copyright notice, this list of conditions and the
 *    following disclaimer in the documentation and/or other
 *    materials provided with the distribution.
 *
 * 3. The name "OpenEJB" must not be used to endorse or promote
 *    products derived from this Software without prior written
 *    permission of The OpenEJB Group.  For written permission,
 *    please contact [EMAIL PROTECTED]
 *
 * 4. Products derived from this Software may not be called "OpenEJB"
 *    nor may "OpenEJB" appear in their names without prior written
 *    permission of The OpenEJB Group. OpenEJB is a registered
 *    trademark of The OpenEJB Group.
 *
 * 5. Due credit should be given to the OpenEJB Project
 *    (http://openejb.org/).
 *
 * THIS SOFTWARE IS PROVIDED BY THE OPENEJB GROUP AND CONTRIBUTORS
 * ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT
 * NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
 * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL
 * THE OPENEJB GROUP OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
 * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
 * OF THE POSSIBILITY OF SUCH DAMAGE.
 *
 * Copyright 2001 (C) The OpenEJB Group. All Rights Reserved.
 *
 * $Id$
 */
package org.openejb.proxy;

import java.io.Serializable;
import java.lang.reflect.Method;
import java.util.Collections;
import java.util.HashMap;
import java.util.Map;
import javax.ejb.EJBHome;
import javax.ejb.EJBLocalHome;
import javax.ejb.EJBLocalObject;
import javax.ejb.EJBObject;

import org.openejb.ContainerIndex;
import org.openejb.EJBContainer;
import org.openejb.EJBInterfaceType;
import org.openejb.ContainerNotFoundException;
import org.openejb.dispatch.InterfaceMethodSignature;

public class EJBProxyFactory implements Serializable, 
org.tranql.ejb.EJBProxyFactory {
    private static final Class[] sessionBaseClasses =
            new Class[]{SessionEJBObject.class, SessionEJBHome.class, 
SessionEJBLocalObject.class, SessionEJBLocalHome.class};

    private static final Class[] entityBaseClasses =
            new Class[]{EntityEJBObject.class, EntityEJBHome.class, 
EntityEJBLocalObject.class, EntityEJBLocalHome.class};

    private final String containerId;
    private final boolean isSessionBean;
    private final Class remoteInterface;
    private final Class homeInterface;
    private final Class localInterface;
    private final Class localHomeInterface;

    private transient final CglibEJBProxyFactory remoteFactory;
    private transient final CglibEJBProxyFactory homeFactory;
    private transient final CglibEJBProxyFactory localFactory;
    private transient final CglibEJBProxyFactory localHomeFactory;

    private transient EJBContainer container;

    private transient int[] remoteMap;
    private transient int[] homeMap;
    private transient int[] localMap;
    private transient int[] localHomeMap;

    private transient Map legacyMethodMap;

    public EJBProxyFactory(EJBContainer container) {
        this(container.getProxyInfo());
        setContainer(container);
    }

    public EJBProxyFactory(ProxyInfo proxyInfo) {
        this(
                proxyInfo.getContainerID(),
                proxyInfo.isSessionBean(),
                proxyInfo.getRemoteInterface(),
                proxyInfo.getHomeInterface(),
                proxyInfo.getLocalInterface(),
                proxyInfo.getLocalHomeInterface());
    }

    public EJBProxyFactory(
            String containerId,
            boolean sessionBean,
            Class remoteInterface,
            Class homeInterface,
            Class localInterface,
            Class localHomeInterface) {
        this.containerId = containerId;
        isSessionBean = sessionBean;

// JNB: these are temporarily disabled due to classloader issues during 
deployment
//        assert remoteInterface == null || (remoteInterface.isInterface() && 
EJBObject.class.isAssignableFrom(remoteInterface));
        this.remoteInterface = remoteInterface;

//        assert homeInterface == null || (homeInterface.isInterface() && 
EJBHome.class.isAssignableFrom(homeInterface));
        this.homeInterface = homeInterface;

//        assert localInterface == null || (localInterface.isInterface() && 
EJBLocalObject.class.isAssignableFrom(localInterface));
        this.localInterface = localInterface;

//        assert localHomeInterface == null || 
(localHomeInterface.isInterface() && 
EJBLocalHome.class.isAssignableFrom(localHomeInterface));
        this.localHomeInterface = localHomeInterface;

        this.remoteFactory = getFactory(EJBInterfaceType.REMOTE.getOrdinal(), 
remoteInterface);
        this.homeFactory = getFactory(EJBInterfaceType.HOME.getOrdinal(), 
homeInterface);
        this.localFactory = getFactory(EJBInterfaceType.LOCAL.getOrdinal(), 
localInterface);
        this.localHomeFactory = 
getFactory(EJBInterfaceType.LOCALHOME.getOrdinal(), localHomeInterface);
    }

    public String getEJBName() {
        return container.getEjbName();
    }

    EJBContainer getContainer() throws ContainerNotFoundException {
        if (container == null) {
            locateContainer();
        }
        return container;
    }

    private void setContainer(EJBContainer container) {
        assert container != null: "container is null";
        this.container = container;

        ProxyInfo proxyInfo = container.getProxyInfo();
        InterfaceMethodSignature[] signatures = container.getSignatures();

        // build the legacy map
        Map map = new HashMap();
        addLegacyMethods(map, proxyInfo.getRemoteInterface(), signatures);
        addLegacyMethods(map, proxyInfo.getHomeInterface(), signatures);
        addLegacyMethods(map, proxyInfo.getLocalInterface(), signatures);
        addLegacyMethods(map, proxyInfo.getLocalHomeInterface(), signatures);
        addLegacyMethods(map, proxyInfo.getServiceEndpointInterface(), 
signatures);
        legacyMethodMap = Collections.unmodifiableMap(map);

        remoteMap = createOperationsMap(remoteFactory, signatures);
        homeMap = createOperationsMap(homeFactory, signatures);

        localMap = createOperationsMap(localFactory, signatures);
        localHomeMap = createOperationsMap(localHomeFactory, signatures);
    }

    public ClassLoader getClassLoader() {
        if (remoteFactory != null) {
            return remoteFactory.getType().getClassLoader();
        } else {
            return localFactory.getType().getClassLoader();
        }
    }

    int[] getOperationMap(EJBInterfaceType type) throws 
ContainerNotFoundException {
        if (container == null) {
            locateContainer();
        }

        if (type == EJBInterfaceType.REMOTE) {
            return remoteMap;
        } else if (type == EJBInterfaceType.HOME) {
            return homeMap;
        } else if (type == EJBInterfaceType.LOCAL) {
            return localMap;
        } else if (type == EJBInterfaceType.LOCALHOME) {
            return localHomeMap;
        } else {
            throw new IllegalArgumentException("Unsupported interface type " + 
type);
        }
    }

    public int getMethodIndex(Method method) {
        Integer index = (Integer) legacyMethodMap.get(method);
        if (index == null) {
            index = new Integer(-1);
        }
        return index.intValue();
    }

    public Class getLocalInterfaceClass() {
        return localInterface;
    }

    public Class getRemoteInterfaceClass() {
        return remoteInterface;
    }

    /**
     * Return a proxy for the EJB's remote interface. This can be passed back
     * to any client that wishes to access the EJB (e.g. in response to a
     * call to SessionContext.getEJBObject() )
     * @return the proxy for this EJB's home interface
     */
    public EJBObject getEJBObject(Object primaryKey) {
        if (remoteFactory == null) {
            throw new IllegalStateException("getEJBObject is not allowed if no 
remote interface is defined");
        }
        EJBMethodInterceptor handler = new EJBMethodInterceptor(
                this,
                EJBInterfaceType.REMOTE,
                container,
                remoteMap,
                primaryKey);
        return (EJBObject) remoteFactory.create(handler);
    }

    /**
     * Return a proxy for the EJB's home interface. This can be passed back
     * to any client that wishes to access the EJB (e.g. in response to a
     * call to EJBContext.getEJBHome() )
     * @return the proxy for this EJB's home interface
     */
    public EJBHome getEJBHome() {
        if (homeFactory == null) {
            throw new IllegalStateException("getEJBHome is not allowed if no 
remote interface is defined");
        }
        EJBMethodInterceptor handler = new EJBMethodInterceptor(
                this,
                EJBInterfaceType.HOME,
                container,
                homeMap);
        return (EJBHome) homeFactory.create(handler);
    }

    /**
     * Return a proxy for the EJB's local interface. This can be passed back
     * to any client that wishes to access the EJB (e.g. in response to a
     * call to SessionContext.getEJBLocalObject() )
     * @return the proxy for this EJB's local interface
     */

    public EJBLocalObject getEJBLocalObject(Object primaryKey) {
        if (localFactory == null) {
            throw new IllegalStateException("getEJBLocalObject is not allowed 
if no local interface is defined");
        }
        EJBMethodInterceptor handler = new EJBMethodInterceptor(
                this,
                EJBInterfaceType.LOCAL,
                container,
                localMap,
                primaryKey);
        return (EJBLocalObject) localFactory.create(handler);
    }

    /**
     * Return a proxy for the EJB's local home interface. This can be
     * passed back to any client that wishes to access the EJB
     * (e.g. in response to a call to EJBContext.getEJBLocalHome() )
     * @return the proxy for this EJB's local home interface
     */

    public EJBLocalHome getEJBLocalHome() {
        if (localFactory == null) {
            throw new IllegalStateException("getEJBLocalHome is not allowed if 
no local interface is defined");
        }
        EJBMethodInterceptor handler = new EJBMethodInterceptor(
                this,
                EJBInterfaceType.LOCALHOME,
                container,
                localHomeMap);
        return (EJBLocalHome) localHomeFactory.create(handler);
    }

    private int[] createOperationsMap(CglibEJBProxyFactory factory, 
InterfaceMethodSignature[] signatures) {
        if (factory == null) return new int[0];
        return EJBProxyHelper.getOperationMap(factory.getType(), signatures, 
false);
    }

    private CglibEJBProxyFactory getFactory(int interfaceType, Class 
interfaceClass) {
        if (interfaceClass == null) {
            return null;
        }

        Class baseClass;
        if (isSessionBean) {
            baseClass = sessionBaseClasses[interfaceType];
        } else {
            baseClass = entityBaseClasses[interfaceType];
        }

        ClassLoader classLoader = findClassLoader(baseClass, interfaceClass);

        return new CglibEJBProxyFactory(baseClass, interfaceClass, classLoader);
    }

    private ClassLoader findClassLoader(Class baseClass, Class interfaceClass) {
        ClassLoader cl = interfaceClass.getClassLoader();
        try {
            cl.loadClass(baseClass.getName());
            return cl;
        } catch (ClassNotFoundException e) {

        }
        cl = baseClass.getClassLoader();
        try {
            cl.loadClass(interfaceClass.getName());
            return cl;
        } catch (ClassNotFoundException e) {
            throw new IllegalStateException("Openejb base class: " + 
baseClass.getName() + " and interface class: " + interfaceClass.getName() + " 
do not have a common classloader that will load both!");
        }
    }

    private static void addLegacyMethods(Map legacyMethodMap, Class clazz, 
InterfaceMethodSignature[] signatures) {
        if (clazz == null) {
            return;
        }

        for (int i = 0; i < signatures.length; i++) {
            InterfaceMethodSignature signature = signatures[i];
            Method method = signature.getMethod(clazz);
            if (method != null) {
                legacyMethodMap.put(method, new Integer(i));
            }
        }
    }

    private void locateContainer() throws ContainerNotFoundException {
        ContainerIndex containerIndex = ContainerIndex.getInstance();
        EJBContainer c = containerIndex.getContainer(containerId);
        if (c == null) {
            throw new IllegalStateException("Contianer not found: " + 
containerId);
        }
        setContainer(c);
    }

    private Object readResolve() {
        return new EJBProxyFactory(
                containerId,
                isSessionBean,
                remoteInterface,
                homeInterface,
                localInterface,
                localHomeInterface);
    }
}

  \ No newline at end of file
  +/**
 * Redistribution and use of this software and associated documentation
 * ("Software"), with or without modification, are permitted provided
 * that the following conditions are met:
 *
 * 1. Redistributions of source code must retain copyright
 *    statements and notices.  Redistributions must also contain a
 *    copy of this document.
 *
 * 2. Redistributions in binary form must reproduce the
 *    above copyright notice, this list of conditions and the
 *    following disclaimer in the documentation and/or other
 *    materials provided with the distribution.
 *
 * 3. The name "OpenEJB" must not be used to endorse or promote
 *    products derived from this Software without prior written
 *    permission of The OpenEJB Group.  For written permission,
 *    please contact [EMAIL PROTECTED]
 *
 * 4. Products derived from this Software may not be called "OpenEJB"
 *    nor may "OpenEJB" appear in their names without prior written
 *    permission of The OpenEJB Group. OpenEJB is a registered
 *    trademark of The OpenEJB Group.
 *
 * 5. Due credit should be given to the OpenEJB Project
 *    (http://openejb.org/).
 *
 * THIS SOFTWARE IS PROVIDED BY THE OPENEJB GROUP AND CONTRIBUTORS
 * ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT
 * NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
 * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL
 * THE OPENEJB GROUP OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
 * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
 * OF THE POSSIBILITY OF SUCH DAMAGE.
 *
 * Copyright 2001 (C) The OpenEJB Group. All Rights Reserved.
 *
 * $Id$
 */
package org.openejb.proxy;

import java.io.Serializable;
import java.lang.reflect.Method;
import java.util.Collections;
import java.util.HashMap;
import java.util.Map;
import javax.ejb.EJBHome;
import javax.ejb.EJBLocalHome;
import javax.ejb.EJBLocalObject;
import javax.ejb.EJBObject;

import org.openejb.DeploymentIndex;
import org.openejb.RpcEjbDeployment;
import org.openejb.EJBInterfaceType;
import org.openejb.DeploymentNotFoundException;
import org.openejb.dispatch.InterfaceMethodSignature;

public class EJBProxyFactory implements Serializable, 
org.tranql.ejb.EJBProxyFactory {
    private static final Class[] sessionBaseClasses =
            new Class[]{SessionEJBObject.class, SessionEJBHome.class, 
SessionEJBLocalObject.class, SessionEJBLocalHome.class};

    private static final Class[] entityBaseClasses =
            new Class[]{EntityEJBObject.class, EntityEJBHome.class, 
EntityEJBLocalObject.class, EntityEJBLocalHome.class};

    private final String containerId;
    private final boolean isSessionBean;
    private final Class remoteInterface;
    private final Class homeInterface;
    private final Class localInterface;
    private final Class localHomeInterface;

    private transient final CglibEJBProxyFactory remoteFactory;
    private transient final CglibEJBProxyFactory homeFactory;
    private transient final CglibEJBProxyFactory localFactory;
    private transient final CglibEJBProxyFactory localHomeFactory;

    private transient RpcEjbDeployment container;

    private transient int[] remoteMap;
    private transient int[] homeMap;
    private transient int[] localMap;
    private transient int[] localHomeMap;

    private transient Map legacyMethodMap;

    public EJBProxyFactory(RpcEjbDeployment container) {
        this(container.getProxyInfo());
        setContainer(container);
    }

    public EJBProxyFactory(ProxyInfo proxyInfo) {
        this(
                proxyInfo.getContainerID(),
                proxyInfo.isSessionBean(),
                proxyInfo.getRemoteInterface(),
                proxyInfo.getHomeInterface(),
                proxyInfo.getLocalInterface(),
                proxyInfo.getLocalHomeInterface());
    }

    public EJBProxyFactory(
            String containerId,
            boolean sessionBean,
            Class remoteInterface,
            Class homeInterface,
            Class localInterface,
            Class localHomeInterface) {
        this.containerId = containerId;
        isSessionBean = sessionBean;

// JNB: these are temporarily disabled due to classloader issues during 
deployment
//        assert remoteInterface == null || (remoteInterface.isInterface() && 
EJBObject.class.isAssignableFrom(remoteInterface));
        this.remoteInterface = remoteInterface;

//        assert homeInterface == null || (homeInterface.isInterface() && 
EJBHome.class.isAssignableFrom(homeInterface));
        this.homeInterface = homeInterface;

//        assert localInterface == null || (localInterface.isInterface() && 
EJBLocalObject.class.isAssignableFrom(localInterface));
        this.localInterface = localInterface;

//        assert localHomeInterface == null || 
(localHomeInterface.isInterface() && 
EJBLocalHome.class.isAssignableFrom(localHomeInterface));
        this.localHomeInterface = localHomeInterface;

        this.remoteFactory = getFactory(EJBInterfaceType.REMOTE.getOrdinal(), 
remoteInterface);
        this.homeFactory = getFactory(EJBInterfaceType.HOME.getOrdinal(), 
homeInterface);
        this.localFactory = getFactory(EJBInterfaceType.LOCAL.getOrdinal(), 
localInterface);
        this.localHomeFactory = 
getFactory(EJBInterfaceType.LOCALHOME.getOrdinal(), localHomeInterface);
    }

    public String getEJBName() {
        return container.getEjbName();
    }

    RpcEjbDeployment getContainer() throws DeploymentNotFoundException {
        if (container == null) {
            locateContainer();
        }
        return container;
    }

    private void setContainer(RpcEjbDeployment container) {
        assert container != null: "container is null";
        this.container = container;

        ProxyInfo proxyInfo = container.getProxyInfo();
        InterfaceMethodSignature[] signatures = container.getSignatures();

        // build the legacy map
        Map map = new HashMap();
        addLegacyMethods(map, proxyInfo.getRemoteInterface(), signatures);
        addLegacyMethods(map, proxyInfo.getHomeInterface(), signatures);
        addLegacyMethods(map, proxyInfo.getLocalInterface(), signatures);
        addLegacyMethods(map, proxyInfo.getLocalHomeInterface(), signatures);
        addLegacyMethods(map, proxyInfo.getServiceEndpointInterface(), 
signatures);
        legacyMethodMap = Collections.unmodifiableMap(map);

        remoteMap = createOperationsMap(remoteFactory, signatures);
        homeMap = createOperationsMap(homeFactory, signatures);

        localMap = createOperationsMap(localFactory, signatures);
        localHomeMap = createOperationsMap(localHomeFactory, signatures);
    }

    public ClassLoader getClassLoader() {
        if (remoteFactory != null) {
            return remoteFactory.getType().getClassLoader();
        } else {
            return localFactory.getType().getClassLoader();
        }
    }

    int[] getOperationMap(EJBInterfaceType type) throws 
DeploymentNotFoundException {
        if (container == null) {
            locateContainer();
        }

        if (type == EJBInterfaceType.REMOTE) {
            return remoteMap;
        } else if (type == EJBInterfaceType.HOME) {
            return homeMap;
        } else if (type == EJBInterfaceType.LOCAL) {
            return localMap;
        } else if (type == EJBInterfaceType.LOCALHOME) {
            return localHomeMap;
        } else {
            throw new IllegalArgumentException("Unsupported interface type " + 
type);
        }
    }

    public int getMethodIndex(Method method) {
        Integer index = (Integer) legacyMethodMap.get(method);
        if (index == null) {
            index = new Integer(-1);
        }
        return index.intValue();
    }

    public Class getLocalInterfaceClass() {
        return localInterface;
    }

    public Class getRemoteInterfaceClass() {
        return remoteInterface;
    }

    /**
     * Return a proxy for the EJB's remote interface. This can be passed back
     * to any client that wishes to access the EJB (e.g. in response to a
     * call to SessionContext.getEJBObject() )
     * @return the proxy for this EJB's home interface
     */
    public EJBObject getEJBObject(Object primaryKey) {
        if (remoteFactory == null) {
            throw new IllegalStateException("getEJBObject is not allowed if no 
remote interface is defined");
        }
        EJBMethodInterceptor handler = new EJBMethodInterceptor(
                this,
                EJBInterfaceType.REMOTE,
                container,
                remoteMap,
                primaryKey);
        return (EJBObject) remoteFactory.create(handler);
    }

    /**
     * Return a proxy for the EJB's home interface. This can be passed back
     * to any client that wishes to access the EJB (e.g. in response to a
     * call to EJBContext.getEJBHome() )
     * @return the proxy for this EJB's home interface
     */
    public EJBHome getEJBHome() {
        if (homeFactory == null) {
            throw new IllegalStateException("getEJBHome is not allowed if no 
remote interface is defined");
        }
        EJBMethodInterceptor handler = new EJBMethodInterceptor(
                this,
                EJBInterfaceType.HOME,
                container,
                homeMap);
        return (EJBHome) homeFactory.create(handler);
    }

    /**
     * Return a proxy for the EJB's local interface. This can be passed back
     * to any client that wishes to access the EJB (e.g. in response to a
     * call to SessionContext.getEJBLocalObject() )
     * @return the proxy for this EJB's local interface
     */

    public EJBLocalObject getEJBLocalObject(Object primaryKey) {
        if (localFactory == null) {
            throw new IllegalStateException("getEJBLocalObject is not allowed 
if no local interface is defined");
        }
        EJBMethodInterceptor handler = new EJBMethodInterceptor(
                this,
                EJBInterfaceType.LOCAL,
                container,
                localMap,
                primaryKey);
        return (EJBLocalObject) localFactory.create(handler);
    }

    /**
     * Return a proxy for the EJB's local home interface. This can be
     * passed back to any client that wishes to access the EJB
     * (e.g. in response to a call to EJBContext.getEJBLocalHome() )
     * @return the proxy for this EJB's local home interface
     */

    public EJBLocalHome getEJBLocalHome() {
        if (localFactory == null) {
            throw new IllegalStateException("getEJBLocalHome is not allowed if 
no local interface is defined");
        }
        EJBMethodInterceptor handler = new EJBMethodInterceptor(
                this,
                EJBInterfaceType.LOCALHOME,
                container,
                localHomeMap);
        return (EJBLocalHome) localHomeFactory.create(handler);
    }

    private int[] createOperationsMap(CglibEJBProxyFactory factory, 
InterfaceMethodSignature[] signatures) {
        if (factory == null) return new int[0];
        return EJBProxyHelper.getOperationMap(factory.getType(), signatures, 
false);
    }

    private CglibEJBProxyFactory getFactory(int interfaceType, Class 
interfaceClass) {
        if (interfaceClass == null) {
            return null;
        }

        Class baseClass;
        if (isSessionBean) {
            baseClass = sessionBaseClasses[interfaceType];
        } else {
            baseClass = entityBaseClasses[interfaceType];
        }

        ClassLoader classLoader = findClassLoader(baseClass, interfaceClass);

        return new CglibEJBProxyFactory(baseClass, interfaceClass, classLoader);
    }

    private ClassLoader findClassLoader(Class baseClass, Class interfaceClass) {
        ClassLoader cl = interfaceClass.getClassLoader();
        try {
            cl.loadClass(baseClass.getName());
            return cl;
        } catch (ClassNotFoundException e) {

        }
        cl = baseClass.getClassLoader();
        try {
            cl.loadClass(interfaceClass.getName());
            return cl;
        } catch (ClassNotFoundException e) {
            throw new IllegalStateException("Openejb base class: " + 
baseClass.getName() + " and interface class: " + interfaceClass.getName() + " 
do not have a common classloader that will load both!");
        }
    }

    private static void addLegacyMethods(Map legacyMethodMap, Class clazz, 
InterfaceMethodSignature[] signatures) {
        if (clazz == null) {
            return;
        }

        for (int i = 0; i < signatures.length; i++) {
            InterfaceMethodSignature signature = signatures[i];
            Method method = signature.getMethod(clazz);
            if (method != null) {
                legacyMethodMap.put(method, new Integer(i));
            }
        }
    }

    private void locateContainer() throws DeploymentNotFoundException {
        DeploymentIndex deploymentIndex = DeploymentIndex.getInstance();
        RpcEjbDeployment c = deploymentIndex.getDeployment(containerId);
        if (c == null) {
            throw new IllegalStateException("Contianer not found: " + 
containerId);
        }
        setContainer(c);
    }

    private Object readResolve() {
        return new EJBProxyFactory(
                containerId,
                isSessionBean,
                remoteInterface,
                homeInterface,
                localInterface,
                localHomeInterface);
    }
}

  \ No newline at end of file
  
  
  
  1.8       +11 -11    
openejb/modules/core/src/java/org/openejb/proxy/ProxyInfo.java
  
  Index: ProxyInfo.java
  ===================================================================
  RCS file: 
/home/projects/openejb/scm/openejb/modules/core/src/java/org/openejb/proxy/ProxyInfo.java,v
  retrieving revision 1.7
  retrieving revision 1.8
  diff -u -r1.7 -r1.8
  --- ProxyInfo.java    13 Jan 2005 17:00:23 -0000      1.7
  +++ ProxyInfo.java    1 Feb 2006 11:50:08 -0000       1.8
  @@ -50,18 +50,18 @@
   
   
   public class ProxyInfo implements Serializable {
  -    
  +    private static final long serialVersionUID = 569021597222976175L;
       private final int componentType;
       private final String containerId;
       private final Object primaryKey;
  -    
  +
       private final Class remoteInterface;
       private final Class homeInterface;
  -    private final Class localObjectInterface;
       private final Class localHomeInterface;
  +    private final Class localInterface;
       private final Class serviceEndpointInterface;
       private final Class primaryKeyClass;
  -    
  +
   
       public ProxyInfo(ProxyInfo info, Object primaryKey) {
           this.componentType = info.componentType;
  @@ -69,7 +69,7 @@
           this.homeInterface = info.homeInterface;
           this.remoteInterface = info.remoteInterface;
           this.localHomeInterface = info.localHomeInterface;
  -        this.localObjectInterface = info.localObjectInterface;
  +        this.localInterface = info.localInterface;
           this.serviceEndpointInterface = info.serviceEndpointInterface;
           this.primaryKeyClass = info.primaryKeyClass;
           this.primaryKey = primaryKey;
  @@ -81,7 +81,7 @@
               Class homeInterface,
               Class remoteInterface,
               Class localHomeInterface,
  -            Class localObjectInterface,
  +            Class localInterface,
               Class serviceEndpointInterface,
               Class primaryKeyClass) {
   
  @@ -90,7 +90,7 @@
           this.homeInterface = homeInterface;
           this.remoteInterface = remoteInterface;
           this.localHomeInterface = localHomeInterface;
  -        this.localObjectInterface = localObjectInterface;
  +        this.localInterface = localInterface;
           this.serviceEndpointInterface = serviceEndpointInterface;
           this.primaryKeyClass = primaryKeyClass;
           this.primaryKey = null;
  @@ -131,17 +131,17 @@
       public Class getHomeInterface() {
           return homeInterface;
       }
  -    
  +
       public Class getRemoteInterface() {
           return remoteInterface;
       }
  -    
  +
       public Class getLocalHomeInterface() {
           return localHomeInterface;
       }
   
       public Class getLocalInterface() {
  -        return localObjectInterface;
  +        return localInterface;
       }
   
       public Class getServiceEndpointInterface() {
  
  
  
  1.3       +3 -2      
openejb/modules/core/src/java/org/openejb/proxy/ProxyMemento.java
  
  Index: ProxyMemento.java
  ===================================================================
  RCS file: 
/home/projects/openejb/scm/openejb/modules/core/src/java/org/openejb/proxy/ProxyMemento.java,v
  retrieving revision 1.2
  retrieving revision 1.3
  diff -u -r1.2 -r1.3
  --- ProxyMemento.java 21 Dec 2005 14:21:53 -0000      1.2
  +++ ProxyMemento.java 1 Feb 2006 11:50:08 -0000       1.3
  @@ -51,6 +51,7 @@
   import java.rmi.RemoteException;
   
   import org.apache.geronimo.kernel.ClassLoading;
  +import org.apache.geronimo.kernel.ClassLoading;
   import org.openejb.EJBComponentType;
   
   /**
  
  
  
  1.3       +3 -3      
openejb/modules/core/src/java/org/openejb/proxy/SessionEJBHome.java
  
  Index: SessionEJBHome.java
  ===================================================================
  RCS file: 
/home/projects/openejb/scm/openejb/modules/core/src/java/org/openejb/proxy/SessionEJBHome.java,v
  retrieving revision 1.2
  retrieving revision 1.3
  diff -u -r1.2 -r1.3
  --- SessionEJBHome.java       9 Feb 2005 02:07:56 -0000       1.2
  +++ SessionEJBHome.java       1 Feb 2006 11:50:08 -0000       1.3
  @@ -51,7 +51,7 @@
   import javax.ejb.Handle;

   import javax.ejb.RemoveException;

   

  -import org.openejb.ContainerNotFoundException;

  +import org.openejb.DeploymentNotFoundException;

   

   

   /**

  @@ -71,7 +71,7 @@
               ProxyInfo proxyInfo = null;

               try {

                   proxyInfo = ejbHandler.getProxyInfo();

  -            } catch (ContainerNotFoundException e) {

  +            } catch (DeploymentNotFoundException e) {

                   throw new NoSuchObjectException(e.getMessage());

               }

               Class remoteInterface = proxyInfo.getRemoteInterface();

  
  
  

Reply via email to