You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@maven.apache.org by ti...@apache.org on 2019/08/07 15:11:18 UTC

[maven] 01/01: [MNG-6729] StringSearchModelInterpolator introspects objects from Java API

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

tibordigana pushed a commit to branch MNG-6729
in repository https://gitbox.apache.org/repos/asf/maven.git

commit 6921e60a63ec7d2476b2ba66afef317187a2744f
Author: tibordigana <ti...@apache.org>
AuthorDate: Mon Aug 5 16:47:27 2019 +0200

    [MNG-6729] StringSearchModelInterpolator introspects objects from Java API
---
 maven-model-builder/pom.xml                        |   5 +
 .../StringSearchModelInterpolator.java             |  56 ++++++-----
 .../StringSearchModelInterpolatorTest.java         | 110 +++++++++++++++++++++
 pom.xml                                            |   6 ++
 4 files changed, 154 insertions(+), 23 deletions(-)

diff --git a/maven-model-builder/pom.xml b/maven-model-builder/pom.xml
index 9a85016..f91280a 100644
--- a/maven-model-builder/pom.xml
+++ b/maven-model-builder/pom.xml
@@ -84,6 +84,11 @@ under the License.
       <artifactId>xmlunit-matchers</artifactId>
       <scope>test</scope>
     </dependency>
+    <dependency>
+      <groupId>org.powermock</groupId>
+      <artifactId>powermock-reflect</artifactId>
+      <scope>test</scope>
+    </dependency>
   </dependencies>
 
   <build>
diff --git a/maven-model-builder/src/main/java/org/apache/maven/model/interpolation/StringSearchModelInterpolator.java b/maven-model-builder/src/main/java/org/apache/maven/model/interpolation/StringSearchModelInterpolator.java
index 3c2ea13..279c388 100644
--- a/maven-model-builder/src/main/java/org/apache/maven/model/interpolation/StringSearchModelInterpolator.java
+++ b/maven-model-builder/src/main/java/org/apache/maven/model/interpolation/StringSearchModelInterpolator.java
@@ -250,7 +250,13 @@ public class StringSearchModelInterpolator
 
             private boolean isQualifiedForInterpolation( Class<?> cls )
             {
-                return !cls.getName().startsWith( "java" );
+                Package pkg = cls.getPackage();
+                if ( pkg == null )
+                {
+                    return true;
+                }
+                String pkgName = pkg.getName();
+                return !pkgName.startsWith( "java." ) && !pkgName.startsWith( "javax." );
             }
 
             private boolean isQualifiedForInterpolation( Field field, Class<?> fieldType )
@@ -278,33 +284,37 @@ public class StringSearchModelInterpolator
                 this.isQualifiedForInterpolation = isQualifiedForInterpolation( clazz );
                 this.isArray = clazz.isArray();
                 List<CacheField> fields = new ArrayList<>();
-                for ( Field currentField : clazz.getDeclaredFields() )
+                if ( isQualifiedForInterpolation )
                 {
-                    Class<?> type = currentField.getType();
-                    if ( isQualifiedForInterpolation( currentField, type ) )
+                    for ( Field currentField : clazz.getDeclaredFields() )
                     {
-                        if ( String.class == type )
+                        Class<?> type = currentField.getType();
+                        if ( isQualifiedForInterpolation( currentField, type ) )
                         {
-                            if ( !Modifier.isFinal( currentField.getModifiers() ) )
+                            if ( String.class == type )
                             {
-                                fields.add( new StringField( currentField ) );
+                                if ( !Modifier.isFinal( currentField.getModifiers() ) )
+                                {
+                                    fields.add( new StringField( currentField ) );
+                                }
+                            }
+                            else if ( List.class.isAssignableFrom( type ) )
+                            {
+                                fields.add( new ListField( currentField ) );
+                            }
+                            else if ( Collection.class.isAssignableFrom( type ) )
+                            {
+                                throw new RuntimeException(
+                                        "We dont interpolate into collections, use a list instead" );
+                            }
+                            else if ( Map.class.isAssignableFrom( type ) )
+                            {
+                                fields.add( new MapField( currentField ) );
+                            }
+                            else
+                            {
+                                fields.add( new ObjectField( currentField ) );
                             }
-                        }
-                        else if ( List.class.isAssignableFrom( type ) )
-                        {
-                            fields.add( new ListField( currentField ) );
-                        }
-                        else if ( Collection.class.isAssignableFrom( type ) )
-                        {
-                            throw new RuntimeException( "We dont interpolate into collections, use a list instead" );
-                        }
-                        else if ( Map.class.isAssignableFrom( type ) )
-                        {
-                            fields.add( new MapField( currentField ) );
-                        }
-                        else
-                        {
-                            fields.add( new ObjectField( currentField ) );
                         }
                     }
                 }
diff --git a/maven-model-builder/src/test/java/org/apache/maven/model/interpolation/StringSearchModelInterpolatorTest.java b/maven-model-builder/src/test/java/org/apache/maven/model/interpolation/StringSearchModelInterpolatorTest.java
index 71ebf51..b66abca 100644
--- a/maven-model-builder/src/test/java/org/apache/maven/model/interpolation/StringSearchModelInterpolatorTest.java
+++ b/maven-model-builder/src/test/java/org/apache/maven/model/interpolation/StringSearchModelInterpolatorTest.java
@@ -33,6 +33,12 @@ import java.util.concurrent.CountDownLatch;
 import java.util.concurrent.Future;
 import java.util.concurrent.FutureTask;
 
+import static org.hamcrest.CoreMatchers.anyOf;
+import static org.hamcrest.CoreMatchers.is;
+import static org.junit.Assert.assertThat;
+import static org.powermock.reflect.Whitebox.getField;
+import static org.powermock.reflect.Whitebox.getInternalState;
+
 /**
  * @author jdcasey
  * @author Benjamin Bentmann
@@ -337,6 +343,100 @@ public class StringSearchModelInterpolatorTest
         assertEquals( "value4", ( (String[]) obj.values.get( "key2" ) )[1] );
     }
 
+    public void testInterpolateObjectWithPomFile()
+            throws Exception
+    {
+        Model model = new Model();
+        model.setPomFile( new File( System.getProperty( "user.dir" ), "pom.xml" ) );
+        File baseDir = model.getProjectDirectory();
+
+        Properties p = new Properties();
+
+        Map<String, String> values = new HashMap<>();
+        values.put( "key", "${project.basedir}" + File.separator + "target" );
+
+        ObjectWithMapField obj = new ObjectWithMapField( values );
+
+        StringSearchModelInterpolator interpolator = (StringSearchModelInterpolator) createInterpolator();
+
+        ModelBuildingRequest config = createModelBuildingRequest( p );
+
+        SimpleProblemCollector collector = new SimpleProblemCollector();
+        interpolator.interpolateObject( obj, model, new File( "." ), config, collector );
+        assertProblemFree( collector );
+
+        assertThat( baseDir.getCanonicalPath(), is( System.getProperty( "user.dir" ) ) );
+        assertThat( obj.values.size(), is( 1 ) );
+        assertThat( (String) obj.values.get( "key" ), is( anyOf(
+                is( System.getProperty( "user.dir" ) + File.separator + "target" ),
+                // TODO why MVN adds dot /./ in paths???
+                is( System.getProperty( "user.dir" ) + File.separator + '.' + File.separator + "target" )
+        ) ) );
+    }
+
+    public void testNotInterpolateObjectWithFile()
+            throws Exception
+    {
+        Model model = new Model();
+
+        File baseDir = new File( System.getProperty( "user.dir" ) );
+
+        Properties p = new Properties();
+
+        ObjectWithNotInterpolatedFile obj = new ObjectWithNotInterpolatedFile( baseDir );
+
+        StringSearchModelInterpolator interpolator = (StringSearchModelInterpolator) createInterpolator();
+
+        ModelBuildingRequest config = createModelBuildingRequest( p );
+
+        SimpleProblemCollector collector = new SimpleProblemCollector();
+        interpolator.interpolateObject( obj, model, new File( "." ), config, collector );
+        assertProblemFree( collector );
+
+        //noinspection unchecked
+        Map<Class<?>, ?> cache =
+                (Map<Class<?>, ?>) getField( StringSearchModelInterpolator.class, "CACHED_ENTRIES" )
+                        .get( null );
+
+        Object objCacheItem = cache.get( Object.class );
+        Object fileCacheItem = cache.get( File.class );
+
+        assertNotNull( objCacheItem );
+        assertNotNull( fileCacheItem );
+
+        assertThat( ( (Object[]) getInternalState( objCacheItem, "fields" ) ).length, is( 0 ) );
+        assertThat( ( (Object[]) getInternalState( fileCacheItem, "fields" ) ).length, is( 0 ) );
+    }
+
+    public void testNotInterpolateFile()
+            throws Exception
+    {
+        Model model = new Model();
+
+        File baseDir = new File( System.getProperty( "user.dir" ) );
+
+        Properties p = new Properties();
+
+        StringSearchModelInterpolator interpolator = (StringSearchModelInterpolator) createInterpolator();
+
+        ModelBuildingRequest config = createModelBuildingRequest( p );
+
+        SimpleProblemCollector collector = new SimpleProblemCollector();
+        interpolator.interpolateObject( baseDir, model, new File( "." ), config, collector );
+        assertProblemFree( collector );
+
+        //noinspection unchecked
+        Map<Class<?>, ?> cache =
+                (Map<Class<?>, ?>) getField( StringSearchModelInterpolator.class, "CACHED_ENTRIES" )
+                        .get( null );
+
+        Object fileCacheItem = cache.get( File.class );
+
+        assertNotNull( fileCacheItem );
+
+        assertThat( ( (Object[]) getInternalState( fileCacheItem, "fields" ) ).length, is( 0 ) );
+    }
+
 
     public void testConcurrentInterpolation()
         throws Exception
@@ -432,6 +532,16 @@ public class StringSearchModelInterpolatorTest
         }
     }
 
+    private static final class ObjectWithNotInterpolatedFile
+    {
+        private final File f;
+
+        ObjectWithNotInterpolatedFile( File f )
+        {
+            this.f = f;
+        }
+    }
+
     @SuppressWarnings( "unused" )
     private static final class ObjectWithMixedProtection
     {
diff --git a/pom.xml b/pom.xml
index c3f4bcb..81ff46a 100644
--- a/pom.xml
+++ b/pom.xml
@@ -67,6 +67,7 @@ under the License.
     <resolverVersion>1.3.3</resolverVersion>
     <slf4jVersion>1.7.25</slf4jVersion>
     <xmlunitVersion>2.2.1</xmlunitVersion>
+    <powermockVersion>1.7.4</powermockVersion>
     <maven.test.redirectTestOutputToFile>true</maven.test.redirectTestOutputToFile>
     <!-- Control the name of the distribution and information output by mvn -->
     <distributionId>apache-maven</distributionId>
@@ -418,6 +419,11 @@ under the License.
         <version>${xmlunitVersion}</version>
         <scope>test</scope>
       </dependency>
+      <dependency>
+        <groupId>org.powermock</groupId>
+        <artifactId>powermock-reflect</artifactId>
+        <version>${powermockVersion}</version>
+      </dependency>
     </dependencies>
     <!--bootstrap-start-comment-->
   </dependencyManagement>