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/02/24 21:57:57 UTC
[maven] 01/02: [MNG-6656] Introduce ModelSourceTransformer
This is an automated email from the ASF dual-hosted git repository.
rfscholte pushed a commit to branch MNG-6656
in repository https://gitbox.apache.org/repos/asf/maven.git
commit 3294a6b44f2b3d0b87a611fbaf82136ecd7b97eb
Author: rfscholte <rf...@apache.org>
AuthorDate: Sat Feb 22 16:55:35 2020 +0100
[MNG-6656] Introduce ModelSourceTransformer
---
.../maven/project/DefaultProjectBuilder.java | 9 +-
.../apache/maven/project/ProjectModelResolver.java | 6 +-
.../org/apache/maven/project/ReactorModelPool.java | 96 ++++++++++++------
.../maven/model/building/DefaultModelBuilder.java | 88 +----------------
.../model/building/DefaultModelBuilderFactory.java | 6 ++
.../model/building/DefaultModelProcessor.java | 19 ++++
.../building/DefaultModelSourceTransformer.java | 109 +++++++++++++++++++++
.../maven/model/building/ModelProcessor.java | 19 ++++
...lProcessor.java => ModelSourceTransformer.java} | 21 ++--
9 files changed, 246 insertions(+), 127 deletions(-)
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 c5bf26c..237ba04 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
@@ -366,7 +366,8 @@ public class DefaultProjectBuilder
List<InterimResult> interimResults = new ArrayList<>();
- ReactorModelPool modelPool = new ReactorModelPool();
+ ReactorModelPool.Builder poolBuilder = new ReactorModelPool.Builder();
+ ReactorModelPool modelPool = poolBuilder.build();
InternalConfig config = new InternalConfig( request, modelPool,
useGlobalModelCache() ? getModelCache() : new ReactorModelCache() );
@@ -377,7 +378,7 @@ public class DefaultProjectBuilder
build( results, interimResults, projectIndex, pomFiles, new LinkedHashSet<>(), true, recursive,
config );
- populateReactorModelPool( modelPool, interimResults );
+ populateReactorModelPool( poolBuilder, interimResults );
ClassLoader oldContextClassLoader = Thread.currentThread().getContextClassLoader();
@@ -592,12 +593,12 @@ public class DefaultProjectBuilder
}
- private void populateReactorModelPool( ReactorModelPool reactorModelPool, List<InterimResult> interimResults )
+ private void populateReactorModelPool( ReactorModelPool.Builder reactorModelPool, List<InterimResult> interimResults )
{
for ( InterimResult interimResult : interimResults )
{
Model model = interimResult.result.getEffectiveModel();
- reactorModelPool.put( model.getGroupId(), model.getArtifactId(), model.getVersion(), model.getPomFile() );
+ reactorModelPool.put( model.getPomFile().toPath(), model );
populateReactorModelPool( reactorModelPool, interimResult.modules );
}
diff --git a/maven-core/src/main/java/org/apache/maven/project/ProjectModelResolver.java b/maven-core/src/main/java/org/apache/maven/project/ProjectModelResolver.java
index 24b36dd..e927f77 100644
--- a/maven-core/src/main/java/org/apache/maven/project/ProjectModelResolver.java
+++ b/maven-core/src/main/java/org/apache/maven/project/ProjectModelResolver.java
@@ -25,9 +25,11 @@ import java.util.Collections;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
+import java.util.Optional;
import java.util.Set;
import org.apache.maven.model.Dependency;
+import org.apache.maven.model.Model;
import org.apache.maven.model.Parent;
import org.apache.maven.model.Repository;
import org.apache.maven.model.building.FileModelSource;
@@ -178,7 +180,9 @@ public class ProjectModelResolver
if ( modelPool != null )
{
- pomFile = modelPool.get( groupId, artifactId, version );
+ pomFile = Optional.ofNullable( modelPool.get( groupId, artifactId,
+ version ) ).map( Model::getPomFile )
+ .orElse( null );
}
if ( pomFile == null )
diff --git a/maven-core/src/main/java/org/apache/maven/project/ReactorModelPool.java b/maven-core/src/main/java/org/apache/maven/project/ReactorModelPool.java
index 64b30dd..048a091 100644
--- a/maven-core/src/main/java/org/apache/maven/project/ReactorModelPool.java
+++ b/maven-core/src/main/java/org/apache/maven/project/ReactorModelPool.java
@@ -19,53 +19,100 @@ package org.apache.maven.project;
* under the License.
*/
-import java.io.File;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.util.ArrayList;
+import java.util.Collections;
import java.util.HashMap;
+import java.util.List;
import java.util.Map;
+import java.util.NoSuchElementException;
+import java.util.Objects;
+
+import org.apache.maven.model.Model;
/**
- * Holds all POM files that are known to the reactor. This allows the project builder to resolve imported POMs from the
+ * Holds all Models that are known to the reactor. This allows the project builder to resolve imported Models from the
* reactor when building another project's effective model.
*
* @author Benjamin Bentmann
+ * @Robert Scholte
*/
class ReactorModelPool
{
+ private final Map<GAKey, List<Model>> modelsByGa = new HashMap<>();
+
+ private final Map<Path, Model> modelsByPath = new HashMap<>();
+
+ /**
+ * This used to be the only method, which
+ *
+ * @param groupId, never {@code null}
+ * @param artifactId, never {@code null}
+ * @param version, might be {@code null}
+ * @return
+ * @throws IllegalStateException if version was null and multiple modules share the same groupId + artifactId
+ * @throws NoSuchElementException if model could not be found
+ */
+ public Model get( String groupId, String artifactId, String version ) throws IllegalStateException, NoSuchElementException
+ {
+ // TODO DefaultModelBuilder.readParentExternally still tries to use the ReactorModelPool, should be fixed
+ // For now, use getOrDefault/orElse instead of get
+ return modelsByGa.getOrDefault( new GAKey( groupId, artifactId ), Collections.emptyList() ).stream()
+ .filter( m -> version == null || version.equals( m.getVersion() ) )
+ .reduce( ( a, b ) -> {
+ throw new IllegalStateException( "Multiple modules with key "
+ + a.getGroupId() + ':' + a.getArtifactId() );
+ } ).orElse( null );
+ }
- private final Map<CacheKey, File> pomFiles = new HashMap<>();
-
- public File get( String groupId, String artifactId, String version )
+ public Model get( Path path )
{
- return pomFiles.get( new CacheKey( groupId, artifactId, version ) );
+ final Path pomFile;
+ if ( Files.isDirectory( path ) )
+ {
+ pomFile = path.resolve( "pom.xml" );
+ }
+ else
+ {
+ pomFile = path;
+ }
+ return modelsByPath.get( pomFile );
}
- public void put( String groupId, String artifactId, String version, File pomFile )
+ static class Builder
{
- pomFiles.put( new CacheKey( groupId, artifactId, version ), pomFile );
+ private ReactorModelPool pool = new ReactorModelPool();
+
+ Builder put( Path pomFile, Model model )
+ {
+ pool.modelsByPath.put( pomFile, model );
+ pool.modelsByGa.computeIfAbsent( new GAKey( model.getGroupId(), model.getArtifactId() ),
+ k -> new ArrayList<Model>() ).add( model );
+ return this;
+ }
+
+ ReactorModelPool build()
+ {
+ return pool;
+ }
}
- private static final class CacheKey
+ private static final class GAKey
{
private final String groupId;
private final String artifactId;
- private final String version;
-
private final int hashCode;
- CacheKey( String groupId, String artifactId, String version )
+ GAKey( String groupId, String artifactId )
{
this.groupId = ( groupId != null ) ? groupId : "";
this.artifactId = ( artifactId != null ) ? artifactId : "";
- this.version = ( version != null ) ? version : "";
- int hash = 17;
- hash = hash * 31 + this.groupId.hashCode();
- hash = hash * 31 + this.artifactId.hashCode();
- hash = hash * 31 + this.version.hashCode();
- hashCode = hash;
+ hashCode = Objects.hash( this.groupId, this.artifactId );
}
@Override
@@ -76,15 +123,9 @@ class ReactorModelPool
return true;
}
- if ( !( obj instanceof CacheKey ) )
- {
- return false;
- }
+ GAKey that = (GAKey) obj;
- CacheKey that = (CacheKey) obj;
-
- return artifactId.equals( that.artifactId ) && groupId.equals( that.groupId )
- && version.equals( that.version );
+ return artifactId.equals( that.artifactId ) && groupId.equals( that.groupId );
}
@Override
@@ -97,10 +138,9 @@ class ReactorModelPool
public String toString()
{
StringBuilder buffer = new StringBuilder( 128 );
- buffer.append( groupId ).append( ':' ).append( artifactId ).append( ':' ).append( version );
+ buffer.append( groupId ).append( ':' ).append( artifactId );
return buffer.toString();
}
-
}
}
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 98d2703..c635d05 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
@@ -24,14 +24,7 @@ import static org.apache.maven.model.building.Result.newResult;
import org.apache.maven.artifact.versioning.ArtifactVersion;
import java.io.File;
-import java.io.FileInputStream;
-import java.io.FilterOutputStream;
import java.io.IOException;
-import java.io.InputStream;
-import java.io.OutputStream;
-import java.io.PipedInputStream;
-import java.io.PipedOutputStream;
-import java.nio.file.Path;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
@@ -48,9 +41,6 @@ import javax.inject.Provider;
import javax.inject.Singleton;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.transform.TransformerException;
-import javax.xml.transform.TransformerFactory;
-import javax.xml.transform.sax.SAXSource;
-import javax.xml.transform.stream.StreamResult;
import org.apache.maven.artifact.versioning.DefaultArtifactVersion;
import org.apache.maven.artifact.versioning.InvalidVersionSpecificationException;
@@ -100,7 +90,6 @@ import org.apache.maven.model.resolution.UnresolvableModelException;
import org.apache.maven.model.resolution.WorkspaceModelResolver;
import org.apache.maven.model.superpom.SuperPomProvider;
import org.apache.maven.model.validation.ModelValidator;
-import org.apache.maven.xml.Factories;
import org.apache.maven.xml.sax.filter.BuildPomXMLFilterFactory;
import org.apache.maven.xml.sax.filter.BuildPomXMLFilterListener;
import org.codehaus.plexus.interpolation.MapBasedValueSource;
@@ -699,7 +688,7 @@ public class DefaultModelBuilder
{
try
{
- Model rawModel = modelProcessor.read( transformData( pomFile.toPath() ), null );
+ Model rawModel = modelProcessor.read( pomFile.toPath(), buildPomXMLFilterFactory.get() );
model.setPomFile( pomFile );
@@ -894,81 +883,6 @@ public class DefaultModelBuilder
inheritanceAssembler.assembleModelInheritance( child, parent, request, problems );
}
}
-
- private InputStream transformData( final Path pomFile )
- throws IOException, TransformerException, SAXException, ParserConfigurationException
- {
- final TransformerFactory transformerFactory = Factories.newTransformerFactory() ;
-
- final PipedOutputStream pipedOutputStream = new PipedOutputStream();
- final PipedInputStream pipedInputStream = new PipedInputStream( pipedOutputStream );
-
- // Should always be FileSource for reactor poms
- // System.out.println( "transforming " + pomFile );
-
- final SAXSource transformSource =
- new SAXSource( buildPomXMLFilterFactory.get().get( pomFile ),
- new org.xml.sax.InputSource( new FileInputStream( pomFile.toFile() ) ) );
-
- OutputStream out;
- if ( xmlFilterListener != null )
- {
- out = new FilterOutputStream( pipedOutputStream )
- {
- @Override
- public void write( byte[] b, int off, int len )
- throws IOException
- {
- super.write( b, off, len );
- xmlFilterListener.write( pomFile, b, off, len );
- }
- };
- }
- else
- {
- out = pipedOutputStream;
- }
-
- final StreamResult result = new StreamResult( out );
-
-//// final Callable<Void> callable = () ->
-//// {
-//// try ( PipedOutputStream out = pipedOutputStream )
-//// {
-//// transformerFactory.newTransformer().transform( transformSource, result );
-//// }
-//// return null;
-//// };
-////
-//// ExecutorService executorService = Executors.newSingleThreadExecutor();
-//// try
-//// {
-//// executorService.submit( callable ).get();
-//// }
-//// catch ( InterruptedException | ExecutionException e )
-//// {
-//// throw new TransformerException( "Failed to transform pom", e );
-//// }
- final Runnable runnable = new Runnable()
- {
- @Override
- public void run()
- {
- try ( PipedOutputStream out = pipedOutputStream )
- {
- transformerFactory.newTransformer().transform( transformSource, result );
- }
- catch ( TransformerException | IOException e )
- {
- throw new RuntimeException( e );
- }
- }
- };
-
- new Thread( runnable ).start();
-
- return pipedInputStream;
- }
private Map<String, Activation> getProfileActivations( Model model, boolean clone )
{
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 82cd713..f84cc0d 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
@@ -82,6 +82,7 @@ public class DefaultModelBuilderFactory
DefaultModelProcessor processor = new DefaultModelProcessor();
processor.setModelLocator( newModelLocator() );
processor.setModelReader( newModelReader() );
+ processor.setTransformer( newTransformer() );
return processor;
}
@@ -200,6 +201,11 @@ public class DefaultModelBuilderFactory
return new DefaultReportingConverter();
}
+ protected ModelSourceTransformer newTransformer()
+ {
+ return new DefaultModelSourceTransformer();
+ }
+
/**
* Creates a new model builder instance.
*
diff --git a/maven-model-builder/src/main/java/org/apache/maven/model/building/DefaultModelProcessor.java b/maven-model-builder/src/main/java/org/apache/maven/model/building/DefaultModelProcessor.java
index 76370ac..d87609b 100644
--- a/maven-model-builder/src/main/java/org/apache/maven/model/building/DefaultModelProcessor.java
+++ b/maven-model-builder/src/main/java/org/apache/maven/model/building/DefaultModelProcessor.java
@@ -23,16 +23,21 @@ import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.io.Reader;
+import java.nio.file.Path;
import java.util.Map;
import javax.inject.Inject;
import javax.inject.Named;
import javax.inject.Singleton;
+import javax.xml.parsers.ParserConfigurationException;
+import javax.xml.transform.TransformerConfigurationException;
import org.apache.maven.model.Model;
import org.apache.maven.model.io.ModelReader;
import org.apache.maven.model.locator.ModelLocator;
+import org.apache.maven.xml.sax.filter.BuildPomXMLFilterFactory;
import org.eclipse.sisu.Typed;
+import org.xml.sax.SAXException;
/**
*
@@ -71,6 +76,9 @@ public class DefaultModelProcessor
@Inject
private ModelReader reader;
+
+ @Inject
+ private ModelSourceTransformer transformer;
public DefaultModelProcessor setModelLocator( ModelLocator locator )
{
@@ -83,6 +91,12 @@ public class DefaultModelProcessor
this.reader = reader;
return this;
}
+
+ public DefaultModelProcessor setTransformer( ModelSourceTransformer transformer )
+ {
+ this.transformer = transformer;
+ return this;
+ }
@Override
public File locatePom( File projectDirectory )
@@ -111,4 +125,9 @@ public class DefaultModelProcessor
return reader.read( input, options );
}
+ @Override
+ public Model read( Path pomFile, BuildPomXMLFilterFactory factory ) throws IOException, TransformerConfigurationException, SAXException, ParserConfigurationException
+ {
+ return reader.read( transformer.transform( pomFile, factory ), null );
+ }
}
diff --git a/maven-model-builder/src/main/java/org/apache/maven/model/building/DefaultModelSourceTransformer.java b/maven-model-builder/src/main/java/org/apache/maven/model/building/DefaultModelSourceTransformer.java
new file mode 100644
index 0000000..6171089
--- /dev/null
+++ b/maven-model-builder/src/main/java/org/apache/maven/model/building/DefaultModelSourceTransformer.java
@@ -0,0 +1,109 @@
+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.io.FileInputStream;
+import java.io.FilterOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.io.PipedInputStream;
+import java.io.PipedOutputStream;
+import java.nio.file.Path;
+
+import javax.inject.Inject;
+import javax.inject.Named;
+import javax.inject.Singleton;
+import javax.xml.parsers.ParserConfigurationException;
+import javax.xml.transform.TransformerConfigurationException;
+import javax.xml.transform.TransformerException;
+import javax.xml.transform.TransformerFactory;
+import javax.xml.transform.sax.SAXSource;
+import javax.xml.transform.stream.StreamResult;
+
+import org.apache.maven.xml.Factories;
+import org.apache.maven.xml.sax.filter.BuildPomXMLFilterFactory;
+import org.apache.maven.xml.sax.filter.BuildPomXMLFilterListener;
+import org.eclipse.sisu.Nullable;
+import org.xml.sax.SAXException;
+
+@Named
+@Singleton
+class DefaultModelSourceTransformer implements ModelSourceTransformer
+{
+ @Inject
+ @Nullable
+ private BuildPomXMLFilterListener xmlFilterListener;
+
+ @Override
+ public InputStream transform( Path pomFile, BuildPomXMLFilterFactory buildPomXMLFilterFactory )
+ throws IOException, TransformerConfigurationException, SAXException, ParserConfigurationException
+ {
+ final TransformerFactory transformerFactory = Factories.newTransformerFactory() ;
+
+ final PipedOutputStream pipedOutputStream = new PipedOutputStream();
+ final PipedInputStream pipedInputStream = new PipedInputStream( pipedOutputStream );
+
+ final SAXSource transformSource =
+ new SAXSource( buildPomXMLFilterFactory.get( pomFile ),
+ new org.xml.sax.InputSource( new FileInputStream( pomFile.toFile() ) ) );
+
+ OutputStream out;
+ if ( xmlFilterListener != null )
+ {
+ out = new FilterOutputStream( pipedOutputStream )
+ {
+ @Override
+ public void write( byte[] b, int off, int len )
+ throws IOException
+ {
+ super.write( b, off, len );
+ xmlFilterListener.write( pomFile, b, off, len );
+ }
+ };
+ }
+ else
+ {
+ out = pipedOutputStream;
+ }
+
+ final StreamResult result = new StreamResult( out );
+
+ final Runnable runnable = new Runnable()
+ {
+ @Override
+ public void run()
+ {
+ try ( PipedOutputStream out = pipedOutputStream )
+ {
+ transformerFactory.newTransformer().transform( transformSource, result );
+ }
+ catch ( TransformerException | IOException e )
+ {
+ throw new RuntimeException( e );
+ }
+ }
+ };
+
+ new Thread( runnable ).start();
+
+ return pipedInputStream;
+ }
+}
diff --git a/maven-model-builder/src/main/java/org/apache/maven/model/building/ModelProcessor.java b/maven-model-builder/src/main/java/org/apache/maven/model/building/ModelProcessor.java
index c2c2ec0..2adb2c0 100644
--- a/maven-model-builder/src/main/java/org/apache/maven/model/building/ModelProcessor.java
+++ b/maven-model-builder/src/main/java/org/apache/maven/model/building/ModelProcessor.java
@@ -1,5 +1,17 @@
package org.apache.maven.model.building;
+import java.io.IOException;
+import java.io.InputStream;
+import java.nio.file.Path;
+import java.util.Map;
+import java.util.function.Function;
+
+import javax.xml.parsers.ParserConfigurationException;
+import javax.xml.transform.TransformerConfigurationException;
+
+import org.apache.maven.model.Model;
+import org.apache.maven.model.io.ModelParseException;
+
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
@@ -21,6 +33,8 @@ package org.apache.maven.model.building;
import org.apache.maven.model.io.ModelReader;
import org.apache.maven.model.locator.ModelLocator;
+import org.apache.maven.xml.sax.filter.BuildPomXMLFilterFactory;
+import org.xml.sax.SAXException;
/**
* ModelProcessor
@@ -31,5 +45,10 @@ public interface ModelProcessor
{
String SOURCE = "org.apache.maven.model.building.source";
+
+ default Model read( Path pomFile, BuildPomXMLFilterFactory factory ) throws IOException, TransformerConfigurationException, SAXException, ParserConfigurationException
+ {
+ return read( pomFile.toFile(), null );
+ }
}
diff --git a/maven-model-builder/src/main/java/org/apache/maven/model/building/ModelProcessor.java b/maven-model-builder/src/main/java/org/apache/maven/model/building/ModelSourceTransformer.java
similarity index 59%
copy from maven-model-builder/src/main/java/org/apache/maven/model/building/ModelProcessor.java
copy to maven-model-builder/src/main/java/org/apache/maven/model/building/ModelSourceTransformer.java
index c2c2ec0..5ee3252 100644
--- a/maven-model-builder/src/main/java/org/apache/maven/model/building/ModelProcessor.java
+++ b/maven-model-builder/src/main/java/org/apache/maven/model/building/ModelSourceTransformer.java
@@ -19,17 +19,24 @@ package org.apache.maven.model.building;
* under the License.
*/
-import org.apache.maven.model.io.ModelReader;
-import org.apache.maven.model.locator.ModelLocator;
+import java.io.IOException;
+import java.io.InputStream;
+import java.nio.file.Path;
+
+import javax.xml.parsers.ParserConfigurationException;
+import javax.xml.transform.TransformerConfigurationException;
+
+import org.apache.maven.xml.sax.filter.BuildPomXMLFilterFactory;
+import org.xml.sax.SAXException;
/**
- * ModelProcessor
+ *
+ * @author Robert Scholte
+ * @since 3.7.0
*/
-@SuppressWarnings( "checkstyle:interfaceistype" )
-public interface ModelProcessor
- extends ModelLocator, ModelReader
+public interface ModelSourceTransformer
{
- String SOURCE = "org.apache.maven.model.building.source";
+ InputStream transform( Path pomFile, BuildPomXMLFilterFactory buildPomXMLFilterFactory ) throws IOException, TransformerConfigurationException, SAXException, ParserConfigurationException;
}