You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@maven.apache.org by rf...@apache.org on 2020/12/21 21:24:01 UTC
[maven] 01/01: [MNG-6957] versionless reactor dependencies/parent
should work even if modules are aggregated in reverse order
This is an automated email from the ASF dual-hosted git repository.
rfscholte pushed a commit to branch MNG-6957_squashed
in repository https://gitbox.apache.org/repos/asf/maven.git
commit 12f31c9519b9e558443bfd1ffdc87d8a956607e7
Author: rfscholte <rf...@apache.org>
AuthorDate: Mon Dec 21 22:23:43 2020 +0100
[MNG-6957] versionless reactor dependencies/parent should work even if modules are aggregated in reverse order
---
.../aether/ConsumerModelSourceTransformer.java | 4 +-
.../maven/project/DefaultProjectBuilder.java | 122 ++---
.../apache/maven/project/ReactorModelCache.java | 9 +-
.../DefaultConsumerPomXMLFilterFactory.java | 29 +-
.../building/BuildModelSourceTransformer.java | 2 +-
.../building/DefaultBuildPomXMLFilterFactory.java | 39 +-
.../maven/model/building/DefaultModelBuilder.java | 572 ++++++++++++++-------
.../building/DefaultModelBuildingRequest.java | 21 +-
.../model/building/DefaultModelBuildingResult.java | 30 ++
.../model/building/DefaultTransformerContext.java | 95 ++++
.../model/building/FilterModelBuildingRequest.java | 12 +-
.../apache/maven/model/building/ModelBuilder.java | 2 +
.../maven/model/building/ModelBuildingRequest.java | 27 +-
.../maven/model/building/ModelBuildingResult.java | 7 +
.../apache/maven/model/building/ModelCacheTag.java | 10 +-
.../org/apache/maven/model/building/ModelData.java | 113 +---
.../model/building/ModelSourceTransformer.java | 12 +
.../maven/model/building/TransformerContext.java | 6 +-
...sformer.java => TransformerContextBuilder.java} | 25 +-
.../apache/maven/model/io/DefaultModelReader.java | 12 +-
.../org/apache/maven/model/io/ModelReader.java | 6 +
maven-model-builder/src/site/apt/index.apt | 27 +-
.../validation/DefaultModelValidatorTest.java | 4 -
.../xml/sax/filter/BuildPomXMLFilterFactory.java | 45 +-
.../maven/xml/sax/filter/CiFriendlyXMLFilter.java | 13 +-
.../sax/filter/ConsumerPomXMLFilterFactory.java | 33 +-
.../maven/xml/sax/filter/ParentXMLFilter.java | 21 +-
.../xml/sax/filter/CiFriendlyXMLFilterTest.java | 2 +-
.../xml/sax/filter/ConsumerPomXMLFilterTest.java | 17 +-
.../maven/xml/sax/filter/ParentXMLFilterTest.java | 25 +
30 files changed, 826 insertions(+), 516 deletions(-)
diff --git a/maven-core/src/main/java/org/apache/maven/internal/aether/ConsumerModelSourceTransformer.java b/maven-core/src/main/java/org/apache/maven/internal/aether/ConsumerModelSourceTransformer.java
index d81571d..4d5d263 100644
--- a/maven-core/src/main/java/org/apache/maven/internal/aether/ConsumerModelSourceTransformer.java
+++ b/maven-core/src/main/java/org/apache/maven/internal/aether/ConsumerModelSourceTransformer.java
@@ -46,13 +46,13 @@ import org.xml.sax.ext.LexicalHandler;
class ConsumerModelSourceTransformer extends AbstractModelSourceTransformer
{
@Override
- protected AbstractSAXFilter getSAXFilter( Path pomFile,
+ protected AbstractSAXFilter getSAXFilter( Path pomFile,
TransformerContext context,
Consumer<LexicalHandler> lexicalHandlerConsumer )
throws TransformerConfigurationException, SAXException, ParserConfigurationException
{
return new DefaultConsumerPomXMLFilterFactory( new DefaultBuildPomXMLFilterFactory( context,
- lexicalHandlerConsumer ) ).get( pomFile );
+ lexicalHandlerConsumer, true ) ).get( pomFile );
}
/**
diff --git a/maven-core/src/main/java/org/apache/maven/project/DefaultProjectBuilder.java b/maven-core/src/main/java/org/apache/maven/project/DefaultProjectBuilder.java
index 624f6ad..a86cb1f 100644
--- a/maven-core/src/main/java/org/apache/maven/project/DefaultProjectBuilder.java
+++ b/maven-core/src/main/java/org/apache/maven/project/DefaultProjectBuilder.java
@@ -21,7 +21,6 @@ package org.apache.maven.project;
import java.io.File;
import java.io.IOException;
-import java.nio.file.Path;
import java.util.AbstractMap;
import java.util.ArrayList;
import java.util.Arrays;
@@ -33,6 +32,7 @@ import java.util.LinkedHashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
+import java.util.stream.Collectors;
import javax.inject.Inject;
import javax.inject.Named;
@@ -56,6 +56,7 @@ import org.apache.maven.model.Plugin;
import org.apache.maven.model.Profile;
import org.apache.maven.model.ReportPlugin;
import org.apache.maven.model.building.ArtifactModelSource;
+import org.apache.maven.model.building.TransformerContextBuilder;
import org.apache.maven.model.building.DefaultModelBuildingRequest;
import org.apache.maven.model.building.DefaultModelProblem;
import org.apache.maven.model.building.FileModelSource;
@@ -129,7 +130,7 @@ public class DefaultProjectBuilder
throws ProjectBuildingException
{
return build( pomFile, new FileModelSource( pomFile ),
- new InternalConfig( request, null, useGlobalModelCache() ? getModelCache() : null ) );
+ new InternalConfig( request, null, useGlobalModelCache() ? getModelCache() : null, null ) );
}
private boolean useGlobalModelCache()
@@ -142,7 +143,7 @@ public class DefaultProjectBuilder
throws ProjectBuildingException
{
return build( null, modelSource,
- new InternalConfig( request, null, useGlobalModelCache() ? getModelCache() : null ) );
+ new InternalConfig( request, null, useGlobalModelCache() ? getModelCache() : null, null ) );
}
private ProjectBuildingResult build( File pomFile, ModelSource modelSource, InternalConfig config )
@@ -263,14 +264,7 @@ public class DefaultProjectBuilder
private List<String> getProfileIds( List<Profile> profiles )
{
- List<String> ids = new ArrayList<>( profiles.size() );
-
- for ( Profile profile : profiles )
- {
- ids.add( profile.getId() );
- }
-
- return ids;
+ return profiles.stream().map( Profile::getId ).collect( Collectors.toList() );
}
private ModelBuildingRequest getModelBuildingRequest( InternalConfig config )
@@ -295,7 +289,7 @@ public class DefaultProjectBuilder
request.setBuildStartTime( configuration.getBuildStartTime() );
request.setModelResolver( resolver );
request.setModelCache( config.modelCache );
- request.setTransformerContext( (TransformerContext) config.session.getData().get( TransformerContext.KEY ) );
+ request.setTransformerContextBuilder( config.transformerContextBuilder );
return request;
}
@@ -314,7 +308,8 @@ public class DefaultProjectBuilder
org.eclipse.aether.artifact.Artifact pomArtifact = RepositoryUtils.toArtifact( artifact );
pomArtifact = ArtifactDescriptorUtils.toPomArtifact( pomArtifact );
- InternalConfig config = new InternalConfig( request, null, useGlobalModelCache() ? getModelCache() : null );
+ InternalConfig config =
+ new InternalConfig( request, null, useGlobalModelCache() ? getModelCache() : null, null );
boolean localProject;
@@ -386,36 +381,13 @@ public class DefaultProjectBuilder
ReactorModelPool.Builder poolBuilder = new ReactorModelPool.Builder();
final ReactorModelPool modelPool = poolBuilder.build();
- if ( Features.buildConsumer().isActive() )
- {
- final TransformerContext context = new TransformerContext()
- {
- @Override
- public String getUserProperty( String key )
- {
- return request.getUserProperties().getProperty( key );
- }
-
- @Override
- public Model getRawModel( Path p )
- {
- return modelPool.get( p );
- }
-
- @Override
- public Model getRawModel( String groupId, String artifactId )
- {
- return modelPool.get( groupId, artifactId, null );
- }
- };
- request.getRepositorySession().getData().set( TransformerContext.KEY, context );
- }
-
- InternalConfig config = new InternalConfig( request, modelPool,
- useGlobalModelCache() ? getModelCache() : new ReactorModelCache() );
+ InternalConfig config =
+ new InternalConfig( request, modelPool, useGlobalModelCache() ? getModelCache() : new ReactorModelCache(),
+ modelBuilder.newTransformerContextBuilder() );
- Map<String, MavenProject> projectIndex = new HashMap<>( 256 );
+ Map<File, MavenProject> projectIndex = new HashMap<>( 256 );
+ // phase 1: get file Models from the reactor.
boolean noErrors =
build( results, interimResults, projectIndex, pomFiles, new LinkedHashSet<>(), true, recursive,
config, poolBuilder );
@@ -424,6 +396,7 @@ public class DefaultProjectBuilder
try
{
+ // Phase 2: get effective models from the reactor
noErrors =
build( results, new ArrayList<>(), projectIndex, interimResults, request,
new HashMap<>(), config.session ) && noErrors;
@@ -433,6 +406,12 @@ public class DefaultProjectBuilder
Thread.currentThread().setContextClassLoader( oldContextClassLoader );
}
+ if ( Features.buildConsumer().isActive() )
+ {
+ request.getRepositorySession().getData().set( TransformerContext.KEY,
+ config.transformerContextBuilder.build() );
+ }
+
if ( !noErrors )
{
throw new ProjectBuildingException( results );
@@ -443,7 +422,7 @@ public class DefaultProjectBuilder
@SuppressWarnings( "checkstyle:parameternumber" )
private boolean build( List<ProjectBuildingResult> results, List<InterimResult> interimResults,
- Map<String, MavenProject> projectIndex, List<File> pomFiles, Set<File> aggregatorFiles,
+ Map<File, MavenProject> projectIndex, List<File> pomFiles, Set<File> aggregatorFiles,
boolean root, boolean recursive, InternalConfig config,
ReactorModelPool.Builder poolBuilder )
{
@@ -467,20 +446,19 @@ public class DefaultProjectBuilder
@SuppressWarnings( "checkstyle:parameternumber" )
private boolean build( List<ProjectBuildingResult> results, List<InterimResult> interimResults,
- Map<String, MavenProject> projectIndex, File pomFile, Set<File> aggregatorFiles,
+ Map<File, MavenProject> projectIndex, File pomFile, Set<File> aggregatorFiles,
boolean isRoot, boolean recursive, InternalConfig config,
ReactorModelPool.Builder poolBuilder )
{
boolean noErrors = true;
- ModelBuildingRequest request = getModelBuildingRequest( config );
-
MavenProject project = new MavenProject();
project.setFile( pomFile );
- request.setPomFile( pomFile );
- request.setTwoPhaseBuilding( true );
- request.setLocationTracking( true );
+ ModelBuildingRequest request = getModelBuildingRequest( config )
+ .setPomFile( pomFile )
+ .setTwoPhaseBuilding( true )
+ .setLocationTracking( true );
DefaultModelBuildingListener listener =
new DefaultModelBuildingListener( project, projectBuildingHelper, config.request );
@@ -494,7 +472,7 @@ public class DefaultProjectBuilder
catch ( ModelBuildingException e )
{
result = e.getResult();
- if ( result == null || result.getEffectiveModel() == null )
+ if ( result == null || result.getFileModel() == null )
{
results.add( new DefaultProjectBuildingResult( e.getModelId(), pomFile, e.getProblems() ) );
@@ -505,32 +483,17 @@ public class DefaultProjectBuilder
noErrors = false;
}
- Model model = result.getEffectiveModel();
+ Model model = result.getFileModel().clone();
- poolBuilder.put( model.getPomFile().toPath(), result.getRawModel() );
+ poolBuilder.put( model.getPomFile().toPath(), model );
- try
- {
- // first pass: build without building parent.
- initProject( project, projectIndex, false, result, new HashMap<>( 0 ), config.request );
- }
- catch ( InvalidArtifactRTException iarte )
- {
- result.getProblems().add( new DefaultModelProblem( null, ModelProblem.Severity.ERROR, null, model, -1, -1,
- iarte ) );
- }
-
- projectIndex.put( result.getModelIds().get( 0 ), project );
-
InterimResult interimResult = new InterimResult( pomFile, request, result, listener, isRoot );
interimResults.add( interimResult );
- if ( recursive && !model.getModules().isEmpty() )
+ if ( recursive )
{
File basedir = pomFile.getParentFile();
-
List<File> moduleFiles = new ArrayList<>();
-
for ( String module : model.getModules() )
{
if ( StringUtils.isEmpty( module ) )
@@ -608,6 +571,8 @@ public class DefaultProjectBuilder
noErrors = false;
}
}
+
+ projectIndex.put( pomFile, project );
return noErrors;
}
@@ -640,7 +605,7 @@ public class DefaultProjectBuilder
}
private boolean build( List<ProjectBuildingResult> results, List<MavenProject> projects,
- Map<String, MavenProject> projectIndex, List<InterimResult> interimResults,
+ Map<File, MavenProject> projectIndex, List<InterimResult> interimResults,
ProjectBuildingRequest request, Map<File, Boolean> profilesXmls,
RepositorySystemSession session )
{
@@ -685,12 +650,14 @@ public class DefaultProjectBuilder
catch ( ModelBuildingException e )
{
DefaultProjectBuildingResult result = null;
- if ( project == null )
+ if ( project == null || interimResult.result.getEffectiveModel() == null )
{
result = new DefaultProjectBuildingResult( e.getModelId(), interimResult.pomFile, e.getProblems() );
}
else
{
+ project.setModel( interimResult.result.getEffectiveModel() );
+
result = new DefaultProjectBuildingResult( project, e.getProblems(), null );
}
results.add( result );
@@ -703,15 +670,14 @@ public class DefaultProjectBuilder
}
@SuppressWarnings( "checkstyle:methodlength" )
- private void initProject( MavenProject project, Map<String, MavenProject> projects,
+ private void initProject( MavenProject project, Map<File, MavenProject> projects,
boolean buildParentIfNotExisting, ModelBuildingResult result,
Map<File, Boolean> profilesXmls, ProjectBuildingRequest projectBuildingRequest )
{
Model model = result.getEffectiveModel();
project.setModel( model );
- project.setOriginalModel( result.getRawModel() );
- project.setFile( model.getPomFile() );
+ project.setOriginalModel( result.getFileModel() );
initParent( project, projects, buildParentIfNotExisting, result, projectBuildingRequest );
@@ -938,7 +904,7 @@ public class DefaultProjectBuilder
}
}
- private void initParent( MavenProject project, Map<String, MavenProject> projects, boolean buildParentIfNotExisting,
+ private void initParent( MavenProject project, Map<File, MavenProject> projects, boolean buildParentIfNotExisting,
ModelBuildingResult result, ProjectBuildingRequest projectBuildingRequest )
{
Model parentModel = result.getModelIds().size() > 1 && !result.getModelIds().get( 1 ).isEmpty()
@@ -957,7 +923,7 @@ public class DefaultProjectBuilder
// org.apache.maven.its.mng4834:parent:0.1
String parentModelId = result.getModelIds().get( 1 );
File parentPomFile = result.getRawModel( parentModelId ).getPomFile();
- MavenProject parent = projects.get( parentModelId );
+ MavenProject parent = projects.get( parentPomFile );
if ( parent == null && buildParentIfNotExisting )
{
//
@@ -1095,16 +1061,22 @@ public class DefaultProjectBuilder
private final ReactorModelPool modelPool;
private final ReactorModelCache modelCache;
+
+ private final TransformerContextBuilder transformerContextBuilder;
- InternalConfig( ProjectBuildingRequest request, ReactorModelPool modelPool, ReactorModelCache modelCache )
+ InternalConfig( ProjectBuildingRequest request, ReactorModelPool modelPool, ReactorModelCache modelCache,
+ TransformerContextBuilder transformerContextBuilder )
{
this.request = request;
this.modelPool = modelPool;
this.modelCache = modelCache;
+ this.transformerContextBuilder = transformerContextBuilder;
+
session =
LegacyLocalRepositoryManager.overlay( request.getLocalRepository(), request.getRepositorySession(),
repoSystem );
repositories = RepositoryUtils.toRepos( request.getRemoteRepositories() );
+
}
}
diff --git a/maven-core/src/main/java/org/apache/maven/project/ReactorModelCache.java b/maven-core/src/main/java/org/apache/maven/project/ReactorModelCache.java
index 72c25c7..20e57b9 100644
--- a/maven-core/src/main/java/org/apache/maven/project/ReactorModelCache.java
+++ b/maven-core/src/main/java/org/apache/maven/project/ReactorModelCache.java
@@ -80,13 +80,7 @@ class ReactorModelCache
this.artifactId = ( artifactId != null ) ? artifactId : "";
this.version = ( version != null ) ? version : "";
this.tag = ( tag != null ) ? tag : "";
-
- int hash = 17;
- hash = hash * 31 + this.groupId.hashCode();
- hash = hash * 31 + this.artifactId.hashCode();
- hash = hash * 31 + this.version.hashCode();
- hash = hash * 31 + this.tag.hashCode();
- hashCode = hash;
+ this.hashCode = Objects.hash( groupId, artifactId, version, tag );
}
@Override
@@ -113,7 +107,6 @@ class ReactorModelCache
{
return hashCode;
}
-
}
private static final class SourceCacheKey
diff --git a/maven-core/src/main/java/org/apache/maven/xml/internal/DefaultConsumerPomXMLFilterFactory.java b/maven-core/src/main/java/org/apache/maven/xml/internal/DefaultConsumerPomXMLFilterFactory.java
index aa68680..b27a87b 100644
--- a/maven-core/src/main/java/org/apache/maven/xml/internal/DefaultConsumerPomXMLFilterFactory.java
+++ b/maven-core/src/main/java/org/apache/maven/xml/internal/DefaultConsumerPomXMLFilterFactory.java
@@ -9,7 +9,7 @@ package org.apache.maven.xml.internal;
* "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
+ * 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
@@ -19,10 +19,7 @@ package org.apache.maven.xml.internal;
* under the License.
*/
-import java.util.Optional;
-
import org.apache.maven.model.building.DefaultBuildPomXMLFilterFactory;
-import org.apache.maven.model.building.TransformerContext;
import org.apache.maven.xml.sax.filter.ConsumerPomXMLFilterFactory;
/**
@@ -34,32 +31,8 @@ import org.apache.maven.xml.sax.filter.ConsumerPomXMLFilterFactory;
*/
public class DefaultConsumerPomXMLFilterFactory extends ConsumerPomXMLFilterFactory
{
- private final TransformerContext context;
-
public DefaultConsumerPomXMLFilterFactory( DefaultBuildPomXMLFilterFactory buildPomXMLFilterFactory )
{
super( buildPomXMLFilterFactory );
- this.context = buildPomXMLFilterFactory.getContext();
- }
-
- @Override
- protected Optional<String> getChangelist()
- {
- return Optional.ofNullable( context.getUserProperty( "changelist" ) );
- }
-
- @Override
- protected Optional<String> getRevision()
- {
- return Optional.ofNullable( context.getUserProperty( "revision" ) );
}
-
- @Override
- protected Optional<String> getSha1()
- {
- return Optional.ofNullable( context.getUserProperty( "sha1" ) );
- }
-
-
-
}
diff --git a/maven-model-builder/src/main/java/org/apache/maven/model/building/BuildModelSourceTransformer.java b/maven-model-builder/src/main/java/org/apache/maven/model/building/BuildModelSourceTransformer.java
index 9766b8d..1119623 100644
--- a/maven-model-builder/src/main/java/org/apache/maven/model/building/BuildModelSourceTransformer.java
+++ b/maven-model-builder/src/main/java/org/apache/maven/model/building/BuildModelSourceTransformer.java
@@ -58,7 +58,7 @@ class BuildModelSourceTransformer extends AbstractModelSourceTransformer
throws TransformerConfigurationException, SAXException, ParserConfigurationException
{
BuildPomXMLFilterFactory buildPomXMLFilterFactory =
- new DefaultBuildPomXMLFilterFactory( context, lexicalHandlerConsumer );
+ new DefaultBuildPomXMLFilterFactory( context, lexicalHandlerConsumer, false );
return buildPomXMLFilterFactory.get( pomFile );
}
diff --git a/maven-model-builder/src/main/java/org/apache/maven/model/building/DefaultBuildPomXMLFilterFactory.java b/maven-model-builder/src/main/java/org/apache/maven/model/building/DefaultBuildPomXMLFilterFactory.java
index cf095e0..122b144 100644
--- a/maven-model-builder/src/main/java/org/apache/maven/model/building/DefaultBuildPomXMLFilterFactory.java
+++ b/maven-model-builder/src/main/java/org/apache/maven/model/building/DefaultBuildPomXMLFilterFactory.java
@@ -32,7 +32,8 @@ import org.apache.maven.xml.sax.filter.RelativeProject;
import org.xml.sax.ext.LexicalHandler;
/**
- *
+ * A BuildPomXMLFilterFactory which is context aware
+ *
* @author Robert Scholte
* @since 4.0.0
*/
@@ -40,18 +41,20 @@ public class DefaultBuildPomXMLFilterFactory extends BuildPomXMLFilterFactory
{
private final TransformerContext context;
+ /**
+ *
+ * @param context a set of data to extract values from as required for the build pom
+ * @param lexicalHandlerConsumer the lexical handler consumer
+ * @param consume {@code true} if this factory is being used for creating the consumer pom, otherwise {@code false}
+ */
public DefaultBuildPomXMLFilterFactory( TransformerContext context,
- Consumer<LexicalHandler> lexicalHandlerConsumer )
+ Consumer<LexicalHandler> lexicalHandlerConsumer,
+ boolean consume )
{
- super( lexicalHandlerConsumer );
+ super( lexicalHandlerConsumer, consume );
this.context = context;
}
-
- public final TransformerContext getContext()
- {
- return context;
- }
-
+
@Override
protected Function<Path, Optional<RelativeProject>> getRelativePathMapper()
{
@@ -66,6 +69,24 @@ public class DefaultBuildPomXMLFilterFactory extends BuildPomXMLFilterFactory
.orElse( null );
}
+ @Override
+ protected Optional<String> getChangelist()
+ {
+ return Optional.ofNullable( context.getUserProperty( "changelist" ) );
+ }
+
+ @Override
+ protected Optional<String> getRevision()
+ {
+ return Optional.ofNullable( context.getUserProperty( "revision" ) );
+ }
+
+ @Override
+ protected Optional<String> getSha1()
+ {
+ return Optional.ofNullable( context.getUserProperty( "sha1" ) );
+ }
+
private static RelativeProject toRelativeProject( final Model m )
{
String groupId = m.getGroupId();
diff --git a/maven-model-builder/src/main/java/org/apache/maven/model/building/DefaultModelBuilder.java b/maven-model-builder/src/main/java/org/apache/maven/model/building/DefaultModelBuilder.java
index 8b31908..f833c25 100644
--- a/maven-model-builder/src/main/java/org/apache/maven/model/building/DefaultModelBuilder.java
+++ b/maven-model-builder/src/main/java/org/apache/maven/model/building/DefaultModelBuilder.java
@@ -25,16 +25,21 @@ import static org.apache.maven.model.building.Result.newResult;
import org.apache.maven.artifact.versioning.ArtifactVersion;
import java.io.File;
import java.io.IOException;
+import java.nio.file.Files;
+import java.nio.file.Path;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
+import java.util.HashSet;
import java.util.Iterator;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.Properties;
+import java.util.Set;
+import java.util.concurrent.ConcurrentHashMap;
import javax.inject.Inject;
import javax.inject.Named;
@@ -69,6 +74,7 @@ import org.apache.maven.model.composition.DependencyManagementImporter;
import org.apache.maven.model.inheritance.InheritanceAssembler;
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.DependencyManagementInjector;
import org.apache.maven.model.management.PluginManagementInjector;
import org.apache.maven.model.merge.ModelMerger;
@@ -257,6 +263,12 @@ public class DefaultModelBuilder
}
@Override
+ public DefaultTransformerContextBuilder newTransformerContextBuilder()
+ {
+ return new DefaultTransformerContextBuilder();
+ }
+
+ @Override
public ModelBuildingResult build( ModelBuildingRequest request )
throws ModelBuildingException
{
@@ -272,6 +284,33 @@ public class DefaultModelBuilder
DefaultModelProblemCollector problems = new DefaultModelProblemCollector( result );
+ // read and validate raw model
+ Model fileModel = readFileModel( request, problems );
+
+ request.setFileModel( fileModel );
+ result.setFileModel( fileModel );
+
+ activateFileModel( request, result, problems );
+
+ if ( !request.isTwoPhaseBuilding() )
+ {
+ return build( request, result, importIds );
+ }
+ else if ( hasModelErrors( problems ) )
+ {
+ throw problems.newModelBuildingException();
+ }
+
+ return result;
+ }
+
+ private void activateFileModel( final ModelBuildingRequest request, final DefaultModelBuildingResult result,
+ DefaultModelProblemCollector problems )
+ throws ModelBuildingException
+ {
+ Model inputModel = request.getFileModel();
+ problems.setRootModel( inputModel );
+
// profile activation
DefaultProfileActivationContext profileActivationContext = getProfileActivationContext( request );
@@ -292,47 +331,89 @@ public class DefaultModelBuilder
profileActivationContext.setUserProperties( profileProps );
}
- // read and validate raw model
- Model inputModel = request.getRawModel();
- if ( inputModel == null )
+ profileActivationContext.setProjectProperties( inputModel.getProperties() );
+ problems.setSource( inputModel );
+ List<Profile> activePomProfiles = profileSelector.getActiveProfiles( inputModel.getProfiles(),
+ profileActivationContext, problems );
+
+ // model normalization
+ problems.setSource( inputModel );
+ modelNormalizer.mergeDuplicates( inputModel, request, problems );
+
+ Map<String, Activation> interpolatedActivations = getProfileActivations( inputModel, false );
+ injectProfileActivations( inputModel, interpolatedActivations );
+
+ // profile injection
+ for ( Profile activeProfile : activePomProfiles )
{
- inputModel = readModel( request.getModelSource(), request.getPomFile(), request, problems );
+ profileInjector.injectProfile( inputModel, activeProfile, request, problems );
}
+ for ( Profile activeProfile : activeExternalProfiles )
+ {
+ profileInjector.injectProfile( inputModel, activeProfile, request, problems );
+ }
+ }
+
+ @SuppressWarnings( "checkstyle:methodlength" )
+ private Model readEffectiveModel( final ModelBuildingRequest request, final DefaultModelBuildingResult result,
+ DefaultModelProblemCollector problems )
+ throws ModelBuildingException
+ {
+ Model inputModel =
+ readRawModel( request, problems );
+
problems.setRootModel( inputModel );
ModelData resultData = new ModelData( request.getModelSource(), inputModel );
ModelData superData = new ModelData( null, getSuperModel() );
+ // profile activation
+ DefaultProfileActivationContext profileActivationContext = getProfileActivationContext( request );
+
+ List<Profile> activeExternalProfiles = result.getActiveExternalProfiles();
+
+ if ( !activeExternalProfiles.isEmpty() )
+ {
+ Properties profileProps = new Properties();
+ for ( Profile profile : activeExternalProfiles )
+ {
+ profileProps.putAll( profile.getProperties() );
+ }
+ profileProps.putAll( profileActivationContext.getUserProperties() );
+ profileActivationContext.setUserProperties( profileProps );
+ }
+
Collection<String> parentIds = new LinkedHashSet<>();
- List<ModelData> lineage = new ArrayList<>();
+
+ List<Model> lineage = new ArrayList<>();
for ( ModelData currentData = resultData; currentData != null; )
{
- lineage.add( currentData );
+ String modelId = currentData.getId();
+ result.addModelId( modelId );
Model rawModel = currentData.getModel();
- currentData.setRawModel( rawModel );
+ result.setRawModel( modelId, rawModel );
+ profileActivationContext.setProjectProperties( rawModel.getProperties() );
+ problems.setSource( rawModel );
+ List<Profile> activePomProfiles = profileSelector.getActiveProfiles( rawModel.getProfiles(),
+ profileActivationContext, problems );
+ result.setActivePomProfiles( modelId, activePomProfiles );
+
Model tmpModel = rawModel.clone();
- currentData.setModel( tmpModel );
-
+
problems.setSource( tmpModel );
// model normalization
modelNormalizer.mergeDuplicates( tmpModel, request, problems );
- profileActivationContext.setProjectProperties( tmpModel.getProperties() );
-
- List<Profile> activePomProfiles = profileSelector.getActiveProfiles( rawModel.getProfiles(),
- profileActivationContext, problems );
- currentData.setActiveProfiles( activePomProfiles );
-
- Map<String, Activation> interpolatedActivations = getProfileActivations( rawModel, false );
+ Map<String, Activation> interpolatedActivations = getProfileActivations( tmpModel, false );
injectProfileActivations( tmpModel, interpolatedActivations );
// profile injection
- for ( Profile activeProfile : activePomProfiles )
+ for ( Profile activeProfile : result.getActivePomProfiles( modelId ) )
{
profileInjector.injectProfile( tmpModel, activeProfile, request, problems );
}
@@ -343,8 +424,11 @@ public class DefaultModelBuilder
{
profileInjector.injectProfile( tmpModel, activeProfile, request, problems );
}
+ result.setEffectiveModel( tmpModel );
}
-
+
+ lineage.add( tmpModel );
+
if ( currentData == superData )
{
break;
@@ -352,36 +436,19 @@ public class DefaultModelBuilder
configureResolver( request.getModelResolver(), tmpModel, problems );
- ModelData parentData = readParent( tmpModel, currentData.getSource(), request, problems );
+ ModelData parentData =
+ readParent( currentData.getModel(), currentData.getSource(), request, result, problems );
if ( parentData == null )
{
currentData = superData;
}
- else if ( currentData == resultData )
- { // First iteration - add initial id after version resolution.
- currentData.setGroupId( currentData.getRawModel().getGroupId() == null ? parentData.getGroupId()
- : currentData.getRawModel()
- .getGroupId() );
-
- currentData.setVersion( currentData.getRawModel().getVersion() == null ? parentData.getVersion()
- : currentData.getRawModel()
- .getVersion() );
-
- currentData.setArtifactId( currentData.getRawModel().getArtifactId() );
- parentIds.add( currentData.getId() );
- // Reset - only needed for 'getId'.
- currentData.setGroupId( null );
- currentData.setArtifactId( null );
- currentData.setVersion( null );
- currentData = parentData;
- }
else if ( !parentIds.add( parentData.getId() ) )
{
StringBuilder message = new StringBuilder( "The parents form a cycle: " );
- for ( String modelId : parentIds )
+ for ( String parentId : parentIds )
{
- message.append( modelId ).append( " -> " );
+ message.append( parentId ).append( " -> " );
}
message.append( parentData.getId() );
@@ -396,86 +463,50 @@ public class DefaultModelBuilder
}
}
- problems.setSource( inputModel );
+ problems.setSource( result.getRawModel() );
checkPluginVersions( lineage, request, problems );
// inheritance assembly
assembleInheritance( lineage, request, problems );
- Model resultModel = resultData.getModel();
+ Model resultModel = lineage.get( 0 );
+
+ // consider caching inherited model
problems.setSource( resultModel );
problems.setRootModel( resultModel );
// model interpolation
resultModel = interpolateModel( resultModel, request, problems );
- resultData.setModel( resultModel );
-
- if ( resultModel.getParent() != null )
- {
- final ModelData parentData = lineage.get( 1 );
- if ( parentData.getVersion() == null || parentData.getVersion().contains( "${" ) )
- {
- final Model interpolatedParent = interpolateModel( parentData.getModel(), request, problems );
- // parentData.setModel( interpolatedParent );
- parentData.setVersion( interpolatedParent.getVersion() );
- }
- }
// url normalization
modelUrlNormalizer.normalize( resultModel, request );
+
+ result.setEffectiveModel( resultModel );
// Now the fully interpolated model is available: reconfigure the resolver
configureResolver( request.getModelResolver(), resultModel, problems, true );
-
- resultData.setGroupId( resultModel.getGroupId() );
- resultData.setArtifactId( resultModel.getArtifactId() );
- resultData.setVersion( resultModel.getVersion() );
-
- if ( request.getPomFile() != null )
- {
- intoCache( request.getModelCache(), new FileModelSource( request.getPomFile() ), ModelCacheTag.RAW,
- resultData );
- }
- else
- {
- intoCache( request.getModelCache(), request.getModelSource(), ModelCacheTag.RAW, resultData );
- }
-
- result.setEffectiveModel( resultModel );
- for ( ModelData currentData : lineage )
- {
- String modelId = ( currentData != superData ) ? currentData.getId() : "";
-
- result.addModelId( modelId );
- result.setActivePomProfiles( modelId, currentData.getActiveProfiles() );
- result.setRawModel( modelId, currentData.getRawModel() );
- }
-
- if ( !request.isTwoPhaseBuilding() )
- {
- build( request, result, importIds );
- }
-
- return result;
+ return resultModel;
}
@Override
- public ModelBuildingResult build( ModelBuildingRequest request, ModelBuildingResult result )
+ public ModelBuildingResult build( final ModelBuildingRequest request, final ModelBuildingResult result )
throws ModelBuildingException
{
return build( request, result, new LinkedHashSet<>() );
}
- private ModelBuildingResult build( ModelBuildingRequest request, ModelBuildingResult result,
+ private ModelBuildingResult build( final ModelBuildingRequest request, final ModelBuildingResult phaseOneResult,
Collection<String> imports )
throws ModelBuildingException
{
- // phase 2
- Model resultModel = result.getEffectiveModel();
+ DefaultModelBuildingResult result = asDefaultModelBuildingResult( phaseOneResult );
DefaultModelProblemCollector problems = new DefaultModelProblemCollector( result );
+
+ // phase 2
+ Model resultModel = readEffectiveModel( request, result, problems );
problems.setSource( resultModel );
problems.setRootModel( resultModel );
@@ -529,6 +560,18 @@ public class DefaultModelBuilder
return result;
}
+ private DefaultModelBuildingResult asDefaultModelBuildingResult( ModelBuildingResult phaseOneResult )
+ {
+ if ( phaseOneResult instanceof DefaultModelBuildingResult )
+ {
+ return (DefaultModelBuildingResult) phaseOneResult;
+ }
+ else
+ {
+ return new DefaultModelBuildingResult( phaseOneResult );
+ }
+ }
+
@Override
public Result<? extends Model> buildRawModel( File pomFile, int validationLevel, boolean locationTracking )
{
@@ -538,7 +581,7 @@ public class DefaultModelBuilder
new DefaultModelProblemCollector( new DefaultModelBuildingResult() );
try
{
- return newResult( readModel( null, pomFile, request, collector ), collector.getProblems() );
+ return newResult( readFileModel( request, collector ), collector.getProblems() );
}
catch ( ModelBuildingException e )
{
@@ -547,24 +590,15 @@ public class DefaultModelBuilder
}
@SuppressWarnings( "checkstyle:methodlength" )
- private Model readModel( ModelSource modelSource, File pomFile, ModelBuildingRequest request,
- DefaultModelProblemCollector problems )
+ private Model readFileModel( ModelBuildingRequest request,
+ DefaultModelProblemCollector problems )
throws ModelBuildingException
{
- if ( modelSource == null )
+ ModelSource modelSource = request.getModelSource();
+ Model model = getModelFromCache( modelSource, request.getModelCache() );
+ if ( model != null )
{
- modelSource =
- new FileModelSource( Objects.requireNonNull( pomFile, "neither pomFile nor modelSource can be null" ) );
- }
-
- Model model;
- if ( pomFile == null )
- {
- model = getModelFromCache( modelSource, request.getModelCache() );
- if ( model != null )
- {
- return model;
- }
+ return model;
}
problems.setSource( modelSource.getLocation() );
@@ -609,7 +643,7 @@ public class DefaultModelBuilder
throw e;
}
- if ( pomFile != null )
+ if ( modelSource instanceof FileModelSource )
{
problems.add( new ModelProblemCollectorRequest( Severity.ERROR, Version.V20 )
.setMessage( "Malformed POM " + modelSource.getLocation() + ": " + e.getMessage() )
@@ -655,69 +689,106 @@ public class DefaultModelBuilder
.setMessage( "Non-readable POM " + modelSource.getLocation() + ": " + msg ).setException( e ) );
throw problems.newModelBuildingException();
}
- if ( pomFile != null )
- {
- model.setPomFile( pomFile );
- }
- else if ( modelSource instanceof FileModelSource )
+
+ if ( modelSource instanceof FileModelSource )
{
model.setPomFile( ( (FileModelSource) modelSource ).getFile() );
}
problems.setSource( model );
modelValidator.validateFileModel( model, request, problems );
- request.setFileModel( model );
+
+ if ( hasFatalErrors( problems ) )
+ {
+ throw problems.newModelBuildingException();
+ }
+
+ intoCache( request.getModelCache(), modelSource, ModelCacheTag.FILE, model );
+ if ( modelSource instanceof FileModelSource )
+ {
+ if ( request.getTransformerContextBuilder() instanceof DefaultTransformerContextBuilder )
+ {
+ DefaultTransformerContextBuilder contextBuilder =
+ (DefaultTransformerContextBuilder) request.getTransformerContextBuilder();
+ contextBuilder.putSource( getGroupId( model ), model.getArtifactId(), modelSource );
+ }
+ }
+
+ return model;
+ }
+
+ private Model readRawModel( ModelBuildingRequest request, DefaultModelProblemCollector problems )
+ throws ModelBuildingException
+ {
+ ModelSource modelSource = request.getModelSource();
+
+ ModelData cachedData = fromCache( request.getModelCache(), modelSource, ModelCacheTag.RAW );
+ if ( cachedData != null )
+ {
+ return cachedData.getModel();
+ }
- if ( Features.buildConsumer().isActive() && pomFile != null )
+ Model rawModel;
+ if ( Features.buildConsumer().isActive() && modelSource instanceof FileModelSource )
{
+ rawModel = readFileModel( request, problems );
+ File pomFile = ( (FileModelSource) modelSource ).getFile();
+
+ TransformerContext context = null;
+ if ( request.getTransformerContextBuilder() != null )
+ {
+ context = request.getTransformerContextBuilder().initialize( request, problems );
+ }
+
try
{
- Model rawModel =
- modelProcessor.read( pomFile,
- Collections.singletonMap( "transformerContext", request.getTransformerContext() ) );
+ // must implement TransformContext, but should use request to access system properties/modelcache
+ Model transformedFileModel = modelProcessor.read( pomFile,
+ Collections.singletonMap( ModelReader.TRANSFORMER_CONTEXT, context ) );
- model.setPomFile( pomFile );
-
- // model with locationTrackers, required for proper feedback during validations
- model = request.getFileModel().clone();
+ // rawModel with locationTrackers, required for proper feedback during validations
// Apply enriched data
- modelMerger.merge( model, rawModel, false, null );
+ modelMerger.merge( rawModel, transformedFileModel, false, null );
}
catch ( IOException e )
{
problems.add( new ModelProblemCollectorRequest( Severity.FATAL, Version.V37 ).setException( e ) );
}
}
+ else if ( request.getFileModel() == null )
+ {
+ rawModel = readFileModel( request, problems );
+ }
+ else
+ {
+ rawModel = request.getFileModel().clone();
+ }
- modelValidator.validateRawModel( model, request, problems );
+ modelValidator.validateRawModel( rawModel, request, problems );
if ( hasFatalErrors( problems ) )
{
throw problems.newModelBuildingException();
}
- if ( pomFile != null )
- {
- intoCache( request.getModelCache(), modelSource, ModelCacheTag.FILEMODEL, model );
- }
-
- String groupId = getGroupId( model );
- String artifactId = model.getArtifactId();
- String version = getVersion( model );
+ String groupId = getGroupId( rawModel );
+ String artifactId = rawModel.getArtifactId();
+ String version = getVersion( rawModel );
- ModelData modelData = new ModelData( modelSource, model, groupId, artifactId, version );
+ ModelData modelData = new ModelData( modelSource, rawModel, groupId, artifactId, version );
intoCache( request.getModelCache(), groupId, artifactId, version, ModelCacheTag.RAW, modelData );
-
- return model;
+ intoCache( request.getModelCache(), modelSource, ModelCacheTag.RAW, modelData );
+
+ return rawModel;
}
- private Model getModelFromCache( ModelSource modelSource, ModelCache cache )
+ private Model getModelFromCache( Source source, ModelCache cache )
{
Model model;
- if ( modelSource instanceof ArtifactModelSource )
+ if ( source instanceof ArtifactModelSource )
{
- ArtifactModelSource artifactModelSource = ( ArtifactModelSource ) modelSource;
+ ArtifactModelSource artifactModelSource = ( ArtifactModelSource ) source;
ModelData modelData = fromCache( cache, artifactModelSource.getGroupId(),
artifactModelSource.getArtifactId(),
artifactModelSource.getVersion(), ModelCacheTag.RAW );
@@ -732,12 +803,7 @@ public class DefaultModelBuilder
}
else
{
- model = fromCache( cache, modelSource, ModelCacheTag.FILEMODEL );
-
- if ( model != null )
- {
- model = model.clone();
- }
+ model = fromCache( cache, source, ModelCacheTag.FILE );
}
return model;
}
@@ -807,7 +873,7 @@ public class DefaultModelBuilder
}
}
- private void checkPluginVersions( List<ModelData> lineage, ModelBuildingRequest request,
+ private void checkPluginVersions( List<Model> lineage, ModelBuildingRequest request,
ModelProblemCollector problems )
{
if ( request.getValidationLevel() < ModelBuildingRequest.VALIDATION_LEVEL_MAVEN_2_0 )
@@ -821,7 +887,7 @@ public class DefaultModelBuilder
for ( int i = lineage.size() - 1; i >= 0; i-- )
{
- Model model = lineage.get( i ).getModel();
+ Model model = lineage.get( i );
Build build = model.getBuild();
if ( build != null )
{
@@ -859,13 +925,13 @@ public class DefaultModelBuilder
}
}
- private void assembleInheritance( List<ModelData> lineage, ModelBuildingRequest request,
+ private void assembleInheritance( List<Model> lineage, ModelBuildingRequest request,
ModelProblemCollector problems )
{
for ( int i = lineage.size() - 2; i >= 0; i-- )
{
- Model parent = lineage.get( i + 1 ).getModel();
- Model child = lineage.get( i ).getModel();
+ Model parent = lineage.get( i + 1 );
+ Model child = lineage.get( i );
inheritanceAssembler.assembleModelInheritance( child, parent, request, problems );
}
}
@@ -950,8 +1016,8 @@ public class DefaultModelBuilder
return interpolatedModel;
}
- private ModelData readParent( Model childModel, ModelSource childSource, ModelBuildingRequest request,
- DefaultModelProblemCollector problems )
+ private ModelData readParent( Model childModel, Source childSource, ModelBuildingRequest request,
+ ModelBuildingResult result, DefaultModelProblemCollector problems )
throws ModelBuildingException
{
ModelData parentData = null;
@@ -960,11 +1026,11 @@ public class DefaultModelBuilder
if ( parent != null )
{
- ModelSource expectedParentSource = getParentPomFile( childModel, childSource );
+ Source expectedParentSource = getParentPomFile( childModel, childSource );
if ( expectedParentSource != null )
{
- ModelData candidateData = readParentLocally( childModel, childSource, request, problems );
+ ModelData candidateData = readParentLocally( childModel, childSource, request, result, problems );
if ( candidateData != null )
{
@@ -1007,7 +1073,7 @@ public class DefaultModelBuilder
}
else
{
- parentData = readParentExternally( childModel, request, problems );
+ parentData = readParentExternally( childModel, request, result, problems );
intoCache( request.getModelCache(),
parentData.getGroupId(), parentData.getArtifactId(),
@@ -1032,8 +1098,8 @@ public class DefaultModelBuilder
return parentData;
}
- private ModelData readParentLocally( Model childModel, ModelSource childSource, ModelBuildingRequest request,
- DefaultModelProblemCollector problems )
+ private ModelData readParentLocally( Model childModel, Source childSource, ModelBuildingRequest request,
+ ModelBuildingResult result, DefaultModelProblemCollector problems )
throws ModelBuildingException
{
final Parent parent = childModel.getParent();
@@ -1048,8 +1114,17 @@ public class DefaultModelBuilder
{
return null;
}
+
+ ModelBuildingRequest candidateBuildRequest = new FilterModelBuildingRequest( request )
+ {
+ @Override
+ public ModelSource getModelSource()
+ {
+ return candidateSource;
+ }
+ };
- candidateModel = readModel( candidateSource, null, request, problems );
+ candidateModel = readRawModel( candidateBuildRequest, problems );
}
else
{
@@ -1083,11 +1158,6 @@ public class DefaultModelBuilder
groupId = candidateModel.getParent().getGroupId();
}
String artifactId = candidateModel.getArtifactId();
- String version = candidateModel.getVersion();
- if ( version == null && candidateModel.getParent() != null )
- {
- version = candidateModel.getParent().getVersion();
- }
if ( groupId == null || !groupId.equals( parent.getGroupId() ) || artifactId == null
|| !artifactId.equals( parent.getArtifactId() ) )
@@ -1107,6 +1177,12 @@ public class DefaultModelBuilder
.setMessage( buffer.toString() ).setLocation( parent.getLocation( "" ) ) );
return null;
}
+
+ String version = candidateModel.getVersion();
+ if ( version == null && candidateModel.getParent() != null )
+ {
+ version = candidateModel.getParent().getVersion();
+ }
if ( version != null && parent.getVersion() != null && !version.equals( parent.getVersion() ) )
{
try
@@ -1161,12 +1237,10 @@ public class DefaultModelBuilder
* if ( version == null || !version.equals( parent.getVersion() ) ) { return null; }
*/
- ModelData parentData = new ModelData( candidateSource, candidateModel, groupId, artifactId, version );
-
- return parentData;
+ return new ModelData( candidateSource, candidateModel, groupId, artifactId, version );
}
- private ModelSource getParentPomFile( Model childModel, ModelSource source )
+ private ModelSource getParentPomFile( Model childModel, Source source )
{
if ( !( source instanceof ModelSource2 ) )
{
@@ -1184,12 +1258,12 @@ public class DefaultModelBuilder
}
private ModelData readParentExternally( Model childModel, ModelBuildingRequest request,
- DefaultModelProblemCollector problems )
+ ModelBuildingResult result, DefaultModelProblemCollector problems )
throws ModelBuildingException
{
problems.setSource( childModel );
- Parent parent = childModel.getParent().clone();
+ Parent parent = childModel.getParent();
String groupId = parent.getGroupId();
String artifactId = parent.getArtifactId();
@@ -1237,20 +1311,28 @@ public class DefaultModelBuilder
throw problems.newModelBuildingException();
}
- ModelBuildingRequest lenientRequest = request;
- if ( request.getValidationLevel() > ModelBuildingRequest.VALIDATION_LEVEL_MAVEN_2_0 )
+ int validationLevel = Math.min( request.getValidationLevel(), ModelBuildingRequest.VALIDATION_LEVEL_MAVEN_2_0 );
+ ModelBuildingRequest lenientRequest = new FilterModelBuildingRequest( request )
{
- lenientRequest = new FilterModelBuildingRequest( request )
+ @Override
+ public int getValidationLevel()
{
- @Override
- public int getValidationLevel()
- {
- return ModelBuildingRequest.VALIDATION_LEVEL_MAVEN_2_0;
- }
- };
- }
+ return validationLevel;
+ }
+
+ @Override
+ public ModelSource getModelSource()
+ {
+ return modelSource;
+ }
+ @Override
+ public Model getFileModel()
+ {
+ return null;
+ }
+ };
- Model parentModel = readModel( modelSource, null, lenientRequest, problems );
+ Model parentModel = readRawModel( lenientRequest, problems );
if ( !parent.getVersion().equals( version ) )
{
@@ -1276,10 +1358,8 @@ public class DefaultModelBuilder
// MNG-2199: What else to check here ?
}
- ModelData parentData = new ModelData( modelSource, parentModel, parent.getGroupId(), parent.getArtifactId(),
- parent.getVersion() );
-
- return parentData;
+ return new ModelData( modelSource, parentModel, parent.getGroupId(), parent.getArtifactId(),
+ parent.getVersion() );
}
private Model getSuperModel()
@@ -1486,7 +1566,7 @@ public class DefaultModelBuilder
}
}
- private <T> T fromCache( ModelCache modelCache, String groupId, String artifactId, String version,
+ private static <T> T fromCache( ModelCache modelCache, String groupId, String artifactId, String version,
ModelCacheTag<T> tag )
{
if ( modelCache != null )
@@ -1500,7 +1580,7 @@ public class DefaultModelBuilder
return null;
}
- private <T> T fromCache( ModelCache modelCache, Source source, ModelCacheTag<T> tag )
+ private static <T> T fromCache( ModelCache modelCache, Source source, ModelCacheTag<T> tag )
{
if ( modelCache != null )
{
@@ -1713,4 +1793,132 @@ public class DefaultModelBuilder
// don't merge
}
}
+
+ /**
+ * Builds up the transformer context.
+ * After the buildplan is ready, the build()-method returns the immutable context useful during distribution.
+ * This is an inner class, as it must be able to call readRawModel()
+ *
+ * @author Robert Scholte
+ * @since 4.0.0
+ */
+ private class DefaultTransformerContextBuilder implements TransformerContextBuilder
+ {
+ private final DefaultTransformerContext context = new DefaultTransformerContext();
+
+ private final Map<DefaultTransformerContext.GAKey, Set<Source>> mappedSources
+ = new ConcurrentHashMap<>( 64 );
+
+ /**
+ * If an interface could be extracted, DefaultModelProblemCollector should be ModelProblemCollectorExt
+ *
+ * @param request
+ * @param collector
+ * @return
+ */
+ @Override
+ public TransformerContext initialize( ModelBuildingRequest request, ModelProblemCollector collector )
+ {
+ // We must assume the TransformerContext was created using this.newTransformerContextBuilder()
+ DefaultModelProblemCollector problems = (DefaultModelProblemCollector) collector;
+ return new TransformerContext()
+ {
+ @Override
+ public String getUserProperty( String key )
+ {
+ return context.userProperties.computeIfAbsent( key,
+ k -> request.getUserProperties().getProperty( key ) );
+ }
+
+ @Override
+ public Model getRawModel( String gId, String aId )
+ {
+ return context.modelByGA.computeIfAbsent( new DefaultTransformerContext.GAKey( gId, aId ),
+ k -> findRawModel( gId, aId ) );
+ }
+
+ @Override
+ public Model getRawModel( Path path )
+ {
+ return context.modelByPath.computeIfAbsent( path, k -> findRawModel( path ) );
+ }
+
+ private Model findRawModel( String groupId, String artifactId )
+ {
+ Source source = getSource( groupId, artifactId );
+ if ( source != null )
+ {
+ try
+ {
+ ModelBuildingRequest gaBuildingRequest = new FilterModelBuildingRequest( request )
+ {
+ @Override
+ public ModelSource getModelSource()
+ {
+ return (ModelSource) source;
+ }
+
+ };
+ return readRawModel( gaBuildingRequest, problems );
+ }
+ catch ( ModelBuildingException e )
+ {
+ // gathered with problem collector
+ }
+ }
+ return null;
+ }
+
+ private Model findRawModel( Path p )
+ {
+ if ( !Files.isRegularFile( p ) )
+ {
+ throw new IllegalArgumentException( "Not a regular file: " + p );
+ }
+
+ DefaultModelBuildingRequest req = new DefaultModelBuildingRequest( request )
+ .setPomFile( p.toFile() )
+ .setModelSource( new FileModelSource( p.toFile() ) );
+
+ try
+ {
+ return readRawModel( req, problems );
+ }
+ catch ( ModelBuildingException e )
+ {
+ // gathered with problem collector
+ }
+ return null;
+ }
+ };
+ }
+
+ @Override
+ public TransformerContext build()
+ {
+ return context;
+ }
+
+ public Source getSource( String groupId, String artifactId )
+ {
+ Set<Source> sources = mappedSources.get( new DefaultTransformerContext.GAKey( groupId, artifactId ) );
+ if ( sources == null )
+ {
+ return null;
+ }
+ return sources.stream().reduce( ( a, b ) ->
+ {
+ throw new IllegalStateException( String.format( "No unique Source for %s:%s: %s and %s",
+ groupId, artifactId,
+ a.getLocation(), b.getLocation() ) );
+ } ).orElse( null );
+ }
+
+ public void putSource( String groupId, String artifactId, Source source )
+ {
+ mappedSources.computeIfAbsent( new DefaultTransformerContext.GAKey( groupId, artifactId ),
+ k -> new HashSet<>() ).add( source );
+ }
+
+ }
}
diff --git a/maven-model-builder/src/main/java/org/apache/maven/model/building/DefaultModelBuildingRequest.java b/maven-model-builder/src/main/java/org/apache/maven/model/building/DefaultModelBuildingRequest.java
index 2012bb1..44ad425 100644
--- a/maven-model-builder/src/main/java/org/apache/maven/model/building/DefaultModelBuildingRequest.java
+++ b/maven-model-builder/src/main/java/org/apache/maven/model/building/DefaultModelBuildingRequest.java
@@ -40,8 +40,6 @@ public class DefaultModelBuildingRequest
{
private Model fileModel;
- private Model rawModel;
-
private File pomFile;
private ModelSource modelSource;
@@ -74,7 +72,7 @@ public class DefaultModelBuildingRequest
private WorkspaceModelResolver workspaceResolver;
- private TransformerContext context;
+ private TransformerContextBuilder contextBuilder;
/**
* Creates an empty request.
@@ -104,6 +102,7 @@ public class DefaultModelBuildingRequest
setModelResolver( request.getModelResolver() );
setModelBuildingListener( request.getModelBuildingListener() );
setModelCache( request.getModelCache() );
+ setTransformerContextBuilder( request.getTransformerContextBuilder() );
}
@Override
@@ -397,17 +396,16 @@ public class DefaultModelBuildingRequest
this.fileModel = fileModel;
return this;
}
-
+
@Override
public Model getRawModel()
{
- return rawModel;
+ return null;
}
@Override
public ModelBuildingRequest setRawModel( Model rawModel )
{
- this.rawModel = rawModel;
return this;
}
@@ -423,17 +421,18 @@ public class DefaultModelBuildingRequest
this.workspaceResolver = workspaceResolver;
return this;
}
-
+
@Override
- public TransformerContext getTransformerContext()
+ public TransformerContextBuilder getTransformerContextBuilder()
{
- return context;
+ return contextBuilder;
}
@Override
- public ModelBuildingRequest setTransformerContext( TransformerContext context )
+ public ModelBuildingRequest setTransformerContextBuilder( TransformerContextBuilder contextBuilder )
{
- this.context = context;
+ this.contextBuilder = contextBuilder;
return this;
}
+
}
diff --git a/maven-model-builder/src/main/java/org/apache/maven/model/building/DefaultModelBuildingResult.java b/maven-model-builder/src/main/java/org/apache/maven/model/building/DefaultModelBuildingResult.java
index 13b7714..731c583 100644
--- a/maven-model-builder/src/main/java/org/apache/maven/model/building/DefaultModelBuildingResult.java
+++ b/maven-model-builder/src/main/java/org/apache/maven/model/building/DefaultModelBuildingResult.java
@@ -36,6 +36,7 @@ import org.apache.maven.model.Profile;
class DefaultModelBuildingResult
implements ModelBuildingResult
{
+ private Model fileModel;
private Model effectiveModel;
@@ -57,6 +58,35 @@ class DefaultModelBuildingResult
activeExternalProfiles = new ArrayList<>();
problems = new ArrayList<>();
}
+
+ DefaultModelBuildingResult( ModelBuildingResult result )
+ {
+ this();
+ this.activeExternalProfiles.addAll( result.getActiveExternalProfiles() );
+ this.effectiveModel = result.getEffectiveModel();
+ this.fileModel = result.getFileModel();
+ this.problems.addAll( result.getProblems() );
+
+ for ( String modelId : result.getModelIds() )
+ {
+ this.modelIds.add( modelId );
+ this.rawModels.put( modelId, result.getRawModel( modelId ) );
+ this.activePomProfiles.put( modelId, result.getActivePomProfiles( modelId ) );
+ }
+ }
+
+ @Override
+ public Model getFileModel()
+ {
+ return fileModel;
+ }
+
+ public DefaultModelBuildingResult setFileModel( Model fileModel )
+ {
+ this.fileModel = fileModel;
+
+ return this;
+ }
@Override
public Model getEffectiveModel()
diff --git a/maven-model-builder/src/main/java/org/apache/maven/model/building/DefaultTransformerContext.java b/maven-model-builder/src/main/java/org/apache/maven/model/building/DefaultTransformerContext.java
new file mode 100644
index 0000000..1930a48
--- /dev/null
+++ b/maven-model-builder/src/main/java/org/apache/maven/model/building/DefaultTransformerContext.java
@@ -0,0 +1,95 @@
+package org.apache.maven.model.building;
+
+/*
+ * 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.nio.file.Path;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.Objects;
+
+import org.apache.maven.model.Model;
+
+/**
+ *
+ * @author Robert Scholte
+ * @since 4.0.0
+ */
+class DefaultTransformerContext implements TransformerContext
+{
+ final Map<String, String> userProperties = new HashMap<>();
+
+ final Map<Path, Model> modelByPath = new HashMap<>();
+
+ final Map<GAKey, Model> modelByGA = new HashMap<>();
+
+ @Override
+ public String getUserProperty( String key )
+ {
+ return userProperties.get( key );
+ }
+
+ @Override
+ public Model getRawModel( Path p )
+ {
+ return modelByPath.get( p );
+ }
+
+ @Override
+ public Model getRawModel( String groupId, String artifactId )
+ {
+ return modelByGA.get( new GAKey( groupId, artifactId ) );
+ }
+
+ static class GAKey
+ {
+ private final String groupId;
+ private final String artifactId;
+ private final int hashCode;
+
+ GAKey( String groupId, String artifactId )
+ {
+ this.groupId = groupId;
+ this.artifactId = artifactId;
+ this.hashCode = Objects.hash( groupId, artifactId );
+ }
+
+ @Override
+ public int hashCode()
+ {
+ return hashCode;
+ }
+
+ @Override
+ public boolean equals( Object obj )
+ {
+ if ( this == obj )
+ {
+ return true;
+ }
+ if ( !( obj instanceof GAKey ) )
+ {
+ return false;
+ }
+
+ GAKey other = (GAKey) obj;
+ return Objects.equals( artifactId, other.artifactId ) && Objects.equals( groupId, other.groupId );
+ }
+ }
+}
diff --git a/maven-model-builder/src/main/java/org/apache/maven/model/building/FilterModelBuildingRequest.java b/maven-model-builder/src/main/java/org/apache/maven/model/building/FilterModelBuildingRequest.java
index 1dd2643..1374cbb 100644
--- a/maven-model-builder/src/main/java/org/apache/maven/model/building/FilterModelBuildingRequest.java
+++ b/maven-model-builder/src/main/java/org/apache/maven/model/building/FilterModelBuildingRequest.java
@@ -268,7 +268,7 @@ class FilterModelBuildingRequest
request.setFileModel( fileModel );
return this;
}
-
+
@Override
public Model getRawModel()
{
@@ -294,17 +294,17 @@ class FilterModelBuildingRequest
request.setWorkspaceModelResolver( workspaceResolver );
return this;
}
-
+
@Override
- public TransformerContext getTransformerContext()
+ public TransformerContextBuilder getTransformerContextBuilder()
{
- return request.getTransformerContext();
+ return request.getTransformerContextBuilder();
}
@Override
- public ModelBuildingRequest setTransformerContext( TransformerContext context )
+ public ModelBuildingRequest setTransformerContextBuilder( TransformerContextBuilder contextBuilder )
{
- request.setTransformerContext( context );
+ request.setTransformerContextBuilder( contextBuilder );
return this;
}
}
\ No newline at end of file
diff --git a/maven-model-builder/src/main/java/org/apache/maven/model/building/ModelBuilder.java b/maven-model-builder/src/main/java/org/apache/maven/model/building/ModelBuilder.java
index e42469a..85455f6 100644
--- a/maven-model-builder/src/main/java/org/apache/maven/model/building/ModelBuilder.java
+++ b/maven-model-builder/src/main/java/org/apache/maven/model/building/ModelBuilder.java
@@ -59,5 +59,7 @@ public interface ModelBuilder
* Performs only the part of {@link ModelBuilder#build(ModelBuildingRequest)} that loads the raw model
*/
Result<? extends Model> buildRawModel( File pomFile, int validationLevel, boolean locationTracking );
+
+ TransformerContextBuilder newTransformerContextBuilder();
}
diff --git a/maven-model-builder/src/main/java/org/apache/maven/model/building/ModelBuildingRequest.java b/maven-model-builder/src/main/java/org/apache/maven/model/building/ModelBuildingRequest.java
index c9451ef..5bd1ddf 100644
--- a/maven-model-builder/src/main/java/org/apache/maven/model/building/ModelBuildingRequest.java
+++ b/maven-model-builder/src/main/java/org/apache/maven/model/building/ModelBuildingRequest.java
@@ -63,16 +63,19 @@ public interface ModelBuildingRequest
* Denotes strict validation as recommended by the current Maven version.
*/
int VALIDATION_LEVEL_STRICT = VALIDATION_LEVEL_MAVEN_3_0;
-
+
/**
- *
- * @return the file model
+ * Gets the file model to build (with profile activation).
+ * If not set, model source will be used to load file model.
+ *
+ * @return The file model to build or {@code null} if not set.
* @since 4.0.0
*/
Model getFileModel();
-
+
/**
- *
+ * Set the file model with profile activation
+ *
* @param fileModel
* @return This request, never {@code null}.
* @since 4.0.0
@@ -80,17 +83,15 @@ public interface ModelBuildingRequest
ModelBuildingRequest setFileModel( Model fileModel );
/**
- * Gets the raw model to build. If not set, model source will be used to load raw model.
- *
- * @return The raw model to build or {@code null} if not set.
+ * @deprecated rawModel is never set, instead the fileModel is set
*/
+ @Deprecated
Model getRawModel();
/**
- * Set raw model.
- *
- * @param rawModel
+ * @deprecated setting the rawModel has no effect, instead the fileModel of phase one will be set
*/
+ @Deprecated
ModelBuildingRequest setRawModel( Model rawModel );
/**
@@ -350,9 +351,9 @@ public interface ModelBuildingRequest
ModelBuildingRequest setWorkspaceModelResolver( WorkspaceModelResolver workspaceResolver );
- TransformerContext getTransformerContext();
+ TransformerContextBuilder getTransformerContextBuilder();
- ModelBuildingRequest setTransformerContext( TransformerContext context );
+ ModelBuildingRequest setTransformerContextBuilder( TransformerContextBuilder contextBuilder );
}
diff --git a/maven-model-builder/src/main/java/org/apache/maven/model/building/ModelBuildingResult.java b/maven-model-builder/src/main/java/org/apache/maven/model/building/ModelBuildingResult.java
index 44b1295..f9615c8 100644
--- a/maven-model-builder/src/main/java/org/apache/maven/model/building/ModelBuildingResult.java
+++ b/maven-model-builder/src/main/java/org/apache/maven/model/building/ModelBuildingResult.java
@@ -41,6 +41,13 @@ public interface ModelBuildingResult
* @return The model identifiers from the lineage of models, never {@code null}.
*/
List<String> getModelIds();
+
+ /**
+ *
+ * @return the file model
+ * @since 4.0.0
+ */
+ Model getFileModel();
/**
* Gets the assembled model.
diff --git a/maven-model-builder/src/main/java/org/apache/maven/model/building/ModelCacheTag.java b/maven-model-builder/src/main/java/org/apache/maven/model/building/ModelCacheTag.java
index f38bb62..c6fdc1c 100644
--- a/maven-model-builder/src/main/java/org/apache/maven/model/building/ModelCacheTag.java
+++ b/maven-model-builder/src/main/java/org/apache/maven/model/building/ModelCacheTag.java
@@ -65,7 +65,7 @@ interface ModelCacheTag<T>
T fromCache( T data );
/**
- * The tag used to denote raw model data.
+ * The tag used for the raw model without profile activation
*/
ModelCacheTag<ModelData> RAW = new ModelCacheTag<ModelData>()
{
@@ -129,12 +129,16 @@ interface ModelCacheTag<T>
};
- ModelCacheTag<Model> FILEMODEL = new ModelCacheTag<Model>()
+ /**
+ * The tag used for the file model without profile activation
+ * @since 4.0.0
+ */
+ ModelCacheTag<Model> FILE = new ModelCacheTag<Model>()
{
@Override
public String getName()
{
- return "file-model";
+ return "file";
}
@Override
diff --git a/maven-model-builder/src/main/java/org/apache/maven/model/building/ModelData.java b/maven-model-builder/src/main/java/org/apache/maven/model/building/ModelData.java
index 1f39ad4..1ef4341 100644
--- a/maven-model-builder/src/main/java/org/apache/maven/model/building/ModelData.java
+++ b/maven-model-builder/src/main/java/org/apache/maven/model/building/ModelData.java
@@ -19,10 +19,10 @@ package org.apache.maven.model.building;
* under the License.
*/
-import java.util.List;
+import java.util.Objects;
+import org.apache.maven.building.Source;
import org.apache.maven.model.Model;
-import org.apache.maven.model.Profile;
/**
* Holds a model along with some auxiliary information. This internal utility class assists the model builder during POM
@@ -32,13 +32,9 @@ import org.apache.maven.model.Profile;
*/
class ModelData
{
- private final ModelSource source;
+ private final Source source;
- private Model model;
-
- private Model rawModel;
-
- private List<Profile> activeProfiles;
+ private final Model model;
private String groupId;
@@ -51,7 +47,7 @@ class ModelData
*
* @param model The model to wrap, may be {@code null}.
*/
- ModelData( ModelSource source, Model model )
+ ModelData( Source source, Model model )
{
this.source = source;
this.model = model;
@@ -65,16 +61,16 @@ class ModelData
* @param artifactId The effective artifact identifier of the model, may be {@code null}.
* @param version The effective version of the model, may be {@code null}.
*/
- ModelData( ModelSource source, Model model, String groupId, String artifactId, String version )
+ ModelData( Source source, Model model, String groupId, String artifactId, String version )
{
this.source = source;
this.model = model;
- setGroupId( groupId );
- setArtifactId( artifactId );
- setVersion( version );
+ this.groupId = groupId;
+ this.artifactId = artifactId;
+ this.version = version;
}
- public ModelSource getSource()
+ public Source getSource()
{
return source;
}
@@ -90,56 +86,6 @@ class ModelData
}
/**
- * Sets the model being wrapped.
- *
- * @param model The model, may be {@code null}.
- */
- public void setModel( Model model )
- {
- this.model = model;
- }
-
- /**
- * Gets the raw model being wrapped.
- *
- * @return The raw model or {@code null} if not set.
- */
- public Model getRawModel()
- {
- return rawModel;
- }
-
- /**
- * Sets the raw model being wrapped.
- *
- * @param rawModel The raw model, may be {@code null}.
- */
- public void setRawModel( Model rawModel )
- {
- this.rawModel = rawModel;
- }
-
- /**
- * Gets the active profiles from the model.
- *
- * @return The active profiles or {@code null} if not set.
- */
- public List<Profile> getActiveProfiles()
- {
- return activeProfiles;
- }
-
- /**
- * Sets the active profiles from the model.
- *
- * @param activeProfiles The active profiles, may be {@code null}.
- */
- public void setActiveProfiles( List<Profile> activeProfiles )
- {
- this.activeProfiles = activeProfiles;
- }
-
- /**
* Gets the effective group identifier of the model.
*
* @return The effective group identifier of the model or an empty string if unknown, never {@code null}.
@@ -150,16 +96,6 @@ class ModelData
}
/**
- * Sets the effective group identifier of the model.
- *
- * @param groupId The effective group identifier of the model, may be {@code null}.
- */
- public void setGroupId( String groupId )
- {
- this.groupId = groupId;
- }
-
- /**
* Gets the effective artifact identifier of the model.
*
* @return The effective artifact identifier of the model or an empty string if unknown, never {@code null}.
@@ -170,16 +106,6 @@ class ModelData
}
/**
- * Sets the effective artifact identifier of the model.
- *
- * @param artifactId The effective artifact identifier of the model, may be {@code null}.
- */
- public void setArtifactId( String artifactId )
- {
- this.artifactId = artifactId;
- }
-
- /**
* Gets the effective version of the model.
*
* @return The effective version of the model or an empty string if unknown, never {@code null}.
@@ -190,27 +116,14 @@ class ModelData
}
/**
- * Sets the effective version of the model.
- *
- * @param version The effective version of the model, may be {@code null}.
- */
- public void setVersion( String version )
- {
- this.version = version;
- }
-
- /**
- * Gets the effective identifier of the model in the form {@code <groupId>:<artifactId>:<version>}.
+ * Gets unique identifier of the model
*
* @return The effective identifier of the model, never {@code null}.
*/
public String getId()
{
- StringBuilder buffer = new StringBuilder( 128 );
-
- buffer.append( getGroupId() ).append( ':' ).append( getArtifactId() ).append( ':' ).append( getVersion() );
-
- return buffer.toString();
+ // if source is null, it is the supermodel, which can be accessed via empty string
+ return Objects.toString( source, "" );
}
@Override
diff --git a/maven-model-builder/src/main/java/org/apache/maven/model/building/ModelSourceTransformer.java b/maven-model-builder/src/main/java/org/apache/maven/model/building/ModelSourceTransformer.java
index b502e1e..bc3743b 100644
--- a/maven-model-builder/src/main/java/org/apache/maven/model/building/ModelSourceTransformer.java
+++ b/maven-model-builder/src/main/java/org/apache/maven/model/building/ModelSourceTransformer.java
@@ -24,12 +24,24 @@ import java.io.InputStream;
import java.nio.file.Path;
/**
+ * The ModelSourceTransformer is a way to transform the local pom while streaming the input.
+ *
+ * The {@link #transform(Path, TransformerContext)} method uses a Path on purpose, to ensure the
+ * local pom is the the original source.
*
* @author Robert Scholte
* @since 4.0.0
*/
public interface ModelSourceTransformer
{
+ /**
+ *
+ * @param pomFile the pom file, cannot be null
+ * @param context the context, cannot be null
+ * @return the InputStream for the ModelReader
+ * @throws IOException if an I/O error occurs
+ * @throws TransformerException if the transformation fails
+ */
InputStream transform( Path pomFile, TransformerContext context )
throws IOException, TransformerException;
}
diff --git a/maven-model-builder/src/main/java/org/apache/maven/model/building/TransformerContext.java b/maven-model-builder/src/main/java/org/apache/maven/model/building/TransformerContext.java
index 3779a39..d7a43dc 100644
--- a/maven-model-builder/src/main/java/org/apache/maven/model/building/TransformerContext.java
+++ b/maven-model-builder/src/main/java/org/apache/maven/model/building/TransformerContext.java
@@ -47,10 +47,10 @@ public interface TransformerContext
/**
* Get the model based on the path, will be used to resolve the parent based on relativePath
*
- * @param p the path
+ * @param pomFile the path to the pomFile
* @return the model, otherwise {@code null}
*/
- Model getRawModel( Path p );
+ Model getRawModel( Path pomFile );
/**
* Get the model from the reactor based on the groupId and artifactId, will be used for reactor dependencies
@@ -60,5 +60,5 @@ public interface TransformerContext
* @return the model, otherwise {@code null}
* @throws IllegalStateException if multiple versions of the same GA are part of the reactor
*/
- Model getRawModel( String groupId, String artifactId ) throws IllegalStateException;
+ Model getRawModel( String groupId, String artifactId );
}
diff --git a/maven-model-builder/src/main/java/org/apache/maven/model/building/ModelSourceTransformer.java b/maven-model-builder/src/main/java/org/apache/maven/model/building/TransformerContextBuilder.java
similarity index 55%
copy from maven-model-builder/src/main/java/org/apache/maven/model/building/ModelSourceTransformer.java
copy to maven-model-builder/src/main/java/org/apache/maven/model/building/TransformerContextBuilder.java
index b502e1e..a10798e 100644
--- a/maven-model-builder/src/main/java/org/apache/maven/model/building/ModelSourceTransformer.java
+++ b/maven-model-builder/src/main/java/org/apache/maven/model/building/TransformerContextBuilder.java
@@ -19,17 +19,28 @@ package org.apache.maven.model.building;
* under the License.
*/
-import java.io.IOException;
-import java.io.InputStream;
-import java.nio.file.Path;
-
/**
+ * The transformerContextBuilder is responsible for initializing the TransformerContext.
+ * In case rawModels are missing, it could do new buildingRequests on the ModelBuilder.
*
* @author Robert Scholte
* @since 4.0.0
*/
-public interface ModelSourceTransformer
+public interface TransformerContextBuilder
{
- InputStream transform( Path pomFile, TransformerContext context )
- throws IOException, TransformerException;
+ /**
+ * This method is used to initialize the TransformerContext
+ *
+ * @param request the modelBuildingRequest
+ * @param problems the problemCollector
+ * @return the mutable transformerContext
+ */
+ TransformerContext initialize( ModelBuildingRequest request, ModelProblemCollector problems );
+
+ /**
+ * The immutable transformerContext, can be used after the buildplan is finished.
+ *
+ * @return the immutable transformerContext
+ */
+ TransformerContext build();
}
diff --git a/maven-model-builder/src/main/java/org/apache/maven/model/io/DefaultModelReader.java b/maven-model-builder/src/main/java/org/apache/maven/model/io/DefaultModelReader.java
index 1bae747..23cab35 100644
--- a/maven-model-builder/src/main/java/org/apache/maven/model/io/DefaultModelReader.java
+++ b/maven-model-builder/src/main/java/org/apache/maven/model/io/DefaultModelReader.java
@@ -66,11 +66,7 @@ public class DefaultModelReader
{
Objects.requireNonNull( input, "input cannot be null" );
- TransformerContext context = null;
- if ( options != null )
- {
- context = (TransformerContext) options.get( "transformerContext" );
- }
+ TransformerContext context = getTransformerContext( options );
final InputStream is;
if ( context == null )
@@ -134,6 +130,12 @@ public class DefaultModelReader
Object value = ( options != null ) ? options.get( INPUT_SOURCE ) : null;
return (InputSource) value;
}
+
+ private TransformerContext getTransformerContext( Map<String, ?> options )
+ {
+ Object value = ( options != null ) ? options.get( TRANSFORMER_CONTEXT ) : null;
+ return (TransformerContext) value;
+ }
private Model read( Reader reader, boolean strict, InputSource source )
throws IOException
diff --git a/maven-model-builder/src/main/java/org/apache/maven/model/io/ModelReader.java b/maven-model-builder/src/main/java/org/apache/maven/model/io/ModelReader.java
index 75a5ebe..dd6e1e5 100644
--- a/maven-model-builder/src/main/java/org/apache/maven/model/io/ModelReader.java
+++ b/maven-model-builder/src/main/java/org/apache/maven/model/io/ModelReader.java
@@ -47,6 +47,12 @@ public interface ModelReader
* location tracking.
*/
String INPUT_SOURCE = "org.apache.maven.model.io.inputSource";
+
+ /**
+ * The key for the option to provide a transformer context, which can be used to transform the input while reading
+ * to get an advanced version of the model.
+ */
+ String TRANSFORMER_CONTEXT = "transformerContext";
/**
* Reads the model from the specified file.
diff --git a/maven-model-builder/src/site/apt/index.apt b/maven-model-builder/src/site/apt/index.apt
index e18ad9d..3b5355a 100644
--- a/maven-model-builder/src/site/apt/index.apt
+++ b/maven-model-builder/src/site/apt/index.apt
@@ -38,11 +38,27 @@ Maven Model Builder
The sequence is divided into 2 phases:
* phase 1
-
+
** profile activation: see {{{./apidocs/org/apache/maven/model/profile/activation/package-summary.html}available activators}}.
Notice that model interpolation hasn't happened yet, then interpolation for file-based activation is limited to
<<<$\{basedir}>>> (since Maven 3), System properties and request properties
+ ** file model validation: <<<ModelValidator>>> ({{{./apidocs/org/apache/maven/model/validation/ModelValidator.html}javadoc}}),
+ with its <<<DefaultModelValidator>>> implementation
+ ({{{./xref/org/apache/maven/model/validation/DefaultModelValidator.html}source}})
+
+ []
+
+ * phase 2, with optional plugin processing
+
+ ** Build up a raw model by re-reading the file and enrich it based on information available in the reactor. Some features:
+
+ *** Resolve version of versionless parents based on realtivePath (including ci-friendly versions)
+
+ *** Resolve version of versionless dependencies that are part of the reactor
+
+ []
+
** raw model validation: <<<ModelValidator>>> ({{{./apidocs/org/apache/maven/model/validation/ModelValidator.html}javadoc}}),
with its <<<DefaultModelValidator>>> implementation
({{{./xref/org/apache/maven/model/validation/DefaultModelValidator.html}source}})
@@ -65,10 +81,6 @@ Maven Model Builder
with its <<<DefaultUrlNormalizer>>> implementation
({{{./xref/org/apache/maven/model/path/DefaultUrlNormalizer.html}source}})
- []
-
- * phase 2, with optional plugin processing
-
** model path translation: <<<ModelPathTranslator>>> ({{{./apidocs/org/apache/maven/model/path/ModelPathTranslator.html}javadoc}}),
with its <<<DefaultModelPathTranslator>>> implementation
({{{./xref/org/apache/maven/model/path/DefaultModelPathTranslator.html}source}})
@@ -194,6 +206,11 @@ Maven Model Builder
*----+------+------+
| <<<settings.*>>> | Local user settings (see {{{../maven-settings/settings.html}settings reference}}) | <<<$\{settings.localRepository\}>>> |
*----+------+------+
+| <<<changelist>>> \
+<<<revision>>> \
+<<<sha1>>> | CI friendly placeholders for the project version (see {{{/maven-ci-friendly.html}Maven CI Friendly Versions}}) | <<<1.0.0-$\{changelist\}-SNAPSHOT>>> |
+*----+------+------+
+
** Notice
diff --git a/maven-model-builder/src/test/java/org/apache/maven/model/validation/DefaultModelValidatorTest.java b/maven-model-builder/src/test/java/org/apache/maven/model/validation/DefaultModelValidatorTest.java
index d2a9e60..252b1d9 100644
--- a/maven-model-builder/src/test/java/org/apache/maven/model/validation/DefaultModelValidatorTest.java
+++ b/maven-model-builder/src/test/java/org/apache/maven/model/validation/DefaultModelValidatorTest.java
@@ -69,8 +69,6 @@ public class DefaultModelValidatorTest
SimpleProblemCollector problems = new SimpleProblemCollector( model );
- request.setFileModel( model );
-
validator.validateEffectiveModel( model, request, problems );
return problems;
@@ -87,8 +85,6 @@ public class DefaultModelValidatorTest
validator.validateFileModel( model, request, problems );
- request.setFileModel( model );
-
validator.validateRawModel( model, request, problems );
return problems;
diff --git a/maven-xml/src/main/java/org/apache/maven/xml/sax/filter/BuildPomXMLFilterFactory.java b/maven-xml/src/main/java/org/apache/maven/xml/sax/filter/BuildPomXMLFilterFactory.java
index 066be35..2a194d1 100644
--- a/maven-xml/src/main/java/org/apache/maven/xml/sax/filter/BuildPomXMLFilterFactory.java
+++ b/maven-xml/src/main/java/org/apache/maven/xml/sax/filter/BuildPomXMLFilterFactory.java
@@ -41,16 +41,19 @@ import org.xml.sax.ext.LexicalHandler;
*/
public class BuildPomXMLFilterFactory
{
+ private final boolean consume;
+
private final Consumer<LexicalHandler> lexicalHandlerConsumer;
-
- public BuildPomXMLFilterFactory()
+
+ public BuildPomXMLFilterFactory( Consumer<LexicalHandler> lexicalHandlerConsumer )
{
- this( null );
+ this( lexicalHandlerConsumer, false );
}
-
- public BuildPomXMLFilterFactory( Consumer<LexicalHandler> lexicalHandlerConsumer )
+
+ public BuildPomXMLFilterFactory( Consumer<LexicalHandler> lexicalHandlerConsumer, boolean consume )
{
this.lexicalHandlerConsumer = lexicalHandlerConsumer;
+ this.consume = consume;
}
/**
@@ -89,6 +92,18 @@ public class BuildPomXMLFilterFactory
parent = parentFilter;
}
+ CiFriendlyXMLFilter ciFriendlyFilter = new CiFriendlyXMLFilter( consume );
+ getChangelist().ifPresent( ciFriendlyFilter::setChangelist );
+ getRevision().ifPresent( ciFriendlyFilter::setRevision );
+ getSha1().ifPresent( ciFriendlyFilter::setSha1 );
+
+ if ( ciFriendlyFilter.isSet() )
+ {
+ ciFriendlyFilter.setParent( parent );
+ parent.setLexicalHandler( ciFriendlyFilter );
+ parent = ciFriendlyFilter;
+ }
+
return new BuildPomXMLFilter( parent );
}
@@ -98,7 +113,7 @@ public class BuildPomXMLFilterFactory
xmlReader.setFeature( "http://xml.org/sax/features/namespaces", true );
return xmlReader;
}
-
+
/**
* @return the mapper or {@code null} if relativePaths don't need to be mapped
*/
@@ -111,4 +126,22 @@ public class BuildPomXMLFilterFactory
{
return null;
}
+
+ // getters for the 3 magic properties of CIFriendly versions ( https://maven.apache.org/maven-ci-friendly.html )
+
+ protected Optional<String> getChangelist()
+ {
+ return Optional.empty();
+ }
+
+ protected Optional<String> getRevision()
+ {
+ return Optional.empty();
+ }
+
+ protected Optional<String> getSha1()
+ {
+ return Optional.empty();
+ }
+
}
diff --git a/maven-xml/src/main/java/org/apache/maven/xml/sax/filter/CiFriendlyXMLFilter.java b/maven-xml/src/main/java/org/apache/maven/xml/sax/filter/CiFriendlyXMLFilter.java
index 0bda110..ef74880 100644
--- a/maven-xml/src/main/java/org/apache/maven/xml/sax/filter/CiFriendlyXMLFilter.java
+++ b/maven-xml/src/main/java/org/apache/maven/xml/sax/filter/CiFriendlyXMLFilter.java
@@ -33,20 +33,23 @@ import org.xml.sax.SAXException;
class CiFriendlyXMLFilter
extends AbstractSAXFilter
{
+ private final boolean replace;
+
private Function<String, String> replaceChain = Function.identity();
private String characters;
private boolean parseVersion;
-
- CiFriendlyXMLFilter()
+
+ CiFriendlyXMLFilter( boolean replace )
{
- super();
+ this.replace = replace;
}
- CiFriendlyXMLFilter( AbstractSAXFilter parent )
+ CiFriendlyXMLFilter( AbstractSAXFilter parent, boolean replace )
{
super( parent );
+ this.replace = replace;
}
public CiFriendlyXMLFilter setChangelist( String changelist )
@@ -108,7 +111,7 @@ class CiFriendlyXMLFilter
if ( parseVersion )
{
// assuming this has the best performance
- if ( characters != null && characters.contains( "${" ) )
+ if ( replace && characters != null && characters.contains( "${" ) )
{
char[] ch = replaceChain.apply( characters ).toCharArray();
super.characters( ch, 0, ch.length );
diff --git a/maven-xml/src/main/java/org/apache/maven/xml/sax/filter/ConsumerPomXMLFilterFactory.java b/maven-xml/src/main/java/org/apache/maven/xml/sax/filter/ConsumerPomXMLFilterFactory.java
index 18e3208..0f2bd7e 100644
--- a/maven-xml/src/main/java/org/apache/maven/xml/sax/filter/ConsumerPomXMLFilterFactory.java
+++ b/maven-xml/src/main/java/org/apache/maven/xml/sax/filter/ConsumerPomXMLFilterFactory.java
@@ -20,7 +20,6 @@ package org.apache.maven.xml.sax.filter;
*/
import java.nio.file.Path;
-import java.util.Optional;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.transform.TransformerConfigurationException;
@@ -46,20 +45,10 @@ public class ConsumerPomXMLFilterFactory
{
BuildPomXMLFilter parent = buildPomXMLFilterFactory.get( projectPath );
-
+
// Ensure that xs:any elements aren't touched by next filters
AbstractSAXFilter filter = new FastForwardFilter( parent );
-
- CiFriendlyXMLFilter ciFriendlyFilter = new CiFriendlyXMLFilter( filter );
- getChangelist().ifPresent( ciFriendlyFilter::setChangelist );
- getRevision().ifPresent( ciFriendlyFilter::setRevision );
- getSha1().ifPresent( ciFriendlyFilter::setSha1 );
-
- if ( ciFriendlyFilter.isSet() )
- {
- filter = ciFriendlyFilter;
- }
-
+
// Strip modules
filter = new ModulesXMLFilter( filter );
// Adjust relativePath
@@ -67,22 +56,4 @@ public class ConsumerPomXMLFilterFactory
return new ConsumerPomXMLFilter( filter );
}
-
- // getters for the 3 magic properties of CIFriendly versions ( https://maven.apache.org/maven-ci-friendly.html )
-
- protected Optional<String> getChangelist()
- {
- return Optional.empty();
- }
-
- protected Optional<String> getRevision()
- {
- return Optional.empty();
- }
-
- protected Optional<String> getSha1()
- {
- return Optional.empty();
- }
-
}
diff --git a/maven-xml/src/main/java/org/apache/maven/xml/sax/filter/ParentXMLFilter.java b/maven-xml/src/main/java/org/apache/maven/xml/sax/filter/ParentXMLFilter.java
index ac48188..220e062 100644
--- a/maven-xml/src/main/java/org/apache/maven/xml/sax/filter/ParentXMLFilter.java
+++ b/maven-xml/src/main/java/org/apache/maven/xml/sax/filter/ParentXMLFilter.java
@@ -19,6 +19,7 @@ package org.apache.maven.xml.sax.filter;
* under the License.
*/
+import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
@@ -60,6 +61,8 @@ class ParentXMLFilter
private boolean hasVersion;
+ private boolean hasRelativePath;
+
private Optional<RelativeProject> resolvedParent;
private final Function<Path, Optional<RelativeProject>> relativePathMapper;
@@ -107,6 +110,9 @@ class ParentXMLFilter
state = localName;
hasVersion |= "version".equals( localName );
+
+ // can be set to empty on purpose to enforce repository download
+ hasRelativePath |= "relativePath".equals( localName );
}
super.startElement( uri, localName, qName, atts );
@@ -153,11 +159,15 @@ class ParentXMLFilter
switch ( localName )
{
case "parent":
- if ( !hasVersion || relativePath != null )
+ if ( !hasVersion && ( !hasRelativePath || relativePath != null ) )
{
resolvedParent =
resolveRelativePath( Paths.get( Objects.toString( relativePath, "../pom.xml" ) ) );
}
+ else
+ {
+ resolvedParent = Optional.empty();
+ }
if ( !hasVersion && resolvedParent.isPresent() )
{
@@ -194,8 +204,13 @@ class ParentXMLFilter
protected Optional<RelativeProject> resolveRelativePath( Path relativePath )
{
- Optional<RelativeProject> mappedProject =
- relativePathMapper.apply( projectPath.resolve( relativePath ).normalize() );
+ Path pomPath = projectPath.resolve( relativePath );
+ if ( Files.isDirectory( pomPath ) )
+ {
+ pomPath = pomPath.resolve( "pom.xml" );
+ }
+
+ Optional<RelativeProject> mappedProject = relativePathMapper.apply( pomPath.normalize() );
if ( mappedProject.isPresent() )
{
diff --git a/maven-xml/src/test/java/org/apache/maven/xml/sax/filter/CiFriendlyXMLFilterTest.java b/maven-xml/src/test/java/org/apache/maven/xml/sax/filter/CiFriendlyXMLFilterTest.java
index e93c720..7dcdc4f 100644
--- a/maven-xml/src/test/java/org/apache/maven/xml/sax/filter/CiFriendlyXMLFilterTest.java
+++ b/maven-xml/src/test/java/org/apache/maven/xml/sax/filter/CiFriendlyXMLFilterTest.java
@@ -35,7 +35,7 @@ public class CiFriendlyXMLFilterTest extends AbstractXMLFilterTests
@Before
public void setUp()
{
- filter = new CiFriendlyXMLFilter();
+ filter = new CiFriendlyXMLFilter( true );
filter.setChangelist( "CHANGELIST" );
}
diff --git a/maven-xml/src/test/java/org/apache/maven/xml/sax/filter/ConsumerPomXMLFilterTest.java b/maven-xml/src/test/java/org/apache/maven/xml/sax/filter/ConsumerPomXMLFilterTest.java
index 70dc5b4..5ea73a4 100644
--- a/maven-xml/src/test/java/org/apache/maven/xml/sax/filter/ConsumerPomXMLFilterTest.java
+++ b/maven-xml/src/test/java/org/apache/maven/xml/sax/filter/ConsumerPomXMLFilterTest.java
@@ -47,7 +47,7 @@ public class ConsumerPomXMLFilterTest extends AbstractXMLFilterTests
protected AbstractSAXFilter getFilter( Consumer<LexicalHandler> lexicalHandlerConsumer )
throws SAXException, ParserConfigurationException, TransformerConfigurationException
{
- final BuildPomXMLFilterFactory buildPomXMLFilterFactory = new BuildPomXMLFilterFactory( lexicalHandlerConsumer )
+ final BuildPomXMLFilterFactory buildPomXMLFilterFactory = new BuildPomXMLFilterFactory( lexicalHandlerConsumer, true )
{
@Override
protected Function<Path, Optional<RelativeProject>> getRelativePathMapper()
@@ -60,10 +60,7 @@ public class ConsumerPomXMLFilterTest extends AbstractXMLFilterTests
{
return null;
}
- };
-
- ConsumerPomXMLFilter filter = new ConsumerPomXMLFilterFactory( buildPomXMLFilterFactory )
- {
+
@Override
protected Optional<String> getSha1()
{
@@ -81,7 +78,11 @@ public class ConsumerPomXMLFilterTest extends AbstractXMLFilterTests
{
return Optional.of( "CL" );
}
- }.get( Paths.get( "pom.xml" ) );
+
+ };
+
+ ConsumerPomXMLFilter filter =
+ new ConsumerPomXMLFilterFactory( buildPomXMLFilterFactory ).get( Paths.get( "pom.xml" ) );
filter.setFeature( "http://xml.org/sax/features/namespaces", true );
return filter;
}
@@ -234,7 +235,7 @@ public class ConsumerPomXMLFilterTest extends AbstractXMLFilterTests
String actual = transform( input );
assertThat( actual ).and( expected ).areIdentical();
}
-
+
@Test
public void lexicalHandler() throws Exception
{
@@ -245,7 +246,7 @@ public class ConsumerPomXMLFilterTest extends AbstractXMLFilterTests
+ "<!--post-in-->"
+ "</modules>"
+ "<!--after--></project>";
- String expected = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n" +
+ String expected = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n" +
"<project><!--before--><!--after--></project>";
String actual = transform( input );
assertThat( actual ).and( expected ).areIdentical();
diff --git a/maven-xml/src/test/java/org/apache/maven/xml/sax/filter/ParentXMLFilterTest.java b/maven-xml/src/test/java/org/apache/maven/xml/sax/filter/ParentXMLFilterTest.java
index eee0359..5cbf707 100644
--- a/maven-xml/src/test/java/org/apache/maven/xml/sax/filter/ParentXMLFilterTest.java
+++ b/maven-xml/src/test/java/org/apache/maven/xml/sax/filter/ParentXMLFilterTest.java
@@ -89,6 +89,31 @@ public class ParentXMLFilterTest extends AbstractXMLFilterTests
assertEquals( expected, actual );
}
+ /**
+ * An empty relative path means it must downloaded from a repository.
+ * That implies that the version cannot be solved (if missing, Maven should complain)
+ *
+ * @throws Exception
+ */
+ @Test
+ public void testEmptyRelativePathNoVersion() throws Exception
+ {
+ String input = "<parent>"
+ + "<groupId>GROUPID</groupId>"
+ + "<artifactId>ARTIFACTID</artifactId>"
+ + "<relativePath></relativePath>"
+ + "</parent>";
+ String expected = "<parent>"
+ + "<groupId>GROUPID</groupId>"
+ + "<artifactId>ARTIFACTID</artifactId>"
+ + "<relativePath/>" // SAX optimization, however "" != null ...
+ + "</parent>";
+
+ String actual = transform( input );
+
+ assertEquals( expected, actual );
+ }
+
@Test
public void testNoVersion() throws Exception
{