mirror of https://github.com/apache/maven.git
[MNG-4542] StringSearchModelInterpolator concurrency problem
Revived test from 2.2.X code base, fixed concurrency issue and added concurrency test git-svn-id: https://svn.apache.org/repos/asf/maven/maven-3/trunk@902080 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
parent
664537e3f8
commit
0bfae6deed
|
@ -60,7 +60,7 @@ public abstract class AbstractStringBasedModelInterpolator
|
|||
/**
|
||||
* The default format used for build timestamps.
|
||||
*/
|
||||
private static final String DEFAULT_BUILD_TIMESTAMP_FORMAT = "yyyyMMdd-HHmm";
|
||||
static final String DEFAULT_BUILD_TIMESTAMP_FORMAT = "yyyyMMdd-HHmm";
|
||||
|
||||
/**
|
||||
* The name of a property that if present in the model's {@code <properties>} section specifies a custom format for
|
||||
|
|
|
@ -58,12 +58,14 @@ public class StringSearchModelInterpolator
|
|||
return model;
|
||||
}
|
||||
|
||||
protected void interpolateObject( Object obj, Model model, File projectDir, ModelBuildingRequest config, ModelProblemCollector problems )
|
||||
protected void interpolateObject( Object obj, Model model, File projectDir, ModelBuildingRequest config,
|
||||
ModelProblemCollector problems )
|
||||
{
|
||||
try
|
||||
{
|
||||
List<? extends ValueSource> valueSources = createValueSources( model, projectDir, config, problems );
|
||||
List<? extends InterpolationPostProcessor> postProcessors = createPostProcessors( model, projectDir, config );
|
||||
List<? extends InterpolationPostProcessor> postProcessors = createPostProcessors( model, projectDir,
|
||||
config );
|
||||
|
||||
InterpolateObjectAction action =
|
||||
new InterpolateObjectAction( obj, valueSources, postProcessors, this, problems );
|
||||
|
@ -95,7 +97,7 @@ public class StringSearchModelInterpolator
|
|||
|
||||
public InterpolateObjectAction( Object target, List<? extends ValueSource> valueSources,
|
||||
List<? extends InterpolationPostProcessor> postProcessors,
|
||||
StringSearchModelInterpolator modelInterpolator, ModelProblemCollector problems )
|
||||
StringSearchModelInterpolator modelInterpolator, ModelProblemCollector problems)
|
||||
{
|
||||
this.valueSources = valueSources;
|
||||
this.postProcessors = postProcessors;
|
||||
|
@ -135,28 +137,21 @@ public class StringSearchModelInterpolator
|
|||
}
|
||||
else if ( isQualifiedForInterpolation( cls ) )
|
||||
{
|
||||
Field[] fields = fieldsByClass.get( cls );
|
||||
if ( fields == null )
|
||||
Field[] fields = getFields(cls);
|
||||
for (Field currentField : fields)
|
||||
{
|
||||
fields = cls.getDeclaredFields();
|
||||
fieldsByClass.put( cls, fields );
|
||||
}
|
||||
|
||||
for ( int i = 0; i < fields.length; i++ )
|
||||
{
|
||||
Class<?> type = fields[i].getType();
|
||||
if ( isQualifiedForInterpolation( fields[i], type ) )
|
||||
Class<?> type = currentField.getType();
|
||||
if ( isQualifiedForInterpolation( currentField, type ) )
|
||||
{
|
||||
boolean isAccessible = fields[i].isAccessible();
|
||||
fields[i].setAccessible( true );
|
||||
try
|
||||
{
|
||||
synchronized ( currentField){
|
||||
boolean isAccessible = currentField.isAccessible();
|
||||
currentField.setAccessible( true );
|
||||
try
|
||||
{
|
||||
if ( String.class == type )
|
||||
{
|
||||
String value = (String) fields[i].get( target );
|
||||
if ( value != null && !Modifier.isFinal( fields[i].getModifiers() ) )
|
||||
String value = (String) currentField.get( target );
|
||||
if ( value != null && !Modifier.isFinal( currentField.getModifiers() ) )
|
||||
{
|
||||
String interpolated =
|
||||
modelInterpolator.interpolateInternal( value, valueSources, postProcessors,
|
||||
|
@ -164,13 +159,13 @@ public class StringSearchModelInterpolator
|
|||
|
||||
if ( !interpolated.equals( value ) )
|
||||
{
|
||||
fields[i].set( target, interpolated );
|
||||
currentField.set( target, interpolated );
|
||||
}
|
||||
}
|
||||
}
|
||||
else if ( Collection.class.isAssignableFrom( type ) )
|
||||
{
|
||||
Collection<Object> c = (Collection<Object>) fields[i].get( target );
|
||||
Collection<Object> c = (Collection<Object>) currentField.get( target );
|
||||
if ( c != null && !c.isEmpty() )
|
||||
{
|
||||
List<Object> originalValues = new ArrayList<Object>( c );
|
||||
|
@ -192,7 +187,8 @@ public class StringSearchModelInterpolator
|
|||
String interpolated =
|
||||
modelInterpolator.interpolateInternal( (String) value,
|
||||
valueSources,
|
||||
postProcessors, problems );
|
||||
postProcessors,
|
||||
problems );
|
||||
|
||||
if ( !interpolated.equals( value ) )
|
||||
{
|
||||
|
@ -226,7 +222,7 @@ public class StringSearchModelInterpolator
|
|||
}
|
||||
else if ( Map.class.isAssignableFrom( type ) )
|
||||
{
|
||||
Map<Object, Object> m = (Map<Object, Object>) fields[i].get( target );
|
||||
Map<Object, Object> m = (Map<Object, Object>) currentField.get( target );
|
||||
if ( m != null && !m.isEmpty() )
|
||||
{
|
||||
for ( Map.Entry<Object, Object> entry : m.entrySet() )
|
||||
|
@ -240,7 +236,8 @@ public class StringSearchModelInterpolator
|
|||
String interpolated =
|
||||
modelInterpolator.interpolateInternal( (String) value,
|
||||
valueSources,
|
||||
postProcessors, problems );
|
||||
postProcessors,
|
||||
problems );
|
||||
|
||||
if ( !interpolated.equals( value ) )
|
||||
{
|
||||
|
@ -271,10 +268,10 @@ public class StringSearchModelInterpolator
|
|||
}
|
||||
else
|
||||
{
|
||||
Object value = fields[i].get( target );
|
||||
Object value = currentField.get( target );
|
||||
if ( value != null )
|
||||
{
|
||||
if ( fields[i].getType().isArray() )
|
||||
if ( currentField.getType().isArray() )
|
||||
{
|
||||
evaluateArray( value );
|
||||
}
|
||||
|
@ -287,18 +284,21 @@ public class StringSearchModelInterpolator
|
|||
}
|
||||
catch ( IllegalArgumentException e )
|
||||
{
|
||||
problems.add( Severity.ERROR, "Failed to interpolate field: " + fields[i]
|
||||
+ " on class: " + cls.getName(), e );
|
||||
e.printStackTrace(System.err);
|
||||
|
||||
problems.add( Severity.ERROR, "Failed to interpolate field3: " + currentField +
|
||||
" on class: " + cls.getName(), e );
|
||||
}
|
||||
catch ( IllegalAccessException e )
|
||||
{
|
||||
problems.add( Severity.ERROR, "Failed to interpolate field: " + fields[i]
|
||||
+ " on class: " + cls.getName(), e );
|
||||
e.printStackTrace(System.err);
|
||||
problems.add( Severity.ERROR, "Failed to interpolate field4: " + currentField +
|
||||
" on class: " + cls.getName(), e );
|
||||
}
|
||||
finally
|
||||
{
|
||||
currentField.setAccessible( isAccessible );
|
||||
}
|
||||
}
|
||||
finally
|
||||
{
|
||||
fields[i].setAccessible( isAccessible );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -307,6 +307,20 @@ public class StringSearchModelInterpolator
|
|||
}
|
||||
}
|
||||
|
||||
private Field[] getFields(Class<?> cls) {
|
||||
Field[] fields;
|
||||
synchronized(fieldsByClass)
|
||||
{
|
||||
fields = fieldsByClass.get( cls );
|
||||
if ( fields == null )
|
||||
{
|
||||
fields = cls.getDeclaredFields();
|
||||
fieldsByClass.put( cls, fields );
|
||||
}
|
||||
}
|
||||
return fields;
|
||||
}
|
||||
|
||||
private boolean isQualifiedForInterpolation( Class<?> cls )
|
||||
{
|
||||
return !cls.getName().startsWith( "java" );
|
||||
|
@ -314,23 +328,23 @@ public class StringSearchModelInterpolator
|
|||
|
||||
private boolean isQualifiedForInterpolation( Field field, Class<?> fieldType )
|
||||
{
|
||||
Boolean primitive = fieldIsPrimitiveByClass.get( fieldType );
|
||||
if ( primitive == null )
|
||||
Boolean primitive;
|
||||
synchronized ( fieldIsPrimitiveByClass)
|
||||
{
|
||||
primitive = Boolean.valueOf( fieldType.isPrimitive() );
|
||||
fieldIsPrimitiveByClass.put( fieldType, primitive );
|
||||
primitive = fieldIsPrimitiveByClass.get( fieldType );
|
||||
if ( primitive == null )
|
||||
{
|
||||
primitive = fieldType.isPrimitive();
|
||||
fieldIsPrimitiveByClass.put( fieldType, primitive );
|
||||
}
|
||||
}
|
||||
if ( primitive.booleanValue() )
|
||||
if ( primitive )
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if ( "parent".equals( field.getName() ) )
|
||||
{
|
||||
return false;
|
||||
}
|
||||
return !"parent".equals(field.getName());
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
private void evaluateArray( Object target )
|
||||
|
|
|
@ -0,0 +1,466 @@
|
|||
package org.apache.maven.model.interpolation;
|
||||
|
||||
/*
|
||||
* 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.apache.maven.model.Build;
|
||||
import org.apache.maven.model.Dependency;
|
||||
import org.apache.maven.model.Model;
|
||||
import org.apache.maven.model.Organization;
|
||||
import org.apache.maven.model.Repository;
|
||||
import org.apache.maven.model.Resource;
|
||||
import org.apache.maven.model.Scm;
|
||||
import org.apache.maven.model.building.DefaultModelBuildingRequest;
|
||||
import org.apache.maven.model.building.ModelBuildingRequest;
|
||||
import org.apache.maven.model.building.SimpleProblemCollector;
|
||||
import org.apache.maven.model.path.PathTranslator;
|
||||
import org.codehaus.plexus.PlexusTestCase;
|
||||
|
||||
import java.io.File;
|
||||
import java.text.SimpleDateFormat;
|
||||
import java.util.Calendar;
|
||||
import java.util.Date;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
import java.util.Properties;
|
||||
|
||||
/**
|
||||
* @author jdcasey
|
||||
* @version $Id: AbstractModelInterpolatorTest.java 813569 2009-09-10 20:04:14Z jdcasey $
|
||||
*/
|
||||
public abstract class AbstractModelInterpolatorTest
|
||||
extends PlexusTestCase
|
||||
{
|
||||
private Properties context;
|
||||
|
||||
protected void setUp()
|
||||
throws Exception
|
||||
{
|
||||
super.setUp();
|
||||
|
||||
context = new Properties();
|
||||
context.put( "basedir", "myBasedir" );
|
||||
context.put( "project.baseUri", "myBaseUri" );
|
||||
}
|
||||
|
||||
|
||||
protected void assertProblemFree(SimpleProblemCollector collector){
|
||||
|
||||
assertEquals( "Expected no errors", 0, collector.getErrors().size() );
|
||||
assertEquals( "Expected no warnings", 0, collector.getWarnings().size() );
|
||||
assertEquals( "Expected no fatals", 0, collector.getFatals().size() );
|
||||
}
|
||||
protected void assertColllectorState(int numFatals, int numErrors, int numWarnings, SimpleProblemCollector collector){
|
||||
assertEquals( "Errors", numErrors, collector.getErrors().size() );
|
||||
assertEquals( "Warnings", numWarnings, collector.getWarnings().size() );
|
||||
assertEquals( "Fatals", numFatals, collector.getFatals().size() );
|
||||
}
|
||||
|
||||
private ModelBuildingRequest createModelBuildingRequest(Properties p) {
|
||||
ModelBuildingRequest config = new DefaultModelBuildingRequest();
|
||||
if (p!= null) config.setSystemProperties( p);
|
||||
return config;
|
||||
}
|
||||
|
||||
public void testDefaultBuildTimestampFormatShouldParseTimeIn24HourFormat()
|
||||
{
|
||||
Calendar cal = Calendar.getInstance();
|
||||
cal.set( Calendar.HOUR, 12 );
|
||||
cal.set( Calendar.AM_PM, Calendar.AM );
|
||||
|
||||
// just to make sure all the bases are covered...
|
||||
cal.set( Calendar.HOUR_OF_DAY, 0 );
|
||||
cal.set( Calendar.MINUTE, 16 );
|
||||
cal.set( Calendar.YEAR, 1976 );
|
||||
cal.set( Calendar.MONTH, Calendar.NOVEMBER );
|
||||
cal.set( Calendar.DATE, 11 );
|
||||
|
||||
Date firstTestDate = cal.getTime();
|
||||
|
||||
cal.set( Calendar.HOUR, 11 );
|
||||
cal.set( Calendar.AM_PM, Calendar.PM );
|
||||
|
||||
// just to make sure all the bases are covered...
|
||||
cal.set( Calendar.HOUR_OF_DAY, 23 );
|
||||
|
||||
Date secondTestDate = cal.getTime();
|
||||
|
||||
SimpleDateFormat format = new SimpleDateFormat( AbstractStringBasedModelInterpolator.DEFAULT_BUILD_TIMESTAMP_FORMAT );
|
||||
assertEquals( "19761111-0016", format.format( firstTestDate ) );
|
||||
assertEquals( "19761111-2316", format.format( secondTestDate ) );
|
||||
}
|
||||
|
||||
public void testShouldNotThrowExceptionOnReferenceToNonExistentValue()
|
||||
throws Exception
|
||||
{
|
||||
Model model = new Model();
|
||||
|
||||
Scm scm = new Scm();
|
||||
scm.setConnection( "${test}/somepath" );
|
||||
|
||||
model.setScm( scm );
|
||||
|
||||
ModelInterpolator interpolator = createInterpolator();
|
||||
|
||||
final SimpleProblemCollector collector = new SimpleProblemCollector();
|
||||
Model out = interpolator.interpolateModel( model, new File("."), createModelBuildingRequest(context),
|
||||
collector );
|
||||
|
||||
assertProblemFree( collector );
|
||||
assertEquals( "${test}/somepath", out.getScm().getConnection() );
|
||||
}
|
||||
|
||||
public void testShouldThrowExceptionOnRecursiveScmConnectionReference()
|
||||
throws Exception
|
||||
{
|
||||
Model model = new Model();
|
||||
|
||||
Scm scm = new Scm();
|
||||
scm.setConnection( "${project.scm.connection}/somepath" );
|
||||
|
||||
model.setScm( scm );
|
||||
|
||||
try
|
||||
{
|
||||
ModelInterpolator interpolator = createInterpolator();
|
||||
|
||||
final SimpleProblemCollector collector = new SimpleProblemCollector();
|
||||
interpolator.interpolateModel( model, null, createModelBuildingRequest(context), collector );
|
||||
assertColllectorState( 0, 1, 0, collector );
|
||||
}
|
||||
catch ( Exception e )
|
||||
{
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
public void testShouldNotThrowExceptionOnReferenceToValueContainingNakedExpression()
|
||||
throws Exception
|
||||
{
|
||||
Model model = new Model();
|
||||
|
||||
Scm scm = new Scm();
|
||||
scm.setConnection( "${test}/somepath" );
|
||||
|
||||
model.setScm( scm );
|
||||
|
||||
model.addProperty( "test", "test" );
|
||||
|
||||
ModelInterpolator interpolator = createInterpolator();
|
||||
|
||||
final SimpleProblemCollector collector = new SimpleProblemCollector();
|
||||
Model out = interpolator.interpolateModel( model, new File("."), createModelBuildingRequest(context),
|
||||
collector );
|
||||
|
||||
assertProblemFree( collector );
|
||||
|
||||
|
||||
assertEquals( "test/somepath", out.getScm().getConnection() );
|
||||
}
|
||||
|
||||
public void testShouldInterpolateOrganizationNameCorrectly()
|
||||
throws Exception
|
||||
{
|
||||
String orgName = "MyCo";
|
||||
|
||||
Model model = new Model();
|
||||
model.setName( "${pom.organization.name} Tools" );
|
||||
|
||||
Organization org = new Organization();
|
||||
org.setName( orgName );
|
||||
|
||||
model.setOrganization( org );
|
||||
|
||||
ModelInterpolator interpolator = createInterpolator();
|
||||
|
||||
Model out = interpolator.interpolateModel( model, new File("."), createModelBuildingRequest(context), new SimpleProblemCollector() );
|
||||
|
||||
assertEquals( orgName + " Tools", out.getName() );
|
||||
}
|
||||
|
||||
public void testShouldInterpolateDependencyVersionToSetSameAsProjectVersion()
|
||||
throws Exception
|
||||
{
|
||||
Model model = new Model();
|
||||
model.setVersion( "3.8.1" );
|
||||
|
||||
Dependency dep = new Dependency();
|
||||
dep.setVersion( "${version}" );
|
||||
|
||||
model.addDependency( dep );
|
||||
|
||||
ModelInterpolator interpolator = createInterpolator();
|
||||
|
||||
final SimpleProblemCollector collector = new SimpleProblemCollector();
|
||||
Model out = interpolator.interpolateModel( model, new File("."), createModelBuildingRequest(context),
|
||||
collector );
|
||||
assertColllectorState(0, 0, 1, collector );
|
||||
|
||||
|
||||
assertEquals( "3.8.1", ( out.getDependencies().get( 0 ) ).getVersion() );
|
||||
}
|
||||
|
||||
public void testShouldNotInterpolateDependencyVersionWithInvalidReference()
|
||||
throws Exception
|
||||
{
|
||||
Model model = new Model();
|
||||
model.setVersion( "3.8.1" );
|
||||
|
||||
Dependency dep = new Dependency();
|
||||
dep.setVersion( "${something}" );
|
||||
|
||||
model.addDependency( dep );
|
||||
|
||||
/*
|
||||
// This is the desired behaviour, however there are too many crappy poms in the repo and an issue with the
|
||||
// timing of executing the interpolation
|
||||
|
||||
try
|
||||
{
|
||||
new RegexBasedModelInterpolator().interpolate( model, context );
|
||||
fail( "Should have failed to interpolate with invalid reference" );
|
||||
}
|
||||
catch ( ModelInterpolationException expected )
|
||||
{
|
||||
assertTrue( true );
|
||||
}
|
||||
*/
|
||||
|
||||
ModelInterpolator interpolator = createInterpolator();
|
||||
|
||||
final SimpleProblemCollector collector = new SimpleProblemCollector();
|
||||
Model out = interpolator.interpolateModel( model, new File("."), createModelBuildingRequest(context),
|
||||
collector );
|
||||
assertProblemFree( collector );
|
||||
|
||||
|
||||
assertEquals( "${something}", ( out.getDependencies().get( 0 ) ).getVersion() );
|
||||
}
|
||||
|
||||
public void testTwoReferences()
|
||||
throws Exception
|
||||
{
|
||||
Model model = new Model();
|
||||
model.setVersion( "3.8.1" );
|
||||
model.setArtifactId( "foo" );
|
||||
|
||||
Dependency dep = new Dependency();
|
||||
dep.setVersion( "${artifactId}-${version}" );
|
||||
|
||||
model.addDependency( dep );
|
||||
|
||||
ModelInterpolator interpolator = createInterpolator();
|
||||
|
||||
final SimpleProblemCollector collector = new SimpleProblemCollector();
|
||||
Model out = interpolator.interpolateModel( model, new File("."), createModelBuildingRequest(context),
|
||||
collector );
|
||||
assertColllectorState( 0, 0, 2, collector );
|
||||
|
||||
assertEquals( "foo-3.8.1", ( out.getDependencies().get( 0 ) ).getVersion() );
|
||||
|
||||
}
|
||||
|
||||
public void testBasedir()
|
||||
throws Exception
|
||||
{
|
||||
Model model = new Model();
|
||||
model.setVersion( "3.8.1" );
|
||||
model.setArtifactId( "foo" );
|
||||
|
||||
Repository repository = new Repository();
|
||||
|
||||
repository.setUrl( "file://localhost/${basedir}/temp-repo" );
|
||||
|
||||
model.addRepository( repository );
|
||||
|
||||
ModelInterpolator interpolator = createInterpolator();
|
||||
|
||||
final SimpleProblemCollector collector = new SimpleProblemCollector();
|
||||
Model out = interpolator.interpolateModel( model, null, createModelBuildingRequest(context), collector );
|
||||
assertProblemFree( collector );
|
||||
|
||||
|
||||
assertEquals( "file://localhost/myBasedir/temp-repo", ( out.getRepositories().get( 0 ) ).getUrl() );
|
||||
}
|
||||
|
||||
public void testBaseUri()
|
||||
throws Exception
|
||||
{
|
||||
Model model = new Model();
|
||||
model.setVersion( "3.8.1" );
|
||||
model.setArtifactId( "foo" );
|
||||
|
||||
Repository repository = new Repository();
|
||||
|
||||
repository.setUrl( "${project.baseUri}/temp-repo" );
|
||||
|
||||
model.addRepository( repository );
|
||||
|
||||
ModelInterpolator interpolator = createInterpolator();
|
||||
|
||||
final SimpleProblemCollector collector = new SimpleProblemCollector();
|
||||
Model out = interpolator.interpolateModel( model, null, createModelBuildingRequest(context), collector );
|
||||
assertProblemFree( collector );
|
||||
|
||||
|
||||
assertEquals( "myBaseUri/temp-repo", ( out.getRepositories().get( 0 ) ).getUrl() );
|
||||
}
|
||||
|
||||
public void testEnvars()
|
||||
throws Exception
|
||||
{
|
||||
Properties context = new Properties();
|
||||
|
||||
context.put( "env.HOME", "/path/to/home" );
|
||||
|
||||
Model model = new Model();
|
||||
|
||||
Properties modelProperties = new Properties();
|
||||
|
||||
modelProperties.setProperty( "outputDirectory", "${env.HOME}" );
|
||||
|
||||
model.setProperties( modelProperties );
|
||||
|
||||
ModelInterpolator interpolator = createInterpolator();
|
||||
|
||||
final SimpleProblemCollector collector = new SimpleProblemCollector();
|
||||
Model out = interpolator.interpolateModel( model, new File("."), createModelBuildingRequest(context),
|
||||
collector );
|
||||
assertProblemFree( collector );
|
||||
|
||||
|
||||
assertEquals( "/path/to/home", out.getProperties().getProperty( "outputDirectory" ) );
|
||||
}
|
||||
|
||||
public void testEnvarExpressionThatEvaluatesToNullReturnsTheLiteralString()
|
||||
throws Exception
|
||||
{
|
||||
Model model = new Model();
|
||||
|
||||
Properties modelProperties = new Properties();
|
||||
|
||||
modelProperties.setProperty( "outputDirectory", "${env.DOES_NOT_EXIST}" );
|
||||
|
||||
model.setProperties( modelProperties );
|
||||
|
||||
ModelInterpolator interpolator = createInterpolator();
|
||||
|
||||
final SimpleProblemCollector collector = new SimpleProblemCollector();
|
||||
Model out = interpolator.interpolateModel( model, new File("."), createModelBuildingRequest(context),
|
||||
collector );
|
||||
assertProblemFree( collector );
|
||||
|
||||
|
||||
assertEquals( out.getProperties().getProperty( "outputDirectory" ), "${env.DOES_NOT_EXIST}" );
|
||||
}
|
||||
|
||||
public void testExpressionThatEvaluatesToNullReturnsTheLiteralString()
|
||||
throws Exception
|
||||
{
|
||||
Model model = new Model();
|
||||
|
||||
Properties modelProperties = new Properties();
|
||||
|
||||
modelProperties.setProperty( "outputDirectory", "${DOES_NOT_EXIST}" );
|
||||
|
||||
model.setProperties( modelProperties );
|
||||
|
||||
ModelInterpolator interpolator = createInterpolator();
|
||||
|
||||
final SimpleProblemCollector collector = new SimpleProblemCollector();
|
||||
Model out = interpolator.interpolateModel( model, new File("."), createModelBuildingRequest(context),
|
||||
collector );
|
||||
assertProblemFree( collector );
|
||||
|
||||
|
||||
assertEquals( out.getProperties().getProperty( "outputDirectory" ), "${DOES_NOT_EXIST}" );
|
||||
}
|
||||
|
||||
public void testShouldInterpolateSourceDirectoryReferencedFromResourceDirectoryCorrectly()
|
||||
throws Exception
|
||||
{
|
||||
Model model = new Model();
|
||||
|
||||
Build build = new Build();
|
||||
build.setSourceDirectory( "correct" );
|
||||
|
||||
Resource res = new Resource();
|
||||
res.setDirectory( "${project.build.sourceDirectory}" );
|
||||
|
||||
build.addResource( res );
|
||||
|
||||
Resource res2 = new Resource();
|
||||
res2.setDirectory( "${pom.build.sourceDirectory}" );
|
||||
|
||||
build.addResource( res2 );
|
||||
|
||||
Resource res3 = new Resource();
|
||||
res3.setDirectory( "${build.sourceDirectory}" );
|
||||
|
||||
build.addResource( res3 );
|
||||
|
||||
model.setBuild( build );
|
||||
|
||||
ModelInterpolator interpolator = createInterpolator();
|
||||
|
||||
final SimpleProblemCollector collector = new SimpleProblemCollector();
|
||||
Model out = interpolator.interpolateModel( model, null, createModelBuildingRequest(context), collector );
|
||||
assertColllectorState( 0, 0, 2, collector );
|
||||
|
||||
|
||||
List outResources = out.getBuild().getResources();
|
||||
Iterator resIt = outResources.iterator();
|
||||
|
||||
assertEquals( build.getSourceDirectory(), ( (Resource) resIt.next() ).getDirectory() );
|
||||
assertEquals( build.getSourceDirectory(), ( (Resource) resIt.next() ).getDirectory() );
|
||||
assertEquals( build.getSourceDirectory(), ( (Resource) resIt.next() ).getDirectory() );
|
||||
}
|
||||
|
||||
public void testShouldInterpolateUnprefixedBasedirExpression()
|
||||
throws Exception
|
||||
{
|
||||
File basedir = new File( "/test/path" );
|
||||
Model model = new Model();
|
||||
Dependency dep = new Dependency();
|
||||
dep.setSystemPath( "${basedir}/artifact.jar" );
|
||||
|
||||
model.addDependency( dep );
|
||||
|
||||
ModelInterpolator interpolator = createInterpolator();
|
||||
|
||||
final SimpleProblemCollector collector = new SimpleProblemCollector();
|
||||
Model result = interpolator.interpolateModel( model, basedir, createModelBuildingRequest(context), collector );
|
||||
assertProblemFree( collector );
|
||||
|
||||
|
||||
List rDeps = result.getDependencies();
|
||||
assertNotNull( rDeps );
|
||||
assertEquals( 1, rDeps.size() );
|
||||
assertEquals( new File( basedir, "artifact.jar" ).getAbsolutePath(), new File( ( (Dependency) rDeps.get( 0 ) )
|
||||
.getSystemPath() ).getAbsolutePath() );
|
||||
}
|
||||
|
||||
protected abstract ModelInterpolator createInterpolator( PathTranslator translator )
|
||||
throws Exception;
|
||||
|
||||
protected abstract ModelInterpolator createInterpolator()
|
||||
throws Exception;
|
||||
|
||||
|
||||
}
|
|
@ -19,21 +19,435 @@ package org.apache.maven.model.interpolation;
|
|||
* under the License.
|
||||
*/
|
||||
|
||||
import java.util.Properties;
|
||||
|
||||
import org.apache.maven.model.Model;
|
||||
import org.apache.maven.model.building.DefaultModelBuildingRequest;
|
||||
import org.apache.maven.model.building.ModelBuildingRequest;
|
||||
import org.apache.maven.model.building.SimpleProblemCollector;
|
||||
|
||||
import junit.framework.TestCase;
|
||||
import java.io.File;
|
||||
import java.util.*;
|
||||
import java.util.concurrent.Callable;
|
||||
import java.util.concurrent.CountDownLatch;
|
||||
import java.util.concurrent.Future;
|
||||
import java.util.concurrent.FutureTask;
|
||||
|
||||
/**
|
||||
* @author jdcasey
|
||||
* @author Benjamin Bentmann
|
||||
* @version $Id$
|
||||
*/
|
||||
public class StringSearchModelInterpolatorTest
|
||||
extends TestCase
|
||||
extends AbstractModelInterpolatorTest
|
||||
{
|
||||
|
||||
|
||||
protected ModelInterpolator interpolator;
|
||||
|
||||
@Override
|
||||
protected void setUp()
|
||||
throws Exception
|
||||
{
|
||||
super.setUp();
|
||||
interpolator = lookup(ModelInterpolator.class);
|
||||
}
|
||||
|
||||
|
||||
protected ModelInterpolator createInterpolator( org.apache.maven.model.path.PathTranslator translator )
|
||||
throws Exception
|
||||
{
|
||||
return this.interpolator;
|
||||
}
|
||||
|
||||
protected ModelInterpolator createInterpolator()
|
||||
throws Exception
|
||||
{
|
||||
return this.interpolator;
|
||||
}
|
||||
|
||||
public void testInterpolateStringArray()
|
||||
throws Exception
|
||||
{
|
||||
Model model = new Model();
|
||||
|
||||
Properties p = new Properties();
|
||||
p.setProperty( "key", "value" );
|
||||
p.setProperty( "key2", "value2" );
|
||||
|
||||
String[] values = { "${key}", "${key2}" };
|
||||
|
||||
StringSearchModelInterpolator interpolator = (StringSearchModelInterpolator) createInterpolator();
|
||||
|
||||
ModelBuildingRequest config = createModelBuildingRequest(p);
|
||||
|
||||
final SimpleProblemCollector collector = new SimpleProblemCollector();
|
||||
interpolator.interpolateObject( values, model, new File( "." ), config, collector );
|
||||
assertProblemFree( collector );
|
||||
|
||||
|
||||
assertEquals( "value", values[0] );
|
||||
assertEquals( "value2", values[1] );
|
||||
}
|
||||
|
||||
private ModelBuildingRequest createModelBuildingRequest(Properties p) {
|
||||
ModelBuildingRequest config = new DefaultModelBuildingRequest();
|
||||
config.setSystemProperties( p);
|
||||
return config;
|
||||
}
|
||||
|
||||
public void testInterpolateObjectWithStringArrayField()
|
||||
throws Exception
|
||||
{
|
||||
Model model = new Model();
|
||||
|
||||
Properties p = new Properties();
|
||||
p.setProperty( "key", "value" );
|
||||
p.setProperty( "key2", "value2" );
|
||||
|
||||
String[] values = { "${key}", "${key2}" };
|
||||
|
||||
ObjectWithStringArrayField obj = new ObjectWithStringArrayField( values );
|
||||
|
||||
StringSearchModelInterpolator interpolator = (StringSearchModelInterpolator) createInterpolator();
|
||||
|
||||
ModelBuildingRequest config = createModelBuildingRequest(p);
|
||||
|
||||
final SimpleProblemCollector collector = new SimpleProblemCollector();
|
||||
interpolator.interpolateObject( obj, model, new File( "." ), config, collector );
|
||||
assertProblemFree( collector );
|
||||
|
||||
|
||||
assertEquals( "value", obj.values[0] );
|
||||
assertEquals( "value2", obj.values[1] );
|
||||
}
|
||||
|
||||
public void testInterpolateObjectWithStringListField()
|
||||
throws Exception
|
||||
{
|
||||
Model model = new Model();
|
||||
|
||||
Properties p = new Properties();
|
||||
p.setProperty( "key", "value" );
|
||||
p.setProperty( "key2", "value2" );
|
||||
|
||||
List<String> values = new ArrayList<String>();
|
||||
values.add( "${key}" );
|
||||
values.add( "${key2}" );
|
||||
|
||||
ObjectWithListField obj = new ObjectWithListField( values );
|
||||
|
||||
StringSearchModelInterpolator interpolator = (StringSearchModelInterpolator) createInterpolator();
|
||||
|
||||
ModelBuildingRequest config = createModelBuildingRequest(p);
|
||||
|
||||
final SimpleProblemCollector collector = new SimpleProblemCollector();
|
||||
interpolator.interpolateObject( obj, model, new File( "." ), config, collector );
|
||||
assertProblemFree( collector );
|
||||
|
||||
|
||||
assertEquals( "value", obj.values.get( 0 ) );
|
||||
assertEquals( "value2", obj.values.get( 1 ) );
|
||||
}
|
||||
|
||||
public void testInterpolateObjectWithStringListFieldAndOneLiteralValue()
|
||||
throws Exception
|
||||
{
|
||||
Model model = new Model();
|
||||
|
||||
Properties p = new Properties();
|
||||
p.setProperty( "key", "value" );
|
||||
p.setProperty( "key2", "value2" );
|
||||
|
||||
List<String> values = new ArrayList<String>();
|
||||
values.add( "key" );
|
||||
values.add( "${key2}" );
|
||||
|
||||
ObjectWithListField obj = new ObjectWithListField( values );
|
||||
|
||||
StringSearchModelInterpolator interpolator = (StringSearchModelInterpolator) createInterpolator();
|
||||
|
||||
ModelBuildingRequest config = createModelBuildingRequest(p);
|
||||
|
||||
final SimpleProblemCollector collector = new SimpleProblemCollector();
|
||||
interpolator.interpolateObject( obj, model, new File( "." ), config, collector );
|
||||
assertProblemFree( collector );
|
||||
|
||||
|
||||
assertEquals( "key", obj.values.get( 0 ) );
|
||||
assertEquals( "value2", obj.values.get( 1 ) );
|
||||
}
|
||||
|
||||
public void testInterpolateObjectWithUnmodifiableStringListField()
|
||||
throws Exception
|
||||
{
|
||||
Model model = new Model();
|
||||
|
||||
Properties p = new Properties();
|
||||
p.setProperty( "key", "value" );
|
||||
p.setProperty( "key2", "value2" );
|
||||
|
||||
List values = Collections.unmodifiableList( Collections.singletonList( "${key}" ) );
|
||||
|
||||
ObjectWithListField obj = new ObjectWithListField( values );
|
||||
|
||||
StringSearchModelInterpolator interpolator = (StringSearchModelInterpolator) createInterpolator();
|
||||
|
||||
ModelBuildingRequest config = createModelBuildingRequest(p);
|
||||
|
||||
final SimpleProblemCollector collector = new SimpleProblemCollector();
|
||||
interpolator.interpolateObject( obj, model, new File( "." ), config, collector );
|
||||
assertProblemFree( collector );
|
||||
|
||||
|
||||
assertEquals( "${key}", obj.values.get( 0 ) );
|
||||
}
|
||||
|
||||
public void testInterpolateObjectWithStringArrayListField()
|
||||
throws Exception
|
||||
{
|
||||
Model model = new Model();
|
||||
|
||||
Properties p = new Properties();
|
||||
p.setProperty( "key", "value" );
|
||||
p.setProperty( "key2", "value2" );
|
||||
p.setProperty( "key3", "value3" );
|
||||
p.setProperty( "key4", "value4" );
|
||||
|
||||
List<String[]> values = new ArrayList<String[]>();
|
||||
values.add( new String[] { "${key}", "${key2}" } );
|
||||
values.add( new String[] { "${key3}", "${key4}" } );
|
||||
|
||||
ObjectWithListField obj = new ObjectWithListField( values );
|
||||
|
||||
StringSearchModelInterpolator interpolator = (StringSearchModelInterpolator) createInterpolator();
|
||||
|
||||
ModelBuildingRequest config = createModelBuildingRequest(p);
|
||||
|
||||
final SimpleProblemCollector collector = new SimpleProblemCollector();
|
||||
interpolator.interpolateObject( obj, model, new File( "." ), config, collector );
|
||||
assertProblemFree( collector );
|
||||
|
||||
|
||||
assertEquals( "value", ( (String[]) obj.values.get( 0 ) )[0] );
|
||||
assertEquals( "value2", ( (String[]) obj.values.get( 0 ) )[1] );
|
||||
assertEquals( "value3", ( (String[]) obj.values.get( 1 ) )[0] );
|
||||
assertEquals( "value4", ( (String[]) obj.values.get( 1 ) )[1] );
|
||||
}
|
||||
|
||||
public void testInterpolateObjectWithStringToStringMapField()
|
||||
throws Exception
|
||||
{
|
||||
Model model = new Model();
|
||||
|
||||
Properties p = new Properties();
|
||||
p.setProperty( "key", "value" );
|
||||
p.setProperty( "key2", "value2" );
|
||||
|
||||
Map<String, String> values = new HashMap<String, String>();
|
||||
values.put( "key", "${key}" );
|
||||
values.put( "key2", "${key2}" );
|
||||
|
||||
ObjectWithMapField obj = new ObjectWithMapField( values );
|
||||
|
||||
StringSearchModelInterpolator interpolator = (StringSearchModelInterpolator) createInterpolator();
|
||||
|
||||
ModelBuildingRequest config = createModelBuildingRequest(p);
|
||||
|
||||
final SimpleProblemCollector collector = new SimpleProblemCollector();
|
||||
interpolator.interpolateObject( obj, model, new File( "." ), config, collector );
|
||||
assertProblemFree( collector );
|
||||
|
||||
|
||||
assertEquals( "value", obj.values.get( "key" ) );
|
||||
assertEquals( "value2", obj.values.get( "key2" ) );
|
||||
}
|
||||
|
||||
public void testInterpolateObjectWithStringToStringMapFieldAndOneLiteralValue()
|
||||
throws Exception
|
||||
{
|
||||
Model model = new Model();
|
||||
|
||||
Properties p = new Properties();
|
||||
p.setProperty( "key", "value" );
|
||||
p.setProperty( "key2", "value2" );
|
||||
|
||||
Map<String, String> values = new HashMap<String, String>();
|
||||
values.put( "key", "val" );
|
||||
values.put( "key2", "${key2}" );
|
||||
|
||||
ObjectWithMapField obj = new ObjectWithMapField( values );
|
||||
|
||||
StringSearchModelInterpolator interpolator = (StringSearchModelInterpolator) createInterpolator();
|
||||
|
||||
ModelBuildingRequest config = createModelBuildingRequest(p);
|
||||
|
||||
final SimpleProblemCollector collector = new SimpleProblemCollector();
|
||||
interpolator.interpolateObject( obj, model, new File( "." ), config, collector );
|
||||
assertProblemFree( collector );
|
||||
|
||||
|
||||
assertEquals( "val", obj.values.get( "key" ) );
|
||||
assertEquals( "value2", obj.values.get( "key2" ) );
|
||||
}
|
||||
|
||||
public void testInterpolateObjectWithUnmodifiableStringToStringMapField()
|
||||
throws Exception
|
||||
{
|
||||
Model model = new Model();
|
||||
|
||||
Properties p = new Properties();
|
||||
p.setProperty( "key", "value" );
|
||||
p.setProperty( "key2", "value2" );
|
||||
|
||||
Map values = Collections.unmodifiableMap( Collections.singletonMap( "key", "${key}" ) );
|
||||
|
||||
ObjectWithMapField obj = new ObjectWithMapField( values );
|
||||
|
||||
StringSearchModelInterpolator interpolator = (StringSearchModelInterpolator) createInterpolator();
|
||||
|
||||
ModelBuildingRequest config = createModelBuildingRequest(p);
|
||||
|
||||
final SimpleProblemCollector collector = new SimpleProblemCollector();
|
||||
interpolator.interpolateObject( obj, model, new File( "." ), config, collector );
|
||||
assertProblemFree( collector );
|
||||
|
||||
|
||||
assertEquals( "${key}", obj.values.get( "key" ) );
|
||||
}
|
||||
|
||||
public void testInterpolateObjectWithStringToStringArrayMapField()
|
||||
throws Exception
|
||||
{
|
||||
Model model = new Model();
|
||||
|
||||
Properties p = new Properties();
|
||||
p.setProperty( "key", "value" );
|
||||
p.setProperty( "key2", "value2" );
|
||||
p.setProperty( "key3", "value3" );
|
||||
p.setProperty( "key4", "value4" );
|
||||
|
||||
Map<String, String[]> values = new HashMap<String, String[]>();
|
||||
values.put( "key", new String[] { "${key}", "${key2}" } );
|
||||
values.put( "key2", new String[] { "${key3}", "${key4}" } );
|
||||
|
||||
ObjectWithMapField obj = new ObjectWithMapField( values );
|
||||
|
||||
StringSearchModelInterpolator interpolator = (StringSearchModelInterpolator) createInterpolator();
|
||||
|
||||
ModelBuildingRequest config = createModelBuildingRequest(p);
|
||||
|
||||
final SimpleProblemCollector collector = new SimpleProblemCollector();
|
||||
interpolator.interpolateObject( obj, model, new File( "." ), config, collector );
|
||||
assertProblemFree( collector );
|
||||
|
||||
|
||||
assertEquals( "value", ( (String[]) obj.values.get( "key" ) )[0] );
|
||||
assertEquals( "value2", ( (String[]) obj.values.get( "key" ) )[1] );
|
||||
assertEquals( "value3", ( (String[]) obj.values.get( "key2" ) )[0] );
|
||||
assertEquals( "value4", ( (String[]) obj.values.get( "key2" ) )[1] );
|
||||
}
|
||||
|
||||
|
||||
public void testConcurrentInterpolation() throws Exception {
|
||||
final Model model = new Model();
|
||||
|
||||
Properties p = new Properties();
|
||||
p.setProperty( "key", "value" );
|
||||
p.setProperty( "key2", "value2" );
|
||||
p.setProperty( "key3", "value3" );
|
||||
p.setProperty( "key4", "value4" );
|
||||
|
||||
List<String[]> values = new ArrayList<String[]>();
|
||||
|
||||
values.add( new String[] { "${key}", "${key2}" } );
|
||||
values.add( new String[] { "${key3}", "${key4}" } );
|
||||
List values2 = new ArrayList();
|
||||
values.add( new String[] { "${key}", "${key2}" } );
|
||||
values.add( new String[] { "${key3}", "${key4}" } );
|
||||
List values3 = new ArrayList();
|
||||
values.add( new String[] { "${key}", "${key2}" } );
|
||||
values.add( new String[] { "${key3}", "${key4}" } );
|
||||
|
||||
// There is an interesting issue here; if I send three identical collections into the three Lists in "obj",
|
||||
// like this:
|
||||
// final ObjectWithMixedProtection obj = new ObjectWithMixedProtection( values, values, values );
|
||||
// I will have concurrency issues on the interpolation of the individual collections, since current
|
||||
// synchronization is per-field and not per-underlying object.
|
||||
// If this turns out to be a realistic use case, we will need to synchronize on the underlying collection
|
||||
// in the interpolate method.
|
||||
|
||||
final ObjectWithMixedProtection obj = new ObjectWithMixedProtection( values, values2, values3 );
|
||||
final StringSearchModelInterpolator interpolator = (StringSearchModelInterpolator) createInterpolator();
|
||||
final ModelBuildingRequest config = createModelBuildingRequest(p);
|
||||
|
||||
|
||||
int numItems = 250;
|
||||
final CountDownLatch countDownLatch = new CountDownLatch(1);
|
||||
|
||||
List<Future<SimpleProblemCollector>> futures = new ArrayList<Future<SimpleProblemCollector>>();
|
||||
for (int i = 0; i < numItems; i++){
|
||||
Callable<SimpleProblemCollector> future = new Callable<SimpleProblemCollector>() {
|
||||
public SimpleProblemCollector call() throws Exception {
|
||||
countDownLatch.await();
|
||||
final SimpleProblemCollector collector = new SimpleProblemCollector();
|
||||
interpolator.interpolateObject( obj, model, new File( "." ), config, collector);
|
||||
return collector;
|
||||
}
|
||||
};
|
||||
FutureTask<SimpleProblemCollector> task = new FutureTask<SimpleProblemCollector>(future);
|
||||
futures.add ( task);
|
||||
new Thread( task).start();
|
||||
}
|
||||
countDownLatch.countDown(); // Start all the threads
|
||||
for(Future<SimpleProblemCollector> result : futures){
|
||||
result.get(); // ArrayIndexOutOfBoundsException are typical indication of threading issues
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private static final class ObjectWithStringArrayField
|
||||
{
|
||||
private final String[] values;
|
||||
|
||||
public ObjectWithStringArrayField( String[] values )
|
||||
{
|
||||
this.values = values;
|
||||
}
|
||||
}
|
||||
|
||||
private static final class ObjectWithListField
|
||||
{
|
||||
private final List values;
|
||||
|
||||
public ObjectWithListField( List values )
|
||||
{
|
||||
this.values = values;
|
||||
}
|
||||
}
|
||||
|
||||
private static final class ObjectWithMapField
|
||||
{
|
||||
private final Map values;
|
||||
|
||||
public ObjectWithMapField( Map values )
|
||||
{
|
||||
this.values = values;
|
||||
}
|
||||
}
|
||||
|
||||
@SuppressWarnings({"UnusedDeclaration"})
|
||||
private static final class ObjectWithMixedProtection
|
||||
{
|
||||
private List values1;
|
||||
protected List values2;
|
||||
List values3;
|
||||
|
||||
private ObjectWithMixedProtection(List values1, List values2, List values3) {
|
||||
this.values1 = values1;
|
||||
this.values2 = values2;
|
||||
this.values3 = values3;
|
||||
}
|
||||
}
|
||||
|
||||
public void testFinalFieldsExcludedFromInterpolation()
|
||||
{
|
||||
Properties props = new Properties();
|
||||
|
@ -45,16 +459,12 @@ public class StringSearchModelInterpolatorTest
|
|||
StringSearchModelInterpolator interpolator = new StringSearchModelInterpolator();
|
||||
interpolator.interpolateObject( new ClassWithFinalField(), new Model(), null, request, problems );
|
||||
|
||||
assertTrue( problems.getFatals().toString(), problems.getFatals().isEmpty() );
|
||||
assertTrue( problems.getErrors().toString(), problems.getErrors().isEmpty() );
|
||||
assertTrue( problems.getWarnings().toString(), problems.getWarnings().isEmpty() );
|
||||
assertProblemFree( problems );
|
||||
}
|
||||
|
||||
@SuppressWarnings({"UnusedDeclaration"})
|
||||
static class ClassWithFinalField
|
||||
{
|
||||
|
||||
public static final String CONSTANT = "${expression}";
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue