Author: mbenson
Date: Wed Dec 16 17:15:51 2015
New Revision: 1720392

URL: http://svn.apache.org/viewvc?rev=1720392&view=rev
Log:
formalize the 'weave lifecycle' and build upon that to introduce a provider 
dependency mechanism

Added:
    
commons/proper/weaver/trunk/processor/src/main/java/org/apache/commons/weaver/Consumes.java
   (with props)
    
commons/proper/weaver/trunk/processor/src/main/java/org/apache/commons/weaver/ProcessorBase.java
   (with props)
    
commons/proper/weaver/trunk/processor/src/main/java/org/apache/commons/weaver/Produces.java
   (with props)
    
commons/proper/weaver/trunk/processor/src/main/java/org/apache/commons/weaver/lifecycle/
    
commons/proper/weaver/trunk/processor/src/main/java/org/apache/commons/weaver/lifecycle/WeaveLifecycle.java
   (with props)
    
commons/proper/weaver/trunk/processor/src/main/java/org/apache/commons/weaver/lifecycle/WeaveLifecycleToken.java
   (with props)
    
commons/proper/weaver/trunk/processor/src/main/java/org/apache/commons/weaver/lifecycle/package-info.java
   (with props)
    
commons/proper/weaver/trunk/processor/src/main/java/org/apache/commons/weaver/spi/WeaveLifecycleProvider.java
   (with props)
    
commons/proper/weaver/trunk/processor/src/main/java/org/apache/commons/weaver/utils/Providers.java
   (with props)
    
commons/proper/weaver/trunk/processor/src/test/java/org/apache/commons/weaver/utils/ProvidersTest.java
   (with props)
Modified:
    commons/proper/weaver/trunk/ant/pom.xml
    commons/proper/weaver/trunk/parent/   (props changed)
    commons/proper/weaver/trunk/parent/pom.xml
    commons/proper/weaver/trunk/processor/pom.xml
    
commons/proper/weaver/trunk/processor/src/main/java/org/apache/commons/weaver/CleanProcessor.java
    
commons/proper/weaver/trunk/processor/src/main/java/org/apache/commons/weaver/WeaveProcessor.java
    
commons/proper/weaver/trunk/processor/src/main/java/org/apache/commons/weaver/spi/Cleaner.java
    
commons/proper/weaver/trunk/processor/src/main/java/org/apache/commons/weaver/spi/Weaver.java

Modified: commons/proper/weaver/trunk/ant/pom.xml
URL: 
http://svn.apache.org/viewvc/commons/proper/weaver/trunk/ant/pom.xml?rev=1720392&r1=1720391&r2=1720392&view=diff
==============================================================================
--- commons/proper/weaver/trunk/ant/pom.xml (original)
+++ commons/proper/weaver/trunk/ant/pom.xml Wed Dec 16 17:15:51 2015
@@ -49,7 +49,6 @@ under the License.
     <dependency>
       <groupId>org.apache.commons</groupId>
       <artifactId>commons-lang3</artifactId>
-      <version>3.1</version>
     </dependency>
     <dependency>
       <groupId>org.apache.ant</groupId>
@@ -115,21 +114,25 @@ under the License.
 
               <relocations>
                 <relocation>
-                  <pattern>org.apache.commons.lang3.</pattern>
-                  
<shadedPattern>org.apache.commons.weaver.ant._lang3.</shadedPattern>
+                  <pattern>org.apache.commons.collections4.</pattern>
+                  
<shadedPattern>org.apache.commons.weaver.ant._collections4.</shadedPattern>
                 </relocation>
                 <relocation>
                   <pattern>org.apache.commons.io.</pattern>
                   
<shadedPattern>org.apache.commons.weaver.ant._io.</shadedPattern>
                 </relocation>
                 <relocation>
+                  <pattern>org.apache.commons.lang3.</pattern>
+                  
<shadedPattern>org.apache.commons.weaver.ant._lang3.</shadedPattern>
+                </relocation>
+                <relocation>
                   <pattern>org.apache.xbean.</pattern>
                   
<shadedPattern>org.apache.commons.weaver.ant._xbean.</shadedPattern>
                 </relocation>
               </relocations>
               <filters>
                 <filter>
-                  <artifact>org.apache.commons:commons-lang3</artifact>
+                  <artifact>org.apache.commons:commons-collections4</artifact>
                   <excludes>
                     <exclude>META-INF/**</exclude>
                   </excludes>
@@ -139,6 +142,12 @@ under the License.
                   <excludes>
                     <exclude>META-INF/**</exclude>
                   </excludes>
+                </filter>
+                <filter>
+                  <artifact>org.apache.commons:commons-lang3</artifact>
+                  <excludes>
+                    <exclude>META-INF/**</exclude>
+                  </excludes>
                 </filter>
                 <filter>
                   <artifact>org.apache.xbean:*</artifact>

Propchange: commons/proper/weaver/trunk/parent/
------------------------------------------------------------------------------
--- svn:ignore (original)
+++ svn:ignore Wed Dec 16 17:15:51 2015
@@ -1 +1,3 @@
+.project
+.settings
 target

Modified: commons/proper/weaver/trunk/parent/pom.xml
URL: 
http://svn.apache.org/viewvc/commons/proper/weaver/trunk/parent/pom.xml?rev=1720392&r1=1720391&r2=1720392&view=diff
==============================================================================
--- commons/proper/weaver/trunk/parent/pom.xml (original)
+++ commons/proper/weaver/trunk/parent/pom.xml Wed Dec 16 17:15:51 2015
@@ -37,6 +37,7 @@ under the License.
 
     <ant.version>1.9.4</ant.version>
     <checkstyle.version>2.11</checkstyle.version>
+    <hamcrest.version>1.3</hamcrest.version>
   </properties>
 
   <scm>
@@ -160,6 +161,11 @@ under the License.
         <version>3.3.2</version>
       </dependency>
       <dependency>
+        <groupId>org.apache.commons</groupId>
+        <artifactId>commons-collections4</artifactId>
+        <version>4.1</version>
+      </dependency>
+      <dependency>
         <groupId>commons-io</groupId>
         <artifactId>commons-io</artifactId>
         <version>2.4</version>
@@ -200,6 +206,18 @@ under the License.
         <version>4.11</version>
         <scope>test</scope>
       </dependency>
+      <dependency>
+        <groupId>org.hamcrest</groupId>
+        <artifactId>hamcrest-core</artifactId>
+        <version>${hamcrest.version}</version>
+        <scope>test</scope>
+      </dependency>
+      <dependency>
+        <groupId>org.hamcrest</groupId>
+        <artifactId>hamcrest-library</artifactId>
+        <version>${hamcrest.version}</version>
+        <scope>test</scope>
+      </dependency>
     </dependencies>
   </dependencyManagement>
 

Modified: commons/proper/weaver/trunk/processor/pom.xml
URL: 
http://svn.apache.org/viewvc/commons/proper/weaver/trunk/processor/pom.xml?rev=1720392&r1=1720391&r2=1720392&view=diff
==============================================================================
--- commons/proper/weaver/trunk/processor/pom.xml (original)
+++ commons/proper/weaver/trunk/processor/pom.xml Wed Dec 16 17:15:51 2015
@@ -50,10 +50,19 @@ under the License.
       <artifactId>commons-lang3</artifactId>
     </dependency>
     <dependency>
+      <groupId>org.apache.commons</groupId>
+      <artifactId>commons-collections4</artifactId>
+    </dependency>
+    <dependency>
       <groupId>junit</groupId>
       <artifactId>junit</artifactId>
       <scope>test</scope>
     </dependency>
+    <dependency>
+      <groupId>org.hamcrest</groupId>
+      <artifactId>hamcrest-library</artifactId>
+      <scope>test</scope>
+    </dependency>
   </dependencies>
   <build>
     <plugins>

Modified: 
commons/proper/weaver/trunk/processor/src/main/java/org/apache/commons/weaver/CleanProcessor.java
URL: 
http://svn.apache.org/viewvc/commons/proper/weaver/trunk/processor/src/main/java/org/apache/commons/weaver/CleanProcessor.java?rev=1720392&r1=1720391&r2=1720392&view=diff
==============================================================================
--- 
commons/proper/weaver/trunk/processor/src/main/java/org/apache/commons/weaver/CleanProcessor.java
 (original)
+++ 
commons/proper/weaver/trunk/processor/src/main/java/org/apache/commons/weaver/CleanProcessor.java
 Wed Dec 16 17:15:51 2015
@@ -20,8 +20,6 @@ package org.apache.commons.weaver;
 
 import java.io.File;
 import java.net.URLClassLoader;
-import java.util.ArrayList;
-import java.util.Collections;
 import java.util.LinkedHashSet;
 import java.util.List;
 import java.util.Properties;
@@ -29,65 +27,39 @@ import java.util.ServiceLoader;
 import java.util.Set;
 import java.util.logging.Logger;
 
-import org.apache.commons.lang3.Validate;
+import org.apache.commons.weaver.lifecycle.WeaveLifecycle;
 import org.apache.commons.weaver.model.WeaveEnvironment;
 import org.apache.commons.weaver.spi.Cleaner;
 import org.apache.commons.weaver.utils.URLArray;
 import org.apache.xbean.finder.archive.FileArchive;
 
 /**
- * This class discovers and invokes available {@link Cleaner} plugins.
+ * Implements {@link WeaveLifecycle#CLEAN}.
  */
-public class CleanProcessor {
-    private static final Logger LOG = 
Logger.getLogger(CleanProcessor.class.getName());
+public class CleanProcessor extends ProcessorBase<Cleaner> {
 
     /**
-     * List of picked up cleaner plugins.
+     * Create a new {@link CleanProcessor} instance using the {@link 
ServiceLoader} mechanism.
+     *
+     * @param classpath not {@code null}
+     * @param target not {@code null}
+     * @param configuration not {@code null}
      */
-    private static final List<Cleaner> CLEANERS;
-
-    static {
-        final List<Cleaner> cleaners = new ArrayList<Cleaner>();
-        final ClassLoader cleanerLoader = Cleaner.class.getClassLoader();
-        if 
(!Thread.currentThread().getContextClassLoader().equals(cleanerLoader)) {
-            for (final Cleaner cleaner : ServiceLoader.load(Cleaner.class, 
cleanerLoader)) {
-                cleaners.add(cleaner);
-            }
-        }
-        for (final Cleaner cleaner : ServiceLoader.load(Cleaner.class)) {
-            cleaners.add(cleaner);
-        }
-        CLEANERS = Collections.unmodifiableList(cleaners);
+    public CleanProcessor(final List<String> classpath, final File target, 
final Properties configuration) {
+        this(classpath, target, configuration, 
getServiceInstances(Cleaner.class));
     }
 
     /**
-     * The classpath which will be used to look up cross references during 
cleaning.
-     */
-    private final List<String> classpath;
-
-    /**
-     * The actual path to be woven, replacing any affected classes.
-     */
-    private final File target;
-
-    /**
-     * Properties for configuring discovered plugin modules.
-     */
-    private final Properties configuration;
-
-    /**
      * Create a new {@link CleanProcessor} instance.
      *
      * @param classpath not {@code null}
      * @param target not {@code null}
      * @param configuration not {@code null}
+     * @param providers not (@code null}
      */
-    public CleanProcessor(final List<String> classpath, final File target, 
final Properties configuration) {
-        super();
-        this.classpath = Validate.notNull(classpath, "classpath");
-        this.target = Validate.notNull(target, "target");
-        Validate.isTrue(!target.exists() || target.isDirectory(), "%s is not a 
directory", target);
-        this.configuration = Validate.notNull(configuration, "configuration");
+    public CleanProcessor(final List<String> classpath, final File target, 
final Properties configuration,
+        final Iterable<Cleaner> providers) {
+        super(classpath, target, configuration, providers);
     }
 
     /**
@@ -95,17 +67,16 @@ public class CleanProcessor {
      */
     public void clean() {
         if (!target.exists()) {
-            LOG.warning("Target directory " + target + " does not exist; 
nothing to do!");
+            log.warning("Target directory " + target + " does not exist; 
nothing to do!");
         }
         final Set<String> finderClasspath = new LinkedHashSet<String>();
         finderClasspath.add(target.getAbsolutePath());
         finderClasspath.addAll(classpath);
         final ClassLoader classLoader = new 
URLClassLoader(URLArray.fromPaths(finderClasspath));
         final Finder finder = new Finder(new FileArchive(classLoader, target));
-        for (final Cleaner cleaner : CLEANERS) {
-            final WeaveEnvironment env =
-                new LocalWeaveEnvironment(target, classLoader, configuration, 
Logger.getLogger(cleaner.getClass()
-                    .getName()));
+        for (final Cleaner cleaner : providers) {
+            final WeaveEnvironment env = new LocalWeaveEnvironment(target, 
classLoader, configuration,
+                Logger.getLogger(cleaner.getClass().getName()));
             cleaner.clean(env, finder);
         }
     }

Added: 
commons/proper/weaver/trunk/processor/src/main/java/org/apache/commons/weaver/Consumes.java
URL: 
http://svn.apache.org/viewvc/commons/proper/weaver/trunk/processor/src/main/java/org/apache/commons/weaver/Consumes.java?rev=1720392&view=auto
==============================================================================
--- 
commons/proper/weaver/trunk/processor/src/main/java/org/apache/commons/weaver/Consumes.java
 (added)
+++ 
commons/proper/weaver/trunk/processor/src/main/java/org/apache/commons/weaver/Consumes.java
 Wed Dec 16 17:15:51 2015
@@ -0,0 +1,44 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.commons.weaver;
+
+import java.lang.annotation.Documented;
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Inherited;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+import org.apache.commons.weaver.spi.WeaveLifecycleProvider;
+
+/**
+ * Mark a {@link WeaveLifecycleProvider} as consuming the output of additional
+ * {@link WeaveLifecycleProvider}es of the same broad type.
+ */
+@Documented
+@Retention(RetentionPolicy.RUNTIME)
+@Target(ElementType.TYPE)
+@Inherited
+public @interface Consumes {
+    /**
+     * The consumed types.
+     * @return Class[]
+     */
+    Class<? extends WeaveLifecycleProvider<?>>[] value();
+}

Propchange: 
commons/proper/weaver/trunk/processor/src/main/java/org/apache/commons/weaver/Consumes.java
------------------------------------------------------------------------------
    svn:executable = *

Added: 
commons/proper/weaver/trunk/processor/src/main/java/org/apache/commons/weaver/ProcessorBase.java
URL: 
http://svn.apache.org/viewvc/commons/proper/weaver/trunk/processor/src/main/java/org/apache/commons/weaver/ProcessorBase.java?rev=1720392&view=auto
==============================================================================
--- 
commons/proper/weaver/trunk/processor/src/main/java/org/apache/commons/weaver/ProcessorBase.java
 (added)
+++ 
commons/proper/weaver/trunk/processor/src/main/java/org/apache/commons/weaver/ProcessorBase.java
 Wed Dec 16 17:15:51 2015
@@ -0,0 +1,104 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.commons.weaver;
+
+import java.io.File;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+import java.util.Properties;
+import java.util.ServiceLoader;
+import java.util.logging.Logger;
+
+import org.apache.commons.lang3.Validate;
+import org.apache.commons.weaver.lifecycle.WeaveLifecycle;
+import org.apache.commons.weaver.spi.WeaveLifecycleProvider;
+import org.apache.commons.weaver.utils.Providers;
+
+/**
+ * Base implementor of a {@link WeaveLifecycle} stage.
+ *
+ * @param <P> managed {@link WeaveLifecycleProvider} type
+ */
+class ProcessorBase<P extends WeaveLifecycleProvider<?>> {
+
+    /**
+     * Use the {@link ServiceLoader} to discover available {@code type} 
implementations.
+     *
+     * @param type not {@code null}
+     * @return {@link Iterable} of {@code T}
+     */
+    static <T> Iterable<T> getServiceInstances(final Class<T> type) {
+        Validate.notNull(type);
+        final List<T> result = new ArrayList<T>();
+        final ClassLoader typeLoader = type.getClassLoader();
+        if 
(!Thread.currentThread().getContextClassLoader().equals(typeLoader)) {
+            for (final T t : ServiceLoader.load(type, typeLoader)) {
+                result.add(t);
+            }
+        }
+        for (final T t : ServiceLoader.load(type)) {
+            result.add(t);
+        }
+        return Collections.unmodifiableList(result);
+    }
+
+    /**
+     * Logger instance.
+     */
+    protected final Logger log = Logger.getLogger(getClass().getName());
+
+    /**
+     * The classpath which will be used to look up cross references during 
weaving.
+     */
+    protected final List<String> classpath;
+
+    /**
+     * The actual path to be woven, replacing any affected classes.
+     */
+    protected final File target;
+
+    /**
+     * Properties for configuring discovered plugin modules.
+     */
+    protected final Properties configuration;
+
+    /**
+     * The managed {@link WeaveLifecycleProvider}es.
+     */
+    protected final Iterable<P> providers;
+
+    /**
+     * Create a new {@link ProcessorBase} instance.
+     *
+     * @param classpath not {@code null}
+     * @param target not {@code null}
+     * @param configuration not {@code null}
+     * @param providers not empty
+     */
+    protected ProcessorBase(final List<String> classpath, final File target, 
final Properties configuration,
+        final Iterable<P> providers) {
+        this.classpath = Validate.notNull(classpath, "classpath");
+        this.target = Validate.notNull(target, "target");
+        Validate.isTrue(!target.exists() || target.isDirectory(), "%s is not a 
directory", target);
+        this.configuration = Validate.notNull(configuration, "configuration");
+        this.providers = Providers.sort(providers);
+    }
+
+}

Propchange: 
commons/proper/weaver/trunk/processor/src/main/java/org/apache/commons/weaver/ProcessorBase.java
------------------------------------------------------------------------------
    svn:executable = *

Added: 
commons/proper/weaver/trunk/processor/src/main/java/org/apache/commons/weaver/Produces.java
URL: 
http://svn.apache.org/viewvc/commons/proper/weaver/trunk/processor/src/main/java/org/apache/commons/weaver/Produces.java?rev=1720392&view=auto
==============================================================================
--- 
commons/proper/weaver/trunk/processor/src/main/java/org/apache/commons/weaver/Produces.java
 (added)
+++ 
commons/proper/weaver/trunk/processor/src/main/java/org/apache/commons/weaver/Produces.java
 Wed Dec 16 17:15:51 2015
@@ -0,0 +1,44 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.commons.weaver;
+
+import java.lang.annotation.Documented;
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Inherited;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+import org.apache.commons.weaver.spi.WeaveLifecycleProvider;
+
+/**
+ * Mark a {@link WeaveLifecycleProvider} as creating output that is consumed 
by additional
+ * {@link WeaveLifecycleProvider}es of the same broad type.
+ */
+@Documented
+@Retention(RetentionPolicy.RUNTIME)
+@Target(ElementType.TYPE)
+@Inherited
+public @interface Produces {
+    /**
+     * The consuming types.
+     * @return Class[]
+     */
+    Class<? extends WeaveLifecycleProvider<?>>[] value();
+}

Propchange: 
commons/proper/weaver/trunk/processor/src/main/java/org/apache/commons/weaver/Produces.java
------------------------------------------------------------------------------
    svn:executable = *

Modified: 
commons/proper/weaver/trunk/processor/src/main/java/org/apache/commons/weaver/WeaveProcessor.java
URL: 
http://svn.apache.org/viewvc/commons/proper/weaver/trunk/processor/src/main/java/org/apache/commons/weaver/WeaveProcessor.java?rev=1720392&r1=1720391&r2=1720392&view=diff
==============================================================================
--- 
commons/proper/weaver/trunk/processor/src/main/java/org/apache/commons/weaver/WeaveProcessor.java
 (original)
+++ 
commons/proper/weaver/trunk/processor/src/main/java/org/apache/commons/weaver/WeaveProcessor.java
 Wed Dec 16 17:15:51 2015
@@ -20,8 +20,6 @@ package org.apache.commons.weaver;
 
 import java.io.File;
 import java.net.URLClassLoader;
-import java.util.ArrayList;
-import java.util.Collections;
 import java.util.LinkedHashSet;
 import java.util.List;
 import java.util.Properties;
@@ -29,66 +27,39 @@ import java.util.ServiceLoader;
 import java.util.Set;
 import java.util.logging.Logger;
 
-import org.apache.commons.lang3.Validate;
+import org.apache.commons.weaver.lifecycle.WeaveLifecycle;
 import org.apache.commons.weaver.model.WeaveEnvironment;
 import org.apache.commons.weaver.spi.Weaver;
 import org.apache.commons.weaver.utils.URLArray;
 import org.apache.xbean.finder.archive.FileArchive;
 
 /**
- * This class discovers and invokes available {@link Weaver} plugins.
+ * Implements {@link WeaveLifecycle#WEAVE}.
  */
-public class WeaveProcessor {
-
-    private static final Logger LOG = 
Logger.getLogger(WeaveProcessor.class.getName());
+public class WeaveProcessor extends ProcessorBase<Weaver> {
 
     /**
-     * List of picked up weaver plugins.
+     * Create a new {@link WeaveProcessor} instance using the {@link 
ServiceLoader} mechanism.
+     *
+     * @param classpath not {@code null}
+     * @param target not {@code null}
+     * @param configuration not {@code null}
      */
-    private static final List<Weaver> WEAVERS;
-
-    static {
-        final List<Weaver> weavers = new ArrayList<Weaver>();
-        final ClassLoader weaverLoader = Weaver.class.getClassLoader();
-        if 
(!Thread.currentThread().getContextClassLoader().equals(weaverLoader)) {
-            for (final Weaver weaver : ServiceLoader.load(Weaver.class, 
weaverLoader)) {
-                weavers.add(weaver);
-            }
-        }
-        for (final Weaver weaver : ServiceLoader.load(Weaver.class)) {
-            weavers.add(weaver);
-        }
-        WEAVERS = Collections.unmodifiableList(weavers);
+    public WeaveProcessor(final List<String> classpath, final File target, 
final Properties configuration) {
+        super(classpath, target, configuration, 
getServiceInstances(Weaver.class));
     }
 
     /**
-     * The classpath which will be used to look up cross references during 
weaving.
-     */
-    private final List<String> classpath;
-
-    /**
-     * The actual path to be woven, replacing any affected classes.
-     */
-    private final File target;
-
-    /**
-     * Properties for configuring discovered plugin modules.
-     */
-    private final Properties configuration;
-
-    /**
      * Create a new {@link WeaveProcessor} instance.
      *
      * @param classpath not {@code null}
      * @param target not {@code null}
      * @param configuration not {@code null}
+     * @param providers not (@code null}
      */
-    public WeaveProcessor(final List<String> classpath, final File target, 
final Properties configuration) {
-        super();
-        this.classpath = Validate.notNull(classpath, "classpath");
-        this.target = Validate.notNull(target, "target");
-        Validate.isTrue(!target.exists() || target.isDirectory(), "%s is not a 
directory", target);
-        this.configuration = Validate.notNull(configuration, "configuration");
+    public WeaveProcessor(final List<String> classpath, final File target, 
final Properties configuration,
+        final Iterable<Weaver> providers) {
+        super(classpath, target, configuration, providers);
     }
 
     /**
@@ -96,17 +67,16 @@ public class WeaveProcessor {
      */
     public void weave() {
         if (!target.exists()) {
-            LOG.warning("Target directory " + target + " does not exist; 
nothing to do!");
+            log.warning("Target directory " + target + " does not exist; 
nothing to do!");
         }
         final Set<String> finderClasspath = new LinkedHashSet<String>();
         finderClasspath.add(target.getAbsolutePath());
         finderClasspath.addAll(classpath);
         final ClassLoader classLoader = new 
URLClassLoader(URLArray.fromPaths(finderClasspath));
         final Finder finder = new Finder(new FileArchive(classLoader, target));
-        for (final Weaver weaver : WEAVERS) {
-            final WeaveEnvironment env =
-                new LocalWeaveEnvironment(target, classLoader, configuration, 
Logger.getLogger(weaver.getClass()
-                    .getName()));
+        for (final Weaver weaver : providers) {
+            final WeaveEnvironment env = new LocalWeaveEnvironment(target, 
classLoader, configuration,
+                Logger.getLogger(weaver.getClass().getName()));
             weaver.process(env, finder);
         }
     }

Added: 
commons/proper/weaver/trunk/processor/src/main/java/org/apache/commons/weaver/lifecycle/WeaveLifecycle.java
URL: 
http://svn.apache.org/viewvc/commons/proper/weaver/trunk/processor/src/main/java/org/apache/commons/weaver/lifecycle/WeaveLifecycle.java?rev=1720392&view=auto
==============================================================================
--- 
commons/proper/weaver/trunk/processor/src/main/java/org/apache/commons/weaver/lifecycle/WeaveLifecycle.java
 (added)
+++ 
commons/proper/weaver/trunk/processor/src/main/java/org/apache/commons/weaver/lifecycle/WeaveLifecycle.java
 Wed Dec 16 17:15:51 2015
@@ -0,0 +1,28 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.commons.weaver.lifecycle;
+
+/**
+ * Defines the parts of the weave lifecycle.
+ * @since 1.2
+ */
+public enum WeaveLifecycle {
+    CLEAN, WEAVE;
+}

Propchange: 
commons/proper/weaver/trunk/processor/src/main/java/org/apache/commons/weaver/lifecycle/WeaveLifecycle.java
------------------------------------------------------------------------------
    svn:executable = *

Added: 
commons/proper/weaver/trunk/processor/src/main/java/org/apache/commons/weaver/lifecycle/WeaveLifecycleToken.java
URL: 
http://svn.apache.org/viewvc/commons/proper/weaver/trunk/processor/src/main/java/org/apache/commons/weaver/lifecycle/WeaveLifecycleToken.java?rev=1720392&view=auto
==============================================================================
--- 
commons/proper/weaver/trunk/processor/src/main/java/org/apache/commons/weaver/lifecycle/WeaveLifecycleToken.java
 (added)
+++ 
commons/proper/weaver/trunk/processor/src/main/java/org/apache/commons/weaver/lifecycle/WeaveLifecycleToken.java
 Wed Dec 16 17:15:51 2015
@@ -0,0 +1,56 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.commons.weaver.lifecycle;
+
+import java.lang.annotation.Documented;
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+/**
+ * Defines token classes corresponding to the elements of the {@link 
WeaveLifecycle}.
+ * 
+ * @since 1.2
+ */
+public class WeaveLifecycleToken {
+    /**
+     * Declares the association between a {@link WeaveLifecycleToken} and an 
element of the {@link WeaveLifecycle}.
+     */
+    @Documented
+    @Retention(RetentionPolicy.RUNTIME)
+    @Target(ElementType.TYPE)
+    public @interface Represents {
+        WeaveLifecycle value();
+    }
+
+    /**
+     * Represents {@link WeaveLifecycle#CLEAN}.
+     */
+    @Represents(WeaveLifecycle.CLEAN)
+    public static final class Clean extends WeaveLifecycleToken {
+    }
+
+    /**
+     * Represents {@link WeaveLifecycle#WEAVE}.
+     */
+    @Represents(WeaveLifecycle.WEAVE)
+    public static final class Weave extends WeaveLifecycleToken {
+    }
+}

Propchange: 
commons/proper/weaver/trunk/processor/src/main/java/org/apache/commons/weaver/lifecycle/WeaveLifecycleToken.java
------------------------------------------------------------------------------
    svn:executable = *

Added: 
commons/proper/weaver/trunk/processor/src/main/java/org/apache/commons/weaver/lifecycle/package-info.java
URL: 
http://svn.apache.org/viewvc/commons/proper/weaver/trunk/processor/src/main/java/org/apache/commons/weaver/lifecycle/package-info.java?rev=1720392&view=auto
==============================================================================
--- 
commons/proper/weaver/trunk/processor/src/main/java/org/apache/commons/weaver/lifecycle/package-info.java
 (added)
+++ 
commons/proper/weaver/trunk/processor/src/main/java/org/apache/commons/weaver/lifecycle/package-info.java
 Wed Dec 16 17:15:51 2015
@@ -0,0 +1,23 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+/**
+ * Weave lifecycle package.
+ * @since 1.2
+ */
+package org.apache.commons.weaver.lifecycle;
\ No newline at end of file

Propchange: 
commons/proper/weaver/trunk/processor/src/main/java/org/apache/commons/weaver/lifecycle/package-info.java
------------------------------------------------------------------------------
    svn:executable = *

Modified: 
commons/proper/weaver/trunk/processor/src/main/java/org/apache/commons/weaver/spi/Cleaner.java
URL: 
http://svn.apache.org/viewvc/commons/proper/weaver/trunk/processor/src/main/java/org/apache/commons/weaver/spi/Cleaner.java?rev=1720392&r1=1720391&r2=1720392&view=diff
==============================================================================
--- 
commons/proper/weaver/trunk/processor/src/main/java/org/apache/commons/weaver/spi/Cleaner.java
 (original)
+++ 
commons/proper/weaver/trunk/processor/src/main/java/org/apache/commons/weaver/spi/Cleaner.java
 Wed Dec 16 17:15:51 2015
@@ -18,16 +18,19 @@
  */
 package org.apache.commons.weaver.spi;
 
+import org.apache.commons.weaver.lifecycle.WeaveLifecycle;
+import org.apache.commons.weaver.lifecycle.WeaveLifecycleToken.Clean;
 import org.apache.commons.weaver.model.Scanner;
 import org.apache.commons.weaver.model.WeaveEnvironment;
 
 /**
- * SPI to provide a means for a weaver module to remove woven classes during
- * incremental builds, if necessary.
+ * SPI to provide a means for a weaver module to remove woven classes during 
incremental builds, if necessary.
+ * Implements the {@code CLEAN} stage of the {@link WeaveLifecycle}.
  */
-public interface Cleaner {
+public interface Cleaner extends WeaveLifecycleProvider<Clean> {
     /**
      * Using the supplied {@link Scanner}, clean a {@link WeaveEnvironment}.
+     * 
      * @param environment to use
      * @param scanner to use
      * @return whether any work was done.

Added: 
commons/proper/weaver/trunk/processor/src/main/java/org/apache/commons/weaver/spi/WeaveLifecycleProvider.java
URL: 
http://svn.apache.org/viewvc/commons/proper/weaver/trunk/processor/src/main/java/org/apache/commons/weaver/spi/WeaveLifecycleProvider.java?rev=1720392&view=auto
==============================================================================
--- 
commons/proper/weaver/trunk/processor/src/main/java/org/apache/commons/weaver/spi/WeaveLifecycleProvider.java
 (added)
+++ 
commons/proper/weaver/trunk/processor/src/main/java/org/apache/commons/weaver/spi/WeaveLifecycleProvider.java
 Wed Dec 16 17:15:51 2015
@@ -0,0 +1,28 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.commons.weaver.spi;
+
+import org.apache.commons.weaver.lifecycle.WeaveLifecycleToken;
+
+/**
+ * Marker interface for commmons-weaver processes.
+ * @since 1.2
+ */
+public interface WeaveLifecycleProvider<S extends WeaveLifecycleToken> {
+}

Propchange: 
commons/proper/weaver/trunk/processor/src/main/java/org/apache/commons/weaver/spi/WeaveLifecycleProvider.java
------------------------------------------------------------------------------
    svn:executable = *

Modified: 
commons/proper/weaver/trunk/processor/src/main/java/org/apache/commons/weaver/spi/Weaver.java
URL: 
http://svn.apache.org/viewvc/commons/proper/weaver/trunk/processor/src/main/java/org/apache/commons/weaver/spi/Weaver.java?rev=1720392&r1=1720391&r2=1720392&view=diff
==============================================================================
--- 
commons/proper/weaver/trunk/processor/src/main/java/org/apache/commons/weaver/spi/Weaver.java
 (original)
+++ 
commons/proper/weaver/trunk/processor/src/main/java/org/apache/commons/weaver/spi/Weaver.java
 Wed Dec 16 17:15:51 2015
@@ -18,16 +18,19 @@
  */
 package org.apache.commons.weaver.spi;
 
+import org.apache.commons.weaver.lifecycle.WeaveLifecycle;
+import org.apache.commons.weaver.lifecycle.WeaveLifecycleToken.Weave;
 import org.apache.commons.weaver.model.Scanner;
 import org.apache.commons.weaver.model.WeaveEnvironment;
 
 /**
- * A {@link Weaver} implementation performs the byte code enhancement in the
- * classes.
+ * A {@link Weaver} implementation implements the {@code WEAVE} stage of the 
{@link WeaveLifecycle} by performing the
+ * byte code enhancement in the classes.
  */
-public interface Weaver {
+public interface Weaver extends WeaveLifecycleProvider<Weave> {
     /**
      * Using the supplied {@link Scanner}, process a {@link WeaveEnvironment}.
+     * 
      * @param environment to use
      * @param scanner to use
      * @return whether any work was done.

Added: 
commons/proper/weaver/trunk/processor/src/main/java/org/apache/commons/weaver/utils/Providers.java
URL: 
http://svn.apache.org/viewvc/commons/proper/weaver/trunk/processor/src/main/java/org/apache/commons/weaver/utils/Providers.java?rev=1720392&view=auto
==============================================================================
--- 
commons/proper/weaver/trunk/processor/src/main/java/org/apache/commons/weaver/utils/Providers.java
 (added)
+++ 
commons/proper/weaver/trunk/processor/src/main/java/org/apache/commons/weaver/utils/Providers.java
 Wed Dec 16 17:15:51 2015
@@ -0,0 +1,210 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.commons.weaver.utils;
+
+import java.util.ArrayDeque;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.Deque;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.LinkedHashSet;
+import java.util.Map;
+import java.util.Set;
+
+import org.apache.commons.collections4.Factory;
+import org.apache.commons.collections4.map.LazyMap;
+import org.apache.commons.lang3.ArrayUtils;
+import org.apache.commons.lang3.Validate;
+import org.apache.commons.weaver.Consumes;
+import org.apache.commons.weaver.Produces;
+import org.apache.commons.weaver.spi.WeaveLifecycleProvider;
+
+/**
+ * Utility for working with {@link WeaveLifecycleProvider} types.
+ */
+public final class Providers {
+    private enum State {
+        VISITING, VISITED;
+    }
+
+    /**
+     * Sort the specified providers with respect to declared {@link Consumes} 
and {@link Produces} annotations.
+     *
+     * @param providers
+     * @return {@link Iterable} of {@code P}
+     */
+    @SuppressWarnings("rawtypes")
+    public static <P extends WeaveLifecycleProvider<?>> Iterable<P> sort(final 
Iterable<P> providers) {
+        Validate.noNullElements(providers);
+
+        final Map<Class<? extends WeaveLifecycleProvider>, Set<Class<? extends 
WeaveLifecycleProvider>>> dependencyMap =
+            toDependencyMap(providers);
+
+        final Collection<Class<? extends WeaveLifecycleProvider>> order =
+            new LinkedHashSet<Class<? extends WeaveLifecycleProvider>>();
+
+        final Map<Class<? extends WeaveLifecycleProvider>, State> stateMap =
+            new HashMap<Class<? extends WeaveLifecycleProvider>, 
Providers.State>();
+        final Deque<Class<? extends WeaveLifecycleProvider>> visiting =
+            new ArrayDeque<Class<? extends WeaveLifecycleProvider>>();
+
+        for (Class<? extends WeaveLifecycleProvider> type : 
dependencyMap.keySet()) {
+            final State state = stateMap.get(type);
+
+            if (state == null) {
+                tsort(type, dependencyMap, stateMap, visiting, order);
+            } else if (state == State.VISITING) {
+                throw new RuntimeException("Unexpected node in visiting state: 
" + type);
+            }
+        }
+
+        return imposeOrder(providers, order);
+    }
+
+    /**
+     * Adapted from Apache Ant's target sorting mechanism.
+     *
+     * @param root current provider type
+     * @param dependencyMap {@link Map} of provider type to dependencies
+     * @param stateMap {@link Map} of current visitation state
+     * @param visiting {@link Deque} used as a stack
+     * @param target destination {@link Collection} which must preserve order
+     */
+    @SuppressWarnings("rawtypes")
+    private static <P extends WeaveLifecycleProvider<?>> void tsort(final 
Class<? extends WeaveLifecycleProvider> root,
+        final Map<Class<? extends WeaveLifecycleProvider>, Set<Class<? extends 
WeaveLifecycleProvider>>> dependencyMap,
+        final Map<Class<? extends WeaveLifecycleProvider>, State> stateMap,
+        final Deque<Class<? extends WeaveLifecycleProvider>> visiting,
+        final Collection<Class<? extends WeaveLifecycleProvider>> target) {
+
+        stateMap.put(root, State.VISITING);
+        visiting.push(root);
+
+        for (Class<? extends WeaveLifecycleProvider> dependency : 
dependencyMap.get(root)) {
+            final State state = stateMap.get(dependency);
+            if (state == State.VISITED) {
+                continue;
+            }
+            Validate.validState(state == null, "Circular dependency: %s of 
%s", dependency.getName(), root.getName());
+            tsort(dependency, dependencyMap, stateMap, visiting, target);
+        }
+        final Class<? extends WeaveLifecycleProvider> top = visiting.pop();
+        Validate.validState(top == root, "Stack out of balance: expected %s, 
found %s", root.getName(), top.getName());
+
+        stateMap.put(root, State.VISITED);
+        target.add(root);
+    }
+
+    /**
+     * Read any {@link Produces} annotation associated with {@code 
providerClass}, designating types before which it
+     * should be invoked.
+     *
+     * @param providerClass
+     * @return {@link Class}[]
+     */
+    private static <P extends WeaveLifecycleProvider<?>> Class<? extends P>[] 
producedBy(
+        final Class<? extends P> providerClass) {
+        Validate.notNull(providerClass);
+        final Produces produces = providerClass.getAnnotation(Produces.class);
+        if (produces == null || produces.value().length == 0) {
+            @SuppressWarnings("unchecked")
+            final Class<? extends P>[] empty = (Class<? extends P>[]) 
ArrayUtils.EMPTY_CLASS_ARRAY;
+            return empty;
+        }
+        @SuppressWarnings("unchecked")
+        final Class<? extends P>[] result = (Class<? extends P>[]) 
produces.value();
+        return result;
+    }
+
+    /**
+     * Read any {@link Consumes} annotation associated with {@code 
providerClass} as dependencies.
+     *
+     * @param providerClass
+     * @return {@link Class}[]
+     */
+    private static <P extends WeaveLifecycleProvider<?>> Class<? extends P>[] 
consumedBy(
+        final Class<? extends P> providerClass) {
+        Validate.notNull(providerClass);
+        final Consumes consumes = providerClass.getAnnotation(Consumes.class);
+        if (consumes == null || consumes.value().length == 0) {
+            @SuppressWarnings("unchecked")
+            final Class<? extends P>[] empty = (Class<? extends P>[]) 
ArrayUtils.EMPTY_CLASS_ARRAY;
+            return empty;
+        }
+        @SuppressWarnings("unchecked")
+        final Class<? extends P>[] result = (Class<? extends P>[]) 
consumes.value();
+        return result;
+    }
+
+    /**
+     * Create a {@link Map} of provider type to dependency types.
+     *
+     * @param providers to inspect
+     * @return {@link Map}
+     */
+    @SuppressWarnings("rawtypes")
+    private static Map<Class<? extends WeaveLifecycleProvider>, Set<Class<? 
extends WeaveLifecycleProvider>>> toDependencyMap(
+        final Iterable<? extends WeaveLifecycleProvider<?>> providers) {
+
+        final Map<Class<? extends WeaveLifecycleProvider>, Set<Class<? extends 
WeaveLifecycleProvider>>> result =
+            LazyMap.lazyMap(
+                new HashMap<Class<? extends WeaveLifecycleProvider>, 
Set<Class<? extends WeaveLifecycleProvider>>>(),
+                new Factory<Set<Class<? extends WeaveLifecycleProvider>>>() {
+
+                    @Override
+                    public Set<Class<? extends WeaveLifecycleProvider>> 
create() {
+                        return new HashSet<Class<? extends 
WeaveLifecycleProvider>>();
+                    }
+                });
+
+        for (WeaveLifecycleProvider<?> provider : providers) {
+            final Class<? extends WeaveLifecycleProvider> type = 
provider.getClass();
+            Collections.addAll(result.get(type), consumedBy(type));
+
+            for (Class<? extends WeaveLifecycleProvider> dependent : 
producedBy(type)) {
+                result.get(dependent).add(type);
+            }
+        }
+        return result;
+    }
+
+    /**
+     * Order providers.
+     *
+     * @param providers to sort
+     * @param order to respect
+     * @return reordered providers
+     */
+    @SuppressWarnings("rawtypes")
+    private static <P extends WeaveLifecycleProvider> Iterable<P> 
imposeOrder(final Iterable<P> providers,
+        final Iterable<Class<? extends WeaveLifecycleProvider>> order) {
+
+        final Set<P> result = new LinkedHashSet<P>();
+
+        for (Class<? extends WeaveLifecycleProvider> type : order) {
+            for (P provider : providers) {
+                if (type.isInstance(provider)) {
+                    result.add(provider);
+                }
+            }
+        }
+        return Collections.unmodifiableSet(result);
+    }
+}

Propchange: 
commons/proper/weaver/trunk/processor/src/main/java/org/apache/commons/weaver/utils/Providers.java
------------------------------------------------------------------------------
    svn:executable = *

Added: 
commons/proper/weaver/trunk/processor/src/test/java/org/apache/commons/weaver/utils/ProvidersTest.java
URL: 
http://svn.apache.org/viewvc/commons/proper/weaver/trunk/processor/src/test/java/org/apache/commons/weaver/utils/ProvidersTest.java?rev=1720392&view=auto
==============================================================================
--- 
commons/proper/weaver/trunk/processor/src/test/java/org/apache/commons/weaver/utils/ProvidersTest.java
 (added)
+++ 
commons/proper/weaver/trunk/processor/src/test/java/org/apache/commons/weaver/utils/ProvidersTest.java
 Wed Dec 16 17:15:51 2015
@@ -0,0 +1,93 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.commons.weaver.utils;
+
+import static org.junit.Assert.assertThat;
+
+import java.util.Arrays;
+
+import org.apache.commons.weaver.Consumes;
+import org.apache.commons.weaver.Produces;
+import org.apache.commons.weaver.lifecycle.WeaveLifecycleToken;
+import org.apache.commons.weaver.spi.WeaveLifecycleProvider;
+import org.apache.commons.weaver.spi.Weaver;
+import org.hamcrest.collection.IsIterableContainingInOrder;
+import org.junit.Test;
+
+public class ProvidersTest {
+
+    @Test(expected = NullPointerException.class)
+    public void testSortNull() {
+        Providers.sort(null);
+    }
+
+    @Test(expected = IllegalArgumentException.class)
+    public void testSortNullElement() {
+        Providers.sort(Arrays.asList((Weaver) null));
+    }
+
+    public interface FauxWeaveProvider extends 
WeaveLifecycleProvider<WeaveLifecycleToken.Weave> {
+    }
+
+    public class A implements FauxWeaveProvider {
+    }
+
+    @Consumes(A.class)
+    @Produces(C.class)
+    public class B implements FauxWeaveProvider {
+    }
+
+    public class C implements FauxWeaveProvider {
+    }
+
+    @Consumes(X.class)
+    public class W implements FauxWeaveProvider {
+    }
+
+    @Consumes(Y.class)
+    public class X implements FauxWeaveProvider {
+    }
+
+    public class Y implements FauxWeaveProvider {
+    }
+
+    @Produces(Y.class)
+    public class Z implements FauxWeaveProvider {
+    }
+
+    @Consumes(Y.class)
+    @Produces(Z.class)
+    public class Monkeywrench implements FauxWeaveProvider {
+    }
+
+    private FauxWeaveProvider a = new A(), b = new B(), c = new C(), w = new 
W(), x = new X(), y = new Y(), z = new Z(),
+                    monkeywrench = new Monkeywrench();
+
+    @Test
+    public void testSort() {
+        assertThat(Providers.sort(Arrays.asList(b, a, c)), 
IsIterableContainingInOrder.contains(a, b, c));
+        assertThat(Providers.sort(Arrays.asList(y, w, x, z)), 
IsIterableContainingInOrder.contains(z, y, x, w));
+    }
+
+    @Test(expected = IllegalStateException.class)
+    public void testCircularSort() {
+        Providers.sort(Arrays.asList(y, z, monkeywrench));
+    }
+
+}

Propchange: 
commons/proper/weaver/trunk/processor/src/test/java/org/apache/commons/weaver/utils/ProvidersTest.java
------------------------------------------------------------------------------
    svn:executable = *


Reply via email to