FileDocCategorySizeDatePackage
InjectionManagerImpl.javaAPI DocGlassfish v2 API22484Fri May 04 22:35:58 BST 2007com.sun.enterprise.util

InjectionManagerImpl

public class InjectionManagerImpl extends Object implements com.sun.enterprise.InjectionManager
Implementation of InjectionManager.
author
Kenneth Saks

Fields Summary
static Logger
_logger
private static LocalStringManagerImpl
localStrings
private com.sun.enterprise.Switch
theSwitch
private com.sun.enterprise.InvocationManager
invocationMgr
private InitialContext
namingCtx
Constructors Summary
public InjectionManagerImpl()


      

        theSwitch = Switch.getSwitch();
        invocationMgr = theSwitch.getInvocationManager();
        
        try {
            namingCtx = new InitialContext();
        } catch(NamingException ne) {
            throw new RuntimeException(ne);
        }

    
Methods Summary
private void_inject(java.lang.Class clazz, java.lang.Object instance, java.util.List injectableResources)


	for (InjectionCapable next : injectableResources ) {

            try {

                final Object value = namingCtx.lookup("java:comp/env/" + 
                                               next.getComponentEnvName());

                // there still could be 2 injection on the same class, better
                // do a loop here
                for (InjectionTarget target : next.getInjectionTargets()) {
                    
                    // if target class is not the class we are injecting
                    // we can just jump to the next target
                    if (!clazz.getName().equals(target.getClassName()))
                        continue;
                    
                    if( target.isFieldInjectable() ) {
                        
                        final Field f = getField(target, clazz);
                        
                        if( Modifier.isStatic(f.getModifiers()) &&
                            (instance != null) ) {
                            throw new InjectionException
                                ("Illegal use of static field " + f + 
                                 " on class that only supports instance-based" 
                                 + " injection");
                        }

                        if( (instance == null) &&
                            !Modifier.isStatic(f.getModifiers()) ) {
                            throw new InjectionException
                                ("Injected field " + f + 
                                 " on Application Client class " + clazz +
                                 " must be declared static");
                        }


                        if(_logger.isLoggable(Level.FINE)) {
                            _logger.fine("Injecting dependency with logical name "
                                    + next.getComponentEnvName() +
                                    " into field " + f + " on class " +
                                    clazz);
                        }
                        
                        // Wrap actual value insertion in doPrivileged to
                        // allow for private/protected field access.
                        if( System.getSecurityManager() != null ) {
                            java.security.AccessController.doPrivileged(
                             new java.security.PrivilegedExceptionAction() {
                               public java.lang.Object run() throws Exception {
                                 f.set(instance, value);
                                 return null;
                               }
                             });
                        } else {
                            f.set(instance, value);
                        }
                    } else if( target.isMethodInjectable() ) {
                        
                        final Method m = getMethod(next, target, clazz);

                        if( Modifier.isStatic(m.getModifiers()) &&
                            (instance != null) ) {
                            throw new InjectionException
                                ("Illegal use of static method " + m + 
                                 " on class that only supports instance-based" 
                                 + " injection");
                        }

                        if( (instance == null) &&
                            !Modifier.isStatic(m.getModifiers()) ) {
                            throw new InjectionException
                                ("Injected method " + m + 
                                 " on Application Client class " + clazz +
                                 " must be declared static");
                        }
                        
                        if(_logger.isLoggable(Level.FINE)) {
                            _logger.fine("Injecting dependency with logical name "
                                    + next.getComponentEnvName() +
                                    " into method " + m + " on class " +
                                    clazz);
                        }

                        if( System.getSecurityManager() != null ) {
                          // Wrap actual value insertion in doPrivileged to
                          // allow for private/protected field access.
                          java.security.AccessController.doPrivileged(
                                new java.security.PrivilegedExceptionAction() {
                            public java.lang.Object run() throws Exception {
                                m.invoke(instance, new Object[] { value });
                                return null;
                            }});
                        } else {
                            m.invoke(instance, new Object[] { value });
                        }
                        
                    }
                }
            } catch(Throwable t) {

                String msg = "Exception attempting to inject " 
                    + next + " into " + clazz;
                _logger.log(Level.FINE, msg, t);
                InjectionException ie = new InjectionException(msg);
                Throwable cause = (t instanceof InvocationTargetException) ?
                    ((InvocationTargetException)t).getCause() : t;
                ie.initCause( cause );
                throw ie;

            }
        }
    
private java.lang.reflect.FieldgetField(com.sun.enterprise.deployment.InjectionTarget target, java.lang.Class resourceClass)


        Field f = target.getField();

        if( f == null ) {
            try {
                // Check for the given field within the resourceClass only.
                // This does not include super-classes of this class.
                f = resourceClass.getDeclaredField
                        (target.getFieldName());

                final Field finalF = f;
                java.security.AccessController.doPrivileged(
                     new java.security.PrivilegedExceptionAction() {
                            public java.lang.Object run() throws Exception {
                                if( !finalF.isAccessible() ) {
                                    finalF.setAccessible(true);
                                }
                                return null;
                            }
                        });

            } catch(java.lang.NoSuchFieldException nsfe) {}

            if( f != null ) {
                target.setField(f);
            }
        }

        if( f == null ) {
            throw new Exception("InjectionManager exception.  Field " + 
                                target.getFieldName() + 
                                " not found in Class " + resourceClass);
        }

        return f;
    
private java.lang.reflect.MethodgetMethod(com.sun.enterprise.deployment.InjectionCapable resource, com.sun.enterprise.deployment.InjectionTarget target, java.lang.Class resourceClass)


        Method m = target.getMethod();

        if( m == null ) {
            // Check for the method within the resourceClass only.
            // This does not include super-classses.
            for(Method next : resourceClass.getDeclaredMethods()) {
                // Overloading is not supported for setter injection 
                // methods, so matching on method-name is sufficient.  
                if(next.getName().equals(target.getMethodName())) {
                    m = next;
                    target.setMethod(m);
                    
                    final Method finalM = m;
                    java.security.AccessController.doPrivileged(
                       new java.security.PrivilegedExceptionAction() {
                          public java.lang.Object run() throws Exception {
                             if( !finalM.isAccessible() ) {
                                 finalM.setAccessible(true);
                             }
                             return null;
                         }});

                    break;
                }
            }
        }

        if( m == null ) {
            throw new Exception("InjectionManager exception.  Method " +
                                "void " + target.getMethodName() +
                                "(" + resource.getInjectResourceType() + ")" +
                                " not found in Class " + resourceClass);
        }

        return m;
    
private java.lang.reflect.MethodgetPostConstructMethod(com.sun.enterprise.deployment.InjectionInfo injInfo, java.lang.Class resourceClass)


        Method m = injInfo.getPostConstructMethod();

        if( m == null ) {
            String postConstructMethodName = 
                injInfo.getPostConstructMethodName();

            // Check for the method within the resourceClass only.
            // This does not include super-classses.
            for(Method next : resourceClass.getDeclaredMethods()) {
                // InjectionManager only handles injection into PostConstruct
                // methods with no arguments. 
                if( next.getName().equals(postConstructMethodName) &&
                    (next.getParameterTypes().length == 0) ) {
                    m = next;
                    injInfo.setPostConstructMethod(m);
                    break;
                }
            }
        }

        if( m == null ) {
            throw new InjectionException
                ("InjectionManager exception. PostConstruct method " +
                 injInfo.getPostConstructMethodName() + 
                 " could not be found in class " + 
                 injInfo.getClassName());
        }

        return m;
    
private java.lang.reflect.MethodgetPreDestroyMethod(com.sun.enterprise.deployment.InjectionInfo injInfo, java.lang.Class resourceClass)


        Method m = injInfo.getPreDestroyMethod();

        if( m == null ) {
            String preDestroyMethodName = injInfo.getPreDestroyMethodName();

            // Check for the method within the resourceClass only.
            // This does not include super-classses.
            for(Method next : resourceClass.getDeclaredMethods()) {
                // InjectionManager only handles injection into PreDestroy
                // methods with no arguments. 
                if( next.getName().equals(preDestroyMethodName) &&
                    (next.getParameterTypes().length == 0) ) {
                    m = next;
                    injInfo.setPreDestroyMethod(m);
                    break;
                }
            }
        }

        if( m == null ) {
            throw new InjectionException
                ("InjectionManager exception. PreDestroy method " +
                 injInfo.getPreDestroyMethodName() + 
                 " could not be found in class " + 
                 injInfo.getClassName());
        }

        return m;
    
private voidinject(java.lang.Class clazz, java.lang.Object instance, com.sun.enterprise.deployment.JndiNameEnvironment envDescriptor, boolean invokePostConstruct)

param
instance Target instance for injection, or null if injection is class-based. Any error encountered during any portion of injection is propagated immediately.

        
        LinkedList<Method> postConstructMethods = new LinkedList<Method>();
            
        Class nextClass = clazz;

        // Process each class in the inheritance hierarchy, starting with
        // the most derived class and ignoring java.lang.Object.
        while((nextClass != Object.class) && (nextClass != null)) {

            InjectionInfo injInfo = 
                envDescriptor.getInjectionInfoByClass(nextClass.getName());

            if( injInfo.getInjectionResources().size() > 0 ) {
                _inject(nextClass, instance, injInfo.getInjectionResources());
            }

            if( invokePostConstruct ) {
                
                if( injInfo.getPostConstructMethodName() != null ) {
                    
                    Method postConstructMethod = getPostConstructMethod
                        (injInfo, nextClass);
                    
                    // Delay calling post construct methods until all
                    // dependency injection within the hierarchy has been
                    // completed.  Then, invoke the methods starting from
                    // the least-derived class downward.  
                    postConstructMethods.addFirst(postConstructMethod);
                }
            }

            nextClass = nextClass.getSuperclass();
        }


        for(Method postConstructMethod : postConstructMethods) {

            invokeLifecycleMethod(postConstructMethod, instance);

        }

    
public voidinjectClass(java.lang.Class clazz, com.sun.enterprise.deployment.JndiNameEnvironment componentEnv)

        injectClass(clazz, componentEnv, true);
    
public voidinjectClass(java.lang.Class clazz, com.sun.enterprise.deployment.JndiNameEnvironment componentEnv, boolean invokePostConstruct)

        inject(clazz, null, componentEnv, invokePostConstruct);
    
public voidinjectInstance(java.lang.Object instance)


        ComponentInvocation inv = invocationMgr.getCurrentInvocation();
        
        if( inv != null ) {

            JndiNameEnvironment componentEnv = (JndiNameEnvironment)
                theSwitch.getDescriptorFor(inv.getContainerContext());

            if( componentEnv != null ) {
                inject(instance.getClass(), instance, componentEnv, true);
            } else {
                throw new InjectionException("No descriptor registered for " +
                                             " current invocation : " + inv);
            }

        } else {
            throw new InjectionException("null invocation context");
        }

    
public voidinjectInstance(java.lang.Object instance, com.sun.enterprise.deployment.JndiNameEnvironment componentEnv)


        inject(instance.getClass(), instance, componentEnv, true);

    
public voidinjectInstance(java.lang.Object instance, com.sun.enterprise.deployment.JndiNameEnvironment componentEnv, boolean invokePostConstruct)


        inject(instance.getClass(), instance, componentEnv, 
               invokePostConstruct);

    
public voidinvokeClassPreDestroy(java.lang.Class clazz, com.sun.enterprise.deployment.JndiNameEnvironment componentEnv)

        invokePreDestroy(clazz, null, componentEnv);
    
public voidinvokeInstancePreDestroy(java.lang.Object instance, com.sun.enterprise.deployment.JndiNameEnvironment componentEnv)

        invokePreDestroy(instance.getClass(), instance, componentEnv);
    
public voidinvokeInstancePreDestroy(java.lang.Object instance)


        ComponentInvocation inv = invocationMgr.getCurrentInvocation();
        
        if( inv != null ) {

            JndiNameEnvironment componentEnv = (JndiNameEnvironment)
                theSwitch.getDescriptorFor(inv.getContainerContext());

            if( componentEnv != null ) {
                invokePreDestroy(instance.getClass(), instance, componentEnv);
            } else {
                throw new InjectionException("No descriptor registered for " +
                                             " current invocation : " + inv);
            }

        } else {
            throw new InjectionException("null invocation context");
        }
    
private voidinvokeLifecycleMethod(java.lang.reflect.Method lifecycleMethod, java.lang.Object instance)


        try {

            if(_logger.isLoggable(Level.FINE)) {
                _logger.fine("Calling lifeccle method " +
                             lifecycleMethod + " on class " +
                             lifecycleMethod.getDeclaringClass());
            }

            // Wrap actual value insertion in doPrivileged to
            // allow for private/protected field access.
            java.security.AccessController.doPrivileged(
                new java.security.PrivilegedExceptionAction() {
                    public java.lang.Object run() throws Exception {
                        if( !lifecycleMethod.isAccessible() ) {
                            lifecycleMethod.setAccessible(true);
                        }
                        lifecycleMethod.invoke(instance);
                        return null;
                    }
                });
        } catch( Throwable t) {

                String msg = "Exception attempting invoke lifecycle " 
                    + " method " + lifecycleMethod;
                _logger.log(Level.FINE, msg, t);
                InjectionException ie = new InjectionException(msg);
                Throwable cause = (t instanceof InvocationTargetException) ?
                    ((InvocationTargetException)t).getCause() : t;
                ie.initCause( cause );
                throw ie;

        }
        
        return;

    
private voidinvokePreDestroy(java.lang.Class clazz, java.lang.Object instance, com.sun.enterprise.deployment.JndiNameEnvironment envDescriptor)

param
instance Target instance for preDestroy, or null if class-based.

        
        LinkedList<Method> preDestroyMethods = new LinkedList<Method>();
            
        Class nextClass = clazz;

        // Process each class in the inheritance hierarchy, starting with
        // the most derived class and ignoring java.lang.Object.
        while((nextClass != Object.class) && (nextClass != null)) {

            InjectionInfo injInfo = 
                envDescriptor.getInjectionInfoByClass(nextClass.getName());

            if( injInfo.getPreDestroyMethodName() != null ) {
                
                Method preDestroyMethod = getPreDestroyMethod
                    (injInfo, nextClass);
                
                // Invoke the preDestroy methods starting from
                // the least-derived class downward.  
                preDestroyMethods.addFirst(preDestroyMethod);
            }

            nextClass = nextClass.getSuperclass();
        }

        for(Method preDestroyMethod : preDestroyMethods) {

            invokeLifecycleMethod(preDestroyMethod, instance);

        }