You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@commons.apache.org by mb...@apache.org on 2013/04/25 00:12:48 UTC

svn commit: r1471730 - in /commons/sandbox/weaver/trunk: ant/lib/src/main/java/org/apache/commons/weaver/ant/ ant/lib/src/main/resources/org/apache/commons/weaver/ant/ example/ maven-plugin/src/main/java/org/apache/commons/weaver/maven/ processor/src/m...

Author: mbenson
Date: Wed Apr 24 22:12:48 2013
New Revision: 1471730

URL: http://svn.apache.org/r1471730
Log:
add Cleaner SPI, CleanProcessor, and CleanTask; restore prepare and test-prepare mojos

Added:
    commons/sandbox/weaver/trunk/ant/lib/src/main/java/org/apache/commons/weaver/ant/CleanTask.java
    commons/sandbox/weaver/trunk/maven-plugin/src/main/java/org/apache/commons/weaver/maven/AbstractPrepareMojo.java
    commons/sandbox/weaver/trunk/processor/src/main/java/org/apache/commons/weaver/CleanProcessor.java
    commons/sandbox/weaver/trunk/processor/src/main/java/org/apache/commons/weaver/spi/Cleaner.java
    commons/sandbox/weaver/trunk/processor/src/test/java/org/apache/commons/weaver/test/CleanProcessorTest.java
    commons/sandbox/weaver/trunk/processor/src/test/java/org/apache/commons/weaver/test/weaver/TestCleaner.java
    commons/sandbox/weaver/trunk/processor/src/test/resources/META-INF/services/org.apache.commons.weaver.spi.Cleaner
Modified:
    commons/sandbox/weaver/trunk/ant/lib/src/main/resources/org/apache/commons/weaver/ant/antlib.xml
    commons/sandbox/weaver/trunk/example/pom.xml
    commons/sandbox/weaver/trunk/maven-plugin/src/main/java/org/apache/commons/weaver/maven/PrepareMojo.java
    commons/sandbox/weaver/trunk/maven-plugin/src/main/java/org/apache/commons/weaver/maven/TestPrepareMojo.java

Added: commons/sandbox/weaver/trunk/ant/lib/src/main/java/org/apache/commons/weaver/ant/CleanTask.java
URL: http://svn.apache.org/viewvc/commons/sandbox/weaver/trunk/ant/lib/src/main/java/org/apache/commons/weaver/ant/CleanTask.java?rev=1471730&view=auto
==============================================================================
--- commons/sandbox/weaver/trunk/ant/lib/src/main/java/org/apache/commons/weaver/ant/CleanTask.java (added)
+++ commons/sandbox/weaver/trunk/ant/lib/src/main/java/org/apache/commons/weaver/ant/CleanTask.java Wed Apr 24 22:12:48 2013
@@ -0,0 +1,136 @@
+/*
+ *  Copyright the original author or authors.
+ *
+ *  Licensed 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.ant;
+
+import java.io.File;
+import java.util.Arrays;
+import java.util.List;
+import java.util.Map;
+import java.util.Properties;
+
+import org.apache.commons.lang3.StringUtils;
+import org.apache.commons.weaver.CleanProcessor;
+import org.apache.tools.ant.BuildException;
+import org.apache.tools.ant.Task;
+import org.apache.tools.ant.types.EnumeratedAttribute;
+import org.apache.tools.ant.types.Path;
+import org.apache.tools.ant.types.PropertySet;
+import org.apache.tools.ant.types.PropertySet.BuiltinPropertySetName;
+import org.apache.tools.ant.types.Reference;
+
+/**
+ * Clean Ant task.
+ */
+public class CleanTask extends Task {
+    private File target;
+    private Path classpath;
+    private String classpathref;
+    private PropertySet propertySet;
+    private InlineProperties inlineProperties;
+
+    @Override
+    public void execute() throws BuildException {
+        try {
+            final CleanProcessor cp = new CleanProcessor(getClassPathEntries(), target, getProperties());
+            cp.clean();
+        } catch (Exception e) {
+            throw new BuildException(e);
+        }
+    }
+
+    protected File getTarget() {
+        return target;
+    }
+
+    public void setTarget(File target) {
+        this.target = target;
+    }
+
+    protected String getClasspathref() {
+        return classpathref;
+    }
+
+    public void setClasspathRef(String classpathref) {
+        this.classpathref = classpathref;
+    }
+
+    protected List<String> getClassPathEntries() {
+        final Path p = new Path(getProject());
+        final Path cp = getClasspath();
+        if (cp != null) {
+            p.add(cp);
+        }
+        p.add(Path.systemClasspath);
+
+        return Arrays.asList(p.list());
+    }
+
+    protected Path getClasspath() {
+        if (classpath == null) {
+            if (getClasspathref() != null) {
+                Path ref = new Path(getProject());
+                ref.setRefid(new Reference(getProject(), getClasspathref()));
+                return ref;
+            }
+        } else if (StringUtils.isNotBlank(getClasspathref())) {
+            throw new BuildException("Only one of classpathref|classpath is permitted.");
+        }
+        return classpath;
+    }
+
+    public void setClasspath(Path classpath) {
+        if (this.classpath != null) {
+            throw new BuildException("classpath already set");
+        }
+        this.classpath = classpath;
+    }
+
+    public InlineProperties createProperties() {
+        if (inlineProperties != null) {
+            throw new BuildException("properties already specified");
+        }
+        inlineProperties = new InlineProperties();
+        return inlineProperties;
+    }
+
+    public PropertySet createPropertySet() {
+        if (propertySet != null) {
+            throw new BuildException("propertyset already specified");
+        }
+        propertySet = new PropertySet();
+        propertySet.setProject(getProject());
+        return propertySet;
+    }
+
+    private Properties getProperties() {
+        if (propertySet == null && inlineProperties == null) {
+            createPropertySet().appendBuiltin(
+                    (BuiltinPropertySetName) EnumeratedAttribute.getInstance(
+                            BuiltinPropertySetName.class, "all"));
+        }
+        final Properties result = new Properties();
+        if (propertySet != null) {
+            result.putAll(propertySet.getProperties());
+        }
+        if (inlineProperties != null) {
+            for (Map.Entry<Object, Object> e : inlineProperties.properties.entrySet()) {
+                result.put(e.getKey(), StringUtils.trim((String) e.getValue()));
+            }
+        }
+        return result;
+    }
+
+}

Modified: commons/sandbox/weaver/trunk/ant/lib/src/main/resources/org/apache/commons/weaver/ant/antlib.xml
URL: http://svn.apache.org/viewvc/commons/sandbox/weaver/trunk/ant/lib/src/main/resources/org/apache/commons/weaver/ant/antlib.xml?rev=1471730&r1=1471729&r2=1471730&view=diff
==============================================================================
--- commons/sandbox/weaver/trunk/ant/lib/src/main/resources/org/apache/commons/weaver/ant/antlib.xml (original)
+++ commons/sandbox/weaver/trunk/ant/lib/src/main/resources/org/apache/commons/weaver/ant/antlib.xml Wed Apr 24 22:12:48 2013
@@ -17,5 +17,6 @@
 
  -->
 <antlib>
+  <taskdef name="clean" classname="org.apache.commons.weaver.ant.CleanTask" />
   <taskdef name="weave" classname="org.apache.commons.weaver.ant.WeaveTask" />
 </antlib>

Modified: commons/sandbox/weaver/trunk/example/pom.xml
URL: http://svn.apache.org/viewvc/commons/sandbox/weaver/trunk/example/pom.xml?rev=1471730&r1=1471729&r2=1471730&view=diff
==============================================================================
--- commons/sandbox/weaver/trunk/example/pom.xml (original)
+++ commons/sandbox/weaver/trunk/example/pom.xml Wed Apr 24 22:12:48 2013
@@ -61,6 +61,7 @@
         <executions>
           <execution>
             <goals>
+              <goal>prepare</goal>
               <goal>weave</goal>
             </goals>
           </execution>

Added: commons/sandbox/weaver/trunk/maven-plugin/src/main/java/org/apache/commons/weaver/maven/AbstractPrepareMojo.java
URL: http://svn.apache.org/viewvc/commons/sandbox/weaver/trunk/maven-plugin/src/main/java/org/apache/commons/weaver/maven/AbstractPrepareMojo.java?rev=1471730&view=auto
==============================================================================
--- commons/sandbox/weaver/trunk/maven-plugin/src/main/java/org/apache/commons/weaver/maven/AbstractPrepareMojo.java (added)
+++ commons/sandbox/weaver/trunk/maven-plugin/src/main/java/org/apache/commons/weaver/maven/AbstractPrepareMojo.java Wed Apr 24 22:12:48 2013
@@ -0,0 +1,66 @@
+/*
+ *  Copyright the original author or authors.
+ *
+ *  Licensed 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.maven;
+
+import java.io.File;
+import java.util.List;
+import java.util.Properties;
+
+import org.apache.commons.weaver.CleanProcessor;
+import org.apache.maven.plugin.AbstractMojo;
+import org.apache.maven.plugin.MojoExecutionException;
+import org.apache.maven.plugins.annotations.Parameter;
+
+/**
+ * Defines common properties.
+ */
+public abstract class AbstractPrepareMojo extends AbstractMojo {
+
+    @Parameter(defaultValue = "false")
+    protected boolean verbose;
+
+    @Parameter(property = "weaver.config", required = false)
+    protected Properties weaverConfig;
+
+    protected abstract List<String> getClasspath();
+
+    protected abstract File getTarget();
+
+    @Override
+    public void execute() throws MojoExecutionException {
+        if (!getTarget().isDirectory()) {
+            return;
+        }
+        final JavaLoggingToMojoLoggingRedirector logRedirector = new JavaLoggingToMojoLoggingRedirector(getLog());
+        logRedirector.activate();
+
+        final List<String> classpath = getClasspath();
+        final File target = getTarget();
+        final Properties config = weaverConfig == null ? new Properties() : weaverConfig;
+
+        getLog().debug(String.format("classpath=%s%ntarget=%s%nconfig=%s", classpath, target, config));
+
+        try {
+            final CleanProcessor cp = new CleanProcessor(classpath, target, config);
+            cp.clean();
+        } catch (Exception e) {
+            throw new MojoExecutionException("cleaning failed due to " + e.getMessage(), e);
+        } finally {
+            logRedirector.deactivate();
+        }
+    }
+
+}

Modified: commons/sandbox/weaver/trunk/maven-plugin/src/main/java/org/apache/commons/weaver/maven/PrepareMojo.java
URL: http://svn.apache.org/viewvc/commons/sandbox/weaver/trunk/maven-plugin/src/main/java/org/apache/commons/weaver/maven/PrepareMojo.java?rev=1471730&r1=1471729&r2=1471730&view=diff
==============================================================================
--- commons/sandbox/weaver/trunk/maven-plugin/src/main/java/org/apache/commons/weaver/maven/PrepareMojo.java (original)
+++ commons/sandbox/weaver/trunk/maven-plugin/src/main/java/org/apache/commons/weaver/maven/PrepareMojo.java Wed Apr 24 22:12:48 2013
@@ -15,33 +15,33 @@
  */
 package org.apache.commons.weaver.maven;
 
-import org.apache.maven.plugin.MojoExecutionException;
-import org.apache.maven.plugins.annotations.Component;
+import java.io.File;
+import java.util.List;
+
 import org.apache.maven.plugins.annotations.LifecyclePhase;
 import org.apache.maven.plugins.annotations.Mojo;
+import org.apache.maven.plugins.annotations.Parameter;
 import org.apache.maven.plugins.annotations.ResolutionScope;
-import org.apache.maven.project.MavenProject;
 
 /**
- * Prepare for weaving by deleting classes previously woven with a different
- * policy.
+ * Prepare for weaving by deleting classes previously woven with a different policy.
  */
 @Mojo(name = "prepare", defaultPhase = LifecyclePhase.INITIALIZE, requiresDependencyCollection = ResolutionScope.COMPILE)
-public class PrepareMojo extends WeaveMojo {
-    @Component
-    private MavenProject project;
+public class PrepareMojo extends AbstractPrepareMojo {
+    @Parameter(readonly = true, required = true, defaultValue = "${project.compileClasspathElements}")
+    protected List<String> classpath;
+
+    @Parameter(readonly = true, required = true, defaultValue = "${project.build.outputDirectory}")
+    protected File target;
+
+    @Override
+    protected List<String> getClasspath() {
+        return classpath;
+    }
 
     @Override
-    public void execute() throws MojoExecutionException {
-        if (target.exists()) {
-            try {
-            /*X TODO do we need the prepare mojo at all?
-                createWeaver().prepare();
-                */
-            } catch (Exception e) {
-                throw new MojoExecutionException("error", e);
-            }
-        }
+    protected File getTarget() {
+        return target;
     }
 
 }

Modified: commons/sandbox/weaver/trunk/maven-plugin/src/main/java/org/apache/commons/weaver/maven/TestPrepareMojo.java
URL: http://svn.apache.org/viewvc/commons/sandbox/weaver/trunk/maven-plugin/src/main/java/org/apache/commons/weaver/maven/TestPrepareMojo.java?rev=1471730&r1=1471729&r2=1471730&view=diff
==============================================================================
--- commons/sandbox/weaver/trunk/maven-plugin/src/main/java/org/apache/commons/weaver/maven/TestPrepareMojo.java (original)
+++ commons/sandbox/weaver/trunk/maven-plugin/src/main/java/org/apache/commons/weaver/maven/TestPrepareMojo.java Wed Apr 24 22:12:48 2013
@@ -15,33 +15,34 @@
  */
 package org.apache.commons.weaver.maven;
 
-import org.apache.maven.plugin.MojoExecutionException;
-import org.apache.maven.plugins.annotations.Component;
+import java.io.File;
+import java.util.List;
+
 import org.apache.maven.plugins.annotations.LifecyclePhase;
 import org.apache.maven.plugins.annotations.Mojo;
+import org.apache.maven.plugins.annotations.Parameter;
 import org.apache.maven.plugins.annotations.ResolutionScope;
-import org.apache.maven.project.MavenProject;
 
 /**
- * Prepare for weaving by deleting test classes previously woven with a different
- * policy.
+ * Prepare for weaving by deleting test classes previously woven with a different policy.
  */
 @Mojo(name = "test-prepare", defaultPhase = LifecyclePhase.INITIALIZE, requiresDependencyCollection = ResolutionScope.TEST)
-public class TestPrepareMojo extends TestWeaveMojo {
-    @Component
-    private MavenProject project;
+public class TestPrepareMojo extends AbstractPrepareMojo {
+
+    @Parameter(readonly = true, required = true, defaultValue = "${project.testClasspathElements}")
+    protected List<String> classpath;
+
+    @Parameter(readonly = true, required = true, defaultValue = "${project.build.testOutputDirectory}")
+    protected File target;
+
+    @Override
+    protected List<String> getClasspath() {
+        return classpath;
+    }
 
     @Override
-    public void execute() throws MojoExecutionException {
-        if (target.exists()) {
-/*X TODO do we need the prepare mojo at all?
-            try {
-                createWeaver().prepare();
-            } catch (Exception e) {
-                throw new MojoExecutionException("error", e);
-            }
-*/
-        }
+    protected File getTarget() {
+        return target;
     }
 
 }

Added: commons/sandbox/weaver/trunk/processor/src/main/java/org/apache/commons/weaver/CleanProcessor.java
URL: http://svn.apache.org/viewvc/commons/sandbox/weaver/trunk/processor/src/main/java/org/apache/commons/weaver/CleanProcessor.java?rev=1471730&view=auto
==============================================================================
--- commons/sandbox/weaver/trunk/processor/src/main/java/org/apache/commons/weaver/CleanProcessor.java (added)
+++ commons/sandbox/weaver/trunk/processor/src/main/java/org/apache/commons/weaver/CleanProcessor.java Wed Apr 24 22:12:48 2013
@@ -0,0 +1,151 @@
+/*
+ * 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.lang.reflect.Constructor;
+import java.lang.reflect.Field;
+import java.lang.reflect.Method;
+import java.net.URLClassLoader;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+import java.util.Properties;
+import java.util.ServiceLoader;
+
+import org.apache.commons.lang3.Validate;
+import org.apache.commons.weaver.model.ScanResult;
+import org.apache.commons.weaver.model.WeaveInterest;
+import org.apache.commons.weaver.spi.Cleaner;
+import org.apache.commons.weaver.utils.URLArray;
+import org.apache.xbean.finder.Annotated;
+import org.apache.xbean.finder.Parameter;
+import org.apache.xbean.finder.archive.FileArchive;
+
+/**
+ * This class discovers and invokes available {@link Cleaner} plugins.
+ */
+public class CleanProcessor {
+
+    /** List of picked up cleaner plugins */
+    private static List<Cleaner> CLEANERS = new ArrayList<Cleaner>();
+    static {
+        List<Cleaner> cleaners = new ArrayList<Cleaner>();
+        for (Cleaner c : ServiceLoader.load(Cleaner.class)) {
+            cleaners.add(c);
+        }
+        CLEANERS = Collections.unmodifiableList(cleaners);
+    }
+
+    /**
+     * 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}
+     */
+    public CleanProcessor(List<String> classpath, File target, Properties configuration) {
+        super();
+        this.classpath = Validate.notNull(classpath, "classpath");
+        this.target = Validate.notNull(target, "target");
+        this.configuration = Validate.notNull(configuration, "configuration");
+    }
+
+    /**
+     * Clean specified targets.
+     */
+    public void clean() {
+        final ClassLoader classLoader = new URLClassLoader(URLArray.fromPaths(classpath));
+        final Finder finder = new Finder(new FileArchive(classLoader, target));
+        for (Cleaner weaver : CLEANERS) {
+            clean(finder, weaver);
+        }
+    }
+
+    private void clean(final Finder finder, final Cleaner cleaner) {
+        cleaner.configure(classpath, target, configuration);
+        final ScanResult result = new ScanResult();
+
+        for (WeaveInterest interest : cleaner.getScanRequest().getInterests()) {
+            switch (interest.target) {
+                case PACKAGE:
+                    for (Annotated<Package> pkg : finder.withAnnotations().findAnnotatedPackages(
+                        interest.annotationType)) {
+                        result.getWeavable(pkg.get()).addAnnotations(pkg.getAnnotation(interest.annotationType));
+                    }
+                case TYPE:
+                    for (Annotated<Class<?>> type : finder.withAnnotations().findAnnotatedClasses(
+                        interest.annotationType)) {
+                        result.getWeavable(type.get()).addAnnotations(type.getAnnotation(interest.annotationType));
+                    }
+                    break;
+                case METHOD:
+                    for (Annotated<Method> method : finder.withAnnotations().findAnnotatedMethods(
+                        interest.annotationType)) {
+                        result.getWeavable(method.get()).addAnnotations(method.getAnnotation(interest.annotationType));
+                    }
+                    break;
+                case CONSTRUCTOR:
+                    for (Annotated<Constructor<?>> cs : finder.withAnnotations().findAnnotatedConstructors(
+                        interest.annotationType)) {
+                        result.getWeavable(cs.get()).addAnnotations(cs.getAnnotation(interest.annotationType));
+                    }
+                    break;
+                case FIELD:
+                    for (Annotated<Field> fld : finder.withAnnotations().findAnnotatedFields(interest.annotationType)) {
+                        result.getWeavable(fld.get()).addAnnotations(fld.getAnnotation(interest.annotationType));
+                    }
+                    break;
+                case PARAMETER:
+                    for (Annotated<Parameter<Method>> parameter : finder.withAnnotations()
+                        .findAnnotatedMethodParameters(interest.annotationType)) {
+                        result.getWeavable(parameter.get().getDeclaringExecutable())
+                            .getWeavableParameter(parameter.get().getIndex())
+                            .addAnnotations(parameter.getAnnotation(interest.annotationType));
+                    }
+                    for (Annotated<Parameter<Constructor<?>>> parameter : finder.withAnnotations()
+                        .findAnnotatedConstructorParameters(interest.annotationType)) {
+                        result.getWeavable(parameter.get().getDeclaringExecutable())
+                            .getWeavableParameter(parameter.get().getIndex())
+                            .addAnnotations(parameter.getAnnotation(interest.annotationType));
+                    }
+                    break;
+                default:
+                    // should we log something?
+                    break;
+            }
+        }
+        cleaner.clean(result);
+    }
+}

Added: commons/sandbox/weaver/trunk/processor/src/main/java/org/apache/commons/weaver/spi/Cleaner.java
URL: http://svn.apache.org/viewvc/commons/sandbox/weaver/trunk/processor/src/main/java/org/apache/commons/weaver/spi/Cleaner.java?rev=1471730&view=auto
==============================================================================
--- commons/sandbox/weaver/trunk/processor/src/main/java/org/apache/commons/weaver/spi/Cleaner.java (added)
+++ commons/sandbox/weaver/trunk/processor/src/main/java/org/apache/commons/weaver/spi/Cleaner.java Wed Apr 24 22:12:48 2013
@@ -0,0 +1,53 @@
+/*
+ * 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 java.io.File;
+import java.util.List;
+import java.util.Properties;
+
+import org.apache.commons.weaver.model.ScanRequest;
+import org.apache.commons.weaver.model.ScanResult;
+
+/**
+ * SPI to provide a means for a weaver module to remove woven classes during incremental builds, if necessary.
+ */
+public interface Cleaner {
+    /**
+     * @see Weaver#configure(List, File, Properties)
+     * 
+     * @param classPath the classpath to look up cross-references in during weaving
+     * @param target the File path where the classes to weave reside
+     * @param config additional configuration for all plugins.
+     */
+    void configure(List<String> classPath, File target, Properties config);
+
+    /**
+     * Get the scan request of this {@link Cleaner}.
+     */
+    ScanRequest getScanRequest();
+
+    /**
+     * Process the scanning results.
+     * 
+     * @param scanResult
+     * @return whether any work was done.
+     */
+    boolean clean(ScanResult scanResult);
+}

Added: commons/sandbox/weaver/trunk/processor/src/test/java/org/apache/commons/weaver/test/CleanProcessorTest.java
URL: http://svn.apache.org/viewvc/commons/sandbox/weaver/trunk/processor/src/test/java/org/apache/commons/weaver/test/CleanProcessorTest.java?rev=1471730&view=auto
==============================================================================
--- commons/sandbox/weaver/trunk/processor/src/test/java/org/apache/commons/weaver/test/CleanProcessorTest.java (added)
+++ commons/sandbox/weaver/trunk/processor/src/test/java/org/apache/commons/weaver/test/CleanProcessorTest.java Wed Apr 24 22:12:48 2013
@@ -0,0 +1,53 @@
+/*
+ * 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.test;
+
+import java.io.File;
+import java.util.Properties;
+
+import org.apache.commons.weaver.CleanProcessor;
+import org.apache.commons.weaver.test.beans.TestBeanWithClassAnnotation;
+import org.apache.commons.weaver.test.beans.TestBeanWithMethodAnnotation;
+import org.junit.Assert;
+import org.junit.Test;
+
+/**
+ * Test the {@link CleanProcessor}
+ */
+public class CleanProcessorTest extends WeaverTestBase {
+
+    @Test
+    public void testWeaveVisiting() throws Exception {
+        addClassForScanning(TestBeanWithMethodAnnotation.class);
+        addClassForScanning(TestBeanWithClassAnnotation.class);
+
+        final Properties config = new Properties();
+        config.put("configKey", "configValue");
+
+        final CleanProcessor cp = new CleanProcessor(getClassPathEntries(), getTargetFolder(), config);
+        cp.clean();
+
+        Assert.assertFalse(new File(getTargetFolder(), TestBeanWithMethodAnnotation.class.getName().replace('.',
+            File.separatorChar)
+            + ".class").exists());
+        Assert.assertFalse(new File(getTargetFolder(), TestBeanWithClassAnnotation.class.getName().replace('.',
+            File.separatorChar)
+            + ".class").exists());
+    }
+}

Added: commons/sandbox/weaver/trunk/processor/src/test/java/org/apache/commons/weaver/test/weaver/TestCleaner.java
URL: http://svn.apache.org/viewvc/commons/sandbox/weaver/trunk/processor/src/test/java/org/apache/commons/weaver/test/weaver/TestCleaner.java?rev=1471730&view=auto
==============================================================================
--- commons/sandbox/weaver/trunk/processor/src/test/java/org/apache/commons/weaver/test/weaver/TestCleaner.java (added)
+++ commons/sandbox/weaver/trunk/processor/src/test/java/org/apache/commons/weaver/test/weaver/TestCleaner.java Wed Apr 24 22:12:48 2013
@@ -0,0 +1,73 @@
+/*
+ * 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.test.weaver;
+
+import java.io.File;
+import java.lang.annotation.ElementType;
+import java.util.List;
+import java.util.Properties;
+
+import org.apache.commons.weaver.model.ScanRequest;
+import org.apache.commons.weaver.model.ScanResult;
+import org.apache.commons.weaver.model.WeavableClass;
+import org.apache.commons.weaver.model.WeaveInterest;
+import org.apache.commons.weaver.spi.Cleaner;
+import org.apache.commons.weaver.test.beans.TestAnnotation;
+import org.junit.Assert;
+
+/**
+ */
+public class TestCleaner implements Cleaner {
+    private File target;
+
+    @Override
+    public void configure(List<String> classPath, File target, Properties config) {
+        Assert.assertNotNull(config);
+        Assert.assertEquals(1, config.size());
+
+        String configValue = (String) config.get("configKey");
+        Assert.assertEquals("configValue", configValue);
+
+        Assert.assertNotNull(target);
+        this.target = target;
+    }
+
+    @Override
+    public ScanRequest getScanRequest() {
+        return new ScanRequest().add(WeaveInterest.of(TestAnnotation.class, ElementType.TYPE)).add(
+            WeaveInterest.of(TestAnnotation.class, ElementType.METHOD));
+    }
+
+    @Override
+    public boolean clean(ScanResult scanResult) {
+        boolean result = false;
+        for (WeavableClass<?> weavableClass : scanResult.getClasses()) {
+
+            final File classFile =
+                new File(target, weavableClass.getTarget().getName().replace('.', File.separatorChar) + ".class");
+            if (classFile.delete()) {
+                result = true;
+            } else {
+                break;
+            }
+        }
+        return result;
+    }
+
+}

Added: commons/sandbox/weaver/trunk/processor/src/test/resources/META-INF/services/org.apache.commons.weaver.spi.Cleaner
URL: http://svn.apache.org/viewvc/commons/sandbox/weaver/trunk/processor/src/test/resources/META-INF/services/org.apache.commons.weaver.spi.Cleaner?rev=1471730&view=auto
==============================================================================
--- commons/sandbox/weaver/trunk/processor/src/test/resources/META-INF/services/org.apache.commons.weaver.spi.Cleaner (added)
+++ commons/sandbox/weaver/trunk/processor/src/test/resources/META-INF/services/org.apache.commons.weaver.spi.Cleaner Wed Apr 24 22:12:48 2013
@@ -0,0 +1,19 @@
+# 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.
+
+# this class gets picked up by the CleanProcessor
+org.apache.commons.weaver.test.weaver.TestCleaner