[jboss-cvs] JBossAS SVN: r93931 - in trunk: server/src/main/org/jboss/web/deployers and 1 other directories.

jboss-cvs-commits at lists.jboss.org jboss-cvs-commits at lists.jboss.org
Tue Sep 22 13:20:07 EDT 2009


Author: remy.maucherat at jboss.com
Date: 2009-09-22 13:20:06 -0400 (Tue, 22 Sep 2009)
New Revision: 93931

Added:
   trunk/server/src/main/org/jboss/web/deployers/HandlesTypesClassFilter.java
   trunk/server/src/main/org/jboss/web/deployers/ServletContainerInitializerDeployer.java
Modified:
   trunk/server/src/main/org/jboss/deployment/AnnotationMetaDataDeployer.java
   trunk/server/src/main/org/jboss/web/deployers/MergedJBossWebMetaDataDeployer.java
   trunk/tomcat/src/main/org/jboss/web/tomcat/service/deployers/JBossContextConfig.java
Log:
- Spin off ServletContainerInitializer to a separate deployer, full of extreme HandlesTypes evilness.
- Implement HandlesTypes support (not tested yet, actually the SCI deployer is not being added yet).
  100% guaranteed evil stuff, or your money back.
- Uncomment stuff as some API is added.
- Add Store support; will fail if the manager is not a PersistentManagerBase.

Modified: trunk/server/src/main/org/jboss/deployment/AnnotationMetaDataDeployer.java
===================================================================
--- trunk/server/src/main/org/jboss/deployment/AnnotationMetaDataDeployer.java	2009-09-22 17:15:53 UTC (rev 93930)
+++ trunk/server/src/main/org/jboss/deployment/AnnotationMetaDataDeployer.java	2009-09-22 17:20:06 UTC (rev 93931)
@@ -183,9 +183,6 @@
 
       try
       {
-         // FIXME: Actually investigate to see when this deployer is run
-         // FIXME: Actually, process classpath elements one by one according to the order, 
-         // producing a separate WebMetaData for each one (only for web metadata)
          processMetaData(unit, webMetaData, clientMetaData, classpath);
       }
       catch (Exception e)

Added: trunk/server/src/main/org/jboss/web/deployers/HandlesTypesClassFilter.java
===================================================================
--- trunk/server/src/main/org/jboss/web/deployers/HandlesTypesClassFilter.java	                        (rev 0)
+++ trunk/server/src/main/org/jboss/web/deployers/HandlesTypesClassFilter.java	2009-09-22 17:20:06 UTC (rev 93931)
@@ -0,0 +1,187 @@
+/*
+ * JBoss, Home of Professional Open Source
+ * Copyright 2007, Red Hat Middleware LLC, and individual contributors
+ * by the @authors tag. See the copyright.txt in the distribution for a
+ * full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+package org.jboss.web.deployers;
+
+import java.io.IOException;
+import java.lang.annotation.Annotation;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+import javax.servlet.ServletContainerInitializer;
+
+import org.jboss.deployers.structure.spi.DeploymentUnit;
+import org.jboss.deployers.vfs.spi.structure.VFSDeploymentUnit;
+import org.jboss.logging.Logger;
+import org.jboss.virtual.VirtualFile;
+import org.jboss.virtual.VirtualFileFilter;
+import org.jboss.virtual.VirtualFileVisitor;
+import org.jboss.virtual.VisitorAttributes;
+
+/**
+ * A VirtualFileVisitor that traverses unit root and determines the
+ * class files that extend, implement, or are annotated by HandlesTypes.
+ * 
+ * @author Scott.Stark at jboss.org
+ * @author Remy Maucherat
+ * @version $Revision: 82920 $
+ */
+public class HandlesTypesClassFilter implements VirtualFileVisitor
+{
+   private static Logger log = Logger.getLogger(HandlesTypesClassFilter.class);
+   private ClassLoader loader;
+   private int rootLength;
+   private HashSet<String> childPaths = new HashSet<String>();
+   //private HashMap<VirtualFile, Class<?>> pathToClasses = new HashMap<VirtualFile, Class<?>>();
+   private Map<ServletContainerInitializer, Set<Class<?>>> handlesTypes;
+   private Class<?>[] typesArray;
+   private Map<Class<?>, ServletContainerInitializer> typesMap;
+
+   public HandlesTypesClassFilter(VFSDeploymentUnit unit, ClassLoader loader,
+         VirtualFile classpathRoot, Class<?>[] typesArray, Map<Class<?>, ServletContainerInitializer> typesMap,
+         Map<ServletContainerInitializer, Set<Class<?>>> handlesTypes)
+   {
+      this.loader = loader;
+      this.handlesTypes = handlesTypes;
+      this.typesArray = typesArray;
+      this.typesMap = typesMap;
+
+      // Work out the root length. If there is a root, we need to add one to jump across the next /
+      String rootName = classpathRoot.getPathName();
+      rootLength = rootName.length();
+      if (rootLength > 0)
+         rootLength += 1;
+      List<DeploymentUnit> children = unit.getChildren();
+      if(children != null)
+      {
+         for(DeploymentUnit cu : children)
+         {
+            String path = cu.getName();
+            childPaths.add(path);
+         }
+      }
+   }
+
+   public VisitorAttributes getAttributes()
+   {
+      VisitorAttributes attributes = new VisitorAttributes();
+      attributes.setIncludeRoot(true);
+      attributes.setRecurseFilter(new NoChildFilter());
+      return attributes;
+   }
+
+   public void visit(VirtualFile file)
+   {
+      try
+      {
+         if(file.isLeaf())
+         {
+            accepts(file);
+         }
+      }
+      catch (IOException e)
+      {
+         throw new Error("Error visiting " + file, e);
+      }
+   }
+
+   public boolean accepts(VirtualFile file)
+   {
+      boolean accepts = file.getPathName().endsWith(".class");
+      if(accepts)
+      {
+         accepts = false;
+         String className = null;
+         try
+         {
+            className = getClassName(file);
+            Class<?> c = loader.loadClass(className);
+            for (Class<?> clazz : typesArray)
+            {
+               if ((clazz.isAnnotation() && c.isAnnotationPresent((Class<? extends Annotation>) clazz))
+                     || clazz.isAssignableFrom(c))
+               {
+                  ServletContainerInitializer sci = typesMap.get(clazz);
+                  handlesTypes.get(sci).add(c);
+               }
+            }
+         }
+         catch(NoClassDefFoundError ignored)
+         {
+            log.debug("Incomplete class: "+className+", NCDFE: "+ignored);
+         }
+         catch(Exception ignored)
+         {
+            if(log.isTraceEnabled())
+               log.trace("Failed to load class: "+className, ignored);
+         }
+      }
+      return accepts;
+   }
+
+   protected String getFilePath(VirtualFile file)
+   {
+      String path = null;
+      try
+      {
+         path = file.toURI().toString();
+      }
+      catch(Exception e)
+      {
+      }
+      return path;
+   }
+
+   /**
+    * Search the classpaths for the root of this file.
+    *
+    * @param classFile the class file
+    * @return fqn class name
+    * @throws IOException for any error
+    */
+   protected String getClassName(VirtualFile classFile) throws IOException
+   {
+      String pathName = classFile.getPathName();
+      String name = pathName.substring(rootLength, pathName.length()-6);
+      name = name.replace('/', '.');
+      return name;
+   }
+
+   class NoChildFilter implements VirtualFileFilter
+   {
+      public boolean accepts(VirtualFile file)
+      {
+         String path = getFilePath(file);
+         boolean accepts = false;
+         try
+         {
+            accepts = file.isLeaf() == false && childPaths.contains(path) == false;
+         }
+         catch(Exception e)
+         {
+         }
+         return accepts;
+      }
+      
+   }
+}

Modified: trunk/server/src/main/org/jboss/web/deployers/MergedJBossWebMetaDataDeployer.java
===================================================================
--- trunk/server/src/main/org/jboss/web/deployers/MergedJBossWebMetaDataDeployer.java	2009-09-22 17:15:53 UTC (rev 93930)
+++ trunk/server/src/main/org/jboss/web/deployers/MergedJBossWebMetaDataDeployer.java	2009-09-22 17:20:06 UTC (rev 93931)
@@ -316,28 +316,6 @@
       unit.addAttachment(WEB_ORDER_ATTACHMENT_NAME, order);
       unit.addAttachment(WEB_OVERLAYS_ATTACHMENT_NAME, overlays);
       
-      // Load the ServletContainerInitializer services
-      ServiceLoader<ServletContainerInitializer> serviceLoader = 
-         ServiceLoader.load(ServletContainerInitializer.class, unit.getClassLoader());
-      HashMap<Class<?>, ServletContainerInitializer> handlesTypes = 
-         new HashMap<Class<?>, ServletContainerInitializer>();
-      for (ServletContainerInitializer service : serviceLoader)
-      {
-         if (service.getClass().isAnnotationPresent(HandlesTypes.class))
-         {
-            HandlesTypes handlesTypesAnnotation = service.getClass().getAnnotation(HandlesTypes.class);
-            Class<?>[] typesArray = handlesTypesAnnotation.value();
-            if (typesArray != null)
-            {
-               for (Class<?> type : typesArray)
-               {
-                  handlesTypes.put(type, service);
-               }
-            }
-         }
-      }
-      // TODO: Find classes which extend, implement, or are annotated by HandlesTypes
-
       // The fragments and corresponding annotations will need to be merged in order
       // For each JAR in the order: 
       // - Merge the annotation metadata into the fragment meta data 

Added: trunk/server/src/main/org/jboss/web/deployers/ServletContainerInitializerDeployer.java
===================================================================
--- trunk/server/src/main/org/jboss/web/deployers/ServletContainerInitializerDeployer.java	                        (rev 0)
+++ trunk/server/src/main/org/jboss/web/deployers/ServletContainerInitializerDeployer.java	2009-09-22 17:20:06 UTC (rev 93931)
@@ -0,0 +1,136 @@
+/*
+ * JBoss, Home of Professional Open Source
+ * Copyright 2008, Red Hat Middleware LLC, and individual contributors
+ * by the @authors tag. See the copyright.txt in the distribution for a
+ * full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+package org.jboss.web.deployers;
+
+import java.io.IOException;
+import java.io.Serializable;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Map;
+import java.util.ServiceLoader;
+import java.util.Set;
+
+import javax.servlet.ServletContainerInitializer;
+import javax.servlet.annotation.HandlesTypes;
+
+import org.jboss.deployers.spi.DeploymentException;
+import org.jboss.deployers.spi.deployer.DeploymentStages;
+import org.jboss.deployers.spi.deployer.helpers.AbstractDeployer;
+import org.jboss.deployers.structure.spi.DeploymentUnit;
+import org.jboss.deployers.vfs.spi.structure.VFSDeploymentUnit;
+import org.jboss.deployment.AnnotatedClassFilter;
+import org.jboss.deployment.AnnotationMetaDataDeployer;
+import org.jboss.metadata.ear.jboss.JBossAppMetaData;
+import org.jboss.metadata.javaee.spec.SecurityRolesMetaData;
+import org.jboss.metadata.web.jboss.JBossWebMetaData;
+import org.jboss.metadata.web.spec.AbsoluteOrderingMetaData;
+import org.jboss.metadata.web.spec.AnnotationMergedView;
+import org.jboss.metadata.web.spec.OrderingElementMetaData;
+import org.jboss.metadata.web.spec.Web25MetaData;
+import org.jboss.metadata.web.spec.Web30MetaData;
+import org.jboss.metadata.web.spec.WebFragmentMetaData;
+import org.jboss.metadata.web.spec.WebCommonMetaData;
+import org.jboss.metadata.web.spec.WebMetaData;
+import org.jboss.virtual.VirtualFile;
+
+/**
+ * A deployer that processes ServletContainerInitializer.
+ * 
+ * @author Remy Maucherat
+ * @version $Revision: 93820 $
+ */
+public class ServletContainerInitializerDeployer extends AbstractDeployer
+{
+   public static final String SCI_ATTACHMENT_NAME = "sci."+WebMetaData.class.getName();
+   public static final String SCI_HANDLESTYPES_ATTACHMENT_NAME = "sci.hasndlestypes."+WebMetaData.class.getName();
+  
+   /**
+    * Create a new MergedJBossWebMetaDataDeployer.
+    */
+   public ServletContainerInitializerDeployer()
+   {
+      setStage(DeploymentStages.POST_CLASSLOADER);
+      addOutput(SCI_ATTACHMENT_NAME);
+      addOutput(SCI_HANDLESTYPES_ATTACHMENT_NAME);
+   }
+
+   public void deploy(DeploymentUnit unit) throws DeploymentException
+   {
+      // Load the ServletContainerInitializer services
+      ServiceLoader<ServletContainerInitializer> serviceLoader = 
+         ServiceLoader.load(ServletContainerInitializer.class, unit.getClassLoader());
+      Map<Class<?>, ServletContainerInitializer> typesMap = 
+         new HashMap<Class<?>, ServletContainerInitializer>();
+      Set<ServletContainerInitializer> scis = new HashSet<ServletContainerInitializer>();
+      Map<ServletContainerInitializer, Set<Class<?>>> handlesTypes = 
+         new HashMap<ServletContainerInitializer, Set<Class<?>>>();
+      for (ServletContainerInitializer service : serviceLoader)
+      {
+         scis.add(service);
+         if (service.getClass().isAnnotationPresent(HandlesTypes.class))
+         {
+            HandlesTypes handlesTypesAnnotation = service.getClass().getAnnotation(HandlesTypes.class);
+            Class<?>[] typesArray = handlesTypesAnnotation.value();
+            if (typesArray != null)
+            {
+               for (Class<?> type : typesArray)
+               {
+                  typesMap.put(type, service);
+                  handlesTypes.put(service, new HashSet<Class<?>>());
+               }
+            }
+         }
+      }
+      
+      Class<?>[] typesArray = typesMap.keySet().toArray(new Class<?>[0]);
+      // Find classes which extend, implement, or are annotated by HandlesTypes
+      if (typesArray.length > 0 && unit instanceof VFSDeploymentUnit)
+      {
+         VFSDeploymentUnit vfsUnit = (VFSDeploymentUnit) unit;
+         VirtualFile webInfLib = vfsUnit.getFile("WEB-INF/lib");
+         if (webInfLib != null)
+         {
+            try
+            {
+               List<VirtualFile> jars = webInfLib.getChildren();
+               for (VirtualFile jar : jars)
+               {
+                  HandlesTypesClassFilter classVisitor = new HandlesTypesClassFilter(vfsUnit, unit.getClassLoader(), 
+                        jar, typesArray, typesMap, handlesTypes);
+                  jar.visit(classVisitor);
+               }
+            }
+            catch (IOException e)
+            {
+            }
+         }
+      }
+      
+      unit.addAttachment(SCI_ATTACHMENT_NAME, scis);
+      unit.addAttachment(SCI_HANDLESTYPES_ATTACHMENT_NAME, handlesTypes);
+  }
+
+}

Modified: trunk/tomcat/src/main/org/jboss/web/tomcat/service/deployers/JBossContextConfig.java
===================================================================
--- trunk/tomcat/src/main/org/jboss/web/tomcat/service/deployers/JBossContextConfig.java	2009-09-22 17:15:53 UTC (rev 93930)
+++ trunk/tomcat/src/main/org/jboss/web/tomcat/service/deployers/JBossContextConfig.java	2009-09-22 17:20:06 UTC (rev 93931)
@@ -25,6 +25,7 @@
 
 import java.io.IOException;
 import java.io.InputStream;
+import java.lang.reflect.Method;
 import java.util.ArrayList;
 import java.util.HashMap;
 import java.util.Iterator;
@@ -40,6 +41,7 @@
 
 import org.apache.catalina.core.ContextJarRepository;
 import org.apache.catalina.core.StandardContext;
+import org.apache.catalina.deploy.Multipart;
 import org.apache.catalina.deploy.SessionCookie;
 import org.apache.catalina.deploy.jsp.FunctionInfo;
 import org.apache.catalina.deploy.jsp.TagAttributeInfo;
@@ -81,6 +83,7 @@
 import org.jboss.metadata.web.spec.LocaleEncodingsMetaData;
 import org.jboss.metadata.web.spec.LoginConfigMetaData;
 import org.jboss.metadata.web.spec.MimeMappingMetaData;
+import org.jboss.metadata.web.spec.MultipartConfigMetaData;
 import org.jboss.metadata.web.spec.SecurityConstraintMetaData;
 import org.jboss.metadata.web.spec.ServletMappingMetaData;
 import org.jboss.metadata.web.spec.SessionConfigMetaData;
@@ -176,10 +179,9 @@
       context.setVersion(metaData.getVersion());
 
       // SetPublicId
-      /* TODO
-       if (metaData.is30())
+      if (metaData.is30())
          context.setPublicId("/javax/servlet/resources/web-app_3_0.dtd");
-      else */ if (metaData.is25())
+      else if (metaData.is25())
          context.setPublicId("/javax/servlet/resources/web-app_2_5.dtd");
       else if (metaData.is24())
          context.setPublicId("/javax/servlet/resources/web-app_2_4.dtd");
@@ -374,6 +376,9 @@
       {
          for (JBossServletMetaData value : servlets)
          {
+            /* TODO: Next meta data web update
+             * if (value.isAnnotation())
+               continue;*/
             org.apache.catalina.Wrapper wrapper = context.createWrapper();
             wrapper.setName(value.getName());
             wrapper.setServletClass(value.getServletClass());
@@ -404,9 +409,8 @@
             }
             wrapper.setAsyncSupported(value.isAsyncSupported());
             wrapper.setEnabled(value.isEnabled());
-            // TODO: Multipart configuration
-            /*
-            if (value.getMultipartConfigMetaData() != null)
+            // Multipart configuration
+            if (value.getMultipartConfig() != null)
             {
                MultipartConfigMetaData multipartConfigMetaData = value.getMultipartConfig();
                Multipart multipartConfig = new Multipart();
@@ -416,7 +420,6 @@
                multipartConfig.setFileSizeThreshold(multipartConfigMetaData.getFileSizeThreshold());
                wrapper.setMultipartConfig(multipartConfig);
              }
-             */
             context.addChild(wrapper);
          }
       }
@@ -736,11 +739,23 @@
             }
 
             // Context/Manager
-            // FIXME: add store
             if (contextMetaData.getManager() != null)
             {
-               context.setManager((org.apache.catalina.Manager)TomcatService.getInstance(contextMetaData.getManager(),
-                     "org.apache.catalina.session.StandardManager"));
+               org.apache.catalina.Manager manager = (org.apache.catalina.Manager)TomcatService.getInstance
+                  (contextMetaData.getManager(), "org.apache.catalina.session.StandardManager");
+               if (contextMetaData.getManager().getStore() != null)
+               {
+                  org.apache.catalina.Store store = (org.apache.catalina.Store)TomcatService.getInstance
+                     (contextMetaData.getManager().getStore(), null);
+                  try {
+                     org.apache.catalina.session.PersistentManagerBase.class.getMethod("setStore", org.apache.catalina.Store.class)
+                        .invoke(manager, store);
+                  } catch (Throwable t) {
+                     // Ignore
+                     log.error("Could not set persistent store", t);
+                  }
+               }
+               context.setManager(manager);
             }
 
             // Context/Parameter
@@ -1002,13 +1017,11 @@
 
    protected void completeConfig() {
 
-      // FIXME:
-      // It is possible it will be done elsewhere in the future, but these annotations
-      // are harder to deal with in AS, and pass to the servlet container; redoing it is cheap,
-      // but takes away some overriding capabilities
-      // Scan all Servlet API related annotations
+      // Process Servlet API related annotations that were dependent on Servlet declarations
       if (ok && !context.getIgnoreAnnotations())
       {
+         // TODO: Process servlets which are annotations, or multipart config and constraints
+         // TODO: Don't call Catalina
          WebAnnotationSet.loadApplicationAnnotations(context);
       }
       




More information about the jboss-cvs-commits mailing list