User: oberg   
  Date: 00/05/30 11:32:19

  Modified:    src/main/org/jboss/ejb Application.java AutoDeployer.java
                        AutoDeployerMBean.java BeanClassLoader.java
                        Container.java ContainerFactory.java
                        ContainerFactoryMBean.java ContainerInvoker.java
                        ContainerPlugin.java DeploymentException.java
                        EJBClassLoader.java EnterpriseContext.java
                        EntityContainer.java EntityEnterpriseContext.java
                        EntityPersistenceManager.java
                        StatefulSessionContainer.java
                        StatelessSessionContainer.java
  Log:
  Major update. Too much to mention.
  
  Revision  Changes    Path
  1.3       +54 -3     jboss/src/main/org/jboss/ejb/Application.java
  
  Index: Application.java
  ===================================================================
  RCS file: /products/cvs/ejboss/jboss/src/main/org/jboss/ejb/Application.java,v
  retrieving revision 1.2
  retrieving revision 1.3
  diff -u -r1.2 -r1.3
  --- Application.java  2000/04/26 06:41:29     1.2
  +++ Application.java  2000/05/30 18:32:15     1.3
  @@ -11,11 +11,13 @@
   import java.util.HashMap;
   
   /**
  - *   <description> 
  + *   An Application represents a collection of beans that are deployed as a unit.
  + *     The beans may use the Application to access other beans within the same 
deployment unit 
    *      
  - *   @see <related>
  + *   @see Container
  + *   @see ContainerFactory
    *   @author Rickard �berg ([EMAIL PROTECTED])
  - *   @version $Revision: 1.2 $
  + *   @version $Revision: 1.3 $
    */
   public class Application
   {
  @@ -30,41 +32,90 @@
   
      // Public --------------------------------------------------------
   
  +
  +     /**
  +      *      Add a container to this application. This is called by the 
ContainerFactory
  +      *
  +      * @param   con  
  +      */
      public void addContainer(Container con)
      {
         containers.put(con.getMetaData().getEjbName(), con);
      }
      
  +
  +     /**
  +      *      Remove a container from this application
  +      *
  +      * @param   con  
  +      */
      public void removeContainer(Container con)
      {
         containers.remove(con.getMetaData().getEjbName());
      }
      
  +
  +     /**
  +      *      Get a container from this Application that corresponds to a given name
  +      *
  +      * @param   name  
  +      * @return     
  +      */
      public Container getContainer(String name)
      {
         return (Container)containers.get(name);
      }
      
  +
  +     /**
  +      *      Get all containers in this Application
  +      *
  +      * @return     
  +      */
      public Collection getContainers()
      {
         return containers.values();
      }
      
  +
  +     /**
  +      *      Get the name of this Application. 
  +      *
  +      * @return     
  +      */
      public String getName()
      {
         return name;
      }
      
  +
  +     /**
  +      *      Set the name of this Application
  +      *
  +      * @param   name  
  +      */
      public void setName(String name)
      {
         this.name = name;
      }
      
  +
  +     /**
  +      *      Get the URL from which this Application was deployed
  +      *
  +      * @return     
  +      */
      public URL getURL()
      {
         return url;
      }
      
  +
  +     /**
  +      *      Set the URL that was used to deploy this Application
  +      *
  +      * @param   url  
  +      */
      public void setURL(URL url)
      {
                if (url == null)
  
  
  
  1.4       +106 -82   jboss/src/main/org/jboss/ejb/AutoDeployer.java
  
  Index: AutoDeployer.java
  ===================================================================
  RCS file: /products/cvs/ejboss/jboss/src/main/org/jboss/ejb/AutoDeployer.java,v
  retrieving revision 1.3
  retrieving revision 1.4
  diff -u -r1.3 -r1.4
  --- AutoDeployer.java 2000/05/23 05:32:32     1.3
  +++ AutoDeployer.java 2000/05/30 18:32:15     1.4
  @@ -15,36 +15,57 @@
   import java.util.StringTokenizer;
   import java.util.HashMap;
   import java.util.ArrayList;
  -import javax.management.*;
  +import javax.management.MBeanServer;
  +import javax.management.MBeanException;
  +import javax.management.RuntimeErrorException;
  +import javax.management.ObjectName;
   
  -
   import org.jboss.logging.Log;
  -//import org.jboss.cluster.*;
   import org.jboss.util.MBeanProxy;
  +import org.jboss.util.ServiceMBeanSupport;
   
   /**
  - *   <description> 
  + *   The AutoDeployer is used to automatically deploy EJB-jars.
  + *     It can be used on either .jar or .xml files. The AutoDeployer can
  + *     be configured to "watch" one or more files. If they are updated they will
  + *     be redeployed. 
  + *
  + *     If it is set to watch a directory instead of a single file, all files within 
that
  + *     directory will be watched separately.
  + *
  + *     When a jar is to be deployed, the AutoDeployer will use a ContainerFactory 
to deploy it.
    *      
  - *   @see <related>
  + *   @see ContainerFactory
    *   @author Rickard �berg ([EMAIL PROTECTED])
  - *   @version $Revision: 1.3 $
  + *   @version $Revision: 1.4 $
    */
   public class AutoDeployer
  -   implements AutoDeployerMBean, MBeanRegistration, Runnable
  +     extends ServiceMBeanSupport
  +   implements AutoDeployerMBean, Runnable
   {
      // Constants -----------------------------------------------------
  -   public static final String OBJECT_NAME = "EJB:service=AutoDeployer";
       
      // Attributes ----------------------------------------------------
  +     
  +     // Callback to the JMX agent
      MBeanServer server;
  +     
  +     // JMX name of the ContainerFactory
      ObjectName factoryName;
      
  +     // The watch thread
      boolean running = false;
      
  +     // Watch these directories for new files
      ArrayList watchedDirectories = new ArrayList();
  +     
  +     // These URL's have been deployed. Check for new timestamp
      HashMap deployedURLs = new HashMap();
  +     
  +     // These URL's are being watched
      ArrayList watchedURLs = new ArrayList();
      
  +     // The logger for this service
      Log log = new Log("Auto deploy");
   
      // Static --------------------------------------------------------
  @@ -52,8 +73,14 @@
      // Constructors --------------------------------------------------
      public AutoDeployer(String urlList)
      {
  +             addURLs(urlList);
  +     }
  +     
  +     public void addURLs(String urlList)
  +     {
         StringTokenizer urls = new StringTokenizer(urlList, ",");
         
  +             // Add URLs to list
         while (urls.hasMoreTokens())
         {
            String url = urls.nextToken();
  @@ -62,17 +89,6 @@
            File urlFile = new File(url);
            if (urlFile.exists() && urlFile.isDirectory())
            {
  -/*            
  -            File[] files = url.listFiles();
  -            for (int i = 0; i < files.length; i++)
  -            {
  -               if (!deployedURLs.contains(files[i].toURL()))
  -               {
  -                  watchedURLs.addElement(new Deployment(files[i].toURL()));
  -               }
  -            }
  -*/          
  -
               File metaFile = new File(urlFile, "META-INF/ejb-jar.xml");
               if (metaFile.exists()) // It's unpackaged
               {
  @@ -86,6 +102,7 @@
                  }
               } else
               {
  +                                     // This is a directory whose contents shall be 
checked for deployments
                  try
                  {
                     watchedDirectories.add(urlFile.getCanonicalFile());
  @@ -105,7 +122,7 @@
                  {
                     log.warning("Cannot auto-deploy "+urlFile);
                  }
  -         } else // It's a real URL
  +         } else // It's a real URL (probably http:) pointing to a JAR
            {
               try
               {
  @@ -113,71 +130,13 @@
               } catch (MalformedURLException e)
               {
                  // Didn't work
  -               log.log("Cannot auto-deploy "+url);
  +               log.warning("Cannot auto-deploy "+url);
               }
            }
         }
      }
      
      // Public --------------------------------------------------------
  -   public void start()
  -      throws Exception
  -   {
  -      running = true;
  -      new Thread(this).start();
  -   }
  -   
  -   public void stop()
  -   {
  -      running = false;
  -   }
  -
  -   public void deploy(String url)
  -      throws Exception
  -   {
  -      try
  -      {   
  -        
  -         // MF INFO: the call will land on ContainerFactory
  -         
  -         server.invoke(factoryName, "deploy",
  -                         new Object[] { url }, new String[] { "java.lang.String" });
  -      } catch (MBeanException e)
  -      {
  -         throw e.getTargetException();
  -      } catch (RuntimeErrorException e)
  -      {
  -         throw e.getTargetError();
  -      }
  -   }
  -   
  -   
  -   public ObjectName preRegister(MBeanServer server, ObjectName name)
  -      throws java.lang.Exception
  -   {
  -      this.server = server;
  -      
  -      // MF INFO: the ObjetName is ContainerFactory 
  -      factoryName = new ObjectName(ContainerFactoryMBean.OBJECT_NAME);
  -      
  -      run(); // Pre-deploy
  -      start();
  -      return new ObjectName(OBJECT_NAME);
  -   }
  -   
  -   public void postRegister(java.lang.Boolean registrationDone)
  -   {
  -   }
  -   
  -   public void preDeregister()
  -      throws java.lang.Exception
  -   {
  -   }
  -   
  -   public void postDeregister()
  -   {
  -   }
  -   
      public void run()
      {
         do 
  @@ -190,7 +149,7 @@
            
            try
            {
  -            // Check directories
  +            // Check directories - add new entries to list of files
               for (int i = 0; i < watchedDirectories.size(); i++)
               {
                  File dir = (File)watchedDirectories.get(i);
  @@ -200,6 +159,8 @@
                     URL fileUrl = files[idx].toURL();
                     if (deployedURLs.get(fileUrl) == null)
                     {
  +                                                     // This file has not been seen 
before
  +                                                     // Add to list of files to 
deploy automatically
                        watchedURLs.add(new Deployment(fileUrl));
                        deployedURLs.put(fileUrl, fileUrl);
                     }
  @@ -215,9 +176,11 @@
                  long lm;
                  if (deployment.watch.getProtocol().startsWith("file"))
                  {
  +                                             // Get timestamp of file from file 
system
                     lm = new File(deployment.watch.getFile()).lastModified();
                  } else
                  {
  +                                             // Use URL connection to get timestamp
                     lm = deployment.watch.openConnection().getLastModified();
                  }
                  
  @@ -229,22 +192,83 @@
                     try
                     {
                        deploy(deployment.url.toString());
  -                  } catch (DeploymentException e)
  +                  } catch (Throwable e)
                     {
                        log.error("Deployment failed:"+deployment.url);
  -                     log.exception(e.getCause());
  +                     log.exception(e);
  +                                                     
  +                                                     // Deployment failed - won't 
retry until updated
                     }
                  }
               }
            } catch (Exception e)
            {
               e.printStackTrace(System.err);
  +                             
  +                             // Stop auto deployer
               running = false;
            }
         } while(running);
      }
  +     
  +   // ServiceMBeanSupport overrides ---------------------------------
  +   public String getName()
  +   {
  +      return "Auto deployer";
  +   }
  +   
  +   protected ObjectName getObjectName(MBeanServer server, ObjectName name)
  +      throws javax.management.MalformedObjectNameException
  +   {
  +     this.server = server;
  +      return new ObjectName(OBJECT_NAME);
  +   }
  +     
  +   protected void initService()
  +      throws Exception
  +   {
  +      // Save JMX name of ContainerFactory
  +      factoryName = new ObjectName(ContainerFactoryMBean.OBJECT_NAME);
  +   }
  +
  +   protected void startService()
  +      throws Exception
  +   {
  +      run(); // Pre-deploy. This is done so that deployments available
  +                      // on start of container is deployed ASAP
  +                      
  +      // Start auto deploy thread
  +      running = true;
  +      new Thread(this, "Auto deploy").start();
  +   }
  +   
  +   protected void stopService()
  +   {
  +     // Stop auto deploy thread
  +      running = false;
  +   }
  +     
      // Protected -----------------------------------------------------
  +   protected void deploy(String url)
  +      throws Exception
  +   {
  +      try
  +      {   
  +             // Call the ContainerFactory that is loaded in the JMX server
  +         server.invoke(factoryName, "deploy",
  +                         new Object[] { url }, new String[] { "java.lang.String" });
  +      } catch (MBeanException e)
  +      {
  +         throw e.getTargetException();
  +      } catch (RuntimeErrorException e)
  +      {
  +         throw e.getTargetError();
  +      }
  +   }
      
  +   // Inner classes -------------------------------------------------
  +     
  +     // This class holds info about a deployement, such as the URL and the last 
timestamp
      static class Deployment
      {
         long lastModified;
  
  
  
  1.2       +8 -15     jboss/src/main/org/jboss/ejb/AutoDeployerMBean.java
  
  Index: AutoDeployerMBean.java
  ===================================================================
  RCS file: /products/cvs/ejboss/jboss/src/main/org/jboss/ejb/AutoDeployerMBean.java,v
  retrieving revision 1.1
  retrieving revision 1.2
  diff -u -r1.1 -r1.2
  --- AutoDeployerMBean.java    2000/04/22 14:30:12     1.1
  +++ AutoDeployerMBean.java    2000/05/30 18:32:15     1.2
  @@ -6,29 +6,22 @@
    */
   package org.jboss.ejb;
   
  +import org.jboss.util.ServiceMBean;
  +
   /**
  - *   <description> 
  + *   This is the interface of the AutoDeployer that is exposed for administration
    *      
  - *   @see <related>
  + *   @see AutoDeployer
    *   @author Rickard �berg ([EMAIL PROTECTED])
  - *   @version $Revision: 1.1 $
  + *   @version $Revision: 1.2 $
    */
   public interface AutoDeployerMBean
  +     extends ServiceMBean
   {
      // Constants -----------------------------------------------------
  +   public static final String OBJECT_NAME = "EJB:service=AutoDeployer";
       
  -   // Attributes ----------------------------------------------------
  -
  -   // Static --------------------------------------------------------
  -
  -   // Constructors --------------------------------------------------
  -   
      // Public --------------------------------------------------------
  -   public void start()
  -      throws Exception;
  -   
  -   public void stop();
  -
  -   // Protected -----------------------------------------------------
  +   public void addURLs(String urlList);
   }
   
  
  
  
  1.3       +15 -5     jboss/src/main/org/jboss/ejb/BeanClassLoader.java
  
  Index: BeanClassLoader.java
  ===================================================================
  RCS file: /products/cvs/ejboss/jboss/src/main/org/jboss/ejb/BeanClassLoader.java,v
  retrieving revision 1.2
  retrieving revision 1.3
  diff -u -r1.2 -r1.3
  --- BeanClassLoader.java      2000/05/22 15:03:00     1.2
  +++ BeanClassLoader.java      2000/05/30 18:32:15     1.3
  @@ -13,11 +13,13 @@
   import java.security.Permissions;
   
   /**
  - *   ClassLoader that one can attach thread-specific data to
  + *   This classloader is used to hold the java: JNDI-namespace root.
  + *     Each container has its own BCL. When a "java:" lookup is made
  + *     the JNDI-provider will use the root to lookup the values.
    *      
  - *   @see <related>
  + *   @see org.jboss.naming.java.javaURLContextFactory
    *   @author Rickard �berg ([EMAIL PROTECTED])
  - *   @version $Revision: 1.2 $
  + *   @version $Revision: 1.3 $
    */
   public class BeanClassLoader
      extends URLClassLoader
  @@ -25,6 +27,7 @@
      // Constants -----------------------------------------------------
       
      // Attributes ----------------------------------------------------
  +     // This is the root of the "java:" JNDI-namespace
      Object jndiRoot;
      
      // Static --------------------------------------------------------
  @@ -36,7 +39,14 @@
      }
      
      // Public --------------------------------------------------------
  -   public void setJNDIRoot(Object root) { this.jndiRoot = root; }
  -   public Object getJNDIRoot() { return jndiRoot; }
  +   public void setJNDIRoot(Object root) 
  +     { 
  +             this.jndiRoot = root; 
  +     }
  +     
  +   public Object getJNDIRoot() 
  +     { 
  +             return jndiRoot; 
  +     }
   }
   
  
  
  
  1.8       +222 -131  jboss/src/main/org/jboss/ejb/Container.java
  
  Index: Container.java
  ===================================================================
  RCS file: /products/cvs/ejboss/jboss/src/main/org/jboss/ejb/Container.java,v
  retrieving revision 1.7
  retrieving revision 1.8
  diff -u -r1.7 -r1.8
  --- Container.java    2000/05/27 20:01:40     1.7
  +++ Container.java    2000/05/30 18:32:15     1.8
  @@ -12,6 +12,7 @@
   import java.security.Principal;
   import java.util.Map;
   import java.util.Iterator;
  +import java.util.Hashtable;
   
   import javax.ejb.Handle;
   import javax.ejb.HomeHandle;
  @@ -23,9 +24,15 @@
   import javax.naming.Name;
   import javax.naming.InitialContext;
   import javax.naming.LinkRef;
  +import javax.naming.Reference;
  +import javax.naming.NamingEnumeration;
  +import javax.naming.NameClassPair;
   import javax.naming.NamingException;
  +import javax.naming.RefAddr;
   import javax.naming.NameNotFoundException;
  +import javax.naming.spi.ObjectFactory;
   import javax.transaction.TransactionManager;
  +import javax.sql.DataSource;
   
   import org.jboss.ejb.deployment.jBossEnterpriseBean;
   import com.dreambean.ejx.ejb.EnvironmentEntry;
  @@ -43,36 +50,61 @@
   import org.jnp.server.NamingServer;
   
   /**
  - *   <description> 
  - *      
  - *   @see <related>
  + *   This is the base class for all EJB-containers in jBoss. A Container
  + *     functions as the central hub of all metadata and plugins. Through this
  + *     the container plugins can get hold of the other plugins and any metadata 
they need.
  + *
  + *     The ContainerFactory creates instances of subclasses of this class and calls 
the appropriate
  + *     initialization methods.
  + *
  + *     A Container does not perform any significant work, but instead delegates to 
the plugins to provide for
  + *     all kinds of algorithmic functionality.
  + *
  + *   @see ContainerFactory
    *   @author Rickard �berg ([EMAIL PROTECTED])
  - *   @version $Revision: 1.7 $
  + *   @version $Revision: 1.8 $
    */
   public abstract class Container
   {
      // Constants -----------------------------------------------------
       
      // Attributes ----------------------------------------------------
  +     
  +     // This is the application that this container is a part of
      protected Application application;
  +     
  +     // This is the classloader of this container. All classes and resources that
  +     // the bean uses will be loaded from here. By doing this we make the bean 
re-deployable
      protected ClassLoader classLoader;
  +     
  +     // This is the jBoss-specific metadata. Note that it extends the generic EJB 
1.1 class from EJX
      protected jBossEnterpriseBean metaData;
  +     
  +     // This is the instancepool that is to be used
      protected InstancePool instancePool;
  -   protected ContainerInvoker containerInvoker;
  -   protected TransactionManager transactionManager;
  +     
  +     // This is the first interceptor in the chain. The last interceptor must be 
provided by the container itself
      protected Interceptor interceptor;
      
  +     // This is the Home interface class
      protected Class homeInterface;
  +     
  +   // This is the Remote interface class
      protected Class remoteInterface;
  +     
  +   // This is the EnterpriseBean class
      protected Class beanClass;
  -   
  -   // Static --------------------------------------------------------
  -
  -   // Constructors --------------------------------------------------
      
  +   // This is the TransactionManager
  +   protected TransactionManager tm;
  +     
      // Public --------------------------------------------------------
  -
  -   // Container implementation --------------------------------------
  +     
  +     public TransactionManager getTransactionManager()
  +     {
  +             return tm;
  +     }
  +     
      public void setApplication(Application app) 
      { 
                if (app == null)
  @@ -92,19 +124,20 @@
         this.classLoader = cl; 
      }
      
  +   public ClassLoader getClassLoader() 
  +     { 
  +             return classLoader; 
  +     }
  +     
      public void setMetaData(jBossEnterpriseBean metaData) 
      { 
         this.metaData = metaData; 
      }
      
  -   public void setContainerInvoker(ContainerInvoker ci) 
  -   { 
  -      if (ci == null)
  -             throw new IllegalArgumentException("Null invoker");
  -                     
  -      this.containerInvoker = ci; 
  -      ci.setContainer(this);
  -   }
  +   public jBossEnterpriseBean getMetaData() 
  +     { 
  +             return metaData; 
  +     }
        
      public void setInstancePool(InstancePool ip) 
      { 
  @@ -114,9 +147,12 @@
         this.instancePool = ip; 
         ip.setContainer(this);
      }
  -
  -   public void setInterceptor(Interceptor in) { this.interceptor = in; }
   
  +   public InstancePool getInstancePool() 
  +     { 
  +             return instancePool; 
  +     }
  +     
      public void addInterceptor(Interceptor in) 
      { 
         if (interceptor == null)
  @@ -134,167 +170,134 @@
            current.setNext(in);
         }
      }
  -   
  -   public ClassLoader getClassLoader(ClassLoader cl) { return classLoader; }
  -   public jBossEnterpriseBean getMetaData() { return metaData; }
  -   public ContainerInvoker getContainerInvoker() { return containerInvoker; }
  -   public InstancePool getInstancePool() { return instancePool; }
  -   public Interceptor getInterceptor() { return interceptor; }
  -      
  -   public TransactionManager getTransactionManager() { return transactionManager; }
  -   public void setTransactionManager(TransactionManager tm) { transactionManager = 
tm; }
      
  -   /*
  -   * init()
  -   *
  -   * The ContainerFactory calls this method.  The ContainerFactory has set all the 
  -   * plugins and interceptors that this bean requires and now proceeds to initialize
  -   * the chain.  The method looks for the standard classes in the URL, sets up
  -   * the naming environment of the bean.
  -   *
  -   */
  -   
  +   public Interceptor getInterceptor() 
  +     { 
  +             return interceptor; 
  +     }
  +        
  +     public Class getHomeClass()
  +     {
  +        return homeInterface;
  +     }
  +     
  +     public Class getRemoteClass()
  +     {
  +        return remoteInterface;
  +     }
  +     
  +     public Class getBeanClass()
  +     {
  +        return beanClass;
  +     }
  +     /**
  +      * The ContainerFactory calls this method.  The ContainerFactory has set all 
the 
  +      * plugins and interceptors that this bean requires and now proceeds to 
initialize
  +      * the chain.  The method looks for the standard classes in the URL, sets up
  +      * the naming environment of the bean.
  +      *
  +      * @exception   Exception  
  +      */
      public void init()
         throws Exception
      {
  -      ClassLoader oldCl = Thread.currentThread().getContextClassLoader();
  -      Thread.currentThread().setContextClassLoader(getClassLoader());
  -      
  +             // Acquire classes from CL
         homeInterface = classLoader.loadClass(metaData.getHome());
         remoteInterface = classLoader.loadClass(metaData.getRemote());
         beanClass = classLoader.loadClass(metaData.getEjbClass());
         
  +             // Get transaction manager
  +             tm = (TransactionManager)new 
InitialContext().lookup("TransactionManager");
  +             
  +             // Setup "java:" namespace
         setupEnvironment();
         
  +             // Initialize pool
         instancePool.init();
         
  -      containerInvoker.init();
  -       
  -       
  -       // Initialize the interceptor by calling the chain
  +        // Initialize the interceptor by calling the chain
         Interceptor in = interceptor;
         while (in != null)
         {
  -             
            in.setContainer(this);
            in.init();
            in = in.getNext();
         }
  -        
  -      Thread.currentThread().setContextClassLoader(oldCl);
      }
      
      public void start()
         throws Exception
      {
  -      ClassLoader oldCl = Thread.currentThread().getContextClassLoader();
  -      Thread.currentThread().setContextClassLoader(getClassLoader());
  -      
  +             // Start the instance pool
         instancePool.start();
  -      
  -      containerInvoker.start();
         
  +             // Start all interceptors in the chain          
         Interceptor in = interceptor;
         while (in != null)
         {
            in.start();
            in = in.getNext();
         }
  -      
  -      Thread.currentThread().setContextClassLoader(oldCl);
      }
      
      public void stop() 
      {
  -      ClassLoader oldCl = Thread.currentThread().getContextClassLoader();
  -      Thread.currentThread().setContextClassLoader(getClassLoader());
  -      
  +             // Stop the instance pool
         instancePool.stop();
  -      
  -      containerInvoker.stop();
         
  +             // Stop all interceptors in the chain           
         Interceptor in = interceptor;
         while (in != null)
         {
            in.stop();
            in = in.getNext();
         }
  -      
  -      Thread.currentThread().setContextClassLoader(oldCl);
      }
      
      public void destroy() 
      {
  -      ClassLoader oldCl = Thread.currentThread().getContextClassLoader();
  -      Thread.currentThread().setContextClassLoader(getClassLoader());
  -      
  +             // Destroy the pool
         instancePool.destroy();
  -      
  -      containerInvoker.destroy();
         
  +             // Destroy all the interceptors in the chain            
         Interceptor in = interceptor;
         while (in != null)
         {
            in.destroy();
            in = in.getNext();
         }
  -      
  -      Thread.currentThread().setContextClassLoader(oldCl);
      }
  -   
  -   /**
  -    *
  -    *
  -    * @return     
  -    */
  -   public ClassLoader getClassLoader() { return classLoader; }
  -   
  -   public Class getHomeClass()
  -   {
  -      if (homeInterface == null)
  -      {
  -         try
  -         {
  -            homeInterface = classLoader.loadClass(metaData.getHome());
  -         } catch (Exception e) {}
  -      }
  -      return homeInterface;
  -   }
  -   
  -   public Class getRemoteClass()
  -   {
  -      if (remoteInterface == null)
  -      {
  -         try
  -         {
  -            remoteInterface = classLoader.loadClass(metaData.getRemote());
  -         } catch (Exception e) {}
  -      }
  -      return remoteInterface;
  -   }
  -   
  -   public Class getBeanClass()
  -   {
  -      if (beanClass == null)
  -      {
  -         try
  -         {
  -            beanClass = classLoader.loadClass(metaData.getEjbClass());
  -         } catch (Exception e) {}
  -      }
  -      return beanClass;
  -   }
  -   
  +
  +     /**
  +      *      This method is called by the ContainerInvoker when a method call comes 
in on the Home object.
  +      *
  +      *      The Container forwards this call to the interceptor chain for further 
processing.
  +      *
  +      * @param   method  the method being invoked
  +      * @param   args  the parameters
  +      * @return     the result of the home invocation
  +      * @exception   Exception  
  +      */
      public abstract Object invokeHome(Method method, Object[] args)
         throws Exception;
  -      
  +
  +     /**
  +      *      This method is called by the ContainerInvoker when a method call comes 
in on an EJBObject.
  +      *
  +      *      The Container forwards this call to the interceptor chain for further 
processing.
  +      *
  +      * @param   id  the id of the object being invoked. May be null if stateless
  +      * @param   method  the method being invoked
  +      * @param   args  the parameters
  +      * @return     the result of the invocation
  +      * @exception   Exception  
  +      */
      public abstract Object invoke(Object id, Method method, Object[] args)
         throws Exception;
         
      // Protected -----------------------------------------------------
      
  -   // MF WHY: why the protected here, it gives a rather strange structure to the 
init
  -   protected abstract Interceptor createContainerInterceptor();
  +   abstract Interceptor createContainerInterceptor();
      
      // Private -------------------------------------------------------
      
  @@ -309,18 +312,18 @@
      * DataSource ressources.
      *
      */
  -   
  -   // MF WHY: part of the issue is that some meta data information is 
  -   // kept in many classes. There 2 repositories of metaData in this case.
  -   // One is the BeanClassLoader the other the "bean" in Container.
  -   
      private void setupEnvironment()
         throws DeploymentException
      {
                try
                {
  +                     // Create a new java: namespace root
              NamingServer root = new NamingServer();
  +                     
  +                     // Associate this root with the classloader of the bean
              ((BeanClassLoader)getClassLoader()).setJNDIRoot(root);
  +                     
  +                     // Since the BCL is already associated with this thread we can 
start using the java: namespace directly
              Context ctx = (Context)new InitialContext().lookup("java:/");
              ctx.createSubcontext("comp");
              ctx = ctx.createSubcontext("comp/env");
  @@ -354,6 +357,7 @@
                       bind(ctx, entry.getName(), new Boolean(entry.getValue()));
                    } else
                    {
  +                                             // Unknown type
                       // Default is string
                       bind(ctx, entry.getName(), entry.getValue());
                    }
  @@ -368,7 +372,6 @@
                    jBossEjbReference ref = (jBossEjbReference)enum.next();
                    
                    Name n = ctx.getNameParser("").parse(ref.getLink());
  -                 ContainerInvoker ci = getContainerInvoker();
                    
                    if (!ref.getJndiName().equals(""))
                    {
  @@ -379,8 +382,23 @@
                    else
                    {
                       // Internal link
  -                    Logger.debug("Bind "+ref.getName() +" to 
"+getApplication().getContainer(ref.getLink()).getContainerInvoker().getEJBHome());
  -                    bind(ctx, ref.getName(), 
getApplication().getContainer(ref.getLink()).getContainerInvoker().getEJBHome());
  +                    Logger.debug("Bind "+ref.getName() +" to "+ref.getLink());
  +                                             
  +                                             final Container con = 
getApplication().getContainer(ref.getLink());
  +                                             
  +                                             // Use Reference to link to ensure 
lazyloading. 
  +                                             // Otherwise we might try to get 
EJBHome from not yet initialized container
  +                                             // will would result in nullpointer 
exception
  +                                             RefAddr refAddr = new RefAddr("EJB")
  +                                             {
  +                                                     public Object getContent() 
  +                                                     {
  +                                                              return con;
  +                                                     }
  +                                             };
  +                                             Reference reference = new 
Reference("javax.ejb.EJBObject",refAddr, new 
EjbReferenceFactory().getClass().getName(), null);
  +                                             
  +                                             bind(ctx, ref.getName(), reference);
                    }
                 }
              }
  @@ -396,18 +414,57 @@
                    ResourceManager rm = rms.getResourceManager(ref.getResourceName());
                    
                                        if (rm == null)
  -                                             throw new DeploymentException("No 
resource manager named "+ref.getResourceName());
  +                                     {
  +                                             // Try to locate defaults
  +                                             if 
(ref.getType().equals("javax.sql.DataSource"))
  +                                             {
  +                                                     // Go through JNDI and look 
for DataSource - use the first one
  +                                                     Context dsCtx = new 
InitialContext();
  +                                                     NamingEnumeration list = 
dsCtx.list("");
  +                                                     while (list.hasMore())
  +                                                     {
  +                                                             NameClassPair pair = 
(NameClassPair)list.next();
  +                                                             try
  +                                                             {
  +                                                                     Class cl = 
getClass().getClassLoader().loadClass(pair.getClassName());
  +                                                                     if 
(DataSource.class.isAssignableFrom(cl))
  +                                                                     {
  +                                                                             // 
Found it!!
  +                                                                             
Logger.log("Using default DataSource:"+pair.getName());
  +                                                                             rm = 
new JDBCResource();
  +                                                                             
((JDBCResource)rm).setJndiName(pair.getName());
  +                                                                             
list.close();
  +                                                                             break;
  +                                                                     }
  +                                                             } catch (Exception e)
  +                                                             {
  +                                                                     
Logger.debug(e);
  +                                                             }
  +                                                     }
  +                                             
  +                                             }
                                                
  +                                             // Default failed? Warn user and move 
on
  +                                             // POTENTIALLY DANGEROUS: should this 
be a critical error?
  +                                             if (rm == null)
  +                                             {
  +                                                     Logger.warning("No resource 
manager found for "+ref.getResourceName());
  +                                                     continue;
  +                                             }
  +                                     }
  +                                             
                    if (rm.getType().equals("javax.sql.DataSource"))
                    {
  +                    // Datasource bindings   
                       JDBCResource res = (JDBCResource)rm;
  -                    bind(ctx, res.getName(), new LinkRef(res.getJndiName()));
  +                    bind(ctx, ref.getName(), new LinkRef(res.getJndiName()));
                    } else if (rm.getType().equals("java.net.URL"))
                    {
  +                    // URL bindings  
                       try
                       {
                          URLResource res = (URLResource)rm;
  -                       bind(ctx, res.getName(), new URL(res.getUrl()));
  +                       bind(ctx, ref.getName(), new URL(res.getUrl()));
                       } catch (MalformedURLException e)
                       {
                          throw new NamingException("Malformed URL:"+e.getMessage());
  @@ -417,15 +474,26 @@
              }
                } catch (NamingException e)
                {
  +                     e.printStackTrace();
  +                     e.getRootCause().printStackTrace();
                        throw new DeploymentException("Could not set up environment", 
e);
                }
      }
      
  +     
  +
  +     /**
  +      *      Bind a value to a name in a JNDI-context, and create any missing 
subcontexts
  +      *
  +      * @param   ctx  
  +      * @param   name  
  +      * @param   val  
  +      * @exception   NamingException  
  +      */
      private void bind(Context ctx, String name, Object val)
         throws NamingException
      {
         // Bind val to name in ctx, and make sure that all intermediate contexts exist
  -      
         Name n = ctx.getNameParser("").parse(name);
         while (n.size() > 1)
         {
  @@ -442,4 +510,27 @@
         
         ctx.bind(n.get(0), val);
      }
  +     
  +     public static class EjbReferenceFactory
  +             implements ObjectFactory
  +     {
  +             public Object getObjectInstance(Object ref,
  +                                             Name name,
  +                                             Context nameCtx,
  +                                             Hashtable environment)
  +                                      throws Exception
  +             {
  +                     Object con = ((Reference)ref).get(0).getContent();
  +                     if (con instanceof EntityContainer)
  +                     {
  +                             return 
((EntityContainer)con).getContainerInvoker().getEJBHome();
  +                     } if (con instanceof StatelessSessionContainer)
  +                     {
  +                             return 
((StatelessSessionContainer)con).getContainerInvoker().getEJBHome();
  +                     } else
  +                     {
  +                             return null;
  +                     }
  +             }
  +     }
   }
  
  
  
  1.10      +154 -101  jboss/src/main/org/jboss/ejb/ContainerFactory.java
  
  Index: ContainerFactory.java
  ===================================================================
  RCS file: /products/cvs/ejboss/jboss/src/main/org/jboss/ejb/ContainerFactory.java,v
  retrieving revision 1.9
  retrieving revision 1.10
  diff -u -r1.9 -r1.10
  --- ContainerFactory.java     2000/05/28 22:18:09     1.9
  +++ ContainerFactory.java     2000/05/30 18:32:16     1.10
  @@ -52,43 +52,65 @@
   import org.jboss.ejb.plugins.*;
   
   /**
  - *   A CF is used to create implementations of EJB Containers. 
  - *   It encapsulates the notion of a configuration since all containers
  - *   that are created use the same persistence engine, the same implementation
  - *   of containers, and so on. If several different such configurations are desired,
  - *   several containerfactories should be used.
  + *   A ContainerFactory is used to deploy EJB applications. It can be given a URL 
to 
  + *     an EJB-jar or EJB-JAR XML file, which will be used to instantiate containers 
and make
  + *     them available for invocation.
    *      
  - *   @see <related>
  + *   @see Container
    *   @author Rickard �berg ([EMAIL PROTECTED])
    *   @author <a href="mailto:[EMAIL PROTECTED]">Marc Fleury</a>
  - *   @version $Revision: 1.9 $
  + *   @version $Revision: 1.10 $
    */
   public class ContainerFactory
      implements ContainerFactoryMBean, MBeanRegistration
   {
      // Constants -----------------------------------------------------
  -    
  +     public static String DEFAULT_STATELESS_CONFIGURATION = "Default Stateless 
SessionBean";
  +     public static String DEFAULT_STATEFUL_CONFIGURATION = "Default Stateful 
SessionBean";
  +     public static String DEFAULT_ENTITY_BMP_CONFIGURATION = "Default BMP 
EntityBean";
  +     public static String DEFAULT_ENTITY_CMP_CONFIGURATION = "Default CMP 
EntityBean";
  +     
      // Attributes ----------------------------------------------------
  +     // The logger of this service
      Log log = new Log("Container factory");
      
  +     // The JMX agent
      MBeanServer server;
      
  +     // A map of current deployments. If a deployment is made and it is already in 
this map,
  +     // then undeploy it first (i.e. make it a re-deploy).
      HashMap deployments = new HashMap();
      
  -   // Static --------------------------------------------------------
  -
  -   // Constructors --------------------------------------------------
  -   
      // Public --------------------------------------------------------
  +
  +     /**
  +      *      Deploy the file at this URL. This method is typically called from 
remote administration
  +      *      tools that cannot handle java.net.URL's as parameters to methods
  +      *
  +      * @param   url  
  +      * @exception   MalformedURLException  
  +      * @exception   DeploymentException  
  +      */
      public void deploy(String url)
         throws MalformedURLException, DeploymentException
      {
  +             // Delegate to "real" deployment
         deploy(new URL(url));
      }
      
  +
  +     /**
  +      *      Undeploy the file at this URL. This method is typically called from 
remote administration
  +      *      tools that cannot handle java.net.URL's as parameters to methods
  +      *
  +      * @param   url  
  +      * @exception   MalformedURLException  
  +      * @exception   DeploymentException  
  +      */
      public void undeploy(String url)
         throws MalformedURLException, DeploymentException
      {
  +      // Delegate to "real" undeployment
         undeploy(new URL(url));
      }
      
  @@ -119,9 +141,8 @@
            Log.setLog(log);
            log.log("Deploying:"+url);
            
  +                     // Create a file manager with which to load the files
            jBossFileManagerFactory fact = new jBossFileManagerFactory();
  -         
  -         // Create classloader
            jBossFileManager efm = (jBossFileManager)fact.createFileManager();
            
            // Setup beancontext
  @@ -131,112 +152,138 @@
            
            // Load XML
            jBossEjbJar jar = efm.load(url);
  -         ClassLoader cl = new EJBClassLoader(new URL[] {url}, 
getClass().getClassLoader(), 
((jBossEnterpriseBeans)jar.getEnterpriseBeans()).isSecure());
  +                     
  +                     // Create classloader for this application
  +         ClassLoader cl = new EJBClassLoader(new URL[] {url}, 
getClass().getClassLoader(), jar.isSecure());
            
  +                     // Get list of beans for which we will create containers
            Iterator beans = jar.getEnterpriseBeans().iterator();
            
  +                     // Create list of containers
            ArrayList containers = new ArrayList();
            
  -         // Deploy bean
  +         // Deploy beans
            Context ctx = new InitialContext();
            while(beans.hasNext())
            {
               Container con = null;
               jBossEnterpriseBean bean = (jBossEnterpriseBean)beans.next();
  +                             
               log.log("Deploying "+bean.getEjbName());
  +                             
               if (bean instanceof jBossSession) // Is session?
               {
                  if (((jBossSession)bean).getSessionType().equals("Stateless")) // Is 
stateless?
                  {
  +                                             // Create container
                     con = new StatelessSessionContainer();
                     
  -//                  con.addInterceptor(new LogInterceptor());
  -//                  con.addInterceptor(new TxInterceptor());
  -                  con.addInterceptor(new StatelessSessionInstanceInterceptor());
  -                  con.addInterceptor(new SecurityInterceptor());
  -                  
  -                  con.addInterceptor(con.createContainerInterceptor());
  -                  
  +                                             // Create classloader for this 
container
                     con.setClassLoader(new BeanClassLoader(cl));
  +                                             
  +                                             // Set metadata
                     con.setMetaData(bean);
                                   
  +                                             // Get container configuration
                     ContainerConfiguration conf = 
jar.getContainerConfigurations().getContainerConfiguration(bean.getConfigurationName());
                    
  -                               // Make sure we have a default configuration
  -                               if (conf == null) {
  -                                       
  -                                      log.log("Using default configuration");
  -                                      
  -                                      // Get the container default configuration
  -                                      conf =  
jar.getContainerConfigurations().getContainerConfiguration("Default Stateless 
SessionBean");
  -                                      
  -                                      // Make sure this bean knows the 
configuration he is using
  -                                      bean.setConfigurationName("Default Stateless 
SessionBean");
  -                               }
  -                               
  -                  
con.setContainerInvoker((ContainerInvoker)cl.loadClass(conf.getContainerInvoker()).newInstance());
  +                                             // Make sure we have a default 
configuration
  +                                             if (conf == null) 
  +                                             {
  +                                                     log.warning("No configuration 
chosen. Using default configuration");
  +
  +                                                     // Get the container default 
configuration
  +                                                     conf = 
jar.getContainerConfigurations().getContainerConfiguration(DEFAULT_STATELESS_CONFIGURATION);
  +
  +                                                     // Make sure this bean knows 
the configuration he is using
  +                                                     
bean.setConfigurationName(DEFAULT_STATELESS_CONFIGURATION);
  +                                             }
  +                                             
  +                                             // Set container invoker
  +                  
((StatelessSessionContainer)con).setContainerInvoker((ContainerInvoker)cl.loadClass(conf.getContainerInvoker()).newInstance());
  +                                             
  +                  // Set instance pool
                     
con.setInstancePool((InstancePool)cl.loadClass(conf.getInstancePool()).newInstance());
                     
  -//                
con.setTransactionManager((TransactionManager)cl.loadClass(conf.getTransactionManager()).newInstance());
  -                  con.setTransactionManager(new org.jboss.tm.TxManager());
  +                  // Create interceptors
  +                  con.addInterceptor(new LogInterceptor());
  +                  con.addInterceptor(new TxInterceptor());
  +                  con.addInterceptor(new StatelessSessionInstanceInterceptor());
  +                  con.addInterceptor(new SecurityInterceptor());
                     
  +                  con.addInterceptor(con.createContainerInterceptor());
  +                                             
  +                                             // Add container to application
                     containers.add(con);
                  } else // Stateful
                  {
  -                                throw new Error("Stateful beans not yet 
implemented");
  +                                        // throw new Error("Stateful beans not yet 
implemented");
                  }
               } else // Entity
               {
  -                  con = new EntityContainer();
  -                  
  -//                  con.addInterceptor(new LogInterceptor());
  -//                  con.addInterceptor(new TxInterceptor());
  -                  con.addInterceptor(new EntityInstanceInterceptor());
  -                  con.addInterceptor(new SecurityInterceptor());
  -                  con.addInterceptor(new EntitySynchronizationInterceptor());
  -                 
  -                  con.addInterceptor(con.createContainerInterceptor());
  -                  
  -                               con.setClassLoader(new BeanClassLoader(cl));
  -                  con.setMetaData(bean);
  -                  
  -                  ContainerConfiguration conf = 
jar.getContainerConfigurations().getContainerConfiguration(bean.getConfigurationName());
  -                  
  -                               // Make sure we have a default configuration
  -                               if (conf == null) {
  -                                       
  -                                       log.log("Using default configuration");
  -                                       if (((jBossEntity) 
bean).getPersistenceType().equalsIgnoreCase("bean")) {
  -                                              
  -                                              // BMP case
  -                                              conf =  
jar.getContainerConfigurations().getContainerConfiguration("BMP EntityBean");
  -                                  
  -                                              // Make sure this bean knows the 
configuration he is using
  -                                              bean.setConfigurationName("BMP 
EntityBean");
  -                                      }
  -                                      else { 
  -                                      
  -                                          // CMP case
  -                                              conf =  
jar.getContainerConfigurations().getContainerConfiguration("CMP EntityBean");
  -                                  
  -                                             // Make sure this bean knows the 
configuration he is using
  -                                             bean.setConfigurationName("CMP 
EntityBean");
  -                                      }
  -                               }
  -                  
con.setContainerInvoker((ContainerInvoker)cl.loadClass(conf.getContainerInvoker()).newInstance());
  -                  
((EntityContainer)con).setInstanceCache((InstanceCache)cl.loadClass(conf.getInstanceCache()).newInstance());
  -                  
con.setInstancePool((InstancePool)cl.loadClass(conf.getInstancePool()).newInstance());
  -                  
((EntityContainer)con).setPersistenceManager((EntityPersistenceManager)cl.loadClass(conf.getPersistenceManager()).newInstance());
  -                       
  -//                
con.setTransactionManager((TransactionManager)cl.loadClass(conf.getTransactionManager()).newInstance());
  -                               con.setTransactionManager(new 
org.jboss.tm.TxManager());
  -                  
  -                  containers.add(con);
  -                  
  +                                     // Create container
  +                                     con = new EntityContainer();
  +
  +                                     // Create classloader for this container
  +                                     con.setClassLoader(new BeanClassLoader(cl));
  +                                     
  +                                     // Set metadata
  +                                     con.setMetaData(bean);
  +
  +                                     // Get container configuration
  +                                     ContainerConfiguration conf = 
jar.getContainerConfigurations().getContainerConfiguration(bean.getConfigurationName());
  +
  +                                     // Make sure we have a default configuration
  +                                     if (conf == null) 
  +                                     {
  +                                             log.warning("No configuration chosen. 
Using default configuration");
  +                                             if (((jBossEntity) 
bean).getPersistenceType().equals("Bean")) 
  +                                             {
  +                                                      // BMP case
  +                                                      conf =  
jar.getContainerConfigurations().getContainerConfiguration(DEFAULT_ENTITY_BMP_CONFIGURATION);
  +
  +                                                      // Make sure this bean knows 
the configuration he is using
  +                                                      
bean.setConfigurationName(DEFAULT_ENTITY_BMP_CONFIGURATION);
  +                                             }
  +                                             else 
  +                                             { 
  +                                                     // CMP case
  +                                                     conf =  
jar.getContainerConfigurations().getContainerConfiguration(DEFAULT_ENTITY_CMP_CONFIGURATION);
  +
  +                                                     // Make sure this bean knows 
the configuration he is using
  +                                                     
bean.setConfigurationName(DEFAULT_ENTITY_CMP_CONFIGURATION);
  +                                             }
  +                                     }
  +                                     
  +                                     // Set container invoker
  +                                     
((EntityContainer)con).setContainerInvoker((ContainerInvoker)cl.loadClass(conf.getContainerInvoker()).newInstance());
  +                                     
  +                                     // Set instance cache
  +                                     
((EntityContainer)con).setInstanceCache((InstanceCache)cl.loadClass(conf.getInstanceCache()).newInstance());
  +                                     
  +                                     // Set instance pool
  +                                     
con.setInstancePool((InstancePool)cl.loadClass(conf.getInstancePool()).newInstance());
  +                                     
  +                                     // Set persistence manager
  +                                     
((EntityContainer)con).setPersistenceManager((EntityPersistenceManager)cl.loadClass(conf.getPersistenceManager()).newInstance());
  +                                          
  +
  +                                     // Create interceptors
  +                                     con.addInterceptor(new LogInterceptor());
  +                                     con.addInterceptor(new TxInterceptor());
  +                                     con.addInterceptor(new 
EntityInstanceInterceptor());
  +                                     con.addInterceptor(new SecurityInterceptor());
  +                                     con.addInterceptor(new 
EntitySynchronizationInterceptor());
  +
  +                                     
con.addInterceptor(con.createContainerInterceptor());
  +
  +                                     // Add container to application
  +                                     containers.add(con);
               }
               
  +                             // Set callback to application
               if (con != null)
  -               con.setApplication(app);
  +                      con.setApplication(app);
            }
            
            // Init/Start container
  @@ -244,9 +291,6 @@
            {
               Container con = (Container)containers.get(i);
               
  -            // Register Container with JMX
  -//            server.registerMBean(con, new 
ObjectName("EJB:service=Container,application="+app.getName()+",name="+con.getMetaData().getEjbName()));
  -            
               // Init container
               con.init();
               
  @@ -255,23 +299,29 @@
               log.log("Started: "+con.getMetaData().getEjbName());
            }
            
  -         // Bind in JNDI
  +         // Bind container in global JNDI namespace
            for (int i = 0; i < containers.size(); i++)
            {
               Container con = (Container)containers.get(i);
  -            rebind(ctx, con.getMetaData().getJndiName(), 
con.getContainerInvoker().getEJBHome());
  -            
  -            // Done
  -            log.log("Bound "+con.getMetaData().getEjbName() + " to " + 
con.getMetaData().getJndiName());
  +                             if (con instanceof EntityContainer)
  +                             {
  +                                     rebind(ctx, con.getMetaData().getJndiName(), 
((EntityContainer)con).getContainerInvoker().getEJBHome());
  +                                     
  +                                     // Done
  +                                     log.log("Bound 
"+con.getMetaData().getEjbName() + " to " + con.getMetaData().getJndiName());
  +                             } else if (con instanceof StatelessSessionContainer)
  +                             {
  +                                     rebind(ctx, con.getMetaData().getJndiName(), 
((StatelessSessionContainer)con).getContainerInvoker().getEJBHome());
  +                                     
  +                                     // Done
  +                                     log.log("Bound 
"+con.getMetaData().getEjbName() + " to " + con.getMetaData().getJndiName());
  +                             }
            }
            
            // Add to webserver so client can access classes through dynamic class 
downloading
            WebProviderMBean webServer = 
(WebProviderMBean)MBeanProxy.create(WebProviderMBean.class, 
WebProviderMBean.OBJECT_NAME);
            webServer.addClassLoader(cl);
            
  -         // Register Application with JMX
  -//         server.registerMBean(app, new 
ObjectName("EJB:service=Application,name="+app.getName()));
  -         
            // Done
            log.log("Deployed application: "+app.getName());
               
  @@ -297,6 +347,7 @@
      public void undeploy(URL url)
         throws DeploymentException
      {
  +             // Get application from table
         Application app = (Application)deployments.get(url);
         
         // Check if deployed
  @@ -310,7 +361,6 @@
         log.log("Undeploying:"+url);
         try
         {
  -         
            // Unbind in JNDI
            Iterator enum = app.getContainers().iterator();
            Context ctx = new InitialContext();
  @@ -329,14 +379,14 @@
            {
               Container con = (Container)enum.next();
               
  -            // Init container
  +            // Stop container
               con.stop();
               
  -            // Start
  +            // Destroy container
               con.destroy();
               
               // Done
  -            log.log("Removed: "+con.getMetaData().getJndiName());
  +            log.log("Removed: "+con.getMetaData().getEjbName());
            }
            
            // Remove deployment
  @@ -346,6 +396,9 @@
            log.log("Undeployed application: "+app.getName());
         } catch (Exception e)
         {
  +         log.error("Undeploy failed");
  +         log.exception(e);
  +                     
            throw new DeploymentException("Undeploy failed", e);
         } finally
         {
  
  
  
  1.2       +23 -0     jboss/src/main/org/jboss/ejb/ContainerFactoryMBean.java
  
  Index: ContainerFactoryMBean.java
  ===================================================================
  RCS file: 
/products/cvs/ejboss/jboss/src/main/org/jboss/ejb/ContainerFactoryMBean.java,v
  retrieving revision 1.1
  retrieving revision 1.2
  diff -u -r1.1 -r1.2
  --- ContainerFactoryMBean.java        2000/04/22 14:30:13     1.1
  +++ ContainerFactoryMBean.java        2000/05/30 18:32:16     1.2
  @@ -8,15 +8,38 @@
   
   import java.net.MalformedURLException;
   
  +/**
  + *   This is the interface of the ContainerFactory that is exposed for 
administration
  + *      
  + *   @see ContainerFactory
  + *   @author Rickard �berg ([EMAIL PROTECTED])
  + *   @version $Revision: 1.2 $
  + */
   public interface ContainerFactoryMBean
   {
      // Constants -----------------------------------------------------
      public static String OBJECT_NAME = "EJB:service=ContainerFactory";
       
      // Public --------------------------------------------------------
  +
  +     /**
  +      *      Deploy an application
  +      *
  +      * @param   url  
  +      * @exception   MalformedURLException  
  +      * @exception   DeploymentException  
  +      */
      public void deploy(String url)
         throws MalformedURLException, DeploymentException;
         
  +
  +     /**
  +      *      Undeploy an application
  +      *
  +      * @param   url  
  +      * @exception   MalformedURLException  
  +      * @exception   DeploymentException  
  +      */
      public void undeploy(String url)
         throws MalformedURLException, DeploymentException;
   }
  
  
  
  1.2       +62 -16    jboss/src/main/org/jboss/ejb/ContainerInvoker.java
  
  Index: ContainerInvoker.java
  ===================================================================
  RCS file: /products/cvs/ejboss/jboss/src/main/org/jboss/ejb/ContainerInvoker.java,v
  retrieving revision 1.1
  retrieving revision 1.2
  diff -u -r1.1 -r1.2
  --- ContainerInvoker.java     2000/04/22 14:30:10     1.1
  +++ ContainerInvoker.java     2000/05/30 18:32:16     1.2
  @@ -15,42 +15,88 @@
   import javax.naming.Name;
   
   /**
  - *   <description> 
  - *      
  - *   @see <related>
  + *   This is an interface for Container plugins. Implementations of this
  + *   interface are responsible for receiving remote invocations of EJB's
  + *   and to forward these requests to the Container it is being used with.
  + *
  + *   It is responsible for providing any EJBObject and EJBHome implementations 
  + *   (which may be statically or dynamically created). 
  + *
  + *   Before forwarding a call to the container it must call 
Thread.setContextClassLoader()
  + *   with the classloader of the container. It must also handle any propagated 
transaction
  + *   and security contexts properly. It may acquire the TransactionManager from 
JNDI.
  + *
  + *   @see Container
    *   @author Rickard �berg ([EMAIL PROTECTED])
  - *   @version $Revision: 1.1 $
  + *   @version $Revision: 1.2 $
    */
   public interface ContainerInvoker
      extends ContainerPlugin
   {
  -   // Constants -----------------------------------------------------
  -    
  -   // Static --------------------------------------------------------
  -   
      // Public --------------------------------------------------------
  +
  +     /**
  +      *      This method is called whenever the metadata for this container is
  +      *      needed.
  +      *
  +      * @return     an implementation of the EJBMetaData interface
  +      */
      public EJBMetaData getEJBMetaData();
      
  +
  +     /**
  +      *      This method is called whenever the EJBHome implementation for this
  +      *      container is needed.
  +      *
  +      * @return     an implementation of the home interface for this container
  +      */
      public EJBHome getEJBHome();
      
  +
  +     /**
  +      *      This method is called whenever an EJBObject implementation for a 
stateless
  +      *      session bean is needed.
  +      *
  +      * @return     an implementation of the remote interface for this container
  +      * @exception   RemoteException  thrown if the EJBObject could not be created
  +      */
      public EJBObject getStatelessSessionEJBObject()
         throws RemoteException;
   
  +
  +     /**
  +      *      This method is called whenever an EJBObject implementation for a 
stateful
  +      *      session bean is needed.
  +      *
  +      * @param   id  the id of the session
  +      * @return     an implementation of the remote interface for this container
  +      * @exception   RemoteException  thrown if the EJBObject could not be created
  +      */
      public EJBObject getStatefulSessionEJBObject(Object id)
         throws RemoteException;
   
  +
  +     /**
  +      *      This method is called whenever an EJBObject implementation for an 
entitybean
  +      * is needed.
  +      *
  +      * @param   id  the primary key of the entity
  +      * @return     an implementation of the remote interface for this container
  +      * @exception   RemoteException  thrown if the EJBObject could not be created
  +      */
      public EJBObject getEntityEJBObject(Object id)
         throws RemoteException;
   
  +
  +     /**
  +      *      This method is called whenever a collection of EJBObjects for a 
collection of primary keys
  +      * is needed.
  +      *
  +      * @param   enum  enumeration of primary keys
  +      * @return     a collection of EJBObjects implementing the remote interface 
for this container
  +      * @exception   RemoteException  thrown if the EJBObjects could not be created
  +      */
      public Collection getEntityCollection(Collection enum)
         throws RemoteException;
  -      
  -   // Package protected ---------------------------------------------
  -    
  -   // Protected -----------------------------------------------------
  -    
  -   // Private -------------------------------------------------------
  -
  -   // Inner classes -------------------------------------------------
   }
   
  
  
  
  1.3       +9 -13     jboss/src/main/org/jboss/ejb/ContainerPlugin.java
  
  Index: ContainerPlugin.java
  ===================================================================
  RCS file: /products/cvs/ejboss/jboss/src/main/org/jboss/ejb/ContainerPlugin.java,v
  retrieving revision 1.2
  retrieving revision 1.3
  diff -u -r1.2 -r1.3
  --- ContainerPlugin.java      2000/05/29 16:06:27     1.2
  +++ ContainerPlugin.java      2000/05/30 18:32:16     1.3
  @@ -9,25 +9,21 @@
   import org.jboss.util.Service;
   
   /**
  - *   <description> 
  + *   This is a superinterface for all Container plugins. All plugin interfaces
  + *     must extend this interface.
    *      
  - *   @see <related>
  + *   @see Service
    *   @author Rickard �berg ([EMAIL PROTECTED])
  - *   @version $Revision: 1.2 $
  + *   @version $Revision: 1.3 $
    */
   public interface ContainerPlugin
      extends Service
   {
  -   // Constants -----------------------------------------------------
  -    
  -   // Static --------------------------------------------------------
  -
      // Public --------------------------------------------------------
  -
  -   /**
  -    *
  -    *
  -    * @return     
  -    */
  +     /**
  +      *      This callback is set by the container so that the plugin may access it
  +      *
  +      * @param   con  the container using this plugin
  +      */
      public void setContainer(Container con);
   }
  
  
  
  1.3       +6 -5      jboss/src/main/org/jboss/ejb/DeploymentException.java
  
  Index: DeploymentException.java
  ===================================================================
  RCS file: 
/products/cvs/ejboss/jboss/src/main/org/jboss/ejb/DeploymentException.java,v
  retrieving revision 1.2
  retrieving revision 1.3
  diff -u -r1.2 -r1.3
  --- DeploymentException.java  2000/05/19 07:11:48     1.2
  +++ DeploymentException.java  2000/05/30 18:32:16     1.3
  @@ -7,17 +7,18 @@
   package org.jboss.ejb;
   
   /**
  - *      
  - *   @see <related>
  + *   This exception is thrown by the ContainerFactory if an EJB application
  + *   could not be deployed
  + *
  + *   @see ContainerFactory
    *   @author Rickard �berg ([EMAIL PROTECTED])
  - *   @version $Revision: 1.2 $
  + *   @version $Revision: 1.3 $
    */
   public class DeploymentException
      extends Exception
   {
  -   // Constants -----------------------------------------------------
  -    
      // Attributes ----------------------------------------------------
  +     // The root cause of this exception
      Exception cause;
      
      // Static --------------------------------------------------------
  
  
  
  1.3       +9 -1      jboss/src/main/org/jboss/ejb/EJBClassLoader.java
  
  Index: EJBClassLoader.java
  ===================================================================
  RCS file: /products/cvs/ejboss/jboss/src/main/org/jboss/ejb/EJBClassLoader.java,v
  retrieving revision 1.2
  retrieving revision 1.3
  diff -u -r1.2 -r1.3
  --- EJBClassLoader.java       2000/05/22 15:03:01     1.2
  +++ EJBClassLoader.java       2000/05/30 18:32:16     1.3
  @@ -17,7 +17,7 @@
    *      
    *   @see <related>
    *   @author Rickard �berg ([EMAIL PROTECTED])
  - *   @version $Revision: 1.2 $
  + *   @version $Revision: 1.3 $
    */
   public class EJBClassLoader
      extends URLClassLoader
  @@ -25,6 +25,7 @@
      // Constants -----------------------------------------------------
       
      // Attributes ----------------------------------------------------
  +     // The permissions given to restricted EJB classes
      Permissions perms;
      
      boolean secure; // True -> Enforce EJB restrictions
  @@ -45,5 +46,12 @@
      }
      
      // Public --------------------------------------------------------
  +   protected PermissionCollection getPermissions(CodeSource source)
  +   {
  +      if (secure)
  +         return perms;
  +      else
  +         return super.getPermissions(source);
  +   }
   }
   
  
  
  
  1.2       +91 -26    jboss/src/main/org/jboss/ejb/EnterpriseContext.java
  
  Index: EnterpriseContext.java
  ===================================================================
  RCS file: /products/cvs/ejboss/jboss/src/main/org/jboss/ejb/EnterpriseContext.java,v
  retrieving revision 1.1
  retrieving revision 1.2
  diff -u -r1.1 -r1.2
  --- EnterpriseContext.java    2000/04/22 14:30:10     1.1
  +++ EnterpriseContext.java    2000/05/30 18:32:16     1.2
  @@ -24,24 +24,31 @@
   import javax.transaction.HeuristicMixedException;
   import javax.transaction.HeuristicRollbackException;
   
  +import org.jboss.logging.Logger;
  +
   /**
  - *   <description> 
  - *      
  - *   @see <related>
  + *   The EnterpriseContext is used to associate EJB instances with metadata about 
it.
  + *   
  + *   @see StatefulSessionEnterpriseContext
  + *   @see StatelessSessionEnterpriseContext
  + *   @see EntityEnterpriseContext
    *   @author Rickard �berg ([EMAIL PROTECTED])
  - *   @version $Revision: 1.1 $
  + *   @version $Revision: 1.2 $
    */
   public abstract class EnterpriseContext
   {
      // Constants -----------------------------------------------------
       
      // Attributes ----------------------------------------------------
  +     // The EJB instanfce
      Object instance;
  +     
  +     // The container using this context
      Container con;
  -   Transaction tx;
  +     
  +     // Set to the synchronization currently associated with this context. May be 
null
      Synchronization synch;
  -   Principal principal;
  -    
  +     
      Object id; // Not used for sessions
      // Static --------------------------------------------------------
      
  @@ -53,19 +60,23 @@
      }
      
      // Public --------------------------------------------------------
  -   public Object getInstance() { return instance; }
  +   public Object getInstance() 
  +     { 
  +             return instance; 
  +     }
      
      public abstract void discard()
         throws RemoteException;
         
  -   public void setPrincipal(Principal p) { principal = p; }
  -   public Principal getPrincipal(Principal p) { return principal; }
  -   
  -   public void setTransaction(Transaction tx) { this.tx = tx; }
  -   public Transaction getTransaction() { return tx; }
  -   
  -   public void setId(Object id) { this.id = id; }
  -   public Object getId() { return id; }
  +   public void setId(Object id) 
  +     { 
  +             this.id = id; 
  +     }
  +     
  +   public Object getId() 
  +     { 
  +             return id; 
  +     }
   
      // Package protected ---------------------------------------------
       
  @@ -77,16 +88,45 @@
      protected class EJBContextImpl
         implements EJBContext
      {
  -      public Identity getCallerIdentity() { throw new EJBException("Deprecated"); }
  +      /**
  +       *
  +       *
  +       * @deprecated
  +       */
  +      public Identity getCallerIdentity() 
  +             { 
  +                     throw new EJBException("Deprecated"); 
  +             }
         
  -      public Principal getCallerPrincipal() { return principal; }
  +      public Principal getCallerPrincipal() 
  +             { 
  +                     throw new Error("Not yet implemented");
  +             }
         
         public EJBHome getEJBHome() 
         { 
  -         return con.getContainerInvoker().getEJBHome(); 
  +                     if (con instanceof EntityContainer)
  +                     {
  +                             return 
((EntityContainer)con).getContainerInvoker().getEJBHome(); 
  +                     } if (con instanceof StatelessSessionContainer)
  +                     {
  +                             return 
((StatelessSessionContainer)con).getContainerInvoker().getEJBHome(); 
  +                     } else
  +                     {
  +                             // Should never get here
  +                             throw new EJBException("No EJBHome available (BUG!)");
  +                     }
         }
         
  -      public Properties getEnvironment() { throw new EJBException("Deprecated"); }
  +      /**
  +       *
  +       *
  +       * @deprecated
  +       */
  +      public Properties getEnvironment() 
  +             { 
  +                     throw new EJBException("Deprecated"); 
  +             }
         
         public boolean getRollbackOnly() 
         { 
  @@ -95,22 +135,47 @@
               return con.getTransactionManager().getStatus() == 
Status.STATUS_MARKED_ROLLBACK; 
            } catch (SystemException e)
            {
  +            Logger.debug(e);
               return true;
            }
         }
          
  -      public void setRollbackOnly() { }
  -   
  -      public boolean isCallerInRole(Identity id) { throw new 
EJBException("Deprecated"); }
  +      public void setRollbackOnly() 
  +             { 
  +                     try
  +                     {
  +                             con.getTransactionManager().setRollbackOnly();
  +                     } catch (SystemException e)
  +                     {
  +                             Logger.debug(e);
  +                     }
  +             }
  +   
  +      /**
  +       *
  +       *
  +       * @deprecated
  +       */
  +      public boolean isCallerInRole(Identity id) 
  +             { 
  +                     throw new EJBException("Deprecated"); 
  +             }
      
         // TODO - how to handle this best?
  -      public boolean isCallerInRole(String id) { return false; }
  +      public boolean isCallerInRole(String id) 
  +             { 
  +                     return false; 
  +             }
      
         // TODO - how to handle this best?
  -      public UserTransaction getUserTransaction() { return new 
UserTransactionImpl(); }
  +      public UserTransaction getUserTransaction() 
  +             { 
  +                     return new UserTransactionImpl(); 
  +             }
      }
      
  -   protected class UserTransactionImpl
  +     // Inner classes -------------------------------------------------
  +   class UserTransactionImpl
         implements UserTransaction
      {
         public void begin()
  
  
  
  1.4       +137 -80   jboss/src/main/org/jboss/ejb/EntityContainer.java
  
  Index: EntityContainer.java
  ===================================================================
  RCS file: /products/cvs/ejboss/jboss/src/main/org/jboss/ejb/EntityContainer.java,v
  retrieving revision 1.3
  retrieving revision 1.4
  diff -u -r1.3 -r1.4
  --- EntityContainer.java      2000/05/24 06:54:37     1.3
  +++ EntityContainer.java      2000/05/30 18:32:16     1.4
  @@ -24,14 +24,15 @@
   import javax.ejb.FinderException;
   import javax.ejb.RemoveException;
   
  -import org.jboss.logging.Log;
  +import org.jboss.logging.Logger;
   
   /**
  - *   <description> 
  + *   This is a Container for EntityBeans (both BMP and CMP).
    *      
  - *   @see <related>
  + *   @see Container
  + *   @see EntityEnterpriseContext
    *   @author Rickard �berg ([EMAIL PROTECTED])
  - *   @version $Revision: 1.3 $
  + *   @version $Revision: 1.4 $
    */
   public class EntityContainer
      extends Container
  @@ -39,24 +40,48 @@
      // Constants -----------------------------------------------------
       
      // Attributes ----------------------------------------------------
  -   Map createMapping;
  -   Map postCreateMapping;
  -   Map homeMapping;
  -   Map beanMapping;
  +     
  +     // These are the mappings between the create methods and the ejbCreate methods
  +   protected Map createMapping;
  +     
  +   // These are the mappings between the create methods and the ejbPostCreate 
methods
  +   protected Map postCreateMapping;
  +     
  +   // 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
  +   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;
      
  -   Log log;
  -   
  -   EntityPersistenceManager persistenceManager;
  -   InstanceCache instanceCache;
  -   
  -   // Static --------------------------------------------------------
  -
  -   // Constructors --------------------------------------------------
  -   
      // 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 void setInstanceCache(InstanceCache ic)
      { 
  +      if (ic == null)
  +             throw new IllegalArgumentException("Null cache");
  +                     
         this.instanceCache = ic; 
         ic.setContainer(this);
      }
  @@ -66,9 +91,16 @@
         return instanceCache; 
      }
      
  -   public EntityPersistenceManager getPersistenceManager() { return 
persistenceManager; }
  +   public EntityPersistenceManager getPersistenceManager() 
  +     { 
  +             return persistenceManager; 
  +     }
  +     
      public void setPersistenceManager(EntityPersistenceManager pm) 
      { 
  +      if (pm == null)
  +             throw new IllegalArgumentException("Null persistence manager");
  +                     
         persistenceManager = pm; 
         pm.setContainer(this);
      }
  @@ -77,55 +109,94 @@
      public void init()
         throws Exception
      {
  +             // Associate thread with classloader
         ClassLoader oldCl = Thread.currentThread().getContextClassLoader();
         Thread.currentThread().setContextClassLoader(getClassLoader());
  -      
  -      log = new Log(getMetaData().getEjbName() + " EJB");
         
  +             // Call default init
         super.init();
         
  +      // Init container invoker
  +      containerInvoker.init();
  +             
  +      // Init instance cache
  +      instanceCache.init();
  +             
         // Init persistence
         persistenceManager.init();
         
         setupBeanMapping();
         setupHomeMapping();
         
  +      // 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
  +      containerInvoker.start();
  +      
  +      // Start instance cache
  +      instanceCache.start();
  +      
         // Start persistence
         persistenceManager.start();
         
  +             // Reset classloader
         Thread.currentThread().setContextClassLoader(oldCl);
      }
      
      public void stop()
      {
  +      // Associate thread with classloader
         ClassLoader oldCl = Thread.currentThread().getContextClassLoader();
         Thread.currentThread().setContextClassLoader(getClassLoader());
  -      
  -      // Stop persistence
  -      persistenceManager.stop();
  -      
  +             
  +             // Call default stop
         super.stop();
  -      
  -      Thread.currentThread().setContextClassLoader(oldCl);
  +             
  +        // Stop container invoker
  +        containerInvoker.stop();
  +        
  +        // Stop instance cache
  +        instanceCache.stop();
  +        
  +        // Stop persistence
  +        persistenceManager.stop();
  +        
  +        // Reset classloader
  +        Thread.currentThread().setContextClassLoader(oldCl);
      }
      
      public void destroy()
      {
  -      // Destroy persistence
  -      persistenceManager.destroy();
  -      
  -      super.destroy();
  +        // Associate thread with classloader
  +        ClassLoader oldCl = Thread.currentThread().getContextClassLoader();
  +        Thread.currentThread().setContextClassLoader(getClassLoader());
  +        
  +        // Call default destroy
  +        super.destroy();
  +        
  +        // Destroy container invoker
  +        containerInvoker.destroy();
  +        
  +        // Destroy instance cache
  +        instanceCache.destroy();
  +        
  +        // Destroy persistence
  +        persistenceManager.destroy();
  +        
  +        // Reset classloader
  +        Thread.currentThread().setContextClassLoader(oldCl);
      }
      
      public Object invokeHome(Method method, Object[] args)
  @@ -134,16 +205,6 @@
           return getInterceptor().invokeHome(method, args, null);
      }
   
  -   /**
  -    *   This method retrieves the instance from an object table, and invokes the 
method
  -    *   on the particular instance through the chain of interceptors
  -    *
  -    * @param   id  
  -    * @param   m  
  -    * @param   args  
  -    * @return     
  -    * @exception   Exception  
  -    */
      public Object invoke(Object id, Method method, Object[] args)
         throws Exception
      {
  @@ -163,14 +224,14 @@
         throws java.rmi.RemoteException
      {
         // TODO
  -      return null;
  +             throw new Error("Not yet implemented");
      }
   
      public Object getPrimaryKey(Method m, Object[] args, EntityEnterpriseContext ctx)
         throws java.rmi.RemoteException
      {
         // TODO
  -      return null;
  +      throw new Error("Not yet implemented");
      }
      
      public EJBHome getEJBHome(Method m, Object[] args, EntityEnterpriseContext ctx)
  @@ -182,7 +243,8 @@
      public boolean isIdentical(Method m, Object[] args, EntityEnterpriseContext ctx)
         throws java.rmi.RemoteException
      {
  -      return false; // TODO
  +             return ((EJBObject)args[0]).getPrimaryKey().equals(ctx.getId());
  +             // TODO - should also check type
      }
      
      // Home interface implementation ---------------------------------
  @@ -214,7 +276,7 @@
      public void removeHome(Method m, Object[] args, EntityEnterpriseContext ctx)
         throws java.rmi.RemoteException, RemoveException
      {
  -      // TODO
  +      throw new Error("Not yet implemented");
      }
      
      public EJBMetaData getEJBMetaDataHome(Method m, Object[] args, 
EntityEnterpriseContext ctx)
  @@ -227,52 +289,58 @@
         throws java.rmi.RemoteException   
      {
         // TODO
  -      return null;
  +      throw new Error("Not yet implemented");
      }
         
      // Private -------------------------------------------------------
      protected void setupHomeMapping()
  -      throws NoSuchMethodException
  +      throws DeploymentException
      {
         Map map = new HashMap();
         
         Method[] m = homeInterface.getMethods();
         for (int i = 0; i < m.length; i++)
         {
  -         // Implemented by container
  -         if (m[i].getName().startsWith("find"))
  -            map.put(m[i], getClass().getMethod("find", new Class[] { Method.class, 
Object[].class, EntityEnterpriseContext.class }));
  -         else            
  -            map.put(m[i], getClass().getMethod(m[i].getName()+"Home", new Class[] { 
Method.class, Object[].class, EntityEnterpriseContext.class }));
  +                     try
  +                     {
  +              // Implemented by container
  +              if (m[i].getName().startsWith("find"))
  +                 map.put(m[i], getClass().getMethod("find", new Class[] { 
Method.class, Object[].class, EntityEnterpriseContext.class }));
  +              else            
  +                 map.put(m[i], getClass().getMethod(m[i].getName()+"Home", new 
Class[] { Method.class, Object[].class, EntityEnterpriseContext.class }));
  +                     } catch (NoSuchMethodException e)
  +                     {
  +                             throw new DeploymentException("Could not find matching 
method for "+m[i], e);
  +                     }
         }
         
         homeMapping = map;
      }
   
      protected void setupBeanMapping()
  -      throws NoSuchMethodException
  +      throws DeploymentException
      {
         Map map = new HashMap();
         
         Method[] m = remoteInterface.getMethods();
         for (int i = 0; i < m.length; i++)
         {
  -         if (!m[i].getDeclaringClass().equals(EJBObject.class))
  -         {
  -            // Implemented by bean
  -            map.put(m[i], beanClass.getMethod(m[i].getName(), 
m[i].getParameterTypes()));
  -         }
  -         else
  -         {
  -            try
  -            {
  +                     try
  +                     {
  +              if (!m[i].getDeclaringClass().equals(EJBObject.class))
  +              {
  +                 // Implemented by bean
  +                 map.put(m[i], beanClass.getMethod(m[i].getName(), 
m[i].getParameterTypes()));
  +              }
  +              else
  +              {
                  // Implemented by container
                  map.put(m[i], getClass().getMethod(m[i].getName(), new Class[] { 
Method.class, Object[].class , EntityEnterpriseContext.class}));
  -            } catch (NoSuchMethodException e)
  -            {
  -               System.out.println(m[i].getName() + " in bean has not been mapped");
  -            }
  -         }
  +              }
  +           } catch (NoSuchMethodException e)
  +           {
  +             throw new DeploymentException("Could not find matching method for 
"+m[i], e);
  +           }
         }
         
         beanMapping = map;
  @@ -283,6 +351,7 @@
         return new ContainerInterceptor();
      }
      
  +     // Inner classes -------------------------------------------------
      // This is the last step before invocation - all interceptors are done
      class ContainerInterceptor
         implements Interceptor
  @@ -303,7 +372,6 @@
            Method m = (Method)homeMapping.get(method);
            // Invoke and handle exceptions
            
  -         Log.setLog(log);
            try
            {
               return m.invoke(EntityContainer.this, new Object[] { method, args, 
ctx});
  @@ -314,9 +382,6 @@
                  throw (Exception)ex;
               else
                  throw (Error)ex;
  -         } finally
  -         {
  -            Log.unsetLog();
            }
         }
            
  @@ -330,7 +395,6 @@
            if (m.getDeclaringClass().equals(EntityContainer.this.getClass()))
            {
               // Invoke and handle exceptions
  -            Log.setLog(log);
               try
               {
                  return m.invoke(EntityContainer.this, new Object[] { method, args, 
ctx });
  @@ -341,14 +405,10 @@
                     throw (Exception)ex;
                  else
                     throw (Error)ex;
  -            } finally
  -            {
  -               Log.unsetLog();
  -            }
  +            } 
            } else
            {
               // Invoke and handle exceptions
  -            Log.setLog(log);
               try
               {
                  return m.invoke(ctx.getInstance(), args);
  @@ -359,10 +419,7 @@
                     throw (Exception)ex;
                  else
                     throw (Error)ex;
  -            } finally
  -            {
  -               Log.unsetLog();
  -            }
  +            } 
            }
         }
      }
  
  
  
  1.2       +74 -26    jboss/src/main/org/jboss/ejb/EntityEnterpriseContext.java
  
  Index: EntityEnterpriseContext.java
  ===================================================================
  RCS file: 
/products/cvs/ejboss/jboss/src/main/org/jboss/ejb/EntityEnterpriseContext.java,v
  retrieving revision 1.1
  retrieving revision 1.2
  diff -u -r1.1 -r1.2
  --- EntityEnterpriseContext.java      2000/04/22 14:30:10     1.1
  +++ EntityEnterpriseContext.java      2000/05/30 18:32:16     1.2
  @@ -13,28 +13,37 @@
   import javax.ejb.EntityBean;
   import javax.ejb.EntityContext;
   
  +import javax.transaction.Transaction;
  +
   /**
  - *   <description> 
  + *   The EntityEnterpriseContext is used to associate EntityBean instances with 
metadata about it.
    *      
  - *   @see <related>
  + *   @see EnterpriseContext
    *   @author Rickard �berg ([EMAIL PROTECTED])
  - *   @version $Revision: 1.1 $
  + *   @version $Revision: 1.2 $
    */
   public class EntityEnterpriseContext
      extends EnterpriseContext
   {
  -   // Constants -----------------------------------------------------
  -    
      // Attributes ----------------------------------------------------
      EJBObject ejbObject;
  +     
  +     // True if this instance has been invoked since it was synchronized with DB
  +     // If true, then we have to store it to synch back to DB
      boolean invoked = false;
  +     
  +     // True if this instances' state is synchronized with the DB
      boolean synched = false;
      
  +   // Set to the tx currently using this context. May be null
  +   Transaction tx;
  +     
  +     // The instance cache may attach any metadata it wishes to this context here
      Object cacheCtx;
  +     
  +   // The persistence manager may attach any metadata it wishes to this context here
      Object persistenceCtx;
       
  -   // Static --------------------------------------------------------
  -   
      // Constructors --------------------------------------------------
      public EntityEnterpriseContext(Object instance, Container con)
         throws RemoteException
  @@ -49,28 +58,67 @@
      {
         ((EntityBean)instance).unsetEntityContext();
      }
  -   
  -   public void setEJBObject(EJBObject eo) { ejbObject = eo; }
  -   public EJBObject getEJBObject() { return ejbObject; }
  -   
  -   public void setPersistenceContext(Object ctx) { this.persistenceCtx = ctx; }
  -   public Object getPersistenceContext() { return persistenceCtx; }
      
  -   public void setCacheContext(Object ctx) { this.cacheCtx = ctx; }
  -   public Object getCacheContext() { return cacheCtx; }
  -   
  -   public void setInvoked(boolean invoked) { this.invoked = invoked; }
  -   public boolean isInvoked() { return invoked; }
  +   public void setEJBObject(EJBObject eo) 
  +     { 
  +             ejbObject = eo; 
  +     }
  +     
  +   public EJBObject getEJBObject() 
  +     { 
  +             return ejbObject; 
  +     }
  +   
  +   public void setTransaction(Transaction tx) 
  +     { 
  +             this.tx = tx; 
  +     }
  +     
  +   public Transaction getTransaction() 
  +     { 
  +             return tx; 
  +     }
  +     
  +   public void setPersistenceContext(Object ctx) 
  +     { 
  +             this.persistenceCtx = ctx; 
  +     }
  +     
  +   public Object getPersistenceContext() 
  +     { 
  +             return persistenceCtx; 
  +     }
  +   
  +   public void setCacheContext(Object ctx) 
  +     { 
  +             this.cacheCtx = ctx; 
  +     }
  +     
  +   public Object getCacheContext() 
  +     { 
  +             return cacheCtx; 
  +     }
  +   
  +   public void setInvoked(boolean invoked) 
  +     { 
  +             this.invoked = invoked; 
  +     }
  +     
  +   public boolean isInvoked() 
  +     { 
  +             return invoked; 
  +     }
   
  -   public void setSynchronized(boolean synched) { this.synched = synched; }
  -   public boolean isSynchronized() { return synched; }
  +   public void setSynchronized(boolean synched) 
  +     { 
  +             this.synched = synched; 
  +     }
  +     
  +   public boolean isSynchronized() 
  +     { 
  +             return synched; 
  +     }
      
  -   // Package protected ---------------------------------------------
  -    
  -   // Protected -----------------------------------------------------
  -    
  -   // Private -------------------------------------------------------
  -
      // Inner classes -------------------------------------------------
      protected class EntityContextImpl
         extends EJBContextImpl
  
  
  
  1.2       +86 -22    jboss/src/main/org/jboss/ejb/EntityPersistenceManager.java
  
  Index: EntityPersistenceManager.java
  ===================================================================
  RCS file: 
/products/cvs/ejboss/jboss/src/main/org/jboss/ejb/EntityPersistenceManager.java,v
  retrieving revision 1.1
  retrieving revision 1.2
  diff -u -r1.1 -r1.2
  --- EntityPersistenceManager.java     2000/04/22 14:30:10     1.1
  +++ EntityPersistenceManager.java     2000/05/30 18:32:16     1.2
  @@ -15,55 +15,119 @@
   import javax.ejb.RemoveException;
   
   /**
  - *   <description> 
  - *      
  - *   @see <related>
  + *   This interface is implemented by any EntityBean persistence managers plugins.
  + *
  + *   Implementations of this interface are called by other plugins in the container.
  + *
  + *   If the persistence manager wants to, it may attach any instance specific 
metadata
  + *   to the EntityEnterpriseContext that is passed in method calls.
  + *
  + *   @see EntityContainer
    *   @author Rickard �berg ([EMAIL PROTECTED])
  - *   @version $Revision: 1.1 $
  + *   @version $Revision: 1.2 $
    */
   public interface EntityPersistenceManager
      extends ContainerPlugin
   {
  -   // Constants -----------------------------------------------------
  -    
  -   // Attributes ----------------------------------------------------
  -    
  -   // Static --------------------------------------------------------
  -   
  -   // Constructors --------------------------------------------------
  -   
      // Public --------------------------------------------------------
  +
  +     /**
  +      *      This method is called whenever an entity is to be created. The 
persistence manager
  +      *      is responsible for calling the ejbCreate methods on the instance and 
to handle the results
  +      *      properly wrt the persistent store.
  +      *
  +      * @param   m  the create method in the home interface that was called
  +      * @param   args  any create parameters
  +      * @param   instance  the instance being used for this create call
  +      * @exception   RemoteException  thrown if some system exception occurs
  +      * @exception   CreateException  thrown if some heuristic problem occurs
  +      */
      public void createEntity(Method m, Object[] args, EntityEnterpriseContext 
instance)
         throws RemoteException, CreateException;
   
  +     /**
  +      *      This method is called when single entities are to be found. The 
persistence manager must find out
  +      *      whether the wanted instance is available in the persistence store, and 
if so it shall use the ContainerInvoker
  +      *      plugin to create an EJBObject to the instance, which is to be returned 
as result.
  +      *
  +      * @param   finderMethod  the find method in the home interface that was called
  +      * @param   args  any finder parameters
  +      * @param   instance  the instance to use for the finder call
  +      * @return     an EJBObject representing the found entity
  +      * @exception   RemoteException  thrown if some system exception occurs
  +      * @exception   FinderException  thrown if some heuristic problem occurs
  +      */
      public Object findEntity(Method finderMethod, Object[] args, 
EntityEnterpriseContext instance)
         throws RemoteException, FinderException;
  -      
  +
  +     /**
  +      *      This method is called when collections of entities are to be found. 
The persistence manager must find out
  +      *      whether the wanted instances are available in the persistence store, 
and if so it shall use the ContainerInvoker
  +      *      plugin to create EJBObjects to the instances, which are to be returned 
as result.
  +      *
  +      * @param   finderMethod  the find method in the home interface that was called
  +      * @param   args  any finder parameters
  +      * @param   instance  the instance to use for the finder call
  +      * @return     an EJBObject collection representing the found entities
  +      * @exception   RemoteException  thrown if some system exception occurs
  +      * @exception   FinderException  thrown if some heuristic problem occurs
  +      */
      public Collection findEntities(Method finderMethod, Object[] args, 
EntityEnterpriseContext instance)
         throws RemoteException, FinderException;
   
  +
  +     /**
  +      * This method is called when an entity shall be activated. The persistence 
manager must call the ejbActivate
  +      *      method on the instance.                                                
                                                                                       
                                                                                       
         
  +      *
  +      * @param   instance  the instance to use for the activation
  +      * @exception   RemoteException  thrown if some system exception occurs
  +      */
      public void activateEntity(EntityEnterpriseContext instance)
         throws RemoteException;
      
  +
  +     /**
  +      *      This method is called whenever an entity shall be load from the 
underlying storage. The persistence manager
  +      *      must load the state from the underlying storage and then call ejbLoad 
on the supplied instance.
  +      *
  +      * @param   instance  the instance to synchronize
  +      * @exception   RemoteException  thrown if some system exception occurs
  +      */
      public void loadEntity(EntityEnterpriseContext instance)
         throws RemoteException;
         
  +     /**
  +      *      This method is called whenever an entity shall be stored to the 
underlying storage. The persistence manager
  +      *      must call ejbStore on the supplied instance and then store the state 
to the underlying storage.
  +      *
  +      * @param   instance  the instance to synchronize
  +      * @exception   RemoteException  thrown if some system exception occurs
  +      */
      public void storeEntity(EntityEnterpriseContext instance)
         throws RemoteException;
   
  +
  +     /**
  +      * This method is called when an entity shall be passivate. The persistence 
manager must call the ejbPassivate
  +      *      method on the instance.                                                
                                                                                       
                                                                                       
         
  +      *
  +      * @param   instance  the instance to passivate
  +      * @exception   RemoteException  thrown if some system exception occurs
  +      */
      public void passivateEntity(EntityEnterpriseContext instance)
         throws RemoteException;
         
  +
  +     /**
  +      * This method is called when an entity shall be removed from the underlying 
storage. The persistence manager 
  +      *      must call ejbRemove on the instance and then remove its state from the 
underlying storage.
  +      *
  +      * @param   instance  the instance to remove
  +      * @exception   RemoteException  thrown if some system exception occurs
  +      * @exception   RemoveException  thrown if the instance could not be removed
  +      */
      public void removeEntity(EntityEnterpriseContext instance)
         throws RemoteException, RemoveException;
  -   // Z implementation ----------------------------------------------
  -    
  -   // Package protected ---------------------------------------------
  -    
  -   // Protected -----------------------------------------------------
  -    
  -   // Private -------------------------------------------------------
  -
  -   // Inner classes -------------------------------------------------
   }
   
  
  
  
  1.3       +23 -22    jboss/src/main/org/jboss/ejb/StatefulSessionContainer.java
  
  Index: StatefulSessionContainer.java
  ===================================================================
  RCS file: 
/products/cvs/ejboss/jboss/src/main/org/jboss/ejb/StatefulSessionContainer.java,v
  retrieving revision 1.2
  retrieving revision 1.3
  diff -u -r1.2 -r1.3
  --- StatefulSessionContainer.java     2000/05/19 07:11:48     1.2
  +++ StatefulSessionContainer.java     2000/05/30 18:32:16     1.3
  @@ -24,14 +24,14 @@
   import javax.ejb.FinderException;
   import javax.ejb.RemoveException;
   
  -import org.jboss.logging.Log;
  +import org.jboss.logging.Logger;
   
   /**
    *   <description> 
    *      
    *   @see <related>
    *   @author Rickard �berg ([EMAIL PROTECTED])
  - *   @version $Revision: 1.2 $
  + *   @version $Revision: 1.3 $
    */
   public class StatefulSessionContainer
      extends Container
  @@ -44,16 +44,31 @@
      Map homeMapping;
      Map beanMapping;
      
  -   Log log;
  +   // This is the container invoker for this container
  +   protected ContainerInvoker containerInvoker;
  +     
  +   // This is the persistence manager for this container
  +   protected StatefulSessionPersistenceManager persistenceManager;
  +   protected InstanceCache instanceCache;
      
  -   StatefulSessionPersistenceManager persistenceManager;
  -   InstanceCache instanceCache;
  -   
      // Static --------------------------------------------------------
   
      // Constructors --------------------------------------------------
      
      // 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 void setInstanceCache(InstanceCache ic)
      { 
  @@ -84,8 +99,6 @@
         super.start();
         setupBeanMapping();
         setupHomeMapping();
  -      
  -      log = new Log(getMetaData().getEjbName() + " EJB");
      }
      
      public Object invokeHome(Method method, Object[] args)
  @@ -243,7 +256,6 @@
            Method m = (Method)homeMapping.get(method);
            // Invoke and handle exceptions
            
  -         Log.setLog(log);
            try
            {
               return m.invoke(StatefulSessionContainer.this, new Object[] { method, 
args, ctx});
  @@ -254,9 +266,6 @@
                  throw (Exception)ex;
               else
                  throw (Error)ex;
  -         } finally
  -         {
  -            Log.unsetLog();
            }
         }
            
  @@ -270,7 +279,6 @@
            if (m.getDeclaringClass().equals(StatefulSessionContainer.this.getClass()))
            {
               // Invoke and handle exceptions
  -            Log.setLog(log);
               try
               {
                  return m.invoke(StatefulSessionContainer.this, new Object[] { 
method, args, ctx });
  @@ -281,14 +289,10 @@
                     throw (Exception)ex;
                  else
                     throw (Error)ex;
  -            } finally
  -            {
  -               Log.unsetLog();
  -            }
  +            } 
            } else
            {
               // Invoke and handle exceptions
  -            Log.setLog(log);
               try
               {
                  return m.invoke(ctx.getInstance(), args);
  @@ -299,10 +303,7 @@
                     throw (Exception)ex;
                  else
                     throw (Error)ex;
  -            } finally
  -            {
  -               Log.unsetLog();
  -            }
  +            } 
            }
         }
      }
  
  
  
  1.3       +77 -4     jboss/src/main/org/jboss/ejb/StatelessSessionContainer.java
  
  Index: StatelessSessionContainer.java
  ===================================================================
  RCS file: 
/products/cvs/ejboss/jboss/src/main/org/jboss/ejb/StatelessSessionContainer.java,v
  retrieving revision 1.2
  retrieving revision 1.3
  diff -u -r1.2 -r1.3
  --- StatelessSessionContainer.java    2000/05/24 06:54:37     1.2
  +++ StatelessSessionContainer.java    2000/05/30 18:32:16     1.3
  @@ -24,7 +24,7 @@
    *      
    *   @see <related>
    *   @author Rickard �berg ([EMAIL PROTECTED])
  - *   @version $Revision: 1.2 $
  + *   @version $Revision: 1.3 $
    */
   public class StatelessSessionContainer
      extends Container
  @@ -32,6 +32,10 @@
      // Constants -----------------------------------------------------
       
      // Attributes ----------------------------------------------------
  +
  +   // This is the container invoker for this container
  +   protected ContainerInvoker containerInvoker;
  +     
      Map homeMapping;
      Map beanMapping;
      
  @@ -40,21 +44,90 @@
      // Constructors --------------------------------------------------
      
      // 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; 
  +   }
  +
      // Container implementation --------------------------------------
  -   public void start()
  +   public void init()
         throws Exception
      {
  +     // Associate thread with classloader
         ClassLoader oldCl = Thread.currentThread().getContextClassLoader();
         Thread.currentThread().setContextClassLoader(getClassLoader());
         
  -      super.start();
  +     // Call default init
  +      super.init();
  +      
  +      // Init container invoker
  +      containerInvoker.init();
  +     
         setupBeanMapping();
         setupHomeMapping();
         
  +      // 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
  +      containerInvoker.start();
  +      
  +     // 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
  +      containerInvoker.stop();
  +      
  +      // 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
  +      containerInvoker.destroy();
  +      
  +      // Reset classloader
  +      Thread.currentThread().setContextClassLoader(oldCl);
  +   }
  +     
      public Object invokeHome(Method method, Object[] args)
         throws Exception
      {
  @@ -167,7 +240,7 @@
         beanMapping = map;
      }
      
  -   public Interceptor createContainerInterceptor()
  +   Interceptor createContainerInterceptor()
      {
         return new ContainerInterceptor();
      }
  
  
  

Reply via email to