You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@maven.apache.org by mi...@apache.org on 2016/06/24 18:00:46 UTC

maven-archetype git commit: [ARCHETYPE-487] Add regex input validation for required properties defined in artifact descriptor

Repository: maven-archetype
Updated Branches:
  refs/heads/master e188f8fd0 -> 147ff3dc6


[ARCHETYPE-487] Add regex input validation for required properties defined in artifact descriptor

This closes #7


Project: http://git-wip-us.apache.org/repos/asf/maven-archetype/repo
Commit: http://git-wip-us.apache.org/repos/asf/maven-archetype/commit/147ff3dc
Tree: http://git-wip-us.apache.org/repos/asf/maven-archetype/tree/147ff3dc
Diff: http://git-wip-us.apache.org/repos/asf/maven-archetype/diff/147ff3dc

Branch: refs/heads/master
Commit: 147ff3dc6086e947faf8bead6b8ee70c584da1b5
Parents: e188f8f
Author: Manuel Ryan <ry...@shamu.ch>
Authored: Fri Sep 4 13:47:43 2015 +0200
Committer: Michael Osipov <mi...@apache.org>
Committed: Fri Jun 24 19:49:50 2016 +0200

----------------------------------------------------------------------
 .../src/main/mdo/archetype-descriptor.mdo       |  6 ++
 .../archetype/ui/ArchetypeConfiguration.java    | 26 ++++++
 .../archetype/ui/DefaultArchetypeFactory.java   | 10 ++-
 .../generation/ArchetypeGenerationQueryer.java  |  4 +-
 .../DefaultArchetypeGenerationConfigurator.java |  5 +-
 .../DefaultArchetypeGenerationQueryer.java      | 49 ++++++++++--
 .../DefaultArchetypeGenerationQueryerTest.java  | 83 ++++++++++++++++++++
 7 files changed, 171 insertions(+), 12 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/maven-archetype/blob/147ff3dc/archetype-models/archetype-descriptor/src/main/mdo/archetype-descriptor.mdo
----------------------------------------------------------------------
diff --git a/archetype-models/archetype-descriptor/src/main/mdo/archetype-descriptor.mdo b/archetype-models/archetype-descriptor/src/main/mdo/archetype-descriptor.mdo
index e18fdb6..c689716 100644
--- a/archetype-models/archetype-descriptor/src/main/mdo/archetype-descriptor.mdo
+++ b/archetype-models/archetype-descriptor/src/main/mdo/archetype-descriptor.mdo
@@ -209,6 +209,12 @@
           <required>false</required>
           <description>Default value of the property.</description>
         </field>
+        <field>
+          <name>validationRegex</name>
+          <type>String</type>
+          <required>false</required>
+          <description>A regular expression used to validate the property.</description>
+        </field>
       </fields>
     </class>
   </classes>

http://git-wip-us.apache.org/repos/asf/maven-archetype/blob/147ff3dc/maven-archetype-plugin/src/main/java/org/apache/maven/archetype/ui/ArchetypeConfiguration.java
----------------------------------------------------------------------
diff --git a/maven-archetype-plugin/src/main/java/org/apache/maven/archetype/ui/ArchetypeConfiguration.java b/maven-archetype-plugin/src/main/java/org/apache/maven/archetype/ui/ArchetypeConfiguration.java
index 08b52bd..a17935f 100644
--- a/maven-archetype-plugin/src/main/java/org/apache/maven/archetype/ui/ArchetypeConfiguration.java
+++ b/maven-archetype-plugin/src/main/java/org/apache/maven/archetype/ui/ArchetypeConfiguration.java
@@ -20,8 +20,11 @@ package org.apache.maven.archetype.ui;
  */
 
 import java.util.ArrayList;
+import java.util.HashMap;
 import java.util.List;
+import java.util.Map;
 import java.util.Properties;
+import java.util.regex.Pattern;
 
 import org.apache.maven.archetype.common.Constants;
 import org.codehaus.plexus.util.StringUtils;
@@ -214,4 +217,27 @@ public class ArchetypeConfiguration
     {
         return defaultProperties;
     }
+
+    Map<String, Pattern> propertiesValidationPatterns = new HashMap<String, Pattern>();
+
+    public void setPropertyValidationRegex( String requiredProperty, String regex )
+    {
+        propertiesValidationPatterns.put( requiredProperty, Pattern.compile( regex ) );
+    }
+
+    public Pattern getPropertyValidationRegex( String requiredProperty )
+    {
+        return propertiesValidationPatterns.get( requiredProperty );
+    }
+
+    public boolean validatePropertyValue( String property, String value )
+    {
+        Pattern pattern = propertiesValidationPatterns.get( property );
+        if ( pattern == null )
+        {
+            return true;
+        }
+        return pattern.matcher( value ).matches();
+    }
+
 }

http://git-wip-us.apache.org/repos/asf/maven-archetype/blob/147ff3dc/maven-archetype-plugin/src/main/java/org/apache/maven/archetype/ui/DefaultArchetypeFactory.java
----------------------------------------------------------------------
diff --git a/maven-archetype-plugin/src/main/java/org/apache/maven/archetype/ui/DefaultArchetypeFactory.java b/maven-archetype-plugin/src/main/java/org/apache/maven/archetype/ui/DefaultArchetypeFactory.java
index 0d0f13b..98f6bb9 100644
--- a/maven-archetype-plugin/src/main/java/org/apache/maven/archetype/ui/DefaultArchetypeFactory.java
+++ b/maven-archetype-plugin/src/main/java/org/apache/maven/archetype/ui/DefaultArchetypeFactory.java
@@ -22,7 +22,6 @@ package org.apache.maven.archetype.ui;
 import org.apache.maven.archetype.common.Constants;
 import org.apache.maven.archetype.metadata.RequiredProperty;
 import org.apache.maven.project.MavenProject;
-
 import org.codehaus.plexus.component.annotations.Component;
 import org.codehaus.plexus.logging.AbstractLogEnabled;
 
@@ -128,6 +127,7 @@ public class DefaultArchetypeFactory
             configuration.addRequiredProperty( key );
 
             String defaultValue = requiredProperty.getDefaultValue();
+            String validationRegex = requiredProperty.getValidationRegex();
 
             if ( properties.getProperty( key ) != null )
             {
@@ -148,6 +148,12 @@ public class DefaultArchetypeFactory
                 configuration.setDefaultProperty( key, defaultValue );
                 getLogger().debug( "Setting defaultProperty " + key + "=" + defaultValue );
             }
+
+            if ( validationRegex != null )
+            {
+                configuration.setPropertyValidationRegex( key, validationRegex );
+                getLogger().debug( "Setting validation regular expression " + key + "=" + defaultValue );
+            }
         }
 
         addRequiredProperty( configuration, properties, Constants.GROUP_ID, null, false );
@@ -269,7 +275,7 @@ public class DefaultArchetypeFactory
 
     /**
      * Check if the given value references a property, ie contains <code>${...}</code>.
-     * 
+     *
      * @param defaultValue the value to check
      * @return <code>true</code> if the value contains <code>${</code> followed by <code>}</code>
      */

http://git-wip-us.apache.org/repos/asf/maven-archetype/blob/147ff3dc/maven-archetype-plugin/src/main/java/org/apache/maven/archetype/ui/generation/ArchetypeGenerationQueryer.java
----------------------------------------------------------------------
diff --git a/maven-archetype-plugin/src/main/java/org/apache/maven/archetype/ui/generation/ArchetypeGenerationQueryer.java b/maven-archetype-plugin/src/main/java/org/apache/maven/archetype/ui/generation/ArchetypeGenerationQueryer.java
index 9f46f69..a432df6 100644
--- a/maven-archetype-plugin/src/main/java/org/apache/maven/archetype/ui/generation/ArchetypeGenerationQueryer.java
+++ b/maven-archetype-plugin/src/main/java/org/apache/maven/archetype/ui/generation/ArchetypeGenerationQueryer.java
@@ -22,6 +22,8 @@ package org.apache.maven.archetype.ui.generation;
 import org.apache.maven.archetype.ui.ArchetypeConfiguration;
 import org.codehaus.plexus.components.interactivity.PrompterException;
 
+import java.util.regex.Pattern;
+
 /**
  * User interaction component to query informations necessary for a project generation from an archetype.
  * 
@@ -32,6 +34,6 @@ public interface ArchetypeGenerationQueryer
     boolean confirmConfiguration( ArchetypeConfiguration archetypeConfiguration )
         throws PrompterException;
 
-    String getPropertyValue( String requiredProperty, String defaultValue )
+    String getPropertyValue( String requiredProperty, String defaultValue, Pattern validationRegex )
         throws PrompterException;
 }

http://git-wip-us.apache.org/repos/asf/maven-archetype/blob/147ff3dc/maven-archetype-plugin/src/main/java/org/apache/maven/archetype/ui/generation/DefaultArchetypeGenerationConfigurator.java
----------------------------------------------------------------------
diff --git a/maven-archetype-plugin/src/main/java/org/apache/maven/archetype/ui/generation/DefaultArchetypeGenerationConfigurator.java b/maven-archetype-plugin/src/main/java/org/apache/maven/archetype/ui/generation/DefaultArchetypeGenerationConfigurator.java
index 88f8fd1..cb0fb3a 100644
--- a/maven-archetype-plugin/src/main/java/org/apache/maven/archetype/ui/generation/DefaultArchetypeGenerationConfigurator.java
+++ b/maven-archetype-plugin/src/main/java/org/apache/maven/archetype/ui/generation/DefaultArchetypeGenerationConfigurator.java
@@ -184,7 +184,7 @@ public class DefaultArchetypeGenerationConfigurator
                                     getTransitiveDefaultValue( packageDefault, archetypeConfiguration, requiredProperty,
                                                                context );
 
-                                value = archetypeGenerationQueryer.getPropertyValue( requiredProperty, value );
+                                value = archetypeGenerationQueryer.getPropertyValue( requiredProperty, value, null );
 
                                 archetypeConfiguration.setProperty( requiredProperty, value );
 
@@ -197,7 +197,8 @@ public class DefaultArchetypeGenerationConfigurator
                                 value = getTransitiveDefaultValue( value, archetypeConfiguration, requiredProperty,
                                                                    context );
 
-                                value = archetypeGenerationQueryer.getPropertyValue( requiredProperty, value );
+                                value = archetypeGenerationQueryer.getPropertyValue( requiredProperty, value,
+                                    archetypeConfiguration.getPropertyValidationRegex( requiredProperty ) );
 
                                 archetypeConfiguration.setProperty( requiredProperty, value );
 

http://git-wip-us.apache.org/repos/asf/maven-archetype/blob/147ff3dc/maven-archetype-plugin/src/main/java/org/apache/maven/archetype/ui/generation/DefaultArchetypeGenerationQueryer.java
----------------------------------------------------------------------
diff --git a/maven-archetype-plugin/src/main/java/org/apache/maven/archetype/ui/generation/DefaultArchetypeGenerationQueryer.java b/maven-archetype-plugin/src/main/java/org/apache/maven/archetype/ui/generation/DefaultArchetypeGenerationQueryer.java
index 80c8f1e..5b8f5ae 100644
--- a/maven-archetype-plugin/src/main/java/org/apache/maven/archetype/ui/generation/DefaultArchetypeGenerationQueryer.java
+++ b/maven-archetype-plugin/src/main/java/org/apache/maven/archetype/ui/generation/DefaultArchetypeGenerationQueryer.java
@@ -26,6 +26,8 @@ import org.codehaus.plexus.components.interactivity.Prompter;
 import org.codehaus.plexus.components.interactivity.PrompterException;
 import org.codehaus.plexus.logging.AbstractLogEnabled;
 
+import java.util.regex.Pattern;
+
 @Component( role = ArchetypeGenerationQueryer.class, hint = "default" )
 public class DefaultArchetypeGenerationQueryer
     extends AbstractLogEnabled
@@ -49,20 +51,53 @@ public class DefaultArchetypeGenerationQueryer
         return "Y".equalsIgnoreCase( answer );
     }
 
-    public String getPropertyValue( String requiredProperty, String defaultValue )
+    public String getPropertyValue( String requiredProperty, String defaultValue, Pattern validationRegex )
         throws PrompterException
     {
-        String query = "Define value for property '" + requiredProperty + "': ";
-        String answer;
+        StringBuilder queryBuilder = new StringBuilder();
+        queryBuilder.append( "Define value for property '" );
+        queryBuilder.append( requiredProperty );
+        queryBuilder.append( '\'' );
 
-        if ( ( defaultValue != null ) && !defaultValue.equals( "null" ) )
+        if ( validationRegex != null )
         {
-            answer = prompter.prompt( query, defaultValue );
+            queryBuilder.append( " (should match expression '" );
+            queryBuilder.append( validationRegex );
+            queryBuilder.append( "')" );
         }
-        else
+
+        String query = queryBuilder.toString();
+        String answer;
+        boolean validAnswer = false;
+
+        do
         {
-            answer = prompter.prompt( query );
+            if ( ( defaultValue != null ) && !defaultValue.equals( "null" ) )
+            {
+                answer = prompter.prompt( query, defaultValue );
+            }
+            else
+            {
+                answer = prompter.prompt( query );
+            }
+
+            if ( validationRegex == null || validationRegex.matcher( answer ).matches() )
+            {
+                validAnswer = true;
+            }
+            else
+            {
+                query = "Value does not match the expression, please try again";
+            }
+
         }
+        while ( !validAnswer );
+
         return answer;
     }
+
+    public void setPrompter( Prompter prompter )
+    {
+        this.prompter = prompter;
+    }
 }

http://git-wip-us.apache.org/repos/asf/maven-archetype/blob/147ff3dc/maven-archetype-plugin/src/test/java/org/apache/maven/archetype/ui/generation/DefaultArchetypeGenerationQueryerTest.java
----------------------------------------------------------------------
diff --git a/maven-archetype-plugin/src/test/java/org/apache/maven/archetype/ui/generation/DefaultArchetypeGenerationQueryerTest.java b/maven-archetype-plugin/src/test/java/org/apache/maven/archetype/ui/generation/DefaultArchetypeGenerationQueryerTest.java
new file mode 100644
index 0000000..13adad9
--- /dev/null
+++ b/maven-archetype-plugin/src/test/java/org/apache/maven/archetype/ui/generation/DefaultArchetypeGenerationQueryerTest.java
@@ -0,0 +1,83 @@
+package org.apache.maven.archetype.ui.generation;
+
+/*
+ * 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.codehaus.plexus.PlexusTestCase;
+import org.codehaus.plexus.components.interactivity.Prompter;
+import org.codehaus.plexus.components.interactivity.PrompterException;
+import org.easymock.AbstractMatcher;
+import org.easymock.ArgumentsMatcher;
+import org.easymock.MockControl;
+
+import java.util.regex.Pattern;
+
+public class DefaultArchetypeGenerationQueryerTest
+    extends PlexusTestCase
+{
+
+    private DefaultArchetypeGenerationQueryer queryer;
+
+    public void setUp()
+        throws Exception
+    {
+        super.setUp();
+
+        queryer = (DefaultArchetypeGenerationQueryer) lookup( ArchetypeGenerationQueryer.class.getName() );
+    }
+
+    public void testPropertyRegexValidationRetry()
+        throws PrompterException
+    {
+
+        MockControl control = MockControl.createControl( Prompter.class );
+
+        Prompter prompter = (Prompter) control.getMock();
+        prompter.prompt( "" );
+        control.setMatcher( createArgumentMatcher() );
+        control.setReturnValue( "invalid-answer" );
+        queryer.setPrompter( prompter );
+        prompter.prompt( "" );
+        control.setReturnValue( "valid-answer" );
+        queryer.setPrompter( prompter );
+        control.replay();
+
+        String value = queryer.getPropertyValue( "custom-property", null, Pattern.compile( "^valid-.*" ) );
+
+        assertEquals( "valid-answer", value );
+
+    }
+
+    private static ArgumentsMatcher createArgumentMatcher()
+    {
+        return new AbstractMatcher()
+        {
+            protected boolean argumentMatches( Object o, Object o1 )
+            {
+                return true;
+            }
+
+            protected String argumentToString( Object o )
+            {
+                return "...";
+            }
+        };
+    }
+
+}