[jboss-cvs] JBossAS SVN: r76750 - in projects/jboss-deployers/trunk:	deployers-vfs/src/main/org/jboss/deployers/vfs/plugins/structure/explicit	and 9 other directories.
    jboss-cvs-commits at lists.jboss.org 
    jboss-cvs-commits at lists.jboss.org
       
    Thu Aug  7 04:29:10 EDT 2008
    
    
  
Author: alesj
Date: 2008-08-07 04:29:09 -0400 (Thu, 07 Aug 2008)
New Revision: 76750
Added:
   projects/jboss-deployers/trunk/deployers-vfs-spi/src/main/org/jboss/deployers/vfs/spi/structure/CandidateAnnotationsCallback.java
   projects/jboss-deployers/trunk/deployers-vfs/src/main/org/jboss/deployers/vfs/plugins/structure/AbstractVFSStructureDeployer.java
Modified:
   projects/jboss-deployers/trunk/deployers-vfs-spi/src/main/org/jboss/deployers/vfs/spi/structure/StructureContext.java
   projects/jboss-deployers/trunk/deployers-vfs-spi/src/main/org/jboss/deployers/vfs/spi/structure/StructureDeployer.java
   projects/jboss-deployers/trunk/deployers-vfs-spi/src/main/org/jboss/deployers/vfs/spi/structure/helpers/AbstractStructureDeployer.java
   projects/jboss-deployers/trunk/deployers-vfs/src/main/org/jboss/deployers/vfs/plugins/structure/StructureDeployerWrapper.java
   projects/jboss-deployers/trunk/deployers-vfs/src/main/org/jboss/deployers/vfs/plugins/structure/explicit/DeclaredStructure.java
   projects/jboss-deployers/trunk/deployers-vfs/src/main/org/jboss/deployers/vfs/plugins/structure/file/FileStructure.java
   projects/jboss-deployers/trunk/deployers-vfs/src/main/org/jboss/deployers/vfs/plugins/structure/jar/JARStructure.java
   projects/jboss-deployers/trunk/deployers-vfs/src/main/org/jboss/deployers/vfs/plugins/structure/war/WARStructure.java
   projects/jboss-deployers/trunk/deployers-vfs/src/tests/org/jboss/test/deployers/vfs/structure/ear/support/MockEarStructureDeployer.java
   projects/jboss-deployers/trunk/deployers-vfs/src/tests/org/jboss/test/deployers/vfs/structure/ear/test/AbstractEARStructureTest.java
   projects/jboss-deployers/trunk/deployers-vfs/src/tests/org/jboss/test/deployers/vfs/structure/support/TestDummyClassLoaderStructureDeployer.java
   projects/jboss-deployers/trunk/deployers-vfs/src/tests/org/jboss/test/deployers/vfs/structure/test/TerminateStructureTestCase.java
Log:
[JBDEPLOY-67]; Add support for candidate structure based on annotations.
Added: projects/jboss-deployers/trunk/deployers-vfs/src/main/org/jboss/deployers/vfs/plugins/structure/AbstractVFSStructureDeployer.java
===================================================================
--- projects/jboss-deployers/trunk/deployers-vfs/src/main/org/jboss/deployers/vfs/plugins/structure/AbstractVFSStructureDeployer.java	                        (rev 0)
+++ projects/jboss-deployers/trunk/deployers-vfs/src/main/org/jboss/deployers/vfs/plugins/structure/AbstractVFSStructureDeployer.java	2008-08-07 08:29:09 UTC (rev 76750)
@@ -0,0 +1,97 @@
+/*
+* JBoss, Home of Professional Open Source
+* Copyright 2006, JBoss Inc., and individual contributors as indicated
+* 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.deployers.vfs.plugins.structure;
+
+import org.jboss.classloader.spi.filter.ClassFilter;
+import org.jboss.classloading.plugins.vfs.VFSResourceVisitor;
+import org.jboss.classloading.spi.visitor.ResourceFilter;
+import org.jboss.deployers.plugins.annotations.GenericAnnotationResourceVisitor;
+import org.jboss.deployers.spi.annotations.AnnotationEnvironment;
+import org.jboss.deployers.structure.spi.DeploymentResourceLoader;
+import org.jboss.deployers.structure.spi.helpers.DeploymentResourceClassLoader;
+import org.jboss.deployers.vfs.spi.structure.helpers.AbstractStructureDeployer;
+import org.jboss.virtual.VirtualFile;
+
+/**
+ * VFS aware structure deployer.
+ *
+ * @author <a href="mailto:ales.justin at jboss.com">Ales Justin</a>
+ */
+public abstract class AbstractVFSStructureDeployer extends AbstractStructureDeployer
+{
+   private ClassFilter included;
+   private ClassFilter excluded;
+   private ResourceFilter filter;
+   private ResourceFilter recurseFilter;
+
+   protected AnnotationEnvironment createAnnotationEnvironment(VirtualFile root)
+   {
+      DeploymentResourceLoader loader = new VFSDeploymentResourceLoaderImpl(root);
+      ClassLoader classLoader = new DeploymentResourceClassLoader(loader);
+      GenericAnnotationResourceVisitor visitor = new GenericAnnotationResourceVisitor(classLoader);
+      ResourceFilter filter = this.filter;
+      if (filter == null)
+         filter = visitor.getFilter();
+      VFSResourceVisitor.visit(new VirtualFile[]{root}, null, included, excluded, classLoader, visitor, filter, recurseFilter);
+      return visitor.getEnv();
+   }
+
+   /**
+    * Set the included class filter.
+    *
+    * @param included the included class filter
+    */
+   public void setIncluded(ClassFilter included)
+   {
+      this.included = included;
+   }
+
+   /**
+    * Set the excluded class filter.
+    *
+    * @param excluded the excluded class filter
+    */
+   public void setExcluded(ClassFilter excluded)
+   {
+      this.excluded = excluded;
+   }
+
+   /**
+    * Set the filter.
+    *
+    * @param filter the filter
+    */
+   public void setFilter(ResourceFilter filter)
+   {
+      this.filter = filter;
+   }
+
+   /**
+    * Set the recurse filter.
+    *
+    * @param recurseFilter the recurse filter
+    */
+   public void setRecurseFilter(ResourceFilter recurseFilter)
+   {
+      this.recurseFilter = recurseFilter;
+   }
+}
Modified: projects/jboss-deployers/trunk/deployers-vfs/src/main/org/jboss/deployers/vfs/plugins/structure/StructureDeployerWrapper.java
===================================================================
--- projects/jboss-deployers/trunk/deployers-vfs/src/main/org/jboss/deployers/vfs/plugins/structure/StructureDeployerWrapper.java	2008-08-07 07:57:30 UTC (rev 76749)
+++ projects/jboss-deployers/trunk/deployers-vfs/src/main/org/jboss/deployers/vfs/plugins/structure/StructureDeployerWrapper.java	2008-08-07 08:29:09 UTC (rev 76750)
@@ -64,6 +64,9 @@
       if (context == null)
          throw new IllegalArgumentException("Null context");
 
+      if (context.isCandidateAnnotationScanning() && deployer.isSupportsCandidateAnnotations() == false)
+         return false;
+      
       ClassLoader previous = SecurityActions.setContextClassLoader(classLoader);
       try
       {
@@ -82,7 +85,12 @@
          SecurityActions.resetContextClassLoader(previous);
       }
    }
-   
+
+   public boolean isSupportsCandidateAnnotations()
+   {
+      return deployer.isSupportsCandidateAnnotations();
+   }
+
    public int getRelativeOrder()
    {
       return deployer.getRelativeOrder();
Modified: projects/jboss-deployers/trunk/deployers-vfs/src/main/org/jboss/deployers/vfs/plugins/structure/explicit/DeclaredStructure.java
===================================================================
--- projects/jboss-deployers/trunk/deployers-vfs/src/main/org/jboss/deployers/vfs/plugins/structure/explicit/DeclaredStructure.java	2008-08-07 07:57:30 UTC (rev 76749)
+++ projects/jboss-deployers/trunk/deployers-vfs/src/main/org/jboss/deployers/vfs/plugins/structure/explicit/DeclaredStructure.java	2008-08-07 08:29:09 UTC (rev 76750)
@@ -25,8 +25,8 @@
 import java.net.URL;
 
 import org.jboss.deployers.spi.DeploymentException;
+import org.jboss.deployers.vfs.plugins.structure.AbstractVFSStructureDeployer;
 import org.jboss.deployers.vfs.spi.structure.StructureContext;
-import org.jboss.deployers.vfs.spi.structure.helpers.AbstractStructureDeployer;
 import org.jboss.virtual.VirtualFile;
 import org.jboss.xb.binding.Unmarshaller;
 import org.jboss.xb.binding.UnmarshallerFactory;
@@ -38,7 +38,7 @@
  * @author Scott.Stark at jboss.org
  * @version $Revision: 1.1 $
  */
-public class DeclaredStructure extends AbstractStructureDeployer
+public class DeclaredStructure extends AbstractVFSStructureDeployer
 {
    /**
     * Set the relative order to 0 by default.
Modified: projects/jboss-deployers/trunk/deployers-vfs/src/main/org/jboss/deployers/vfs/plugins/structure/file/FileStructure.java
===================================================================
--- projects/jboss-deployers/trunk/deployers-vfs/src/main/org/jboss/deployers/vfs/plugins/structure/file/FileStructure.java	2008-08-07 07:57:30 UTC (rev 76749)
+++ projects/jboss-deployers/trunk/deployers-vfs/src/main/org/jboss/deployers/vfs/plugins/structure/file/FileStructure.java	2008-08-07 08:29:09 UTC (rev 76750)
@@ -28,9 +28,9 @@
 import org.jboss.beans.metadata.api.annotations.Uninstall;
 import org.jboss.deployers.spi.DeploymentException;
 import org.jboss.deployers.spi.structure.ContextInfo;
+import org.jboss.deployers.vfs.plugins.structure.AbstractVFSStructureDeployer;
 import org.jboss.deployers.vfs.spi.deployer.FileMatcher;
 import org.jboss.deployers.vfs.spi.structure.StructureContext;
-import org.jboss.deployers.vfs.spi.structure.helpers.AbstractStructureDeployer;
 import org.jboss.virtual.VirtualFile;
 
 /**
@@ -39,7 +39,7 @@
  * @author <a href="adrian at jboss.com">Adrian Brock</a>
  * @version $Revision: 1.1 $
  */
-public class FileStructure extends AbstractStructureDeployer
+public class FileStructure extends AbstractVFSStructureDeployer
 {
    /** The file suffixes */
    private static Set<String> fileSuffixes = new CopyOnWriteArraySet<String>();
Modified: projects/jboss-deployers/trunk/deployers-vfs/src/main/org/jboss/deployers/vfs/plugins/structure/jar/JARStructure.java
===================================================================
--- projects/jboss-deployers/trunk/deployers-vfs/src/main/org/jboss/deployers/vfs/plugins/structure/jar/JARStructure.java	2008-08-07 07:57:30 UTC (rev 76749)
+++ projects/jboss-deployers/trunk/deployers-vfs/src/main/org/jboss/deployers/vfs/plugins/structure/jar/JARStructure.java	2008-08-07 08:29:09 UTC (rev 76750)
@@ -29,8 +29,8 @@
 import org.jboss.deployers.spi.DeploymentException;
 import org.jboss.deployers.spi.deployer.matchers.JarExtensionProvider;
 import org.jboss.deployers.spi.structure.ContextInfo;
+import org.jboss.deployers.vfs.plugins.structure.AbstractVFSStructureDeployer;
 import org.jboss.deployers.vfs.spi.structure.StructureContext;
-import org.jboss.deployers.vfs.spi.structure.helpers.AbstractStructureDeployer;
 import org.jboss.virtual.VirtualFile;
 import org.jboss.virtual.plugins.context.jar.JarUtils;
 
@@ -40,7 +40,7 @@
  * @author <a href="adrian at jboss.com">Adrian Brock</a>
  * @version $Revision: 1.1 $
  */
-public class JARStructure extends AbstractStructureDeployer
+public class JARStructure extends AbstractVFSStructureDeployer
 {
    /**
     * Create a new JARStructure. with the default suffixes
@@ -152,15 +152,24 @@
             return false;
          }
 
-         // Create a context for this jar file with META-INF as the location for metadata  
-         context = createContext(structureContext, "META-INF");
+         boolean valid = true;
 
-         // The classpath is the root
-         super.addClassPath(structureContext, file, true, true, context);
+         StructureContext parentContext = structureContext.getParentContext();
+         if (parentContext != null && parentContext.isCandidateAnnotationScanning() && isSupportsCandidateAnnotations())
+            valid = checkCandidateAnnotations(structureContext, file);
 
-         // We try all the children as potential subdeployments
-         addAllChildren(structureContext);
-         return true;
+         if (valid)
+         {
+            // Create a context for this jar file with META-INF as the location for metadata
+            context = createContext(structureContext, "META-INF");
+
+            // The classpath is the root
+            addClassPath(structureContext, file, true, true, context);
+
+            // We try all the children as potential subdeployments
+            addAllChildren(structureContext);
+         }
+         return valid;
       }
       catch (Exception e)
       {
Modified: projects/jboss-deployers/trunk/deployers-vfs/src/main/org/jboss/deployers/vfs/plugins/structure/war/WARStructure.java
===================================================================
--- projects/jboss-deployers/trunk/deployers-vfs/src/main/org/jboss/deployers/vfs/plugins/structure/war/WARStructure.java	2008-08-07 07:57:30 UTC (rev 76749)
+++ projects/jboss-deployers/trunk/deployers-vfs/src/main/org/jboss/deployers/vfs/plugins/structure/war/WARStructure.java	2008-08-07 08:29:09 UTC (rev 76750)
@@ -26,8 +26,8 @@
 
 import org.jboss.deployers.spi.DeploymentException;
 import org.jboss.deployers.spi.structure.ContextInfo;
+import org.jboss.deployers.vfs.plugins.structure.AbstractVFSStructureDeployer;
 import org.jboss.deployers.vfs.spi.structure.StructureContext;
-import org.jboss.deployers.vfs.spi.structure.helpers.AbstractStructureDeployer;
 import org.jboss.virtual.VirtualFile;
 import org.jboss.virtual.VirtualFileFilter;
 import org.jboss.virtual.VisitorAttributes;
@@ -39,7 +39,7 @@
  * @author <a href="adrian at jboss.com">Adrian Brock</a>
  * @version $Revision: 1.1 $
  */
-public class WARStructure extends AbstractStructureDeployer
+public class WARStructure extends AbstractVFSStructureDeployer
 {
    /** The default filter which allows jars/jar directories */
    public static final VirtualFileFilter DEFAULT_WEB_INF_LIB_FILTER = new SuffixMatchFilter(".jar", VisitorAttributes.DEFAULT);
Modified: projects/jboss-deployers/trunk/deployers-vfs/src/tests/org/jboss/test/deployers/vfs/structure/ear/support/MockEarStructureDeployer.java
===================================================================
--- projects/jboss-deployers/trunk/deployers-vfs/src/tests/org/jboss/test/deployers/vfs/structure/ear/support/MockEarStructureDeployer.java	2008-08-07 07:57:30 UTC (rev 76749)
+++ projects/jboss-deployers/trunk/deployers-vfs/src/tests/org/jboss/test/deployers/vfs/structure/ear/support/MockEarStructureDeployer.java	2008-08-07 08:29:09 UTC (rev 76750)
@@ -25,20 +25,20 @@
 import java.io.InputStream;
 import java.lang.annotation.Annotation;
 import java.util.ArrayList;
+import java.util.HashMap;
 import java.util.List;
+import java.util.Map;
 import java.util.Properties;
 import java.util.jar.Attributes;
 import java.util.jar.Manifest;
 
-import org.jboss.classloader.spi.filter.ClassFilter;
-import org.jboss.classloading.plugins.vfs.VFSResourceVisitor;
-import org.jboss.classloading.spi.visitor.ResourceFilter;
-import org.jboss.deployers.plugins.annotations.GenericAnnotationResourceVisitor;
 import org.jboss.deployers.spi.DeploymentException;
 import org.jboss.deployers.spi.annotations.AnnotationEnvironment;
 import org.jboss.deployers.spi.structure.ContextInfo;
+import org.jboss.deployers.vfs.plugins.structure.AbstractVFSStructureDeployer;
+import org.jboss.deployers.vfs.spi.structure.CandidateAnnotationsCallback;
 import org.jboss.deployers.vfs.spi.structure.StructureContext;
-import org.jboss.deployers.vfs.spi.structure.helpers.AbstractStructureDeployer;
+import org.jboss.logging.Logger;
 import org.jboss.virtual.VFSUtils;
 import org.jboss.virtual.VirtualFile;
 import org.jboss.virtual.VirtualFileFilter;
@@ -52,7 +52,7 @@
  * @author Ales.Justin at jboss.org
  * @version $Revision:$
  */
-public class MockEarStructureDeployer extends AbstractStructureDeployer
+public class MockEarStructureDeployer extends AbstractVFSStructureDeployer
 {
    /**
     * The default ear/lib filter
@@ -135,10 +135,10 @@
          }
 
          // Add the ear manifest locations?
-         super.addClassPath(structureContext, file, false, true, context);
+         addClassPath(structureContext, file, false, true, context);
 
          if (scan)
-            scanEar(file, modules);
+            scanEar(structureContext, file, modules);
 
          // Create subdeployments for the ear modules
          for (EarModule mod : modules)
@@ -204,11 +204,16 @@
       }
    }
 
-   private void scanEar(VirtualFile root, List<EarModule> modules) throws IOException
+   private void scanEar(StructureContext context, VirtualFile root, List<EarModule> modules) throws Exception
    {
       List<VirtualFile> archives = root.getChildren();
-      if (archives != null)
+      if (archives != null && archives.isEmpty() == false)
       {
+         // enable candidate annotations
+         context.setCandidateAnnotationScanning(true);
+         EarCandidateAnnotationsCallback callback = new EarCandidateAnnotationsCallback();
+         context.addCallback(callback);
+
          String earPath = root.getPathName();
          int counter = 0;
          for (VirtualFile vfArchive : archives)
@@ -218,7 +223,18 @@
             EarModule moduleMetaData = getModule(modules, filename);
             if (moduleMetaData == null)
             {
-               int type = typeFromSuffix(filename, vfArchive);
+               // reset callback result
+               callback.reset();
+
+               int type = typeFromSuffix(context, filename, vfArchive);
+               Integer callbackResult = null;
+               if (type < 0)
+               {
+                  callbackResult = callback.getResult();
+                  if (callbackResult != null)
+                     type = callbackResult;
+               }
+
                if (type >= 0)
                {
                   String typeString = null;
@@ -241,12 +257,19 @@
                         typeString = "Web";
                         break;
                   }
-                  moduleMetaData = new EarModule(typeString + "Module" + counter, filename);
-                  modules.add(moduleMetaData);
-                  counter++;
+                  // we didin't do full recognition yet
+                  if (callbackResult == null)
+                  {
+                     moduleMetaData = new EarModule(typeString + "Module" + counter, filename);
+                     modules.add(moduleMetaData);
+                     counter++;
+                  }
                }
             }
          }
+
+         // reset candidate annotation scanning flag
+         context.setCandidateAnnotationScanning(false);
       }
    }
 
@@ -258,10 +281,10 @@
       return null;
    }
 
-   private int typeFromSuffix(String path, VirtualFile archive)
-         throws IOException
+   private int typeFromSuffix(StructureContext context, String path, VirtualFile archive) throws Exception
    {
       int type = -1;
+
       if (path.endsWith(".war"))
          type = J2eeModuleMetaData.WEB;
       else if (path.endsWith(".rar"))
@@ -292,9 +315,7 @@
             }
             else
             {
-               Integer dt = determineType(archive);
-               if (dt != null)
-                  type = dt;
+               determineType(context, archive);
             }
          }
          else if (ejbXml != null || jbossXml != null)
@@ -303,61 +324,18 @@
          }
          else
          {
-            Integer dt = determineType(archive);
-            if (dt != null)
-               type = dt;
+            determineType(context, archive);
          }
       }
 
       return type;
    }
 
-   private Integer determineType(VirtualFile archive)
+   private void determineType(StructureContext context, VirtualFile archive) throws Exception
    {
-      ClassLoader classLoader = new SimpleVFSResourceLoader(Thread.currentThread().getContextClassLoader(), archive);
-      GenericAnnotationResourceVisitor visitor = new GenericAnnotationResourceVisitor(classLoader);
-      ClassFilter included = null;
-      ClassFilter excluded = null;
-      ResourceFilter filter = org.jboss.classloading.spi.visitor.ClassFilter.INSTANCE;
-      VFSResourceVisitor.visit(new VirtualFile[]{archive}, null, included, excluded, classLoader, visitor, filter, null);
-      AnnotationEnvironment env = visitor.getEnv();
-
-      Integer ejbs = getType(env, Stateless.class, J2eeModuleMetaData.EJB);
-      if (ejbs != null)
-      {
-         // check some conflicts - e.g. no @Servlet, ...?
-         return ejbs;
-      }
-
-      Integer services = getType(env, Service.class, J2eeModuleMetaData.SERVICE);
-      if (services != null)
-      {
-         // check some conflicts - e.g. no @Servlet, ...?
-         return services;
-      }
-
-      Integer appc = getType(env, AppClient.class, J2eeModuleMetaData.CLIENT);
-      if (appc != null)
-      {
-         // check some conflicts - e.g. no @Servlet, ...?
-         return appc;
-      }
-
-      Integer wars = getType(env, Servlet.class, J2eeModuleMetaData.WEB);
-      if (wars != null)
-         return wars;
-
-      return null;
+      context.determineChildStructure(archive);
    }
 
-   private Integer getType(AnnotationEnvironment env, Class<? extends Annotation> annotation, int type)
-   {
-      // in real deployer this should use annotation class directly
-      // since annotation class on beans should be the same as
-      // annotation classes in deployer
-      return (env.hasClassAnnotatedWith(annotation.getName())) ? type : null;
-   }
-
    private String earRelativePath(String earPath, String pathName)
    {
       StringBuilder tmp = new StringBuilder(pathName);
@@ -377,4 +355,43 @@
       }
       return metaFile;
    }
+
+   private static class EarCandidateAnnotationsCallback implements CandidateAnnotationsCallback
+   {
+      private static final Logger log = Logger.getLogger(EarCandidateAnnotationsCallback.class);
+      private Integer result;
+
+      private final static Map<Class<? extends Annotation>, Integer> map;
+
+      static
+      {
+         map = new HashMap<Class<? extends Annotation>, Integer>();
+         map.put(Stateless.class, J2eeModuleMetaData.EJB);
+         map.put(Service.class, J2eeModuleMetaData.SERVICE);
+         map.put(AppClient.class, J2eeModuleMetaData.CLIENT);
+         map.put(Servlet.class, J2eeModuleMetaData.WEB);
+      }
+
+      public void executeCallback(VirtualFile root, StructureContext currentContext, AnnotationEnvironment env, Class<? extends Annotation> annotationClass)
+      {
+         if (result == null)
+         {
+            result = map.get(annotationClass);
+         }
+         else
+         {
+            log.warn("Result already set: " + result);
+         }
+      }
+
+      public void reset()
+      {
+         result = null;
+      }
+
+      public Integer getResult()
+      {
+         return result;
+      }
+   }
 }
Modified: projects/jboss-deployers/trunk/deployers-vfs/src/tests/org/jboss/test/deployers/vfs/structure/ear/test/AbstractEARStructureTest.java
===================================================================
--- projects/jboss-deployers/trunk/deployers-vfs/src/tests/org/jboss/test/deployers/vfs/structure/ear/test/AbstractEARStructureTest.java	2008-08-07 07:57:30 UTC (rev 76749)
+++ projects/jboss-deployers/trunk/deployers-vfs/src/tests/org/jboss/test/deployers/vfs/structure/ear/test/AbstractEARStructureTest.java	2008-08-07 08:29:09 UTC (rev 76750)
@@ -28,10 +28,14 @@
 import org.jboss.deployers.vfs.plugins.structure.jar.JARStructure;
 import org.jboss.deployers.vfs.plugins.structure.war.WARStructure;
 import org.jboss.deployers.vfs.spi.client.VFSDeployment;
+import org.jboss.deployers.vfs.spi.structure.StructureDeployer;
 import org.jboss.deployers.vfs.spi.structure.VFSDeploymentContext;
-import org.jboss.deployers.vfs.spi.structure.StructureDeployer;
 import org.jboss.test.deployers.vfs.structure.AbstractStructureTest;
+import org.jboss.test.deployers.vfs.structure.ear.support.AppClient;
 import org.jboss.test.deployers.vfs.structure.ear.support.MockEarStructureDeployer;
+import org.jboss.test.deployers.vfs.structure.ear.support.Service;
+import org.jboss.test.deployers.vfs.structure.ear.support.Servlet;
+import org.jboss.test.deployers.vfs.structure.ear.support.Stateless;
 import org.jboss.virtual.plugins.context.jar.JarUtils;
 
 /**
@@ -62,6 +66,11 @@
    {
       Set<String> defaultSuffixes = JarUtils.getSuffixes();
       JARStructure jarStructure = new JARStructure();
+      jarStructure.setSupportsCandidateAnnotations(true);
+      jarStructure.addCandidateAnnotation(Stateless.class);
+      jarStructure.addCandidateAnnotation(Service.class);
+      jarStructure.addCandidateAnnotation(AppClient.class);
+      jarStructure.addCandidateAnnotation(Servlet.class);
       try
       {
          Set<String> suffixes = new HashSet<String>(jarStructure.getSuffixes());
Modified: projects/jboss-deployers/trunk/deployers-vfs/src/tests/org/jboss/test/deployers/vfs/structure/support/TestDummyClassLoaderStructureDeployer.java
===================================================================
--- projects/jboss-deployers/trunk/deployers-vfs/src/tests/org/jboss/test/deployers/vfs/structure/support/TestDummyClassLoaderStructureDeployer.java	2008-08-07 07:57:30 UTC (rev 76749)
+++ projects/jboss-deployers/trunk/deployers-vfs/src/tests/org/jboss/test/deployers/vfs/structure/support/TestDummyClassLoaderStructureDeployer.java	2008-08-07 08:29:09 UTC (rev 76750)
@@ -22,8 +22,8 @@
 package org.jboss.test.deployers.vfs.structure.support;
 
 import org.jboss.deployers.spi.DeploymentException;
+import org.jboss.deployers.vfs.plugins.structure.AbstractVFSStructureDeployer;
 import org.jboss.deployers.vfs.spi.structure.StructureContext;
-import org.jboss.deployers.vfs.spi.structure.helpers.AbstractStructureDeployer;
 
 /**
  * TestDummyClassLoaderStructureDeployer.
@@ -31,7 +31,7 @@
  * @author <a href="adrian at jboss.com">Adrian Brock</a>
  * @version $Revision: 1.1 $
  */
-public class TestDummyClassLoaderStructureDeployer extends AbstractStructureDeployer
+public class TestDummyClassLoaderStructureDeployer extends AbstractVFSStructureDeployer
 {
    private static ClassLoader classLoader;
 
Modified: projects/jboss-deployers/trunk/deployers-vfs/src/tests/org/jboss/test/deployers/vfs/structure/test/TerminateStructureTestCase.java
===================================================================
--- projects/jboss-deployers/trunk/deployers-vfs/src/tests/org/jboss/test/deployers/vfs/structure/test/TerminateStructureTestCase.java	2008-08-07 07:57:30 UTC (rev 76749)
+++ projects/jboss-deployers/trunk/deployers-vfs/src/tests/org/jboss/test/deployers/vfs/structure/test/TerminateStructureTestCase.java	2008-08-07 08:29:09 UTC (rev 76750)
@@ -22,13 +22,12 @@
 package org.jboss.test.deployers.vfs.structure.test;
 
 import junit.framework.Test;
-
 import org.jboss.deployers.spi.DeploymentException;
+import org.jboss.deployers.vfs.plugins.structure.AbstractVFSStructureDeployer;
 import org.jboss.deployers.vfs.spi.client.VFSDeployment;
 import org.jboss.deployers.vfs.spi.structure.StructureContext;
 import org.jboss.deployers.vfs.spi.structure.StructureDeployer;
 import org.jboss.deployers.vfs.spi.structure.VFSDeploymentContext;
-import org.jboss.deployers.vfs.spi.structure.helpers.AbstractStructureDeployer;
 import org.jboss.test.deployers.vfs.structure.AbstractStructureTest;
 
 /**
@@ -107,7 +106,7 @@
       throw new UnsupportedOperationException("No use case.");
    }
 
-   private class PassStructureDeployer extends AbstractStructureDeployer
+   private class PassStructureDeployer extends AbstractVFSStructureDeployer
    {
       public PassStructureDeployer(int order)
       {
@@ -120,7 +119,7 @@
       }
    }
 
-   private class FailStructureDeployer extends AbstractStructureDeployer
+   private class FailStructureDeployer extends AbstractVFSStructureDeployer
    {
       public FailStructureDeployer(int order)
       {
@@ -133,7 +132,7 @@
       }
    }
 
-   private class REStructureDeployer extends AbstractStructureDeployer
+   private class REStructureDeployer extends AbstractVFSStructureDeployer
    {
       public REStructureDeployer(int order)
       {
Copied: projects/jboss-deployers/trunk/deployers-vfs-spi/src/main/org/jboss/deployers/vfs/spi/structure/CandidateAnnotationsCallback.java (from rev 76701, projects/jboss-deployers/trunk/deployers-vfs-spi/src/main/org/jboss/deployers/vfs/spi/structure/StructureContext.java)
===================================================================
--- projects/jboss-deployers/trunk/deployers-vfs-spi/src/main/org/jboss/deployers/vfs/spi/structure/CandidateAnnotationsCallback.java	                        (rev 0)
+++ projects/jboss-deployers/trunk/deployers-vfs-spi/src/main/org/jboss/deployers/vfs/spi/structure/CandidateAnnotationsCallback.java	2008-08-07 08:29:09 UTC (rev 76750)
@@ -0,0 +1,45 @@
+/*
+* JBoss, Home of Professional Open Source
+* Copyright 2007, JBoss Inc., and individual contributors as indicated
+* 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.deployers.vfs.spi.structure;
+
+import java.lang.annotation.Annotation;
+
+import org.jboss.deployers.spi.annotations.AnnotationEnvironment;
+import org.jboss.virtual.VirtualFile;
+
+/**
+ * CandidateAnnotationsCallback.
+ *
+ * @author <a href="ales.justin at jboss.com">Ales Justin</a>
+ */
+public interface CandidateAnnotationsCallback
+{
+   /**
+    * Execute callback.
+    *
+    * @param root the resources root
+    * @param currentContext the current context
+    * @param env the annotation environment
+    * @param annotationClass the current annotation class
+    */
+   void executeCallback(VirtualFile root, StructureContext currentContext, AnnotationEnvironment env, Class<? extends Annotation> annotationClass);
+}
\ No newline at end of file
Modified: projects/jboss-deployers/trunk/deployers-vfs-spi/src/main/org/jboss/deployers/vfs/spi/structure/StructureContext.java
===================================================================
--- projects/jboss-deployers/trunk/deployers-vfs-spi/src/main/org/jboss/deployers/vfs/spi/structure/StructureContext.java	2008-08-07 07:57:30 UTC (rev 76749)
+++ projects/jboss-deployers/trunk/deployers-vfs-spi/src/main/org/jboss/deployers/vfs/spi/structure/StructureContext.java	2008-08-07 08:29:09 UTC (rev 76750)
@@ -21,6 +21,10 @@
 */
 package org.jboss.deployers.vfs.spi.structure;
 
+import java.util.Set;
+import java.util.HashSet;
+import java.util.Collections;
+
 import org.jboss.deployers.spi.DeploymentException;
 import org.jboss.deployers.spi.structure.ContextInfo;
 import org.jboss.deployers.spi.structure.StructureMetaData;
@@ -30,6 +34,7 @@
  * StructureContext.
  * 
  * @author <a href="adrian at jboss.com">Adrian Brock</a>
+ * @author <a href="ales.justin at jboss.com">Ales Justin</a>
  * @version $Revision: 1.1 $
  */
 public class StructureContext
@@ -52,6 +57,12 @@
    /** The parent structure context */
    private StructureContext parentContext;
 
+   /** The candidate annotation scanning */
+   private boolean candidateAnnotationScanning;
+
+   /** The callbacks */
+   private Set<Object> callbacks;
+
    /**
     * Helper method to check parent is not null before retrieving parameters
     * 
@@ -201,8 +212,73 @@
    {
       return parentContext;
    }
-   
+
    /**
+    * Get the candidate annotation scanning.
+    *
+    * @return the candidate annotation scanning
+    */
+   public boolean isCandidateAnnotationScanning()
+   {
+      return candidateAnnotationScanning;
+   }
+
+   /**
+    * Set the candidate annotation scanning.
+    *
+    * @param candidateAnnotationScanning the candidate annotation scanning
+    */
+   public void setCandidateAnnotationScanning(boolean candidateAnnotationScanning)
+   {
+      this.candidateAnnotationScanning = candidateAnnotationScanning;
+   }
+
+   /***
+    * Get the matching callbacks.
+    *
+    * @param <T> exact callback type
+    * @param callbackType the exact callback type
+    * @return the callbacks
+    */
+   public <T> Set<T> getCallbacks(Class<T> callbackType)
+   {
+      if (callbackType == null)
+         throw new IllegalArgumentException("Null callback type");
+
+      if (callbacks == null || callbacks.isEmpty())
+         return Collections.emptySet();
+
+      Set<T> set = new HashSet<T>();
+      for (Object callback : callbacks)
+      {
+         if (callbackType.isInstance(callback))
+            set.add(callbackType.cast(callback));
+      }
+      return set;
+   }
+
+   /**
+    * Add the callback.
+    *
+    * @param callback the callback
+    */
+   public void addCallback(Object callback)
+   {
+      if (callbacks == null)
+         callbacks = new HashSet<Object>();
+      callbacks.add(callback);
+   }
+
+   /**
+    * Set the callbacks.
+    * @param callbacks the callbacks
+    */
+   public void setCallbacks(Set<Object> callbacks)
+   {
+      this.callbacks = callbacks;
+   }
+
+   /**
     * Determine the child structure
     * 
     * @param child the child
Modified: projects/jboss-deployers/trunk/deployers-vfs-spi/src/main/org/jboss/deployers/vfs/spi/structure/StructureDeployer.java
===================================================================
--- projects/jboss-deployers/trunk/deployers-vfs-spi/src/main/org/jboss/deployers/vfs/spi/structure/StructureDeployer.java	2008-08-07 07:57:30 UTC (rev 76749)
+++ projects/jboss-deployers/trunk/deployers-vfs-spi/src/main/org/jboss/deployers/vfs/spi/structure/StructureDeployer.java	2008-08-07 08:29:09 UTC (rev 76750)
@@ -41,4 +41,11 @@
     * @throws DeploymentException for an error
     */
    boolean determineStructure(StructureContext context) throws DeploymentException;
+
+   /**
+    * Do we support candidate annotations lookup.
+    *
+    * @return true if candidate annotaiotns lookup is supported, false otherwise
+    */
+   boolean isSupportsCandidateAnnotations();
 }
Modified: projects/jboss-deployers/trunk/deployers-vfs-spi/src/main/org/jboss/deployers/vfs/spi/structure/helpers/AbstractStructureDeployer.java
===================================================================
--- projects/jboss-deployers/trunk/deployers-vfs-spi/src/main/org/jboss/deployers/vfs/spi/structure/helpers/AbstractStructureDeployer.java	2008-08-07 07:57:30 UTC (rev 76749)
+++ projects/jboss-deployers/trunk/deployers-vfs-spi/src/main/org/jboss/deployers/vfs/spi/structure/helpers/AbstractStructureDeployer.java	2008-08-07 08:29:09 UTC (rev 76750)
@@ -22,10 +22,14 @@
 package org.jboss.deployers.vfs.spi.structure.helpers;
 
 import java.io.IOException;
+import java.lang.annotation.Annotation;
 import java.util.ArrayList;
+import java.util.LinkedHashSet;
 import java.util.List;
+import java.util.Set;
 
 import org.jboss.deployers.spi.DeploymentException;
+import org.jboss.deployers.spi.annotations.AnnotationEnvironment;
 import org.jboss.deployers.spi.structure.ClassPathEntry;
 import org.jboss.deployers.spi.structure.ContextInfo;
 import org.jboss.deployers.spi.structure.StructureMetaData;
@@ -33,12 +37,13 @@
 import org.jboss.deployers.vfs.spi.structure.StructureContext;
 import org.jboss.deployers.vfs.spi.structure.StructureDeployer;
 import org.jboss.deployers.vfs.spi.structure.VFSStructuralDeployers;
+import org.jboss.deployers.vfs.spi.structure.CandidateAnnotationsCallback;
 import org.jboss.logging.Logger;
+import org.jboss.util.collection.CollectionsFactory;
 import org.jboss.virtual.VFSUtils;
 import org.jboss.virtual.VirtualFile;
 import org.jboss.virtual.VirtualFileVisitor;
 import org.jboss.virtual.VisitorAttributes;
-import org.jboss.util.collection.CollectionsFactory;
 
 /**
  * AbstractStructureDeployer.<p>
@@ -63,6 +68,12 @@
    /** The context info order */
    private Integer contextInfoOrder;
 
+   /** The supports annotations flag */
+   private boolean supportsCandidateAnnotations;
+
+   /** The candidate annotations */
+   private Set<Class<? extends Annotation>> candidateAnnotations;
+
    /**
     * Get the relative path between two virtual files
     * 
@@ -129,6 +140,38 @@
       this.contextInfoOrder = contextInfoOrder;
    }
 
+   /**
+    * Get the candidate annotations.
+    *
+    * @return the candidate annotations
+    */
+   public Set<Class<? extends Annotation>> getCandidateAnnotations()
+   {
+      return candidateAnnotations;
+   }
+
+   /**
+    * Set the candidate annotations.
+    *
+    * @param candidateAnnotations the candidate annotations
+    */
+   public void setCandidateAnnotations(Set<Class<? extends Annotation>> candidateAnnotations)
+   {
+      this.candidateAnnotations = candidateAnnotations;
+   }
+
+   /**
+    * Add candidate annotation.
+    *
+    * @param annotationClass the candidate annotation class
+    */
+   public void addCandidateAnnotation(Class<? extends Annotation> annotationClass)
+   {
+      if (candidateAnnotations == null)
+         candidateAnnotations = new LinkedHashSet<Class<? extends Annotation>>();
+      candidateAnnotations.add(annotationClass);
+   }
+
    // This should be an abstract method JBDEPLOY-66
    public boolean determineStructure(StructureContext context) throws DeploymentException
    {
@@ -140,8 +183,23 @@
    {
       return false;
    }
-   
+
+   public boolean isSupportsCandidateAnnotations()
+   {
+      return supportsCandidateAnnotations;
+   }
+
    /**
+    * Set supportsCandidateAnnotations flag.
+    *
+    * @param supportsCandidateAnnotations the support candidate annotations flag
+    */
+   public void setSupportsCandidateAnnotations(boolean supportsCandidateAnnotations)
+   {
+      this.supportsCandidateAnnotations = supportsCandidateAnnotations;
+   }
+
+   /**
     * Get the candidateStructureVisitorFactory.
     * 
     * @return the candidateStructureVisitorFactory.
@@ -273,6 +331,51 @@
    }
 
    /**
+    * Create annotation environment
+    *
+    * @param root the deployment root
+    * @return new annotation environment
+    */
+   protected abstract AnnotationEnvironment createAnnotationEnvironment(VirtualFile root);
+
+   /**
+    * Check for candidate annotations.
+    *
+    * @param context the structure context
+    * @param roots the roots to check
+    * @return return true if one of the roots includes some candidate annotation
+    */
+   protected boolean checkCandidateAnnotations(StructureContext context, VirtualFile... roots)
+   {
+      if (roots == null || roots.length == 0)
+         throw new IllegalArgumentException("Null or empty roots");
+
+      StructureContext parentContext = context.getParentContext();
+      if (candidateAnnotations == null || candidateAnnotations.isEmpty() || parentContext == null)
+         return true;
+
+      Set<CandidateAnnotationsCallback> callbacks = parentContext.getCallbacks(CandidateAnnotationsCallback.class);
+      if (callbacks.isEmpty())
+         return true;
+
+      boolean result = false;
+      for(VirtualFile root : roots)
+      {
+         AnnotationEnvironment env = createAnnotationEnvironment(root);
+         for (Class<? extends Annotation> annotationClass : candidateAnnotations)
+         {
+            if (env.hasClassAnnotatedWith(annotationClass))
+            {
+               result = true;
+               for (CandidateAnnotationsCallback callback : callbacks)
+                  callback.executeCallback(root, context, env, annotationClass);
+            }
+         }
+      }
+      return result;
+   }
+
+   /**
     * Add all children as candidates
     * 
     * @param context the structure context
    
    
More information about the jboss-cvs-commits
mailing list