From 7e10f5b09f3b6bd6c326672f1c31598cdd665b43 Mon Sep 17 00:00:00 2001 From: Olivier Lamy Date: Fri, 4 May 2012 09:59:49 +0000 Subject: [PATCH] [MPLUGIN-189] commit some stuff on annotation scanning git-svn-id: https://svn.apache.org/repos/asf/maven/plugin-tools/branches/MPLUGIN-189@1333835 13f79535-47bb-0310-9956-ffa450edef68 --- maven-plugin-tools-annotations/pom.xml | 40 ++ ...avaAnnotationsMojoDescriptorExtractor.java | 61 ++ .../annotations/scanner/AnnotatedField.java | 52 ++ .../scanner/ComponentAnnotationContent.java | 84 +++ .../DefaultMojoAnnotationsScanner.java | 204 +++++++ .../scanner/MojoAnnotatedClass.java | 138 +++++ .../scanner/MojoAnnotationsScanner.java | 45 ++ .../MojoAnnotationsScannerRequest.java | 71 +++ .../annotations/scanner/MojoClassVisitor.java | 524 ++++++++++++++++++ .../scanner/ParameterAnnotationContent.java | 184 ++++++ .../resources/META-INF/plexus/components.xml | 42 ++ .../tools/plugin/annotations/FooMojo.java | 50 ++ .../annotations/TestAnnotationsReader.java | 78 +++ pom.xml | 8 +- 14 files changed, 1580 insertions(+), 1 deletion(-) create mode 100644 maven-plugin-tools-annotations/src/main/java/org/apache/maven/tools/plugin/annotations/JavaAnnotationsMojoDescriptorExtractor.java create mode 100644 maven-plugin-tools-annotations/src/main/java/org/apache/maven/tools/plugin/annotations/scanner/AnnotatedField.java create mode 100644 maven-plugin-tools-annotations/src/main/java/org/apache/maven/tools/plugin/annotations/scanner/ComponentAnnotationContent.java create mode 100644 maven-plugin-tools-annotations/src/main/java/org/apache/maven/tools/plugin/annotations/scanner/DefaultMojoAnnotationsScanner.java create mode 100644 maven-plugin-tools-annotations/src/main/java/org/apache/maven/tools/plugin/annotations/scanner/MojoAnnotatedClass.java create mode 100644 maven-plugin-tools-annotations/src/main/java/org/apache/maven/tools/plugin/annotations/scanner/MojoAnnotationsScanner.java create mode 100644 maven-plugin-tools-annotations/src/main/java/org/apache/maven/tools/plugin/annotations/scanner/MojoAnnotationsScannerRequest.java create mode 100644 maven-plugin-tools-annotations/src/main/java/org/apache/maven/tools/plugin/annotations/scanner/MojoClassVisitor.java create mode 100644 maven-plugin-tools-annotations/src/main/java/org/apache/maven/tools/plugin/annotations/scanner/ParameterAnnotationContent.java create mode 100644 maven-plugin-tools-annotations/src/main/resources/META-INF/plexus/components.xml create mode 100644 maven-plugin-tools-annotations/src/test/java/org/apache/maven/tools/plugin/annotations/FooMojo.java create mode 100644 maven-plugin-tools-annotations/src/test/java/org/apache/maven/tools/plugin/annotations/TestAnnotationsReader.java diff --git a/maven-plugin-tools-annotations/pom.xml b/maven-plugin-tools-annotations/pom.xml index e9575bc..56eb0f3 100644 --- a/maven-plugin-tools-annotations/pom.xml +++ b/maven-plugin-tools-annotations/pom.xml @@ -11,4 +11,44 @@ Maven Plugin Tools Annotations + + + + + org.apache.maven + maven-project + + + org.apache.maven + maven-model + + + org.apache.maven + maven-plugin-descriptor + + + org.apache.maven.plugin-tools + maven-plugin-tools-api + + + + org.codehaus.plexus + plexus-utils + + + org.codehaus.plexus + plexus-container-default + + + asm + asm + 3.3.1 + + + asm + asm-commons + 3.3.1 + + + diff --git a/maven-plugin-tools-annotations/src/main/java/org/apache/maven/tools/plugin/annotations/JavaAnnotationsMojoDescriptorExtractor.java b/maven-plugin-tools-annotations/src/main/java/org/apache/maven/tools/plugin/annotations/JavaAnnotationsMojoDescriptorExtractor.java new file mode 100644 index 0000000..9f1a05f --- /dev/null +++ b/maven-plugin-tools-annotations/src/main/java/org/apache/maven/tools/plugin/annotations/JavaAnnotationsMojoDescriptorExtractor.java @@ -0,0 +1,61 @@ +package org.apache.maven.tools.plugin.annotations; +/* + * 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. + */ + +import org.apache.maven.artifact.DependencyResolutionRequiredException; +import org.apache.maven.plugin.descriptor.InvalidPluginDescriptorException; +import org.apache.maven.plugin.descriptor.MojoDescriptor; +import org.apache.maven.plugin.descriptor.PluginDescriptor; +import org.apache.maven.project.MavenProject; +import org.apache.maven.tools.plugin.DefaultPluginToolsRequest; +import org.apache.maven.tools.plugin.PluginToolsRequest; +import org.apache.maven.tools.plugin.extractor.ExtractionException; +import org.apache.maven.tools.plugin.extractor.MojoDescriptorExtractor; +import org.codehaus.plexus.logging.AbstractLogEnabled; + +import java.util.List; + +/** + * @author Olivier Lamy + */ +public class JavaAnnotationsMojoDescriptorExtractor + extends AbstractLogEnabled + implements MojoDescriptorExtractor +{ + + public List execute( MavenProject project, PluginDescriptor pluginDescriptor ) + throws ExtractionException, InvalidPluginDescriptorException + { + return execute( new DefaultPluginToolsRequest( project, pluginDescriptor ) ); + } + + public List execute( PluginToolsRequest request ) + throws ExtractionException, InvalidPluginDescriptorException + { + try + { + List classpathElements = request.getProject().getCompileClasspathElements(); + return null; //To change body of implemented methods use File | Settings | File Templates. + } + catch ( DependencyResolutionRequiredException e ) + { + throw new ExtractionException( e.getMessage(), e ); + } + } +} diff --git a/maven-plugin-tools-annotations/src/main/java/org/apache/maven/tools/plugin/annotations/scanner/AnnotatedField.java b/maven-plugin-tools-annotations/src/main/java/org/apache/maven/tools/plugin/annotations/scanner/AnnotatedField.java new file mode 100644 index 0000000..7bf891a --- /dev/null +++ b/maven-plugin-tools-annotations/src/main/java/org/apache/maven/tools/plugin/annotations/scanner/AnnotatedField.java @@ -0,0 +1,52 @@ +package org.apache.maven.tools.plugin.annotations.scanner; +/* + * 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. + */ + +/** + * @author Olivier Lamy + */ +public class AnnotatedField +{ + private String fieldName; + + public AnnotatedField( String fieldName ) + { + this.fieldName = fieldName; + } + + public String getFieldName() + { + return fieldName; + } + + public void setFieldName( String name ) + { + this.fieldName = name; + } + + @Override + public String toString() + { + final StringBuilder sb = new StringBuilder(); + sb.append( "AnnotatedField" ); + sb.append( "{fieldName='" ).append( fieldName ).append( '\'' ); + sb.append( '}' ); + return sb.toString(); + } +} diff --git a/maven-plugin-tools-annotations/src/main/java/org/apache/maven/tools/plugin/annotations/scanner/ComponentAnnotationContent.java b/maven-plugin-tools-annotations/src/main/java/org/apache/maven/tools/plugin/annotations/scanner/ComponentAnnotationContent.java new file mode 100644 index 0000000..60e3f72 --- /dev/null +++ b/maven-plugin-tools-annotations/src/main/java/org/apache/maven/tools/plugin/annotations/scanner/ComponentAnnotationContent.java @@ -0,0 +1,84 @@ +package org.apache.maven.tools.plugin.annotations.scanner; +/* + * 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. + */ + +import org.apache.maven.tools.plugin.annotations.Component; + +import java.lang.annotation.Annotation; + +/** + * @author Olivier Lamy + */ +public class ComponentAnnotationContent + extends AnnotatedField + implements Component +{ + private String role; + + private String roleHint; + + public ComponentAnnotationContent( String fieldName ) + { + super( fieldName ); + } + + public ComponentAnnotationContent( String fieldName, String role, String roleHint ) + { + this( fieldName ); + this.role = role; + this.roleHint = roleHint; + } + + public String role() + { + return role; + } + + public void role( String role ) + { + this.role = role; + } + + public String roleHint() + { + return roleHint; + } + + public void roleHint( String roleHint ) + { + this.roleHint = roleHint; + } + + public Class annotationType() + { + return null; + } + + @Override + public String toString() + { + final StringBuilder sb = new StringBuilder(); + sb.append( super.toString() ); + sb.append( "ComponentAnnotationContent" ); + sb.append( "{role='" ).append( role ).append( '\'' ); + sb.append( ", roleHint='" ).append( roleHint ).append( '\'' ); + sb.append( '}' ); + return sb.toString(); + } +} diff --git a/maven-plugin-tools-annotations/src/main/java/org/apache/maven/tools/plugin/annotations/scanner/DefaultMojoAnnotationsScanner.java b/maven-plugin-tools-annotations/src/main/java/org/apache/maven/tools/plugin/annotations/scanner/DefaultMojoAnnotationsScanner.java new file mode 100644 index 0000000..cbe9b88 --- /dev/null +++ b/maven-plugin-tools-annotations/src/main/java/org/apache/maven/tools/plugin/annotations/scanner/DefaultMojoAnnotationsScanner.java @@ -0,0 +1,204 @@ +package org.apache.maven.tools.plugin.annotations.scanner; +/* + * 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. + */ + +import org.apache.maven.tools.plugin.annotations.Component; +import org.apache.maven.tools.plugin.annotations.Execute; +import org.apache.maven.tools.plugin.annotations.Mojo; +import org.apache.maven.tools.plugin.annotations.Parameter; +import org.apache.maven.tools.plugin.extractor.ExtractionException; +import org.codehaus.plexus.logging.AbstractLogEnabled; +import org.codehaus.plexus.util.DirectoryScanner; +import org.codehaus.plexus.util.IOUtil; +import org.codehaus.plexus.util.reflection.Reflector; +import org.objectweb.asm.ClassReader; + +import java.io.BufferedInputStream; +import java.io.File; +import java.io.FileInputStream; +import java.io.IOException; +import java.io.InputStream; +import java.util.ArrayList; +import java.util.List; +import java.util.Map; + +/** + * @author Olivier Lamy + */ +public class DefaultMojoAnnotationsScanner + extends AbstractLogEnabled + implements MojoAnnotationsScanner +{ + private Reflector reflector = new Reflector(); + + public List scan( MojoAnnotationsScannerRequest request ) + throws ExtractionException + { + List mojoAnnotatedClasses = new ArrayList(); + try + { + for ( File classDirectory : request.getClassesDirectories() ) + { + mojoAnnotatedClasses.addAll( scanDirectory( classDirectory, request.getIncludePatterns() ) ); + } + return mojoAnnotatedClasses; + } + catch ( IOException e ) + { + throw new ExtractionException( e.getMessage(), e ); + } + } + + protected List scanDirectory( File classDirectory, List includePatterns ) + throws IOException, ExtractionException + { + List mojoAnnotatedClasses = new ArrayList(); + DirectoryScanner scanner = new DirectoryScanner(); + scanner.setBasedir( classDirectory ); + scanner.addDefaultExcludes(); + if ( includePatterns != null ) + { + scanner.setIncludes( includePatterns.toArray( new String[includePatterns.size()] ) ); + } + scanner.scan(); + String[] classFiles = scanner.getIncludedFiles(); + + for ( String classFile : classFiles ) + { + InputStream is = new BufferedInputStream( new FileInputStream( new File( classDirectory, classFile ) ) ); + try + { + + if ( classFile.endsWith( ".class" ) ) + { + MojoClassVisitor mojoClassVisitor = new MojoClassVisitor( getLogger() ); + ClassReader rdr = new ClassReader( is ); + rdr.accept( mojoClassVisitor, + ClassReader.SKIP_FRAMES | ClassReader.SKIP_CODE | ClassReader.SKIP_DEBUG ); + analyzeVisitors( mojoClassVisitor ); + if ( isMojoAnnnotatedClassCandidate( mojoClassVisitor.getMojoAnnotatedClass() ) != null ) + { + mojoAnnotatedClasses.add( mojoClassVisitor.getMojoAnnotatedClass() ); + } + + } + } + finally + { + IOUtil.close( is ); + } + + } + return mojoAnnotatedClasses; + } + + private MojoAnnotatedClass isMojoAnnnotatedClassCandidate( MojoAnnotatedClass mojoAnnotatedClass ) + { + if ( mojoAnnotatedClass == null ) + { + return null; + } + if ( !mojoAnnotatedClass.getComponents().isEmpty() || !mojoAnnotatedClass.getParameters().isEmpty() + || mojoAnnotatedClass.getExecute() != null || mojoAnnotatedClass.getMojo() != null ) + { + return mojoAnnotatedClass; + } + return null; + } + + protected void analyzeVisitors( MojoClassVisitor mojoClassVisitor ) + throws ExtractionException + { + + try + { + MojoClassVisitor.MojoAnnotationVisitor mojoAnnotationVisitor = + mojoClassVisitor.getAnnotationVisitorMap().get( Mojo.class.getName() ); + if ( mojoAnnotationVisitor != null ) + { + MojoClassVisitor.MojoAnnotationContent mojoAnnotationContent = + new MojoClassVisitor.MojoAnnotationContent(); + Class clazz = Thread.currentThread().getContextClassLoader().loadClass( + MojoClassVisitor.MojoAnnotationContent.class.getName() ); + for ( Map.Entry entry : mojoAnnotationVisitor.getAnnotationValues().entrySet() ) + { + reflector.invoke( mojoAnnotationContent, entry.getKey(), new Object[]{ entry.getValue() } ); + } + mojoClassVisitor.getMojoAnnotatedClass().setMojo( mojoAnnotationContent ); + } + + mojoAnnotationVisitor = mojoClassVisitor.getAnnotationVisitorMap().get( Execute.class.getName() ); + if ( mojoAnnotationVisitor != null ) + { + MojoClassVisitor.ExecuteAnnotationContent executeAnnotationContent = + new MojoClassVisitor.ExecuteAnnotationContent(); + Class clazz = Thread.currentThread().getContextClassLoader().loadClass( + MojoClassVisitor.MojoAnnotationContent.class.getName() ); + for ( Map.Entry entry : mojoAnnotationVisitor.getAnnotationValues().entrySet() ) + { + reflector.invoke( executeAnnotationContent, entry.getKey(), new Object[]{ entry.getValue() } ); + } + mojoClassVisitor.getMojoAnnotatedClass().setExecute( executeAnnotationContent ); + } + + List mojoFieldVisitors = + mojoClassVisitor.findFieldWithAnnotationClass( Parameter.class.getName() ); + + for ( MojoClassVisitor.MojoFieldVisitor mojoFieldVisitor : mojoFieldVisitors ) + { + ParameterAnnotationContent parameterAnnotationContent = + new ParameterAnnotationContent( mojoFieldVisitor.getFieldName() ); + if ( mojoFieldVisitor.getMojoAnnotationVisitor() != null ) + { + for ( Map.Entry entry : mojoFieldVisitor.getMojoAnnotationVisitor().getAnnotationValues().entrySet() ) + { + reflector.invoke( parameterAnnotationContent, entry.getKey(), + new Object[]{ entry.getValue() } ); + } + + } + mojoClassVisitor.getMojoAnnotatedClass().getParameters().add( parameterAnnotationContent ); + } + + mojoFieldVisitors = mojoClassVisitor.findFieldWithAnnotationClass( Component.class.getName() ); + + for ( MojoClassVisitor.MojoFieldVisitor mojoFieldVisitor : mojoFieldVisitors ) + { + ComponentAnnotationContent componentAnnotationContent = + new ComponentAnnotationContent( mojoFieldVisitor.getFieldName() ); + + if ( mojoFieldVisitor.getMojoAnnotationVisitor() != null ) + { + for ( Map.Entry entry : mojoFieldVisitor.getMojoAnnotationVisitor().getAnnotationValues().entrySet() ) + { + reflector.invoke( componentAnnotationContent, entry.getKey(), + new Object[]{ entry.getValue() } ); + } + + } + mojoClassVisitor.getMojoAnnotatedClass().getComponents().add( componentAnnotationContent ); + } + + } + catch ( Exception e ) + { + throw new ExtractionException( e.getMessage(), e ); + } + } +} diff --git a/maven-plugin-tools-annotations/src/main/java/org/apache/maven/tools/plugin/annotations/scanner/MojoAnnotatedClass.java b/maven-plugin-tools-annotations/src/main/java/org/apache/maven/tools/plugin/annotations/scanner/MojoAnnotatedClass.java new file mode 100644 index 0000000..2721c18 --- /dev/null +++ b/maven-plugin-tools-annotations/src/main/java/org/apache/maven/tools/plugin/annotations/scanner/MojoAnnotatedClass.java @@ -0,0 +1,138 @@ +package org.apache.maven.tools.plugin.annotations.scanner; +/* + * 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. + */ + +import org.apache.maven.tools.plugin.annotations.Execute; +import org.apache.maven.tools.plugin.annotations.Mojo; + +import java.util.ArrayList; +import java.util.List; + +/** + * @author Olivier Lamy + */ +public class MojoAnnotatedClass +{ + private String className; + + private String parentClassName; + + private Mojo mojo; + + private Execute execute; + + private List parameters; + + private List components; + + public MojoAnnotatedClass() + { + // no op + } + + public String getClassName() + { + return className; + } + + public MojoAnnotatedClass setClassName( String className ) + { + this.className = className; + return this; + } + + public Mojo getMojo() + { + return mojo; + } + + public MojoAnnotatedClass setMojo( Mojo mojo ) + { + this.mojo = mojo; + return this; + } + + public Execute getExecute() + { + return execute; + } + + public MojoAnnotatedClass setExecute( Execute execute ) + { + this.execute = execute; + return this; + } + + public List getParameters() + { + if ( this.parameters == null ) + { + this.parameters = new ArrayList(); + } + return parameters; + } + + public MojoAnnotatedClass setParameters( List parameters ) + { + this.parameters = parameters; + return this; + } + + public List getComponents() + { + if ( this.components == null ) + { + this.components = new ArrayList(); + } + return components; + } + + public MojoAnnotatedClass setComponents( List components ) + { + this.components = components; + return this; + } + + public String getParentClassName() + { + return parentClassName; + } + + public MojoAnnotatedClass setParentClassName( String parentClassName ) + { + this.parentClassName = parentClassName; + return this; + } + + + @Override + public String toString() + { + final StringBuilder sb = new StringBuilder(); + sb.append( "MojoAnnotatedClass" ); + sb.append( "{className='" ).append( className ).append( '\'' ); + sb.append( ", parentClassName='" ).append( parentClassName ).append( '\'' ); + sb.append( ", mojo=" ).append( mojo ); + sb.append( ", execute=" ).append( execute ); + sb.append( ", parameters=" ).append( parameters ); + sb.append( ", components=" ).append( components ); + sb.append( '}' ); + return sb.toString(); + } +} diff --git a/maven-plugin-tools-annotations/src/main/java/org/apache/maven/tools/plugin/annotations/scanner/MojoAnnotationsScanner.java b/maven-plugin-tools-annotations/src/main/java/org/apache/maven/tools/plugin/annotations/scanner/MojoAnnotationsScanner.java new file mode 100644 index 0000000..9a0a4b0 --- /dev/null +++ b/maven-plugin-tools-annotations/src/main/java/org/apache/maven/tools/plugin/annotations/scanner/MojoAnnotationsScanner.java @@ -0,0 +1,45 @@ +package org.apache.maven.tools.plugin.annotations.scanner; +/* + * 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. + */ + +import org.apache.maven.tools.plugin.annotations.Component; +import org.apache.maven.tools.plugin.annotations.Execute; +import org.apache.maven.tools.plugin.annotations.Mojo; +import org.apache.maven.tools.plugin.annotations.Parameter; +import org.apache.maven.tools.plugin.extractor.ExtractionException; + +import java.util.Arrays; +import java.util.List; + +/** + * @author Olivier Lamy + */ +public interface MojoAnnotationsScanner +{ + String ROLE = MojoAnnotationsScanner.class.getName(); + + static final List acceptedClassLevelAnnotationClasses = + Arrays.asList( Mojo.class.getName(), Execute.class.getName() ); + + static final List acceptedFieldLevelAnnotationClasses = + Arrays.asList( Parameter.class.getName(), Component.class.getName() ); + + List scan( MojoAnnotationsScannerRequest request ) + throws ExtractionException; +} diff --git a/maven-plugin-tools-annotations/src/main/java/org/apache/maven/tools/plugin/annotations/scanner/MojoAnnotationsScannerRequest.java b/maven-plugin-tools-annotations/src/main/java/org/apache/maven/tools/plugin/annotations/scanner/MojoAnnotationsScannerRequest.java new file mode 100644 index 0000000..7534b88 --- /dev/null +++ b/maven-plugin-tools-annotations/src/main/java/org/apache/maven/tools/plugin/annotations/scanner/MojoAnnotationsScannerRequest.java @@ -0,0 +1,71 @@ +package org.apache.maven.tools.plugin.annotations.scanner; +/* + * 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. + */ + +import java.io.File; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; + +/** + * @author Olivier Lamy + */ +public class MojoAnnotationsScannerRequest +{ + private List classesDirectories = new ArrayList(); + + private List dependencies = new ArrayList(); + + private List includePatterns = Arrays.asList( "**/*.class" ); + + public MojoAnnotationsScannerRequest() + { + // no o + } + + public List getClassesDirectories() + { + return classesDirectories; + } + + public void setClassesDirectories( List classesDirectories ) + { + this.classesDirectories = classesDirectories; + } + + public List getDependencies() + { + return dependencies; + } + + public void setDependencies( List dependencies ) + { + this.dependencies = dependencies; + } + + public List getIncludePatterns() + { + return includePatterns; + } + + public void setIncludePatterns( List includePatterns ) + { + this.includePatterns = includePatterns; + } +} diff --git a/maven-plugin-tools-annotations/src/main/java/org/apache/maven/tools/plugin/annotations/scanner/MojoClassVisitor.java b/maven-plugin-tools-annotations/src/main/java/org/apache/maven/tools/plugin/annotations/scanner/MojoClassVisitor.java new file mode 100644 index 0000000..53e9cac --- /dev/null +++ b/maven-plugin-tools-annotations/src/main/java/org/apache/maven/tools/plugin/annotations/scanner/MojoClassVisitor.java @@ -0,0 +1,524 @@ +package org.apache.maven.tools.plugin.annotations.scanner; +/* + * 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. + */ + +import org.apache.maven.tools.plugin.annotations.Execute; +import org.apache.maven.tools.plugin.annotations.LifecyclePhase; +import org.apache.maven.tools.plugin.annotations.Mojo; +import org.codehaus.plexus.logging.Logger; +import org.codehaus.plexus.util.StringUtils; +import org.objectweb.asm.AnnotationVisitor; +import org.objectweb.asm.Attribute; +import org.objectweb.asm.ClassVisitor; +import org.objectweb.asm.FieldVisitor; +import org.objectweb.asm.MethodVisitor; +import org.objectweb.asm.Type; + +import java.lang.annotation.Annotation; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +/** + * @author Olivier Lamy + */ +public class MojoClassVisitor + implements ClassVisitor +{ + private Logger logger; + + private MojoAnnotatedClass mojoAnnotatedClass; + + private Map annotationVisitorMap = new HashMap(); + + private List fieldVisitors = new ArrayList(); + + public MojoClassVisitor( Logger logger ) + { + this.logger = logger; + } + + public MojoAnnotatedClass getMojoAnnotatedClass() + { + return mojoAnnotatedClass; + } + + public void setMojoAnnotatedClass( MojoAnnotatedClass mojoAnnotatedClass ) + { + this.mojoAnnotatedClass = mojoAnnotatedClass; + } + + public Map getAnnotationVisitorMap() + { + return annotationVisitorMap; + } + + public void setAnnotationVisitorMap( Map annotationVisitorMap ) + { + this.annotationVisitorMap = annotationVisitorMap; + } + + public List getFieldVisitors() + { + return fieldVisitors; + } + + public void setFieldVisitors( List fieldVisitors ) + { + this.fieldVisitors = fieldVisitors; + } + + public List findFieldWithAnnotationClass( String annotationClassName ) + { + List mojoFieldVisitors = new ArrayList(); + + for ( MojoFieldVisitor mojoFieldVisitor : this.fieldVisitors ) + { + MojoAnnotationVisitor mojoAnnotationVisitor = mojoFieldVisitor.getMojoAnnotationVisitor(); + if ( mojoAnnotationVisitor != null && StringUtils.equals( annotationClassName, + mojoAnnotationVisitor.annotationClassName ) ) + { + mojoFieldVisitors.add( mojoFieldVisitor ); + } + } + + return mojoFieldVisitors; + } + + public void visit( int version, int access, String name, String signature, String superName, String[] interfaces ) + { + mojoAnnotatedClass = new MojoAnnotatedClass(); + mojoAnnotatedClass.setClassName( Type.getObjectType( name ).getClassName() ).setParentClassName( + Type.getObjectType( superName ).getClassName() ); + logger.debug( "MojoClassVisitor#visit" ); + } + + public AnnotationVisitor visitAnnotation( String desc, boolean visible ) + { + logger.debug( "MojoClassVisitor#visitAnnotation" ); + String annotationClassName = Type.getType( desc ).getClassName(); + if ( !MojoAnnotationsScanner.acceptedClassLevelAnnotationClasses.contains( annotationClassName ) ) + { + return null; + } + MojoAnnotationVisitor mojoAnnotationVisitor = new MojoAnnotationVisitor( logger, annotationClassName ); + annotationVisitorMap.put( annotationClassName, mojoAnnotationVisitor ); + return mojoAnnotationVisitor; + } + + public FieldVisitor visitField( int access, String name, String desc, String signature, Object value ) + { + // Type.getType( desc ).getClassName() + logger.debug( "MojoClassVisitor#visitField" ); + MojoFieldVisitor mojoFieldVisitor = new MojoFieldVisitor( logger, name ); + fieldVisitors.add( mojoFieldVisitor ); + return mojoFieldVisitor; + } + + public MethodVisitor visitMethod( int access, String name, String desc, String signature, String[] exceptions ) + { + // we don't need methods informations + return null; + } + + public void visitAttribute( Attribute attr ) + { + } + + public void visitSource( String source, String debug ) + { + } + + public void visitOuterClass( String owner, String name, String desc ) + { + } + + public void visitInnerClass( String name, String outerName, String innerName, int access ) + { + } + + public void visitEnd() + { + logger.debug( "MojoClassVisitor#visitEnd" ); + } + + public static class MojoAnnotationContent + implements Mojo + { + + private String name; + + private LifecyclePhase defaultPhase = LifecyclePhase.NONE; + + private String requiresDependencyResolution = "runtime"; + + private String requiresDependencyCollection = "runtime"; + + private String instantiationStrategy = "per-lookup"; + + private String executionStrategy = "once-per-session"; + + private boolean requiresProject = true; + + private boolean requiresReports = false; + + private boolean aggregator = false; + + private boolean requiresDirectInvocation = false; + + private boolean requiresOnline = false; + + private boolean inheritByDefault = true; + + private String configurator; + + private boolean threadSafe = false; + + public Class annotationType() + { + return null; + } + + public LifecyclePhase defaultPhase() + { + return defaultPhase; + } + + public void defaultPhase( String phase ) + { + this.defaultPhase = LifecyclePhase.valueOf( phase ); + } + + public String requiresDependencyResolution() + { + return requiresDependencyResolution; + } + + public void requiresDependencyResolution( String requiresDependencyResolution ) + { + this.requiresDependencyResolution = requiresDependencyResolution; + } + + public String requiresDependencyCollection() + { + return requiresDependencyCollection; + } + + public void requiresDependencyCollection( String requiresDependencyCollection ) + { + this.requiresDependencyCollection = requiresDependencyCollection; + } + + public String instantiationStrategy() + { + return instantiationStrategy; + } + + public void instantiationStrategy( String instantiationStrategy ) + { + this.instantiationStrategy = instantiationStrategy; + } + + public String executionStrategy() + { + return executionStrategy; + } + + public void executionStrategy( String executionStrategy ) + { + this.executionStrategy = executionStrategy; + } + + public boolean requiresProject() + { + return requiresProject; + } + + public void requiresProject( boolean requiresProject ) + { + this.requiresProject = requiresProject; + } + + public boolean requiresReports() + { + return requiresReports; + } + + public void requiresReports( boolean requiresReports ) + { + this.requiresReports = requiresReports; + } + + public boolean aggregator() + { + return aggregator; + } + + public void aggregator( boolean aggregator ) + { + this.aggregator = aggregator; + } + + public boolean requiresDirectInvocation() + { + return requiresDirectInvocation; + } + + public void requiresDirectInvocation( boolean requiresDirectInvocation ) + { + this.requiresDirectInvocation = requiresDirectInvocation; + } + + public boolean requiresOnline() + { + return requiresOnline; + } + + public void requiresOnline( boolean requiresOnline ) + { + this.requiresOnline = requiresOnline; + } + + public boolean inheritByDefault() + { + return inheritByDefault; + } + + public void inheritByDefault( boolean inheritByDefault ) + { + this.inheritByDefault = inheritByDefault; + } + + public String configurator() + { + return configurator; + } + + public void configurator( String configurator ) + { + this.configurator = configurator; + } + + public boolean threadSafe() + { + return threadSafe; + } + + public void threadSafe( boolean threadSafe ) + { + this.threadSafe = threadSafe; + } + + public String name() + { + return this.name; + } + + public void name( String name ) + { + this.name = name; + } + + @Override + public String toString() + { + final StringBuilder sb = new StringBuilder(); + sb.append( "MojoAnnotationContent" ); + sb.append( "{name='" ).append( name ).append( '\'' ); + sb.append( ", defaultPhase=" ).append( defaultPhase ); + sb.append( ", requiresDependencyResolution='" ).append( requiresDependencyResolution ).append( '\'' ); + sb.append( ", requiresDependencyCollection='" ).append( requiresDependencyCollection ).append( '\'' ); + sb.append( ", instantiationStrategy='" ).append( instantiationStrategy ).append( '\'' ); + sb.append( ", executionStrategy='" ).append( executionStrategy ).append( '\'' ); + sb.append( ", requiresProject=" ).append( requiresProject ); + sb.append( ", requiresReports=" ).append( requiresReports ); + sb.append( ", aggregator=" ).append( aggregator ); + sb.append( ", requiresDirectInvocation=" ).append( requiresDirectInvocation ); + sb.append( ", requiresOnline=" ).append( requiresOnline ); + sb.append( ", inheritByDefault=" ).append( inheritByDefault ); + sb.append( ", configurator='" ).append( configurator ).append( '\'' ); + sb.append( ", threadSafe=" ).append( threadSafe ); + sb.append( '}' ); + return sb.toString(); + } + } + + public static class ExecuteAnnotationContent + implements Execute + { + + private String goal; + + private String lifecycle; + + private LifecyclePhase phase; + + public LifecyclePhase phase() + { + return this.phase; + } + + public String goal() + { + return this.goal; + } + + public String lifecycle() + { + return this.lifecycle; + } + + + public void phase( String phase ) + { + this.phase = LifecyclePhase.valueOf( phase ); + } + + public void goal( String goal ) + { + this.goal = goal; + } + + public void lifecycle( String lifecycle ) + { + this.lifecycle = lifecycle; + } + + + public Class annotationType() + { + return null; + } + + @Override + public String toString() + { + final StringBuilder sb = new StringBuilder(); + sb.append( "ExecuteAnnotationContent" ); + sb.append( "{goal='" ).append( goal ).append( '\'' ); + sb.append( ", lifecycle='" ).append( lifecycle ).append( '\'' ); + sb.append( ", phase=" ).append( phase ); + sb.append( '}' ); + return sb.toString(); + } + } + + //------------------------------------- + // internal classes + //------------------------------------- + static class MojoAnnotationVisitor + implements AnnotationVisitor + { + + private Logger logger; + + private String annotationClassName; + + private Map annotationValues = new HashMap(); + + MojoAnnotationVisitor( Logger logger, String annotationClassName ) + { + this.logger = logger; + this.annotationClassName = annotationClassName; + } + + public Map getAnnotationValues() + { + return annotationValues; + } + + public void visit( String name, Object value ) + { + annotationValues.put( name, value ); + logger.debug( "MojoAnnotationVisitor#visit:" + name + ":" + value ); + } + + public void visitEnum( String name, String desc, String value ) + { + annotationValues.put( name, value ); + logger.debug( "MojoAnnotationVisitor#visitEnum:" + name + ":" + desc + ":" + value ); + } + + public AnnotationVisitor visitAnnotation( String name, String desc ) + { + logger.debug( "MojoAnnotationVisitor#visitAnnotation:" + name + ":" + desc ); + return new MojoAnnotationVisitor( logger, this.annotationClassName ); + } + + public AnnotationVisitor visitArray( String s ) + { + logger.debug( "MojoAnnotationVisitor#visitArray" ); + return new MojoAnnotationVisitor( logger, this.annotationClassName ); + } + + public void visitEnd() + { + logger.debug( "MojoAnnotationVisitor#visitEnd" ); + } + } + + static class MojoFieldVisitor + implements FieldVisitor + { + private Logger logger; + + private String fieldName; + + private MojoAnnotationVisitor mojoAnnotationVisitor; + + MojoFieldVisitor( Logger logger, String fieldName ) + { + this.logger = logger; + this.fieldName = fieldName; + } + + public MojoAnnotationVisitor getMojoAnnotationVisitor() + { + return mojoAnnotationVisitor; + } + + public String getFieldName() + { + return fieldName; + } + + public AnnotationVisitor visitAnnotation( String desc, boolean visible ) + { + logger.debug( "MojoFieldVisitor#visitAnnotation:" + desc ); + String annotationClassName = Type.getType( desc ).getClassName(); + if ( !MojoAnnotationsScanner.acceptedFieldLevelAnnotationClasses.contains( annotationClassName ) ) + { + return null; + } + mojoAnnotationVisitor = new MojoAnnotationVisitor( logger, annotationClassName ); + return mojoAnnotationVisitor; + } + + public void visitAttribute( Attribute attribute ) + { + logger.debug( "MojoFieldVisitor#visitAttribute" ); + } + + public void visitEnd() + { + logger.debug( "MojoFieldVisitor#visitEnd" ); + } + } +} diff --git a/maven-plugin-tools-annotations/src/main/java/org/apache/maven/tools/plugin/annotations/scanner/ParameterAnnotationContent.java b/maven-plugin-tools-annotations/src/main/java/org/apache/maven/tools/plugin/annotations/scanner/ParameterAnnotationContent.java new file mode 100644 index 0000000..bf20605 --- /dev/null +++ b/maven-plugin-tools-annotations/src/main/java/org/apache/maven/tools/plugin/annotations/scanner/ParameterAnnotationContent.java @@ -0,0 +1,184 @@ +package org.apache.maven.tools.plugin.annotations.scanner; +/* + * 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. + */ + +import org.apache.maven.tools.plugin.annotations.Parameter; + +import java.lang.annotation.Annotation; + +/** + * @author Olivier Lamy + */ +public class ParameterAnnotationContent + extends AnnotatedField + implements Parameter +{ + + private String alias; + + private String expression; + + private String defaultValue; + + private boolean required = false; + + private boolean readonly = false; + + public ParameterAnnotationContent( String fieldName ) + { + super( fieldName ); + } + + public ParameterAnnotationContent( String fieldName, String alias, String expression, String defaultValue, + boolean required, boolean readonly ) + { + this( fieldName ); + this.alias = alias; + this.expression = expression; + this.defaultValue = defaultValue; + this.required = required; + this.readonly = readonly; + } + + public String alias() + { + return alias; + } + + public void alias( String alias ) + { + this.alias = alias; + } + + public String expression() + { + return expression; + } + + public void expression( String expression ) + { + this.expression = expression; + } + + public String defaultValue() + { + return defaultValue; + } + + public void defaultValue( String defaultValue ) + { + this.defaultValue = defaultValue; + } + + public boolean required() + { + return required; + } + + public void required( boolean required ) + { + this.required = required; + } + + public boolean readonly() + { + return readonly; + } + + public void readonly( boolean readonly ) + { + this.readonly = readonly; + } + + public Class annotationType() + { + return null; + } + + @Override + public String toString() + { + final StringBuilder sb = new StringBuilder(); + sb.append( super.toString() ); + sb.append( "ParameterAnnotationContent" ); + sb.append( "{alias='" ).append( alias ).append( '\'' ); + sb.append( ", expression='" ).append( expression ).append( '\'' ); + sb.append( ", defaultValue='" ).append( defaultValue ).append( '\'' ); + sb.append( ", required=" ).append( required ); + sb.append( ", readonly=" ).append( readonly ); + sb.append( '}' ); + return sb.toString(); + } + + @Override + public boolean equals( Object o ) + { + if ( this == o ) + { + return true; + } + if ( !( o instanceof ParameterAnnotationContent ) ) + { + return false; + } + + ParameterAnnotationContent that = (ParameterAnnotationContent) o; + + if ( readonly != that.readonly ) + { + return false; + } + if ( required != that.required ) + { + return false; + } + + if ( getFieldName() != null ? !getFieldName().equals( that.getFieldName() ) : that.getFieldName() != null ) + { + return false; + } + + if ( alias != null ? !alias.equals( that.alias ) : that.alias != null ) + { + return false; + } + if ( defaultValue != null ? !defaultValue.equals( that.defaultValue ) : that.defaultValue != null ) + { + return false; + } + if ( expression != null ? !expression.equals( that.expression ) : that.expression != null ) + { + return false; + } + + return true; + } + + @Override + public int hashCode() + { + int result = alias != null ? alias.hashCode() : 0; + result = 31 * result + ( getFieldName() != null ? getFieldName().hashCode() : 0 ); + result = 31 * result + ( expression != null ? expression.hashCode() : 0 ); + result = 31 * result + ( defaultValue != null ? defaultValue.hashCode() : 0 ); + result = 31 * result + ( required ? 1 : 0 ); + result = 31 * result + ( readonly ? 1 : 0 ); + return result; + } +} diff --git a/maven-plugin-tools-annotations/src/main/resources/META-INF/plexus/components.xml b/maven-plugin-tools-annotations/src/main/resources/META-INF/plexus/components.xml new file mode 100644 index 0000000..d7b2dbe --- /dev/null +++ b/maven-plugin-tools-annotations/src/main/resources/META-INF/plexus/components.xml @@ -0,0 +1,42 @@ + + + + + + + + org.apache.maven.tools.plugin.extractor.MojoDescriptorExtractor + java-annotations + org.apache.maven.tools.plugin.annotations.JavaAnnotationsMojoDescriptorExtractor + + + + org.apache.maven.tools.plugin.annotations.scanner.MojoAnnotationsScanner + default + org.apache.maven.tools.plugin.annotations.scanner.DefaultMojoAnnotationsScanner + + + + \ No newline at end of file diff --git a/maven-plugin-tools-annotations/src/test/java/org/apache/maven/tools/plugin/annotations/FooMojo.java b/maven-plugin-tools-annotations/src/test/java/org/apache/maven/tools/plugin/annotations/FooMojo.java new file mode 100644 index 0000000..9bf0d8e --- /dev/null +++ b/maven-plugin-tools-annotations/src/test/java/org/apache/maven/tools/plugin/annotations/FooMojo.java @@ -0,0 +1,50 @@ +package org.apache.maven.tools.plugin.annotations; +/* + * 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. + */ + +import org.apache.maven.plugin.AbstractMojo; +import org.apache.maven.plugin.MojoExecutionException; +import org.apache.maven.plugin.MojoFailureException; + +/** + * @author Olivier Lamy + */ +@Mojo( name = "foo", defaultPhase = LifecyclePhase.COMPILE, threadSafe = true ) +@Execute( goal = "compiler", lifecycle = "my-lifecycle", phase = LifecyclePhase.PACKAGE ) +public class FooMojo + extends AbstractMojo +{ + @Parameter( expression = "${thebar}" ) + private String bar; + + @Parameter( expression = "${thebeer}" ) + private String beer; + + @Component( role = "wine", roleHint = "bordeaux" ) + private Mojo wine; + + @Component( role = "wine", roleHint = "foo" ) + private Mojo foo; + + public void execute() + throws MojoExecutionException, MojoFailureException + { + // nothing + } +} diff --git a/maven-plugin-tools-annotations/src/test/java/org/apache/maven/tools/plugin/annotations/TestAnnotationsReader.java b/maven-plugin-tools-annotations/src/test/java/org/apache/maven/tools/plugin/annotations/TestAnnotationsReader.java new file mode 100644 index 0000000..586ba5f --- /dev/null +++ b/maven-plugin-tools-annotations/src/test/java/org/apache/maven/tools/plugin/annotations/TestAnnotationsReader.java @@ -0,0 +1,78 @@ +package org.apache.maven.tools.plugin.annotations; +/* + * 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. + */ + +import org.apache.maven.tools.plugin.annotations.scanner.ComponentAnnotationContent; +import org.apache.maven.tools.plugin.annotations.scanner.MojoAnnotatedClass; +import org.apache.maven.tools.plugin.annotations.scanner.MojoAnnotationsScanner; +import org.apache.maven.tools.plugin.annotations.scanner.MojoAnnotationsScannerRequest; +import org.apache.maven.tools.plugin.annotations.scanner.ParameterAnnotationContent; +import org.codehaus.plexus.PlexusTestCase; +import org.fest.assertions.Assertions; + +import java.io.File; +import java.util.Arrays; +import java.util.Collections; +import java.util.List; + +/** + * @author Olivier Lamy + */ +public class TestAnnotationsReader + extends PlexusTestCase +{ + public void testReadMojoClass() + throws Exception + { + MojoAnnotationsScanner mojoAnnotationsScanner = (MojoAnnotationsScanner) lookup( MojoAnnotationsScanner.ROLE ); + + MojoAnnotationsScannerRequest request = new MojoAnnotationsScannerRequest(); + request.setClassesDirectories( Collections.singletonList( new File( "target/test-classes" ) ) ); + request.setIncludePatterns( Arrays.asList( "**/FooMojo.class" ) ); + + List mojoAnnotatedClasses = mojoAnnotationsScanner.scan( request ); + + System.out.println( "mojoAnnotatedClasses:" + mojoAnnotatedClasses ); + + Assertions.assertThat( mojoAnnotatedClasses ).isNotNull().isNotEmpty().hasSize( 1 ); + + MojoAnnotatedClass mojoAnnotatedClass = mojoAnnotatedClasses.get( 0 ); + + Mojo mojo = mojoAnnotatedClass.getMojo(); + + assertEquals( "foo", mojo.name() ); + assertEquals( true, mojo.threadSafe() ); + assertEquals( false, mojo.aggregator() ); + assertEquals( LifecyclePhase.COMPILE, mojo.defaultPhase() ); + + Execute execute = mojoAnnotatedClass.getExecute(); + + assertEquals( "compiler", execute.goal() ); + assertEquals( "my-lifecycle", execute.lifecycle() ); + assertEquals( LifecyclePhase.PACKAGE, execute.phase() ); + + List components = mojoAnnotatedClass.getComponents(); + Assertions.assertThat( components ).isNotNull().isNotEmpty().hasSize( 2 ); + + List parameters = mojoAnnotatedClass.getParameters(); + Assertions.assertThat( parameters ).isNotNull().isNotEmpty().hasSize( 2 ).contains( + new ParameterAnnotationContent( "bar", null, "${thebar}", null, false, false ), + new ParameterAnnotationContent( "beer", null, "${thebeer}", null, false, false ) ); + } +} diff --git a/pom.xml b/pom.xml index e76fd51..cb73ded 100644 --- a/pom.xml +++ b/pom.xml @@ -215,7 +215,7 @@ org.codehaus.plexus plexus-utils - 2.0.5 + 3.0 org.codehaus.plexus @@ -239,6 +239,12 @@ 3.8.2 test + + org.easytesting + fest-assert + 1.4 + test +