[jboss-cvs] JBossAS SVN: r77021 - in trunk/tomcat/src/main/org/jboss/web/tomcat/service: injection and 1 other directory.

jboss-cvs-commits at lists.jboss.org jboss-cvs-commits at lists.jboss.org
Wed Aug 13 12:52:19 EDT 2008


Author: emuckenhuber
Date: 2008-08-13 12:52:19 -0400 (Wed, 13 Aug 2008)
New Revision: 77021

Modified:
   trunk/tomcat/src/main/org/jboss/web/tomcat/service/TomcatInjectionContainer.java
   trunk/tomcat/src/main/org/jboss/web/tomcat/service/injection/WebResourceHandler.java
Log:
[JBAS-5673] remove duplicate annotation processing, use the correct persistence unit resolver, better handling for metadata complete

Modified: trunk/tomcat/src/main/org/jboss/web/tomcat/service/TomcatInjectionContainer.java
===================================================================
--- trunk/tomcat/src/main/org/jboss/web/tomcat/service/TomcatInjectionContainer.java	2008-08-13 16:51:15 UTC (rev 77020)
+++ trunk/tomcat/src/main/org/jboss/web/tomcat/service/TomcatInjectionContainer.java	2008-08-13 16:52:19 UTC (rev 77021)
@@ -33,10 +33,11 @@
 import java.util.ArrayList;
 import java.util.Collection;
 import java.util.HashMap;
-import java.util.LinkedHashMap;
+import java.util.HashSet;
 import java.util.List;
 import java.util.Map;
 import java.util.Properties;
+import java.util.Set;
 
 import javax.naming.Context;
 import javax.naming.InitialContext;
@@ -49,9 +50,7 @@
 import org.jboss.deployers.vfs.spi.structure.VFSDeploymentUnit;
 import org.jboss.ejb3.Container;
 import org.jboss.ejb3.DependencyPolicy;
-import org.jboss.ejb3.DeploymentScope;
 import org.jboss.ejb3.deployers.JBoss5DependencyPolicy;
-import org.jboss.ejb3.enc.DeploymentPersistenceUnitResolver;
 import org.jboss.ejb3.entity.PersistenceUnitDeployment;
 import org.jboss.ejb3.javaee.AbstractJavaEEComponent;
 import org.jboss.ejb3.javaee.SimpleJavaEEModule;
@@ -59,32 +58,28 @@
 import org.jboss.injection.EncInjector;
 import org.jboss.injection.ExtendedInjectionContainer;
 import org.jboss.injection.InjectionHandler;
-import org.jboss.injection.InjectionUtil;
 import org.jboss.injection.Injector;
 import org.jboss.injection.PersistenceContextHandler;
 import org.jboss.injection.PersistenceUnitHandler;
-import org.jboss.injection.WebServiceRefHandler;
 import org.jboss.jpa.resolvers.PersistenceUnitDependencyResolver;
 import org.jboss.logging.Logger;
 import org.jboss.metadata.javaee.spec.Environment;
 import org.jboss.metadata.javaee.spec.LifecycleCallbackMetaData;
-import org.jboss.metadata.web.jboss.JBossServletsMetaData;
 import org.jboss.metadata.web.jboss.JBossWebMetaData;
-import org.jboss.metadata.web.spec.FilterMetaData;
-import org.jboss.metadata.web.spec.FiltersMetaData;
-import org.jboss.metadata.web.spec.ListenerMetaData;
-import org.jboss.metadata.web.spec.ServletMetaData;
 import org.jboss.virtual.VirtualFile;
 import org.jboss.web.WebApplication;
+import org.jboss.web.tomcat.service.injection.TomcatInjectionUtils;
 import org.jboss.web.tomcat.service.injection.WebEJBInjectionHandler;
 import org.jboss.web.tomcat.service.injection.WebResourceHandler;
+import org.jboss.web.tomcat.service.injection.WebServiceRefInjectionHandler;
 
 /**
- * Comment
+ * The TomcatInjectionContainer.
  *
  * @author <a href="mailto:bill at jboss.org">Bill Burke</a>
  * @author adrian at jboss.org
  * @author Scott.Stark at jboss.org
+ * @author <a href="mailto:emuckenh at redhat.com">Emanuel Muckenhuber</a>
  * @version $Revision: 1.17 $
  */
 public class TomcatInjectionContainer extends AbstractJavaEEComponent implements ExtendedInjectionContainer, InstanceManager
@@ -129,10 +124,7 @@
 
    protected EncMap encInjectors = new EncMap();
    protected Map<String, Map<AccessibleObject, Injector>> encInjections = new HashMap<String, Map<AccessibleObject, Injector>>();
-   protected Map<String, Map<AccessibleObject, Injector>> resolvedClassInjections = new HashMap<String, Map<AccessibleObject, Injector>>();
 
-   protected List<PersistenceUnitDeployment> persistenceUnitDeployments = new ArrayList<PersistenceUnitDeployment>();
-   protected DeploymentPersistenceUnitResolver persistenceUnitResolver;
    protected DependencyPolicy dependencyPolicy = new JBoss5DependencyPolicy(this);
    protected Collection<InjectionHandler<Environment>> handlers;
    protected VFSDeploymentUnit unit;
@@ -141,6 +133,7 @@
    protected JBossWebMetaData webDD;
    protected org.apache.catalina.Context catalinaContext;
    private PersistenceUnitDependencyResolver persistenceUnitDependencyResolver;
+   private static final Set<String> dynamicClassLoaders = new HashSet<String>();
    private static final Properties restrictedFilters = new Properties();
    private static final Properties restrictedListeners = new Properties();
    private static final Properties restrictedServlets = new Properties();
@@ -183,6 +176,9 @@
        } catch (IOException e) {
     	   log.error("Error reading org/apache/catalina/core/RestrictedFilters.properties", e);
        }
+       
+       // 
+       dynamicClassLoaders.add("org.apache.jasper.servlet.JasperLoader");
    }
    
    public TomcatInjectionContainer(WebApplication appInfo, VFSDeploymentUnit unit, org.apache.catalina.Context catalinaContext, PersistenceUnitDependencyResolver resolver)
@@ -190,17 +186,13 @@
       super(new SimpleJavaEEModule(appInfo.getName()));
       
       this.unit = unit;
-      DeploymentScope deploymentScope = null;
       this.appInfo = appInfo;
       this.catalinaContext = catalinaContext;
-      LinkedHashMap empty = new LinkedHashMap(0);
-      persistenceUnitResolver = new DeploymentPersistenceUnitResolver(persistenceUnitDeployments, deploymentScope, empty);
+      this.persistenceUnitDependencyResolver = resolver;
       
       this.webDD = unit.getAttachment(JBossWebMetaData.class);
       assert this.webDD != null : "webDD is null (no JBossWebMetaData attachment in VFSDeploymentUnit)";
       
-      this.persistenceUnitDependencyResolver = resolver;
-      
    }
 
    private void checkAccess(Class<?> clazz)
@@ -244,18 +236,20 @@
       Class<?> clazz = loader.loadClass(className);
       checkAccess(clazz);
       Object instance = clazz.newInstance();
-	   if (!catalinaContext.getIgnoreAnnotations())
-	   {
+      processInjectors(instance);
+	  if (!catalinaContext.getIgnoreAnnotations())
+	  {
 		   processAnnotations(instance);
 		   postConstruct(instance);
-	   }
-       return instance;
+	  }
+      return instance;
    }
 
    public Object newInstance(String className, ClassLoader classLoader) throws IllegalAccessException, InvocationTargetException, NamingException, InstantiationException, ClassNotFoundException {
        Class<?> clazz = classLoader.loadClass(className);
        checkAccess(clazz);
        Object instance = clazz.newInstance();
+       processInjectors(instance);
 	   if (!catalinaContext.getIgnoreAnnotations())
 	   {
 		   processAnnotations(instance);
@@ -265,11 +259,12 @@
    }
 
    public void newInstance(Object instance) throws IllegalAccessException, InvocationTargetException, NamingException {
-	   if (!catalinaContext.getIgnoreAnnotations())
-	   {
+      processInjectors(instance);
+	  if (!catalinaContext.getIgnoreAnnotations())
+	  {
 		   processAnnotations(instance);
 		   postConstruct(instance);
-	   }
+	  }
    }
 
    public void destroyInstance(Object instance) throws IllegalAccessException, InvocationTargetException {
@@ -279,12 +274,16 @@
 	   }
    }
 
+   /**
+    * Process the @PostConstruct annotation
+    * 
+    * @param object the Object
+    * @throws IllegalAccessException
+    * @throws InvocationTargetException
+    */
    public void postConstruct(Object object) throws IllegalAccessException, InvocationTargetException
    {
-      if (webDD.getPostConstructs() == null)
-         return;
-
-      // @PostConstruct 
+      if (webDD.getPostConstructs() == null) return;
       for (LifecycleCallbackMetaData metaData : webDD.getPostConstructs())
       {
          try
@@ -303,12 +302,16 @@
       }
    }
 
+   /**
+    * Process the @PreDestroy annotation.
+    * 
+    * @param object the Object
+    * @throws IllegalAccessException
+    * @throws InvocationTargetException
+    */
    public void preDestroy(Object object) throws IllegalAccessException, InvocationTargetException
    {
-      if (webDD.getPreDestroys() == null)
-         return;
-
-      // @PreDestroy
+      if (webDD.getPreDestroys() == null) return;
       for (LifecycleCallbackMetaData metaData : webDD.getPreDestroys())
       {
          try
@@ -329,31 +332,56 @@
    }
 
    /**
-    * When we get here, we are assuming that any XML defined ENC has been set up.  We will set up more here
-    * if the class being processed is a JSP
+    * Process the injectors. 
+    * 
+    * @param object the object
+    */
+   private void processInjectors(Object object)
+   {
+      final boolean trace = log.isTraceEnabled();
+      
+      Map<AccessibleObject, Injector> injectors = getEncInjectionsForObject(object);
+      if (injectors == null || injectors.size() == 0)
+      {
+         if (trace)
+            log.trace("-- no injectors found: " + injectors);
+         return;
+      }
+      if (trace)
+         log.trace("-- doing injections");
+      for (Injector injector : injectors.values())
+      {
+         injector.inject(object);
+      }
+   }
+   
+   /**
+    * When we get here, we are assuming that any XML defined injection has been already done.
+    * We will set up more here if the class being processed is a dynamic class.
     *
-    *
-    * @param object
+    * @param object the Object
     * @throws IllegalAccessException
     * @throws InvocationTargetException
     * @throws NamingException
     */
-   public void processAnnotations(Object object) throws IllegalAccessException, InvocationTargetException, NamingException
+   public void processAnnotations(Object object)
+          throws IllegalAccessException, InvocationTargetException, NamingException
    {
-	  if (log.isTraceEnabled()) {
-		 log.trace("**************** Processing annotations for: " + object.getClass().getName());
-	  }
-      Map<AccessibleObject, Injector> injectors = resolvedClassInjections.get(object.getClass().getName());
+      final boolean trace = log.isTraceEnabled();
+      // Only process annotation on dynamic beans
+      if(! isDynamicBean(object))
+         return;
+      
+      Map<AccessibleObject, Injector> injectors = getEncInjectionsForObject(object);
       if (injectors == null)
       {
-    	  if (log.isTraceEnabled())
-    	  {
-    		  log.trace("-- there was no prior annotation preprocessing done");
-    	  }
+         if (trace)
+            log.trace("**************** Processing annotations for: " + object.getClass().getName());
+
          encInjectors.recordAdded();
-         // let's assume this is a JSP or some other artifact that cannot be found within XML
-         injectors = InjectionUtil.processAnnotations(this, handlers, object.getClass());
-         resolvedClassInjections.put(object.getClass().getName(), injectors);
+         
+         // Populate the encInjections
+         TomcatInjectionUtils.processAnnotations(this, handlers, object.getClass());
 
          // only execute injectors that were added additionally
          if (encInjectors.getAdded().size() > 0)
@@ -364,24 +392,54 @@
             }
             encInjectors.clearAdded();
          }
+         
+         // Process the injectors
+         processInjectors(object);
       }
-      if (injectors == null || injectors.size() == 0)
-      {
-    	  if (log.isTraceEnabled()) 
-    	  {
-    		  log.trace("-- no injectors found: " + injectors);
-    	  }
-         return;
-      }
+   }
+   
+   /**
+    * Get the the Injectors for a object and it's superclass.
+    * 
+    * @param object
+    * @return
+    */
+   private Map<AccessibleObject, Injector> getEncInjectionsForObject(Object object)
+   {
+      if(object == null || object.getClass() == Object.class)
+         return null;
+      
+      // TODO - make this recursive ?
+      Map<AccessibleObject, Injector> injectors = encInjections.get(object.getClass().getName());
+      Map<AccessibleObject, Injector> additionalInjectors = null;
+      if(object.getClass().getSuperclass() != null)
+         additionalInjectors = encInjections.get(object.getClass().getSuperclass().getName());
+      
+      if(injectors == null)
+         return additionalInjectors;
+      else if(additionalInjectors != null)
+         injectors.putAll(additionalInjectors);
+      
+      return injectors;
+   }
+   
+   /**
+    * Check if the class is a dynamic bean.
+    * 
+    * @param object the Object
+    * @return
+    */
+   private boolean isDynamicBean(Object object)
+   {
+      if(object == null)
+         throw new IllegalArgumentException("null class");
 
-	  if (log.isTraceEnabled())
-	  {
-		  log.trace("-- doing injections");
-	  }
-      for (Injector injector : injectors.values())
-      {
-         injector.inject(object);
-      }
+      // Check if the object was loaded by a dynamic class loader (e.g. Jasper)
+      String classLoaderName = object.getClass().getClassLoader().getClass().getName();
+      if(dynamicClassLoaders.contains(classLoaderName))
+         return true;
+      
+      return false;
    }
 
    public void populateEnc(ClassLoader loader)
@@ -391,52 +449,12 @@
          injector.inject(this);
       }
    }
-
-   private void processClass(String className, ClassLoader webLoader) throws ClassNotFoundException
-   {
-      if (resolvedClassInjections.containsKey(className))
-         return;
-      Class<?> cls = webLoader.loadClass(className);
-      Map<AccessibleObject, Injector> tmp = InjectionUtil.processAnnotations(this, handlers, cls);
-      resolvedClassInjections.put(className, tmp);
-   }
    
-   private void processFilters(FiltersMetaData filters, ClassLoader webLoader)
-   {
-      if(filters == null) return;
-      for (FilterMetaData filter : filters)
-      {
-         try
-         {
-            processClass(filter.getFilterClass(), webLoader);
-         }
-         catch (ClassNotFoundException e)
-         {
-            throw new RuntimeException("could not find filter class in classpath", e);
-         }
-      }
-   }
-   
-   private void processListeners(List<ListenerMetaData> listeners, ClassLoader webLoader)
-   {
-      if(listeners == null) return;
-      for (ListenerMetaData listener : listeners)
-      {
-         try
-         {
-            processClass(listener.getListenerClass(), webLoader);
-         }
-         catch (ClassNotFoundException e)
-         {
-            throw new RuntimeException("could not find listener class in classpath", e);
-         }
-      }
-   }
-   
    private void processesLifecycleCallbackMetaData(Object object, LifecycleCallbackMetaData lifeCycleMetaData) throws IllegalAccessException, InvocationTargetException
    {
-      Method method = null;
+      final Object args[] = null;
       Class<?> clazz = object.getClass();
+      Method method = null;
       // Also check superClasses for private members
       while(clazz != null)
       {
@@ -454,19 +472,26 @@
       if(method == null)
          throw new IllegalStateException("Method: "+ lifeCycleMetaData.getMethodName() + " not found.");
       
-      Object args[] = null;
-      method.setAccessible(true);
-      // Finally invoke the method
-      method.invoke(object, args);
+      boolean accessible = method.isAccessible();
+      try
+      {
+         // Finally invoke the method
+         method.setAccessible(true);
+         method.invoke(object, args);
+      }
+      finally
+      {
+         method.setAccessible(accessible);
+      }
    }
    
    /**
-    * introspects EJB container to find all dependencies
-    * and initialize any extra metadata.
+    * Process the meta data. There is no introspection needed, as the annotations 
+    * were already processed. The handlers add the EjbEncInjectors to encInjectors.
+    * Other injectors are added to the encInjections map.
     * <p/>
     * This must be called before container is registered with any microcontainer
     *
-    * @param dependencyPolicy
     */
    public void processMetadata()
    {
@@ -476,12 +501,10 @@
       handlers = new ArrayList<InjectionHandler<Environment>>();
       handlers.add(new WebEJBInjectionHandler<Environment>());
       handlers.add(new DependsHandler<Environment>());
-      // FIXME: is this allowed in servlets?
-      //handlers.add(new JndiInjectHandler<Environment>());
       handlers.add(new PersistenceContextHandler<Environment>());
       handlers.add(new PersistenceUnitHandler<Environment>());
       handlers.add(new WebResourceHandler<Environment>());
-      handlers.add(new WebServiceRefHandler<Environment>());
+      handlers.add(new WebServiceRefInjectionHandler<Environment>());
 
       ClassLoader old = Thread.currentThread().getContextClassLoader();
       ClassLoader webLoader = getClassloader();
@@ -490,34 +513,12 @@
       {
          for (InjectionHandler<Environment> handler : handlers)
             handler.loadXml(webDD.getJndiEnvironmentRefsGroup(), this);
-
-         processServlets(webDD.getServlets(), webLoader);
-         processFilters(webDD.getFilters(), webLoader);
-         processListeners(webDD.getListeners(), webLoader);
       }
       finally
       {
          Thread.currentThread().setContextClassLoader(old);
       }
    }
-
-   private void processServlets(JBossServletsMetaData servlets, ClassLoader webLoader)
-   {
-      if(servlets == null) return;
-      for (ServletMetaData servlet : servlets)
-      {
-         try
-         {
-            if (servlet.getServletClass() == null)
-               continue; // jsp
-            processClass(servlet.getServletClass(), webLoader);
-         }
-         catch (ClassNotFoundException e)
-         {
-            log.warn("could not find servlet class " + servlet.getServletClass() + " in classpath when processing annotations.");
-         }
-      }
-   }
    
    public Map<String, EncInjector> getEncInjectors()
    {
@@ -583,7 +584,6 @@
 
    public PersistenceUnitDeployment getPersistenceUnitDeployment(String unitName) throws NameNotFoundException
    {
-      //return persistenceUnitResolver.getPersistenceUnitDeployment(unitName);
       throw new RuntimeException("Call resolvePersistenceUnitSupplier");
    }
 
@@ -605,7 +605,6 @@
    public String getEjbJndiName(Class<?> businessIntf) throws NameNotFoundException
    {
       throw new IllegalStateException("Resolution should not happen via injection container");
-
    }
 
    public String getEjbJndiName(String link, Class<?> businessIntf)

Modified: trunk/tomcat/src/main/org/jboss/web/tomcat/service/injection/WebResourceHandler.java
===================================================================
--- trunk/tomcat/src/main/org/jboss/web/tomcat/service/injection/WebResourceHandler.java	2008-08-13 16:51:15 UTC (rev 77020)
+++ trunk/tomcat/src/main/org/jboss/web/tomcat/service/injection/WebResourceHandler.java	2008-08-13 16:52:19 UTC (rev 77021)
@@ -31,7 +31,6 @@
 
 import javax.annotation.Resource;
 import javax.annotation.Resources;
-import javax.ejb.EJBContext;
 import javax.ejb.EJBException;
 import javax.ejb.SessionContext;
 import javax.ejb.TimerService;
@@ -156,7 +155,7 @@
                   };
                   if(envRef.getInjectionTargets() != null)
                   {
-                     InjectionUtil.createInjectors(container.getInjectors(), container.getClassloader(), factory, envRef.getInjectionTargets());
+                     TomcatInjectionUtils.createInjectors(container.getEncInjections(), container.getClassloader(), factory, envRef.getInjectionTargets());
                      continue;
                   }
                   else
@@ -227,7 +226,7 @@
                      };
                      if(envRef.getInjectionTargets() != null)
                      {
-                        InjectionUtil.createInjectors(container.getInjectors(), container.getClassloader(), factory, envRef.getInjectionTargets());
+                        TomcatInjectionUtils.createInjectors(container.getEncInjections(), container.getClassloader(), factory, envRef.getInjectionTargets());
                         continue;
                      }
                      else
@@ -251,7 +250,7 @@
                      }; 
                      if(envRef.getInjectionTargets() != null)
                      {
-                        InjectionUtil.createInjectors(container.getInjectors(), container.getClassloader(), factory, envRef.getInjectionTargets());
+                        TomcatInjectionUtils.createInjectors(container.getEncInjections(), container.getClassloader(), factory, envRef.getInjectionTargets());
                         continue; 
                      }  
                   }
@@ -479,4 +478,5 @@
             injectors.put(accObj, new JndiPropertyInjector(property, encName, container.getEnc()));
          }      
       }
+            
    }




More information about the jboss-cvs-commits mailing list