From 690841e9be62a93b468d48364b35608dd1b0c2a9 Mon Sep 17 00:00:00 2001 From: Guillaume Nodet Date: Wed, 24 Jul 2019 04:30:12 +0200 Subject: [PATCH] [MNG-6697] New fast model interpolator not using reflection (#261) * [MNG-6697] New fast model interpolator not using reflection * [MNG-6697] Fix management key in case a field has been modified * [MNG-6697] Remove the unused FIELDS_CACHE and make the InnerInterpolator private * [MNG-6697] Clean up the code to remove a few warnings --- .../building/DefaultModelBuilderFactory.java | 4 +- .../AbstractStringBasedModelInterpolator.java | 81 +- .../StringSearchModelInterpolator.java | 130 +- .../StringVisitorModelInterpolator.java | 1457 +++++++++++++++++ maven-model/src/main/mdo/maven.mdo | 8 + 5 files changed, 1547 insertions(+), 133 deletions(-) create mode 100644 maven-model-builder/src/main/java/org/apache/maven/model/interpolation/StringVisitorModelInterpolator.java diff --git a/maven-model-builder/src/main/java/org/apache/maven/model/building/DefaultModelBuilderFactory.java b/maven-model-builder/src/main/java/org/apache/maven/model/building/DefaultModelBuilderFactory.java index 36a0f46a1b53..4240574ff214 100644 --- a/maven-model-builder/src/main/java/org/apache/maven/model/building/DefaultModelBuilderFactory.java +++ b/maven-model-builder/src/main/java/org/apache/maven/model/building/DefaultModelBuilderFactory.java @@ -25,7 +25,7 @@ import org.apache.maven.model.inheritance.DefaultInheritanceAssembler; import org.apache.maven.model.inheritance.InheritanceAssembler; import org.apache.maven.model.interpolation.ModelInterpolator; -import org.apache.maven.model.interpolation.StringSearchModelInterpolator; +import org.apache.maven.model.interpolation.StringVisitorModelInterpolator; import org.apache.maven.model.io.DefaultModelReader; import org.apache.maven.model.io.ModelReader; import org.apache.maven.model.locator.DefaultModelLocator; @@ -126,7 +126,7 @@ protected ModelInterpolator newModelInterpolator() { UrlNormalizer normalizer = newUrlNormalizer(); PathTranslator pathTranslator = newPathTranslator(); - return new StringSearchModelInterpolator().setPathTranslator( pathTranslator ).setUrlNormalizer( normalizer ); + return new StringVisitorModelInterpolator().setPathTranslator( pathTranslator ).setUrlNormalizer( normalizer ); } protected ModelValidator newModelValidator() diff --git a/maven-model-builder/src/main/java/org/apache/maven/model/interpolation/AbstractStringBasedModelInterpolator.java b/maven-model-builder/src/main/java/org/apache/maven/model/interpolation/AbstractStringBasedModelInterpolator.java index 69d7e808d60f..388671d78de2 100644 --- a/maven-model-builder/src/main/java/org/apache/maven/model/interpolation/AbstractStringBasedModelInterpolator.java +++ b/maven-model-builder/src/main/java/org/apache/maven/model/interpolation/AbstractStringBasedModelInterpolator.java @@ -31,16 +31,11 @@ import org.apache.maven.model.Model; import org.apache.maven.model.building.ModelBuildingRequest; -import org.apache.maven.model.building.ModelProblem.Severity; -import org.apache.maven.model.building.ModelProblem.Version; import org.apache.maven.model.building.ModelProblemCollector; -import org.apache.maven.model.building.ModelProblemCollectorRequest; import org.apache.maven.model.path.PathTranslator; import org.apache.maven.model.path.UrlNormalizer; 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; @@ -93,14 +88,8 @@ public abstract class AbstractStringBasedModelInterpolator @Inject private UrlNormalizer urlNormalizer; - private Interpolator interpolator; - - private RecursionInterceptor recursionInterceptor; - public AbstractStringBasedModelInterpolator() { - interpolator = createInterpolator(); - recursionInterceptor = new PrefixAwareRecursionInterceptor( PROJECT_PREFIXES ); } public AbstractStringBasedModelInterpolator setPathTranslator( PathTranslator pathTranslator ) @@ -218,75 +207,9 @@ protected List createPostProcessors( final return processors; } - protected String interpolateInternal( String src, List valueSources, - List postProcessors, - ModelProblemCollector problems ) - { - if ( !src.contains( "${" ) ) - { - 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 ) - { - problems.add( new ModelProblemCollectorRequest( Severity.ERROR, Version.BASE ) - .setMessage( e.getMessage() ).setException( 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() + protected RecursionInterceptor createRecursionInterceptor() { - return interpolator; + return new PrefixAwareRecursionInterceptor( PROJECT_PREFIXES ); } } diff --git a/maven-model-builder/src/main/java/org/apache/maven/model/interpolation/StringSearchModelInterpolator.java b/maven-model-builder/src/main/java/org/apache/maven/model/interpolation/StringSearchModelInterpolator.java index 0fb953d0a275..3c2ea1377bdd 100644 --- a/maven-model-builder/src/main/java/org/apache/maven/model/interpolation/StringSearchModelInterpolator.java +++ b/maven-model-builder/src/main/java/org/apache/maven/model/interpolation/StringSearchModelInterpolator.java @@ -26,8 +26,9 @@ import org.apache.maven.model.building.ModelProblem.Version; import org.apache.maven.model.building.ModelProblemCollector; import org.apache.maven.model.building.ModelProblemCollectorRequest; +import org.codehaus.plexus.interpolation.InterpolationException; import org.codehaus.plexus.interpolation.InterpolationPostProcessor; -import org.codehaus.plexus.interpolation.Interpolator; +import org.codehaus.plexus.interpolation.RecursionInterceptor; import org.codehaus.plexus.interpolation.StringSearchInterpolator; import org.codehaus.plexus.interpolation.ValueSource; @@ -39,6 +40,7 @@ import java.security.PrivilegedAction; import java.util.ArrayList; import java.util.Collection; +import java.util.HashMap; import java.util.LinkedList; import java.util.List; import java.util.Map; @@ -60,6 +62,10 @@ public class StringSearchModelInterpolator new ConcurrentHashMap<>( 80, 0.75f, 2 ); // Empirical data from 3.x, actual =40 + private interface InnerInterpolator + { + String interpolate( String value ); + } @Override public Model interpolateModel( Model model, File projectDir, ModelBuildingRequest config, @@ -71,32 +77,62 @@ public Model interpolateModel( Model model, File projectDir, ModelBuildingReques } protected void interpolateObject( Object obj, Model model, File projectDir, ModelBuildingRequest config, - ModelProblemCollector problems ) + final ModelProblemCollector problems ) { - try - { - List valueSources = createValueSources( model, projectDir, config, problems ); - List postProcessors = - createPostProcessors( model, projectDir, config ); + List valueSources = createValueSources( model, projectDir, config, problems ); + List postProcessors = + createPostProcessors( model, projectDir, config ); - InterpolateObjectAction action = - new InterpolateObjectAction( obj, valueSources, postProcessors, this, problems ); + InnerInterpolator innerInterpolator = createInterpolator( valueSources, postProcessors, problems ); + + PrivilegedAction action; + action = new InterpolateObjectAction( obj, valueSources, postProcessors, innerInterpolator, problems ); + AccessController.doPrivileged( action ); - AccessController.doPrivileged( action ); - } - finally - { - getInterpolator().clearAnswers(); - } } - @Override - protected Interpolator createInterpolator() + private InnerInterpolator createInterpolator( List valueSources, + List postProcessors, + final ModelProblemCollector problems ) { - StringSearchInterpolator interpolator = new StringSearchInterpolator(); + final Map cache = new HashMap<>(); + final StringSearchInterpolator interpolator = new StringSearchInterpolator(); interpolator.setCacheAnswers( true ); - - return interpolator; + for ( ValueSource vs : valueSources ) + { + interpolator.addValueSource( vs ); + } + for ( InterpolationPostProcessor postProcessor : postProcessors ) + { + interpolator.addPostProcessor( postProcessor ); + } + final RecursionInterceptor recursionInterceptor = createRecursionInterceptor(); + return new InnerInterpolator() + { + @Override + public String interpolate( String value ) + { + if ( value != null && value.contains( "${" ) ) + { + String c = cache.get( value ); + if ( c == null ) + { + try + { + c = interpolator.interpolate( value, recursionInterceptor ); + } + catch ( InterpolationException e ) + { + problems.add( new ModelProblemCollectorRequest( Severity.ERROR, Version.BASE ) + .setMessage( e.getMessage() ).setException( e ) ); + } + cache.put( value, c ); + } + return c; + } + return value; + } + }; } private static final class InterpolateObjectAction @@ -105,7 +141,7 @@ private static final class InterpolateObjectAction private final LinkedList interpolationTargets; - private final StringSearchModelInterpolator modelInterpolator; + private final InnerInterpolator interpolator; private final List valueSources; @@ -115,7 +151,7 @@ private static final class InterpolateObjectAction InterpolateObjectAction( Object target, List valueSources, List postProcessors, - StringSearchModelInterpolator modelInterpolator, ModelProblemCollector problems ) + InnerInterpolator interpolator, ModelProblemCollector problems ) { this.valueSources = valueSources; this.postProcessors = postProcessors; @@ -123,7 +159,7 @@ private static final class InterpolateObjectAction this.interpolationTargets = new LinkedList<>(); interpolationTargets.add( target ); - this.modelInterpolator = modelInterpolator; + this.interpolator = interpolator; this.problems = problems; } @@ -144,7 +180,7 @@ public Object run() private String interpolate( String value ) { - return modelInterpolator.interpolateInternal( value, valueSources, postProcessors, problems ); + return interpolator.interpolate( value ); } private void traverseObjectWithParents( Class cls, Object target ) @@ -297,40 +333,30 @@ abstract static class CacheField CacheField( Field field ) { this.field = field; + field.setAccessible( true ); } void interpolate( Object target, InterpolateObjectAction interpolateObjectAction ) { - synchronized ( field ) + try { - boolean isAccessible = field.isAccessible(); - field.setAccessible( true ); - try - { - doInterpolate( target, interpolateObjectAction ); - } - catch ( IllegalArgumentException e ) - { - interpolateObjectAction.problems.add( - new ModelProblemCollectorRequest( Severity.ERROR, Version.BASE ).setMessage( - "Failed to interpolate field3: " + field + " on class: " - + field.getType().getName() ).setException( - e ) ); // TODO Not entirely the same message - } - catch ( IllegalAccessException e ) - { - interpolateObjectAction.problems.add( - new ModelProblemCollectorRequest( Severity.ERROR, Version.BASE ).setMessage( - "Failed to interpolate field4: " + field + " on class: " - + field.getType().getName() ).setException( e ) ); - } - finally - { - field.setAccessible( isAccessible ); - } + doInterpolate( target, interpolateObjectAction ); + } + catch ( IllegalArgumentException e ) + { + interpolateObjectAction.problems.add( + new ModelProblemCollectorRequest( Severity.ERROR, Version.BASE ).setMessage( + "Failed to interpolate field3: " + field + " on class: " + + field.getType().getName() ).setException( + e ) ); // TODO Not entirely the same message + } + catch ( IllegalAccessException e ) + { + interpolateObjectAction.problems.add( + new ModelProblemCollectorRequest( Severity.ERROR, Version.BASE ).setMessage( + "Failed to interpolate field4: " + field + " on class: " + + field.getType().getName() ).setException( e ) ); } - - } abstract void doInterpolate( Object target, InterpolateObjectAction ctx ) diff --git a/maven-model-builder/src/main/java/org/apache/maven/model/interpolation/StringVisitorModelInterpolator.java b/maven-model-builder/src/main/java/org/apache/maven/model/interpolation/StringVisitorModelInterpolator.java new file mode 100644 index 000000000000..0ae5bcefb339 --- /dev/null +++ b/maven-model-builder/src/main/java/org/apache/maven/model/interpolation/StringVisitorModelInterpolator.java @@ -0,0 +1,1457 @@ +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.io.File; +import java.util.HashMap; +import java.util.List; +import java.util.ListIterator; +import java.util.Map; +import java.util.Properties; + +import javax.inject.Named; +import javax.inject.Singleton; + +import org.apache.maven.model.Activation; +import org.apache.maven.model.ActivationFile; +import org.apache.maven.model.ActivationOS; +import org.apache.maven.model.ActivationProperty; +import org.apache.maven.model.Build; +import org.apache.maven.model.BuildBase; +import org.apache.maven.model.CiManagement; +import org.apache.maven.model.Contributor; +import org.apache.maven.model.Dependency; +import org.apache.maven.model.DependencyManagement; +import org.apache.maven.model.Developer; +import org.apache.maven.model.DistributionManagement; +import org.apache.maven.model.Exclusion; +import org.apache.maven.model.Extension; +import org.apache.maven.model.IssueManagement; +import org.apache.maven.model.License; +import org.apache.maven.model.MailingList; +import org.apache.maven.model.Model; +import org.apache.maven.model.ModelBase; +import org.apache.maven.model.Notifier; +import org.apache.maven.model.Organization; +import org.apache.maven.model.Parent; +import org.apache.maven.model.Plugin; +import org.apache.maven.model.PluginExecution; +import org.apache.maven.model.PluginManagement; +import org.apache.maven.model.Prerequisites; +import org.apache.maven.model.Profile; +import org.apache.maven.model.Relocation; +import org.apache.maven.model.ReportPlugin; +import org.apache.maven.model.ReportSet; +import org.apache.maven.model.Reporting; +import org.apache.maven.model.Repository; +import org.apache.maven.model.RepositoryBase; +import org.apache.maven.model.RepositoryPolicy; +import org.apache.maven.model.Resource; +import org.apache.maven.model.Scm; +import org.apache.maven.model.Site; +import org.apache.maven.model.building.ModelBuildingRequest; +import org.apache.maven.model.building.ModelProblem.Severity; +import org.apache.maven.model.building.ModelProblem.Version; +import org.apache.maven.model.building.ModelProblemCollector; +import org.apache.maven.model.building.ModelProblemCollectorRequest; +import org.codehaus.plexus.interpolation.InterpolationException; +import org.codehaus.plexus.interpolation.InterpolationPostProcessor; +import org.codehaus.plexus.interpolation.RecursionInterceptor; +import org.codehaus.plexus.interpolation.StringSearchInterpolator; +import org.codehaus.plexus.interpolation.ValueSource; +import org.codehaus.plexus.util.xml.Xpp3Dom; + +/** + * StringVisitorModelInterpolator + */ +@Named +@Singleton +public class StringVisitorModelInterpolator + extends AbstractStringBasedModelInterpolator +{ + + interface InnerInterpolator + { + String interpolate( String value ); + } + + @Override + public Model interpolateModel( Model model, File projectDir, ModelBuildingRequest config, + ModelProblemCollector problems ) + { + List valueSources = createValueSources( model, projectDir, config, problems ); + List postProcessors = + createPostProcessors( model, projectDir, config ); + + InnerInterpolator innerInterpolator = createInterpolator( valueSources, postProcessors, problems ); + + new ModelVisitor( innerInterpolator ).visit( model ); + + return model; + } + + private InnerInterpolator createInterpolator( List valueSources, + List postProcessors, + final ModelProblemCollector problems ) + { + final Map cache = new HashMap<>(); + final StringSearchInterpolator interpolator = new StringSearchInterpolator(); + interpolator.setCacheAnswers( true ); + for ( ValueSource vs : valueSources ) + { + interpolator.addValueSource( vs ); + } + for ( InterpolationPostProcessor postProcessor : postProcessors ) + { + interpolator.addPostProcessor( postProcessor ); + } + final RecursionInterceptor recursionInterceptor = createRecursionInterceptor(); + return new InnerInterpolator() + { + @Override + public String interpolate( String value ) + { + if ( value != null && value.contains( "${" ) ) + { + String c = cache.get( value ); + if ( c == null ) + { + try + { + c = interpolator.interpolate( value, recursionInterceptor ); + } + catch ( InterpolationException e ) + { + problems.add( new ModelProblemCollectorRequest( Severity.ERROR, Version.BASE ) + .setMessage( e.getMessage() ).setException( e ) ); + } + cache.put( value, c ); + } + return c; + } + return value; + } + }; + } + + @SuppressWarnings( "StringEquality" ) + private static final class ModelVisitor + { + private final InnerInterpolator interpolator; + + ModelVisitor( InnerInterpolator interpolator ) + { + this.interpolator = interpolator; + } + + void visit( Model model ) + { + if ( model != null ) + { + visit( (ModelBase) model ); + // ModelVersion + String orgModelVersion = model.getModelVersion(); + String intModelVersion = interpolate( orgModelVersion ); + if ( orgModelVersion != intModelVersion ) + { + model.setModelVersion( intModelVersion ); + } + visit( model.getParent() ); + // GroupId + String orgGroupId = model.getGroupId(); + String intGroupId = interpolate( orgGroupId ); + if ( orgGroupId != intGroupId ) + { + model.setGroupId( intGroupId ); + } + // ArtifactId + String orgArtifactId = model.getArtifactId(); + String intArtifactId = interpolate( orgArtifactId ); + if ( orgArtifactId != intArtifactId ) + { + model.setArtifactId( intArtifactId ); + } + // Version + String orgVersion = model.getVersion(); + String intVersion = interpolate( orgVersion ); + if ( orgVersion != intVersion ) + { + model.setVersion( intVersion ); + } + + // Packaging + String orgPackaging = model.getPackaging(); + String intPackaging = interpolate( orgPackaging ); + if ( orgPackaging != intPackaging ) + { + model.setPackaging( intPackaging ); + } + // Name + String orgName = model.getName(); + String intName = interpolate( orgName ); + if ( orgName != intName ) + { + model.setName( intName ); + } + // Description + String orgDescription = model.getDescription(); + String intDescription = interpolate( orgDescription ); + if ( orgDescription != intDescription ) + { + model.setDescription( intDescription ); + } + // Url + String orgUrl = model.getUrl(); + String intUrl = interpolate( orgUrl ); + if ( orgUrl != intUrl ) + { + model.setUrl( intUrl ); + } + // ChildProjectUrlInheritAppendPath + String orgChildProjectUrlInheritAppendPath = model.getChildProjectUrlInheritAppendPath(); + String intChildProjectUrlInheritAppendPath = interpolate( orgChildProjectUrlInheritAppendPath ); + if ( orgChildProjectUrlInheritAppendPath != intChildProjectUrlInheritAppendPath ) + { + model.setChildProjectUrlInheritAppendPath( intChildProjectUrlInheritAppendPath ); + } + // InceptionYear + String orgInceptionYear = model.getInceptionYear(); + String intInceptionYear = interpolate( orgInceptionYear ); + if ( orgInceptionYear != intInceptionYear ) + { + model.setInceptionYear( intInceptionYear ); + } + visit( model.getOrganization() ); + for ( License license : model.getLicenses() ) + { + visit( license ); + } + for ( Developer developer : model.getDevelopers() ) + { + visit( developer ); + } + for ( Contributor contributor : model.getContributors() ) + { + visit( contributor ); + } + for ( MailingList mailingList : model.getMailingLists() ) + { + visit( mailingList ); + } + visit( model.getPrerequisites() ); + visit( model.getScm() ); + visit( model.getIssueManagement() ); + visit( model.getCiManagement() ); + visit( model.getBuild() ); + for ( Profile profile : model.getProfiles() ) + { + visit( profile ); + } + + } + } + + private void visit( Parent parent ) + { + if ( parent != null ) + { + String org, val; + // GroupId + org = parent.getGroupId(); + val = interpolate( org ); + if ( org != val ) + { + parent.setGroupId( val ); + } + // ArtifactId + org = parent.getArtifactId(); + val = interpolate( org ); + if ( org != val ) + { + parent.setArtifactId( val ); + } + // Version + org = parent.getVersion(); + val = interpolate( org ); + if ( org != val ) + { + parent.setVersion( val ); + } + // RelativePath + org = parent.getRelativePath(); + val = interpolate( org ); + if ( org != val ) + { + parent.setRelativePath( val ); + } + } + } + + private void visit( Organization organization ) + { + if ( organization != null ) + { + String org, val; + // Name + org = organization.getName(); + val = interpolate( org ); + if ( org != val ) + { + organization.setName( val ); + } + // Url + org = organization.getUrl(); + val = interpolate( org ); + if ( org != val ) + { + organization.setUrl( val ); + } + } + } + + private void visit( License license ) + { + if ( license != null ) + { + String org, val; + // Name + org = license.getName(); + val = interpolate( org ); + if ( org != val ) + { + license.setName( val ); + } + // Url + org = license.getUrl(); + val = interpolate( org ); + if ( org != val ) + { + license.setUrl( val ); + } + // Distribution + org = license.getDistribution(); + val = interpolate( org ); + if ( org != val ) + { + license.setDistribution( val ); + } + // Comments + org = license.getComments(); + val = interpolate( org ); + if ( org != val ) + { + license.setComments( val ); + } + } + } + + private void visit( Developer developer ) + { + if ( developer != null ) + { + String org, val; + // Contributor + visit( (Contributor) developer ); + // Distribution + org = developer.getId(); + val = interpolate( org ); + if ( org != val ) + { + developer.setId( val ); + } + } + } + + private void visit( Contributor contributor ) + { + if ( contributor != null ) + { + String org, val; + // Name + org = contributor.getName(); + val = interpolate( org ); + if ( org != val ) + { + contributor.setName( val ); + } + // Email + org = contributor.getEmail(); + val = interpolate( org ); + if ( org != val ) + { + contributor.setEmail( val ); + } + // Url + org = contributor.getUrl(); + val = interpolate( org ); + if ( org != val ) + { + contributor.setUrl( val ); + } + // Organization + org = contributor.getOrganization(); + val = interpolate( org ); + if ( org != val ) + { + contributor.setOrganization( val ); + } + // OrganizationUrl + org = contributor.getOrganizationUrl(); + val = interpolate( org ); + if ( org != val ) + { + contributor.setOrganizationUrl( val ); + } + // Roles + visit( contributor.getRoles() ); + } + } + + private void visit( MailingList mailingList ) + { + if ( mailingList != null ) + { + String org, val; + // Name + org = mailingList.getName(); + val = interpolate( org ); + if ( org != val ) + { + mailingList.setName( val ); + } + // Subscribe + org = mailingList.getSubscribe(); + val = interpolate( org ); + if ( org != val ) + { + mailingList.setSubscribe( val ); + } + // Unsubscribe + org = mailingList.getUnsubscribe(); + val = interpolate( org ); + if ( org != val ) + { + mailingList.setUnsubscribe( val ); + } + // Post + org = mailingList.getPost(); + val = interpolate( org ); + if ( org != val ) + { + mailingList.setPost( val ); + } + // Archive + org = mailingList.getArchive(); + val = interpolate( org ); + if ( org != val ) + { + mailingList.setArchive( val ); + } + } + } + + private void visit( Prerequisites prerequisites ) + { + if ( prerequisites != null ) + { + String org, val; + // Maven + org = prerequisites.getMaven(); + val = interpolate( org ); + if ( org != val ) + { + prerequisites.setMaven( val ); + } + } + } + + private void visit( Scm scm ) + { + if ( scm != null ) + { + String org, val; + // Connection + org = scm.getConnection(); + val = interpolate( org ); + if ( org != val ) + { + scm.setConnection( val ); + } + // DeveloperConnection + org = scm.getDeveloperConnection(); + val = interpolate( org ); + if ( org != val ) + { + scm.setDeveloperConnection( val ); + } + // Tag + org = scm.getTag(); + val = interpolate( org ); + if ( org != val ) + { + scm.setTag( val ); + } + // Url + org = scm.getUrl(); + val = interpolate( org ); + if ( org != val ) + { + scm.setUrl( val ); + } + // ChildScmConnectionInheritAppendPath + org = scm.getChildScmConnectionInheritAppendPath(); + val = interpolate( org ); + if ( org != val ) + { + scm.setChildScmConnectionInheritAppendPath( val ); + } + // ChildScmDeveloperConnectionInheritAppendPath + org = scm.getChildScmDeveloperConnectionInheritAppendPath(); + val = interpolate( org ); + if ( org != val ) + { + scm.setChildScmDeveloperConnectionInheritAppendPath( val ); + } + // ChildScmUrlInheritAppendPath + org = scm.getChildScmUrlInheritAppendPath(); + val = interpolate( org ); + if ( org != val ) + { + scm.setChildScmUrlInheritAppendPath( val ); + } + } + } + + private void visit( IssueManagement issueManagement ) + { + if ( issueManagement != null ) + { + String org, val; + // System + org = issueManagement.getSystem(); + val = interpolate( org ); + if ( org != val ) + { + issueManagement.setSystem( val ); + } + // Url + org = issueManagement.getUrl(); + val = interpolate( org ); + if ( org != val ) + { + issueManagement.setUrl( val ); + } + } + } + + private void visit( CiManagement ciManagement ) + { + if ( ciManagement != null ) + { + String org, val; + // System + org = ciManagement.getSystem(); + val = interpolate( org ); + if ( org != val ) + { + ciManagement.setSystem( val ); + } + // Url + org = ciManagement.getUrl(); + val = interpolate( org ); + if ( org != val ) + { + ciManagement.setUrl( val ); + } + // Notifiers + for ( Notifier notifier : ciManagement.getNotifiers() ) + { + visit( notifier ); + } + } + } + + private void visit( Notifier notifier ) + { + if ( notifier != null ) + { + String org, val; + // Type + org = notifier.getType(); + val = interpolate( org ); + if ( org != val ) + { + notifier.setType( val ); + } + // Configuration + visit( notifier.getConfiguration() ); + } + } + + private void visit( BuildBase build ) + { + if ( build != null ) + { + String org, val; + // Plugins + for ( Plugin plugin : build.getPlugins() ) + { + visit( plugin ); + } + // PluginManagement + visit( build.getPluginManagement() ); + // DefaultGoal + org = build.getDefaultGoal(); + val = interpolate( org ); + if ( org != val ) + { + build.setDefaultGoal( val ); + } + // Resources + for ( Resource resource : build.getResources() ) + { + visit( resource ); + } + // TestResources + for ( Resource resource : build.getTestResources() ) + { + visit( resource ); + } + // Directory + org = build.getDirectory(); + val = interpolate( org ); + if ( org != val ) + { + build.setDirectory( val ); + } + // FinalName + org = build.getFinalName(); + val = interpolate( org ); + if ( org != val ) + { + build.setFinalName( val ); + } + // Filters + visit( build.getFilters() ); + } + } + + private void visit( PluginManagement pluginManagement ) + { + if ( pluginManagement != null ) + { + for ( Plugin plugin : pluginManagement.getPlugins() ) + { + visit( plugin ); + } + } + } + + private void visit( Build build ) + { + if ( build != null ) + { + String org, val; + // BuildBase + visit( (BuildBase) build ); + // SourceDirectory + org = build.getSourceDirectory(); + val = interpolate( org ); + if ( org != val ) + { + build.setSourceDirectory( val ); + } + // ScriptSourceDirectory + org = build.getScriptSourceDirectory(); + val = interpolate( org ); + if ( org != val ) + { + build.setScriptSourceDirectory( val ); + } + // TestSourceDirectory + org = build.getTestSourceDirectory(); + val = interpolate( org ); + if ( org != val ) + { + build.setTestSourceDirectory( val ); + } + // OutputDirectory + org = build.getOutputDirectory(); + val = interpolate( org ); + if ( org != val ) + { + build.setOutputDirectory( val ); + } + // TestOutputDirectory + org = build.getTestOutputDirectory(); + val = interpolate( org ); + if ( org != val ) + { + build.setTestOutputDirectory( val ); + } + // Extensions + for ( Extension extension : build.getExtensions() ) + { + visit( extension ); + } + } + } + + private void visit( Resource resource ) + { + if ( resource != null ) + { + String org, val; + // Includes + visit( resource.getIncludes() ); + // Excludes + visit( resource.getExcludes() ); + // Directory + org = resource.getDirectory(); + val = interpolate( org ); + if ( org != val ) + { + resource.setDirectory( val ); + } + // TargetPath + org = resource.getTargetPath(); + val = interpolate( org ); + if ( org != val ) + { + resource.setTargetPath( val ); + } + // Filtering + org = resource.getFiltering(); + val = interpolate( org ); + if ( org != val ) + { + resource.setFiltering( val ); + } + } + } + + private void visit( Plugin plugin ) + { + if ( plugin != null ) + { + String org, val; + // Inherited + org = plugin.getInherited(); + val = interpolate( org ); + if ( org != val ) + { + plugin.setInherited( val ); + } + // Configuration + visit( (Xpp3Dom) plugin.getConfiguration() ); + // GroupId + org = plugin.getGroupId(); + val = interpolate( org ); + if ( org != val ) + { + plugin.setGroupId( val ); + } + // ArtifactId + org = plugin.getArtifactId(); + val = interpolate( org ); + if ( org != val ) + { + plugin.setArtifactId( val ); + } + // Version + org = plugin.getVersion(); + val = interpolate( org ); + if ( org != val ) + { + plugin.setVersion( val ); + } + // Extensions + org = plugin.getExtensions(); + val = interpolate( org ); + if ( org != val ) + { + plugin.setExtensions( val ); + } + // Executions + for ( PluginExecution execution : plugin.getExecutions() ) + { + visit( execution ); + } + // Dependencies + for ( Dependency dependency : plugin.getDependencies() ) + { + visit( dependency ); + } + } + } + + private void visit( PluginExecution execution ) + { + if ( execution != null ) + { + String org, val; + // Inherited + org = execution.getInherited(); + val = interpolate( org ); + if ( org != val ) + { + execution.setInherited( val ); + } + // Configuration + visit( (Xpp3Dom) execution.getConfiguration() ); + // Id + org = execution.getId(); + val = interpolate( org ); + if ( org != val ) + { + execution.setId( val ); + } + // Phase + org = execution.getPhase(); + val = interpolate( org ); + if ( org != val ) + { + execution.setPhase( val ); + } + // Goals + visit( execution.getGoals() ); + } + } + + private void visit( Xpp3Dom dom ) + { + if ( dom != null ) + { + String org, val; + // Content + org = dom.getValue(); + val = interpolate( org ); + if ( org != val ) + { + dom.setValue( val ); + } + // Attributes + for ( String attr : dom.getAttributeNames() ) + { + org = dom.getAttribute( attr ); + val = interpolate( org ); + if ( org != val ) + { + dom.setAttribute( attr, val ); + } + } + // Children + for ( int i = 0, l = dom.getChildCount(); i < l; i++ ) + { + visit( dom.getChild( i ) ); + } + } + } + + private void visit( Extension extension ) + { + if ( extension != null ) + { + String org, val; + // GroupId + org = extension.getGroupId(); + val = interpolate( org ); + if ( org != val ) + { + extension.setGroupId( val ); + } + // ArtifactId + org = extension.getArtifactId(); + val = interpolate( org ); + if ( org != val ) + { + extension.setArtifactId( val ); + } + // Version + org = extension.getVersion(); + val = interpolate( org ); + if ( org != val ) + { + extension.setVersion( val ); + } + } + } + + private void visit( Profile profile ) + { + if ( profile != null ) + { + String org, val; + // ModelBase + visit( (ModelBase) profile ); + // Id + org = profile.getId(); + val = interpolate( org ); + if ( org != val ) + { + profile.setId( val ); + } + // Activation + visit( profile.getActivation() ); + // Build + visit( profile.getBuild() ); + } + } + + private void visit( Activation activation ) + { + if ( activation != null ) + { + String org, val; + // Jdk + org = activation.getJdk(); + val = interpolate( org ); + if ( org != val ) + { + activation.setJdk( val ); + } + // OS + visit( activation.getOs() ); + // Property + visit( activation.getProperty() ); + // File + visit( activation.getFile() ); + } + } + + private void visit( ActivationOS activationOS ) + { + if ( activationOS != null ) + { + String org, val; + // Name + org = activationOS.getName(); + val = interpolate( org ); + if ( org != val ) + { + activationOS.setName( val ); + } + // Family + org = activationOS.getFamily(); + val = interpolate( org ); + if ( org != val ) + { + activationOS.setFamily( val ); + } + // Arch + org = activationOS.getArch(); + val = interpolate( org ); + if ( org != val ) + { + activationOS.setArch( val ); + } + // Version + org = activationOS.getVersion(); + val = interpolate( org ); + if ( org != val ) + { + activationOS.setVersion( val ); + } + } + } + + private void visit( ActivationProperty activationProperty ) + { + if ( activationProperty != null ) + { + String org, val; + // Name + org = activationProperty.getName(); + val = interpolate( org ); + if ( org != val ) + { + activationProperty.setName( val ); + } + // Value + org = activationProperty.getValue(); + val = interpolate( org ); + if ( org != val ) + { + activationProperty.setValue( val ); + } + } + } + + private void visit( ActivationFile activationFile ) + { + if ( activationFile != null ) + { + String org, val; + // Missing + org = activationFile.getMissing(); + val = interpolate( org ); + if ( org != val ) + { + activationFile.setMissing( val ); + } + // Exists + org = activationFile.getExists(); + val = interpolate( org ); + if ( org != val ) + { + activationFile.setExists( val ); + } + } + } + + private void visit( ModelBase modelBase ) + { + if ( modelBase != null ) + { + visit( modelBase.getModules() ); + visit( modelBase.getDistributionManagement() ); + visit( modelBase.getProperties() ); + visit( modelBase.getDependencyManagement() ); + for ( Dependency dependency : modelBase.getDependencies() ) + { + visit( dependency ); + } + for ( Repository repository : modelBase.getRepositories() ) + { + visit( repository ); + } + for ( Repository repository : modelBase.getPluginRepositories() ) + { + visit( repository ); + } + visit( modelBase.getReporting() ); + } + } + + private void visit( DistributionManagement distributionManagement ) + { + if ( distributionManagement != null ) + { + String org, val; + // Repository + visit( distributionManagement.getRepository() ); + // SnapshotRepository + visit( distributionManagement.getSnapshotRepository() ); + // Site + visit( distributionManagement.getSite() ); + // DownloadUrl + org = distributionManagement.getDownloadUrl(); + val = interpolate( org ); + if ( org != val ) + { + distributionManagement.setDownloadUrl( val ); + } + // Relocation + visit( distributionManagement.getRelocation() ); + } + } + + private void visit( Site site ) + { + if ( site != null ) + { + String org, val; + // Id + org = site.getId(); + val = interpolate( org ); + if ( org != val ) + { + site.setId( val ); + } + // Name + org = site.getName(); + val = interpolate( org ); + if ( org != val ) + { + site.setName( val ); + } + // Url + org = site.getUrl(); + val = interpolate( org ); + if ( org != val ) + { + site.setUrl( val ); + } + // ChildSiteUrlInheritAppendPath + org = site.getChildSiteUrlInheritAppendPath(); + val = interpolate( org ); + if ( org != val ) + { + site.setChildSiteUrlInheritAppendPath( val ); + } + } + } + + private void visit( Relocation relocation ) + { + if ( relocation != null ) + { + String org, val; + // GroupId + org = relocation.getGroupId(); + val = interpolate( org ); + if ( org != val ) + { + relocation.setGroupId( val ); + } + // ArtifactId + org = relocation.getArtifactId(); + val = interpolate( org ); + if ( org != val ) + { + relocation.setArtifactId( val ); + } + // Version + org = relocation.getVersion(); + val = interpolate( org ); + if ( org != val ) + { + relocation.setVersion( val ); + } + // Message + org = relocation.getMessage(); + val = interpolate( org ); + if ( org != val ) + { + relocation.setMessage( val ); + } + } + } + + private void visit( DependencyManagement dependencyManagement ) + { + if ( dependencyManagement != null ) + { + // Dependencies + for ( Dependency dependency : dependencyManagement.getDependencies() ) + { + visit( dependency ); + } + } + } + + private void visit( Repository repository ) + { + if ( repository != null ) + { + visit( (RepositoryBase) repository ); + visit( repository.getReleases() ); + visit( repository.getSnapshots() ); + } + } + + private void visit( RepositoryBase repositoryBase ) + { + if ( repositoryBase != null ) + { + // Id + String orgId = repositoryBase.getId(); + String intId = interpolate( orgId ); + if ( orgId != intId ) + { + repositoryBase.setId( intId ); + } + // Name + String orgName = repositoryBase.getName(); + String intName = interpolate( orgName ); + if ( orgName != intName ) + { + repositoryBase.setName( intName ); + } + // Url + String orgUrl = repositoryBase.getUrl(); + String intUrl = interpolate( orgUrl ); + if ( orgUrl != intUrl ) + { + repositoryBase.setUrl( intUrl ); + } + // Layout + String orgLayout = repositoryBase.getLayout(); + String intLayout = interpolate( orgLayout ); + if ( orgLayout != intLayout ) + { + repositoryBase.setLayout( intLayout ); + } + } + } + + private void visit( RepositoryPolicy repositoryPolicy ) + { + if ( repositoryPolicy != null ) + { + // Enabled + String orgEnabled = repositoryPolicy.getEnabled(); + String intEnabled = interpolate( orgEnabled ); + if ( orgEnabled != intEnabled ) + { + repositoryPolicy.setEnabled( intEnabled ); + } + // UpdatePolicy + String orgUpdatePolicy = repositoryPolicy.getUpdatePolicy(); + String intUpdatePolicy = interpolate( orgUpdatePolicy ); + if ( orgUpdatePolicy != intUpdatePolicy ) + { + repositoryPolicy.setUpdatePolicy( intUpdatePolicy ); + } + // ChecksumPolicy + String orgChecksumPolicy = repositoryPolicy.getChecksumPolicy(); + String intChecksumPolicy = interpolate( orgChecksumPolicy ); + if ( orgChecksumPolicy != intChecksumPolicy ) + { + repositoryPolicy.setChecksumPolicy( intChecksumPolicy ); + } + } + } + + private void visit( Dependency dependency ) + { + if ( dependency != null ) + { + String org, val; + // GroupId + org = dependency.getGroupId(); + val = interpolate( org ); + if ( org != val ) + { + dependency.setGroupId( val ); + dependency.clearManagementKey(); + } + // ArtifactId + org = dependency.getArtifactId(); + val = interpolate( org ); + if ( org != val ) + { + dependency.setArtifactId( val ); + dependency.clearManagementKey(); + } + // Version + org = dependency.getVersion(); + val = interpolate( org ); + if ( org != val ) + { + dependency.setVersion( val ); + } + // Type + org = dependency.getType(); + val = interpolate( org ); + if ( org != val ) + { + dependency.setType( val ); + dependency.clearManagementKey(); + } + // Classifier + org = dependency.getClassifier(); + val = interpolate( org ); + if ( org != val ) + { + dependency.setClassifier( val ); + dependency.clearManagementKey(); + } + // Scope + org = dependency.getScope(); + val = interpolate( org ); + if ( org != val ) + { + dependency.setScope( val ); + } + // SystemPath + org = dependency.getSystemPath(); + val = interpolate( org ); + if ( org != val ) + { + dependency.setSystemPath( val ); + } + // Exclusions + for ( Exclusion exclusion : dependency.getExclusions() ) + { + visit( exclusion ); + } + // Optional + org = dependency.getOptional(); + val = interpolate( org ); + if ( org != val ) + { + dependency.setOptional( val ); + } + } + } + + private void visit( Exclusion exclusion ) + { + if ( exclusion != null ) + { + String org, val; + // GroupId + org = exclusion.getGroupId(); + val = interpolate( org ); + if ( org != val ) + { + exclusion.setGroupId( val ); + } + // ArtifactId + org = exclusion.getArtifactId(); + val = interpolate( org ); + if ( org != val ) + { + exclusion.setArtifactId( val ); + } + } + } + + private void visit( Reporting reporting ) + { + if ( reporting != null ) + { + String org, val; + // ExcludeDefaults + org = reporting.getExcludeDefaults(); + val = interpolate( org ); + if ( org != val ) + { + reporting.setExcludeDefaults( val ); + } + // OutputDirectory + org = reporting.getOutputDirectory(); + val = interpolate( org ); + if ( org != val ) + { + reporting.setOutputDirectory( val ); + } + // Plugins + for ( ReportPlugin plugin : reporting.getPlugins() ) + { + visit( plugin ); + } + } + } + + private void visit( ReportPlugin plugin ) + { + if ( plugin != null ) + { + String org, val; + // Inherited + org = plugin.getInherited(); + val = interpolate( org ); + if ( org != val ) + { + plugin.setInherited( val ); + } + // Configuration + visit( (Xpp3Dom) plugin.getConfiguration() ); + // GroupId + org = plugin.getGroupId(); + val = interpolate( org ); + if ( org != val ) + { + plugin.setGroupId( val ); + } + // ArtifactId + org = plugin.getArtifactId(); + val = interpolate( org ); + if ( org != val ) + { + plugin.setArtifactId( val ); + } + // Version + org = plugin.getVersion(); + val = interpolate( org ); + if ( org != val ) + { + plugin.setVersion( val ); + } + // ReportSets + for ( ReportSet reportSet : plugin.getReportSets() ) + { + visit( reportSet ); + } + } + } + + private void visit( ReportSet reportSet ) + { + if ( reportSet != null ) + { + String org, val; + // Inherited + org = reportSet.getInherited(); + val = interpolate( org ); + if ( org != val ) + { + reportSet.setInherited( val ); + } + // Configuration + visit( (Xpp3Dom) reportSet.getConfiguration() ); + // Id + org = reportSet.getId(); + val = interpolate( org ); + if ( org != val ) + { + reportSet.setId( val ); + } + // Reports + visit( reportSet.getReports() ); + } + } + + private void visit( Properties properties ) + { + if ( properties != null ) + { + for ( Map.Entry entry : properties.entrySet() ) + { + Object v = entry.getValue(); + if ( v instanceof String ) + { + String value = (String) v; + String inter = interpolate( value ); + if ( value != inter ) + { + entry.setValue( inter ); + } + } + } + } + } + + private void visit( List list ) + { + if ( list != null ) + { + ListIterator it = list.listIterator(); + while ( it.hasNext() ) + { + String value = it.next(); + String inter = interpolate( value ); + if ( value != inter ) + { + it.set( inter ); + } + } + } + } + + private String interpolate( String value ) + { + return interpolator.interpolate( value ); + } + + } +} diff --git a/maven-model/src/main/mdo/maven.mdo b/maven-model/src/main/mdo/maven.mdo index b199ee156ecb..77738f1000a3 100644 --- a/maven-model/src/main/mdo/maven.mdo +++ b/maven-model/src/main/mdo/maven.mdo @@ -1153,6 +1153,14 @@ } return managementKey; } + + /** + * Clears the management key in case one field has been modified. + */ + public void clearManagementKey() + { + managementKey = null; + } ]]>