Skip to content

Commit

Permalink
[MNG-6729] StringSearchModelInterpolator introspects objects from Jav…
Browse files Browse the repository at this point in the history
…a API
  • Loading branch information
Tibor17 committed Aug 9, 2019
1 parent 8a1f572 commit 203cfc6
Show file tree
Hide file tree
Showing 4 changed files with 154 additions and 23 deletions.
5 changes: 5 additions & 0 deletions maven-model-builder/pom.xml
Expand Up @@ -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>
Expand Down
Expand Up @@ -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 )
Expand Down Expand Up @@ -278,33 +284,37 @@ private boolean isQualifiedForInterpolation( Field field, Class<?> fieldType )
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 ) );
}
}
}
Expand Down
Expand Up @@ -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
Expand Down Expand Up @@ -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<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
Expand Down Expand Up @@ -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
{
Expand Down
6 changes: 6 additions & 0 deletions pom.xml
Expand Up @@ -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>
Expand Down Expand Up @@ -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>
Expand Down

0 comments on commit 203cfc6

Please sign in to comment.