You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@hivemind.apache.org by ah...@apache.org on 2007/03/22 22:38:33 UTC

svn commit: r521482 - in /hivemind/hivemind2/trunk: annotations/src/java/org/apache/hivemind/annotations/ annotations/src/java/org/apache/hivemind/annotations/definition/processors/ annotations/src/java/org/apache/hivemind/annotations/internal/ annotat...

Author: ahuegen
Date: Thu Mar 22 14:38:31 2007
New Revision: 521482

URL: http://svn.apache.org/viewvc?view=rev&rev=521482
Log:
More work on annotation processors 

Added:
    hivemind/hivemind2/trunk/annotations/src/java/org/apache/hivemind/annotations/AnnotationsExtensionProvider.java
    hivemind/hivemind2/trunk/annotations/src/java/org/apache/hivemind/annotations/internal/AnnotationProcessorFactory.java
    hivemind/hivemind2/trunk/annotations/src/java/org/apache/hivemind/annotations/internal/AnnotationsExtensionLoader.java
      - copied, changed from r514886, hivemind/hivemind2/trunk/annotations/src/java/org/apache/hivemind/annotations/internal/AnnotationExtensionLoader.java
    hivemind/hivemind2/trunk/annotations/src/test/org/apache/hivemind/annotations/definition/
    hivemind/hivemind2/trunk/annotations/src/test/org/apache/hivemind/annotations/definition/processors/
    hivemind/hivemind2/trunk/annotations/src/test/org/apache/hivemind/annotations/definition/processors/MappedClassLoader.java
    hivemind/hivemind2/trunk/annotations/src/test/org/apache/hivemind/annotations/definition/processors/TestCustomProcessor.java
    hivemind/hivemind2/trunk/annotations/src/test/org/apache/hivemind/annotations/definition/processors/custom-manifest.mf
Removed:
    hivemind/hivemind2/trunk/annotations/src/java/org/apache/hivemind/annotations/internal/AnnotationExtensionLoader.java
Modified:
    hivemind/hivemind2/trunk/annotations/src/java/org/apache/hivemind/annotations/AnnotatedModuleReader.java
    hivemind/hivemind2/trunk/annotations/src/java/org/apache/hivemind/annotations/AnnotationsMessages.java
    hivemind/hivemind2/trunk/annotations/src/java/org/apache/hivemind/annotations/AnnotationsStrings.properties
    hivemind/hivemind2/trunk/annotations/src/java/org/apache/hivemind/annotations/definition/processors/AnnotationProcessor.java
    hivemind/hivemind2/trunk/annotations/src/java/org/apache/hivemind/annotations/internal/AnnotatedModuleProcessor.java
    hivemind/hivemind2/trunk/annotations/src/java/org/apache/hivemind/annotations/internal/AnnotationProcessorRegistry.java
    hivemind/hivemind2/trunk/annotations/src/java/org/apache/hivemind/annotations/internal/AnnotationProcessorRegistryFactory.java
    hivemind/hivemind2/trunk/annotations/src/test/org/apache/hivemind/annotations/TestAnnotatedModuleReader.java
    hivemind/hivemind2/trunk/framework/src/java/org/apache/hivemind/impl/RegistryProviderAutoDetector.java

Modified: hivemind/hivemind2/trunk/annotations/src/java/org/apache/hivemind/annotations/AnnotatedModuleReader.java
URL: http://svn.apache.org/viewvc/hivemind/hivemind2/trunk/annotations/src/java/org/apache/hivemind/annotations/AnnotatedModuleReader.java?view=diff&rev=521482&r1=521481&r2=521482
==============================================================================
--- hivemind/hivemind2/trunk/annotations/src/java/org/apache/hivemind/annotations/AnnotatedModuleReader.java (original)
+++ hivemind/hivemind2/trunk/annotations/src/java/org/apache/hivemind/annotations/AnnotatedModuleReader.java Thu Mar 22 14:38:31 2007
@@ -18,7 +18,9 @@
 import org.apache.commons.logging.LogFactory;
 import org.apache.hivemind.ApplicationRuntimeException;
 import org.apache.hivemind.ClassResolver;
+import org.apache.hivemind.annotations.definition.processors.AnnotationProcessor;
 import org.apache.hivemind.annotations.internal.AnnotatedModuleProcessor;
+import org.apache.hivemind.annotations.internal.AnnotationProcessorRegistry;
 import org.apache.hivemind.annotations.internal.AnnotationProcessorRegistryFactory;
 import org.apache.hivemind.definition.RegistryDefinition;
 import org.apache.hivemind.impl.DefaultClassResolver;
@@ -71,15 +73,28 @@
     }
 
     /**
-     * Reads an annotated module.
+     * Reads an annotated module. Uses the the default {@link AnnotationProcessorRegistry}.
      * 
      * @param moduleClass  class of the module
      */
     public void readModule(Class moduleClass)
     {
+        // TODO: Better cache the factory for performance?
+        AnnotationProcessorRegistryFactory factory = new AnnotationProcessorRegistryFactory();
+        readModule(moduleClass, factory.createDefaultRegistry(_classResolver));
+    }
+    
+    /**
+     * Reads an annotated module.
+     * 
+     * @param moduleClass  class of the module
+     * @param annotationProcessorRegistry  the registry the holds all known {@link AnnotationProcessor annotation processors}
+     */
+    public void readModule(Class moduleClass, AnnotationProcessorRegistry annotationProcessorRegistry)
+    {
         AnnotatedModuleProcessor _processor = new AnnotatedModuleProcessor(
                 _registryDefinition, _classResolver, 
-                AnnotationProcessorRegistryFactory.createDefaultRegistry());
+                annotationProcessorRegistry);
         try
         {
             _processor.processModule(moduleClass);

Added: hivemind/hivemind2/trunk/annotations/src/java/org/apache/hivemind/annotations/AnnotationsExtensionProvider.java
URL: http://svn.apache.org/viewvc/hivemind/hivemind2/trunk/annotations/src/java/org/apache/hivemind/annotations/AnnotationsExtensionProvider.java?view=auto&rev=521482
==============================================================================
--- hivemind/hivemind2/trunk/annotations/src/java/org/apache/hivemind/annotations/AnnotationsExtensionProvider.java (added)
+++ hivemind/hivemind2/trunk/annotations/src/java/org/apache/hivemind/annotations/AnnotationsExtensionProvider.java Thu Mar 22 14:38:31 2007
@@ -0,0 +1,8 @@
+package org.apache.hivemind.annotations;
+
+import org.apache.hivemind.annotations.internal.AnnotationProcessorRegistry;
+
+public interface AnnotationsExtensionProvider
+{
+    public void registerAnnotationProcessors(AnnotationProcessorRegistry registry);
+}

Modified: hivemind/hivemind2/trunk/annotations/src/java/org/apache/hivemind/annotations/AnnotationsMessages.java
URL: http://svn.apache.org/viewvc/hivemind/hivemind2/trunk/annotations/src/java/org/apache/hivemind/annotations/AnnotationsMessages.java?view=diff&rev=521482&r1=521481&r2=521482
==============================================================================
--- hivemind/hivemind2/trunk/annotations/src/java/org/apache/hivemind/annotations/AnnotationsMessages.java (original)
+++ hivemind/hivemind2/trunk/annotations/src/java/org/apache/hivemind/annotations/AnnotationsMessages.java Thu Mar 22 14:38:31 2007
@@ -61,14 +61,14 @@
         return _formatter.format("annotated-method-protected-not-accessible", methodSig.toString());
     }
     
-    public static String unableToCreateAnnotationProcessor(String processorClassName, Exception cause)
+    public static String unableToCreateAnnotationsExtensionProvider(String processorClassName, Exception cause)
     {
-        return _formatter.format("unable-to-create-annotation-processor", processorClassName, cause);
+        return _formatter.format("unable-to-create-annotations-extension-provider", processorClassName, cause);
     }
 
-    public static String annotationProcessorWrongType(String processorClassName, Class requiredInterface)
+    public static String annotationsExtensionProviderWrongType(String processorClassName, Class requiredInterface)
     {
-        return _formatter.format("annotation-processor-wrong-type", processorClassName, requiredInterface.getName());
+        return _formatter.format("annotations-extension-provider-wrong-type", processorClassName, requiredInterface.getName());
     }
 
 }

Modified: hivemind/hivemind2/trunk/annotations/src/java/org/apache/hivemind/annotations/AnnotationsStrings.properties
URL: http://svn.apache.org/viewvc/hivemind/hivemind2/trunk/annotations/src/java/org/apache/hivemind/annotations/AnnotationsStrings.properties?view=diff&rev=521482&r1=521481&r2=521482
==============================================================================
--- hivemind/hivemind2/trunk/annotations/src/java/org/apache/hivemind/annotations/AnnotationsStrings.properties (original)
+++ hivemind/hivemind2/trunk/annotations/src/java/org/apache/hivemind/annotations/AnnotationsStrings.properties Thu Mar 22 14:38:31 2007
@@ -18,5 +18,5 @@
 annotated-method-has-invalid-modifiers=Method ''{0}'' used as {1} has invalid modifiers: {2}
 annotated-method-protected-not-accessible=Method ''{0}'' is protected but not accessible by HiveMind. If a SecurityManager is used then HiveMind must be allowed to call Method#setAccessible.
 
-unable-to-create-annotation-processor=Unable to create AnnotationProcessor of type {0}: {1}
-annotation-processor-wrong-type=AnnotationProcessor class {0} must implement interface {1}
+unable-to-create-annotations-extension-provider=Unable to create AnnotationsExtensionProvider of type {0}: {1}
+annotations-extension-provider-wrong-type=AnnotationsExtensionProvider class {0} must implement interface {1}

Modified: hivemind/hivemind2/trunk/annotations/src/java/org/apache/hivemind/annotations/definition/processors/AnnotationProcessor.java
URL: http://svn.apache.org/viewvc/hivemind/hivemind2/trunk/annotations/src/java/org/apache/hivemind/annotations/definition/processors/AnnotationProcessor.java?view=diff&rev=521482&r1=521481&r2=521482
==============================================================================
--- hivemind/hivemind2/trunk/annotations/src/java/org/apache/hivemind/annotations/definition/processors/AnnotationProcessor.java (original)
+++ hivemind/hivemind2/trunk/annotations/src/java/org/apache/hivemind/annotations/definition/processors/AnnotationProcessor.java Thu Mar 22 14:38:31 2007
@@ -3,8 +3,12 @@
 import org.apache.hivemind.ApplicationRuntimeException;
 
 /**
- * The same instance is used for all annotations of one kind which are loaded
- * by the same AnnotatedModuleProcessor or AnnotatedModuleReader.
+ * Processes a method in an module class which is annotated with a specific
+ * annotation type. The processor gets full access to the module definition
+ * and can add extension points and extensions.
+ * 
+ * The same instance is used for all annotations of one kind which are defined
+ * in the same module.
  * 
  * @author Achim Huegen
  */

Modified: hivemind/hivemind2/trunk/annotations/src/java/org/apache/hivemind/annotations/internal/AnnotatedModuleProcessor.java
URL: http://svn.apache.org/viewvc/hivemind/hivemind2/trunk/annotations/src/java/org/apache/hivemind/annotations/internal/AnnotatedModuleProcessor.java?view=diff&rev=521482&r1=521481&r2=521482
==============================================================================
--- hivemind/hivemind2/trunk/annotations/src/java/org/apache/hivemind/annotations/internal/AnnotatedModuleProcessor.java (original)
+++ hivemind/hivemind2/trunk/annotations/src/java/org/apache/hivemind/annotations/internal/AnnotatedModuleProcessor.java Thu Mar 22 14:38:31 2007
@@ -36,7 +36,8 @@
 /**
  * Does the work for {@link org.apache.hivemind.annotations.AnnotatedModuleReader}. 
  * Processes an annotated class and registers the defined extension and extension points 
- * in a registry definition. For each module class a new instance of this processor is created.
+ * in a registry definition. For each module class a new instance of this processor must
+ * be created.
  * 
  * The processor iterates over the methods of the module class and their annotations.
  * Annotations defined in ancestors are included too.
@@ -59,13 +60,14 @@
     private RegistryDefinition _registryDefinition;
     
     private AnnotationProcessorRegistry _annotationProcessorRegistry;
+    private AnnotationProcessorFactory _annotationProcessorFactory;
 
     public AnnotatedModuleProcessor(RegistryDefinition registryDefinition,
             ClassResolver classResolver, AnnotationProcessorRegistry annotationProcessorRegistry)
     {
         _registryDefinition = registryDefinition;
         _classResolver = classResolver;
-        _annotationProcessorRegistry = annotationProcessorRegistry;
+        _annotationProcessorFactory = new AnnotationProcessorFactory(annotationProcessorRegistry);
     }
     
     public void processModule(Class moduleClass)
@@ -159,7 +161,7 @@
                     annotation, method, location, instanceProvider,
                     _annotationProcessorRegistry);
             
-            List<AnnotationProcessor> processors = _annotationProcessorRegistry.getProcessors(annotation.annotationType());
+            List<AnnotationProcessor> processors = _annotationProcessorFactory.getProcessors(annotation.annotationType());
             if (processors != null) {
                 for (AnnotationProcessor processor : processors)
                 {

Added: hivemind/hivemind2/trunk/annotations/src/java/org/apache/hivemind/annotations/internal/AnnotationProcessorFactory.java
URL: http://svn.apache.org/viewvc/hivemind/hivemind2/trunk/annotations/src/java/org/apache/hivemind/annotations/internal/AnnotationProcessorFactory.java?view=auto&rev=521482
==============================================================================
--- hivemind/hivemind2/trunk/annotations/src/java/org/apache/hivemind/annotations/internal/AnnotationProcessorFactory.java (added)
+++ hivemind/hivemind2/trunk/annotations/src/java/org/apache/hivemind/annotations/internal/AnnotationProcessorFactory.java Thu Mar 22 14:38:31 2007
@@ -0,0 +1,56 @@
+package org.apache.hivemind.annotations.internal;
+
+import java.lang.annotation.Annotation;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import org.apache.hivemind.ApplicationRuntimeException;
+import org.apache.hivemind.annotations.definition.processors.AnnotationProcessor;
+
+public class AnnotationProcessorFactory
+{
+    private AnnotationProcessorRegistry _processorRegistry;
+    private Map<Class<? extends Annotation>, List<AnnotationProcessor>> processorLists = new HashMap<Class<? extends Annotation>, List<AnnotationProcessor>>();
+    
+    public AnnotationProcessorFactory(AnnotationProcessorRegistry processorRegistry)
+    {
+        _processorRegistry = processorRegistry;
+    }
+    
+    public List<AnnotationProcessor> getProcessors(Class<? extends Annotation> annotationClass)
+    {
+        List<AnnotationProcessor> processorList = processorLists.get(annotationClass);
+        if (processorList == null) {
+            processorList = createProcessors(annotationClass);
+            processorLists.put(annotationClass, processorList);
+        }
+        return processorList;
+    }
+    
+    private List<AnnotationProcessor> createProcessors(Class<? extends Annotation> annotationClass)
+    {
+        List<AnnotationProcessor> result = new ArrayList<AnnotationProcessor>();
+        
+        List<Class<? extends AnnotationProcessor>> processorClasses = _processorRegistry.getProcessorClasses(annotationClass);
+        for (Class<? extends AnnotationProcessor> processorClass : processorClasses)
+        {
+            AnnotationProcessor processor;
+            try
+            {
+                processor = processorClass.newInstance();
+                result.add(processor);
+            }
+            catch (Exception e)
+            {
+                // TODO: Improve error handling
+               throw new ApplicationRuntimeException(e);
+            }
+        }
+        
+        return result;
+    }
+
+}
+

Modified: hivemind/hivemind2/trunk/annotations/src/java/org/apache/hivemind/annotations/internal/AnnotationProcessorRegistry.java
URL: http://svn.apache.org/viewvc/hivemind/hivemind2/trunk/annotations/src/java/org/apache/hivemind/annotations/internal/AnnotationProcessorRegistry.java?view=diff&rev=521482&r1=521481&r2=521482
==============================================================================
--- hivemind/hivemind2/trunk/annotations/src/java/org/apache/hivemind/annotations/internal/AnnotationProcessorRegistry.java (original)
+++ hivemind/hivemind2/trunk/annotations/src/java/org/apache/hivemind/annotations/internal/AnnotationProcessorRegistry.java Thu Mar 22 14:38:31 2007
@@ -10,21 +10,21 @@
 
 public class AnnotationProcessorRegistry
 {
-    private Map<Class<? extends Annotation>, List<AnnotationProcessor>> processorLists = new HashMap<Class<? extends Annotation>, List<AnnotationProcessor>>();
+    private Map<Class<? extends Annotation>, List<Class<? extends AnnotationProcessor>>> processorLists = new HashMap<Class<? extends Annotation>, List<Class<? extends AnnotationProcessor>>>();
 
-    public List<AnnotationProcessor> getProcessors(Class<? extends Annotation> annotationClass)
+    public List<Class<? extends AnnotationProcessor>> getProcessorClasses(Class<? extends Annotation> annotationClass)
     {
         return processorLists.get(annotationClass);
     }
 
-    public void registerProcessor(Class<? extends Annotation> annotationClass, AnnotationProcessor processor)
+    public void registerProcessor(Class<? extends Annotation> annotationClass, Class<? extends AnnotationProcessor> processorClass)
     {
-        List<AnnotationProcessor> processorList = getProcessors(annotationClass);
+        List<Class<? extends AnnotationProcessor>> processorList = getProcessorClasses(annotationClass);
         if (processorList == null) {
-            processorList = new ArrayList<AnnotationProcessor>();
+            processorList = new ArrayList<Class<? extends AnnotationProcessor>>();
             processorLists.put(annotationClass, processorList);
         }
-        processorList.add(processor);
+        processorList.add(processorClass);
     }
 }
 

Modified: hivemind/hivemind2/trunk/annotations/src/java/org/apache/hivemind/annotations/internal/AnnotationProcessorRegistryFactory.java
URL: http://svn.apache.org/viewvc/hivemind/hivemind2/trunk/annotations/src/java/org/apache/hivemind/annotations/internal/AnnotationProcessorRegistryFactory.java?view=diff&rev=521482&r1=521481&r2=521482
==============================================================================
--- hivemind/hivemind2/trunk/annotations/src/java/org/apache/hivemind/annotations/internal/AnnotationProcessorRegistryFactory.java (original)
+++ hivemind/hivemind2/trunk/annotations/src/java/org/apache/hivemind/annotations/internal/AnnotationProcessorRegistryFactory.java Thu Mar 22 14:38:31 2007
@@ -1,5 +1,6 @@
 package org.apache.hivemind.annotations.internal;
 
+import org.apache.hivemind.ClassResolver;
 import org.apache.hivemind.annotations.definition.Configuration;
 import org.apache.hivemind.annotations.definition.Contribution;
 import org.apache.hivemind.annotations.definition.Service;
@@ -12,14 +13,31 @@
 public class AnnotationProcessorRegistryFactory
 {
     
-    public static AnnotationProcessorRegistry createDefaultRegistry()
+    public AnnotationProcessorRegistryFactory()
+    {
+    }
+    
+    public AnnotationProcessorRegistry createDefaultRegistry(ClassResolver classResolver)
     {
         AnnotationProcessorRegistry result = new AnnotationProcessorRegistry();
-        result.registerProcessor(Service.class, new ServiceProcessor());
-        result.registerProcessor(Configuration.class, new ConfigurationProcessor());
-        result.registerProcessor(Contribution.class, new ContributionProcessor());
-        result.registerProcessor(Submodule.class, new SubmoduleProcessor());
+        loadExtensions(classResolver, result);
+        registerDefaultProcessors(result);
         return result;
     }
+
+    private void loadExtensions(ClassResolver classResolver, AnnotationProcessorRegistry processorRegistry)
+    {
+        AnnotationsExtensionLoader extensionLoader = new AnnotationsExtensionLoader();
+        extensionLoader.loadExtensions(classResolver, processorRegistry);
+    }
+
+    private void registerDefaultProcessors(AnnotationProcessorRegistry processorRegistry)
+    {
+        processorRegistry.registerProcessor(Service.class, ServiceProcessor.class);
+        processorRegistry.registerProcessor(Configuration.class, ConfigurationProcessor.class);
+        processorRegistry.registerProcessor(Contribution.class, ContributionProcessor.class);
+        processorRegistry.registerProcessor(Submodule.class, SubmoduleProcessor.class);
+    }
+    
 }
 

Copied: hivemind/hivemind2/trunk/annotations/src/java/org/apache/hivemind/annotations/internal/AnnotationsExtensionLoader.java (from r514886, hivemind/hivemind2/trunk/annotations/src/java/org/apache/hivemind/annotations/internal/AnnotationExtensionLoader.java)
URL: http://svn.apache.org/viewvc/hivemind/hivemind2/trunk/annotations/src/java/org/apache/hivemind/annotations/internal/AnnotationsExtensionLoader.java?view=diff&rev=521482&p1=hivemind/hivemind2/trunk/annotations/src/java/org/apache/hivemind/annotations/internal/AnnotationExtensionLoader.java&r1=514886&p2=hivemind/hivemind2/trunk/annotations/src/java/org/apache/hivemind/annotations/internal/AnnotationsExtensionLoader.java&r2=521482
==============================================================================
--- hivemind/hivemind2/trunk/annotations/src/java/org/apache/hivemind/annotations/internal/AnnotationExtensionLoader.java (original)
+++ hivemind/hivemind2/trunk/annotations/src/java/org/apache/hivemind/annotations/internal/AnnotationsExtensionLoader.java Thu Mar 22 14:38:31 2007
@@ -15,92 +15,89 @@
 package org.apache.hivemind.annotations.internal;
 
 import java.lang.reflect.InvocationTargetException;
-import java.util.ArrayList;
-import java.util.List;
 import java.util.StringTokenizer;
 
 import org.apache.commons.logging.Log;
 import org.apache.commons.logging.LogFactory;
 import org.apache.hivemind.ApplicationRuntimeException;
 import org.apache.hivemind.ClassResolver;
+import org.apache.hivemind.annotations.AnnotationsExtensionProvider;
 import org.apache.hivemind.annotations.AnnotationsMessages;
-import org.apache.hivemind.annotations.definition.processors.AnnotationProcessor;
 import org.apache.hivemind.impl.ManifestReader;
 
 /**
+ * Loads all implementations of {@link AnnotationsExtensionProvider} that are defined
+ * in MANIFEST.MF files in the classpath.
+ * The providers get passed in a reference to {@link AnnotationProcessorRegistry} to which
+ * they can add {@link org.apache.hivemind.annotations.definition.processors.AnnotationProcessor} classes.
+ * 
  * @author Achim Huegen
  */
-public class AnnotationExtensionLoader
+public class AnnotationsExtensionLoader
 {
-    private static final Log LOG = LogFactory.getLog(AnnotationExtensionLoader.class);
-    public static final String MANIFEST = "META-INF/MANIFEST.MF";
-    public static final String PROCESSOR_ATTRIBUTE_NAME = "annotation-definition-processors";
+    private static final Log LOG = LogFactory.getLog(AnnotationsExtensionLoader.class);
+    public static final String PROVIDER_ATTRIBUTE_NAME = "annotations-extension-providers";
 
-    private List _processors = new ArrayList();
-    
-    public AnnotationExtensionLoader(ClassResolver resolver)
+    public AnnotationsExtensionLoader()
     {
-        String[] processorValues = ManifestReader.getAttributeValues(resolver, PROCESSOR_ATTRIBUTE_NAME);
-        for (int i = 0; i < processorValues.length; i++)
-        {
-            String processorValue = processorValues[i];
-            handleProcessorValue(resolver, processorValue);
-        }
     }
-    
-    /**
-     * @return  List with instances of {@link AnnotationProcessor}
-     */
-    public List getProcessors()
+   
+    public void loadExtensions(ClassResolver resolver, AnnotationProcessorRegistry annotationProcessorRegistry)
     {
-        return _processors;
+        String[] providerValues = ManifestReader.getAttributeValues(resolver, PROVIDER_ATTRIBUTE_NAME);
+        for (int i = 0; i < providerValues.length; i++)
+        {
+            String providerValue = providerValues[i];
+            handleProviderValue(resolver, annotationProcessorRegistry, providerValue);
+        }
     }
 
     /**
-     * Parse the processor list in an attribute and load all classes.
+     * Parse the providers list in an attribute and load all classes.
      */
-    private void handleProcessorValue(ClassResolver resolver, String processors)
+    private void handleProviderValue(ClassResolver resolver, AnnotationProcessorRegistry annotationProcessorRegistry, String providers)
     {
-        StringTokenizer tokenizer = new StringTokenizer(processors, ",");
+        StringTokenizer tokenizer = new StringTokenizer(providers, ",");
         while (tokenizer.hasMoreTokens())
         {   
-            String processorClassName = tokenizer.nextToken();
-            loadProcessor(resolver, processorClassName);
+            String providerClassName = tokenizer.nextToken();
+            loadProvider(resolver, annotationProcessorRegistry, providerClassName);
         }
     }
     
     /**
-     * Load a processor class and create an instance.
+     * Load a provider class and create an instance.
      * 
      * @param resolver
-     * @param processorClassName
+     * @param providerClassName
      */
-    private void loadProcessor(ClassResolver resolver, String processorClassName)
+    private void loadProvider(ClassResolver resolver, AnnotationProcessorRegistry annotationProcessorRegistry, String providerClassName)
     {
         if (LOG.isDebugEnabled())
-            LOG.debug("Loading processor " + processorClassName);
-        Object processor = null;
+            LOG.debug("Loading provider " + providerClassName);
+        Object provider = null;
         try
         {
-            Class processorClass = resolver.findClass(processorClassName);
-            processor = processorClass.newInstance();
+            Class providerClass = resolver.findClass(providerClassName);
+            provider = providerClass.newInstance();
         }
         catch (Exception e)
         {
-            Exception cause = e;
+            Throwable cause = e;
             if (e instanceof InvocationTargetException)
             {
-                cause = (InvocationTargetException) e;
+                cause = ((InvocationTargetException) e).getTargetException();
             }
-            throw new ApplicationRuntimeException(AnnotationsMessages.unableToCreateAnnotationProcessor(processorClassName, e),
+            throw new ApplicationRuntimeException(AnnotationsMessages.unableToCreateAnnotationsExtensionProvider(providerClassName, e),
                     cause);
         }
-        // Check type of processor
-        if (!(processor instanceof AnnotationProcessor)) {
-            throw new ApplicationRuntimeException(AnnotationsMessages.annotationProcessorWrongType(processorClassName, AnnotationProcessor.class));
+        // Check type of provider
+        if (!(provider instanceof AnnotationsExtensionProvider)) {
+            throw new ApplicationRuntimeException(AnnotationsMessages.annotationsExtensionProviderWrongType(providerClassName, AnnotationsExtensionProvider.class));
         }
         
-        _processors.add(processor);
+        // Let the provider register its processors
+        ((AnnotationsExtensionProvider) provider).registerAnnotationProcessors(annotationProcessorRegistry);
     }
 
 }

Modified: hivemind/hivemind2/trunk/annotations/src/test/org/apache/hivemind/annotations/TestAnnotatedModuleReader.java
URL: http://svn.apache.org/viewvc/hivemind/hivemind2/trunk/annotations/src/test/org/apache/hivemind/annotations/TestAnnotatedModuleReader.java?view=diff&rev=521482&r1=521481&r2=521482
==============================================================================
--- hivemind/hivemind2/trunk/annotations/src/test/org/apache/hivemind/annotations/TestAnnotatedModuleReader.java (original)
+++ hivemind/hivemind2/trunk/annotations/src/test/org/apache/hivemind/annotations/TestAnnotatedModuleReader.java Thu Mar 22 14:38:31 2007
@@ -16,6 +16,7 @@
 
 import org.apache.hivemind.ApplicationRuntimeException;
 import org.apache.hivemind.annotations.internal.AnnotatedModuleProcessor;
+import org.apache.hivemind.annotations.internal.AnnotationProcessorRegistry;
 import org.apache.hivemind.annotations.internal.AnnotationProcessorRegistryFactory;
 import org.apache.hivemind.definition.ModuleDefinition;
 import org.apache.hivemind.definition.RegistryDefinition;
@@ -54,10 +55,16 @@
         assertNotNull(registry.getModule("Test"));
     }
   
+    private AnnotationProcessorRegistry getAnnotationProcessorRegistry()
+    {
+        AnnotationProcessorRegistryFactory factory = new AnnotationProcessorRegistryFactory();
+        return factory.createDefaultRegistry(new DefaultClassResolver());
+    }
+    
     public void testModuleClassNotFinal()
     {
         AnnotatedModuleProcessor processor = new AnnotatedModuleProcessor(new RegistryDefinitionImpl(),
-                new DefaultClassResolver(), AnnotationProcessorRegistryFactory.createDefaultRegistry());
+                new DefaultClassResolver(), getAnnotationProcessorRegistry());
         try
         {
             processor.processModule(FinalModule.class);
@@ -71,7 +78,7 @@
     public void testModuleClassNotAbstract()
     {
         AnnotatedModuleProcessor processor = new AnnotatedModuleProcessor(new RegistryDefinitionImpl(),
-                new DefaultClassResolver(), AnnotationProcessorRegistryFactory.createDefaultRegistry());
+                new DefaultClassResolver(), getAnnotationProcessorRegistry());
         try
         {
             processor.processModule(AbstractModule.class);
@@ -85,7 +92,7 @@
     public void testModuleClassPublic()
     {
         AnnotatedModuleProcessor processor = new AnnotatedModuleProcessor(new RegistryDefinitionImpl(),
-                new DefaultClassResolver(), AnnotationProcessorRegistryFactory.createDefaultRegistry());
+                new DefaultClassResolver(), getAnnotationProcessorRegistry());
         try
         {
             processor.processModule(NotPublicModule.class);

Added: hivemind/hivemind2/trunk/annotations/src/test/org/apache/hivemind/annotations/definition/processors/MappedClassLoader.java
URL: http://svn.apache.org/viewvc/hivemind/hivemind2/trunk/annotations/src/test/org/apache/hivemind/annotations/definition/processors/MappedClassLoader.java?view=auto&rev=521482
==============================================================================
--- hivemind/hivemind2/trunk/annotations/src/test/org/apache/hivemind/annotations/definition/processors/MappedClassLoader.java (added)
+++ hivemind/hivemind2/trunk/annotations/src/test/org/apache/hivemind/annotations/definition/processors/MappedClassLoader.java Thu Mar 22 14:38:31 2007
@@ -0,0 +1,44 @@
+package org.apache.hivemind.annotations.definition.processors;
+
+import java.io.IOException;
+import java.net.URL;
+import java.security.SecureClassLoader;
+import java.util.Enumeration;
+import java.util.HashMap;
+import java.util.Map;
+
+public class MappedClassLoader extends SecureClassLoader
+{
+    private Map mappedResources = new HashMap();
+
+    public MappedClassLoader(ClassLoader parent)
+    {
+        super(parent);
+    }
+    
+    public void addResource(String visiblePath, String originalPath)
+    {
+        mappedResources.put(visiblePath, originalPath);
+    }
+
+    /**
+     * @see java.lang.ClassLoader#findResource(java.lang.String)
+     */
+    protected URL findResource(String name)
+    {
+        return super.findResource(name);
+    }
+
+    /**
+     * @see java.lang.ClassLoader#findResources(java.lang.String)
+     */
+    protected Enumeration findResources(String name) throws IOException
+    {
+        if (mappedResources.containsKey(name)) {
+            String originalName = (String) mappedResources.get(name);
+            return getParent().getResources(originalName);
+        } 
+        
+        return super.findResources(name);
+    }
+}

Added: hivemind/hivemind2/trunk/annotations/src/test/org/apache/hivemind/annotations/definition/processors/TestCustomProcessor.java
URL: http://svn.apache.org/viewvc/hivemind/hivemind2/trunk/annotations/src/test/org/apache/hivemind/annotations/definition/processors/TestCustomProcessor.java?view=auto&rev=521482
==============================================================================
--- hivemind/hivemind2/trunk/annotations/src/test/org/apache/hivemind/annotations/definition/processors/TestCustomProcessor.java (added)
+++ hivemind/hivemind2/trunk/annotations/src/test/org/apache/hivemind/annotations/definition/processors/TestCustomProcessor.java Thu Mar 22 14:38:31 2007
@@ -0,0 +1,21 @@
+package org.apache.hivemind.annotations.definition.processors;
+
+import junit.framework.TestCase;
+
+import org.apache.hivemind.ClassResolver;
+import org.apache.hivemind.annotations.internal.AnnotationsExtensionLoader;
+import org.apache.hivemind.impl.DefaultClassResolver;
+
+public class TestCustomProcessor extends TestCase
+{
+
+    public void testCustomProcessor()
+    {
+        MappedClassLoader classLoader = new MappedClassLoader(Thread.currentThread().getContextClassLoader());
+        classLoader.addResource("META-INF/MANIFEST.MF", TestCustomProcessor.class.getPackage().getName().replace('.', '/') + "/custom-manifest.mf");
+        
+        ClassResolver classResolver = new DefaultClassResolver(classLoader);
+        AnnotationsExtensionLoader loader = new AnnotationsExtensionLoader();
+        loader.loadExtensions(classResolver, null);
+    }
+}

Added: hivemind/hivemind2/trunk/annotations/src/test/org/apache/hivemind/annotations/definition/processors/custom-manifest.mf
URL: http://svn.apache.org/viewvc/hivemind/hivemind2/trunk/annotations/src/test/org/apache/hivemind/annotations/definition/processors/custom-manifest.mf?view=auto&rev=521482
==============================================================================
--- hivemind/hivemind2/trunk/annotations/src/test/org/apache/hivemind/annotations/definition/processors/custom-manifest.mf (added)
+++ hivemind/hivemind2/trunk/annotations/src/test/org/apache/hivemind/annotations/definition/processors/custom-manifest.mf Thu Mar 22 14:38:31 2007
@@ -0,0 +1 @@
+annotations-extension-providers: org.apache.hivemind.Test1

Modified: hivemind/hivemind2/trunk/framework/src/java/org/apache/hivemind/impl/RegistryProviderAutoDetector.java
URL: http://svn.apache.org/viewvc/hivemind/hivemind2/trunk/framework/src/java/org/apache/hivemind/impl/RegistryProviderAutoDetector.java?view=diff&rev=521482&r1=521481&r2=521482
==============================================================================
--- hivemind/hivemind2/trunk/framework/src/java/org/apache/hivemind/impl/RegistryProviderAutoDetector.java (original)
+++ hivemind/hivemind2/trunk/framework/src/java/org/apache/hivemind/impl/RegistryProviderAutoDetector.java Thu Mar 22 14:38:31 2007
@@ -90,10 +90,10 @@
         }
         catch (Exception e)
         {
-            Exception cause = e;
+            Throwable cause = e;
             if (e instanceof InvocationTargetException)
             {
-                cause = (InvocationTargetException) e;
+                cause = ((InvocationTargetException) e).getTargetException();
             }
             throw new ApplicationRuntimeException(ImplMessages.unableToCreateProvider(providerClassName, e),
                     cause);