FileDocCategorySizeDatePackage
EJBObjectInvocationHandler.javaAPI DocGlassfish v2 API10079Fri May 04 22:32:58 BST 2007com.sun.ejb.containers

EJBObjectInvocationHandler

public final class EJBObjectInvocationHandler extends EJBObjectImpl implements InvocationHandler
Handler for EJBObject invocations through EJBObject proxy.
author
Kenneth Saks

Fields Summary
private static final Logger
logger
private static com.sun.enterprise.util.LocalStringManagerImpl
localStrings
private com.sun.ejb.containers.util.MethodMap
invocationInfoMap_
private Class
remoteIntf_
Constructors Summary
public EJBObjectInvocationHandler(com.sun.ejb.containers.util.MethodMap invocationInfoMap, Class remoteIntf)
Constructor used for Remote Home view.


               
      
                                       
          

        invocationInfoMap_ = invocationInfoMap;

        remoteIntf_ = remoteIntf;
        setIsRemoteHomeView(true);

        // NOTE : Container is not set on super-class until after 
        // constructor is called.
    
public EJBObjectInvocationHandler(com.sun.ejb.containers.util.MethodMap invocationInfoMap)
Constructor used for Remote Business view.


        invocationInfoMap_ = invocationInfoMap;

        setIsRemoteHomeView(false);

        // NOTE : Container is not set on super-class until after 
        // constructor is called.
    
Methods Summary
public java.lang.Objectinvoke(java.lang.Object proxy, java.lang.reflect.Method method, java.lang.Object[] args)
This entry point is only used for the Remote Home view.


        return invoke(remoteIntf_, method, args);
    
java.lang.Objectinvoke(java.lang.Class clientInterface, java.lang.reflect.Method method, java.lang.Object[] args)


        ClassLoader originalClassLoader = null;

        // NOTE : be careful with "args" parameter.  It is null
        //        if method signature has 0 arguments.
        try {
            container.onEnteringContainer();

            // In some cases(e.g. if the Home/Remote interfaces appear in
            // a parent of the application's classloader), 
            // ServantLocator.preinvoke() will not be called by the
            // ORB, and therefore BaseContainer.externalPreInvoke will not have
            // been called for this invocation.  In those cases we need to set 
            // the context classloader to the application's classloader before 
            // proceeding. Otherwise, the context classloader could still 
            // reflect the caller's class loader.  
            
            if( Thread.currentThread().getContextClassLoader() != 
                getContainer().getClassLoader() ) {
                originalClassLoader = Utility.setContextClassLoader
                    (getContainer().getClassLoader());
            }
            
            Class methodClass = method.getDeclaringClass();
            if( methodClass == java.lang.Object.class ) {
                return InvocationHandlerUtil.invokeJavaObjectMethod
                    (this, method, args);    
            } 
            
            // Use optimized version of get that takes param count as an 
            // argument.
            InvocationInfo invInfo = (InvocationInfo)
                invocationInfoMap_.get(method, 
                                       ((args != null) ? args.length : 0) );
            
            if( invInfo == null ) {
                throw new RemoteException("Unknown Remote interface method :" 
                                          + method);
            }
            
            if( (methodClass == javax.ejb.EJBObject.class) ||
                invInfo.ejbIntfOverride ) {
                return invokeEJBObjectMethod(method.getName(), args);
            } else if( invInfo.targetMethod1 == null ) {
                Object [] params = new Object[] 
                    { invInfo.ejbName, "Remote", invInfo.method.toString() };
                String errorMsg = localStrings.getLocalString
                    ("ejb.bean_class_method_not_found", "", params);
              
                logger.log(Level.SEVERE, "ejb.bean_class_method_not_found",
                       params);                                   
                throw new RemoteException(errorMsg);           
            }
            
            // Process application-specific method.
            
            Object returnValue = null;
            
            Invocation inv = new Invocation();
            
            inv.isLocal   = false;
            inv.isHome    = false;
            inv.isBusinessInterface = !isRemoteHomeView();
            inv.ejbObject = this;
            inv.method    = method;

            inv.clientInterface = clientInterface;

            // Set cached invocation params.  This will save additional lookups
            // in BaseContainer.
            inv.transactionAttribute = invInfo.txAttr;
            inv.securityPermissions = invInfo.securityPermissions;
            inv.invocationInfo = invInfo;
            inv.beanMethod = invInfo.targetMethod1;
            inv.methodParams = args;
            
            try {
                container.preInvoke(inv);
                returnValue = container.intercept(inv);
            } catch(InvocationTargetException ite) {
                inv.exception = ite.getCause();
                inv.exceptionFromBeanMethod = inv.exception;
            } catch(Throwable t) {
                inv.exception = t;
            } finally {
                container.postInvoke(inv);
            }
            
            if (inv.exception != null) {
                InvocationHandlerUtil.throwRemoteException
                    (inv.exception, method.getExceptionTypes());
            }
            
            return returnValue;
        } finally {
            
            if( originalClassLoader != null ) {
                Utility.setContextClassLoader(originalClassLoader);
            }

            container.onLeavingContainer();
        }
    
private java.lang.ObjectinvokeEJBObjectMethod(java.lang.String methodName, java.lang.Object[] args)

        // Return value is null if target method returns void.
        Object returnValue = null;


        // NOTE : Might be worth optimizing this method check if it
        // turns out to be a bottleneck.  I don't think these methods
        // are called with the frequency that this would be an issue,
        // but it's worth considering.

        if( methodName.equals("getEJBHome") ) {

            returnValue = super.getEJBHome();

        } else if( methodName.equals("getHandle") ) {

            returnValue = super.getHandle();

        } else if( methodName.equals("getPrimaryKey") ) {

            returnValue = super.getPrimaryKey();

        } else if( methodName.equals("isIdentical") ) {

            // boolean isIdentical(EJBObject)
            // Convert the param into an EJBObject.           
            EJBObject other = (EJBObject) args[0];

            returnValue = new Boolean(super.isIdentical(other));

        } else if( methodName.equals("remove") ) {

            super.remove();

        } else {

            throw new RemoteException("unknown EJBObject method = " 
                                      + methodName);
        }

        return returnValue;