mirror of https://github.com/apache/maven.git
o Flipped interpolation over to use the in-memory based interpolator from 2.2.x which makes the overall building twice as fast as before
git-svn-id: https://svn.apache.org/repos/asf/maven/components/trunk@780749 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
parent
9501ad8835
commit
0968ba79f3
|
@ -29,6 +29,10 @@
|
|||
<groupId>org.codehaus.plexus</groupId>
|
||||
<artifactId>plexus-utils</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.codehaus.plexus</groupId>
|
||||
<artifactId>plexus-interpolation</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.codehaus.plexus</groupId>
|
||||
<artifactId>plexus-component-annotations</artifactId>
|
||||
|
|
|
@ -28,11 +28,13 @@ import java.util.List;
|
|||
import java.util.Map;
|
||||
|
||||
import org.apache.maven.model.inheritance.InheritanceAssembler;
|
||||
import org.apache.maven.model.interpolator.Interpolator;
|
||||
import org.apache.maven.model.interpolation.ModelInterpolationException;
|
||||
import org.apache.maven.model.interpolation.ModelInterpolator;
|
||||
import org.apache.maven.model.io.ModelParseException;
|
||||
import org.apache.maven.model.io.ModelReader;
|
||||
import org.apache.maven.model.management.ManagementInjector;
|
||||
import org.apache.maven.model.normalization.ModelNormalizer;
|
||||
import org.apache.maven.model.path.ModelPathTranslator;
|
||||
import org.apache.maven.model.plugin.LifecycleBindingsInjector;
|
||||
import org.apache.maven.model.plugin.PluginConfigurationExpander;
|
||||
import org.apache.maven.model.profile.ProfileActivationException;
|
||||
|
@ -66,7 +68,10 @@ public class DefaultModelBuilder
|
|||
private ModelNormalizer modelNormalizer;
|
||||
|
||||
@Requirement
|
||||
private Interpolator modelInterpolator;
|
||||
private ModelInterpolator modelInterpolator;
|
||||
|
||||
@Requirement
|
||||
private ModelPathTranslator modelPathTranslator;
|
||||
|
||||
@Requirement
|
||||
private InheritanceAssembler inheritanceAssembler;
|
||||
|
@ -155,6 +160,8 @@ public class DefaultModelBuilder
|
|||
resultModel = interpolateModel( resultModel, request );
|
||||
resultModels.set( 0, resultModel );
|
||||
|
||||
modelPathTranslator.alignToBaseDirectory( resultModel, resultModel.getProjectDirectory() );
|
||||
|
||||
if ( request.isProcessPlugins() )
|
||||
{
|
||||
lifecycleBindingsInjector.injectLifecycleBindings( resultModel );
|
||||
|
@ -281,14 +288,11 @@ public class DefaultModelBuilder
|
|||
{
|
||||
try
|
||||
{
|
||||
Model result =
|
||||
modelInterpolator.interpolateModel( model,
|
||||
request.getProfileActivationContext().getExecutionProperties(),
|
||||
model.getProjectDirectory() );
|
||||
Model result = modelInterpolator.interpolateModel( model, model.getProjectDirectory(), request );
|
||||
result.setPomFile( model.getPomFile() );
|
||||
return result;
|
||||
}
|
||||
catch ( IOException e )
|
||||
catch ( ModelInterpolationException e )
|
||||
{
|
||||
throw new ModelBuildingException( "Failed to interpolate model " + toSourceHint( model ), e );
|
||||
}
|
||||
|
|
|
@ -0,0 +1,229 @@
|
|||
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.Model;
|
||||
import org.apache.maven.model.ModelBuildingRequest;
|
||||
import org.apache.maven.model.path.PathTranslator;
|
||||
import org.codehaus.plexus.component.annotations.Requirement;
|
||||
import org.codehaus.plexus.interpolation.AbstractValueSource;
|
||||
import org.codehaus.plexus.interpolation.InterpolationException;
|
||||
import org.codehaus.plexus.interpolation.InterpolationPostProcessor;
|
||||
import org.codehaus.plexus.interpolation.Interpolator;
|
||||
import org.codehaus.plexus.interpolation.MapBasedValueSource;
|
||||
import org.codehaus.plexus.interpolation.ObjectBasedValueSource;
|
||||
import org.codehaus.plexus.interpolation.PrefixAwareRecursionInterceptor;
|
||||
import org.codehaus.plexus.interpolation.PrefixedObjectValueSource;
|
||||
import org.codehaus.plexus.interpolation.PrefixedValueSourceWrapper;
|
||||
import org.codehaus.plexus.interpolation.RecursionInterceptor;
|
||||
import org.codehaus.plexus.interpolation.ValueSource;
|
||||
|
||||
import java.io.File;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.Properties;
|
||||
|
||||
/**
|
||||
* Use a regular expression search to find and resolve expressions within the POM.
|
||||
*
|
||||
* @author jdcasey Created on Feb 3, 2005
|
||||
* @version $Id$
|
||||
* @todo Consolidate this logic with the PluginParameterExpressionEvaluator, minus deprecations/bans.
|
||||
*/
|
||||
public abstract class AbstractStringBasedModelInterpolator
|
||||
implements ModelInterpolator
|
||||
{
|
||||
private static final List<String> PROJECT_PREFIXES = Arrays.asList( new String[]{ "pom.", "project." } );
|
||||
|
||||
private static final List<String> TRANSLATED_PATH_EXPRESSIONS;
|
||||
|
||||
static
|
||||
{
|
||||
List<String> translatedPrefixes = new ArrayList<String>();
|
||||
|
||||
// MNG-1927, MNG-2124, MNG-3355:
|
||||
// If the build section is present and the project directory is non-null, we should make
|
||||
// sure interpolation of the directories below uses translated paths.
|
||||
// Afterward, we'll double back and translate any paths that weren't covered during interpolation via the
|
||||
// code below...
|
||||
translatedPrefixes.add( "build.directory" );
|
||||
translatedPrefixes.add( "build.outputDirectory" );
|
||||
translatedPrefixes.add( "build.testOutputDirectory" );
|
||||
translatedPrefixes.add( "build.sourceDirectory" );
|
||||
translatedPrefixes.add( "build.testSourceDirectory" );
|
||||
translatedPrefixes.add( "build.scriptSourceDirectory" );
|
||||
translatedPrefixes.add( "reporting.outputDirectory" );
|
||||
|
||||
TRANSLATED_PATH_EXPRESSIONS = translatedPrefixes;
|
||||
}
|
||||
|
||||
@Requirement
|
||||
private PathTranslator pathTranslator;
|
||||
|
||||
private Interpolator interpolator;
|
||||
|
||||
private RecursionInterceptor recursionInterceptor;
|
||||
|
||||
public AbstractStringBasedModelInterpolator()
|
||||
{
|
||||
interpolator = createInterpolator();
|
||||
recursionInterceptor = new PrefixAwareRecursionInterceptor( PROJECT_PREFIXES );
|
||||
}
|
||||
|
||||
protected List<ValueSource> createValueSources( final Model model, final File projectDir, final ModelBuildingRequest config )
|
||||
{
|
||||
String timestampFormat = DEFAULT_BUILD_TIMESTAMP_FORMAT;
|
||||
|
||||
Properties modelProperties = model.getProperties();
|
||||
if ( modelProperties != null )
|
||||
{
|
||||
timestampFormat = modelProperties.getProperty( BUILD_TIMESTAMP_FORMAT_PROPERTY, timestampFormat );
|
||||
}
|
||||
|
||||
ValueSource modelValueSource1 = new PrefixedObjectValueSource( PROJECT_PREFIXES, model, false );
|
||||
ValueSource modelValueSource2 = new ObjectBasedValueSource( model );
|
||||
|
||||
ValueSource basedirValueSource = new PrefixedValueSourceWrapper( new AbstractValueSource( false ){
|
||||
public Object getValue( String expression )
|
||||
{
|
||||
if ( projectDir != null && "basedir".equals( expression ) )
|
||||
{
|
||||
return projectDir.getAbsolutePath();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
},
|
||||
PROJECT_PREFIXES, true );
|
||||
ValueSource baseUriValueSource = new PrefixedValueSourceWrapper( new AbstractValueSource( false ){
|
||||
public Object getValue( String expression )
|
||||
{
|
||||
if ( projectDir != null && "baseUri".equals( expression ) )
|
||||
{
|
||||
return projectDir.getAbsoluteFile().toURI().toString();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
},
|
||||
PROJECT_PREFIXES, false );
|
||||
|
||||
List<ValueSource> valueSources = new ArrayList<ValueSource>( 9 );
|
||||
|
||||
// NOTE: Order counts here!
|
||||
valueSources.add( basedirValueSource );
|
||||
valueSources.add( baseUriValueSource );
|
||||
// TODO: valueSources.add( new BuildTimestampValueSource( config.getBuildStartTime(), timestampFormat ) );
|
||||
valueSources.add( modelValueSource1 );
|
||||
valueSources.add( new MapBasedValueSource( modelProperties ) );
|
||||
valueSources.add( new MapBasedValueSource( config.getExecutionProperties() ) );
|
||||
valueSources.add( new AbstractValueSource( false )
|
||||
{
|
||||
public Object getValue( String expression )
|
||||
{
|
||||
return config.getExecutionProperties().getProperty( "env." + expression );
|
||||
}
|
||||
} );
|
||||
valueSources.add( modelValueSource2 );
|
||||
|
||||
return valueSources;
|
||||
}
|
||||
|
||||
protected List<InterpolationPostProcessor> createPostProcessors( final Model model, final File projectDir,
|
||||
final ModelBuildingRequest config )
|
||||
{
|
||||
return Collections.singletonList( (InterpolationPostProcessor) new PathTranslatingPostProcessor(
|
||||
PROJECT_PREFIXES,
|
||||
TRANSLATED_PATH_EXPRESSIONS,
|
||||
projectDir,
|
||||
pathTranslator ) );
|
||||
}
|
||||
|
||||
protected String interpolateInternal( String src, List<ValueSource> valueSources,
|
||||
List<InterpolationPostProcessor> postProcessors )
|
||||
throws ModelInterpolationException
|
||||
{
|
||||
if ( src.indexOf( "${" ) < 0 )
|
||||
{
|
||||
return src;
|
||||
}
|
||||
|
||||
String result = src;
|
||||
synchronized( this )
|
||||
{
|
||||
|
||||
for ( ValueSource vs : valueSources )
|
||||
{
|
||||
interpolator.addValueSource( vs );
|
||||
}
|
||||
|
||||
for ( InterpolationPostProcessor postProcessor : postProcessors )
|
||||
{
|
||||
interpolator.addPostProcessor( postProcessor );
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
try
|
||||
{
|
||||
result = interpolator.interpolate( result, recursionInterceptor );
|
||||
}
|
||||
catch( InterpolationException e )
|
||||
{
|
||||
throw new ModelInterpolationException( e.getMessage(), e );
|
||||
}
|
||||
|
||||
interpolator.clearFeedback();
|
||||
}
|
||||
finally
|
||||
{
|
||||
for ( ValueSource vs : valueSources )
|
||||
{
|
||||
interpolator.removeValuesSource( vs );
|
||||
}
|
||||
|
||||
for ( InterpolationPostProcessor postProcessor : postProcessors )
|
||||
{
|
||||
interpolator.removePostProcessor( postProcessor );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
protected RecursionInterceptor getRecursionInterceptor()
|
||||
{
|
||||
return recursionInterceptor;
|
||||
}
|
||||
|
||||
protected void setRecursionInterceptor( RecursionInterceptor recursionInterceptor )
|
||||
{
|
||||
this.recursionInterceptor = recursionInterceptor;
|
||||
}
|
||||
|
||||
protected abstract Interpolator createInterpolator();
|
||||
|
||||
protected final Interpolator getInterpolator()
|
||||
{
|
||||
return interpolator;
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,63 @@
|
|||
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 java.text.SimpleDateFormat;
|
||||
import java.util.Date;
|
||||
|
||||
import org.codehaus.plexus.interpolation.AbstractValueSource;
|
||||
|
||||
/**
|
||||
*
|
||||
* @version $Id$
|
||||
*/
|
||||
public class BuildTimestampValueSource
|
||||
extends AbstractValueSource
|
||||
{
|
||||
|
||||
private final Date startTime;
|
||||
|
||||
private final String format;
|
||||
|
||||
private String formattedDate;
|
||||
|
||||
public BuildTimestampValueSource( Date startTime, String format )
|
||||
{
|
||||
super( false );
|
||||
this.startTime = startTime;
|
||||
this.format = format;
|
||||
}
|
||||
|
||||
public Object getValue( String expression )
|
||||
{
|
||||
if ( "build.timestamp".equals( expression ) || "maven.build.timestamp".equals( expression ) )
|
||||
{
|
||||
if ( formattedDate == null && startTime != null )
|
||||
{
|
||||
formattedDate = new SimpleDateFormat( format ).format( startTime );
|
||||
}
|
||||
|
||||
return formattedDate;
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,42 @@
|
|||
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.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @author jdcasey
|
||||
* <p/>
|
||||
* Created on Feb 2, 2005
|
||||
*/
|
||||
@SuppressWarnings("serial")
|
||||
public class ModelInterpolationException
|
||||
extends Exception
|
||||
{
|
||||
|
||||
public ModelInterpolationException( String message )
|
||||
{
|
||||
super( message );
|
||||
}
|
||||
|
||||
public ModelInterpolationException( String message, Throwable cause )
|
||||
{
|
||||
super( message, cause );
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,42 @@
|
|||
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.Model;
|
||||
import org.apache.maven.model.ModelBuildingRequest;
|
||||
|
||||
import java.io.File;
|
||||
|
||||
/**
|
||||
* @author jdcasey
|
||||
* <p/>
|
||||
* Created on Feb 2, 2005
|
||||
*/
|
||||
public interface ModelInterpolator
|
||||
{
|
||||
|
||||
String DEFAULT_BUILD_TIMESTAMP_FORMAT = "yyyyMMdd-HHmm";
|
||||
|
||||
String BUILD_TIMESTAMP_FORMAT_PROPERTY = "maven.build.timestamp.format";
|
||||
|
||||
Model interpolateModel( Model model, File projectDir, ModelBuildingRequest request )
|
||||
throws ModelInterpolationException;
|
||||
|
||||
}
|
|
@ -0,0 +1,62 @@
|
|||
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.path.PathTranslator;
|
||||
import org.codehaus.plexus.interpolation.InterpolationPostProcessor;
|
||||
import org.codehaus.plexus.interpolation.util.ValueSourceUtils;
|
||||
|
||||
import java.io.File;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
*
|
||||
* @version $Id$
|
||||
*/
|
||||
public class PathTranslatingPostProcessor
|
||||
implements InterpolationPostProcessor
|
||||
{
|
||||
|
||||
private final List<String> unprefixedPathKeys;
|
||||
private final File projectDir;
|
||||
private final PathTranslator pathTranslator;
|
||||
private final List<String> expressionPrefixes;
|
||||
|
||||
public PathTranslatingPostProcessor( List<String> expressionPrefixes, List<String> unprefixedPathKeys, File projectDir, PathTranslator pathTranslator )
|
||||
{
|
||||
this.expressionPrefixes = expressionPrefixes;
|
||||
this.unprefixedPathKeys = unprefixedPathKeys;
|
||||
this.projectDir = projectDir;
|
||||
this.pathTranslator = pathTranslator;
|
||||
}
|
||||
|
||||
public Object execute( String expression, Object value )
|
||||
{
|
||||
expression = ValueSourceUtils.trimPrefix( expression, expressionPrefixes, true );
|
||||
|
||||
if ( projectDir != null && value != null && unprefixedPathKeys.contains( expression ) )
|
||||
{
|
||||
return pathTranslator.alignToBaseDirectory( String.valueOf( value ), projectDir );
|
||||
}
|
||||
|
||||
return value;
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,365 @@
|
|||
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.Model;
|
||||
import org.apache.maven.model.ModelBuildingRequest;
|
||||
import org.codehaus.plexus.component.annotations.Component;
|
||||
import org.codehaus.plexus.interpolation.InterpolationPostProcessor;
|
||||
import org.codehaus.plexus.interpolation.Interpolator;
|
||||
import org.codehaus.plexus.interpolation.StringSearchInterpolator;
|
||||
import org.codehaus.plexus.interpolation.ValueSource;
|
||||
|
||||
import java.io.File;
|
||||
import java.lang.reflect.Array;
|
||||
import java.lang.reflect.Field;
|
||||
import java.security.AccessController;
|
||||
import java.security.PrivilegedAction;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.WeakHashMap;
|
||||
|
||||
@Component( role = ModelInterpolator.class )
|
||||
public class StringSearchModelInterpolator
|
||||
extends AbstractStringBasedModelInterpolator
|
||||
{
|
||||
|
||||
private static final Map<Class<?>, Field[]> fieldsByClass = new WeakHashMap<Class<?>, Field[]>();
|
||||
private static final Map<Class<?>, Boolean> fieldIsPrimitiveByClass = new WeakHashMap<Class<?>, Boolean>();
|
||||
|
||||
public Model interpolateModel( Model model, File projectDir, ModelBuildingRequest config )
|
||||
throws ModelInterpolationException
|
||||
{
|
||||
interpolateObject( model, model, projectDir, config );
|
||||
|
||||
return model;
|
||||
}
|
||||
|
||||
protected void interpolateObject( Object obj, Model model, File projectDir, ModelBuildingRequest config )
|
||||
throws ModelInterpolationException
|
||||
{
|
||||
try
|
||||
{
|
||||
List<ValueSource> valueSources = createValueSources( model, projectDir, config );
|
||||
List<InterpolationPostProcessor> postProcessors = createPostProcessors( model, projectDir, config );
|
||||
|
||||
InterpolateObjectAction action =
|
||||
new InterpolateObjectAction( obj, valueSources, postProcessors, this );
|
||||
|
||||
ModelInterpolationException error = AccessController.doPrivileged( action );
|
||||
|
||||
if ( error != null )
|
||||
{
|
||||
throw error;
|
||||
}
|
||||
}
|
||||
finally
|
||||
{
|
||||
getInterpolator().clearAnswers();
|
||||
}
|
||||
}
|
||||
|
||||
protected Interpolator createInterpolator()
|
||||
{
|
||||
StringSearchInterpolator interpolator = new StringSearchInterpolator();
|
||||
interpolator.setCacheAnswers( true );
|
||||
|
||||
return interpolator;
|
||||
}
|
||||
|
||||
private static final class InterpolateObjectAction implements PrivilegedAction<ModelInterpolationException>
|
||||
{
|
||||
|
||||
private final LinkedList<Object> interpolationTargets;
|
||||
private final StringSearchModelInterpolator modelInterpolator;
|
||||
private final List<ValueSource> valueSources;
|
||||
private final List<InterpolationPostProcessor> postProcessors;
|
||||
|
||||
public InterpolateObjectAction( Object target, List<ValueSource> valueSources,
|
||||
List<InterpolationPostProcessor> postProcessors,
|
||||
StringSearchModelInterpolator modelInterpolator )
|
||||
{
|
||||
this.valueSources = valueSources;
|
||||
this.postProcessors = postProcessors;
|
||||
|
||||
this.interpolationTargets = new LinkedList<Object>();
|
||||
interpolationTargets.add( target );
|
||||
|
||||
this.modelInterpolator = modelInterpolator;
|
||||
}
|
||||
|
||||
public ModelInterpolationException run()
|
||||
{
|
||||
while( !interpolationTargets.isEmpty() )
|
||||
{
|
||||
Object obj = interpolationTargets.removeFirst();
|
||||
|
||||
try
|
||||
{
|
||||
traverseObjectWithParents( obj.getClass(), obj );
|
||||
}
|
||||
catch ( ModelInterpolationException e )
|
||||
{
|
||||
return e;
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
private void traverseObjectWithParents( Class<?> cls, Object target )
|
||||
throws ModelInterpolationException
|
||||
{
|
||||
if ( cls == null )
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
if ( cls.isArray() )
|
||||
{
|
||||
evaluateArray( target );
|
||||
}
|
||||
else if ( isQualifiedForInterpolation( cls ) )
|
||||
{
|
||||
Field[] fields = fieldsByClass.get( cls );
|
||||
if ( fields == null )
|
||||
{
|
||||
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 ) )
|
||||
{
|
||||
boolean isAccessible = fields[i].isAccessible();
|
||||
fields[i].setAccessible( true );
|
||||
try
|
||||
{
|
||||
try
|
||||
{
|
||||
if ( String.class == type )
|
||||
{
|
||||
String value = (String) fields[i].get( target );
|
||||
if ( value != null )
|
||||
{
|
||||
String interpolated = modelInterpolator.interpolateInternal( value, valueSources, postProcessors );
|
||||
|
||||
if ( !interpolated.equals( value ) )
|
||||
{
|
||||
fields[i].set( target, interpolated );
|
||||
}
|
||||
}
|
||||
}
|
||||
else if ( Collection.class.isAssignableFrom( type ) )
|
||||
{
|
||||
Collection<Object> c = (Collection<Object>) fields[i].get( target );
|
||||
if ( c != null && !c.isEmpty() )
|
||||
{
|
||||
List<Object> originalValues = new ArrayList<Object>( c );
|
||||
try
|
||||
{
|
||||
c.clear();
|
||||
}
|
||||
catch( UnsupportedOperationException e )
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
for ( Object value : originalValues )
|
||||
{
|
||||
if ( value != null )
|
||||
{
|
||||
if( String.class == value.getClass() )
|
||||
{
|
||||
String interpolated = modelInterpolator.interpolateInternal( (String) value, valueSources, postProcessors );
|
||||
|
||||
if ( !interpolated.equals( value ) )
|
||||
{
|
||||
c.add( interpolated );
|
||||
}
|
||||
else
|
||||
{
|
||||
c.add( value );
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
c.add( value );
|
||||
if ( value.getClass().isArray() )
|
||||
{
|
||||
evaluateArray( value );
|
||||
}
|
||||
else
|
||||
{
|
||||
interpolationTargets.add( value );
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// add the null back in...not sure what else to do...
|
||||
c.add( value );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else if ( Map.class.isAssignableFrom( type ) )
|
||||
{
|
||||
Map<Object, Object> m = (Map<Object, Object>) fields[i].get( target );
|
||||
if ( m != null && !m.isEmpty() )
|
||||
{
|
||||
for ( Map.Entry<Object, Object> entry : m.entrySet() )
|
||||
{
|
||||
Object value = entry.getValue();
|
||||
|
||||
if ( value != null )
|
||||
{
|
||||
if( String.class == value.getClass() )
|
||||
{
|
||||
String interpolated = modelInterpolator.interpolateInternal( (String) value, valueSources, postProcessors );
|
||||
|
||||
if ( !interpolated.equals( value ) )
|
||||
{
|
||||
try
|
||||
{
|
||||
entry.setValue( interpolated );
|
||||
}
|
||||
catch( UnsupportedOperationException e )
|
||||
{
|
||||
continue;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if ( value.getClass().isArray() )
|
||||
{
|
||||
evaluateArray( value );
|
||||
}
|
||||
else
|
||||
{
|
||||
interpolationTargets.add( value );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
Object value = fields[i].get( target );
|
||||
if ( value != null )
|
||||
{
|
||||
if ( fields[i].getType().isArray() )
|
||||
{
|
||||
evaluateArray( value );
|
||||
}
|
||||
else
|
||||
{
|
||||
interpolationTargets.add( value );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
catch ( IllegalArgumentException e )
|
||||
{
|
||||
throw new ModelInterpolationException( "Failed to interpolate field: " + fields[i] + " on class: " + cls.getName(), e );
|
||||
}
|
||||
catch ( IllegalAccessException e )
|
||||
{
|
||||
throw new ModelInterpolationException( "Failed to interpolate field: " + fields[i] + " on class: " + cls.getName(), e );
|
||||
}
|
||||
}
|
||||
finally
|
||||
{
|
||||
fields[i].setAccessible( isAccessible );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
traverseObjectWithParents( cls.getSuperclass(), target );
|
||||
}
|
||||
}
|
||||
|
||||
private boolean isQualifiedForInterpolation( Class<?> cls )
|
||||
{
|
||||
return !cls.getPackage().getName().startsWith( "java" );
|
||||
}
|
||||
|
||||
private boolean isQualifiedForInterpolation( Field field, Class<?> fieldType )
|
||||
{
|
||||
if ( !fieldIsPrimitiveByClass.containsKey( fieldType ) )
|
||||
{
|
||||
fieldIsPrimitiveByClass.put( fieldType, Boolean.valueOf( fieldType.isPrimitive() ) );
|
||||
}
|
||||
|
||||
if ( fieldIsPrimitiveByClass.get( fieldType ).booleanValue() )
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
// if ( fieldType.isPrimitive() )
|
||||
// {
|
||||
// return false;
|
||||
// }
|
||||
|
||||
if ( "parent".equals( field.getName() ) )
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
private void evaluateArray( Object target )
|
||||
throws ModelInterpolationException
|
||||
{
|
||||
int len = Array.getLength( target );
|
||||
for( int i = 0; i < len; i++ )
|
||||
{
|
||||
Object value = Array.get( target, i );
|
||||
if ( value != null )
|
||||
{
|
||||
if ( String.class == value.getClass() )
|
||||
{
|
||||
String interpolated = modelInterpolator.interpolateInternal( (String) value, valueSources, postProcessors );
|
||||
|
||||
if ( !interpolated.equals( value ) )
|
||||
{
|
||||
Array.set( target, i, interpolated );
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
interpolationTargets.add( value );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
|
@ -1,710 +0,0 @@
|
|||
package org.apache.maven.model.interpolator;
|
||||
|
||||
import java.io.ByteArrayInputStream;
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.Reader;
|
||||
import java.io.StringReader;
|
||||
import java.io.StringWriter;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
import java.util.Comparator;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.LinkedHashSet;
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Properties;
|
||||
import java.util.Set;
|
||||
import java.util.Map.Entry;
|
||||
|
||||
import org.apache.maven.model.Model;
|
||||
import org.apache.maven.model.io.ModelReader;
|
||||
import org.apache.maven.model.io.ModelWriter;
|
||||
import org.apache.maven.model.path.ModelPathTranslator;
|
||||
import org.codehaus.plexus.component.annotations.Component;
|
||||
import org.codehaus.plexus.component.annotations.Requirement;
|
||||
import org.codehaus.plexus.util.IOUtil;
|
||||
import org.codehaus.plexus.util.ReaderFactory;
|
||||
import org.codehaus.plexus.util.xml.pull.MXParser;
|
||||
import org.codehaus.plexus.util.xml.pull.XmlPullParser;
|
||||
import org.codehaus.plexus.util.xml.pull.XmlPullParserException;
|
||||
|
||||
@Component(role = Interpolator.class)
|
||||
public class DefaultInterpolator
|
||||
implements Interpolator
|
||||
{
|
||||
|
||||
@Requirement
|
||||
private ModelReader modelReader;
|
||||
|
||||
@Requirement
|
||||
private ModelWriter modelWriter;
|
||||
|
||||
@Requirement
|
||||
private ModelPathTranslator modelPathTranslator;
|
||||
|
||||
public Model interpolateModel( Model model, Properties properties, File projectDirectory )
|
||||
throws IOException
|
||||
{
|
||||
if ( model == null )
|
||||
{
|
||||
throw new IllegalArgumentException( "model: null" );
|
||||
}
|
||||
|
||||
if(properties == null)
|
||||
{
|
||||
properties = new Properties();
|
||||
}
|
||||
|
||||
List<InterpolatorProperty> interpolatorProperties = new ArrayList<InterpolatorProperty>();
|
||||
for ( Entry<Object, Object> e : properties.entrySet() )
|
||||
{
|
||||
interpolatorProperties.add( new InterpolatorProperty( "${" + e.getKey() + "}", (String) e.getValue(),
|
||||
PomInterpolatorTag.EXECUTION_PROPERTIES.toString() ) );
|
||||
}
|
||||
|
||||
if ( !containsProjectVersion( interpolatorProperties ) )
|
||||
{
|
||||
aliases.put( "\\$\\{project.version\\}", "\\$\\{version\\}" );
|
||||
}
|
||||
//TODO: Insert customized logic for parsing
|
||||
List<ModelProperty> modelProperties = getModelProperties( model );
|
||||
|
||||
if ( "jar".equals( model.getPackaging() ) )
|
||||
{
|
||||
modelProperties.add( new ModelProperty( ProjectUri.packaging, "jar" ) );
|
||||
}
|
||||
|
||||
List<ModelProperty> firstPassModelProperties = new ArrayList<ModelProperty>();
|
||||
List<ModelProperty> secondPassModelProperties = new ArrayList<ModelProperty>();
|
||||
|
||||
ModelProperty buildProperty = new ModelProperty( ProjectUri.Build.xUri, null );
|
||||
|
||||
for ( ModelProperty mp : modelProperties )
|
||||
{
|
||||
if ( mp.getValue() != null && !mp.getUri().contains( "#property" ) && !mp.getUri().contains( "#collection" ) )
|
||||
{
|
||||
if ( ( !buildProperty.isParentOf( mp ) && !mp.getUri().equals( ProjectUri.Reporting.outputDirectory ) || mp.getUri().equals( ProjectUri.Build.finalName ) ) )
|
||||
{
|
||||
firstPassModelProperties.add( mp );
|
||||
}
|
||||
else
|
||||
{
|
||||
secondPassModelProperties.add( mp );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
List<InterpolatorProperty> standardInterpolatorProperties = new ArrayList<InterpolatorProperty>();
|
||||
|
||||
String basedir = null;
|
||||
if ( projectDirectory != null )
|
||||
{
|
||||
basedir = projectDirectory.getAbsolutePath();
|
||||
standardInterpolatorProperties.add( new InterpolatorProperty( "${project.basedir}", basedir,
|
||||
PomInterpolatorTag.PROJECT_PROPERTIES.name() ) );
|
||||
standardInterpolatorProperties.add( new InterpolatorProperty( "${basedir}", basedir,
|
||||
PomInterpolatorTag.PROJECT_PROPERTIES.name() ) );
|
||||
standardInterpolatorProperties.add( new InterpolatorProperty( "${pom.basedir}", basedir,
|
||||
PomInterpolatorTag.PROJECT_PROPERTIES.name() ) );
|
||||
|
||||
String baseuri = projectDirectory.toURI().toString();
|
||||
standardInterpolatorProperties.add( new InterpolatorProperty( "${project.baseUri}", baseuri,
|
||||
PomInterpolatorTag.PROJECT_PROPERTIES.name() ) );
|
||||
standardInterpolatorProperties.add( new InterpolatorProperty( "${pom.baseUri}", baseuri,
|
||||
PomInterpolatorTag.PROJECT_PROPERTIES.name() ) );
|
||||
}
|
||||
|
||||
for ( ModelProperty mp : modelProperties )
|
||||
{
|
||||
if ( mp.getUri().startsWith( ProjectUri.properties ) && mp.getValue() != null )
|
||||
{
|
||||
String uri = mp.getUri();
|
||||
standardInterpolatorProperties.add( new InterpolatorProperty( "${" + uri.substring( uri.lastIndexOf( "/" ) + 1, uri.length() ) + "}", mp.getValue(),
|
||||
PomInterpolatorTag.PROJECT_PROPERTIES.name() ) );
|
||||
}
|
||||
}
|
||||
|
||||
// FIRST PASS - Withhold using build directories as interpolator
|
||||
// properties
|
||||
List<InterpolatorProperty> ips1 = new ArrayList<InterpolatorProperty>( interpolatorProperties );
|
||||
ips1.addAll( standardInterpolatorProperties );
|
||||
ips1.addAll( createInterpolatorProperties( firstPassModelProperties, ProjectUri.baseUri, aliases, PomInterpolatorTag.PROJECT_PROPERTIES.name() ) );
|
||||
Collections.sort( ips1, new Comparator<InterpolatorProperty>()
|
||||
{
|
||||
public int compare( InterpolatorProperty o, InterpolatorProperty o1 )
|
||||
{
|
||||
if ( o.getTag() == null || o1.getTag() == null )
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
return PomInterpolatorTag.valueOf( o.getTag() ).compareTo( PomInterpolatorTag.valueOf( o1.getTag() ) );
|
||||
}
|
||||
} );
|
||||
|
||||
interpolateModelProperties( modelProperties, ips1 );
|
||||
|
||||
Map<ModelProperty, ModelProperty> buildDirectories = new HashMap<ModelProperty, ModelProperty>();
|
||||
for ( ModelProperty mp : secondPassModelProperties )
|
||||
{
|
||||
if ( mp.getUri().startsWith( ProjectUri.Build.xUri ) || mp.getUri().equals( ProjectUri.Reporting.outputDirectory ) )
|
||||
{
|
||||
File file = new File( mp.getResolvedValue() );
|
||||
if ( !file.isAbsolute() && !mp.getResolvedValue().startsWith( "${project.build." )
|
||||
&& !mp.getResolvedValue().equals( "${project.basedir}" ) && basedir != null )
|
||||
{
|
||||
buildDirectories.put( mp, new ModelProperty( mp.getUri(), new File( basedir, file.getPath() ).getAbsolutePath() ) );
|
||||
}
|
||||
}
|
||||
}
|
||||
for ( Map.Entry<ModelProperty, ModelProperty> e : buildDirectories.entrySet() )
|
||||
{
|
||||
secondPassModelProperties.remove( e.getKey() );
|
||||
secondPassModelProperties.add( e.getValue() );
|
||||
}
|
||||
|
||||
|
||||
// THIRD PASS - Use build directories as interpolator properties
|
||||
List<InterpolatorProperty> ips2 = new ArrayList<InterpolatorProperty>( interpolatorProperties );
|
||||
ips2.addAll( standardInterpolatorProperties );
|
||||
ips2.addAll( createInterpolatorProperties( secondPassModelProperties, ProjectUri.baseUri, aliases, PomInterpolatorTag.PROJECT_PROPERTIES.name() ) );
|
||||
ips2.addAll( interpolatorProperties );
|
||||
Collections.sort( ips2, new Comparator<InterpolatorProperty>()
|
||||
{
|
||||
public int compare( InterpolatorProperty o, InterpolatorProperty o1 )
|
||||
{
|
||||
if ( o.getTag() == null || o1.getTag() == null )
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
return PomInterpolatorTag.valueOf( o.getTag() ).compareTo( PomInterpolatorTag.valueOf( o1.getTag() ) );
|
||||
}
|
||||
} );
|
||||
|
||||
interpolateModelProperties( modelProperties, ips2 );
|
||||
|
||||
try
|
||||
{
|
||||
String xml = unmarshalModelPropertiesToXml( modelProperties, ProjectUri.baseUri );
|
||||
Model m = modelReader.read( new StringReader( xml ), null );
|
||||
modelPathTranslator.alignToBaseDirectory( m, projectDirectory );
|
||||
return m;
|
||||
}
|
||||
catch ( IOException e )
|
||||
{
|
||||
throw new IllegalStateException( "Unmarshalling of model properties failed", e );
|
||||
}
|
||||
}
|
||||
|
||||
private static void interpolateModelProperties( List<ModelProperty> modelProperties, List<InterpolatorProperty> interpolatorProperties )
|
||||
{
|
||||
if ( modelProperties == null )
|
||||
{
|
||||
throw new IllegalArgumentException( "modelProperties: null" );
|
||||
}
|
||||
|
||||
if ( interpolatorProperties == null )
|
||||
{
|
||||
throw new IllegalArgumentException( "interpolatorProperties: null" );
|
||||
}
|
||||
|
||||
List<ModelProperty> unresolvedProperties = new ArrayList<ModelProperty>();
|
||||
for ( ModelProperty mp : modelProperties )
|
||||
{
|
||||
if ( !mp.isResolved() )
|
||||
{
|
||||
unresolvedProperties.add( mp );
|
||||
}
|
||||
}
|
||||
|
||||
LinkedHashSet<InterpolatorProperty> ips = new LinkedHashSet<InterpolatorProperty>();
|
||||
ips.addAll( interpolatorProperties );
|
||||
boolean continueInterpolation = true;
|
||||
while ( continueInterpolation )
|
||||
{
|
||||
continueInterpolation = false;
|
||||
for ( InterpolatorProperty ip : ips )
|
||||
{
|
||||
for ( ModelProperty mp : unresolvedProperties )
|
||||
{
|
||||
if ( mp.resolveWith( ip ) && !continueInterpolation )
|
||||
{
|
||||
continueInterpolation = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static List<InterpolatorProperty> createInterpolatorProperties( List<ModelProperty> modelProperties, String baseUriForModel, Map<String, String> aliases, String interpolatorTag )
|
||||
{
|
||||
if ( modelProperties == null )
|
||||
{
|
||||
throw new IllegalArgumentException( "modelProperties: null" );
|
||||
}
|
||||
|
||||
if ( baseUriForModel == null )
|
||||
{
|
||||
throw new IllegalArgumentException( "baseUriForModel: null" );
|
||||
}
|
||||
|
||||
List<InterpolatorProperty> interpolatorProperties = new ArrayList<InterpolatorProperty>();
|
||||
|
||||
for ( ModelProperty mp : modelProperties )
|
||||
{
|
||||
InterpolatorProperty ip = mp.asInterpolatorProperty( baseUriForModel );
|
||||
if ( ip != null )
|
||||
{
|
||||
ip.setTag( interpolatorTag );
|
||||
interpolatorProperties.add( ip );
|
||||
for ( Map.Entry<String, String> a : aliases.entrySet() )
|
||||
{
|
||||
interpolatorProperties.add( new InterpolatorProperty( ip.getKey().replaceAll( a.getKey(), a.getValue() ), ip.getValue().replaceAll( a.getKey(), a.getValue() ), interpolatorTag ) );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
List<InterpolatorProperty> ips = new ArrayList<InterpolatorProperty>();
|
||||
for ( InterpolatorProperty ip : interpolatorProperties )
|
||||
{
|
||||
if ( !ips.contains( ip ) )
|
||||
{
|
||||
ips.add( ip );
|
||||
}
|
||||
}
|
||||
return ips;
|
||||
}
|
||||
|
||||
|
||||
private List<ModelProperty> getModelProperties( Model model )
|
||||
throws IOException
|
||||
{
|
||||
StringWriter writer = new StringWriter();
|
||||
modelWriter.write( writer, null, model );
|
||||
|
||||
Set<String> s = new HashSet<String>();
|
||||
//TODO: Should add all collections from ProjectUri
|
||||
s.addAll( URIS );
|
||||
s.add( ProjectUri.Build.PluginManagement.Plugins.Plugin.Executions.xUri );
|
||||
s.add( ProjectUri.DependencyManagement.Dependencies.Dependency.Exclusions.xUri );
|
||||
s.add( ProjectUri.Dependencies.Dependency.Exclusions.xUri );
|
||||
s.add( ProjectUri.Build.Plugins.Plugin.Executions.xUri );
|
||||
s.add( ProjectUri.Build.Plugins.Plugin.Executions.Execution.Goals.xURI );
|
||||
s.add( ProjectUri.Reporting.Plugins.Plugin.ReportSets.xUri );
|
||||
s.add( ProjectUri.Reporting.Plugins.Plugin.ReportSets.ReportSet.configuration );
|
||||
s.add( ProjectUri.Build.Plugins.Plugin.Executions.Execution.configuration );
|
||||
//TODO: More profile info
|
||||
s.add( ProjectUri.Profiles.Profile.Build.PluginManagement.Plugins.Plugin.Executions.xUri );
|
||||
s.add( ProjectUri.Profiles.Profile.DependencyManagement.Dependencies.Dependency.Exclusions.xUri );
|
||||
s.add( ProjectUri.Profiles.Profile.Dependencies.Dependency.Exclusions.xUri );
|
||||
s.add( ProjectUri.Profiles.Profile.Build.Plugins.Plugin.Executions.xUri );
|
||||
s.add( ProjectUri.Profiles.Profile.Build.Plugins.Plugin.Executions.Execution.Goals.xURI );
|
||||
s.add( ProjectUri.Profiles.Profile.Reporting.Plugins.Plugin.ReportSets.xUri );
|
||||
s.add( ProjectUri.Profiles.Profile.Reporting.Plugins.Plugin.ReportSets.ReportSet.configuration );
|
||||
s.add( ProjectUri.Profiles.Profile.Build.Plugins.Plugin.Executions.Execution.configuration );
|
||||
s.add( ProjectUri.Profiles.Profile.properties );
|
||||
s.add( ProjectUri.Profiles.Profile.modules );
|
||||
s.add( ProjectUri.Profiles.Profile.Dependencies.xUri );
|
||||
s.add( ProjectUri.Profiles.Profile.Build.Plugins.Plugin.configuration );
|
||||
|
||||
return new ArrayList<ModelProperty>( marshallXmlToModelProperties( new ByteArrayInputStream(writer.toString().getBytes( "UTF-8" )), ProjectUri.baseUri, s ) );
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns XML string unmarshalled from the specified list of model properties
|
||||
*
|
||||
* @param modelProperties the model properties to unmarshal. May not be null or empty
|
||||
* @param baseUri the base uri of every model property. May not be null or empty.
|
||||
* @return XML string unmarshalled from the specified list of model properties
|
||||
* @throws IOException if there was a problem with unmarshalling
|
||||
*/
|
||||
private static String unmarshalModelPropertiesToXml( List<ModelProperty> modelProperties, String baseUri )
|
||||
throws IOException
|
||||
{
|
||||
if ( modelProperties == null || modelProperties.isEmpty() )
|
||||
{
|
||||
throw new IllegalArgumentException( "modelProperties: null or empty" );
|
||||
}
|
||||
|
||||
if ( baseUri == null || baseUri.trim().length() == 0 )
|
||||
{
|
||||
throw new IllegalArgumentException( "baseUri: null or empty" );
|
||||
}
|
||||
|
||||
final int basePosition = baseUri.length();
|
||||
|
||||
StringBuffer sb = new StringBuffer();
|
||||
List<String> lastUriTags = new ArrayList<String>();
|
||||
for ( ModelProperty mp : modelProperties )
|
||||
{
|
||||
String uri = mp.getUri();
|
||||
if ( uri.contains( "#property" ) )
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
if ( !uri.startsWith( baseUri ) )
|
||||
{
|
||||
throw new IllegalArgumentException( "Passed in model property that does not match baseUri: Property URI = " + uri + ", Base URI = " + baseUri );
|
||||
}
|
||||
|
||||
List<String> tagNames = getTagNamesFromUri( basePosition, uri );
|
||||
|
||||
for ( int i = lastUriTags.size() - 1; i >= 0 && i >= tagNames.size() - 1; i-- )
|
||||
{
|
||||
sb.append( toEndTag( lastUriTags.get( i ) ) );
|
||||
}
|
||||
|
||||
String tag = tagNames.get( tagNames.size() - 1 );
|
||||
|
||||
List<ModelProperty> attributes = new ArrayList<ModelProperty>();
|
||||
for ( int peekIndex = modelProperties.indexOf( mp ) + 1; peekIndex < modelProperties.size(); peekIndex++ )
|
||||
{
|
||||
if ( peekIndex <= modelProperties.size() - 1 )
|
||||
{
|
||||
ModelProperty peekProperty = modelProperties.get( peekIndex );
|
||||
if ( peekProperty.getUri().contains( "#property" ) )
|
||||
{
|
||||
attributes.add( peekProperty );
|
||||
}
|
||||
else
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
sb.append( toStartTag( tag, attributes ) );
|
||||
|
||||
if ( mp.getResolvedValue() != null )
|
||||
{
|
||||
sb.append( mp.getResolvedValue() );
|
||||
}
|
||||
|
||||
lastUriTags = tagNames;
|
||||
}
|
||||
|
||||
for ( int i = lastUriTags.size() - 1; i >= 1; i-- )
|
||||
{
|
||||
sb.append( toEndTag( lastUriTags.get( i ) ) );
|
||||
}
|
||||
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns list of tag names parsed from the specified uri. All #collection parts of the tag are
|
||||
* removed from the tag names.
|
||||
*
|
||||
* @param basePosition the base position in the specified URI to start the parse
|
||||
* @param uri the uri to parse for tag names
|
||||
* @return list of tag names parsed from the specified uri
|
||||
*/
|
||||
private static List<String> getTagNamesFromUri( int basePosition, String uri )
|
||||
{
|
||||
return Arrays.asList( uri.substring( basePosition ).replaceAll( "#collection", "" ).replaceAll( "#set", "" ).split( "/" ) );
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the XML formatted start tag for the specified value and the specified attribute.
|
||||
*
|
||||
* @param value the value to use for the start tag
|
||||
* @param attributes the attribute to use in constructing of start tag
|
||||
* @return the XML formatted start tag for the specified value and the specified attribute
|
||||
*/
|
||||
private static String toStartTag( String value, List<ModelProperty> attributes )
|
||||
{
|
||||
StringBuffer sb = new StringBuffer(); //TODO: Support more than one attribute
|
||||
sb.append( "\r\n<" ).append( value );
|
||||
if ( attributes != null )
|
||||
{
|
||||
for ( ModelProperty attribute : attributes )
|
||||
{
|
||||
sb.append( " " ).append( attribute.getUri().substring( attribute.getUri().indexOf( "#property/" ) + 10 ) ).append( "=\"" ).append( attribute.getResolvedValue() ).append( "\" " );
|
||||
}
|
||||
}
|
||||
sb.append( ">" );
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns XML formatted end tag for the specified value.
|
||||
*
|
||||
* @param value the value to use for the end tag
|
||||
* @return xml formatted end tag for the specified value
|
||||
*/
|
||||
private static String toEndTag( String value )
|
||||
{
|
||||
if ( value.trim().length() == 0 )
|
||||
{
|
||||
return "";
|
||||
}
|
||||
StringBuffer sb = new StringBuffer();
|
||||
sb.append( "</" ).append( value ).append( ">" );
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
private static final Set<String> URIS = Collections.unmodifiableSet( new HashSet<String>( Arrays.asList( ProjectUri.Build.Extensions.xUri, ProjectUri.Build.PluginManagement.Plugins.xUri,
|
||||
ProjectUri.Build.PluginManagement.Plugins.Plugin.configuration,
|
||||
ProjectUri.Build.PluginManagement.Plugins.Plugin.Executions.xUri,
|
||||
ProjectUri.Build.PluginManagement.Plugins.Plugin.Executions.Execution.Goals.xURI,
|
||||
ProjectUri.Build.PluginManagement.Plugins.Plugin.Dependencies.xUri,
|
||||
ProjectUri.Build.PluginManagement.Plugins.Plugin.Dependencies.Dependency.Exclusions.xUri,
|
||||
ProjectUri.Build.Plugins.xUri, ProjectUri.properties,
|
||||
ProjectUri.Build.Plugins.Plugin.configuration, ProjectUri.Reporting.Plugins.xUri,
|
||||
ProjectUri.Reporting.Plugins.Plugin.configuration,
|
||||
ProjectUri.Build.Plugins.Plugin.Dependencies.xUri, ProjectUri.Build.Resources.xUri,
|
||||
ProjectUri.Build.Resources.Resource.includes,
|
||||
ProjectUri.Build.Resources.Resource.excludes, ProjectUri.Build.TestResources.xUri,
|
||||
ProjectUri.Build.Filters.xUri, ProjectUri.CiManagement.Notifiers.xUri,
|
||||
ProjectUri.Contributors.xUri, ProjectUri.Dependencies.xUri,
|
||||
ProjectUri.DependencyManagement.Dependencies.xUri, ProjectUri.Developers.xUri,
|
||||
ProjectUri.Developers.Developer.roles, ProjectUri.Licenses.xUri,
|
||||
ProjectUri.MailingLists.xUri, ProjectUri.Modules.xUri, ProjectUri.PluginRepositories.xUri,
|
||||
ProjectUri.Profiles.xUri, ProjectUri.Profiles.Profile.Build.Plugins.xUri,
|
||||
ProjectUri.Profiles.Profile.Build.Plugins.Plugin.Dependencies.xUri,
|
||||
ProjectUri.Profiles.Profile.Build.Plugins.Plugin.Executions.xUri,
|
||||
ProjectUri.Profiles.Profile.Build.Resources.xUri,
|
||||
ProjectUri.Profiles.Profile.Build.TestResources.xUri,
|
||||
ProjectUri.Profiles.Profile.Dependencies.xUri,
|
||||
ProjectUri.Profiles.Profile.DependencyManagement.Dependencies.xUri,
|
||||
ProjectUri.Profiles.Profile.PluginRepositories.xUri,
|
||||
ProjectUri.Profiles.Profile.Reporting.Plugins.xUri,
|
||||
ProjectUri.Profiles.Profile.Repositories.xUri,
|
||||
ProjectUri.Profiles.Profile.Build.PluginManagement.Plugins.xUri,
|
||||
ProjectUri.Profiles.Profile.Build.PluginManagement.Plugins.Plugin.Dependencies.xUri,
|
||||
ProjectUri.Reporting.Plugins.xUri, ProjectUri.Repositories.xUri ) ) );
|
||||
|
||||
/**
|
||||
* Returns list of model properties transformed from the specified input stream.
|
||||
*
|
||||
* @param inputStream input stream containing the xml document. May not be null.
|
||||
* @param baseUri the base uri of every model property. May not be null or empty.
|
||||
* @param collections set of uris that are to be treated as a collection (multiple entries). May
|
||||
* be null.
|
||||
* @return list of model properties transformed from the specified input stream.
|
||||
* @throws IOException if there was a problem doing the transform
|
||||
*/
|
||||
private static List<ModelProperty> marshallXmlToModelProperties( InputStream inputStream, String baseUri, Set<String> collections )
|
||||
throws IOException
|
||||
{
|
||||
if ( inputStream == null )
|
||||
{
|
||||
throw new IllegalArgumentException( "inputStream: null" );
|
||||
}
|
||||
|
||||
if ( baseUri == null || baseUri.trim().length() == 0 )
|
||||
{
|
||||
throw new IllegalArgumentException( "baseUri: null" );
|
||||
}
|
||||
|
||||
if ( collections == null )
|
||||
{
|
||||
collections = Collections.emptySet();
|
||||
}
|
||||
|
||||
List<ModelProperty> modelProperties = new ArrayList<ModelProperty>();
|
||||
|
||||
Uri uri = new Uri( baseUri );
|
||||
String tagName = baseUri;
|
||||
StringBuilder tagValue = new StringBuilder( 256 );
|
||||
|
||||
int depth = 0;
|
||||
int depthOfTagValue = depth;
|
||||
Reader reader = null;
|
||||
try
|
||||
{
|
||||
reader = ReaderFactory.newXmlReader( inputStream );
|
||||
|
||||
XmlPullParser parser = new MXParser();
|
||||
parser.setInput( reader );
|
||||
|
||||
Map<String, String> attributes = new HashMap<String, String>();
|
||||
for ( int type = parser.getEventType();; type = parser.next() )
|
||||
{
|
||||
switch ( type )
|
||||
{
|
||||
case XmlPullParser.TEXT:
|
||||
{
|
||||
if ( depth == depthOfTagValue )
|
||||
{
|
||||
tagValue.append( parser.getText() );
|
||||
}
|
||||
break;
|
||||
}
|
||||
case XmlPullParser.START_TAG:
|
||||
{
|
||||
if ( !tagName.equals( baseUri ) )
|
||||
{
|
||||
String value = null;
|
||||
if ( depth < depthOfTagValue )
|
||||
{
|
||||
value = tagValue.toString().trim();
|
||||
}
|
||||
modelProperties.add( new ModelProperty( tagName, value ) );
|
||||
if ( !attributes.isEmpty() )
|
||||
{
|
||||
for ( Map.Entry<String, String> e : attributes.entrySet() )
|
||||
{
|
||||
modelProperties.add( new ModelProperty( e.getKey(), e.getValue() ) );
|
||||
}
|
||||
attributes.clear();
|
||||
}
|
||||
}
|
||||
|
||||
depth++;
|
||||
tagName = uri.getUriFor( parser.getName(), depth );
|
||||
if ( collections.contains( tagName + "#collection" ) )
|
||||
{
|
||||
tagName = tagName + "#collection";
|
||||
uri.addTag( parser.getName() + "#collection" );
|
||||
}
|
||||
else if ( collections.contains( tagName + "#set" ) )
|
||||
{
|
||||
tagName = tagName + "#set";
|
||||
uri.addTag( parser.getName() + "#set" );
|
||||
}
|
||||
else
|
||||
{
|
||||
uri.addTag( parser.getName() );
|
||||
}
|
||||
tagValue.setLength( 0 );
|
||||
depthOfTagValue = depth;
|
||||
|
||||
for ( int i = 0; i < parser.getAttributeCount(); i++ )
|
||||
{
|
||||
|
||||
attributes.put( tagName + "#property/" + parser.getAttributeName( i ),
|
||||
parser.getAttributeValue( i ) );
|
||||
}
|
||||
break;
|
||||
}
|
||||
case XmlPullParser.END_TAG:
|
||||
{
|
||||
depth--;
|
||||
break;
|
||||
}
|
||||
case XmlPullParser.END_DOCUMENT:
|
||||
{
|
||||
modelProperties.add( new ModelProperty( tagName, tagValue.toString().trim() ) );
|
||||
if ( !attributes.isEmpty() )
|
||||
{
|
||||
for ( Map.Entry<String, String> e : attributes.entrySet() )
|
||||
{
|
||||
modelProperties.add( new ModelProperty( e.getKey(), e.getValue() ) );
|
||||
}
|
||||
}
|
||||
return modelProperties;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
catch ( XmlPullParserException e )
|
||||
{
|
||||
throw (IOException) new IOException( "Failed to parser POM:" + e.toString() ).initCause( e );
|
||||
}
|
||||
finally
|
||||
{
|
||||
IOUtil.close( reader );
|
||||
}
|
||||
}
|
||||
|
||||
private static final Map<String, String> aliases = new HashMap<String, String>();
|
||||
|
||||
private static void addProjectAlias( String element, boolean leaf )
|
||||
{
|
||||
String suffix = leaf ? "\\}" : "\\.";
|
||||
aliases.put( "\\$\\{project\\." + element + suffix, "\\$\\{" + element + suffix );
|
||||
}
|
||||
|
||||
static
|
||||
{
|
||||
aliases.put( "\\$\\{project\\.", "\\$\\{pom\\." );
|
||||
addProjectAlias( "modelVersion", true );
|
||||
addProjectAlias( "groupId", true );
|
||||
addProjectAlias( "artifactId", true );
|
||||
addProjectAlias( "version", true );
|
||||
addProjectAlias( "packaging", true );
|
||||
addProjectAlias( "name", true );
|
||||
addProjectAlias( "description", true );
|
||||
addProjectAlias( "inceptionYear", true );
|
||||
addProjectAlias( "url", true );
|
||||
addProjectAlias( "parent", false );
|
||||
addProjectAlias( "prerequisites", false );
|
||||
addProjectAlias( "organization", false );
|
||||
addProjectAlias( "build", false );
|
||||
addProjectAlias( "reporting", false );
|
||||
addProjectAlias( "scm", false );
|
||||
addProjectAlias( "distributionManagement", false );
|
||||
addProjectAlias( "issueManagement", false );
|
||||
addProjectAlias( "ciManagement", false );
|
||||
}
|
||||
|
||||
private static boolean containsProjectVersion( List<InterpolatorProperty> interpolatorProperties )
|
||||
{
|
||||
InterpolatorProperty versionInterpolatorProperty = new ModelProperty( ProjectUri.version, "" ).asInterpolatorProperty( ProjectUri.baseUri );
|
||||
for ( InterpolatorProperty ip : interpolatorProperties )
|
||||
{
|
||||
if ( ip.equals( versionInterpolatorProperty ) )
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Class for storing information about URIs.
|
||||
*/
|
||||
private static class Uri
|
||||
{
|
||||
|
||||
List<String> uris;
|
||||
|
||||
Uri( String baseUri )
|
||||
{
|
||||
uris = new LinkedList<String>();
|
||||
uris.add( baseUri );
|
||||
}
|
||||
|
||||
String getUriFor( String tag, int depth )
|
||||
{
|
||||
setUrisToDepth( depth );
|
||||
StringBuffer sb = new StringBuffer();
|
||||
for ( String tagName : uris )
|
||||
{
|
||||
sb.append( tagName ).append( "/" );
|
||||
}
|
||||
sb.append( tag );
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
void addTag( String tag )
|
||||
{
|
||||
uris.add( tag );
|
||||
}
|
||||
|
||||
void setUrisToDepth( int depth )
|
||||
{
|
||||
uris = new LinkedList<String>( uris.subList( 0, depth ) );
|
||||
}
|
||||
}
|
||||
|
||||
private static enum PomInterpolatorTag
|
||||
{
|
||||
PROJECT_PROPERTIES,
|
||||
|
||||
EXECUTION_PROPERTIES
|
||||
}
|
||||
}
|
|
@ -1,13 +0,0 @@
|
|||
package org.apache.maven.model.interpolator;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.util.Properties;
|
||||
|
||||
import org.apache.maven.model.Model;
|
||||
|
||||
public interface Interpolator
|
||||
{
|
||||
Model interpolateModel( Model model, Properties properties, File projectDirectory )
|
||||
throws IOException;
|
||||
}
|
|
@ -1,145 +0,0 @@
|
|||
package org.apache.maven.model.interpolator;
|
||||
|
||||
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Provides interpolator property information.
|
||||
*/
|
||||
final class InterpolatorProperty
|
||||
{
|
||||
/**
|
||||
* The key (or name) of the property
|
||||
*/
|
||||
private final String key;
|
||||
|
||||
/**
|
||||
* The value of the property
|
||||
*/
|
||||
private final String value;
|
||||
|
||||
/**
|
||||
* Metadata tag (general use)
|
||||
*/
|
||||
private String tag;
|
||||
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
* @param key the key (or name) of the property. May not be null
|
||||
* @param value the value of the property. May not be null.
|
||||
*/
|
||||
public InterpolatorProperty( String key, String value )
|
||||
{
|
||||
this(key, value, null);
|
||||
}
|
||||
|
||||
public InterpolatorProperty( String key, String value, String tag )
|
||||
{
|
||||
if ( key == null )
|
||||
{
|
||||
throw new IllegalArgumentException( "key: null" );
|
||||
}
|
||||
|
||||
if ( value == null )
|
||||
{
|
||||
throw new IllegalArgumentException( "value: null" );
|
||||
}
|
||||
this.key = key;
|
||||
this.value = value;
|
||||
this.tag = tag;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns key (or name) of property.
|
||||
*
|
||||
* @return key (or name) of property
|
||||
*/
|
||||
public String getKey()
|
||||
{
|
||||
return key;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns value of property.
|
||||
*
|
||||
* @return value of property
|
||||
*/
|
||||
public String getValue()
|
||||
{
|
||||
return value;
|
||||
}
|
||||
|
||||
public String getTag()
|
||||
{
|
||||
return tag;
|
||||
}
|
||||
|
||||
public void setTag(String tag)
|
||||
{
|
||||
this.tag = tag;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if key values match, otherwise returns false.
|
||||
*
|
||||
* @param o interpolator property to compare
|
||||
* @return true if key values match, otherwise returns false
|
||||
*/
|
||||
public boolean equals( Object o )
|
||||
{
|
||||
if ( this == o )
|
||||
{
|
||||
return true;
|
||||
}
|
||||
if ( o == null || getClass() != o.getClass() )
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
InterpolatorProperty that = (InterpolatorProperty) o;
|
||||
|
||||
if ( !key.equals( that.key ) )
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns hash code of interpolator property key.
|
||||
*
|
||||
* @return hash code of interpolator property key
|
||||
*/
|
||||
public int hashCode()
|
||||
{
|
||||
return key.hashCode();
|
||||
}
|
||||
|
||||
public String toString()
|
||||
{
|
||||
return "Key = " + key + ", Value = " + value + ", Hash = " +
|
||||
this.hashCode();
|
||||
}
|
||||
}
|
||||
|
|
@ -1,255 +0,0 @@
|
|||
package org.apache.maven.model.interpolator;
|
||||
|
||||
/*
|
||||
* 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 java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
|
||||
/**
|
||||
* Maps a URI to a string value, which may be null. This class is immutable.
|
||||
*/
|
||||
final class ModelProperty
|
||||
{
|
||||
|
||||
/**
|
||||
* A pattern used for finding pom, project and env properties
|
||||
*/
|
||||
private static final Pattern EXPRESSION_PATTERN = Pattern.compile( "\\$\\{(pom\\.|project\\.|env\\.)?([^}]+)\\}" );
|
||||
|
||||
/**
|
||||
* URI of the resource
|
||||
*/
|
||||
private final String uri;
|
||||
|
||||
/**
|
||||
* Value associated with the uri
|
||||
*/
|
||||
private final String value;
|
||||
|
||||
/**
|
||||
* The count of '/' within this model property's uri, which is the depth of its XML nodes.
|
||||
*/
|
||||
private final int depth;
|
||||
|
||||
/**
|
||||
* Value of this model property after interpolation
|
||||
*/
|
||||
private String resolvedValue;
|
||||
|
||||
/**
|
||||
* List of unresolved expressions within this model property's value
|
||||
*/
|
||||
private final List<String> unresolvedExpressions;
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
* @param uri URI of the resource. May not be null
|
||||
* @param value Value associated with specified uri. Value may be null if uri does not map to primitive type.
|
||||
*/
|
||||
public ModelProperty( String uri, String value )
|
||||
{
|
||||
if ( uri == null )
|
||||
{
|
||||
throw new IllegalArgumentException( "uri" );
|
||||
}
|
||||
this.uri = uri;
|
||||
this.value = value;
|
||||
resolvedValue = value;
|
||||
|
||||
unresolvedExpressions = new ArrayList<String>();
|
||||
if ( value != null )
|
||||
{
|
||||
Matcher matcher = EXPRESSION_PATTERN.matcher( value );
|
||||
while ( matcher.find() )
|
||||
{
|
||||
unresolvedExpressions.add( matcher.group( 0 ) );
|
||||
}
|
||||
}
|
||||
|
||||
String uriWithoutProperty;
|
||||
int index = uri.lastIndexOf( "/" );
|
||||
if(index > -1) {
|
||||
uriWithoutProperty = uri.substring( 0, uri.lastIndexOf( "/" ) );
|
||||
if(uriWithoutProperty.endsWith("#property") || uriWithoutProperty.endsWith("combine.children") )
|
||||
{
|
||||
uriWithoutProperty = uriWithoutProperty.substring( 0, uriWithoutProperty.lastIndexOf( "/" ) );
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
uriWithoutProperty = uri;
|
||||
}
|
||||
|
||||
depth = uriWithoutProperty.split( "/" ).length;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns URI key
|
||||
*
|
||||
* @return URI key
|
||||
*/
|
||||
public String getUri()
|
||||
{
|
||||
return uri;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns value for the URI key. Value may be null.
|
||||
*
|
||||
* @return value for the URI key. Value may be null
|
||||
*/
|
||||
public String getValue()
|
||||
{
|
||||
return value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Value of this model property after interpolation. CDATA section will be added if needed.
|
||||
*
|
||||
* @return value of this model property after interpolation
|
||||
*/
|
||||
public String getResolvedValue()
|
||||
{
|
||||
if( !uri.contains("#property") && resolvedValue != null && !resolvedValue.startsWith ("<![CDATA[")
|
||||
&& (resolvedValue.contains( "=" ) || resolvedValue.contains( "<" ) || resolvedValue.contains( "&" )))
|
||||
{
|
||||
resolvedValue = "<![CDATA[" + resolvedValue + "]]>";
|
||||
}
|
||||
return resolvedValue;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if model property is completely interpolated, otherwise returns false.
|
||||
*
|
||||
* @return true if model property is completely interpolated, otherwise returns false
|
||||
*/
|
||||
public boolean isResolved()
|
||||
{
|
||||
return unresolvedExpressions.isEmpty();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns copy of the uninterpolated model property
|
||||
*
|
||||
* @return copy of the uninterpolated model property
|
||||
*/
|
||||
public ModelProperty createCopyOfOriginal()
|
||||
{
|
||||
return new ModelProperty( uri, value );
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the count of '/' within this model property's uri, which is the depth of its XML nodes.
|
||||
*
|
||||
* @return the count of '/' within this model property's uri, which is the depth of its XML nodes
|
||||
*/
|
||||
public int getDepth()
|
||||
{
|
||||
return depth;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if this model property is a direct parent of the specified model property, otherwise returns false.
|
||||
*
|
||||
* @param modelProperty the model property
|
||||
* @return true if this model property is a direct parent of the specified model property, otherwise returns false
|
||||
*/
|
||||
public boolean isParentOf( ModelProperty modelProperty )
|
||||
{
|
||||
if ( Math.abs( depth - modelProperty.getDepth() ) > 1 )
|
||||
{
|
||||
return false;
|
||||
}
|
||||
if ( uri.equals( modelProperty.getUri() ) || uri.startsWith( modelProperty.getUri() ) )
|
||||
{
|
||||
return false;
|
||||
}
|
||||
return ( modelProperty.getUri().startsWith( uri ) );
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns this model property as an interpolator property, allowing the interpolation of model elements within
|
||||
* other model elements.
|
||||
*
|
||||
* @param baseUri the base uri of the model property
|
||||
* @return this model property as an interpolator property, allowing the interpolation of model elements within
|
||||
* other model elements
|
||||
*/
|
||||
public InterpolatorProperty asInterpolatorProperty( String baseUri )
|
||||
{
|
||||
if ( uri.contains( "#collection" ) || uri.contains("#set") || value == null )
|
||||
{
|
||||
return null;
|
||||
}
|
||||
String key = "${" + uri.replace( baseUri + "/", "" ).replace( "/", "." ) + "}";
|
||||
return new InterpolatorProperty( key, value );
|
||||
}
|
||||
|
||||
/**
|
||||
* Resolves any unresolved model property expressions using the specified interpolator property
|
||||
*
|
||||
* @param property the interpolator property used to resolve
|
||||
*/
|
||||
public boolean resolveWith( InterpolatorProperty property )
|
||||
{
|
||||
if ( property == null )
|
||||
{
|
||||
throw new IllegalArgumentException( "property: null" );
|
||||
}
|
||||
if ( isResolved() )
|
||||
{
|
||||
return false;
|
||||
}
|
||||
boolean resolved = false;
|
||||
for ( String expression : unresolvedExpressions )
|
||||
{
|
||||
if ( property.getKey().equals( expression ) )
|
||||
{
|
||||
resolved = true;
|
||||
resolvedValue = resolvedValue.replace( property.getKey(), property.getValue() );
|
||||
unresolvedExpressions.clear();
|
||||
Matcher matcher = EXPRESSION_PATTERN.matcher( resolvedValue );
|
||||
while ( matcher.find() )
|
||||
{
|
||||
unresolvedExpressions.add( matcher.group( 0 ) );
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
return resolved;
|
||||
}
|
||||
|
||||
public String toCode() {
|
||||
String val = (value != null) ? "\"" + value + "\"" : null;
|
||||
return "mpz.add(new ModelProperty(\"" + uri + "\", " + val +"));";
|
||||
}
|
||||
|
||||
public String toString()
|
||||
{
|
||||
return "Uri = " + uri + ", Value = " + value + ", Resolved Value = " + resolvedValue + ", Hash = " +
|
||||
this.hashCode();
|
||||
}
|
||||
}
|
||||
|
||||
|
File diff suppressed because it is too large
Load Diff
2
pom.xml
2
pom.xml
|
@ -52,7 +52,7 @@ under the License.
|
|||
<easyMockVersion>1.2_Java1.3</easyMockVersion>
|
||||
<junitVersion>3.8.1</junitVersion>
|
||||
<plexusVersion>1.0-beta-3.0.8-SNAPSHOT</plexusVersion>
|
||||
<plexusInterpolationVersion>1.1</plexusInterpolationVersion>
|
||||
<plexusInterpolationVersion>1.8.1</plexusInterpolationVersion>
|
||||
<plexusPluginManagerVersion>1.0-alpha-1</plexusPluginManagerVersion>
|
||||
<plexusUtilsVersion>1.5.8</plexusUtilsVersion>
|
||||
<plexusJetty6Version>1.6</plexusJetty6Version>
|
||||
|
|
Loading…
Reference in New Issue