User: docodan 
  Date: 01/06/03 09:28:48

  Added:       src/main/org/jboss/ejb/plugins/local
                        BaseLocalContainerInvoker.java LocalProxy.java
  Log:
  Some basic work towards local interfaces; not yet finished or hooked up.
  
  Revision  Changes    Path
  1.1                  
jboss/src/main/org/jboss/ejb/plugins/local/BaseLocalContainerInvoker.java
  
  Index: BaseLocalContainerInvoker.java
  ===================================================================
  /*
   * JBoss, the OpenSource EJB server
   *
   * Distributable under LGPL license.
   * See terms of license at gnu.org.
   */
  package org.jboss.ejb.plugins.local;
  
  import java.awt.Component;
  import java.beans.beancontext.BeanContextChildComponentProxy;
  import java.io.File;
  import java.io.IOException;
  import java.lang.reflect.Method;
  import java.lang.reflect.Constructor;
  import java.security.Principal;
  import java.util.ArrayList;
  import java.util.Collection;
  import java.util.Iterator;
  import java.util.Map;
  import java.util.HashMap;
  import java.util.Properties;
  import java.lang.reflect.InvocationHandler;
  import java.lang.reflect.Proxy;
  
  import javax.ejb.EJBMetaData;
  import javax.ejb.EJBLocalHome;
  import javax.ejb.EJBLocalObject;
  import javax.naming.Name;
  import javax.naming.InitialContext;
  import javax.naming.Context;
  import javax.naming.NamingException;
  import javax.naming.NameNotFoundException;
  import javax.transaction.Transaction;
  import javax.transaction.TransactionManager;
  
  import org.jboss.ejb.MethodInvocation;
  import org.jboss.ejb.plugins.jrmp.interfaces.RemoteMethodInvocation;
  
  import org.jboss.ejb.Container;
  import org.jboss.ejb.ContainerInvokerContainer;
  import org.jboss.ejb.Interceptor;
  import org.jboss.ejb.LocalContainerInvoker;
  import org.jboss.ejb.plugins.jrmp.interfaces.EJBMetaDataImpl;
  import org.jboss.ejb.CacheKey;
  
  import org.jboss.tm.TransactionPropagationContextFactory;
  
  import org.jboss.security.SecurityAssociation;
  
  import org.jboss.logging.Logger;
  
  import org.jboss.ejb.DeploymentException;
  import org.jboss.metadata.MetaData;
  import org.jboss.metadata.EntityMetaData;
  import org.jboss.metadata.SessionMetaData;
  
  
  /**
   *      <description>
   *
   *      @author Daniel OConnor ([EMAIL PROTECTED])
   */
  public abstract class BaseLocalContainerInvoker implements LocalContainerInvoker
  {
     // Attributes ----------------------------------------------------
     protected Container container;
     protected String jndiName;
     protected TransactionManager transactionManager;
     // The home can be one.
     protected EJBLocalHome home;
     // The Stateless Object can be one.
     protected EJBLocalObject statelessObject;
  
     protected Map beanMethodInvokerMap;
     protected Map homeMethodInvokerMap;
     
     // Static --------------------------------------------------------
  
     private static TransactionPropagationContextFactory tpcFactory;
  
     // Constructors --------------------------------------------------
  
     // Public --------------------------------------------------------
  
     
     public String getJndiName()
     {
        return jndiName;
     }
  
     // ContainerService implementation -------------------------------
     public void setContainer(Container con)
     {
        this.container = con;
     }
  
     public void init()
     throws Exception
     {
        Context ctx = new InitialContext();
  
        jndiName = container.getBeanMetaData().getJndiName();
  
        // Set the transaction manager and transaction propagation
        // context factory of the GenericProxy class
        transactionManager = 
((TransactionManager)ctx.lookup("java:/TransactionManager"));
  
        // Create method mappings for container invoker
        Method[] methods = 
((ContainerInvokerContainer)container).getLocalClass().getMethods();
        beanMethodInvokerMap = new HashMap();
        for (int i = 0; i < methods.length; i++)
           beanMethodInvokerMap.put(new 
Long(RemoteMethodInvocation.calculateHash(methods[i])), methods[i]);
        
        methods = 
((ContainerInvokerContainer)container).getLocalHomeClass().getMethods();
        homeMethodInvokerMap = new HashMap();
        for (int i = 0; i < methods.length; i++)
           homeMethodInvokerMap.put(new 
Long(RemoteMethodInvocation.calculateHash(methods[i])), methods[i]);
     }
  
     public void start()
     throws Exception
     {
        // put in the static hashmap
     }
  
     public void stop()
     {
        // remove from the static hashmap
     }
  
     public void destroy()
     {
     }
       
     
     // ContainerInvoker implementation -------------------------------
     public EJBLocalHome getEJBLocalHome()
     {
        throw new UnsupportedOperationException();
     }
  
     public EJBLocalObject getStatelessSessionEJBLocalObject()
     {
        ContainerInvokerContainer cic = (ContainerInvokerContainer) container;
        return (EJBLocalObject) Proxy.newProxyInstance( 
           cic.getLocalClass().getClassLoader(),
           new Class[]{cic.getLocalClass()}, new StatelessSessionProxy() );
     }
  
     public EJBLocalObject getStatefulSessionEJBLocalObject(Object id)
     {
        ContainerInvokerContainer cic = (ContainerInvokerContainer) container;
        return (EJBLocalObject) Proxy.newProxyInstance( 
           cic.getLocalClass().getClassLoader(),
           new Class[]{cic.getLocalClass()}, new StatefulSessionProxy(id) );
     }
  
     public EJBLocalObject getEntityEJBLocalObject(Object id)
     {
        ContainerInvokerContainer cic = (ContainerInvokerContainer) container;
        return (EJBLocalObject) Proxy.newProxyInstance( 
           cic.getLocalClass().getClassLoader(),
           new Class[]{cic.getLocalClass()}, new EntityProxy(id ) );
     }
  
     public Collection getEntityLocalCollection(Collection ids)
     {
        ArrayList list = new ArrayList( ids.size() );
        Iterator iter = ids.iterator();
        while (iter.hasNext())
        {
           list.add( getEntityEJBLocalObject(iter.next()) );
        }
        return list;
     }
  
     /**
      *  Invoke a Home interface method.
      */
     public Object invokeHome(Method m, Object[] args, Transaction tx,
        Principal identity, Object credential)
     throws Exception
     {
        // Set the right context classloader
        ClassLoader oldCl = Thread.currentThread().getContextClassLoader();
        Thread.currentThread().setContextClassLoader(container.getClassLoader());
  
        try
        {
           return container.invokeHome(new MethodInvocation(null, m, args, tx,
              identity, credential));
        } finally
        {
           Thread.currentThread().setContextClassLoader(oldCl);
        }
     }
  
     /**
      *  Return the principal to use for invocations with this proxy.
      */
     Principal getPrincipal()
     {
        return SecurityAssociation.getPrincipal();
     }
  
     /**
      *  Return the credentials to use for invocations with this proxy.
      */
     Object getCredential()
     {
        return SecurityAssociation.getCredential();
     }
  
     /**
      *  Return the transaction associated with the current thread.
      *  Returns <code>null</code> if the transaction manager was never
      *  set, or if no transaction is associated with the current thread.
      */
     Transaction getTransaction()
        throws javax.transaction.SystemException
     {
        return (transactionManager == null) ? null : 
transactionManager.getTransaction();
     }
  
     
     /**
      *  Invoke a Remote interface method.
      */
     public Object invoke(Object id, Method m, Object[] args )
     throws Exception
     {
        // Set the right context classloader
        ClassLoader oldCl = Thread.currentThread().getContextClassLoader();
        Thread.currentThread().setContextClassLoader(container.getClassLoader());
  
        try
        {
           return container.invoke(new MethodInvocation(id, m, args, getTransaction(), 
              getPrincipal(), getCredential()));
        } finally
        {
           Thread.currentThread().setContextClassLoader(oldCl);
        }
     }
  
     class EntityProxy extends LocalProxy 
        implements InvocationHandler
     {
        CacheKey cacheKey;
        
        EntityProxy( Object id )
        {
           if (!(id instanceof CacheKey))
              id = new CacheKey( id );
           cacheKey = (CacheKey) id;
        }
        
        public final Object invoke(final Object proxy,
                                 final Method m,
                                 Object[] args)
          throws Throwable
         {
            if (args == null)
                args = EMPTY_ARGS;
            
            Object retValue = super.invoke( proxy, m, args, jndiName, cacheKey.id );
            if (retValue != null)
               return retValue;
            // If not taken care of, go on and call the container
            else {
                return BaseLocalContainerInvoker.this.invoke(
                 cacheKey, m, args);
            }
         }
        
      }
     
     class StatefulSessionProxy extends LocalProxy 
        implements InvocationHandler
     {
        Object id;
        
        StatefulSessionProxy( Object id )
        {
           this.id = id;
        }
        
        public final Object invoke(final Object proxy,
                                 final Method m,
                                 Object[] args)
          throws Throwable
         {
            if (args == null)
                args = EMPTY_ARGS;
            
            Object retValue = super.invoke( proxy, m, args, jndiName, id );
            if (retValue != null)
               return retValue;
            // If not taken care of, go on and call the container
            else {
                return BaseLocalContainerInvoker.this.invoke(
                 id, m, args);
            }
         }
     }
     
     class StatelessSessionProxy extends LocalProxy 
        implements InvocationHandler
     {
        public final Object invoke(final Object proxy,
                                 final Method m,
                                 Object[] args)
          throws Throwable
       {
          if (args == null)
             args = EMPTY_ARGS;
            
         // Implement local methods
         if (m.equals(TO_STRING)) {
                 return jndiName + ":Stateless";
         }
         else if (m.equals(EQUALS)) {
                 return invoke(proxy, IS_IDENTICAL, args);
         }
         else if (m.equals(HASH_CODE)) {
                 // We base the stateless hash on the hash of the proxy...
                 // MF XXX: it could be that we want to return the hash of the name?
                 return new Integer(this.hashCode());
         }
         else if (m.equals(GET_PRIMARY_KEY)) {
                 // MF FIXME 
                 // The spec says that SSB PrimaryKeys should not be returned and the 
call should throw an exception
                 // However we need to expose the field *somehow* so we can check for 
"isIdentical"
                 // For now we use a non-spec compliant implementation and just return 
the key as is
                 // See jboss1.0 for the PKHolder and the hack to be spec-compliant 
and yet solve the problem
  
                 // This should be the following call 
                 //throw new RemoteException("Session Beans do not expose their keys, 
RTFS");
  
                 // This is how it can be solved with a PKHolder (extends 
RemoteException)
                 // throw new PKHolder("RTFS", name);
  
                 // This is non-spec compliant but will do for now
                 // We can consider the name of the container to be the primary key, 
since all stateless beans
                 // are equal within a home
                 return jndiName;
         }
          else if (m.equals(GET_EJB_HOME)) {
           throw new UnsupportedOperationException();
          }
                else if (m.equals(IS_IDENTICAL)) {
                        // All stateless beans are identical within a home,
                        // if the names are equal we are equal
              return isIdentical(args[0], jndiName);
                }
            // If not taken care of, go on and call the container
            else {
                return BaseLocalContainerInvoker.this.invoke(
                 jndiName, m, args);
            }
         }
     }
  
  }
  
  
  
  
  1.1                  jboss/src/main/org/jboss/ejb/plugins/local/LocalProxy.java
  
  Index: LocalProxy.java
  ===================================================================
  /*
   * JBoss, the OpenSource EJB server
   *
   * Distributable under LGPL license.
   * See terms of license at gnu.org.
   */
  package org.jboss.ejb.plugins.local;
  
  import java.io.IOException;
  import java.io.ObjectInput;
  import java.io.ObjectOutput;
  
  import java.util.HashMap;
  import java.lang.reflect.Method;
  import java.security.Principal;
  
  import javax.transaction.Transaction;
  import javax.transaction.TransactionManager;
  import javax.transaction.SystemException;
  
  import javax.ejb.EJBLocalHome;
  import javax.ejb.EJBLocalObject;
  
  
  import org.jboss.security.SecurityAssociation;
  import org.jboss.ejb.CacheKey;
  
  
  /**
   * Abstract superclass of local client-side proxies.
   * 
   * @author  Daniel OConnor ([EMAIL PROTECTED])
   */
  public abstract class LocalProxy
  {
     // Constants -----------------------------------------------------
  
     // Attributes ----------------------------------------------------
  
     // Static --------------------------------------------------------
  
     /** An empty method parameter list. */
     protected static final Object[] EMPTY_ARGS = {};
      
     /** {@link Object#toString} method reference. */
     protected static final Method TO_STRING;
  
     /** {@link Object#hashCode} method reference. */
     protected static final Method HASH_CODE;
  
     /** {@link Object#equals} method reference. */
     protected static final Method EQUALS;
  
      /** {@link EJBObject#getPrimaryKey} method reference. */
      protected static final Method GET_PRIMARY_KEY;
  
      /** {@link EJBObject#getEJBHome} method reference. */
        protected static final Method GET_EJB_HOME;
  
      /** {@link EJBObject#isIdentical} method reference. */
      protected static final Method IS_IDENTICAL;
  
      /**
       * Initialize {@link EJBObject} method references.
       */
      static {
          try {
              final Class[] empty = {};
              final Class type = EJBLocalObject.class;
           
                        GET_PRIMARY_KEY = type.getMethod("getPrimaryKey", empty);
                        GET_EJB_HOME = type.getMethod("getEJBLocalHome", empty);
                        IS_IDENTICAL = type.getMethod("isIdentical", new Class[] { 
type });
          }
          catch (Exception e) {
              e.printStackTrace();
              throw new ExceptionInInitializerError(e);
          }
      }
  
  
     /**
      * Initialize {@link Object} method references.
      */
     static {
         try {
             final Class[] empty = {};
             final Class type = Object.class;
  
             TO_STRING = type.getMethod("toString", empty);
             HASH_CODE = type.getMethod("hashCode", empty);
             EQUALS = type.getMethod("equals", new Class[] { type });
         }
         catch (Exception e) {
             e.printStackTrace();
             throw new ExceptionInInitializerError(e);
         }
     }  
  
      /**
       * Test the identitiy of an <tt>EJBObject</tt>.
       *
       * @param a    <tt>EJBObject</tt>.
       * @param b    Object to test identity with.
       * @return     True if objects are identical.
       *
       * @throws ClassCastException   Not an EJBObject instance.
       */
      Boolean isIdentical(final Object a, final Object b)
      {
          final EJBLocalObject ejb = (EJBLocalObject)a;
          final Object pk = ejb.getPrimaryKey();
          return new Boolean(pk.equals(b));
      }
  
        public final Object invoke(final Object proxy,
                                 final Method m,
                                 Object[] args,
                                 String jndiName,
                                 Object id)
          throws Throwable
         {
            // Implement local methods
            if (m.equals(TO_STRING)) {
                return jndiName + ":" + id.toString();
            }
            else if (m.equals(EQUALS)) {
                return invoke(proxy, IS_IDENTICAL, args, jndiName, id );
            }
            else if (m.equals(HASH_CODE)) {
              return new Integer(id.hashCode());
            }
  
            // Implement local EJB calls
            else if (m.equals(GET_PRIMARY_KEY)) {
                return id;
            }
            else if (m.equals(GET_EJB_HOME)) {
               throw new UnsupportedOperationException(); 
               //return getEJBHome();
            }
            else if (m.equals(IS_IDENTICAL)) {
                return isIdentical(args[0], id);
            }
            return null;
        }
  
  }
  
  
  
  

_______________________________________________
Jboss-development mailing list
[EMAIL PROTECTED]
http://lists.sourceforge.net/lists/listinfo/jboss-development

Reply via email to