You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@maven.apache.org by sj...@apache.org on 2022/07/24 23:09:29 UTC

[maven-plugin-tools] 01/01: [MPLUGIN-410] Create implementation attribute for @Parameter

This is an automated email from the ASF dual-hosted git repository.

sjaranowski pushed a commit to branch MPLUGIN-410
in repository https://gitbox.apache.org/repos/asf/maven-plugin-tools.git

commit 578790289fb42323f6607df9a92b6e09830f3742
Author: Slawomir Jaranowski <s....@gmail.com>
AuthorDate: Mon Jul 25 01:08:41 2022 +0200

    [MPLUGIN-410] Create implementation attribute for @Parameter
---
 .../maven/plugins/annotations/Parameter.java       |  7 +++
 .../verify.groovy                                  | 16 +++++-
 .../JavaAnnotationsMojoDescriptorExtractor.java    |  1 +
 .../datamodel/ParameterAnnotationContent.java      | 64 ++++++++++++++++++----
 .../src/site/apt/index.apt                         |  1 +
 .../plugin/extractor/annotations/FooInterface.java | 24 ++++++++
 .../extractor/annotations/FooInterfaceImpl.java    | 24 ++++++++
 .../plugin/extractor/annotations/FooMojo.java      |  6 ++
 .../annotations/TestAnnotationsReader.java         | 17 ++++--
 9 files changed, 143 insertions(+), 17 deletions(-)

diff --git a/maven-plugin-annotations/src/main/java/org/apache/maven/plugins/annotations/Parameter.java b/maven-plugin-annotations/src/main/java/org/apache/maven/plugins/annotations/Parameter.java
index d6be4f9b..0e643d6b 100644
--- a/maven-plugin-annotations/src/main/java/org/apache/maven/plugins/annotations/Parameter.java
+++ b/maven-plugin-annotations/src/main/java/org/apache/maven/plugins/annotations/Parameter.java
@@ -72,6 +72,13 @@ public @interface Parameter
      */
     String defaultValue() default "";
 
+    /**
+     * Defines the implementation in the case the parameter type is an interface.
+     *
+     * @return the implementation class name
+     */
+    Class<?> implementation() default Object.class;
+
     /**
      * is the parameter required?
      * @return <code>true</code> if the Mojo should fail when the parameter cannot be injected
diff --git a/maven-plugin-plugin/src/it/annotation-with-inheritance-from-deps/verify.groovy b/maven-plugin-plugin/src/it/annotation-with-inheritance-from-deps/verify.groovy
index ad969aa0..1ef2944d 100644
--- a/maven-plugin-plugin/src/it/annotation-with-inheritance-from-deps/verify.groovy
+++ b/maven-plugin-plugin/src/it/annotation-with-inheritance-from-deps/verify.groovy
@@ -64,13 +64,14 @@ assert mojo.requirements.requirement[1].role.text() == 'org.apache.maven.project
 assert mojo.requirements.requirement[1].'role-hint'.text() == ''
 assert mojo.requirements.requirement[1].'field-name'.text() == 'projectHelper'
 
-assert mojo.parameters.parameter.size() == 3
+assert mojo.parameters.parameter.size() == 4
 
 def parameter = mojo.parameters.parameter.findAll{ it.name.text() == "aliasedParam"}[0]
 
 assert parameter.name.text() == 'aliasedParam'
 assert parameter.alias.text() == 'alias'
 assert parameter.type.text() == 'java.lang.String'
+assert parameter.implementation.isEmpty()
 assert parameter.deprecated.text() == 'As of 0.2'
 assert parameter.required.text() == 'false'
 assert parameter.editable.text() == 'true'
@@ -81,6 +82,7 @@ parameter = mojo.parameters.parameter.findAll{ it.name.text() == "beer"}[0]
 assert parameter.name.text() == 'beer'
 assert parameter.alias.isEmpty()
 assert parameter.type.text() == 'java.lang.String'
+assert parameter.implementation.isEmpty()
 assert parameter.deprecated.text() == "wine is better"
 assert parameter.required.text() == 'false'
 assert parameter.editable.text() == 'true'
@@ -91,9 +93,21 @@ parameter = mojo.parameters.parameter.findAll{ it.name.text() == "bar"}[0]
 assert parameter.name.text() == 'bar'
 assert parameter.alias.isEmpty()
 assert parameter.type.text() == 'java.lang.String'
+assert parameter.implementation.isEmpty()
 assert parameter.deprecated.isEmpty()
 assert parameter.required.text() == 'true'
 assert parameter.editable.text() == 'true'
 assert parameter.description.text() == 'the cool bar to go'
 
+parameter = mojo.parameters.parameter.findAll{ it.name.text() == "fooInterface"}[0]
+
+assert parameter.name.text() == 'fooInterface'
+assert parameter.alias.isEmpty()
+assert parameter.type.text() == 'org.apache.maven.tools.plugin.extractor.annotations.FooInterface'
+assert parameter.implementation.text() == 'org.apache.maven.tools.plugin.extractor.annotations.FooInterfaceImpl'
+assert parameter.deprecated.isEmpty()
+assert parameter.required.text() == 'false'
+assert parameter.editable.text() == 'true'
+assert parameter.description.text() == 'Interface type as parameter.'
+
 return true;
diff --git a/maven-plugin-tools-annotations/src/main/java/org/apache/maven/tools/plugin/extractor/annotations/JavaAnnotationsMojoDescriptorExtractor.java b/maven-plugin-tools-annotations/src/main/java/org/apache/maven/tools/plugin/extractor/annotations/JavaAnnotationsMojoDescriptorExtractor.java
index a4b5f6d4..973d2e0c 100644
--- a/maven-plugin-tools-annotations/src/main/java/org/apache/maven/tools/plugin/extractor/annotations/JavaAnnotationsMojoDescriptorExtractor.java
+++ b/maven-plugin-tools-annotations/src/main/java/org/apache/maven/tools/plugin/extractor/annotations/JavaAnnotationsMojoDescriptorExtractor.java
@@ -567,6 +567,7 @@ public class JavaAnnotationsMojoDescriptorExtractor
                 parameter.setName( name );
                 parameter.setAlias( parameterAnnotationContent.alias() );
                 parameter.setDefaultValue( parameterAnnotationContent.defaultValue() );
+                parameter.setImplementation( parameterAnnotationContent.getImplementationClassName() );
                 parameter.setDeprecated( parameterAnnotationContent.getDeprecated() );
                 parameter.setDescription( parameterAnnotationContent.getDescription() );
                 parameter.setEditable( !parameterAnnotationContent.readonly() );
diff --git a/maven-plugin-tools-annotations/src/main/java/org/apache/maven/tools/plugin/extractor/annotations/datamodel/ParameterAnnotationContent.java b/maven-plugin-tools-annotations/src/main/java/org/apache/maven/tools/plugin/extractor/annotations/datamodel/ParameterAnnotationContent.java
index 1db117ac..3d9f8922 100644
--- a/maven-plugin-tools-annotations/src/main/java/org/apache/maven/tools/plugin/extractor/annotations/datamodel/ParameterAnnotationContent.java
+++ b/maven-plugin-tools-annotations/src/main/java/org/apache/maven/tools/plugin/extractor/annotations/datamodel/ParameterAnnotationContent.java
@@ -20,8 +20,10 @@ package org.apache.maven.tools.plugin.extractor.annotations.datamodel;
  */
 
 import org.apache.maven.plugins.annotations.Parameter;
+import org.objectweb.asm.Type;
 
 import java.lang.annotation.Annotation;
+import java.util.Objects;
 
 /**
  * @author Olivier Lamy
@@ -40,6 +42,8 @@ public class ParameterAnnotationContent
 
     private String defaultValue;
 
+    private String implementationClassName;
+
     private boolean required = false;
 
     private boolean readonly = false;
@@ -53,12 +57,13 @@ public class ParameterAnnotationContent
     }
 
     public ParameterAnnotationContent( String fieldName, String alias, String property, String defaultValue,
-                                       boolean required, boolean readonly, String className )
+                                       Class<?> implementation, boolean required, boolean readonly, String className )
     {
         this( fieldName, className );
         this.alias = alias;
         this.property = property;
         this.defaultValue = defaultValue;
+        this.implementationClassName = implementation != null ? implementation.getName() : null;
         this.required = required;
         this.readonly = readonly;
     }
@@ -107,6 +112,33 @@ public class ParameterAnnotationContent
         this.defaultValue = defaultValue;
     }
 
+    public void implementation( Type implementation )
+    {
+
+        implementationClassName = implementation.getClassName();
+        if ( implementationClassName.equals( Object.class.getName() ) )
+        {
+            // Object is default value for implementation attribute
+            this.implementationClassName = null;
+        }
+    }
+
+    public String getImplementationClassName()
+    {
+        return implementationClassName;
+    }
+
+    @Override
+    public Class<?> implementation()
+    {
+        // needed for implementing @Parameter
+        // we don't have access to project class path,
+        // so loading class is not possible without build additional classLoader
+        // we only operate on classes names
+        throw new UnsupportedOperationException(
+            "please use getImplementationClassName instead of implementation method" );
+    }
+
     @Override
     public boolean required()
     {
@@ -151,10 +183,14 @@ public class ParameterAnnotationContent
         final StringBuilder sb = new StringBuilder();
         sb.append( super.toString() );
         sb.append( "ParameterAnnotationContent" );
-        sb.append( "{name='" ).append( name ).append( '\'' );
+        sb.append( "{fieldName='" ).append( getFieldName() ).append( '\'' );
+        sb.append( ", className='" ).append( getClassName() ).append( '\'' );
+        sb.append( ", name='" ).append( name ).append( '\'' );
+        sb.append( ", alias='" ).append( alias ).append( '\'' );
         sb.append( ", alias='" ).append( alias ).append( '\'' );
         sb.append( ", property='" ).append( property ).append( '\'' );
         sb.append( ", defaultValue='" ).append( defaultValue ).append( '\'' );
+        sb.append( ", implementation='" ).append( implementationClassName ).append( '\'' );
         sb.append( ", required=" ).append( required );
         sb.append( ", readonly=" ).append( readonly );
         sb.append( '}' );
@@ -189,15 +225,24 @@ public class ParameterAnnotationContent
             return false;
         }
 
-        if ( alias != null ? !alias.equals( that.alias ) : that.alias != null )
+        if ( getClassName() != null ? !getClassName().equals( that.getClassName() ) : that.getClassName() != null )
+        {
+            return false;
+        }
+
+        if ( !Objects.equals( alias, that.alias ) )
+        {
+            return false;
+        }
+        if ( !Objects.equals( defaultValue, that.defaultValue ) )
         {
             return false;
         }
-        if ( defaultValue != null ? !defaultValue.equals( that.defaultValue ) : that.defaultValue != null )
+        if ( !Objects.equals( property, that.property ) )
         {
             return false;
         }
-        if ( property != null ? !property.equals( that.property ) : that.property != null )
+        if ( !Objects.equals( implementationClassName, that.implementationClassName ) )
         {
             return false;
         }
@@ -208,12 +253,7 @@ public class ParameterAnnotationContent
     @Override
     public int hashCode()
     {
-        int result = alias != null ? alias.hashCode() : 0;
-        result = 31 * result + ( getFieldName() != null ? getFieldName().hashCode() : 0 );
-        result = 31 * result + ( property != null ? property.hashCode() : 0 );
-        result = 31 * result + ( defaultValue != null ? defaultValue.hashCode() : 0 );
-        result = 31 * result + ( required ? 1 : 0 );
-        result = 31 * result + ( readonly ? 1 : 0 );
-        return result;
+        return Objects.hash( alias, getFieldName(), property, defaultValue, required, readonly,
+                             implementationClassName );
     }
 }
diff --git a/maven-plugin-tools-annotations/src/site/apt/index.apt b/maven-plugin-tools-annotations/src/site/apt/index.apt
index 7ffc3bad..db372a25 100644
--- a/maven-plugin-tools-annotations/src/site/apt/index.apt
+++ b/maven-plugin-tools-annotations/src/site/apt/index.apt
@@ -83,6 +83,7 @@ public class MyMojo
                 alias = "myAlias",
                 property = "a.property",
                 defaultValue = "an expression, possibly with ${variables}",
+                implementation = "class of implementation in the case the parameter type is an interface"
                 readonly = <false|true>,
                 required = <false|true> )
     private String parameter;
diff --git a/maven-plugin-tools-annotations/src/test/java/org/apache/maven/tools/plugin/extractor/annotations/FooInterface.java b/maven-plugin-tools-annotations/src/test/java/org/apache/maven/tools/plugin/extractor/annotations/FooInterface.java
new file mode 100644
index 00000000..f8932933
--- /dev/null
+++ b/maven-plugin-tools-annotations/src/test/java/org/apache/maven/tools/plugin/extractor/annotations/FooInterface.java
@@ -0,0 +1,24 @@
+package org.apache.maven.tools.plugin.extractor.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.
+ */
+
+public interface FooInterface
+{
+}
diff --git a/maven-plugin-tools-annotations/src/test/java/org/apache/maven/tools/plugin/extractor/annotations/FooInterfaceImpl.java b/maven-plugin-tools-annotations/src/test/java/org/apache/maven/tools/plugin/extractor/annotations/FooInterfaceImpl.java
new file mode 100644
index 00000000..99f593b8
--- /dev/null
+++ b/maven-plugin-tools-annotations/src/test/java/org/apache/maven/tools/plugin/extractor/annotations/FooInterfaceImpl.java
@@ -0,0 +1,24 @@
+package org.apache.maven.tools.plugin.extractor.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.
+ */
+
+public class FooInterfaceImpl implements FooInterface
+{
+}
diff --git a/maven-plugin-tools-annotations/src/test/java/org/apache/maven/tools/plugin/extractor/annotations/FooMojo.java b/maven-plugin-tools-annotations/src/test/java/org/apache/maven/tools/plugin/extractor/annotations/FooMojo.java
index 179b2ffe..36dd9737 100644
--- a/maven-plugin-tools-annotations/src/test/java/org/apache/maven/tools/plugin/extractor/annotations/FooMojo.java
+++ b/maven-plugin-tools-annotations/src/test/java/org/apache/maven/tools/plugin/extractor/annotations/FooMojo.java
@@ -43,6 +43,12 @@ public class FooMojo
     @Parameter( property = "thebar", required = true, defaultValue = "coolbar" )
     protected String bar;
 
+    /**
+     * Interface type as parameter.
+     */
+    @Parameter( property = "fooInterface", implementation = FooInterfaceImpl.class )
+    protected FooInterface fooInterface;
+
     /**
      * beer for non french folks
      * @deprecated wine is better
diff --git a/maven-plugin-tools-annotations/src/test/java/org/apache/maven/tools/plugin/extractor/annotations/TestAnnotationsReader.java b/maven-plugin-tools-annotations/src/test/java/org/apache/maven/tools/plugin/extractor/annotations/TestAnnotationsReader.java
index 41fd2474..797f46e7 100644
--- a/maven-plugin-tools-annotations/src/test/java/org/apache/maven/tools/plugin/extractor/annotations/TestAnnotationsReader.java
+++ b/maven-plugin-tools-annotations/src/test/java/org/apache/maven/tools/plugin/extractor/annotations/TestAnnotationsReader.java
@@ -92,9 +92,18 @@ class TestAnnotationsReader
         assertThat( components ).isNotNull().isNotEmpty().hasSize( 1 );
 
         Collection<ParameterAnnotationContent> parameters = mojoAnnotatedClass.getParameters().values();
-        assertThat( parameters ).isNotNull().isNotEmpty().hasSize( 2 ).contains(
-            new ParameterAnnotationContent( "bar", null, "thebar", "coolbar", true, false, String.class.getName() ),
-            new ParameterAnnotationContent( "beer", null, "thebeer", "coolbeer", false, false,
-                                            String.class.getName() ) );
+        assertThat( parameters ).isNotNull()
+            .isNotEmpty()
+            .hasSize( 3 )
+            .contains(
+                new ParameterAnnotationContent( "bar", null, "thebar", "coolbar", null, true, false,
+                                                String.class.getName() ),
+                new ParameterAnnotationContent( "beer", null, "thebeer", "coolbeer", null, false, false,
+                                                String.class.getName() ),
+                new ParameterAnnotationContent( "fooInterface", null, "fooInterface", null,
+                                                FooInterfaceImpl.class,
+                                                false,
+                                                false, FooInterface.class.getName() )
+            );
     }
 }