From 203cfc67cc4cf58662a4f05477878c6c735acb91 Mon Sep 17 00:00:00 2001 From: tibordigana Date: Mon, 5 Aug 2019 16:47:27 +0200 Subject: [PATCH] [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 9a85016fbea..f91280ae83b 100644 --- a/maven-model-builder/pom.xml +++ b/maven-model-builder/pom.xml @@ -84,6 +84,11 @@ under the License. xmlunit-matchers test + + org.powermock + powermock-reflect + test + 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 3c2ea1377bd..279c388e0fa 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 @@ private static class CacheItem 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 @@ private boolean isQualifiedForInterpolation( Field field, Class fieldType ) this.isQualifiedForInterpolation = isQualifiedForInterpolation( clazz ); this.isArray = clazz.isArray(); List 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 71ebf5103a4..b66abcade2a 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.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 void testInterpolateObjectWithStringToStringArrayMapField() 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 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, ?> cache = + (Map, ?>) 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, ?> cache = + (Map, ?>) 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 ObjectWithMapField( Map values ) } } + 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 c3f4bcbdaaf..81ff46ab84e 100644 --- a/pom.xml +++ b/pom.xml @@ -67,6 +67,7 @@ under the License. 1.3.3 1.7.25 2.2.1 + 1.7.4 true apache-maven @@ -418,6 +419,11 @@ under the License. ${xmlunitVersion} test + + org.powermock + powermock-reflect + ${powermockVersion} +