User: mnf999 Date: 01/12/18 21:17:07 Modified: src/main/org/jboss/ejb EntityContainer.java Log: moved to detached invokers, MBean dynamic invocation and use of "invocation" throughout the chain Revision Changes Path 1.60 +362 -327 jboss/src/main/org/jboss/ejb/EntityContainer.java Index: EntityContainer.java =================================================================== RCS file: /cvsroot/jboss/jboss/src/main/org/jboss/ejb/EntityContainer.java,v retrieving revision 1.59 retrieving revision 1.60 diff -u -r1.59 -r1.60 --- EntityContainer.java 2001/12/03 23:00:16 1.59 +++ EntityContainer.java 2001/12/19 05:17:07 1.60 @@ -1,9 +1,9 @@ /* - * JBoss, the OpenSource J2EE webOS - * - * Distributable under LGPL license. - * See terms of license at gnu.org. - */ +* JBoss, the OpenSource J2EE webOS +* +* Distributable under LGPL license. +* See terms of license at gnu.org. +*/ package org.jboss.ejb; import java.lang.reflect.Method; @@ -26,108 +26,111 @@ import javax.transaction.Transaction; import org.jboss.deployment.DeploymentException; +import org.jboss.invocation.Invocation; +import org.jboss.invocation.MarshalledInvocation; import org.jboss.monitor.StatisticsProvider; import org.jboss.util.SerializableEnumeration; +import org.jboss.system.Registry; /** - * This is a Container for EntityBeans (both BMP and CMP). - * - * @see Container - * @see EntityEnterpriseContext - * - * @author <a href="mailto:[EMAIL PROTECTED]">Rickard Öberg</a> - * @author <a href="mailto:[EMAIL PROTECTED]">Marc Fleury</a> - * @author <a href="mailto:[EMAIL PROTECTED]">Sebastien Alborini</a> - * @author <a href="mailto:[EMAIL PROTECTED]">Daniel OConnor</a> - * @author <a href="[EMAIL PROTECTED]">Bill Burke</a> - * @author <a href="mailto:[EMAIL PROTECTED]">Andreas Schaefer</a> - * @version $Revision: 1.59 $ - * - * <p><b>Revisions:</b> - * - * <p><b>20010701 marc fleury:</b> - * <ul> - * <li>Transaction to context wiring was moved to the instance interceptor - * </ul> - * <p><b>20010718 andreas schaefer:</b> - * <ul> - * <li>- Added statistics gathering - * </ul> - * <p><b>20010807 bill burke:</b> - * <ul> - * <li> Moved storeEntity from EntitySynchronization to here so other classes can use it. - * <li> Moved synchronizeEntitiesWithinTransaction to here from Application as a static method. - * </ul> - */ +* This is a Container for EntityBeans (both BMP and CMP). +* +* @see Container +* @see EntityEnterpriseContext +* +* @author <a href="mailto:[EMAIL PROTECTED]">Rickard Öberg</a> +* @author <a href="mailto:[EMAIL PROTECTED]">Marc Fleury</a> +* @author <a href="mailto:[EMAIL PROTECTED]">Sebastien Alborini</a> +* @author <a href="mailto:[EMAIL PROTECTED]">Daniel OConnor</a> +* @author <a href="[EMAIL PROTECTED]">Bill Burke</a> +* @author <a href="mailto:[EMAIL PROTECTED]">Andreas Schaefer</a> +* @version $Revision: 1.60 $ +* +* <p><b>Revisions:</b> +* +* <p><b>20010701 marc fleury:</b> +* <ul> +* <li>Transaction to context wiring was moved to the instance interceptor +* </ul> +* <p><b>20010718 andreas schaefer:</b> +* <ul> +* <li>- Added statistics gathering +* </ul> +* <p><b>20010807 bill burke:</b> +* <ul> +* <li> Moved storeEntity from EntitySynchronization to here so other classes can use it. +* <li> Moved synchronizeEntitiesWithinTransaction to here from Application as a static method. +* </ul> + +* <p><b>20011219 marc fleury:</b> +* <ul> +* <li> Moved to new invoker scheme, using Invocation and MBean invokers. +* </ul> +*/ public class EntityContainer - extends Container - implements ContainerInvokerContainer, InstancePoolContainer, StatisticsProvider +extends Container +implements ContainerInvokerContainer, InstancePoolContainer, StatisticsProvider { // Constants ----------------------------------------------------- - + // Attributes ---------------------------------------------------- - - /** This is the Home interface class. */ - protected Class homeInterface; - - /** This is the Remote interface class. */ - protected Class remoteInterface; - + /** - * These are the mappings between the home interface methods and the - * container methods. - */ + * These are the mappings between the home interface methods and the + * container methods. + */ protected Map homeMapping; - + /** - * These are the mappings between the remote interface methods and the - * bean methods. - */ + * These are the mappings between the remote interface methods and the + * bean methods. + */ protected Map beanMapping; - + + /** This is the container invoker for this container */ protected ContainerInvoker containerInvoker; - + /** This is the persistence manager for this container */ protected EntityPersistenceManager persistenceManager; - + /** This is the instance cache for this container */ protected InstanceCache instanceCache; - + /** This is the instancepool that is to be used */ protected InstancePool instancePool; - + protected TxEntityMap txEntityMap = new TxEntityMap(); - + /** - * This is the first interceptor in the chain. The last interceptor must - * be provided by the container itself. - */ + * This is the first interceptor in the chain. The last interceptor must + * be provided by the container itself. + */ protected Interceptor interceptor; - + // These members contains statistics variable protected long createCount = 0; protected long removeCount = 0; - + /** - * This provides a way to find the entities that are part of a given - * transaction EntitySynchronizationInterceptor and InstanceSynchronization - * manage this instance. - */ + * This provides a way to find the entities that are part of a given + * transaction EntitySynchronizationInterceptor and InstanceSynchronization + * manage this instance. + */ protected static GlobalTxEntityMap globalTxEntityMap = new GlobalTxEntityMap(); - - + + public static GlobalTxEntityMap getGlobalTxEntityMap() { return globalTxEntityMap; } - + /** - * Stores all of the entities associated with the specified transaction. - * As per the spec 9.6.4, entities must be synchronized with the datastore - * when an ejbFind<METHOD> is called. - * Also, all entities within entire transaction should be synchronized before - * a remove, otherwise there may be problems with 'cascade delete'. - * @param tx the transaction that associated entites will be stored - * @throws Exception if an problem occures while storing the entities - */ + * Stores all of the entities associated with the specified transaction. + * As per the spec 9.6.4, entities must be synchronized with the datastore + * when an ejbFind<METHOD> is called. + * Also, all entities within entire transaction should be synchronized before + * a remove, otherwise there may be problems with 'cascade delete'. + * @param tx the transaction that associated entites will be stored + * @throws Exception if an problem occures while storing the entities + */ public static void synchronizeEntitiesWithinTransaction(Transaction tx) { // If there is no transaction, there is nothing to synchronize. @@ -149,75 +152,75 @@ throw new EJBException(ex); } } - + // Public -------------------------------------------------------- - + public void setContainerInvoker(ContainerInvoker ci) { if (ci == null) throw new IllegalArgumentException("Null invoker"); - + this.containerInvoker = ci; ci.setContainer(this); } - + public ContainerInvoker getContainerInvoker() { return containerInvoker; } - + public LocalContainerInvoker getLocalContainerInvoker() { return localContainerInvoker; } - + public void setInstancePool(InstancePool ip) { if (ip == null) throw new IllegalArgumentException("Null pool"); - + this.instancePool = ip; ip.setContainer(this); } - + public InstancePool getInstancePool() { return instancePool; } - + public TxEntityMap getTxEntityMap() { return txEntityMap; } - + public void setInstanceCache(InstanceCache ic) { if (ic == null) throw new IllegalArgumentException("Null cache"); - + this.instanceCache = ic; ic.setContainer(this); } - + public InstanceCache getInstanceCache() { return instanceCache; } - + public EntityPersistenceManager getPersistenceManager() { return persistenceManager; } - + public void setPersistenceManager(EntityPersistenceManager pm) { if (pm == null) throw new IllegalArgumentException("Null persistence manager"); - + persistenceManager = pm; pm.setContainer(this); } - + public void addInterceptor(Interceptor in) { if (interceptor == null) @@ -226,117 +229,120 @@ } else { - + Interceptor current = interceptor; while ( current.getNext() != null) { current = current.getNext(); } - + current.setNext(in); } } - + public Interceptor getInterceptor() { return interceptor; } - + public Class getHomeClass() { return homeInterface; } - + public Class getRemoteClass() { return remoteInterface; } - + /** - * Returns a new instance of the bean class or a subclass of the bean class. - * If this is 1.x cmp, simply return a new instance of the bean class. - * If this is 2.x cmp, return a subclass that provides an implementation - * of the abstract accessors. - * - * @see java.lang.Class#newInstance - * - * @return The new instance. - */ + * Returns a new instance of the bean class or a subclass of the bean class. + * If this is 1.x cmp, simply return a new instance of the bean class. + * If this is 2.x cmp, return a subclass that provides an implementation + * of the abstract accessors. + * + * @see java.lang.Class#newInstance + * + * @return The new instance. + */ public Object createBeanClassInstance() throws Exception { return persistenceManager.createBeanClassInstance(); } - + // Container implementation -------------------------------------- - - public void init() throws Exception + + public void create() throws Exception { // Associate thread with classloader ClassLoader oldCl = Thread.currentThread().getContextClassLoader(); Thread.currentThread().setContextClassLoader(getClassLoader()); - + // Acquire classes from CL if (metaData.getHome() != null) homeInterface = classLoader.loadClass(metaData.getHome()); if (metaData.getRemote() != null) remoteInterface = classLoader.loadClass(metaData.getRemote()); - + // Call default init - super.init(); - + super.create(); + // Map the bean methods setupBeanMapping(); - + // Map the home methods setupHomeMapping(); - + + // Map the interfaces to Long + setupMarshalledInvocationMapping(); + // Initialize pool - instancePool.init(); - + instancePool.create(); + // Init container invoker if (containerInvoker != null) - containerInvoker.init(); - + containerInvoker.create(); + // Init instance cache - instanceCache.init(); - + instanceCache.create(); + // Init persistence - persistenceManager.init(); - + persistenceManager.create(); + // Initialize the interceptor by calling the chain Interceptor in = interceptor; while (in != null) { in.setContainer(this); - in.init(); + in.create(); in = in.getNext(); } - + // Reset classloader Thread.currentThread().setContextClassLoader(oldCl); } - + public void start() throws Exception { // Associate thread with classloader ClassLoader oldCl = Thread.currentThread().getContextClassLoader(); Thread.currentThread().setContextClassLoader(getClassLoader()); - + // Call default start super.start(); - + // Start container invoker if (containerInvoker != null) containerInvoker.start(); - + // Start instance cache instanceCache.start(); - + // Start persistence persistenceManager.start(); - + // Start the instance pool instancePool.start(); - + // Start all interceptors in the chain Interceptor in = interceptor; while (in != null) @@ -344,33 +350,33 @@ in.start(); in = in.getNext(); } - + // Reset classloader Thread.currentThread().setContextClassLoader(oldCl); } - + public void stop() { // Associate thread with classloader ClassLoader oldCl = Thread.currentThread().getContextClassLoader(); Thread.currentThread().setContextClassLoader(getClassLoader()); - + // Call default stop super.stop(); - + // Stop container invoker if (containerInvoker != null) containerInvoker.stop(); - + // Stop instance cache instanceCache.stop(); - + // Stop persistence persistenceManager.stop(); - + // Stop the instance pool instancePool.stop(); - + // Stop all interceptors in the chain Interceptor in = interceptor; while (in != null) @@ -378,33 +384,33 @@ in.stop(); in = in.getNext(); } - + // Reset classloader Thread.currentThread().setContextClassLoader(oldCl); } - + public void destroy() { // Associate thread with classloader ClassLoader oldCl = Thread.currentThread().getContextClassLoader(); Thread.currentThread().setContextClassLoader(getClassLoader()); - + // Call default destroy super.destroy(); - + // Destroy container invoker if (containerInvoker != null) containerInvoker.destroy(); - + // Destroy instance cache instanceCache.destroy(); - + // Destroy persistence persistenceManager.destroy(); - + // Destroy the pool instancePool.destroy(); - + // Destroy all the interceptors in the chain Interceptor in = interceptor; while (in != null) @@ -412,131 +418,132 @@ in.destroy(); in = in.getNext(); } - + // Reset classloader Thread.currentThread().setContextClassLoader(oldCl); } - - public Object invokeHome(MethodInvocation mi) throws Exception + + public Object invokeHome(Invocation mi) throws Exception { + return getInterceptor().invokeHome(mi); } - - public Object invoke(MethodInvocation mi) throws Exception + + public Object invoke(Invocation mi) throws Exception { // Invoke through interceptors return getInterceptor().invoke(mi); } - + // EJBObject implementation -------------------------------------- - - public void remove(MethodInvocation mi) - throws RemoteException, RemoveException + + public void remove(Invocation mi) + throws RemoteException, RemoveException { // synchronize entities with the datastore before the bean is removed // this will write queued updates so datastore will be consistent before removal synchronizeEntitiesWithinTransaction(mi.getTransaction()); - + // Get the persistence manager to do the dirty work getPersistenceManager().removeEntity((EntityEnterpriseContext)mi.getEnterpriseContext()); - + // We signify "removed" with a null id // There is no need to synchronize on the context since all the threads reaching here have // gone through the InstanceInterceptor so the instance is locked and we only have one thread // the case of reentrant threads is unclear (would you want to delete an instance in reentrancy) - mi.getEnterpriseContext().setId(null); + ((EnterpriseContext) mi.getEnterpriseContext()).setId(null); removeCount++; } - + /** - * @throws Error Not yet implemented. - */ - public Handle getHandle(MethodInvocation mi) - throws RemoteException + * @throws Error Not yet implemented. + */ + public Handle getHandle(Invocation mi) + throws RemoteException { // TODO throw new Error("Not yet implemented"); } - + /** - * @throws Error Not yet implemented. - */ - public Object getPrimaryKey(MethodInvocation mi) - throws RemoteException + * @throws Error Not yet implemented. + */ + public Object getPrimaryKey(Invocation mi) + throws RemoteException { // TODO throw new Error("Not yet implemented"); } - + /** - * @throws IllegalStateException If container invoker is null. - */ - public EJBHome getEJBHome(MethodInvocation mi) - throws RemoteException + * @throws IllegalStateException If container invoker is null. + */ + public EJBHome getEJBHome(Invocation mi) + throws RemoteException { if (containerInvoker == null) { throw new IllegalStateException(); } - return containerInvoker.getEJBHome(); + return (EJBHome) containerInvoker.getEJBHome(); } - - public boolean isIdentical(MethodInvocation mi) - throws RemoteException + + public boolean isIdentical(Invocation mi) + throws RemoteException { - return ((EJBObject)mi.getArguments()[0]).getPrimaryKey().equals(mi.getEnterpriseContext().getId()); + return ((EJBObject)mi.getArguments()[0]).getPrimaryKey().equals(((EnterpriseContext) mi.getEnterpriseContext()).getId()); // TODO - should also check type } - + /** - * MF FIXME these are implemented on the client - */ - public EJBLocalHome getEJBLocalHome(MethodInvocation mi) + * MF FIXME these are implemented on the client + */ + public EJBLocalHome getEJBLocalHome(Invocation mi) { return localContainerInvoker.getEJBLocalHome(); } - + /** - * @throws Error Not yet implemented. - */ - public void removeLocalHome(MethodInvocation mi) - throws RemoteException, RemoveException + * @throws Error Not yet implemented. + */ + public void removeLocalHome(Invocation mi) + throws RemoteException, RemoveException { throw new Error("Not Yet Implemented"); } - + /** - * Local home interface implementation - */ - public EJBLocalObject createLocalHome(MethodInvocation mi) - throws Exception + * Local home interface implementation + */ + public EJBLocalObject createLocalHome(Invocation mi) + throws Exception { // The persistence manager takes care of the wiring and creating the EJBLocalObject getPersistenceManager().createEntity(mi.getMethod(),mi.getArguments(), - (EntityEnterpriseContext) mi.getEnterpriseContext()); - + (EntityEnterpriseContext) mi.getEnterpriseContext()); + // The context implicitely carries the EJBObject createCount++; return ((EntityEnterpriseContext)mi.getEnterpriseContext()).getEJBLocalObject(); } - - public Object findLocal(MethodInvocation mi) - throws Exception + + public Object findLocal(Invocation mi) + throws Exception { /** - * As per the spec 9.6.4, entities must be synchronized with the datastore - * when an ejbFind<METHOD> is called. - */ + * As per the spec 9.6.4, entities must be synchronized with the datastore + * when an ejbFind<METHOD> is called. + */ synchronizeEntitiesWithinTransaction(mi.getTransaction()); - + // Multi-finder? if (!mi.getMethod().getReturnType().equals(getLocalClass())) { // Iterator finder Collection c = getPersistenceManager().findEntities(mi.getMethod(), mi.getArguments(), (EntityEnterpriseContext)mi.getEnterpriseContext()); - + // Get the EJBObjects with that Collection ec = localContainerInvoker.getEntityLocalCollection(c); - + // BMP entity finder methods are allowed to return java.util.Enumeration. try { if (mi.getMethod().getReturnType().equals(Class.forName("java.util.Enumeration"))) @@ -557,38 +564,38 @@ { // Single entity finder Object id = getPersistenceManager().findEntity(mi.getMethod(), - mi.getArguments(), - (EntityEnterpriseContext)mi.getEnterpriseContext()); - + mi.getArguments(), + (EntityEnterpriseContext)mi.getEnterpriseContext()); + //create the EJBObject return (EJBLocalObject)localContainerInvoker.getEntityEJBLocalObject(id); } } - + // Home interface implementation --------------------------------- - + /** - * This methods finds the target instances by delegating to the persistence - * manager It then manufactures EJBObject for all the involved instances - * found. - */ - public Object find(MethodInvocation mi) throws Exception + * This methods finds the target instances by delegating to the persistence + * manager It then manufactures EJBObject for all the involved instances + * found. + */ + public Object find(Invocation mi) throws Exception { /** - * As per the spec 9.6.4, entities must be synchronized with the datastore - * when an ejbFind<METHOD> is called. - */ + * As per the spec 9.6.4, entities must be synchronized with the datastore + * when an ejbFind<METHOD> is called. + */ synchronizeEntitiesWithinTransaction(mi.getTransaction()); - + // Multi-finder? if (!mi.getMethod().getReturnType().equals(getRemoteClass())) { // Iterator finder Collection c = getPersistenceManager().findEntities(mi.getMethod(), mi.getArguments(), (EntityEnterpriseContext)mi.getEnterpriseContext()); - + // Get the EJBObjects with that Collection ec = containerInvoker.getEntityCollection(c); - + // BMP entity finder methods are allowed to return java.util.Enumeration. // We need a serializable Enumeration, so we can't use Collections.enumeration() try { @@ -610,18 +617,18 @@ { // Single entity finder Object id = getPersistenceManager().findEntity(mi.getMethod(), - mi.getArguments(), - (EntityEnterpriseContext)mi.getEnterpriseContext()); - + mi.getArguments(), + (EntityEnterpriseContext)mi.getEnterpriseContext()); + //create the EJBObject return (EJBObject)containerInvoker.getEntityEJBObject(id); } } - - + + /** - * store entity - */ + * store entity + */ public void storeEntity(EntityEnterpriseContext ctx) throws Exception { if (ctx.getId() != null) @@ -631,82 +638,82 @@ } } } - + /** - * This method takes care of the wiring of the "EJBObject" trio - * (target, context, proxy). It delegates to the persistence manager. - */ - public EJBObject createHome(MethodInvocation mi) - throws Exception + * This method takes care of the wiring of the "EJBObject" trio + * (target, context, proxy). It delegates to the persistence manager. + */ + public EJBObject createHome(Invocation mi) + throws Exception { // The persistence manager takes care of the wiring and creating the EJBObject getPersistenceManager().createEntity(mi.getMethod(),mi.getArguments(), - (EntityEnterpriseContext) mi.getEnterpriseContext()); - + (EntityEnterpriseContext) mi.getEnterpriseContext()); + // The context implicitely carries the EJBObject createCount++; return ((EntityEnterpriseContext)mi.getEnterpriseContext()).getEJBObject(); } - + /** - * A method for the getEJBObject from the handle - */ - public EJBObject getEJBObject(MethodInvocation mi) - throws RemoteException + * A method for the getEJBObject from the handle + */ + public EJBObject getEJBObject(Invocation mi) + throws RemoteException { // All we need is an EJBObject for this Id; return (EJBObject)containerInvoker.getEntityEJBObject(((EntityCache) instanceCache).createCacheKey(mi.getId())); } - + // EJBHome implementation ---------------------------------------- - + /** - * @throws Error Not yet implemented. - */ - public void removeHome(MethodInvocation mi) - throws RemoteException, RemoveException + * @throws Error Not yet implemented. + */ + public void removeHome(Invocation mi) + throws RemoteException, RemoveException { throw new Error("Not yet implemented"); } - - public EJBMetaData getEJBMetaDataHome(MethodInvocation mi) - throws RemoteException + + public EJBMetaData getEJBMetaDataHome(Invocation mi) + throws RemoteException { return getContainerInvoker().getEJBMetaData(); } - + /** - * @throws Error Not yet implemented. - */ - public HomeHandle getHomeHandleHome(MethodInvocation mi) - throws RemoteException + * @throws Error Not yet implemented. + */ + public HomeHandle getHomeHandleHome(Invocation mi) + throws RemoteException { // TODO throw new Error("Not yet implemented"); } - - // StatisticsProvider implementation ------------------------------------ - public Map retrieveStatistic() - { - // Loop through all Interceptors and add statistics - Map lStatistics = new HashMap(); - StatisticsProvider lProvider = (StatisticsProvider) getPersistenceManager(); - lStatistics.putAll( lProvider.retrieveStatistic() ); - lProvider = (StatisticsProvider) getInstancePool(); - lStatistics.putAll( lProvider.retrieveStatistic() ); - return lStatistics; - } - public void resetStatistic() - { - } - + + // StatisticsProvider implementation ------------------------------------ + public Map retrieveStatistic() + { + // Loop through all Interceptors and add statistics + Map lStatistics = new HashMap(); + StatisticsProvider lProvider = (StatisticsProvider) getPersistenceManager(); + lStatistics.putAll( lProvider.retrieveStatistic() ); + lProvider = (StatisticsProvider) getInstancePool(); + lStatistics.putAll( lProvider.retrieveStatistic() ); + return lStatistics; + } + public void resetStatistic() + { + } + // Private ------------------------------------------------------- - + private void setupHomeMappingImpl( Map map, - Method[] m, - String finderName, - String append ) - throws DeploymentException + Method[] m, + String finderName, + String append ) + throws DeploymentException { for (int i = 0; i < m.length; i++) { @@ -716,20 +723,20 @@ { String methodName = "ejbHome" + Character.toUpperCase(m[i].getName().charAt(0)) + m[i].getName().substring(1); map.put(m[i], beanClass.getMethod(methodName, m[i].getParameterTypes())); - + continue; } catch (NoSuchMethodException e) { // Ignore - just go on with other types of methods } - + // Implemented by container (in both cases) if (m[i].getName().startsWith("find")) { - map.put(m[i], this.getClass().getMethod(finderName, new Class[] { MethodInvocation.class })); + map.put(m[i], this.getClass().getMethod(finderName, new Class[] { Invocation.class })); }else { - map.put(m[i], this.getClass().getMethod(m[i].getName()+append, new Class[] { MethodInvocation.class })); + map.put(m[i], this.getClass().getMethod(m[i].getName()+append, new Class[] { Invocation.class })); } } catch (NoSuchMethodException e) { @@ -737,12 +744,12 @@ } } } - + protected void setupHomeMapping() - throws DeploymentException + throws DeploymentException { Map map = new HashMap(); - + if (homeInterface != null) { Method[] m = homeInterface.getMethods(); @@ -753,32 +760,32 @@ Method[] m = localHomeInterface.getMethods(); setupHomeMappingImpl( map, m, "findLocal", "LocalHome" ); } - + // Special methods - + try { - + // Get the One on Handle (getEJBObject), get the class Class handleClass = Class.forName("javax.ejb.Handle"); - + // Get the methods (there is only one) Method[] handleMethods = handleClass.getMethods(); - + //Just to make sure let's iterate for (int j=0; j<handleMethods.length ;j++) { - + try { - + //Get only the one called handle.getEJBObject if (handleMethods[j].getName().equals("getEJBObject")) { - + //Map it in the home stuff map.put(handleMethods[j], this.getClass().getMethod("getEJBObject", new Class[] - {MethodInvocation.class - })); + {Invocation.class + })); } } catch (NoSuchMethodException e) @@ -791,13 +798,13 @@ { // DEBUG Logger.exception(e); } - + // We are done keep the home map homeMapping = map; } - + private void setupBeanMappingImpl( Map map, Method[] m, String intfName ) - throws DeploymentException + throws DeploymentException { for (int i = 0; i < m.length; i++) { @@ -812,8 +819,8 @@ { // Implemented by container map.put(m[i], getClass().getMethod(m[i].getName(), new Class[] - { MethodInvocation.class - })); + { Invocation.class + })); } } catch (NoSuchMethodException e) { @@ -821,12 +828,12 @@ } } } - + protected void setupBeanMapping() - throws DeploymentException + throws DeploymentException { Map map = new HashMap(); - + if (remoteInterface != null) { Method[] m = remoteInterface.getMethods(); @@ -837,58 +844,86 @@ Method[] m = localInterface.getMethods(); setupBeanMappingImpl( map, m, "javax.ejb.EJBLocalObject" ); } - + beanMapping = map; - + } - + + protected void setupMarshalledInvocationMapping() + { + try + {// Create method mappings for container invoker + Method [] m = homeInterface.getMethods(); + for (int i = 0 ; i<m.length ; i++) + { + marshalledInvocationMapping.put( new Long(MarshalledInvocation.calculateHash(m[i])), m[i]); + } + m = remoteInterface.getMethods(); + for (int j = 0 ; j<m.length ; j++) + { + marshalledInvocationMapping.put( new Long(MarshalledInvocation.calculateHash(m[j])), m[j]); + } + + // Get the getEJBObjectMethod + Method getEJBObjectMethod = Class.forName("javax.ejb.Handle").getMethod("getEJBObject", new Class[0]); + + // Hash it + marshalledInvocationMapping.put(new Long(MarshalledInvocation.calculateHash(getEJBObjectMethod)),getEJBObjectMethod); + } + catch (Exception e) + { + e.printStackTrace(); + log.error("getEJBObject failed", e); + } + } + Interceptor createContainerInterceptor() { return new ContainerInterceptor(); } - + // Inner classes ------------------------------------------------- - + // This is the last step before invocation - all interceptors are done - + class ContainerInterceptor - implements Interceptor + implements Interceptor { public void setContainer(Container con) { } - + public void setNext(Interceptor interceptor) { } - + public Interceptor getNext() { return null; } - - public void init() + + public void create() { } - + public void start() { } - + public void stop() { } - + public void destroy() { } - - public Object invokeHome(MethodInvocation mi) - throws Exception + + public Object invokeHome(Invocation mi) + throws Exception { // Invoke and handle exceptions Method m = (Method)homeMapping.get(mi.getMethod()); - + if (m.getDeclaringClass().equals(EntityContainer.class)) { try @@ -914,7 +949,7 @@ { try { - return m.invoke(mi.getEnterpriseContext().getInstance(), mi.getArguments()); + return m.invoke(((EnterpriseContext) mi.getEnterpriseContext()).getInstance(), mi.getArguments()); } catch (IllegalAccessException e) { // Throw this as a bean exception...(?) @@ -933,13 +968,13 @@ } } } - - public Object invoke(MethodInvocation mi) - throws Exception + + public Object invoke(Invocation mi) + throws Exception { // Get method Method m = (Method)beanMapping.get(mi.getMethod()); - + // Select instance to invoke (container or bean) if (m.getDeclaringClass().equals(EntityContainer.class)) { @@ -969,7 +1004,7 @@ // Invoke and handle exceptions try { - return m.invoke(mi.getEnterpriseContext().getInstance(), mi.getArguments()); + return m.invoke(((EnterpriseContext) mi.getEnterpriseContext()).getInstance(), mi.getArguments()); } catch (IllegalAccessException e) { // Throw this as a bean exception...(?)
_______________________________________________ Jboss-development mailing list [EMAIL PROTECTED] https://lists.sourceforge.net/lists/listinfo/jboss-development