FileDocCategorySizeDatePackage
SessionContainer.javaAPI DocJBoss 4.2.114085Fri Jul 13 20:53:58 BST 2007org.jboss.ejb3

SessionContainer

public abstract class SessionContainer extends EJBContainer
Comment
author
Bill Burke
version
$Revision: 61280 $

Fields Summary
private static final Logger
log
protected ProxyDeployer
proxyDeployer
protected Map
clusterFamilies
protected ThreadLocalStack
invokedMethod
Constructors Summary
public SessionContainer(ClassLoader cl, String beanClassName, String ejbName, org.jboss.aop.AspectManager manager, Hashtable ctxProperties, org.jboss.ejb3.interceptor.InterceptorInfoRepository interceptorRepository, Ejb3Deployment deployment)


           
                              
                            
   
      super(Ejb3Module.BASE_EJB3_JMX_NAME + ",name=" + ejbName, manager, cl, beanClassName, ejbName, ctxProperties, interceptorRepository, deployment);
      proxyDeployer = new ProxyDeployer(this);
   
Methods Summary
public abstract java.lang.ObjectcreateLocalProxy(java.lang.Object id)

protected voidcreateMethodMap()

      super.createMethodMap();
      try
      {
         RemoteHome home = (RemoteHome) resolveAnnotation(RemoteHome.class);
         if (home != null)
         {
            Method[] declaredMethods = home.value().getMethods();
            for (int i = 0; i < declaredMethods.length; i++)
            {
               long hash = MethodHashing.methodHash(declaredMethods[i]);
               advisedMethods.put(hash, declaredMethods[i]);
            }

            declaredMethods = javax.ejb.EJBObject.class.getMethods();
            for (int i = 0; i < declaredMethods.length; i++)
            {
               long hash = MethodHashing.methodHash(declaredMethods[i]);
               advisedMethods.put(hash, declaredMethods[i]);
            }
         }

         LocalHome localHome = (LocalHome) resolveAnnotation(LocalHome.class);
         if (localHome != null)
         {
            Method[] declaredMethods = localHome.value().getMethods();
            for (int i = 0; i < declaredMethods.length; i++)
            {
               long hash = MethodHashing.methodHash(declaredMethods[i]);
               advisedMethods.put(hash, declaredMethods[i]);
            }

            declaredMethods = javax.ejb.EJBLocalObject.class.getMethods();
            for (int i = 0; i < declaredMethods.length; i++)
            {
               long hash = MethodHashing.methodHash(declaredMethods[i]);
               advisedMethods.put(hash, declaredMethods[i]);
            }
         }
      }
      catch (Exception e)
      {
         throw new RuntimeException(e);
      }
   
public abstract java.lang.ObjectcreateRemoteProxy(java.lang.Object id)

protected abstract java.lang.ObjectcreateSession(java.lang.Class[] initParameterTypes, java.lang.Object[] initParameterValues)
Create session to an EJB bean.

param
initParameterTypes the parameter types used by the home's create method
param
initParameterValues the arguments for the home's create method
return
the identifier of the session

protected voiddestroySession(java.lang.Object id)
Destroy a created session.

param
id the identifier of the session

      throw new RuntimeException("NYI");
   
public java.util.MapgetClusterFamilies()

      return clusterFamilies;
   
public java.lang.ClassgetInvokedBusinessInterface()

      InvokedMethod method = invokedMethod.get();
      if (method == null) throw new IllegalStateException("getInvokedBusinessInterface() being invoked outside of a business invocation");
      if (method.method == null) throw new IllegalStateException("getInvokedBusinessInterface() being invoked outside of a business invocation");
      if (method.isLocalInterface) return method.method.getDeclaringClass();
      Class[] remoteInterfaces = ProxyFactoryHelper.getRemoteInterfaces(this);
      for (Class intf : remoteInterfaces)
      {
         try
         {
            intf.getMethod(method.method.getName(), method.method.getParameterTypes());
            return intf;
         }
         catch (NoSuchMethodException ignored)
         {
            // continue
         }
      }
      throw new IllegalStateException("Unable to find geInvokedBusinessInterface()");
   
public voidinstantiated()

      super.instantiated();
      proxyDeployer.initializeRemoteBindingMetadata();
      proxyDeployer.initializeLocalBindingMetadata();
   
public java.lang.Objectinvoke(ProxyFactory factory, java.lang.Object id, java.lang.reflect.Method method, java.lang.Object[] args, org.jboss.aspects.asynch.FutureHolder provider)
Invoke a method on the virtual EJB bean. The method must be one of the methods defined in one of the business interfaces (or home interface) of the bean. TODO: work in progress

param
factory the originating end point
param
id unique identifier (primary key), can be null for stateless
param
method the business or home method to invoke
param
args the arguments for the method
param
provider for asynchronous usage

      ClassLoader oldLoader = Thread.currentThread().getContextClassLoader();
      pushEnc();
      try
      {
         long hash = MethodHashing.calculateHash(method);
         MethodInfo info = (MethodInfo) methodInterceptors.get(hash);
         if (info == null)
         {
            throw new RuntimeException(
                    "Could not resolve beanClass method from proxy call: "
                            + method.toString());
         }

         Method unadvisedMethod = info.getUnadvisedMethod();

         if (unadvisedMethod != null && isHomeMethod(unadvisedMethod))
         {
            return invokeHomeMethod(factory, info, args);
         }
         else if (unadvisedMethod != null && isEJBObjectMethod(unadvisedMethod))
         {
            return invokeEJBObjectMethod(factory, id, info, args);
         }

         // FIXME: Ahem, stateful container invocation works on all.... (violating contract though)
         EJBContainerInvocation nextInvocation = new StatefulContainerInvocation(info, id);
         nextInvocation.setAdvisor(this);
         nextInvocation.setArguments(args);
         
         // allow a container to supplement information into an invocation
         nextInvocation = populateInvocation(nextInvocation);

         ProxyUtils.addLocalAsynchronousInfo(nextInvocation, provider);
         try
         {
            invokedMethod.push(new InvokedMethod(true, method));
            return nextInvocation.invokeNext();
         }
         finally
         {
            invokedMethod.pop();
         }
      }
      finally
      {
         Thread.currentThread().setContextClassLoader(oldLoader);
         popEnc();
      }
   
protected java.lang.ObjectinvokeEJBObjectMethod(ProxyFactory factory, java.lang.Object id, org.jboss.aop.MethodInfo info, java.lang.Object[] args)

      Method unadvisedMethod = info.getUnadvisedMethod();
      if(unadvisedMethod.getName().equals("getEJBHome"))
      {
         return factory.createHomeProxy();
      }
      if(unadvisedMethod.getName().equals("getPrimaryKey"))
      {
         return id;
      }
      if(unadvisedMethod.getName().equals("isIdentical"))
      {
         // object has no identity
         if(id == null)
            return false;
         
         EJBObject bean = (EJBObject) args[0];

         Object primaryKey = bean.getPrimaryKey();
         if(primaryKey == null)
            return false;

         boolean isIdentical = id.equals(primaryKey);

         return isIdentical;
      }
      if (unadvisedMethod.getName().equals("remove"))
      {
         destroySession(id);

         return null;
      }
      throw new RuntimeException("NYI");
   
private java.lang.ObjectinvokeHomeMethod(ProxyFactory factory, org.jboss.aop.MethodInfo info, java.lang.Object[] args)
TODO: work in progress (refactor both invokeHomeMethod's, localHomeInvoke)

      Method unadvisedMethod = info.getUnadvisedMethod();
      if (unadvisedMethod.getName().equals("create"))
      {
         Class[] initParameterTypes = {};
         Object[] initParameterValues = {};
         if (unadvisedMethod.getParameterTypes().length > 0)
         {
            initParameterTypes = unadvisedMethod.getParameterTypes();
            initParameterValues = args;
         }

         Object id = createSession(initParameterTypes, initParameterValues);
         
         Object proxy = factory.createProxy(id);

         return proxy;
      }
      else if (unadvisedMethod.getName().equals("remove"))
      {
         if(args[0] instanceof Handle)
            removeHandle((Handle) args[0]);
         else
            destroySession(args[0]);

         return null;
      }
      else
      {
         throw new IllegalArgumentException("illegal home method " + unadvisedMethod);
      }
   
protected booleanisEJBObjectMethod(java.lang.reflect.Method method)

      if (method.getDeclaringClass().getName().equals("javax.ejb.EJBObject"))
         return true;

      if (method.getDeclaringClass().getName().equals("javax.ejb.EJBLocalObject"))
         return true;

      return false;
   
protected booleanisHandleMethod(java.lang.reflect.Method method)

      if (method.getDeclaringClass().getName().equals("javax.ejb.Handle"))
         return true;

      return false;
   
protected booleanisHomeMethod(java.lang.reflect.Method method)

      if (javax.ejb.EJBHome.class.isAssignableFrom(method.getDeclaringClass())) return true;
      if (javax.ejb.EJBLocalHome.class.isAssignableFrom(method.getDeclaringClass())) return true;
      return false;
   
public static org.jboss.aop.joinpoint.InvocationResponsemarshallException(org.jboss.aop.joinpoint.Invocation invocation, java.lang.Throwable exception, java.util.Map responseContext)

      if (!invocation.getMetaData().hasTag(IsLocalInterceptor.IS_LOCAL)) throw exception;

      InvocationResponse response = new InvocationResponse();
      response.setContextInfo(responseContext);

      response.addAttachment(IsLocalInterceptor.IS_LOCAL_EXCEPTION, new MarshalledObjectForLocalCalls(exception));

      return response;
   
public static org.jboss.aop.joinpoint.InvocationResponsemarshallResponse(org.jboss.aop.joinpoint.Invocation invocation, java.lang.Object rtn, java.util.Map responseContext)

      InvocationResponse response;
      // marshall return value
      if (rtn != null && invocation.getMetaData().hasTag(IsLocalInterceptor.IS_LOCAL))
      {
         response = new InvocationResponse(new MarshalledObjectForLocalCalls(rtn));
      }
      else
      {
         response = new InvocationResponse(rtn);
      }
      response.setContextInfo(responseContext);
      return response;
   
protected EJBContainerInvocationpopulateInvocation(EJBContainerInvocation invocation)
Allow a container sub class to supplement an invocation. Per default nothing to supplement.

param
invocation
return

      return invocation;
   
public voidprocessMetadata(DependencyPolicy dependencyPolicy)

      super.processMetadata(dependencyPolicy);
   
protected abstract voidremoveHandle(javax.ejb.Handle handle)

public voidstart()

      super.start();
      // So that Remoting layer can reference this container easily.
      Dispatcher.singleton.registerTarget(getObjectName().getCanonicalName(), this);
      proxyDeployer.start();
   
public voidstop()

      try
      {
         proxyDeployer.stop();
      }
      catch (Exception ignore)
      {
         log.trace("Proxy deployer stop failed", ignore);
      }
      try
      {
         Dispatcher.singleton.unregisterTarget(getObjectName().getCanonicalName());
      }
      catch (Exception ignore)
      {
         log.trace("Dispatcher unregister target failed", ignore);
      }
      super.stop();