[seam-commits] Seam SVN: r7532 - in trunk: src/main/org/jboss/seam/deployment and 1 other directory.

seam-commits at lists.jboss.org seam-commits at lists.jboss.org
Tue Mar 11 14:28:41 EDT 2008


Author: pete.muir at jboss.org
Date: 2008-03-11 14:28:40 -0400 (Tue, 11 Mar 2008)
New Revision: 7532

Added:
   trunk/src/main/org/jboss/seam/deployment/AnnotationDeploymentHandler.java
Modified:
   trunk/doc/reference/en/modules/configuration.xml
   trunk/src/main/org/jboss/seam/deployment/HotDeploymentStrategy.java
   trunk/src/main/org/jboss/seam/deployment/StandardDeploymentStrategy.java
Log:
JBSEAM-2726

Modified: trunk/doc/reference/en/modules/configuration.xml
===================================================================
--- trunk/doc/reference/en/modules/configuration.xml	2008-03-11 15:26:21 UTC (rev 7531)
+++ trunk/doc/reference/en/modules/configuration.xml	2008-03-11 18:28:40 UTC (rev 7532)
@@ -884,11 +884,49 @@
         </para>
         
         <para>
-            You may also want Seam to handle custom resources. For example, you
-            could use this to process classes with a custom annotation at 
-            startup. To do this, we need to write a custom deployment handler:
+            You may also want Seam to handle custom resources. A common use case
+            is to handle a specific annotation and Seam provides specific 
+            support for this. First, tell Seam which annotations to handle in
+            <literal>/META-INF/seam-deployment.properties</literal>:
         </para>
         
+        <programlisting><![CDATA[# A comma separated list of annotation types to handle
+org.jboss.seam.deployment.annotationTypes=com.acme.Foo]]></programlisting>
+         
+        <para>
+            Then, during application startup you can get hold of all classes
+            annotated with <literal>@Foo</literal>:
+        </para>
+        
+        <programlisting><![CDATA[@Name("fooStartup")
+ at Scope(APPLICATION)
+ at Startup
+public class FooStartup {
+
+   @In("#{deploymentStrategy.annotatedClasses['com.acme.Foo']}")
+   private Set<Class<Object>> fooClasses;
+   
+   @In("#{hotDeploymentStrategy.annotatedClasses['com.acme.Foo']}")
+   private Set<Class<Object>> hotFooClasses;
+
+   @Create
+   public void create() {
+      for (Class clazz : fooClasses) {
+         handleClass(clazz);
+      }
+      for (Class clazz : hotFooClasses) {
+         handleClass(clazz);
+      }
+   }
+
+}]]></programlisting>
+
+        <para>    
+            You can also handle <emphasis>any</emphasis> resource. For example, 
+            you process any files with the extension <literal>.foo.xml</literal>.
+            To do this, we need to write a custom deployment handler:
+        </para>
+        
         <programlisting><![CDATA[public class FooDeploymentHandler implements DeploymentHandler {
         
    private Set<InputStream> files = new HashSet<InputStream>();
@@ -941,10 +979,10 @@
 @Startup
 public class FooStartup {
 
-   @In("#{org.jboss.seam.deployment.deploymentStrategy['fooDeploymentHandler']}")
+   @In("#{deploymentStrategy['fooDeploymentHandler']}")
    private MyDeploymentHandler myDeploymentHandler;
    
-   @In("#{org.jboss.seam.deployment.hotDeploymentStrategy['fooDeploymentHandler']}")
+   @In("#{hotDeploymentStrategy['fooDeploymentHandler']}")
    private MyDeploymentHandler myHotDeploymentHandler;
 
    @Create

Added: trunk/src/main/org/jboss/seam/deployment/AnnotationDeploymentHandler.java
===================================================================
--- trunk/src/main/org/jboss/seam/deployment/AnnotationDeploymentHandler.java	                        (rev 0)
+++ trunk/src/main/org/jboss/seam/deployment/AnnotationDeploymentHandler.java	2008-03-11 18:28:40 UTC (rev 7532)
@@ -0,0 +1,116 @@
+package org.jboss.seam.deployment;
+
+import java.io.IOException;
+import java.lang.annotation.Annotation;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+import javassist.bytecode.ClassFile;
+import org.jboss.seam.log.LogProvider;
+import org.jboss.seam.log.Logging;
+
+public class AnnotationDeploymentHandler extends AbstractDeploymentHandler
+{
+
+   /**
+    * Name under which this {@link DeploymentHandler} is registered
+    */
+   public static final String NAME = "org.jboss.seam.deployment.AnnotationDeploymentHandler";
+   
+   public static final String ANNOTATIONS_KEY = "org.jboss.seam.deployment.annotationTypes";
+   
+   private Map<String, Set<Class<Object>>> classes;
+   private Set<Class<? extends Annotation>> annotations;
+   
+   private static final LogProvider log = Logging.getLogProvider(AnnotationDeploymentHandler.class);
+   
+   public AnnotationDeploymentHandler(List<String> annotationTypes, ClassLoader classLoader)
+   {
+      annotations = new HashSet<Class<? extends Annotation>>();
+      for (String classname: annotationTypes)
+      {
+         try
+         {
+            annotations.add((Class<? extends Annotation>) classLoader.loadClass(classname));
+         }
+         catch (ClassNotFoundException cnfe) 
+         {
+            log.warn("could not load annotation class: " + classname, cnfe);
+         }
+         catch (NoClassDefFoundError ncdfe) 
+         {
+            log.warn("could not load annotation class (missing dependency): " + classname, ncdfe);
+         }
+         catch (ClassCastException cce)
+         {
+            log.warn("could not load annotation class (not an annotation): " + classname, cce);
+         }
+      }
+      
+      classes = new HashMap<String, Set<Class<Object>>>();
+      for (Class annotation: annotations)
+      {
+         classes.put(annotation.getName(), new HashSet<Class<Object>>());
+      }
+   }
+
+   /**
+    * Get annotated classes
+    */
+   public Map<String, Set<Class<Object>>> getClasses()
+   {
+      return Collections.unmodifiableMap(classes);
+   }
+   
+   
+   public String getName()
+   {
+      return NAME;
+   }
+
+   public void handle(String name, ClassLoader classLoader)
+   {
+      if (name.endsWith(".class")) 
+      {
+         String classname = filenameToClassname(name);
+         try 
+         {
+            ClassFile classFile = getClassFile(name, classLoader);
+            Class clazz = null;
+            for (Class<? extends Annotation> annotationType: annotations)
+            {
+               if (hasAnnotation(classFile, annotationType)) 
+               {
+                  log.trace("found class annotated with " + annotationType + ": " + name);
+                  if (clazz == null)
+                  {
+                     try
+                     {
+                        clazz = classLoader.loadClass(classname);
+                     }
+                     catch (ClassNotFoundException cnfe) 
+                     {
+                        log.debug("could not load class: " + classname, cnfe);
+                     }
+                     catch (NoClassDefFoundError ncdfe) 
+                     {
+                        log.debug("could not load class (missing dependency): " + classname, ncdfe);
+                     }
+                  }
+                  classes.get(annotationType.getName()).add( clazz );
+               }
+            }
+         }
+         catch (IOException ioe) 
+         {
+            log.debug("could not load classfile: " + classname, ioe);
+         }
+      }
+
+   }
+
+}


Property changes on: trunk/src/main/org/jboss/seam/deployment/AnnotationDeploymentHandler.java
___________________________________________________________________
Name: svn:mime-type
   + text/plain

Modified: trunk/src/main/org/jboss/seam/deployment/HotDeploymentStrategy.java
===================================================================
--- trunk/src/main/org/jboss/seam/deployment/HotDeploymentStrategy.java	2008-03-11 15:26:21 UTC (rev 7531)
+++ trunk/src/main/org/jboss/seam/deployment/HotDeploymentStrategy.java	2008-03-11 18:28:40 UTC (rev 7532)
@@ -1,10 +1,12 @@
 package org.jboss.seam.deployment;
 
 import java.io.File;
+import java.lang.annotation.Annotation;
 import java.lang.reflect.Constructor;
 import java.net.MalformedURLException;
 import java.net.URL;
 import java.net.URLClassLoader;
+import java.util.Map;
 import java.util.Set;
 
 import org.jboss.seam.contexts.Contexts;
@@ -27,7 +29,7 @@
     * The contextual variable name this deployment strategy is made available at
     * during Seam startup.
     */
-   public static final String NAME = "org.jboss.seam.deployment.hotDeploymentStrategy";
+   public static final String NAME = "hotDeploymentStrategy";
    
    /**
     * The key under which to list extra hot deployment directories
@@ -50,6 +52,7 @@
    private File[] hotDeploymentPaths;
    
    private ComponentDeploymentHandler componentDeploymentHandler;
+   private AnnotationDeploymentHandler annotationDeploymentHandler;
    
    /**
     * @param classLoader The parent classloader of the hot deployment classloader
@@ -60,7 +63,9 @@
    {
       initHotDeployClassLoader(classLoader, hotDeployDirectory);
       componentDeploymentHandler = new ComponentDeploymentHandler();
-      getDeploymentHandlers().put(ComponentDeploymentHandler.NAME, componentDeploymentHandler);  
+      getDeploymentHandlers().put(ComponentDeploymentHandler.NAME, componentDeploymentHandler);
+      annotationDeploymentHandler = new AnnotationDeploymentHandler(getPropertyValues(AnnotationDeploymentHandler.ANNOTATIONS_KEY), classLoader);
+      getDeploymentHandlers().put(AnnotationDeploymentHandler.NAME, annotationDeploymentHandler);
    }
    
    private void initHotDeployClassLoader(ClassLoader classLoader, File hotDeployDirectory)
@@ -141,6 +146,11 @@
       return componentDeploymentHandler.getClasses();
    }
 
+   public Map<String, Set<Class<Object>>> getAnnotatedClasses()
+   {
+      return annotationDeploymentHandler.getClasses();
+   }
+   
    @Override
    public void scan()
    {

Modified: trunk/src/main/org/jboss/seam/deployment/StandardDeploymentStrategy.java
===================================================================
--- trunk/src/main/org/jboss/seam/deployment/StandardDeploymentStrategy.java	2008-03-11 15:26:21 UTC (rev 7531)
+++ trunk/src/main/org/jboss/seam/deployment/StandardDeploymentStrategy.java	2008-03-11 18:28:40 UTC (rev 7532)
@@ -1,5 +1,7 @@
 package org.jboss.seam.deployment;
 
+import java.lang.annotation.Annotation;
+import java.util.Map;
 import java.util.Set;
 
 import org.jboss.seam.contexts.Contexts;
@@ -25,7 +27,7 @@
     * The contextual variable name this deployment strategy is made available at
     * during Seam startup.
     */
-   public static final String NAME = "org.jboss.seam.deployment.deploymentStrategy";
+   public static final String NAME = "deploymentStrategy";
    
    /**
     * The key under which to list extra deployment handlers.
@@ -37,6 +39,7 @@
 
    private ComponentDeploymentHandler componentDeploymentHandler;
    private NamespaceDeploymentHandler namespaceDeploymentHandler;
+   private AnnotationDeploymentHandler annotationDeploymentHandler;
    
    /**
     * @param classLoader The classloader used to load and handle resources
@@ -48,6 +51,8 @@
       getDeploymentHandlers().put(ComponentDeploymentHandler.NAME, componentDeploymentHandler);
       namespaceDeploymentHandler = new NamespaceDeploymentHandler();
       getDeploymentHandlers().put(NamespaceDeploymentHandler.NAME, namespaceDeploymentHandler);
+      annotationDeploymentHandler = new AnnotationDeploymentHandler(getPropertyValues(AnnotationDeploymentHandler.ANNOTATIONS_KEY), classLoader);
+      getDeploymentHandlers().put(AnnotationDeploymentHandler.NAME, annotationDeploymentHandler);
    }
 
    @Override
@@ -86,6 +91,11 @@
       return namespaceDeploymentHandler.getPackages();
    }
    
+   public Map<String, Set<Class<Object>>> getAnnotatedClasses()
+   {
+      return annotationDeploymentHandler.getClasses();
+   }
+   
    @Override
    public void scan()
    {




More information about the seam-commits mailing list