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

EJBHomeInvocationHandler

public final class EJBHomeInvocationHandler extends ReadOnlyEJBHomeImpl implements InvocationHandler
Handler for EJBHome invocations through EJBHome proxy.
author
Kenneth Saks

Fields Summary
private static final Logger
logger
private static com.sun.enterprise.util.LocalStringManagerImpl
localStrings
private boolean
isStatelessSession_
private boolean
isEntity_
private javax.ejb.EJBHome
proxy_
private Class
homeIntfClass_
private com.sun.ejb.containers.util.MethodMap
invocationInfoMap_
Constructors Summary
EJBHomeInvocationHandler(com.sun.enterprise.deployment.EjbDescriptor ejbDescriptor, Class homeIntfClass, com.sun.ejb.containers.util.MethodMap invocationInfoMap)


     
                              
                               
          

        if( ejbDescriptor instanceof EjbSessionDescriptor ) {
            isEntity_ = false;
            isStatelessSession_ = 
                ((EjbSessionDescriptor)ejbDescriptor).isStateless();
        } else {
            isStatelessSession_ = false;
            isEntity_ = true;
        }

        invocationInfoMap_ = invocationInfoMap;

        homeIntfClass_ = homeIntfClass;

        // NOTE : Container is not set on super-class until after 
        // constructor is called.
    
Methods Summary
protected javax.ejb.EJBHomegetEJBHome()

        return proxy_;
    
public java.lang.Objectinvoke(java.lang.Object proxy, java.lang.reflect.Method method, java.lang.Object[] args)
Called by EJBHome proxy.


        ClassLoader originalClassLoader = null;

        // NOTE : be careful with "args" parameter.  It is null
        //        if method signature has 0 arguments.
        try {
            ((BaseContainer) getContainer()).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);    
            } else if( methodClass == ReadOnlyEJBHome.class ) {
                if( method.getName().equals("_refresh_All") ) {
                    super._refresh_All();
                } else {
                    super._refresh_com_sun_ejb_containers_read_only_bean_
                        (args[0]);
                }
                return null;
            }

            // 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 Home interface method :" 
                                          + method);

            } else if( (methodClass == javax.ejb.EJBHome.class) ||
                       invInfo.ejbIntfOverride ) {
                
                return invokeEJBHomeMethod(method.getName(), args);
                
            } else if( GenericEJBHome.class.isAssignableFrom(methodClass) ) {
                
                // This is an internal creation request through the EJB 3.0
                // client view, so just create an business object and return it
                EJBObjectImpl busObjectImpl = createRemoteBusinessObjectImpl();
                return busObjectImpl.getStub((String) args[0]);
                
            }                
            
            // Process finder, create method, or home method.
            EJBObjectImpl ejbObjectImpl = null;
            Object returnValue = null;
            
            if( !isEntity_ && invInfo.startsWithCreate ) {
                ejbObjectImpl = createEJBObjectImpl();
                returnValue = ejbObjectImpl.getStub();
            }
            
            if( !isStatelessSession_ ) {
                
                if( invInfo.targetMethod1 == null ) {
                    
                    String errorMsg = localStrings.getLocalString
                        ("ejb.bean_class_method_not_found", "", new Object[]
                            { invInfo.ejbName, "Home", 
                              invInfo.method.toString() });
                    logger.log(Level.SEVERE, errorMsg);
                    throw new RemoteException(errorMsg);            
                    
                }
                
                Invocation inv = new Invocation();
                
                inv.isLocal = false;
                inv.method  = method;
                inv.isHome  = true;
                
                inv.clientInterface = homeIntfClass_;

                // Set cached invocation params.  This will save 
                // additional lookups in BaseContainer.

                inv.transactionAttribute = invInfo.txAttr;
                inv.securityPermissions = invInfo.securityPermissions;
                inv.invocationInfo = invInfo;
                
                if( !isEntity_ && invInfo.startsWithCreate ) {
                    inv.ejbObject = (EJBLocalRemoteObject) ejbObjectImpl;
                }
                
                BaseContainer container = (BaseContainer) getContainer();
                
                try {
                    
                    container.preInvoke(inv);
                    
                    if( invInfo.startsWithCreate ) {
                        
                        Object ejbCreateReturnValue = container.
                            invokeTargetBeanMethod(invInfo.targetMethod1, 
                                                   inv, inv.ejb, args, null);
                        if( isEntity_ ) {
                            container.postCreate(inv, ejbCreateReturnValue);
                            container.invokeTargetBeanMethod
                                (invInfo.targetMethod2, 
                                 inv, inv.ejb, args, null);
                        } 
                        if( inv.ejbObject != null ) {
                            returnValue = ((EJBObjectImpl)inv.ejbObject).
                                getStub();
                        } 
                        
                    } else if (invInfo.startsWithFindByPrimaryKey) {
                        EntityContainer entityContainer = (EntityContainer) 
                            container;
                        returnValue = entityContainer.invokeFindByPrimaryKey
                            (invInfo.targetMethod1, inv, args);
                                                                             
                    } else if ( invInfo.startsWithFind ) {
                        
                        Object pKeys = container.invokeTargetBeanMethod
                            (invInfo.targetMethod1, inv, inv.ejb, args, null);
                                                                        
                        returnValue = container.postFind(inv, pKeys, null);
                        
                    } else {
                        
                        returnValue = container.invokeTargetBeanMethod
                            (invInfo.targetMethod1, inv, inv.ejb, args, null);
                    }
                } catch(InvocationTargetException ite) {
                    inv.exception = ite.getCause();
                } catch(Throwable c) {
                    inv.exception = c;
                } finally {
                    container.postInvoke(inv);
                }
                
                if (inv.exception != null) {
                    InvocationHandlerUtil.throwRemoteException
                        (inv.exception, method.getExceptionTypes());
                }
            }
            
            return returnValue;
        } finally {
            
            if( originalClassLoader != null ) {
                Utility.setContextClassLoader(originalClassLoader);
            }

            ((BaseContainer) getContainer()).onLeavingContainer();
        }
    
private java.lang.ObjectinvokeEJBHomeMethod(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("getEJBMetaData") ) {

            returnValue = super.getEJBMetaData();

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

            returnValue = super.getHomeHandle();

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

            if( args[0] instanceof javax.ejb.Handle ) {
                super.remove((javax.ejb.Handle)args[0]);
            } else {
                super.remove(args[0]);
            }

        } else {

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

        }

        return returnValue;
    
public voidsetProxy(javax.ejb.EJBHome proxy)

        proxy_ = proxy;