/*
* jBoss, the OpenSource EJB server
*
* Distributable under GPL license.
* See terms of license at gnu.org.
*/
package org.jboss.ejb;

import java.net.URL;
import java.net.URLClassLoader;

import javax.naming.Context;
import javax.naming.InitialContext;
import javax.naming.NamingException;
import javax.transaction.TransactionManager;

import org.jboss.ejb.plugins.*;
import org.jboss.system.EJBSecurityManager;
import org.jboss.system.RealmMapping;
import org.jboss.metadata.*;

/**
 * Bean Deployer encapsulates all the Container configurations that are
based on
 * the Bean's properties. Concrete implementations represent the individual
Bean types.
 * This abstract class also provides from default method impleementations.
 *
 * @author <a href="mailto:[EMAIL PROTECTED]">Jack Bolles</a>
 */
public abstract class BeanDeployer {

   protected Container container;
   protected ConfigurationMetaData conf;
   protected BeanMetaData bean;
   protected ClassLoader cl;
   protected boolean metricsEnabled;

   /**
    * Determines the  concrete deployer implementation based on bean type
    * (as of 12/16/2000, Message Driven, Stateless Session, Stateful
Session, Entity),
    *
    * Initializes the appropriate Container and sets Container's params
    * based on the BeanMetaData.
    *
    * @param bean
    * @exception DeploymentException
    */
   public static void deployBean(BeanMetaData bmd, ClassLoader loader,
boolean enableMetrics) throws DeploymentException{
      //determine appropriate deployer
      BeanDeployer deployer = null;

      if (bmd.isMessageDriven()) {
         deployer = new MessageDrivenDeployer(bmd, loader, enableMetrics);
      }
      else if (bmd.isSession())
      {
         if (((SessionMetaData)bmd).isStateless())
         {
            deployer = new StatelessSessionDeployer(bmd, loader,
enableMetrics);
         } else {
            deployer = new StatefulSessionDeployer(bmd, loader,
enableMetrics);
         }
      }else { //is entity
         deployer = new EntityDeployer(bmd, loader, enableMetrics);
      }

      deployer.deploy();
   }

   protected BeanDeployer(BeanMetaData bmd, ClassLoader loader, boolean
enableMetrics) {
      //set instance variables
      setMetricsEnabled(enableMetrics);
      cl = loader;
      bean = bmd;
   }

   protected void deploy() throws DeploymentException {
      // get the container configuration for this bean
      // a default configuration is now always provided by the bean
      conf = bean.getContainerConfiguration();
      initContainer();
   }

   protected void initContainer() throws DeploymentException {
      // Create classloader for this container
      // Only used to identify bean. Not really used for class loading!
      container.setClassLoader(new URLClassLoader(new URL[0], cl));

      // Set metadata
      container.setBeanMetaData(bean);

      //prepare the container to deploy the bean
      setTransactionManager();
      setSecurityManager();
      setRealmMapping();
      setContainerInvoker();
      setInstancePool();
      setInstanceCache();
      setPersistenceManager();
      setInterceptors();
   }

   protected abstract void setInstancePool() throws DeploymentException;
   protected abstract void setInstanceCache() throws DeploymentException;
   protected abstract void setPersistenceManager() throws
DeploymentException;


   protected void setTransactionManager() throws DeploymentException{
      try {
         container.setTransactionManager((TransactionManager)new
InitialContext().lookup("java:/TransactionManager"));
      } catch(NamingException ne) {
         throw new DeploymentException( "Could not find the Transaction
Manager specified for this container", ne );
      }
   }

   protected void setSecurityManager() throws DeploymentException{
      String securityManagerJNDIName = conf.getAuthenticationModule();
      if(securityManagerJNDIName == null) {
         throw new DeploymentException( "Could not find the Security
Manager specified for this container", ne );
      }

      try {
         EJBSecurityManager ejbS = (EJBSecurityManager)new InitialContext
().lookup(securityManagerJNDIName);
         container.setSecurityManager( ejbS );
      } catch(NamingException ne) {
         throw new DeploymentException( "Could not find the Security
Manager specified for this container", ne );
      }
   }

   protected void setRealmMapping() throws DeploymentException{
      String roleMappingManagerJNDIName = conf.getRoleMappingManager();
      if(roleMappingManagerJNDIName == null) {
         throw new DeploymentException( "Could not find the Role Mapping
Manager specified for this container", ne );
      }

      try {
         RealmMapping rM = (RealmMapping)new InitialContext
().lookup(roleMappingManagerJNDIName);
         container.setRealmMapping( rM );
      } catch(NamingException ne) {
         throw new DeploymentException( "Could not find the Role Mapping
Manager specified for this container", ne );
      }
   }

   protected void setContainerInvoker() throws DeploymentException{
      try {
         ContainerInvoker ci
= (ContainerInvoker)cl.loadClass(conf.getContainerInvoker()).newInstance();
         if(ci instanceof XmlLoadable) {
            // the container invoker can load its configuration from the
jboss.xml element
            ((XmlLoadable)ci).importXml(conf.getContainerInvokerConf());
         }
         container.setContainerInvoker(ci);
      } catch(Exception e) {
         throw new DeploymentException("Missing or invalid Container
Invoker (in jboss.xml or standardjboss.xml)");
      }
   }

   protected void setInterceptors() throws DeploymentException {
      // Create interceptors
      container.addInterceptor(new LogInterceptor());
      container.addInterceptor(new SecurityInterceptor());
      if(metricsEnabled) {
         container.addInterceptor(new MetricsInterceptor());
      }
      // Finally we add the last interceptor from the container
      container.addInterceptor(container.createContainerInterceptor());

      //when *MetaData.isContainerManagedTx()
      //becomes a signature and if-else can go away
      if(bean.isMessageDriven()) {
         if (((MessageDrivenMetaData)bean).isContainerManagedTx())
         {
            // CMT
            container.addInterceptor(new TxInterceptorCMT());
         }
         else
         {
            // BMT
            container.addInterceptor(new MessageDrivenInstanceInterceptor
());
            // FIXME. should we have a special BMT tx interceptor to place
ACK there???
            container.addInterceptor(new MessageDrivenTxInterceptorBMT());
         }
      }
      else if(bean.isSession()){
         if(((SessionMetaData)bean).isContainerManagedTx()) {
            // CMT
            container.addInterceptor(new TxInterceptorCMT());
         } else {
            // BMT : the tx interceptor needs the context from the instance
interceptor
            container.addInterceptor(new TxInterceptorBMT());
         }

      } else { /*isEntity*/
         // entity beans are always CMT
         container.addInterceptor(new TxInterceptorCMT());
      }
   }

   /** @see ContainerFactory
   */
   public void setMetricsEnabled(boolean enable) {
      metricsEnabled = enable;
  }

  /**
   * Checks if this container factory initializes the metrics interceptor.
   *
   * @return true if metrics are enabled; false otherwise
   */
  public boolean isMetricsEnabled() {
      return metricsEnabled;
  }

}


Reply via email to