From 65a5a1bbaaf205fa2614d0725291a4bbc63f9633 Mon Sep 17 00:00:00 2001 From: rfscholte Date: Tue, 14 May 2019 21:26:07 +0200 Subject: [PATCH 01/52] [MNG-6656] Introduce base for build/consumer pom --- maven-core/pom.xml | 5 + ...DefaultRepositorySystemSessionFactory.java | 107 +++++++++++++-- .../maven/xml/filter/BuildPomXMLFilter.java | 44 ++++++ .../xml/filter/ConsumerPomXMLFilter.java | 73 ++++++++++ .../maven/xml/filter/FastForwardFilter.java | 128 ++++++++++++++++++ .../maven/xml/filter/ModulesXMLFilter.java | 102 ++++++++++++++ .../xml/filter/RelativePathXMLFilter.java | 98 ++++++++++++++ .../xml/filter/AbstractXMLFilterTests.java | 80 +++++++++++ .../xml/filter/ConsumerPomXMLFilterTest.java | 64 +++++++++ .../xml/filter/ModulesXMLFilterTest.java | 62 +++++++++ .../xml/filter/RelativePathXMLFilterTest.java | 61 +++++++++ pom.xml | 8 +- 12 files changed, 823 insertions(+), 9 deletions(-) create mode 100644 maven-core/src/main/java/org/apache/maven/xml/filter/BuildPomXMLFilter.java create mode 100644 maven-core/src/main/java/org/apache/maven/xml/filter/ConsumerPomXMLFilter.java create mode 100644 maven-core/src/main/java/org/apache/maven/xml/filter/FastForwardFilter.java create mode 100644 maven-core/src/main/java/org/apache/maven/xml/filter/ModulesXMLFilter.java create mode 100644 maven-core/src/main/java/org/apache/maven/xml/filter/RelativePathXMLFilter.java create mode 100644 maven-core/src/test/java/org/apache/maven/xml/filter/AbstractXMLFilterTests.java create mode 100644 maven-core/src/test/java/org/apache/maven/xml/filter/ConsumerPomXMLFilterTest.java create mode 100644 maven-core/src/test/java/org/apache/maven/xml/filter/ModulesXMLFilterTest.java create mode 100644 maven-core/src/test/java/org/apache/maven/xml/filter/RelativePathXMLFilterTest.java diff --git a/maven-core/pom.xml b/maven-core/pom.xml index be31a3eca54b..e467851442b5 100644 --- a/maven-core/pom.xml +++ b/maven-core/pom.xml @@ -136,6 +136,11 @@ under the License. mockito-core test + + org.xmlunit + xmlunit-assertj + test + diff --git a/maven-core/src/main/java/org/apache/maven/internal/aether/DefaultRepositorySystemSessionFactory.java b/maven-core/src/main/java/org/apache/maven/internal/aether/DefaultRepositorySystemSessionFactory.java index 248a3b6dd120..792b08544784 100644 --- a/maven-core/src/main/java/org/apache/maven/internal/aether/DefaultRepositorySystemSessionFactory.java +++ b/maven-core/src/main/java/org/apache/maven/internal/aether/DefaultRepositorySystemSessionFactory.java @@ -19,6 +19,27 @@ * under the License. */ +import java.io.File; +import java.io.FileReader; +import java.io.IOException; +import java.io.InputStream; +import java.io.PipedInputStream; +import java.io.PipedOutputStream; +import java.util.ArrayList; +import java.util.Collection; +import java.util.Collections; +import java.util.LinkedHashMap; +import java.util.Map; +import java.util.Properties; + +import javax.inject.Inject; +import javax.inject.Named; +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.RepositoryUtils; import org.apache.maven.artifact.handler.manager.ArtifactHandlerManager; import org.apache.maven.bridge.MavenRepositorySystem; @@ -32,32 +53,31 @@ import org.apache.maven.settings.crypto.DefaultSettingsDecryptionRequest; import org.apache.maven.settings.crypto.SettingsDecrypter; import org.apache.maven.settings.crypto.SettingsDecryptionResult; +import org.apache.maven.xml.filter.ConsumerPomXMLFilter; import org.codehaus.plexus.configuration.xml.XmlPlexusConfiguration; import org.codehaus.plexus.logging.Logger; import org.codehaus.plexus.util.xml.Xpp3Dom; import org.eclipse.aether.ConfigurationProperties; import org.eclipse.aether.DefaultRepositorySystemSession; import org.eclipse.aether.RepositorySystem; +import org.eclipse.aether.artifact.Artifact; import org.eclipse.aether.repository.LocalRepository; import org.eclipse.aether.repository.NoLocalRepositoryManagerException; import org.eclipse.aether.repository.RepositoryPolicy; import org.eclipse.aether.repository.WorkspaceReader; import org.eclipse.aether.resolution.ResolutionErrorPolicy; import org.eclipse.aether.spi.localrepo.LocalRepositoryManagerFactory; +import org.eclipse.aether.transform.FileTransformer; +import org.eclipse.aether.transform.FileTransformerManager; +import org.eclipse.aether.transform.TransformException; import org.eclipse.aether.util.repository.AuthenticationBuilder; import org.eclipse.aether.util.repository.DefaultAuthenticationSelector; import org.eclipse.aether.util.repository.DefaultMirrorSelector; import org.eclipse.aether.util.repository.DefaultProxySelector; import org.eclipse.aether.util.repository.SimpleResolutionErrorPolicy; import org.eclipse.sisu.Nullable; - -import javax.inject.Inject; -import javax.inject.Named; -import java.io.IOException; -import java.io.InputStream; -import java.util.LinkedHashMap; -import java.util.Map; -import java.util.Properties; +import org.xml.sax.InputSource; +import org.xml.sax.SAXException; /** * @since 3.3.0 @@ -238,9 +258,80 @@ else if ( request.isUpdateSnapshots() ) mavenRepositorySystem.injectProxy( session, request.getPluginArtifactRepositories() ); mavenRepositorySystem.injectAuthentication( session, request.getPluginArtifactRepositories() ); + if ( Boolean.getBoolean( "maven.experimental.buildconsumer" ) ) + { + session.setFileTransformerManager( newFileTransformerManager() ); + } return session; } + private FileTransformerManager newFileTransformerManager() + { + return new FileTransformerManager() + { + @Override + public Collection getTransformersForArtifact( Artifact artifact ) + { + Collection transformers = new ArrayList<>(); + if ( "pom".equals( artifact.getExtension() ) ) + { + final TransformerFactory transformerFactory = TransformerFactory.newInstance(); + + transformers.add( new FileTransformer() + { + @Override + public InputStream transformData( File file ) + throws IOException, TransformException + { + try + { + final PipedOutputStream pipedOutputStream = new PipedOutputStream(); + final PipedInputStream pipedInputStream = new PipedInputStream( pipedOutputStream ); + + final SAXSource transformSource = + new SAXSource( new ConsumerPomXMLFilter(), + new InputSource( new FileReader( file ) ) ); + + final StreamResult result = new StreamResult( pipedOutputStream ); + + 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; + } + catch ( SAXException | ParserConfigurationException e ) + { + throw new TransformException( e ); + } + } + + @Override + public Artifact transformArtifact( Artifact artifact ) + { + return artifact; + } + } ); + } + return Collections.unmodifiableCollection( transformers ); + } + }; + } + private String getUserAgent() { return "Apache-Maven/" + getMavenVersion() + " (Java " + System.getProperty( "java.version" ) + "; " diff --git a/maven-core/src/main/java/org/apache/maven/xml/filter/BuildPomXMLFilter.java b/maven-core/src/main/java/org/apache/maven/xml/filter/BuildPomXMLFilter.java new file mode 100644 index 000000000000..60f0c4951d32 --- /dev/null +++ b/maven-core/src/main/java/org/apache/maven/xml/filter/BuildPomXMLFilter.java @@ -0,0 +1,44 @@ +package org.apache.maven.xml.filter; + +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +import org.xml.sax.XMLReader; +import org.xml.sax.helpers.XMLFilterImpl; + +/** + * Filter to adjust pom on filesystem before being processed for effective pom. + * + * @author Robert Scholte + * @since 3.7.0 + */ +public class BuildPomXMLFilter extends XMLFilterImpl +{ + public BuildPomXMLFilter() + { + super(); + } + + public BuildPomXMLFilter( XMLReader parent ) + { + super( parent ); + } + + +} diff --git a/maven-core/src/main/java/org/apache/maven/xml/filter/ConsumerPomXMLFilter.java b/maven-core/src/main/java/org/apache/maven/xml/filter/ConsumerPomXMLFilter.java new file mode 100644 index 000000000000..8709b9c0a15d --- /dev/null +++ b/maven-core/src/main/java/org/apache/maven/xml/filter/ConsumerPomXMLFilter.java @@ -0,0 +1,73 @@ +package org.apache.maven.xml.filter; + +/* + * 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 javax.xml.parsers.ParserConfigurationException; +import javax.xml.parsers.SAXParserFactory; + +import org.xml.sax.SAXException; +import org.xml.sax.XMLFilter; +import org.xml.sax.XMLReader; + +import org.xml.sax.helpers.XMLFilterImpl; + +/** + * XML Filter to transform pom.xml to consumer pom. + * This often means stripping of build-specific information. + * + * This filter is used at 2 locations: + * - {@link org.apache.maven.internal.aether.DefaultRepositorySystemSessionFactory} when publishing pom files. + * - TODO ???Class when a reactor module is used as dependency. This ensures consistency of dependency handling + * + * @author Robert Scholte + * @since 3.7.0 + */ +public class ConsumerPomXMLFilter extends XMLFilterImpl +{ + private final XMLFilter rootFilter; + + public ConsumerPomXMLFilter() throws SAXException, ParserConfigurationException + { + this( SAXParserFactory.newInstance().newSAXParser().getXMLReader() ); + } + + public ConsumerPomXMLFilter( XMLReader parent ) + { + rootFilter = new BuildPomXMLFilter( parent ); + + // Ensure that xs:any elements aren't touched by next filters + XMLFilter filter = new FastForwardFilter( rootFilter ); + + // Strip modules + filter = new ModulesXMLFilter( filter ); + // Adjust relativePath + filter = new RelativePathXMLFilter( filter ); + + // maybe more to follow + + super.setParent( filter ); + } + + @Override + public void setParent( XMLReader parent ) + { + rootFilter.setParent( parent ); + } +} diff --git a/maven-core/src/main/java/org/apache/maven/xml/filter/FastForwardFilter.java b/maven-core/src/main/java/org/apache/maven/xml/filter/FastForwardFilter.java new file mode 100644 index 000000000000..df68167a1394 --- /dev/null +++ b/maven-core/src/main/java/org/apache/maven/xml/filter/FastForwardFilter.java @@ -0,0 +1,128 @@ +package org.apache.maven.xml.filter; + +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +import java.util.ArrayDeque; +import java.util.Deque; + +import org.xml.sax.Attributes; +import org.xml.sax.ContentHandler; +import org.xml.sax.SAXException; +import org.xml.sax.XMLFilter; +import org.xml.sax.XMLReader; +import org.xml.sax.helpers.XMLFilterImpl; + +/** + * This filter will skip all following filters and write directly to the output. + * Should be used in case of a DOM that should not be effected by other filters, even though the elements match + * + * @author Robert Scholte + * @since 4.0.0 + */ +class FastForwardFilter extends XMLFilterImpl +{ + /** + * DOM elements of pom + * + *
    + *
  • execution.configuration
  • + *
  • plugin.configuration
  • + *
  • plugin.goals
  • + *
  • profile.reports
  • + *
  • project.reports
  • + *
  • reportSet.configuration
  • + *
      + */ + private final Deque state = new ArrayDeque<>(); + + private int domDepth = 0; + + private ContentHandler originalHandler; + + FastForwardFilter() + { + super(); + } + + FastForwardFilter( XMLReader parent ) + { + super( parent ); + } + + @Override + public void startElement( String uri, String localName, String qName, Attributes atts ) + throws SAXException + { + super.startElement( uri, localName, qName, atts ); + if ( domDepth > 0 ) + { + domDepth++; + } + else + { + final String key = state.peek() + '.' + localName; + switch ( key ) + { + case "execution.configuration": + case "plugin.configuration": + case "plugin.goals": + case "profile.reports": + case "project.reports": + case "reportSet.configuration": + domDepth++; + + originalHandler = getContentHandler(); + + ContentHandler outputContentHandler = getContentHandler(); + while ( outputContentHandler instanceof XMLFilter ) + { + outputContentHandler = ( (XMLFilter) outputContentHandler ).getContentHandler(); + } + setContentHandler( outputContentHandler ); + break; + default: + break; + } + state.push( localName ); + } + } + + @Override + public void endElement( String uri, String localName, String qName ) + throws SAXException + { + if ( domDepth > 0 ) + { + domDepth--; + + if ( domDepth == 0 ) + { + setContentHandler( originalHandler ); + } + } + else + { + state.pop(); + } + super.endElement( uri, localName, qName ); + } + + +} \ No newline at end of file diff --git a/maven-core/src/main/java/org/apache/maven/xml/filter/ModulesXMLFilter.java b/maven-core/src/main/java/org/apache/maven/xml/filter/ModulesXMLFilter.java new file mode 100644 index 000000000000..9e7b6fdbe5de --- /dev/null +++ b/maven-core/src/main/java/org/apache/maven/xml/filter/ModulesXMLFilter.java @@ -0,0 +1,102 @@ +package org.apache.maven.xml.filter; + +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +import org.xml.sax.Attributes; +import org.xml.sax.SAXException; +import org.xml.sax.XMLReader; +import org.xml.sax.helpers.XMLFilterImpl; + +/** + * Remove all modules, this is just buildtime information + * + * @author Robert Scholte + * @since 3.7.0 + */ +class ModulesXMLFilter + extends XMLFilterImpl +{ + /** + * Using 3 to also remove whitespace-block after closing tag + * -1 none + * 1 started + * 2 ended + */ + int modulesStatus = -1; + + ModulesXMLFilter() + { + super(); + } + + ModulesXMLFilter( XMLReader parent ) + { + super( parent ); + } + + @Override + public void startElement( String uri, String localName, String qName, Attributes atts ) + throws SAXException + { + if ( modulesStatus == -1 && "modules".equals( localName ) ) + { + modulesStatus = 1; + } + else if ( modulesStatus == 2 ) + { + modulesStatus = -1; + } + + if ( modulesStatus != 1 ) + { + super.startElement( uri, localName, qName, atts ); + } + } + + @Override + public void endElement( String uri, String localName, String qName ) + throws SAXException + { + if ( modulesStatus == 1 && "modules".equals( localName ) ) + { + modulesStatus = 2; + } + else if ( modulesStatus == 2 ) + { + modulesStatus = -1; + } + + if ( modulesStatus == -1 ) + { + super.endElement( uri, localName, qName ); + } + } + + @Override + public void characters( char[] ch, int start, int length ) + throws SAXException + { + if ( modulesStatus == -1 ) + { + super.characters( ch, start, length ); + } + } + +} diff --git a/maven-core/src/main/java/org/apache/maven/xml/filter/RelativePathXMLFilter.java b/maven-core/src/main/java/org/apache/maven/xml/filter/RelativePathXMLFilter.java new file mode 100644 index 000000000000..8548ddd73d9c --- /dev/null +++ b/maven-core/src/main/java/org/apache/maven/xml/filter/RelativePathXMLFilter.java @@ -0,0 +1,98 @@ +package org.apache.maven.xml.filter; + +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +import org.xml.sax.Attributes; +import org.xml.sax.SAXException; +import org.xml.sax.XMLReader; +import org.xml.sax.helpers.XMLFilterImpl; + +/** + * Remove content from relativePath + * + * TODO fix indentation of closing parent tag + * + * @author Robert Scholte + * @since 3.7.0 + */ +class RelativePathXMLFilter + extends XMLFilterImpl +{ + /** + * Using 3 to also remove whitespace-block after closing tag + * -1 none + * 1 started + * 2 ended + */ + int relativePathStatus = -1; + + RelativePathXMLFilter() + { + super(); + } + + RelativePathXMLFilter( XMLReader parent ) + { + super( parent ); + } + + @Override + public void startElement( String uri, String localName, String qName, Attributes atts ) + throws SAXException + { + if ( relativePathStatus == -1 && "relativePath".equals( localName ) ) + { + relativePathStatus = 1; + } + else if ( relativePathStatus == 2 ) + { + relativePathStatus = -1; + } + + super.startElement( uri, localName, qName, atts ); + } + + @Override + public void endElement( String uri, String localName, String qName ) + throws SAXException + { + if ( relativePathStatus == 1 && "relativePath".equals( localName ) ) + { + relativePathStatus = 2; + } + else if ( relativePathStatus == 2 ) + { + relativePathStatus = -1; + } + + super.endElement( uri, localName, qName ); + } + + @Override + public void characters( char[] ch, int start, int length ) + throws SAXException + { + if ( relativePathStatus != 1 ) + { + super.characters( ch, start, length ); + } + } + +} diff --git a/maven-core/src/test/java/org/apache/maven/xml/filter/AbstractXMLFilterTests.java b/maven-core/src/test/java/org/apache/maven/xml/filter/AbstractXMLFilterTests.java new file mode 100644 index 000000000000..69fc33ba8f59 --- /dev/null +++ b/maven-core/src/test/java/org/apache/maven/xml/filter/AbstractXMLFilterTests.java @@ -0,0 +1,80 @@ +package org.apache.maven.xml.filter; + +import java.io.Reader; + +/* + * 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.StringReader; +import java.io.StringWriter; +import java.io.Writer; + +import javax.xml.transform.OutputKeys; +import javax.xml.transform.Transformer; +import javax.xml.transform.TransformerException; +import javax.xml.transform.TransformerFactory; +import javax.xml.transform.sax.SAXSource; +import javax.xml.transform.stream.StreamResult; + +import org.xml.sax.InputSource; +import org.xml.sax.SAXException; +import org.xml.sax.XMLFilter; +import org.xml.sax.XMLReader; +import org.xml.sax.helpers.XMLReaderFactory; + +public class AbstractXMLFilterTests +{ + + public AbstractXMLFilterTests() + { + super(); + } + + protected String transform( String input, XMLFilter filter ) + throws TransformerException, SAXException + { + return transform( new StringReader( input ), filter ); + } + + protected String transform( Reader input, XMLFilter filter ) + throws TransformerException, SAXException + { + XMLReader reader = XMLReaderFactory.createXMLReader(); + + XMLFilter parent = filter; + while ( parent.getParent() instanceof XMLFilter ) + { + parent = (XMLFilter) parent.getParent(); + } + parent.setParent( reader ); + + Writer writer = new StringWriter(); + StreamResult result = new StreamResult( writer ); + + TransformerFactory transformerFactory = TransformerFactory.newInstance(); + Transformer transformer = transformerFactory.newTransformer(); + transformer.setOutputProperty( OutputKeys.OMIT_XML_DECLARATION, "yes" ); + + SAXSource transformSource = new SAXSource( filter, new InputSource( input ) ); + + transformer.transform( transformSource, result ); + + return writer.toString(); + } +} \ No newline at end of file diff --git a/maven-core/src/test/java/org/apache/maven/xml/filter/ConsumerPomXMLFilterTest.java b/maven-core/src/test/java/org/apache/maven/xml/filter/ConsumerPomXMLFilterTest.java new file mode 100644 index 000000000000..b3d44db91b6b --- /dev/null +++ b/maven-core/src/test/java/org/apache/maven/xml/filter/ConsumerPomXMLFilterTest.java @@ -0,0 +1,64 @@ +package org.apache.maven.xml.filter; + +/* + * 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 static org.xmlunit.assertj.XmlAssert.assertThat; + +import org.junit.Before; +import org.junit.Test; + +public class ConsumerPomXMLFilterTest extends AbstractXMLFilterTests +{ + private ConsumerPomXMLFilter filter; + + @Before + public void setup() throws Exception { + filter = new ConsumerPomXMLFilter(); + } + + @Test + public void testAllFilters() throws Exception { + String input = "\n" + + " \n" + + " GROUPID\n" + + " PARENT\n" + + " VERSION\n" + + " ../pom.xml\n" + + " \n" + + " PROJECT\n" + + " \n" + + " ab\n" + + " ../cd\n" + + " \n" + + ""; + String expected = "\n" + + " \n" + + " GROUPID\n" + + " PARENT\n" + + " VERSION\n" + + " \n" + + " \n" + + " PROJECT\n" + + ""; + String actual = transform( input, filter ); + assertThat( actual ).and( expected ).ignoreWhitespace().areIdentical(); + } + +} diff --git a/maven-core/src/test/java/org/apache/maven/xml/filter/ModulesXMLFilterTest.java b/maven-core/src/test/java/org/apache/maven/xml/filter/ModulesXMLFilterTest.java new file mode 100644 index 000000000000..353f1742d896 --- /dev/null +++ b/maven-core/src/test/java/org/apache/maven/xml/filter/ModulesXMLFilterTest.java @@ -0,0 +1,62 @@ +package org.apache.maven.xml.filter; + +/* + * 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 static org.xmlunit.assertj.XmlAssert.assertThat; + +import org.junit.Before; +import org.junit.Test; + +public class ModulesXMLFilterTest extends AbstractXMLFilterTests { + + private ModulesXMLFilter filter; + + @Before + public void setup() { + filter = new ModulesXMLFilter(); + } + + @Test + public void testEmptyModules() throws Exception { + String input = ""; + String expected = ""; + String actual = transform( input, filter ); + assertThat( actual ).and( expected ).areIdentical(); + } + + @Test + public void testSetOfModules() throws Exception { + String input = "" + + "ab" + + "../cd" + + ""; + String expected = ""; + String actual = transform( input, filter ); + assertThat( actual ).and( expected ).areIdentical(); + } + + @Test + public void testNoModules() throws Exception { + String input = "NAME"; + String expected = input; + String actual = transform( input, filter ); + assertThat( actual ).and( expected ).areIdentical(); + } +} diff --git a/maven-core/src/test/java/org/apache/maven/xml/filter/RelativePathXMLFilterTest.java b/maven-core/src/test/java/org/apache/maven/xml/filter/RelativePathXMLFilterTest.java new file mode 100644 index 000000000000..298197dd1c81 --- /dev/null +++ b/maven-core/src/test/java/org/apache/maven/xml/filter/RelativePathXMLFilterTest.java @@ -0,0 +1,61 @@ +package org.apache.maven.xml.filter; + +import static org.xmlunit.assertj.XmlAssert.assertThat; + +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +import org.junit.Before; +import org.junit.Test; + +public class RelativePathXMLFilterTest extends AbstractXMLFilterTests +{ + private RelativePathXMLFilter filter; + + @Before + public void setup() { + filter = new RelativePathXMLFilter(); + } + + @Test + public void testRelativePath() throws Exception + { + String input = "\n" + + " \n" + + " GROUPID\n" + + " PARENT\n" + + " VERSION\n" + + " ../pom.xml\n" + + " \n" + + " PROJECT\n" + + ""; + String expected = "\n" + + " \n" + + " GROUPID\n" + + " PARENT\n" + + " VERSION\n" + + " \n" + + " \n" + + " PROJECT\n" + + ""; + String actual = transform( input, filter ); + assertThat( actual ).and( expected ).areIdentical(); + } + +} diff --git a/pom.xml b/pom.xml index cb9dae5b6647..640e57cbd9a1 100644 --- a/pom.xml +++ b/pom.xml @@ -66,7 +66,7 @@ under the License. 1.3 1.3.3 1.7.25 - 2.2.1 + 2.6.2 true apache-maven @@ -405,6 +405,12 @@ under the License. ${mockitoVersion} test + + org.xmlunit + xmlunit-assertj + ${xmlunitVersion} + test + org.xmlunit xmlunit-core From dfb0c2cc75d9b381332c979d3ca1fb17330115b9 Mon Sep 17 00:00:00 2001 From: rfscholte Date: Tue, 14 May 2019 21:26:07 +0200 Subject: [PATCH 02/52] [MNG-6656] Introduce base for build/consumer pom --- maven-core/pom.xml | 5 + ...DefaultRepositorySystemSessionFactory.java | 107 +++++++++++++-- .../maven/xml/filter/BuildPomXMLFilter.java | 44 ++++++ .../xml/filter/ConsumerPomXMLFilter.java | 73 ++++++++++ .../maven/xml/filter/FastForwardFilter.java | 128 ++++++++++++++++++ .../maven/xml/filter/ModulesXMLFilter.java | 102 ++++++++++++++ .../xml/filter/RelativePathXMLFilter.java | 98 ++++++++++++++ .../xml/filter/AbstractXMLFilterTests.java | 80 +++++++++++ .../xml/filter/ConsumerPomXMLFilterTest.java | 64 +++++++++ .../xml/filter/ModulesXMLFilterTest.java | 62 +++++++++ .../xml/filter/RelativePathXMLFilterTest.java | 61 +++++++++ pom.xml | 8 +- 12 files changed, 823 insertions(+), 9 deletions(-) create mode 100644 maven-core/src/main/java/org/apache/maven/xml/filter/BuildPomXMLFilter.java create mode 100644 maven-core/src/main/java/org/apache/maven/xml/filter/ConsumerPomXMLFilter.java create mode 100644 maven-core/src/main/java/org/apache/maven/xml/filter/FastForwardFilter.java create mode 100644 maven-core/src/main/java/org/apache/maven/xml/filter/ModulesXMLFilter.java create mode 100644 maven-core/src/main/java/org/apache/maven/xml/filter/RelativePathXMLFilter.java create mode 100644 maven-core/src/test/java/org/apache/maven/xml/filter/AbstractXMLFilterTests.java create mode 100644 maven-core/src/test/java/org/apache/maven/xml/filter/ConsumerPomXMLFilterTest.java create mode 100644 maven-core/src/test/java/org/apache/maven/xml/filter/ModulesXMLFilterTest.java create mode 100644 maven-core/src/test/java/org/apache/maven/xml/filter/RelativePathXMLFilterTest.java diff --git a/maven-core/pom.xml b/maven-core/pom.xml index be31a3eca54b..e467851442b5 100644 --- a/maven-core/pom.xml +++ b/maven-core/pom.xml @@ -136,6 +136,11 @@ under the License. mockito-core test + + org.xmlunit + xmlunit-assertj + test + diff --git a/maven-core/src/main/java/org/apache/maven/internal/aether/DefaultRepositorySystemSessionFactory.java b/maven-core/src/main/java/org/apache/maven/internal/aether/DefaultRepositorySystemSessionFactory.java index 248a3b6dd120..792b08544784 100644 --- a/maven-core/src/main/java/org/apache/maven/internal/aether/DefaultRepositorySystemSessionFactory.java +++ b/maven-core/src/main/java/org/apache/maven/internal/aether/DefaultRepositorySystemSessionFactory.java @@ -19,6 +19,27 @@ * under the License. */ +import java.io.File; +import java.io.FileReader; +import java.io.IOException; +import java.io.InputStream; +import java.io.PipedInputStream; +import java.io.PipedOutputStream; +import java.util.ArrayList; +import java.util.Collection; +import java.util.Collections; +import java.util.LinkedHashMap; +import java.util.Map; +import java.util.Properties; + +import javax.inject.Inject; +import javax.inject.Named; +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.RepositoryUtils; import org.apache.maven.artifact.handler.manager.ArtifactHandlerManager; import org.apache.maven.bridge.MavenRepositorySystem; @@ -32,32 +53,31 @@ import org.apache.maven.settings.crypto.DefaultSettingsDecryptionRequest; import org.apache.maven.settings.crypto.SettingsDecrypter; import org.apache.maven.settings.crypto.SettingsDecryptionResult; +import org.apache.maven.xml.filter.ConsumerPomXMLFilter; import org.codehaus.plexus.configuration.xml.XmlPlexusConfiguration; import org.codehaus.plexus.logging.Logger; import org.codehaus.plexus.util.xml.Xpp3Dom; import org.eclipse.aether.ConfigurationProperties; import org.eclipse.aether.DefaultRepositorySystemSession; import org.eclipse.aether.RepositorySystem; +import org.eclipse.aether.artifact.Artifact; import org.eclipse.aether.repository.LocalRepository; import org.eclipse.aether.repository.NoLocalRepositoryManagerException; import org.eclipse.aether.repository.RepositoryPolicy; import org.eclipse.aether.repository.WorkspaceReader; import org.eclipse.aether.resolution.ResolutionErrorPolicy; import org.eclipse.aether.spi.localrepo.LocalRepositoryManagerFactory; +import org.eclipse.aether.transform.FileTransformer; +import org.eclipse.aether.transform.FileTransformerManager; +import org.eclipse.aether.transform.TransformException; import org.eclipse.aether.util.repository.AuthenticationBuilder; import org.eclipse.aether.util.repository.DefaultAuthenticationSelector; import org.eclipse.aether.util.repository.DefaultMirrorSelector; import org.eclipse.aether.util.repository.DefaultProxySelector; import org.eclipse.aether.util.repository.SimpleResolutionErrorPolicy; import org.eclipse.sisu.Nullable; - -import javax.inject.Inject; -import javax.inject.Named; -import java.io.IOException; -import java.io.InputStream; -import java.util.LinkedHashMap; -import java.util.Map; -import java.util.Properties; +import org.xml.sax.InputSource; +import org.xml.sax.SAXException; /** * @since 3.3.0 @@ -238,9 +258,80 @@ else if ( request.isUpdateSnapshots() ) mavenRepositorySystem.injectProxy( session, request.getPluginArtifactRepositories() ); mavenRepositorySystem.injectAuthentication( session, request.getPluginArtifactRepositories() ); + if ( Boolean.getBoolean( "maven.experimental.buildconsumer" ) ) + { + session.setFileTransformerManager( newFileTransformerManager() ); + } return session; } + private FileTransformerManager newFileTransformerManager() + { + return new FileTransformerManager() + { + @Override + public Collection getTransformersForArtifact( Artifact artifact ) + { + Collection transformers = new ArrayList<>(); + if ( "pom".equals( artifact.getExtension() ) ) + { + final TransformerFactory transformerFactory = TransformerFactory.newInstance(); + + transformers.add( new FileTransformer() + { + @Override + public InputStream transformData( File file ) + throws IOException, TransformException + { + try + { + final PipedOutputStream pipedOutputStream = new PipedOutputStream(); + final PipedInputStream pipedInputStream = new PipedInputStream( pipedOutputStream ); + + final SAXSource transformSource = + new SAXSource( new ConsumerPomXMLFilter(), + new InputSource( new FileReader( file ) ) ); + + final StreamResult result = new StreamResult( pipedOutputStream ); + + 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; + } + catch ( SAXException | ParserConfigurationException e ) + { + throw new TransformException( e ); + } + } + + @Override + public Artifact transformArtifact( Artifact artifact ) + { + return artifact; + } + } ); + } + return Collections.unmodifiableCollection( transformers ); + } + }; + } + private String getUserAgent() { return "Apache-Maven/" + getMavenVersion() + " (Java " + System.getProperty( "java.version" ) + "; " diff --git a/maven-core/src/main/java/org/apache/maven/xml/filter/BuildPomXMLFilter.java b/maven-core/src/main/java/org/apache/maven/xml/filter/BuildPomXMLFilter.java new file mode 100644 index 000000000000..60f0c4951d32 --- /dev/null +++ b/maven-core/src/main/java/org/apache/maven/xml/filter/BuildPomXMLFilter.java @@ -0,0 +1,44 @@ +package org.apache.maven.xml.filter; + +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +import org.xml.sax.XMLReader; +import org.xml.sax.helpers.XMLFilterImpl; + +/** + * Filter to adjust pom on filesystem before being processed for effective pom. + * + * @author Robert Scholte + * @since 3.7.0 + */ +public class BuildPomXMLFilter extends XMLFilterImpl +{ + public BuildPomXMLFilter() + { + super(); + } + + public BuildPomXMLFilter( XMLReader parent ) + { + super( parent ); + } + + +} diff --git a/maven-core/src/main/java/org/apache/maven/xml/filter/ConsumerPomXMLFilter.java b/maven-core/src/main/java/org/apache/maven/xml/filter/ConsumerPomXMLFilter.java new file mode 100644 index 000000000000..8709b9c0a15d --- /dev/null +++ b/maven-core/src/main/java/org/apache/maven/xml/filter/ConsumerPomXMLFilter.java @@ -0,0 +1,73 @@ +package org.apache.maven.xml.filter; + +/* + * 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 javax.xml.parsers.ParserConfigurationException; +import javax.xml.parsers.SAXParserFactory; + +import org.xml.sax.SAXException; +import org.xml.sax.XMLFilter; +import org.xml.sax.XMLReader; + +import org.xml.sax.helpers.XMLFilterImpl; + +/** + * XML Filter to transform pom.xml to consumer pom. + * This often means stripping of build-specific information. + * + * This filter is used at 2 locations: + * - {@link org.apache.maven.internal.aether.DefaultRepositorySystemSessionFactory} when publishing pom files. + * - TODO ???Class when a reactor module is used as dependency. This ensures consistency of dependency handling + * + * @author Robert Scholte + * @since 3.7.0 + */ +public class ConsumerPomXMLFilter extends XMLFilterImpl +{ + private final XMLFilter rootFilter; + + public ConsumerPomXMLFilter() throws SAXException, ParserConfigurationException + { + this( SAXParserFactory.newInstance().newSAXParser().getXMLReader() ); + } + + public ConsumerPomXMLFilter( XMLReader parent ) + { + rootFilter = new BuildPomXMLFilter( parent ); + + // Ensure that xs:any elements aren't touched by next filters + XMLFilter filter = new FastForwardFilter( rootFilter ); + + // Strip modules + filter = new ModulesXMLFilter( filter ); + // Adjust relativePath + filter = new RelativePathXMLFilter( filter ); + + // maybe more to follow + + super.setParent( filter ); + } + + @Override + public void setParent( XMLReader parent ) + { + rootFilter.setParent( parent ); + } +} diff --git a/maven-core/src/main/java/org/apache/maven/xml/filter/FastForwardFilter.java b/maven-core/src/main/java/org/apache/maven/xml/filter/FastForwardFilter.java new file mode 100644 index 000000000000..df68167a1394 --- /dev/null +++ b/maven-core/src/main/java/org/apache/maven/xml/filter/FastForwardFilter.java @@ -0,0 +1,128 @@ +package org.apache.maven.xml.filter; + +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +import java.util.ArrayDeque; +import java.util.Deque; + +import org.xml.sax.Attributes; +import org.xml.sax.ContentHandler; +import org.xml.sax.SAXException; +import org.xml.sax.XMLFilter; +import org.xml.sax.XMLReader; +import org.xml.sax.helpers.XMLFilterImpl; + +/** + * This filter will skip all following filters and write directly to the output. + * Should be used in case of a DOM that should not be effected by other filters, even though the elements match + * + * @author Robert Scholte + * @since 4.0.0 + */ +class FastForwardFilter extends XMLFilterImpl +{ + /** + * DOM elements of pom + * + *
        + *
      • execution.configuration
      • + *
      • plugin.configuration
      • + *
      • plugin.goals
      • + *
      • profile.reports
      • + *
      • project.reports
      • + *
      • reportSet.configuration
      • + *
          + */ + private final Deque state = new ArrayDeque<>(); + + private int domDepth = 0; + + private ContentHandler originalHandler; + + FastForwardFilter() + { + super(); + } + + FastForwardFilter( XMLReader parent ) + { + super( parent ); + } + + @Override + public void startElement( String uri, String localName, String qName, Attributes atts ) + throws SAXException + { + super.startElement( uri, localName, qName, atts ); + if ( domDepth > 0 ) + { + domDepth++; + } + else + { + final String key = state.peek() + '.' + localName; + switch ( key ) + { + case "execution.configuration": + case "plugin.configuration": + case "plugin.goals": + case "profile.reports": + case "project.reports": + case "reportSet.configuration": + domDepth++; + + originalHandler = getContentHandler(); + + ContentHandler outputContentHandler = getContentHandler(); + while ( outputContentHandler instanceof XMLFilter ) + { + outputContentHandler = ( (XMLFilter) outputContentHandler ).getContentHandler(); + } + setContentHandler( outputContentHandler ); + break; + default: + break; + } + state.push( localName ); + } + } + + @Override + public void endElement( String uri, String localName, String qName ) + throws SAXException + { + if ( domDepth > 0 ) + { + domDepth--; + + if ( domDepth == 0 ) + { + setContentHandler( originalHandler ); + } + } + else + { + state.pop(); + } + super.endElement( uri, localName, qName ); + } + + +} \ No newline at end of file diff --git a/maven-core/src/main/java/org/apache/maven/xml/filter/ModulesXMLFilter.java b/maven-core/src/main/java/org/apache/maven/xml/filter/ModulesXMLFilter.java new file mode 100644 index 000000000000..9e7b6fdbe5de --- /dev/null +++ b/maven-core/src/main/java/org/apache/maven/xml/filter/ModulesXMLFilter.java @@ -0,0 +1,102 @@ +package org.apache.maven.xml.filter; + +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +import org.xml.sax.Attributes; +import org.xml.sax.SAXException; +import org.xml.sax.XMLReader; +import org.xml.sax.helpers.XMLFilterImpl; + +/** + * Remove all modules, this is just buildtime information + * + * @author Robert Scholte + * @since 3.7.0 + */ +class ModulesXMLFilter + extends XMLFilterImpl +{ + /** + * Using 3 to also remove whitespace-block after closing tag + * -1 none + * 1 started + * 2 ended + */ + int modulesStatus = -1; + + ModulesXMLFilter() + { + super(); + } + + ModulesXMLFilter( XMLReader parent ) + { + super( parent ); + } + + @Override + public void startElement( String uri, String localName, String qName, Attributes atts ) + throws SAXException + { + if ( modulesStatus == -1 && "modules".equals( localName ) ) + { + modulesStatus = 1; + } + else if ( modulesStatus == 2 ) + { + modulesStatus = -1; + } + + if ( modulesStatus != 1 ) + { + super.startElement( uri, localName, qName, atts ); + } + } + + @Override + public void endElement( String uri, String localName, String qName ) + throws SAXException + { + if ( modulesStatus == 1 && "modules".equals( localName ) ) + { + modulesStatus = 2; + } + else if ( modulesStatus == 2 ) + { + modulesStatus = -1; + } + + if ( modulesStatus == -1 ) + { + super.endElement( uri, localName, qName ); + } + } + + @Override + public void characters( char[] ch, int start, int length ) + throws SAXException + { + if ( modulesStatus == -1 ) + { + super.characters( ch, start, length ); + } + } + +} diff --git a/maven-core/src/main/java/org/apache/maven/xml/filter/RelativePathXMLFilter.java b/maven-core/src/main/java/org/apache/maven/xml/filter/RelativePathXMLFilter.java new file mode 100644 index 000000000000..8548ddd73d9c --- /dev/null +++ b/maven-core/src/main/java/org/apache/maven/xml/filter/RelativePathXMLFilter.java @@ -0,0 +1,98 @@ +package org.apache.maven.xml.filter; + +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +import org.xml.sax.Attributes; +import org.xml.sax.SAXException; +import org.xml.sax.XMLReader; +import org.xml.sax.helpers.XMLFilterImpl; + +/** + * Remove content from relativePath + * + * TODO fix indentation of closing parent tag + * + * @author Robert Scholte + * @since 3.7.0 + */ +class RelativePathXMLFilter + extends XMLFilterImpl +{ + /** + * Using 3 to also remove whitespace-block after closing tag + * -1 none + * 1 started + * 2 ended + */ + int relativePathStatus = -1; + + RelativePathXMLFilter() + { + super(); + } + + RelativePathXMLFilter( XMLReader parent ) + { + super( parent ); + } + + @Override + public void startElement( String uri, String localName, String qName, Attributes atts ) + throws SAXException + { + if ( relativePathStatus == -1 && "relativePath".equals( localName ) ) + { + relativePathStatus = 1; + } + else if ( relativePathStatus == 2 ) + { + relativePathStatus = -1; + } + + super.startElement( uri, localName, qName, atts ); + } + + @Override + public void endElement( String uri, String localName, String qName ) + throws SAXException + { + if ( relativePathStatus == 1 && "relativePath".equals( localName ) ) + { + relativePathStatus = 2; + } + else if ( relativePathStatus == 2 ) + { + relativePathStatus = -1; + } + + super.endElement( uri, localName, qName ); + } + + @Override + public void characters( char[] ch, int start, int length ) + throws SAXException + { + if ( relativePathStatus != 1 ) + { + super.characters( ch, start, length ); + } + } + +} diff --git a/maven-core/src/test/java/org/apache/maven/xml/filter/AbstractXMLFilterTests.java b/maven-core/src/test/java/org/apache/maven/xml/filter/AbstractXMLFilterTests.java new file mode 100644 index 000000000000..69fc33ba8f59 --- /dev/null +++ b/maven-core/src/test/java/org/apache/maven/xml/filter/AbstractXMLFilterTests.java @@ -0,0 +1,80 @@ +package org.apache.maven.xml.filter; + +import java.io.Reader; + +/* + * 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.StringReader; +import java.io.StringWriter; +import java.io.Writer; + +import javax.xml.transform.OutputKeys; +import javax.xml.transform.Transformer; +import javax.xml.transform.TransformerException; +import javax.xml.transform.TransformerFactory; +import javax.xml.transform.sax.SAXSource; +import javax.xml.transform.stream.StreamResult; + +import org.xml.sax.InputSource; +import org.xml.sax.SAXException; +import org.xml.sax.XMLFilter; +import org.xml.sax.XMLReader; +import org.xml.sax.helpers.XMLReaderFactory; + +public class AbstractXMLFilterTests +{ + + public AbstractXMLFilterTests() + { + super(); + } + + protected String transform( String input, XMLFilter filter ) + throws TransformerException, SAXException + { + return transform( new StringReader( input ), filter ); + } + + protected String transform( Reader input, XMLFilter filter ) + throws TransformerException, SAXException + { + XMLReader reader = XMLReaderFactory.createXMLReader(); + + XMLFilter parent = filter; + while ( parent.getParent() instanceof XMLFilter ) + { + parent = (XMLFilter) parent.getParent(); + } + parent.setParent( reader ); + + Writer writer = new StringWriter(); + StreamResult result = new StreamResult( writer ); + + TransformerFactory transformerFactory = TransformerFactory.newInstance(); + Transformer transformer = transformerFactory.newTransformer(); + transformer.setOutputProperty( OutputKeys.OMIT_XML_DECLARATION, "yes" ); + + SAXSource transformSource = new SAXSource( filter, new InputSource( input ) ); + + transformer.transform( transformSource, result ); + + return writer.toString(); + } +} \ No newline at end of file diff --git a/maven-core/src/test/java/org/apache/maven/xml/filter/ConsumerPomXMLFilterTest.java b/maven-core/src/test/java/org/apache/maven/xml/filter/ConsumerPomXMLFilterTest.java new file mode 100644 index 000000000000..b3d44db91b6b --- /dev/null +++ b/maven-core/src/test/java/org/apache/maven/xml/filter/ConsumerPomXMLFilterTest.java @@ -0,0 +1,64 @@ +package org.apache.maven.xml.filter; + +/* + * 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 static org.xmlunit.assertj.XmlAssert.assertThat; + +import org.junit.Before; +import org.junit.Test; + +public class ConsumerPomXMLFilterTest extends AbstractXMLFilterTests +{ + private ConsumerPomXMLFilter filter; + + @Before + public void setup() throws Exception { + filter = new ConsumerPomXMLFilter(); + } + + @Test + public void testAllFilters() throws Exception { + String input = "\n" + + " \n" + + " GROUPID\n" + + " PARENT\n" + + " VERSION\n" + + " ../pom.xml\n" + + " \n" + + " PROJECT\n" + + " \n" + + " ab\n" + + " ../cd\n" + + " \n" + + ""; + String expected = "\n" + + " \n" + + " GROUPID\n" + + " PARENT\n" + + " VERSION\n" + + " \n" + + " \n" + + " PROJECT\n" + + ""; + String actual = transform( input, filter ); + assertThat( actual ).and( expected ).ignoreWhitespace().areIdentical(); + } + +} diff --git a/maven-core/src/test/java/org/apache/maven/xml/filter/ModulesXMLFilterTest.java b/maven-core/src/test/java/org/apache/maven/xml/filter/ModulesXMLFilterTest.java new file mode 100644 index 000000000000..353f1742d896 --- /dev/null +++ b/maven-core/src/test/java/org/apache/maven/xml/filter/ModulesXMLFilterTest.java @@ -0,0 +1,62 @@ +package org.apache.maven.xml.filter; + +/* + * 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 static org.xmlunit.assertj.XmlAssert.assertThat; + +import org.junit.Before; +import org.junit.Test; + +public class ModulesXMLFilterTest extends AbstractXMLFilterTests { + + private ModulesXMLFilter filter; + + @Before + public void setup() { + filter = new ModulesXMLFilter(); + } + + @Test + public void testEmptyModules() throws Exception { + String input = ""; + String expected = ""; + String actual = transform( input, filter ); + assertThat( actual ).and( expected ).areIdentical(); + } + + @Test + public void testSetOfModules() throws Exception { + String input = "" + + "ab" + + "../cd" + + ""; + String expected = ""; + String actual = transform( input, filter ); + assertThat( actual ).and( expected ).areIdentical(); + } + + @Test + public void testNoModules() throws Exception { + String input = "NAME"; + String expected = input; + String actual = transform( input, filter ); + assertThat( actual ).and( expected ).areIdentical(); + } +} diff --git a/maven-core/src/test/java/org/apache/maven/xml/filter/RelativePathXMLFilterTest.java b/maven-core/src/test/java/org/apache/maven/xml/filter/RelativePathXMLFilterTest.java new file mode 100644 index 000000000000..298197dd1c81 --- /dev/null +++ b/maven-core/src/test/java/org/apache/maven/xml/filter/RelativePathXMLFilterTest.java @@ -0,0 +1,61 @@ +package org.apache.maven.xml.filter; + +import static org.xmlunit.assertj.XmlAssert.assertThat; + +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +import org.junit.Before; +import org.junit.Test; + +public class RelativePathXMLFilterTest extends AbstractXMLFilterTests +{ + private RelativePathXMLFilter filter; + + @Before + public void setup() { + filter = new RelativePathXMLFilter(); + } + + @Test + public void testRelativePath() throws Exception + { + String input = "\n" + + " \n" + + " GROUPID\n" + + " PARENT\n" + + " VERSION\n" + + " ../pom.xml\n" + + " \n" + + " PROJECT\n" + + ""; + String expected = "\n" + + " \n" + + " GROUPID\n" + + " PARENT\n" + + " VERSION\n" + + " \n" + + " \n" + + " PROJECT\n" + + ""; + String actual = transform( input, filter ); + assertThat( actual ).and( expected ).areIdentical(); + } + +} diff --git a/pom.xml b/pom.xml index c3f4bcbdaaf8..967785678438 100644 --- a/pom.xml +++ b/pom.xml @@ -66,7 +66,7 @@ under the License. 1.3 1.3.3 1.7.25 - 2.2.1 + 2.6.2 true apache-maven @@ -406,6 +406,12 @@ under the License. ${mockitoVersion} test + + org.xmlunit + xmlunit-assertj + ${xmlunitVersion} + test + org.xmlunit xmlunit-core From 79c4813558486fcedcdd902f8f3188591c747a21 Mon Sep 17 00:00:00 2001 From: rfscholte Date: Sat, 1 Jun 2019 19:08:21 +0200 Subject: [PATCH 03/52] [MNG-6656] separate module for maven-xml, maven-model-builder doesn't depend on maven-core --- maven-core/pom.xml | 4 + ...DefaultRepositorySystemSessionFactory.java | 53 ++++----- maven-model-builder/pom.xml | 6 +- .../model/building/DefaultModelBuilder.java | 15 ++- maven-xml/pom.xml | 62 ++++++++++ .../java/org/apache/maven/xml/SAXEvent.java | 34 ++++++ .../org/apache/maven/xml/SAXEventFactory.java | 111 ++++++++++++++++++ .../org/apache/maven/xml/SAXEventUtils.java | 38 ++++++ .../maven/xml/filter/BuildPomXMLFilter.java | 11 +- .../xml/filter/ConsumerPomXMLFilter.java | 23 +++- .../maven/xml/filter/FastForwardFilter.java | 0 .../maven/xml/filter/ModulesXMLFilter.java | 0 .../xml/filter/RelativePathXMLFilter.java | 0 .../xml/filter/AbstractXMLFilterTests.java | 0 .../xml/filter/ConsumerPomXMLFilterTest.java | 0 .../xml/filter/ModulesXMLFilterTest.java | 0 .../xml/filter/RelativePathXMLFilterTest.java | 0 pom.xml | 27 +++++ 18 files changed, 337 insertions(+), 47 deletions(-) create mode 100644 maven-xml/pom.xml create mode 100644 maven-xml/src/main/java/org/apache/maven/xml/SAXEvent.java create mode 100644 maven-xml/src/main/java/org/apache/maven/xml/SAXEventFactory.java create mode 100644 maven-xml/src/main/java/org/apache/maven/xml/SAXEventUtils.java rename {maven-core => maven-xml}/src/main/java/org/apache/maven/xml/filter/BuildPomXMLFilter.java (85%) rename {maven-core => maven-xml}/src/main/java/org/apache/maven/xml/filter/ConsumerPomXMLFilter.java (79%) rename {maven-core => maven-xml}/src/main/java/org/apache/maven/xml/filter/FastForwardFilter.java (100%) rename {maven-core => maven-xml}/src/main/java/org/apache/maven/xml/filter/ModulesXMLFilter.java (100%) rename {maven-core => maven-xml}/src/main/java/org/apache/maven/xml/filter/RelativePathXMLFilter.java (100%) rename {maven-core => maven-xml}/src/test/java/org/apache/maven/xml/filter/AbstractXMLFilterTests.java (100%) rename {maven-core => maven-xml}/src/test/java/org/apache/maven/xml/filter/ConsumerPomXMLFilterTest.java (100%) rename {maven-core => maven-xml}/src/test/java/org/apache/maven/xml/filter/ModulesXMLFilterTest.java (100%) rename {maven-core => maven-xml}/src/test/java/org/apache/maven/xml/filter/RelativePathXMLFilterTest.java (100%) diff --git a/maven-core/pom.xml b/maven-core/pom.xml index e467851442b5..79dc86e2600f 100644 --- a/maven-core/pom.xml +++ b/maven-core/pom.xml @@ -60,6 +60,10 @@ under the License. org.apache.maven maven-artifact + + org.apache.maven + maven-xml + org.apache.maven maven-plugin-api diff --git a/maven-core/src/main/java/org/apache/maven/internal/aether/DefaultRepositorySystemSessionFactory.java b/maven-core/src/main/java/org/apache/maven/internal/aether/DefaultRepositorySystemSessionFactory.java index 792b08544784..5ee55255d033 100644 --- a/maven-core/src/main/java/org/apache/maven/internal/aether/DefaultRepositorySystemSessionFactory.java +++ b/maven-core/src/main/java/org/apache/maven/internal/aether/DefaultRepositorySystemSessionFactory.java @@ -34,7 +34,6 @@ import javax.inject.Inject; import javax.inject.Named; -import javax.xml.parsers.ParserConfigurationException; import javax.xml.transform.TransformerException; import javax.xml.transform.TransformerFactory; import javax.xml.transform.sax.SAXSource; @@ -77,7 +76,6 @@ import org.eclipse.aether.util.repository.SimpleResolutionErrorPolicy; import org.eclipse.sisu.Nullable; import org.xml.sax.InputSource; -import org.xml.sax.SAXException; /** * @since 3.3.0 @@ -283,41 +281,34 @@ public Collection getTransformersForArtifact( Artifact artifact public InputStream transformData( File file ) throws IOException, TransformException { - try + final PipedOutputStream pipedOutputStream = new PipedOutputStream(); + final PipedInputStream pipedInputStream = new PipedInputStream( pipedOutputStream ); + + final SAXSource transformSource = + new SAXSource( new ConsumerPomXMLFilter( null /* @TODO bass BuildPomXMLFilter */ ), + new InputSource( new FileReader( file ) ) ); + + final StreamResult result = new StreamResult( pipedOutputStream ); + + final Runnable runnable = new Runnable() { - final PipedOutputStream pipedOutputStream = new PipedOutputStream(); - final PipedInputStream pipedInputStream = new PipedInputStream( pipedOutputStream ); - - final SAXSource transformSource = - new SAXSource( new ConsumerPomXMLFilter(), - new InputSource( new FileReader( file ) ) ); - - final StreamResult result = new StreamResult( pipedOutputStream ); - - final Runnable runnable = new Runnable() + @Override + public void run() { - @Override - public void run() + try ( PipedOutputStream out = pipedOutputStream ) { - try ( PipedOutputStream out = pipedOutputStream ) - { - transformerFactory.newTransformer().transform( transformSource, result ); - } - catch ( TransformerException | IOException e ) - { - throw new RuntimeException( e ); - } + transformerFactory.newTransformer().transform( transformSource, result ); } - }; + catch ( TransformerException | IOException e ) + { + throw new RuntimeException( e ); + } + } + }; - new Thread( runnable ).start(); + new Thread( runnable ).start(); - return pipedInputStream; - } - catch ( SAXException | ParserConfigurationException e ) - { - throw new TransformException( e ); - } + return pipedInputStream; } @Override diff --git a/maven-model-builder/pom.xml b/maven-model-builder/pom.xml index 9a85016fbeaf..0f10fa927670 100644 --- a/maven-model-builder/pom.xml +++ b/maven-model-builder/pom.xml @@ -58,6 +58,11 @@ under the License. org.apache.maven maven-builder-support + + org.apache.maven + maven-xml + + org.eclipse.sisu org.eclipse.sisu.inject @@ -67,7 +72,6 @@ under the License. org.eclipse.sisu.plexus test - com.google.inject guice 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 f981944f940f..7022781e6e04 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 @@ -549,6 +549,7 @@ private Model readModel( ModelSource modelSource, File pomFile, ModelBuildingReq try { + // RFS adjust inputstream model = modelProcessor.read( modelSource.getInputStream(), options ); } catch ( ModelParseException e ) @@ -733,12 +734,24 @@ private void checkPluginVersions( List lineage, ModelBuildingRequest private void assembleInheritance( List lineage, ModelBuildingRequest request, ModelProblemCollector problems ) { - for ( int i = lineage.size() - 2; i >= 0; i-- ) + for ( int i = lineage.size() - 2; i >= 1; i-- ) { Model parent = lineage.get( i + 1 ).getModel(); Model child = lineage.get( i ).getModel(); inheritanceAssembler.assembleModelInheritance( child, parent, request, problems ); } + + // re-read model from file + if ( Boolean.getBoolean( "maven.experimental.buildconsumer" ) ) + { + throw new UnsupportedOperationException(); + } + else + { + Model parent = lineage.get( 1 ).getModel(); + Model child = lineage.get( 0 ).getModel(); + inheritanceAssembler.assembleModelInheritance( child, parent, request, problems ); + } } private Map getProfileActivations( Model model, boolean clone ) diff --git a/maven-xml/pom.xml b/maven-xml/pom.xml new file mode 100644 index 000000000000..aeef99eab9ec --- /dev/null +++ b/maven-xml/pom.xml @@ -0,0 +1,62 @@ + + + + + + 4.0.0 + + org.apache.maven + maven + 3.6.2-SNAPSHOT + + maven-xml + Maven XML + + + 1.8 + 1.8 + + + + + + org.codehaus.mojo + animal-sniffer-maven-plugin + + + org.codehaus.mojo.signature + java18 + 1.0 + + + + + + + + + org.xmlunit + xmlunit-assertj + test + + + \ No newline at end of file diff --git a/maven-xml/src/main/java/org/apache/maven/xml/SAXEvent.java b/maven-xml/src/main/java/org/apache/maven/xml/SAXEvent.java new file mode 100644 index 000000000000..07da2808b4a0 --- /dev/null +++ b/maven-xml/src/main/java/org/apache/maven/xml/SAXEvent.java @@ -0,0 +1,34 @@ +package org.apache.maven.xml; + +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +import org.xml.sax.SAXException; + +/** + * Command pattern to gather events which can be executed later on. + * + * @author Robert Scholte + * @since + */ +@FunctionalInterface +public interface SAXEvent +{ + void execute() throws SAXException; +} diff --git a/maven-xml/src/main/java/org/apache/maven/xml/SAXEventFactory.java b/maven-xml/src/main/java/org/apache/maven/xml/SAXEventFactory.java new file mode 100644 index 000000000000..42739e120bbb --- /dev/null +++ b/maven-xml/src/main/java/org/apache/maven/xml/SAXEventFactory.java @@ -0,0 +1,111 @@ +package org.apache.maven.xml; + +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +import org.xml.sax.Attributes; +import org.xml.sax.ContentHandler; +import org.xml.sax.Locator; + +/** + * Factory for SAXEvents + * + * @author Robert Scholte + * @since 4.0.0 + */ +public final class SAXEventFactory +{ + private final ContentHandler contentHandler; + + protected SAXEventFactory( ContentHandler contentHandler ) + { + this.contentHandler = contentHandler; + } + + public SAXEvent characters( final char[] ch, final int start, final int length ) + { + final char[] txt; + if ( start > 0 ) + { + txt = new char[length]; + System.arraycopy( ch, start, txt, 0, length ); + } + else + { + txt = ch; + } + + return () -> contentHandler.characters( txt, 0, length ); + } + + public SAXEvent endDocument() + { + return () -> contentHandler.endDocument(); + } + + public SAXEvent endElement( final String uri, final String localName, final String qName ) + { + return () -> contentHandler.endElement( uri, localName, qName ); + } + + public SAXEvent endPrefixMapping( final String prefix ) + { + return () -> contentHandler.endPrefixMapping( prefix ); + } + + public SAXEvent ignorableWhitespace( final char[] ch, final int start, final int length ) + { + return () -> contentHandler.ignorableWhitespace( ch, start, length ); + } + + public SAXEvent processingInstruction( final String target, final String data ) + { + return () -> contentHandler.processingInstruction( target, data ); + } + + public SAXEvent setDocumentLocator( final Locator locator ) + { + return () -> contentHandler.setDocumentLocator( locator ); + } + + public SAXEvent skippedEntity( final String name ) + { + return () -> contentHandler.skippedEntity( name ); + } + + public SAXEvent startDocument() + { + return () -> contentHandler.startDocument(); + } + + public SAXEvent startElement( final String uri, final String localName, final String qName, final Attributes atts ) + { + return () -> contentHandler.startElement( uri, localName, qName, atts ); + } + + public SAXEvent startPrefixMapping( final String prefix, final String uri ) + { + return () -> contentHandler.startPrefixMapping( prefix, uri ); + } + + public static SAXEventFactory newInstance( ContentHandler handler ) + { + return new SAXEventFactory( handler ); + } +} diff --git a/maven-xml/src/main/java/org/apache/maven/xml/SAXEventUtils.java b/maven-xml/src/main/java/org/apache/maven/xml/SAXEventUtils.java new file mode 100644 index 000000000000..06f4f26d98d9 --- /dev/null +++ b/maven-xml/src/main/java/org/apache/maven/xml/SAXEventUtils.java @@ -0,0 +1,38 @@ +package org.apache.maven.xml; + +/* + * 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. + */ + +/** + * Utility class for SAXEvents + * + * @author Robert Scholte + * @since 4.0.0 + */ +public final class SAXEventUtils +{ + private SAXEventUtils() + { + } + + public static String renameQName( String oldQName, String newLocalName ) + { + return oldQName.replaceFirst( "[^:]+$", newLocalName ); + } +} diff --git a/maven-core/src/main/java/org/apache/maven/xml/filter/BuildPomXMLFilter.java b/maven-xml/src/main/java/org/apache/maven/xml/filter/BuildPomXMLFilter.java similarity index 85% rename from maven-core/src/main/java/org/apache/maven/xml/filter/BuildPomXMLFilter.java rename to maven-xml/src/main/java/org/apache/maven/xml/filter/BuildPomXMLFilter.java index 60f0c4951d32..58d219b29657 100644 --- a/maven-core/src/main/java/org/apache/maven/xml/filter/BuildPomXMLFilter.java +++ b/maven-xml/src/main/java/org/apache/maven/xml/filter/BuildPomXMLFilter.java @@ -19,7 +19,6 @@ * under the License. */ -import org.xml.sax.XMLReader; import org.xml.sax.helpers.XMLFilterImpl; /** @@ -30,15 +29,7 @@ */ public class BuildPomXMLFilter extends XMLFilterImpl { - public BuildPomXMLFilter() - { - super(); - } - - public BuildPomXMLFilter( XMLReader parent ) - { - super( parent ); - } + } diff --git a/maven-core/src/main/java/org/apache/maven/xml/filter/ConsumerPomXMLFilter.java b/maven-xml/src/main/java/org/apache/maven/xml/filter/ConsumerPomXMLFilter.java similarity index 79% rename from maven-core/src/main/java/org/apache/maven/xml/filter/ConsumerPomXMLFilter.java rename to maven-xml/src/main/java/org/apache/maven/xml/filter/ConsumerPomXMLFilter.java index 8709b9c0a15d..a367419fb948 100644 --- a/maven-core/src/main/java/org/apache/maven/xml/filter/ConsumerPomXMLFilter.java +++ b/maven-xml/src/main/java/org/apache/maven/xml/filter/ConsumerPomXMLFilter.java @@ -31,6 +31,7 @@ /** * XML Filter to transform pom.xml to consumer pom. * This often means stripping of build-specific information. + * When extra information is required during filtering it is probably a member of the BuildPomXMLFilter * * This filter is used at 2 locations: * - {@link org.apache.maven.internal.aether.DefaultRepositorySystemSessionFactory} when publishing pom files. @@ -43,15 +44,29 @@ public class ConsumerPomXMLFilter extends XMLFilterImpl { private final XMLFilter rootFilter; - public ConsumerPomXMLFilter() throws SAXException, ParserConfigurationException + // only for testing purpose + ConsumerPomXMLFilter() throws SAXException, ParserConfigurationException { this( SAXParserFactory.newInstance().newSAXParser().getXMLReader() ); } - - public ConsumerPomXMLFilter( XMLReader parent ) + + // only for testing purpose + ConsumerPomXMLFilter( XMLReader parent ) { - rootFilter = new BuildPomXMLFilter( parent ); + this.rootFilter = new XMLFilterImpl( parent ); + applyFilters(); + } + + public ConsumerPomXMLFilter( BuildPomXMLFilter buildPomXMLFilter ) + { + this.rootFilter = buildPomXMLFilter; + + applyFilters(); + } + + private void applyFilters() + { // Ensure that xs:any elements aren't touched by next filters XMLFilter filter = new FastForwardFilter( rootFilter ); diff --git a/maven-core/src/main/java/org/apache/maven/xml/filter/FastForwardFilter.java b/maven-xml/src/main/java/org/apache/maven/xml/filter/FastForwardFilter.java similarity index 100% rename from maven-core/src/main/java/org/apache/maven/xml/filter/FastForwardFilter.java rename to maven-xml/src/main/java/org/apache/maven/xml/filter/FastForwardFilter.java diff --git a/maven-core/src/main/java/org/apache/maven/xml/filter/ModulesXMLFilter.java b/maven-xml/src/main/java/org/apache/maven/xml/filter/ModulesXMLFilter.java similarity index 100% rename from maven-core/src/main/java/org/apache/maven/xml/filter/ModulesXMLFilter.java rename to maven-xml/src/main/java/org/apache/maven/xml/filter/ModulesXMLFilter.java diff --git a/maven-core/src/main/java/org/apache/maven/xml/filter/RelativePathXMLFilter.java b/maven-xml/src/main/java/org/apache/maven/xml/filter/RelativePathXMLFilter.java similarity index 100% rename from maven-core/src/main/java/org/apache/maven/xml/filter/RelativePathXMLFilter.java rename to maven-xml/src/main/java/org/apache/maven/xml/filter/RelativePathXMLFilter.java diff --git a/maven-core/src/test/java/org/apache/maven/xml/filter/AbstractXMLFilterTests.java b/maven-xml/src/test/java/org/apache/maven/xml/filter/AbstractXMLFilterTests.java similarity index 100% rename from maven-core/src/test/java/org/apache/maven/xml/filter/AbstractXMLFilterTests.java rename to maven-xml/src/test/java/org/apache/maven/xml/filter/AbstractXMLFilterTests.java diff --git a/maven-core/src/test/java/org/apache/maven/xml/filter/ConsumerPomXMLFilterTest.java b/maven-xml/src/test/java/org/apache/maven/xml/filter/ConsumerPomXMLFilterTest.java similarity index 100% rename from maven-core/src/test/java/org/apache/maven/xml/filter/ConsumerPomXMLFilterTest.java rename to maven-xml/src/test/java/org/apache/maven/xml/filter/ConsumerPomXMLFilterTest.java diff --git a/maven-core/src/test/java/org/apache/maven/xml/filter/ModulesXMLFilterTest.java b/maven-xml/src/test/java/org/apache/maven/xml/filter/ModulesXMLFilterTest.java similarity index 100% rename from maven-core/src/test/java/org/apache/maven/xml/filter/ModulesXMLFilterTest.java rename to maven-xml/src/test/java/org/apache/maven/xml/filter/ModulesXMLFilterTest.java diff --git a/maven-core/src/test/java/org/apache/maven/xml/filter/RelativePathXMLFilterTest.java b/maven-xml/src/test/java/org/apache/maven/xml/filter/RelativePathXMLFilterTest.java similarity index 100% rename from maven-core/src/test/java/org/apache/maven/xml/filter/RelativePathXMLFilterTest.java rename to maven-xml/src/test/java/org/apache/maven/xml/filter/RelativePathXMLFilterTest.java diff --git a/pom.xml b/pom.xml index 967785678438..da0b9de53f2e 100644 --- a/pom.xml +++ b/pom.xml @@ -92,6 +92,7 @@ under the License. maven-embedder maven-compat apache-maven + maven-xml @@ -229,6 +230,11 @@ under the License. maven-slf4j-provider ${project.version} + + org.apache.maven + maven-xml + ${project.version} + @@ -442,6 +448,27 @@ under the License. + + org.apache.maven.plugins + maven-enforcer-plugin + + + enforce-bytecode-version + + enforce + + + + + + org.apache.maven:maven-xml + + + + + + + org.codehaus.plexus plexus-component-metadata From eeea0bb98c1d4d205914c5acaf85d0b620b01c0a Mon Sep 17 00:00:00 2001 From: Stefan Oehme Date: Tue, 23 Jul 2019 12:25:34 +0200 Subject: [PATCH 04/52] [MNG-6720] MultiThreadedBuilder: wait for parallel running projects when using --fail-fast Otherwise the sessionFinished event may be sent before some projects/goals finish, which violates the contracts of execution listeners and makes it hard to properly life cycle components that are needed for goal execution. This closes #272 --- .../multithreaded/MultiThreadedBuilder.java | 20 ++++--------------- 1 file changed, 4 insertions(+), 16 deletions(-) diff --git a/maven-core/src/main/java/org/apache/maven/lifecycle/internal/builder/multithreaded/MultiThreadedBuilder.java b/maven-core/src/main/java/org/apache/maven/lifecycle/internal/builder/multithreaded/MultiThreadedBuilder.java index bfbfb0260a29..94d10af4b44c 100644 --- a/maven-core/src/main/java/org/apache/maven/lifecycle/internal/builder/multithreaded/MultiThreadedBuilder.java +++ b/maven-core/src/main/java/org/apache/maven/lifecycle/internal/builder/multithreaded/MultiThreadedBuilder.java @@ -27,7 +27,7 @@ import java.util.concurrent.ExecutorCompletionService; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; -import java.util.concurrent.Future; +import java.util.concurrent.TimeUnit; import org.apache.maven.execution.MavenSession; import org.apache.maven.lifecycle.internal.BuildThreadFactory; @@ -114,6 +114,9 @@ public void build( MavenSession session, ReactorContext reactorContext, ProjectB } } + + executor.shutdown(); + executor.awaitTermination( Long.MAX_VALUE, TimeUnit.MILLISECONDS ); } private void multiThreadedProjectTaskSegmentBuild( ConcurrencyDependencyGraph analyzer, @@ -172,21 +175,6 @@ private void multiThreadedProjectTaskSegmentBuild( ConcurrencyDependencyGraph an break; } } - - // cancel outstanding builds (if any) - this can happen if an exception is thrown in above block - - Future unprocessed; - while ( ( unprocessed = service.poll() ) != null ) - { - try - { - unprocessed.get(); - } - catch ( InterruptedException | ExecutionException e ) - { - throw new RuntimeException( e ); - } - } } private Callable createBuildCallable( final MavenSession rootSession, From 144076c00c0b82026ddf028844169861e9b7d172 Mon Sep 17 00:00:00 2001 From: tibordigana Date: Tue, 30 Jul 2019 11:52:43 +0200 Subject: [PATCH 05/52] [MNG-6725] Skip '.mavenrc' via MAVEN_SKIP_RC=1 and '-Dmaven.skip.rc=true' on child ITs (by default on Jenkins CI). --- Jenkinsfile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Jenkinsfile b/Jenkinsfile index b9e510dae4e2..af9a395c4144 100644 --- a/Jenkinsfile +++ b/Jenkinsfile @@ -100,7 +100,7 @@ for (String os in runITsOses) { withMaven(jdk: jdkName, maven: mvnName, mavenLocalRepo:"${WORK_DIR}/it-local-repo", options:[ junitPublisher(ignoreAttachments: false) ]) { - String cmd = "${runITscommand} -DmavenDistro=$WORK_DIR/apache-maven-dist.zip -Dmaven.test.failure.ignore=true" + String cmd = "${runITscommand} -DmavenDistro=$WORK_DIR/apache-maven-dist.zip -Dmaven.test.failure.ignore=true -Dmaven.skip.rc=true" if (stageId.endsWith('-jdk7')) { // Java 7u80 has TLS 1.2 disabled by default: need to explicitly enable cmd = "${cmd} -Dhttps.protocols=TLSv1.2" From b9c7c4af6e2e93e2d0ac500d4dcc720e26fe217d Mon Sep 17 00:00:00 2001 From: tibordigana Date: Wed, 31 Jul 2019 17:22:07 +0200 Subject: [PATCH 06/52] IT archives --- Jenkinsfile | 43 +++++++++++++++++++++++++++++-------------- 1 file changed, 29 insertions(+), 14 deletions(-) diff --git a/Jenkinsfile b/Jenkinsfile index af9a395c4144..0998f02f8b2d 100644 --- a/Jenkinsfile +++ b/Jenkinsfile @@ -97,22 +97,29 @@ for (String os in runITsOses) { bat "if exist apache-maven-dist.zip del /q apache-maven-dist.zip" } unstash 'dist' - withMaven(jdk: jdkName, maven: mvnName, mavenLocalRepo:"${WORK_DIR}/it-local-repo", options:[ - junitPublisher(ignoreAttachments: false) - ]) { - String cmd = "${runITscommand} -DmavenDistro=$WORK_DIR/apache-maven-dist.zip -Dmaven.test.failure.ignore=true -Dmaven.skip.rc=true" - if (stageId.endsWith('-jdk7')) { - // Java 7u80 has TLS 1.2 disabled by default: need to explicitly enable - cmd = "${cmd} -Dhttps.protocols=TLSv1.2" - } - - if (isUnix()) { - sh "${cmd}" - } else { - bat "${cmd}" + try { + withMaven(jdk: jdkName, maven: mvnName, mavenLocalRepo:"${WORK_DIR}/it-local-repo", options:[ + junitPublisher(ignoreAttachments: false) + ]) { + String cmd = "${runITscommand} -DmavenDistro=$WORK_DIR/apache-maven-dist.zip -Dmaven.test.failure.ignore=true -Dmaven.skip.rc=true" + if (stageId.endsWith('-jdk7')) { + // Java 7u80 has TLS 1.2 disabled by default: need to explicitly enable + cmd = "${cmd} -Dhttps.protocols=TLSv1.2" + } + + if (isUnix()) { + sh 'df -hT' + sh "${cmd}" + } else { + bat 'wmic logicaldisk get size,freespace,caption' + bat "${cmd}" + } } + } finally { + archiveDirs(stageId, ['core-it-suite-logs':'core-it-suite/target/test-classes', + 'core-it-suite-reports':'core-it-suite/target/surefire-reports']) + deleteDir() // clean up after ourselves to reduce disk space } - deleteDir() // clean up after ourselves to reduce disk space } } } @@ -156,3 +163,11 @@ parallel(runITsTasks) jenkinsNotify() } } + +def archiveDirs(stageId, archives) { + archives.each { archivePrefix, pathToContent -> + if (fileExists(pathToContent)) { + zip(zipFile: "${archivePrefix}-${stageId}.zip", dir: pathToContent, archive: true) + } + } +} From 5822ea7a4fe2ca50524a939fe5260f7c35e3054d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Herv=C3=A9=20Boutemy?= Date: Mon, 5 Aug 2019 13:12:08 +0100 Subject: [PATCH 07/52] improved handlers documentation: artifact vs dependency attributes --- maven-core/src/site/apt/artifact-handlers.apt | 53 ++++++++++--------- 1 file changed, 27 insertions(+), 26 deletions(-) diff --git a/maven-core/src/site/apt/artifact-handlers.apt b/maven-core/src/site/apt/artifact-handlers.apt index f79c5a065edb..299d7d821218 100644 --- a/maven-core/src/site/apt/artifact-handlers.apt +++ b/maven-core/src/site/apt/artifact-handlers.apt @@ -26,33 +26,34 @@ Default Artifact Handlers Reference Artifact handlers (see {{{../maven-artifact/apidocs/org/apache/maven/artifact/handler/ArtifactHandler.html} API}}) - define for each {{{../maven-model/maven.html#class_dependency}dependency type}} information on the artifact. + define for each {{{../maven-model/maven.html#class_dependency}dependency type}} information on the artifact + (classifier, extension, language) and how to manage it as dependency (add to classpath, include dependencies). Some artifact handlers are configured by default in <<>>: -*--------------------+------------+------------+---------------+-----------+---------------------+-----------------------+ -|| type || extension || packaging || classifier || language || added to classpath || includesDependencies || -*--------------------+------------+------------+---------------+-----------+---------------------+-----------------------+ -| <<>> | <= type> | <= type> | | none | | | -*--------------------+------------+------------+---------------+-----------+---------------------+-----------------------+ -| <<>> | <= type> | <= type> | | java | <<>> | | -*--------------------+------------+------------+---------------+-----------+---------------------+-----------------------+ -| <<>> | <<>> | <<>> | <<>> | java | <<>> | | -*--------------------+------------+------------+---------------+-----------+---------------------+-----------------------+ -| <<>> | <<>> | <= type> | | java | <<>> | | -*--------------------+------------+------------+---------------+-----------+---------------------+-----------------------+ -| <<>> | <<>> | <= type> | | java | <<>> | | -*--------------------+------------+------------+---------------+-----------+---------------------+-----------------------+ -| <<>> | <<>> | <<>> | <<>> | java | <<>> | | -*--------------------+------------+------------+---------------+-----------+---------------------+-----------------------+ -| <<>> | <= type> | <= type> | | java | | <<>> | -*--------------------+------------+------------+---------------+-----------+---------------------+-----------------------+ -| <<>> | <= type> | <= type> | | java | | <<>> | -*--------------------+------------+------------+---------------+-----------+---------------------+-----------------------+ -| <<>> | <= type> | <= type> | | java | | <<>> | -*--------------------+------------+------------+---------------+-----------+---------------------+-----------------------+ -| <<>> | <<>> | <= type> | <<>> | java | | | -*--------------------+------------+------------+---------------+-----------+---------------------+-----------------------+ -| <<>> | <<>> | <= type> | <<>> | java | <<>> | | -*--------------------+------------+------------+---------------+-----------+---------------------+-----------------------+ +*--------------------+---------------+------------+------------+-----------+---------------------+-----------------------+ +|| type || classifier || extension || packaging || language || added to classpath || includesDependencies || +*--------------------+---------------+------------+------------+-----------+---------------------+-----------------------+ +| <<>> | | <= type> | <= type> | none | | | +*--------------------+---------------+------------+------------+-----------+---------------------+-----------------------+ +| <<>> | | <= type> | <= type> | java | <<>> | | +*--------------------+---------------+------------+------------+-----------+---------------------+-----------------------+ +| <<>> | <<>> | <<>> | <<>> | java | <<>> | | +*--------------------+---------------+------------+------------+-----------+---------------------+-----------------------+ +| <<>> | | <<>> | <= type> | java | <<>> | | +*--------------------+---------------+------------+------------+-----------+---------------------+-----------------------+ +| <<>> | | <<>> | <= type> | java | <<>> | | +*--------------------+---------------+------------+------------+-----------+---------------------+-----------------------+ +| <<>> | <<>> | <<>> | <<>> | java | <<>> | | +*--------------------+---------------+------------+------------+-----------+---------------------+-----------------------+ +| <<>> | | <= type> | <= type> | java | | <<>> | +*--------------------+---------------+------------+------------+-----------+---------------------+-----------------------+ +| <<>> | | <= type> | <= type> | java | | <<>> | +*--------------------+---------------+------------+------------+-----------+---------------------+-----------------------+ +| <<>> | | <= type> | <= type> | java | | <<>> | +*--------------------+---------------+------------+------------+-----------+---------------------+-----------------------+ +| <<>> | <<>> | <<>> | <= type> | java | | | +*--------------------+---------------+------------+------------+-----------+---------------------+-----------------------+ +| <<>> | <<>> | <<>> | <= type> | java | <<>> | | +*--------------------+---------------+------------+------------+-----------+---------------------+-----------------------+ From 01972483e14ba5b2e2e8ccd159ecca89145a6418 Mon Sep 17 00:00:00 2001 From: rfscholte Date: Mon, 5 Aug 2019 18:43:09 +0200 Subject: [PATCH 08/52] [INFRA-18812] Revert unnecessary commits after fixing INFRA-18812 --- Jenkinsfile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Jenkinsfile b/Jenkinsfile index 0998f02f8b2d..5d5d998c0398 100644 --- a/Jenkinsfile +++ b/Jenkinsfile @@ -101,7 +101,7 @@ for (String os in runITsOses) { withMaven(jdk: jdkName, maven: mvnName, mavenLocalRepo:"${WORK_DIR}/it-local-repo", options:[ junitPublisher(ignoreAttachments: false) ]) { - String cmd = "${runITscommand} -DmavenDistro=$WORK_DIR/apache-maven-dist.zip -Dmaven.test.failure.ignore=true -Dmaven.skip.rc=true" + String cmd = "${runITscommand} -DmavenDistro=$WORK_DIR/apache-maven-dist.zip -Dmaven.test.failure.ignore=true" if (stageId.endsWith('-jdk7')) { // Java 7u80 has TLS 1.2 disabled by default: need to explicitly enable cmd = "${cmd} -Dhttps.protocols=TLSv1.2" From 297a6b72a18fc97fe139393c7ffbe6900b6ed802 Mon Sep 17 00:00:00 2001 From: tibordigana Date: Mon, 5 Aug 2019 23:38:16 +0200 Subject: [PATCH 09/52] fixed ArtifactHandlerTest after commit d5b0f4ce --- .../maven/artifact/handler/ArtifactHandlerTest.java | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/maven-core/src/test/java/org/apache/maven/artifact/handler/ArtifactHandlerTest.java b/maven-core/src/test/java/org/apache/maven/artifact/handler/ArtifactHandlerTest.java index ac02e106d318..69f59fdb364e 100644 --- a/maven-core/src/test/java/org/apache/maven/artifact/handler/ArtifactHandlerTest.java +++ b/maven-core/src/test/java/org/apache/maven/artifact/handler/ArtifactHandlerTest.java @@ -42,7 +42,7 @@ public void testAptConsistency() { String[] cols = line.split( "\\|\\|" ); String[] expected = - new String[] { "", "type", "extension", "packaging", "classifier", "language", "added to classpath", + new String[] { "", "type", "classifier", "extension", "packaging", "language", "added to classpath", "includesDependencies", "" }; int i = 0; @@ -56,9 +56,9 @@ else if ( line.startsWith( "|" ) ) String[] cols = line.split( "\\|" ); String type = trimApt( cols[1] ); - String extension = trimApt( cols[2], type ); - String packaging = trimApt( cols[3], type ); - String classifier = trimApt( cols[4] ); + String classifier = trimApt( cols[2] ); + String extension = trimApt( cols[3], type ); + String packaging = trimApt( cols[4], type ); String language = trimApt( cols[5] ); String addedToClasspath = trimApt( cols[6] ); String includesDependencies = trimApt( cols[7] ); From e6240d586c89442aa8732711ede859f08cae5fa7 Mon Sep 17 00:00:00 2001 From: Ray Tsang Date: Tue, 6 Aug 2019 09:18:58 -0700 Subject: [PATCH 10/52] [MNG-6713] Fix ExclusionArtifactFilter to respect wildcard exclusions. (#269) * [MNG-6713] Fix ExclusionArtifactFilter to respect wildcard exclusions. * Moved `*` to a constant --- .../filter/ExclusionArtifactFilter.java | 24 +++- .../filter/ExclusionArtifactFilterTest.java | 123 ++++++++++++++++++ 2 files changed, 142 insertions(+), 5 deletions(-) create mode 100644 maven-core/src/test/java/org/apache/maven/artifact/resolver/filter/ExclusionArtifactFilterTest.java diff --git a/maven-core/src/main/java/org/apache/maven/artifact/resolver/filter/ExclusionArtifactFilter.java b/maven-core/src/main/java/org/apache/maven/artifact/resolver/filter/ExclusionArtifactFilter.java index 42390d640a26..e0c9994f2ae8 100644 --- a/maven-core/src/main/java/org/apache/maven/artifact/resolver/filter/ExclusionArtifactFilter.java +++ b/maven-core/src/main/java/org/apache/maven/artifact/resolver/filter/ExclusionArtifactFilter.java @@ -19,16 +19,18 @@ * under the License. */ -import java.util.List; - import org.apache.maven.artifact.Artifact; import org.apache.maven.model.Exclusion; +import java.util.List; + /** - * Filter to exclude from a list of artifact patterns. + * Filter to exclude from a list of artifact patterns. */ public class ExclusionArtifactFilter implements ArtifactFilter { + private static final String WILDCARD = "*"; + private final List exclusions; public ExclusionArtifactFilter( List exclusions ) @@ -41,8 +43,20 @@ public boolean include( Artifact artifact ) { for ( Exclusion exclusion : exclusions ) { - if ( exclusion.getGroupId().equals( artifact.getGroupId() ) - && exclusion.getArtifactId().equals( artifact.getArtifactId() ) ) + if ( WILDCARD.equals( exclusion.getGroupId() ) && WILDCARD.equals( exclusion.getArtifactId() ) ) + { + return false; + } + if ( WILDCARD.equals( exclusion.getGroupId() ) ) + { + return !exclusion.getArtifactId().equals( artifact.getArtifactId() ); + } + if ( WILDCARD.equals( exclusion.getArtifactId() ) ) + { + return !exclusion.getGroupId().equals( artifact.getGroupId() ); + } + if ( exclusion.getGroupId().equals( artifact.getGroupId() ) && exclusion.getArtifactId().equals( + artifact.getArtifactId() ) ) { return false; } diff --git a/maven-core/src/test/java/org/apache/maven/artifact/resolver/filter/ExclusionArtifactFilterTest.java b/maven-core/src/test/java/org/apache/maven/artifact/resolver/filter/ExclusionArtifactFilterTest.java new file mode 100644 index 000000000000..62a49111b777 --- /dev/null +++ b/maven-core/src/test/java/org/apache/maven/artifact/resolver/filter/ExclusionArtifactFilterTest.java @@ -0,0 +1,123 @@ +package org.apache.maven.artifact.resolver.filter; + +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +import org.apache.maven.artifact.Artifact; +import org.apache.maven.model.Exclusion; +import org.junit.Before; +import org.junit.Test; + +import java.util.Collections; + +import static org.hamcrest.CoreMatchers.is; +import static org.junit.Assert.assertThat; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.when; + +public class ExclusionArtifactFilterTest +{ + private Artifact artifact; + + @Before + public void setup() + { + artifact = mock( Artifact.class ); + when( artifact.getGroupId() ).thenReturn( "org.apache.maven" ); + when( artifact.getArtifactId() ).thenReturn( "maven-core" ); + } + + @Test + public void testExcludeExact() + { + Exclusion exclusion = new Exclusion(); + exclusion.setGroupId( "org.apache.maven" ); + exclusion.setArtifactId( "maven-core" ); + ExclusionArtifactFilter filter = new ExclusionArtifactFilter( Collections.singletonList( exclusion ) ); + + assertThat( filter.include( artifact ), is( false ) ); + } + + @Test + public void testExcludeNoMatch() + { + Exclusion exclusion = new Exclusion(); + exclusion.setGroupId( "org.apache.maven" ); + exclusion.setArtifactId( "maven-model" ); + ExclusionArtifactFilter filter = new ExclusionArtifactFilter( Collections.singletonList( exclusion ) ); + + assertThat( filter.include( artifact ), is( true ) ); + } + + @Test + public void testExcludeGroupIdWildcard() + { + Exclusion exclusion = new Exclusion(); + exclusion.setGroupId( "*" ); + exclusion.setArtifactId( "maven-core" ); + ExclusionArtifactFilter filter = new ExclusionArtifactFilter( Collections.singletonList( exclusion ) ); + + assertThat( filter.include( artifact ), is( false ) ); + } + + + @Test + public void testExcludeGroupIdWildcardNoMatch() + { + Exclusion exclusion = new Exclusion(); + exclusion.setGroupId( "*" ); + exclusion.setArtifactId( "maven-compat" ); + ExclusionArtifactFilter filter = new ExclusionArtifactFilter( Collections.singletonList( exclusion ) ); + + assertThat( filter.include( artifact ), is( true ) ); + } + + @Test + public void testExcludeArtifactIdWildcard() + { + Exclusion exclusion = new Exclusion(); + exclusion.setGroupId( "org.apache.maven" ); + exclusion.setArtifactId( "*" ); + ExclusionArtifactFilter filter = new ExclusionArtifactFilter( Collections.singletonList( exclusion ) ); + + assertThat( filter.include( artifact ), is( false ) ); + } + + @Test + public void testExcludeArtifactIdWildcardNoMatch() + { + Exclusion exclusion = new Exclusion(); + exclusion.setGroupId( "org.apache.groovy" ); + exclusion.setArtifactId( "*" ); + ExclusionArtifactFilter filter = new ExclusionArtifactFilter( Collections.singletonList( exclusion ) ); + + assertThat( filter.include( artifact ), is( true ) ); + } + + @Test + public void testExcludeAllWildcard() + { + Exclusion exclusion = new Exclusion(); + exclusion.setGroupId( "*" ); + exclusion.setArtifactId( "*" ); + ExclusionArtifactFilter filter = new ExclusionArtifactFilter( Collections.singletonList( exclusion ) ); + + assertThat( filter.include( artifact ), is( false ) ); + } +} \ No newline at end of file From 5065aecb27fdc1d825d9d53c71e72f422b0d4c70 Mon Sep 17 00:00:00 2001 From: rfscholte Date: Sat, 24 Aug 2019 18:10:31 +0200 Subject: [PATCH 11/52] Move Filters to maven-xml filter, so it can be picked up by maven-model-builder and maven-core Provide BuildPomXMlFilter to set CI Friendly properties --- ...DefaultRepositorySystemSessionFactory.java | 32 +++--- .../model/building/DefaultModelBuilder.java | 40 +++---- maven-xml/pom.xml | 5 + .../maven/xml/filter/BuildPomXMLFilter.java | 13 ++- .../xml/filter/ConsumerPomXMLFilter.java | 19 ++++ .../maven/xml/filter/FastForwardFilter.java | 2 +- .../xml/filter/RelativePathXMLFilter.java | 1 + .../xml/filter/AbstractXMLFilterTests.java | 33 +++--- .../xml/filter/ConsumerPomXMLFilterTest.java | 103 ++++++++++++++++-- .../xml/filter/ModulesXMLFilterTest.java | 22 +++- .../xml/filter/RelativePathXMLFilterTest.java | 75 +++++++++++-- 11 files changed, 264 insertions(+), 81 deletions(-) diff --git a/maven-core/src/main/java/org/apache/maven/internal/aether/DefaultRepositorySystemSessionFactory.java b/maven-core/src/main/java/org/apache/maven/internal/aether/DefaultRepositorySystemSessionFactory.java index a291c4d27677..20bd44982194 100644 --- a/maven-core/src/main/java/org/apache/maven/internal/aether/DefaultRepositorySystemSessionFactory.java +++ b/maven-core/src/main/java/org/apache/maven/internal/aether/DefaultRepositorySystemSessionFactory.java @@ -34,6 +34,7 @@ import javax.inject.Inject; import javax.inject.Named; +import javax.xml.parsers.ParserConfigurationException; import javax.xml.transform.TransformerException; import javax.xml.transform.TransformerFactory; import javax.xml.transform.sax.SAXSource; @@ -52,9 +53,7 @@ import org.apache.maven.settings.crypto.DefaultSettingsDecryptionRequest; import org.apache.maven.settings.crypto.SettingsDecrypter; import org.apache.maven.settings.crypto.SettingsDecryptionResult; -import org.apache.maven.xml.filter.BuildPomXMLFilter; -import org.apache.maven.xml.filter.BuildPomXMLFilterFactory; -import org.apache.maven.xml.filter.ConsumerPomXMLFilter; +import org.apache.maven.xml.filter.ConsumerPomXMLFilterFactory; import org.codehaus.plexus.configuration.xml.XmlPlexusConfiguration; import org.codehaus.plexus.logging.Logger; import org.codehaus.plexus.util.xml.Xpp3Dom; @@ -79,8 +78,6 @@ import org.eclipse.sisu.Nullable; import org.xml.sax.InputSource; import org.xml.sax.SAXException; -import org.xml.sax.XMLReader; -import org.xml.sax.helpers.XMLReaderFactory; /** * @since 3.3.0 @@ -116,6 +113,9 @@ public class DefaultRepositorySystemSessionFactory @Inject MavenRepositorySystem mavenRepositorySystem; + @Inject + private ConsumerPomXMLFilterFactory consumerPomXMLFilterFactory; + public DefaultRepositorySystemSession newRepositorySession( MavenExecutionRequest request ) { DefaultRepositorySystemSession session = MavenRepositorySystemUtils.newSession(); @@ -273,7 +273,7 @@ private FileTransformerManager newFileTransformerManager() return new FileTransformerManager() { @Override - public Collection getTransformersForArtifact( Artifact artifact ) + public Collection getTransformersForArtifact( final Artifact artifact ) { Collection transformers = new ArrayList<>(); if ( "pom".equals( artifact.getExtension() ) ) @@ -286,23 +286,24 @@ public Collection getTransformersForArtifact( Artifact artifact public InputStream transformData( File file ) throws IOException, TransformException { + System.out.println( "transforming " + file.getAbsolutePath() ); final PipedOutputStream pipedOutputStream = new PipedOutputStream(); final PipedInputStream pipedInputStream = new PipedInputStream( pipedOutputStream ); - XMLReader parent; + final SAXSource transformSource; try { - parent = XMLReaderFactory.createXMLReader(); + transformSource = + new SAXSource( consumerPomXMLFilterFactory.get( artifact.getGroupId(), + artifact.getArtifactId() ), + new InputSource( new FileReader( file ) ) ); } - catch ( SAXException e ) - { - throw new TransformException( "Failed to create XMLReader", e ); + catch ( SAXException | ParserConfigurationException e ) + { + e.printStackTrace(); + throw new TransformException( "Failed to create a consumerPomXMLFilter", e ); } - final SAXSource transformSource = - new SAXSource( new ConsumerPomXMLFilter( new B ), - new InputSource( new FileReader( file ) ) ); - final StreamResult result = new StreamResult( pipedOutputStream ); final Runnable runnable = new Runnable() @@ -316,6 +317,7 @@ public void run() } catch ( TransformerException | IOException e ) { + e.printStackTrace(); throw new RuntimeException( e ); } } 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 50f877393154..1fea6ddd8b70 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 @@ -39,10 +39,10 @@ import javax.inject.Inject; import javax.inject.Named; +import javax.inject.Provider; import javax.inject.Singleton; import javax.xml.crypto.dsig.TransformException; import javax.xml.parsers.ParserConfigurationException; -import javax.xml.parsers.SAXParserFactory; import javax.xml.transform.TransformerException; import javax.xml.transform.TransformerFactory; import javax.xml.transform.sax.SAXSource; @@ -87,12 +87,11 @@ 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.filter.BuildPomXMLFilter; +import org.apache.maven.xml.filter.BuildPomXMLFilterFactory; import org.codehaus.plexus.interpolation.MapBasedValueSource; import org.codehaus.plexus.interpolation.StringSearchInterpolator; import org.eclipse.sisu.Nullable; import org.xml.sax.SAXException; -import org.xml.sax.XMLReader; /** * @author Benjamin Bentmann @@ -153,6 +152,9 @@ public class DefaultModelBuilder @Inject private ReportingConverter reportingConverter; + + @Inject + private Provider buildPomXMLFilterFactory; public DefaultModelBuilder setModelProcessor( ModelProcessor modelProcessor ) { @@ -561,7 +563,6 @@ private Model readModel( ModelSource modelSource, File pomFile, ModelBuildingReq try { - // RFS adjust inputstream model = modelProcessor.read( modelSource.getInputStream(), options ); } catch ( ModelParseException e ) @@ -760,14 +761,19 @@ private void assembleInheritance( List lineage, ModelBuildingRequest { // TODO: parent might be part of reactor... better read all lineage items like this? Model parent = lineage.get( 1 ).getModel(); - Model child = lineage.get( 0 ).getModel(); - // modelProcessor.read( lineage.get( 0 ).getSource().getInputStream(), null ); + + Model child = modelProcessor.read( transformData( lineage.get( 0 ) ), null ); inheritanceAssembler.assembleModelInheritance( child, parent, request, problems ); + + // sync pomfile, is transient + child.setPomFile( lineage.get( 0 ).getModel().getPomFile() ); + // overwrite child + lineage.get( 0 ).setModel( child ); } - finally -// catch ( IOException e ) + catch ( IOException | TransformException | SAXException | ParserConfigurationException e ) { // this is second read, should not happen + e.printStackTrace(); } } else @@ -778,27 +784,17 @@ private void assembleInheritance( List lineage, ModelBuildingRequest } } - private InputStream transformData( InputStream inputStream ) - throws IOException, TransformException + private InputStream transformData( ModelData modelData ) + throws IOException, TransformException, SAXException, ParserConfigurationException { final TransformerFactory transformerFactory = TransformerFactory.newInstance(); final PipedOutputStream pipedOutputStream = new PipedOutputStream(); final PipedInputStream pipedInputStream = new PipedInputStream( pipedOutputStream ); - XMLReader parent; - try - { - parent = SAXParserFactory.newInstance().newSAXParser().getXMLReader(); - } - catch ( SAXException | ParserConfigurationException e ) - { - throw new TransformException( "Failed to create XMLReader", e ); - } - final SAXSource transformSource = - new SAXSource( new BuildPomXMLFilter( parent ), - new org.xml.sax.InputSource( inputStream ) ); + new SAXSource( buildPomXMLFilterFactory.get().get( modelData.getGroupId(), modelData.getArtifactId() ), + new org.xml.sax.InputSource( modelData.getSource().getInputStream() ) ); final StreamResult result = new StreamResult( pipedOutputStream ); diff --git a/maven-xml/pom.xml b/maven-xml/pom.xml index aeef99eab9ec..1c576907b20f 100644 --- a/maven-xml/pom.xml +++ b/maven-xml/pom.xml @@ -53,6 +53,11 @@ under the License. + + javax.inject + javax.inject + true + org.xmlunit xmlunit-assertj diff --git a/maven-xml/src/main/java/org/apache/maven/xml/filter/BuildPomXMLFilter.java b/maven-xml/src/main/java/org/apache/maven/xml/filter/BuildPomXMLFilter.java index 9e8d2613fcc7..ab846a080a4b 100644 --- a/maven-xml/src/main/java/org/apache/maven/xml/filter/BuildPomXMLFilter.java +++ b/maven-xml/src/main/java/org/apache/maven/xml/filter/BuildPomXMLFilter.java @@ -1,7 +1,5 @@ package org.apache.maven.xml.filter; -import org.xml.sax.XMLFilter; - /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file @@ -36,8 +34,6 @@ */ public class BuildPomXMLFilter extends XMLFilterImpl { - private XMLFilter rootFilter; - BuildPomXMLFilter() { super(); @@ -47,4 +43,13 @@ public class BuildPomXMLFilter extends XMLFilterImpl { super( parent ); } + + @Override + public final void setParent( XMLReader parent ) + { + if ( getParent() == null ) + { + super.setParent( parent ); + } + } } diff --git a/maven-xml/src/main/java/org/apache/maven/xml/filter/ConsumerPomXMLFilter.java b/maven-xml/src/main/java/org/apache/maven/xml/filter/ConsumerPomXMLFilter.java index 6c2ea9f65f9c..9975c224f7ee 100644 --- a/maven-xml/src/main/java/org/apache/maven/xml/filter/ConsumerPomXMLFilter.java +++ b/maven-xml/src/main/java/org/apache/maven/xml/filter/ConsumerPomXMLFilter.java @@ -1,5 +1,24 @@ package org.apache.maven.xml.filter; +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + import org.xml.sax.XMLReader; import org.xml.sax.helpers.XMLFilterImpl; diff --git a/maven-xml/src/main/java/org/apache/maven/xml/filter/FastForwardFilter.java b/maven-xml/src/main/java/org/apache/maven/xml/filter/FastForwardFilter.java index df68167a1394..6e03a3459d42 100644 --- a/maven-xml/src/main/java/org/apache/maven/xml/filter/FastForwardFilter.java +++ b/maven-xml/src/main/java/org/apache/maven/xml/filter/FastForwardFilter.java @@ -34,7 +34,7 @@ * Should be used in case of a DOM that should not be effected by other filters, even though the elements match * * @author Robert Scholte - * @since 4.0.0 + * @since 3.7.0 */ class FastForwardFilter extends XMLFilterImpl { diff --git a/maven-xml/src/main/java/org/apache/maven/xml/filter/RelativePathXMLFilter.java b/maven-xml/src/main/java/org/apache/maven/xml/filter/RelativePathXMLFilter.java index 8548ddd73d9c..5dc367fa993e 100644 --- a/maven-xml/src/main/java/org/apache/maven/xml/filter/RelativePathXMLFilter.java +++ b/maven-xml/src/main/java/org/apache/maven/xml/filter/RelativePathXMLFilter.java @@ -57,6 +57,7 @@ class RelativePathXMLFilter public void startElement( String uri, String localName, String qName, Attributes atts ) throws SAXException { + if ( relativePathStatus == -1 && "relativePath".equals( localName ) ) { relativePathStatus = 1; diff --git a/maven-xml/src/test/java/org/apache/maven/xml/filter/AbstractXMLFilterTests.java b/maven-xml/src/test/java/org/apache/maven/xml/filter/AbstractXMLFilterTests.java index 69fc33ba8f59..4ee0e313690c 100644 --- a/maven-xml/src/test/java/org/apache/maven/xml/filter/AbstractXMLFilterTests.java +++ b/maven-xml/src/test/java/org/apache/maven/xml/filter/AbstractXMLFilterTests.java @@ -1,7 +1,5 @@ package org.apache.maven.xml.filter; -import java.io.Reader; - /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file @@ -21,10 +19,13 @@ * under the License. */ +import java.io.Reader; import java.io.StringReader; import java.io.StringWriter; import java.io.Writer; +import javax.xml.parsers.ParserConfigurationException; +import javax.xml.parsers.SAXParserFactory; import javax.xml.transform.OutputKeys; import javax.xml.transform.Transformer; import javax.xml.transform.TransformerException; @@ -35,34 +36,32 @@ import org.xml.sax.InputSource; import org.xml.sax.SAXException; import org.xml.sax.XMLFilter; -import org.xml.sax.XMLReader; -import org.xml.sax.helpers.XMLReaderFactory; -public class AbstractXMLFilterTests +public abstract class AbstractXMLFilterTests { - public AbstractXMLFilterTests() { super(); } + + protected abstract XMLFilter getFilter() throws TransformerException, SAXException, ParserConfigurationException; + - protected String transform( String input, XMLFilter filter ) - throws TransformerException, SAXException + protected String transform( String input ) + throws TransformerException, SAXException, ParserConfigurationException { - return transform( new StringReader( input ), filter ); + return transform( new StringReader( input ) ); } - protected String transform( Reader input, XMLFilter filter ) - throws TransformerException, SAXException + protected String transform( Reader input ) + throws TransformerException, SAXException, ParserConfigurationException { - XMLReader reader = XMLReaderFactory.createXMLReader(); - - XMLFilter parent = filter; - while ( parent.getParent() instanceof XMLFilter ) + XMLFilter filter = getFilter(); + if( filter.getParent() == null ) { - parent = (XMLFilter) parent.getParent(); + filter.setParent( SAXParserFactory.newInstance().newSAXParser().getXMLReader() ); + filter.setFeature( "http://xml.org/sax/features/namespaces", true ); } - parent.setParent( reader ); Writer writer = new StringWriter(); StreamResult result = new StreamResult( writer ); diff --git a/maven-xml/src/test/java/org/apache/maven/xml/filter/ConsumerPomXMLFilterTest.java b/maven-xml/src/test/java/org/apache/maven/xml/filter/ConsumerPomXMLFilterTest.java index a169b132dc2e..8fe2d67e4b56 100644 --- a/maven-xml/src/test/java/org/apache/maven/xml/filter/ConsumerPomXMLFilterTest.java +++ b/maven-xml/src/test/java/org/apache/maven/xml/filter/ConsumerPomXMLFilterTest.java @@ -21,18 +21,56 @@ import static org.xmlunit.assertj.XmlAssert.assertThat; -import javax.xml.parsers.SAXParserFactory; +import java.util.Optional; + +import javax.inject.Provider; +import javax.xml.parsers.ParserConfigurationException; -import org.junit.Before; import org.junit.Test; +import org.xml.sax.SAXException; +import org.xml.sax.XMLFilter; public class ConsumerPomXMLFilterTest extends AbstractXMLFilterTests { - private ConsumerPomXMLFilter filter; - - @Before - public void setup() throws Exception { - filter = new ConsumerPomXMLFilterFactory(){}.get( new BuildPomXMLFilter( SAXParserFactory.newInstance().newSAXParser().getXMLReader() ) ); + @Override + protected XMLFilter getFilter() throws SAXException, ParserConfigurationException + { + final BuildPomXMLFilterFactory buildPomXMLFilterFactory = new BuildPomXMLFilterFactory() + { + @Override + protected Optional getSha1() + { + return Optional.empty(); + } + + @Override + protected Optional getRevision() + { + return Optional.empty(); + } + + @Override + protected Optional getChangelist() + { + return Optional.of( "CL" ); + } + }; + + Provider provider = new Provider() + { + + @Override + public BuildPomXMLFilterFactory get() + { + return buildPomXMLFilterFactory; + } + }; + + XMLFilter filter = new ConsumerPomXMLFilterFactory( provider ) + { + }.get( "G", "A" ); + filter.setFeature( "http://xml.org/sax/features/namespaces", true ); + return filter; } @Test @@ -59,8 +97,57 @@ public void testAllFilters() throws Exception { + " \n" + " PROJECT\n" + ""; - String actual = transform( input, filter ); + String actual = transform( input ); assertThat( actual ).and( expected ).ignoreWhitespace().areIdentical(); } + + @Test + public void testMe() throws Exception { + String input = "\r\n" + + "\r\n" + + " 4.0.0\r\n" + + " org.sonatype.mavenbook.multispring\r\n" + + " parent\r\n" + + " 0.9-${changelist}-SNAPSHOT\r\n" + + " pom\r\n" + + " Multi-Spring Chapter Parent Project\r\n" + + " \r\n" + + " simple-parent\r\n" + + " \r\n" + + " \r\n" + + " \r\n" + + " \r\n" + + " apache.snapshots\r\n" + + " http://repository.apache.org/snapshots/\r\n" + + " \r\n" + + " \r\n" + + ""; + String expected = "\r\n" + + "\r\n" + + " 4.0.0\r\n" + + " org.sonatype.mavenbook.multispring\r\n" + + " parent\r\n" + + " 0.9-CL-SNAPSHOT\r\n" + + " pom\r\n" + + " Multi-Spring Chapter Parent Project\r\n" + + " \r\n" + + " \r\n" + + " \r\n" + + " apache.snapshots\r\n" + + " http://repository.apache.org/snapshots/\r\n" + + " \r\n" + + " \r\n" + + ""; + String actual = transform( input ); + assertThat( actual ).and( expected ).ignoreWhitespace().areIdentical(); + } + + } diff --git a/maven-xml/src/test/java/org/apache/maven/xml/filter/ModulesXMLFilterTest.java b/maven-xml/src/test/java/org/apache/maven/xml/filter/ModulesXMLFilterTest.java index 353f1742d896..63880ed27008 100644 --- a/maven-xml/src/test/java/org/apache/maven/xml/filter/ModulesXMLFilterTest.java +++ b/maven-xml/src/test/java/org/apache/maven/xml/filter/ModulesXMLFilterTest.java @@ -21,23 +21,35 @@ import static org.xmlunit.assertj.XmlAssert.assertThat; +import javax.xml.parsers.SAXParserFactory; + import org.junit.Before; import org.junit.Test; +import org.xml.sax.XMLFilter; +import org.xml.sax.XMLReader; public class ModulesXMLFilterTest extends AbstractXMLFilterTests { private ModulesXMLFilter filter; + + @Override + protected XMLFilter getFilter() + { + return new ModulesXMLFilter(); + } @Before - public void setup() { - filter = new ModulesXMLFilter(); + public void setup() throws Exception { + XMLReader xmlReader = SAXParserFactory.newInstance().newSAXParser().getXMLReader(); + filter = new ModulesXMLFilter( xmlReader ); + filter.setFeature( "http://xml.org/sax/features/namespaces", true ); } @Test public void testEmptyModules() throws Exception { String input = ""; String expected = ""; - String actual = transform( input, filter ); + String actual = transform( input ); assertThat( actual ).and( expected ).areIdentical(); } @@ -48,7 +60,7 @@ public void testSetOfModules() throws Exception { + "../cd" + ""; String expected = ""; - String actual = transform( input, filter ); + String actual = transform( input ); assertThat( actual ).and( expected ).areIdentical(); } @@ -56,7 +68,7 @@ public void testSetOfModules() throws Exception { public void testNoModules() throws Exception { String input = "NAME"; String expected = input; - String actual = transform( input, filter ); + String actual = transform( input ); assertThat( actual ).and( expected ).areIdentical(); } } diff --git a/maven-xml/src/test/java/org/apache/maven/xml/filter/RelativePathXMLFilterTest.java b/maven-xml/src/test/java/org/apache/maven/xml/filter/RelativePathXMLFilterTest.java index 298197dd1c81..1fed1cadf500 100644 --- a/maven-xml/src/test/java/org/apache/maven/xml/filter/RelativePathXMLFilterTest.java +++ b/maven-xml/src/test/java/org/apache/maven/xml/filter/RelativePathXMLFilterTest.java @@ -1,7 +1,5 @@ package org.apache.maven.xml.filter; -import static org.xmlunit.assertj.XmlAssert.assertThat; - /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file @@ -21,16 +19,17 @@ * under the License. */ -import org.junit.Before; +import static org.xmlunit.assertj.XmlAssert.assertThat; + import org.junit.Test; +import org.xml.sax.XMLFilter; public class RelativePathXMLFilterTest extends AbstractXMLFilterTests { - private RelativePathXMLFilter filter; - - @Before - public void setup() { - filter = new RelativePathXMLFilter(); + @Override + protected XMLFilter getFilter() + { + return new RelativePathXMLFilter(); } @Test @@ -54,7 +53,65 @@ public void testRelativePath() throws Exception + " \n" + " PROJECT\n" + ""; - String actual = transform( input, filter ); + String actual = transform( input ); + assertThat( actual ).and( expected ).areIdentical(); + } + + @Test + public void testRelativePathNS() throws Exception + { + String input = "\n" + + " \n" + + " GROUPID\n" + + " PARENT\n" + + " VERSION\n" + + " ../pom.xml\n" + + " \n" + + " PROJECT\n" + + ""; + String expected = "\n" + + " \n" + + " GROUPID\n" + + " PARENT\n" + + " VERSION\n" + + " \n" + + " \n" + + " PROJECT\n" + + ""; + String actual = transform( input ); + assertThat( actual ).and( expected ).areIdentical(); + } + + @Test + public void testRelativePathPasNS() throws Exception + { + String input = "\n" + + " \n" + + " GROUPID\n" + + " PARENT\n" + + " VERSION\n" + + " ../pom.xml\n" + + " \n" + + " PROJECT\n" + + ""; + String expected = "\n" + + " \n" + + " GROUPID\n" + + " PARENT\n" + + " VERSION\n" + + " \n" + + " \n" + + " PROJECT\n" + + ""; + String actual = transform( input ); assertThat( actual ).and( expected ).areIdentical(); } From 82d8693fad39cbe5217bcf1a9518f548a2444eb1 Mon Sep 17 00:00:00 2001 From: rfscholte Date: Sat, 24 Aug 2019 18:36:02 +0200 Subject: [PATCH 12/52] Add missing classes --- .../DefaultBuildPomXMLFilterFactory.java | 69 +++++++++++++++ .../DefaultConsumerPomXMLFilterFactory.java | 37 ++++++++ .../xml/filter/BuildPomXMLFilterFactory.java | 70 ++++++++++++++++ .../maven/xml/filter/CiFriendlyXMLFilter.java | 84 +++++++++++++++++++ .../filter/ConsumerPomXMLFilterFactory.java | 65 ++++++++++++++ 5 files changed, 325 insertions(+) create mode 100644 maven-core/src/main/java/org/apache/maven/xml/internal/DefaultBuildPomXMLFilterFactory.java create mode 100644 maven-core/src/main/java/org/apache/maven/xml/internal/DefaultConsumerPomXMLFilterFactory.java create mode 100644 maven-xml/src/main/java/org/apache/maven/xml/filter/BuildPomXMLFilterFactory.java create mode 100644 maven-xml/src/main/java/org/apache/maven/xml/filter/CiFriendlyXMLFilter.java create mode 100644 maven-xml/src/main/java/org/apache/maven/xml/filter/ConsumerPomXMLFilterFactory.java diff --git a/maven-core/src/main/java/org/apache/maven/xml/internal/DefaultBuildPomXMLFilterFactory.java b/maven-core/src/main/java/org/apache/maven/xml/internal/DefaultBuildPomXMLFilterFactory.java new file mode 100644 index 000000000000..0b51da2a99fa --- /dev/null +++ b/maven-core/src/main/java/org/apache/maven/xml/internal/DefaultBuildPomXMLFilterFactory.java @@ -0,0 +1,69 @@ +package org.apache.maven.xml.internal; + +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +import java.util.Optional; + +import javax.inject.Inject; +import javax.inject.Named; +//import javax.inject.Provider; +import javax.inject.Singleton; + +import org.apache.maven.execution.MavenSession; +import org.apache.maven.xml.filter.BuildPomXMLFilterFactory; +import org.codehaus.mojo.animal_sniffer.IgnoreJRERequirement; + +/** + * + * @author Robert Scholte + * @since 3.7.0 + */ +@Named +@Singleton +@IgnoreJRERequirement( ) +public class DefaultBuildPomXMLFilterFactory extends BuildPomXMLFilterFactory +{ + private MavenSession session; + + @Inject + public DefaultBuildPomXMLFilterFactory( MavenSession session ) + { + this.session = session; + } + + @Override + protected Optional getChangelist() + { + return Optional.ofNullable( session.getUserProperties().getProperty( "changelist" ) ); + } + + @Override + protected Optional getRevision() + { + return Optional.ofNullable( session.getUserProperties().getProperty( "revision" ) ); + } + + @Override + protected Optional getSha1() + { + return Optional.ofNullable( session.getUserProperties().getProperty( "sha1" ) ); + } + +} 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 new file mode 100644 index 000000000000..af05bc392344 --- /dev/null +++ b/maven-core/src/main/java/org/apache/maven/xml/internal/DefaultConsumerPomXMLFilterFactory.java @@ -0,0 +1,37 @@ +package org.apache.maven.xml.internal; + +/* + * 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 javax.inject.Named; +import javax.inject.Singleton; + +import org.apache.maven.xml.filter.ConsumerPomXMLFilterFactory; + +/** + * + * @author Robert Scholte + * @since 3.7.0 + */ +@Named +@Singleton +public class DefaultConsumerPomXMLFilterFactory extends ConsumerPomXMLFilterFactory +{ + +} diff --git a/maven-xml/src/main/java/org/apache/maven/xml/filter/BuildPomXMLFilterFactory.java b/maven-xml/src/main/java/org/apache/maven/xml/filter/BuildPomXMLFilterFactory.java new file mode 100644 index 000000000000..03cad018c9b6 --- /dev/null +++ b/maven-xml/src/main/java/org/apache/maven/xml/filter/BuildPomXMLFilterFactory.java @@ -0,0 +1,70 @@ +package org.apache.maven.xml.filter; + +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +import java.util.Optional; + +import javax.xml.parsers.ParserConfigurationException; +import javax.xml.parsers.SAXParserFactory; + +import org.xml.sax.SAXException; +import org.xml.sax.XMLReader; + +/** + * + * @author Robert Scholte + * + * @since 3.7.0 + */ +public abstract class BuildPomXMLFilterFactory +{ + public final BuildPomXMLFilter get( String groupId, String artifactId ) + throws SAXException, ParserConfigurationException + { + CiFriendlyXMLFilter filter = new CiFriendlyXMLFilter(); + getChangelist().ifPresent( filter::setChangelist ); + getRevision().ifPresent( filter::setRevision ); + getSha1().ifPresent( filter::setSha1 ); + + if ( filter.isSet() ) + { + filter.setParent( getParent() ); + return new BuildPomXMLFilter( filter ); + } + else + { + return new BuildPomXMLFilter( getParent() ); + } + } + + protected XMLReader getParent() throws SAXException, ParserConfigurationException + { + XMLReader xmlReader = SAXParserFactory.newInstance().newSAXParser().getXMLReader(); + xmlReader.setFeature( "http://xml.org/sax/features/namespaces", true ); + return xmlReader; + } + + // For CIFriendly + protected abstract Optional getChangelist(); + + protected abstract Optional getRevision(); + + protected abstract Optional getSha1(); +} diff --git a/maven-xml/src/main/java/org/apache/maven/xml/filter/CiFriendlyXMLFilter.java b/maven-xml/src/main/java/org/apache/maven/xml/filter/CiFriendlyXMLFilter.java new file mode 100644 index 000000000000..7f8c206232ed --- /dev/null +++ b/maven-xml/src/main/java/org/apache/maven/xml/filter/CiFriendlyXMLFilter.java @@ -0,0 +1,84 @@ +package org.apache.maven.xml.filter; + +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +import java.util.function.Function; + +import org.xml.sax.SAXException; +import org.xml.sax.helpers.XMLFilterImpl; + +/** + * Resolves all ci-friendly properties occurrences + * + * @author Robert Scholte + * @since 3.7.0 + */ +class CiFriendlyXMLFilter + extends XMLFilterImpl +{ + private Function replaceChain = Function.identity(); + + public CiFriendlyXMLFilter setChangelist( String changelist ) + { + replaceChain = replaceChain.andThen( t -> t.replace( "${changelist}", changelist ) ); + return this; + } + + public CiFriendlyXMLFilter setRevision( String revision ) + { + replaceChain = replaceChain.andThen( t -> t.replace( "${revision}", revision ) ); + return this; + } + + public CiFriendlyXMLFilter setSha1( String sha1 ) + { + replaceChain = replaceChain.andThen( t -> t.replace( "${sha1}", sha1 ) ); + return this; + } + + /** + * @return {@code true} is any of the ci properties is set, otherwise {@code false} + */ + public boolean isSet() + { + return !replaceChain.equals( Function.identity() ); + } + + @Override + public void characters( char[] ch, int start, int length ) + throws SAXException + { + String text = new String( ch, start, length ); + + // assuming this has the best performance + if ( text.contains( "${" ) ) + { + String newText = replaceChain.apply( text ); + + super.characters( newText.toCharArray(), 0, newText.length() ); + } + else + { + super.characters( ch, start, length ); + } + } + + +} \ No newline at end of file diff --git a/maven-xml/src/main/java/org/apache/maven/xml/filter/ConsumerPomXMLFilterFactory.java b/maven-xml/src/main/java/org/apache/maven/xml/filter/ConsumerPomXMLFilterFactory.java new file mode 100644 index 000000000000..c185fdfb4186 --- /dev/null +++ b/maven-xml/src/main/java/org/apache/maven/xml/filter/ConsumerPomXMLFilterFactory.java @@ -0,0 +1,65 @@ +package org.apache.maven.xml.filter; + +/* + * 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 javax.inject.Inject; +import javax.inject.Provider; +import javax.xml.parsers.ParserConfigurationException; + +import org.xml.sax.SAXException; +import org.xml.sax.XMLFilter; +import org.xml.sax.XMLReader; + +/** + * + * @author Robert Scholte + * @since 3.7.0 + */ +public abstract class ConsumerPomXMLFilterFactory +{ + @Inject + private Provider buildPomXMLFilterFactory; + + public ConsumerPomXMLFilterFactory() + { + } + + // For testing purpose + ConsumerPomXMLFilterFactory( Provider buildPomXMLFilterFactory ) + { + this.buildPomXMLFilterFactory = buildPomXMLFilterFactory; + } + + public final ConsumerPomXMLFilter get( String groupId, String artifactId ) + throws SAXException, ParserConfigurationException + { + XMLFilter parent = buildPomXMLFilterFactory.get().get( groupId, artifactId ); + + // Ensure that xs:any elements aren't touched by next filters + XMLReader filter = new FastForwardFilter( parent ); + + // Strip modules + filter = new ModulesXMLFilter( filter ); + // Adjust relativePath + filter = new RelativePathXMLFilter( filter ); + + return new ConsumerPomXMLFilter( filter ); + } +} From a6843705d184bcf7267df1e6ae421cb257bd5093 Mon Sep 17 00:00:00 2001 From: rfscholte Date: Mon, 26 Aug 2019 16:35:08 +0200 Subject: [PATCH 13/52] [MNG-6656] Support versionless parent --- ...DefaultRepositorySystemSessionFactory.java | 8 +- .../DefaultBuildPomXMLFilterFactory.java | 34 +- .../model/building/DefaultModelBuilder.java | 23 +- .../building/DefaultModelCacheManager.java | 55 +++ .../model/building/ModelCacheManager.java | 38 +++ .../maven/model/building/ModelData.java | 23 +- .../validation/DefaultModelValidator.java | 8 +- .../xml/filter/BuildPomXMLFilterFactory.java | 35 +- .../filter/ConsumerPomXMLFilterFactory.java | 6 +- .../maven/xml/filter/ParentXMLFilter.java | 313 ++++++++++++++++++ .../maven/xml/filter/RelativeProject.java | 56 ++++ .../xml/filter/AbstractXMLFilterTests.java | 30 +- .../xml/filter/ConsumerPomXMLFilterTest.java | 11 +- .../maven/xml/filter/ParentXMLFilterTest.java | 185 +++++++++++ pom.xml | 27 +- 15 files changed, 795 insertions(+), 57 deletions(-) create mode 100644 maven-model-builder/src/main/java/org/apache/maven/model/building/DefaultModelCacheManager.java create mode 100644 maven-model-builder/src/main/java/org/apache/maven/model/building/ModelCacheManager.java create mode 100644 maven-xml/src/main/java/org/apache/maven/xml/filter/ParentXMLFilter.java create mode 100644 maven-xml/src/main/java/org/apache/maven/xml/filter/RelativeProject.java create mode 100644 maven-xml/src/test/java/org/apache/maven/xml/filter/ParentXMLFilterTest.java diff --git a/maven-core/src/main/java/org/apache/maven/internal/aether/DefaultRepositorySystemSessionFactory.java b/maven-core/src/main/java/org/apache/maven/internal/aether/DefaultRepositorySystemSessionFactory.java index 20bd44982194..e4f8439012ab 100644 --- a/maven-core/src/main/java/org/apache/maven/internal/aether/DefaultRepositorySystemSessionFactory.java +++ b/maven-core/src/main/java/org/apache/maven/internal/aether/DefaultRepositorySystemSessionFactory.java @@ -34,6 +34,7 @@ import javax.inject.Inject; import javax.inject.Named; +import javax.inject.Provider; import javax.xml.parsers.ParserConfigurationException; import javax.xml.transform.TransformerException; import javax.xml.transform.TransformerFactory; @@ -114,7 +115,8 @@ public class DefaultRepositorySystemSessionFactory MavenRepositorySystem mavenRepositorySystem; @Inject - private ConsumerPomXMLFilterFactory consumerPomXMLFilterFactory; + @Nullable + private Provider consumerPomXMLFilterFactory; public DefaultRepositorySystemSession newRepositorySession( MavenExecutionRequest request ) { @@ -286,7 +288,6 @@ public Collection getTransformersForArtifact( final Artifact ar public InputStream transformData( File file ) throws IOException, TransformException { - System.out.println( "transforming " + file.getAbsolutePath() ); final PipedOutputStream pipedOutputStream = new PipedOutputStream(); final PipedInputStream pipedInputStream = new PipedInputStream( pipedOutputStream ); @@ -294,8 +295,7 @@ public InputStream transformData( File file ) try { transformSource = - new SAXSource( consumerPomXMLFilterFactory.get( artifact.getGroupId(), - artifact.getArtifactId() ), + new SAXSource( consumerPomXMLFilterFactory.get().get( file.toPath() ), new InputSource( new FileReader( file ) ) ); } catch ( SAXException | ParserConfigurationException e ) diff --git a/maven-core/src/main/java/org/apache/maven/xml/internal/DefaultBuildPomXMLFilterFactory.java b/maven-core/src/main/java/org/apache/maven/xml/internal/DefaultBuildPomXMLFilterFactory.java index 0b51da2a99fa..cdded2bca759 100644 --- a/maven-core/src/main/java/org/apache/maven/xml/internal/DefaultBuildPomXMLFilterFactory.java +++ b/maven-core/src/main/java/org/apache/maven/xml/internal/DefaultBuildPomXMLFilterFactory.java @@ -19,16 +19,20 @@ * under the License. */ + +import java.nio.file.Path; import java.util.Optional; +import java.util.function.Function; import javax.inject.Inject; import javax.inject.Named; -//import javax.inject.Provider; import javax.inject.Singleton; import org.apache.maven.execution.MavenSession; +import org.apache.maven.model.Model; +import org.apache.maven.model.building.ModelCacheManager; import org.apache.maven.xml.filter.BuildPomXMLFilterFactory; -import org.codehaus.mojo.animal_sniffer.IgnoreJRERequirement; +import org.apache.maven.xml.filter.RelativeProject; /** * @@ -37,11 +41,13 @@ */ @Named @Singleton -@IgnoreJRERequirement( ) public class DefaultBuildPomXMLFilterFactory extends BuildPomXMLFilterFactory { private MavenSession session; + @Inject + private ModelCacheManager rawModelCache; + @Inject public DefaultBuildPomXMLFilterFactory( MavenSession session ) { @@ -66,4 +72,26 @@ protected Optional getSha1() return Optional.ofNullable( session.getUserProperties().getProperty( "sha1" ) ); } + @Override + protected Function> getRelativePathMapper() + { + return p -> Optional.ofNullable( rawModelCache.get( p ) ).map( m -> toRelativeProject( m ) ); + } + + private RelativeProject toRelativeProject( final Model m ) + { + String groupId = m.getGroupId(); + if ( groupId == null && m.getParent() != null ) + { + groupId = m.getParent().getGroupId(); + } + + String version = m.getVersion(); + if ( version == null && m.getParent() != null ) + { + version = m.getParent().getVersion(); + } + + return new RelativeProject( groupId, m.getArtifactId(), version ); + } } 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 1fea6ddd8b70..0b0a615ea8c3 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 @@ -51,6 +51,7 @@ import org.apache.maven.artifact.versioning.DefaultArtifactVersion; import org.apache.maven.artifact.versioning.InvalidVersionSpecificationException; import org.apache.maven.artifact.versioning.VersionRange; +import org.apache.maven.building.FileSource; import org.apache.maven.model.Activation; import org.apache.maven.model.Build; import org.apache.maven.model.Dependency; @@ -154,7 +155,12 @@ public class DefaultModelBuilder private ReportingConverter reportingConverter; @Inject + @Nullable private Provider buildPomXMLFilterFactory; + + @Inject + @Nullable + private ModelCacheManager modelCacheManager; public DefaultModelBuilder setModelProcessor( ModelProcessor modelProcessor ) { @@ -294,7 +300,11 @@ public ModelBuildingResult build( ModelBuildingRequest request ) { inputModel = readModel( request.getModelSource(), request.getPomFile(), request, problems ); } - + if ( modelCacheManager != null && request.getPomFile() != null ) + { + modelCacheManager.put( request.getPomFile().toPath(), inputModel ); + } + problems.setRootModel( inputModel ); ModelData resultData = new ModelData( request.getModelSource(), inputModel ); @@ -755,7 +765,7 @@ private void assembleInheritance( List lineage, ModelBuildingRequest } // re-read model from file - if ( Boolean.getBoolean( "maven.experimental.buildconsumer" ) ) + if ( Boolean.getBoolean( "maven.experimental.buildconsumer" ) && !lineage.get( 0 ).isExternal() ) { try { @@ -791,9 +801,12 @@ private InputStream transformData( ModelData modelData ) final PipedOutputStream pipedOutputStream = new PipedOutputStream(); final PipedInputStream pipedInputStream = new PipedInputStream( pipedOutputStream ); + + // Should always be FileSource for reactor poms + FileSource source = (FileSource) modelData.getSource(); final SAXSource transformSource = - new SAXSource( buildPomXMLFilterFactory.get().get( modelData.getGroupId(), modelData.getArtifactId() ), + new SAXSource( buildPomXMLFilterFactory.get().get( source.getFile().toPath() ), new org.xml.sax.InputSource( modelData.getSource().getInputStream() ) ); final StreamResult result = new StreamResult( pipedOutputStream ); @@ -1103,6 +1116,8 @@ private ModelData readParentLocally( Model childModel, ModelSource childSource, */ ModelData parentData = new ModelData( candidateSource, candidateModel, groupId, artifactId, version ); + + parentData.setExternal( false ); return parentData; } @@ -1220,6 +1235,8 @@ public int getValidationLevel() ModelData parentData = new ModelData( modelSource, parentModel, parent.getGroupId(), parent.getArtifactId(), parent.getVersion() ); + parentData.setExternal( true ); + return parentData; } diff --git a/maven-model-builder/src/main/java/org/apache/maven/model/building/DefaultModelCacheManager.java b/maven-model-builder/src/main/java/org/apache/maven/model/building/DefaultModelCacheManager.java new file mode 100644 index 000000000000..9a87805c158b --- /dev/null +++ b/maven-model-builder/src/main/java/org/apache/maven/model/building/DefaultModelCacheManager.java @@ -0,0 +1,55 @@ +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.Collections; +import java.util.HashMap; +import java.util.Map; + +import javax.inject.Named; +import javax.inject.Singleton; + +import org.apache.maven.model.Model; + +/** + * + * @author Robert Scholte + * @since 3.7.0 + */ +@Named +@Singleton +public class DefaultModelCacheManager implements ModelCacheManager +{ + private static final Map RAWMODELCACHE = Collections.synchronizedMap( new HashMap() ); + + @Override + public void put( Path p, Model t ) + { + RAWMODELCACHE.put( p, t ); + } + + @Override + public Model get( Path p ) + { + return RAWMODELCACHE.get( p ); + } + +} diff --git a/maven-model-builder/src/main/java/org/apache/maven/model/building/ModelCacheManager.java b/maven-model-builder/src/main/java/org/apache/maven/model/building/ModelCacheManager.java new file mode 100644 index 000000000000..6619607d3be3 --- /dev/null +++ b/maven-model-builder/src/main/java/org/apache/maven/model/building/ModelCacheManager.java @@ -0,0 +1,38 @@ +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 org.apache.maven.model.Model; + +/** + * Registers models for usage later on + * + * @author Robert Scholte + * @since 3.7.0 + */ +public interface ModelCacheManager +{ + void put( Path p, Model t ); + + Model get( Path p ); + +} 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 1f39ad443b80..2d093c6ba31e 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 @@ -45,6 +45,8 @@ class ModelData private String artifactId; private String version; + + private boolean external = true; /** * Creates a new container for the specified model. @@ -199,6 +201,25 @@ public void setVersion( String version ) this.version = version; } + /** + * + * @return {@code false} if model is part of reactor, otherwise {@code true} + */ + public boolean isExternal() + { + return external; + } + + /** + * Set to {@code false} if model is part of reactor, otherwise {@code true} + * + * @param external + */ + public void setExternal( boolean external ) + { + this.external = external; + } + /** * Gets the effective identifier of the model in the form {@code ::}. * @@ -212,7 +233,7 @@ public String getId() return buffer.toString(); } - + @Override public String toString() { diff --git a/maven-model-builder/src/main/java/org/apache/maven/model/validation/DefaultModelValidator.java b/maven-model-builder/src/main/java/org/apache/maven/model/validation/DefaultModelValidator.java index cfa6e20f6cdc..15a55878bdc8 100644 --- a/maven-model-builder/src/main/java/org/apache/maven/model/validation/DefaultModelValidator.java +++ b/maven-model-builder/src/main/java/org/apache/maven/model/validation/DefaultModelValidator.java @@ -98,8 +98,12 @@ public void validateRawModel( Model m, ModelBuildingRequest request, ModelProble validateStringNotEmpty( "parent.artifactId", problems, Severity.FATAL, Version.BASE, parent.getArtifactId(), parent ); - validateStringNotEmpty( "parent.version", problems, Severity.FATAL, Version.BASE, parent.getVersion(), - parent ); + // resolvedModel will assign version based on relativePath + if ( !Boolean.getBoolean( "maven.experimental.buildconsumer" ) ) + { + validateStringNotEmpty( "parent.version", problems, Severity.FATAL, Version.BASE, parent.getVersion(), + parent ); + } if ( equals( parent.getGroupId(), m.getGroupId() ) && equals( parent.getArtifactId(), m.getArtifactId() ) ) { diff --git a/maven-xml/src/main/java/org/apache/maven/xml/filter/BuildPomXMLFilterFactory.java b/maven-xml/src/main/java/org/apache/maven/xml/filter/BuildPomXMLFilterFactory.java index 03cad018c9b6..7a3f52ac0909 100644 --- a/maven-xml/src/main/java/org/apache/maven/xml/filter/BuildPomXMLFilterFactory.java +++ b/maven-xml/src/main/java/org/apache/maven/xml/filter/BuildPomXMLFilterFactory.java @@ -19,7 +19,9 @@ * under the License. */ +import java.nio.file.Path; import java.util.Optional; +import java.util.function.Function; import javax.xml.parsers.ParserConfigurationException; import javax.xml.parsers.SAXParserFactory; @@ -35,23 +37,31 @@ */ public abstract class BuildPomXMLFilterFactory { - public final BuildPomXMLFilter get( String groupId, String artifactId ) + public final BuildPomXMLFilter get( Path projectFile ) throws SAXException, ParserConfigurationException { - CiFriendlyXMLFilter filter = new CiFriendlyXMLFilter(); - getChangelist().ifPresent( filter::setChangelist ); - getRevision().ifPresent( filter::setRevision ); - getSha1().ifPresent( filter::setSha1 ); + XMLReader parent = getParent(); - if ( filter.isSet() ) + if ( getRelativePathMapper() != null ) { - filter.setParent( getParent() ); - return new BuildPomXMLFilter( filter ); + ParentXMLFilter parentFilter = new ParentXMLFilter( getRelativePathMapper() ); + parentFilter.setProjectPath( projectFile.getParent() ); + parentFilter.setParent( parent ); + parent = parentFilter; } - else + + CiFriendlyXMLFilter ciFriendlyFilter = new CiFriendlyXMLFilter(); + getChangelist().ifPresent( ciFriendlyFilter::setChangelist ); + getRevision().ifPresent( ciFriendlyFilter::setRevision ); + getSha1().ifPresent( ciFriendlyFilter::setSha1 ); + + if ( ciFriendlyFilter.isSet() ) { - return new BuildPomXMLFilter( getParent() ); + ciFriendlyFilter.setParent( parent ); + parent = ciFriendlyFilter; } + + return new BuildPomXMLFilter( parent ); } protected XMLReader getParent() throws SAXException, ParserConfigurationException @@ -67,4 +77,9 @@ protected XMLReader getParent() throws SAXException, ParserConfigurationExceptio protected abstract Optional getRevision(); protected abstract Optional getSha1(); + + /** + * @return the mapper or {@code null} if relativePaths don't need to be mapped + */ + protected abstract Function> getRelativePathMapper(); } diff --git a/maven-xml/src/main/java/org/apache/maven/xml/filter/ConsumerPomXMLFilterFactory.java b/maven-xml/src/main/java/org/apache/maven/xml/filter/ConsumerPomXMLFilterFactory.java index c185fdfb4186..dfea9ba06aa5 100644 --- a/maven-xml/src/main/java/org/apache/maven/xml/filter/ConsumerPomXMLFilterFactory.java +++ b/maven-xml/src/main/java/org/apache/maven/xml/filter/ConsumerPomXMLFilterFactory.java @@ -19,6 +19,8 @@ * under the License. */ +import java.nio.file.Path; + import javax.inject.Inject; import javax.inject.Provider; import javax.xml.parsers.ParserConfigurationException; @@ -47,10 +49,10 @@ public ConsumerPomXMLFilterFactory() this.buildPomXMLFilterFactory = buildPomXMLFilterFactory; } - public final ConsumerPomXMLFilter get( String groupId, String artifactId ) + public final ConsumerPomXMLFilter get( Path projectPath ) throws SAXException, ParserConfigurationException { - XMLFilter parent = buildPomXMLFilterFactory.get().get( groupId, artifactId ); + XMLFilter parent = buildPomXMLFilterFactory.get().get( projectPath ); // Ensure that xs:any elements aren't touched by next filters XMLReader filter = new FastForwardFilter( parent ); diff --git a/maven-xml/src/main/java/org/apache/maven/xml/filter/ParentXMLFilter.java b/maven-xml/src/main/java/org/apache/maven/xml/filter/ParentXMLFilter.java new file mode 100644 index 000000000000..244ecc576f1e --- /dev/null +++ b/maven-xml/src/main/java/org/apache/maven/xml/filter/ParentXMLFilter.java @@ -0,0 +1,313 @@ +package org.apache.maven.xml.filter; + +/* + * 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.nio.file.Paths; + +import java.util.ArrayList; +import java.util.List; +import java.util.Objects; +import java.util.Optional; +import java.util.function.Function; + +import org.apache.maven.xml.SAXEvent; +import org.apache.maven.xml.SAXEventFactory; +import org.apache.maven.xml.SAXEventUtils; +import org.xml.sax.Attributes; +import org.xml.sax.Locator; +import org.xml.sax.SAXException; +import org.xml.sax.helpers.XMLFilterImpl; + +/** + *

          + * Transforms relativePath to version. + * We could decide to simply allow {@code }, but let's require the GA for now for checking + *

          + * + * @author Robert Scholte + */ +class ParentXMLFilter + extends XMLFilterImpl +{ + private boolean parsingParent = false; + + // states + private String state; + + private String groupId; + + private String artifactId; + + private String relativePath; + + private boolean hasVersion; + + private Optional resolvedParent; + + private char[] linebreak; + + private List saxEvents = new ArrayList<>(); + + private SAXEventFactory eventFactory; + + private final Function> relativePathMapper; + + private Path projectPath; + + /** + * + * + * @param relativePathMapper + */ + ParentXMLFilter( Function> relativePathMapper ) + { + this.relativePathMapper = relativePathMapper; + } + + public void setProjectPath( Path projectPath ) + { + this.projectPath = projectPath; + } + + private SAXEventFactory getEventFactory() + { + if ( eventFactory == null ) + { + eventFactory = SAXEventFactory.newInstance( getContentHandler() ); + } + return eventFactory; + } + + private void processEvent( final SAXEvent event ) + throws SAXException + { + if ( parsingParent ) + { + final String eventState = state; + + saxEvents.add( () -> + { + if ( !( "relativePath".equals( eventState ) && resolvedParent.isPresent() ) ) + { + event.execute(); + } + } ); + } + else + { + event.execute(); + } + } + + @Override + public void startElement( String uri, final String localName, String qName, Attributes atts ) + throws SAXException + { + if ( !parsingParent && "parent".equals( localName ) ) + { + parsingParent = true; + } + + if ( parsingParent ) + { + state = localName; + + hasVersion |= "version".equals( localName ); + } + + processEvent( getEventFactory().startElement( uri, localName, qName, atts ) ); + } + + @Override + public void characters( char[] ch, int start, int length ) + throws SAXException + { + if ( parsingParent ) + { + final String eventState = state; + + switch ( eventState ) + { + case "parent": + int l; + for ( l = length ; l >= 0; l-- ) + { + int i = start + l - 1; + if ( ch[i] == '\n' || ch[i] == '\r' ) + { + break; + } + } + + linebreak = new char[l]; + System.arraycopy( ch, start, linebreak, 0, l ); + break; + case "relativePath": + relativePath = new String( ch, start, length ); + break; + case "groupId": + groupId = new String( ch, start, length ); + break; + case "artifactId": + artifactId = new String( ch, start, length ); + break; + default: + break; + } + } + + processEvent( getEventFactory().characters( ch, start, length ) ); + } + + @Override + public void endDocument() + throws SAXException + { + processEvent( getEventFactory().endDocument() ); + } + + @Override + public void endElement( String uri, final String localName, String qName ) + throws SAXException + { + if ( parsingParent ) + { + switch ( localName ) + { + case "parent": + if ( !hasVersion || relativePath != null ) + { + resolvedParent = + resolveRelativePath( Paths.get( Objects.toString( relativePath, "../pom.xml" ) ) ); + } + + // not with streams due to checked SAXException + for ( SAXEvent saxEvent : saxEvents ) + { + saxEvent.execute(); + } + + if ( !hasVersion && resolvedParent.isPresent() ) + { + String versionQName = SAXEventUtils.renameQName( qName, "version" ); + + getEventFactory().startElement( uri, "version", versionQName, null ).execute(); + + String resolvedParentVersion = resolvedParent.get().getVersion(); + + getEventFactory().characters( resolvedParentVersion.toCharArray(), 0, + resolvedParentVersion.length() ).execute(); + + getEventFactory().endElement( uri, "version", versionQName ).execute(); + + if ( linebreak != null ) + { + getEventFactory().characters( linebreak, 0, linebreak.length ).execute(); + } + } + + parsingParent = false; + break; + default: + break; + } + } + + processEvent( getEventFactory().endElement( uri, localName, qName ) ); + + // for this simple structure resetting to parent it sufficient + state = "parent"; + } + + @Override + public void endPrefixMapping( String prefix ) + throws SAXException + { + processEvent( getEventFactory().endPrefixMapping( prefix ) ); + } + + @Override + public void ignorableWhitespace( char[] ch, int start, int length ) + throws SAXException + { + processEvent( getEventFactory().ignorableWhitespace( ch, start, length ) ); + } + + @Override + public void processingInstruction( String target, String data ) + throws SAXException + { + processEvent( getEventFactory().processingInstruction( target, data ) ); + + } + + @Override + public void setDocumentLocator( Locator locator ) + { + try + { + processEvent( getEventFactory().setDocumentLocator( locator ) ); + } + catch ( SAXException e ) + { + // noop + } + } + + @Override + public void skippedEntity( String name ) + throws SAXException + { + processEvent( getEventFactory().skippedEntity( name ) ); + } + + @Override + public void startDocument() + throws SAXException + { + processEvent( getEventFactory().startDocument() ); + } + + @Override + public void startPrefixMapping( String prefix, String uri ) + throws SAXException + { + processEvent( getEventFactory().startPrefixMapping( prefix, uri ) ); + } + + protected Optional resolveRelativePath( Path relativePath ) + { + Optional mappedProject = + relativePathMapper.apply( projectPath.resolve( relativePath ).normalize() ); + + if ( mappedProject.isPresent() ) + { + RelativeProject project = mappedProject.get(); + + if ( Objects.equals( groupId, project.getGroupId() ) + && Objects.equals( artifactId, project.getArtifactId() ) ) + { + return mappedProject; + } + } + return Optional.empty(); + } +} diff --git a/maven-xml/src/main/java/org/apache/maven/xml/filter/RelativeProject.java b/maven-xml/src/main/java/org/apache/maven/xml/filter/RelativeProject.java new file mode 100644 index 000000000000..bbceff36597d --- /dev/null +++ b/maven-xml/src/main/java/org/apache/maven/xml/filter/RelativeProject.java @@ -0,0 +1,56 @@ +package org.apache.maven.xml.filter; + +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +/** + * + * @author Robert Scholte + * @since 3.7.0 + */ +public class RelativeProject +{ + private String groupId; + + private String artifactId; + + private String version; + + public RelativeProject( String groupId, String artifactId, String version ) + { + this.groupId = groupId; + this.artifactId = artifactId; + this.version = version; + } + + public String getGroupId() + { + return groupId; + } + + public String getArtifactId() + { + return artifactId; + } + + public String getVersion() + { + return version; + } +} diff --git a/maven-xml/src/test/java/org/apache/maven/xml/filter/AbstractXMLFilterTests.java b/maven-xml/src/test/java/org/apache/maven/xml/filter/AbstractXMLFilterTests.java index 4ee0e313690c..e406f6c9e544 100644 --- a/maven-xml/src/test/java/org/apache/maven/xml/filter/AbstractXMLFilterTests.java +++ b/maven-xml/src/test/java/org/apache/maven/xml/filter/AbstractXMLFilterTests.java @@ -46,22 +46,38 @@ public AbstractXMLFilterTests() protected abstract XMLFilter getFilter() throws TransformerException, SAXException, ParserConfigurationException; + private void setParent( XMLFilter filter ) throws SAXException, ParserConfigurationException + { + if( filter.getParent() == null ) + { + filter.setParent( SAXParserFactory.newInstance().newSAXParser().getXMLReader() ); + filter.setFeature( "http://xml.org/sax/features/namespaces", true ); + } + } protected String transform( String input ) throws TransformerException, SAXException, ParserConfigurationException { return transform( new StringReader( input ) ); } + + protected String transform( Reader input ) throws TransformerException, SAXException, ParserConfigurationException + { + XMLFilter filter = getFilter(); + setParent( filter ); + return transform( input, filter ); + } - protected String transform( Reader input ) + protected String transform( String input, XMLFilter filter ) + throws TransformerException, SAXException, ParserConfigurationException + { + setParent( filter ); + return transform( new StringReader( input ), filter ); + } + + protected String transform( Reader input, XMLFilter filter ) throws TransformerException, SAXException, ParserConfigurationException { - XMLFilter filter = getFilter(); - if( filter.getParent() == null ) - { - filter.setParent( SAXParserFactory.newInstance().newSAXParser().getXMLReader() ); - filter.setFeature( "http://xml.org/sax/features/namespaces", true ); - } Writer writer = new StringWriter(); StreamResult result = new StreamResult( writer ); diff --git a/maven-xml/src/test/java/org/apache/maven/xml/filter/ConsumerPomXMLFilterTest.java b/maven-xml/src/test/java/org/apache/maven/xml/filter/ConsumerPomXMLFilterTest.java index 8fe2d67e4b56..b02589e72285 100644 --- a/maven-xml/src/test/java/org/apache/maven/xml/filter/ConsumerPomXMLFilterTest.java +++ b/maven-xml/src/test/java/org/apache/maven/xml/filter/ConsumerPomXMLFilterTest.java @@ -21,7 +21,10 @@ import static org.xmlunit.assertj.XmlAssert.assertThat; +import java.nio.file.Path; +import java.nio.file.Paths; import java.util.Optional; +import java.util.function.Function; import javax.inject.Provider; import javax.xml.parsers.ParserConfigurationException; @@ -54,6 +57,12 @@ protected Optional getChangelist() { return Optional.of( "CL" ); } + + @Override + protected Function> getRelativePathMapper() + { + return null; + } }; Provider provider = new Provider() @@ -68,7 +77,7 @@ public BuildPomXMLFilterFactory get() XMLFilter filter = new ConsumerPomXMLFilterFactory( provider ) { - }.get( "G", "A" ); + }.get( Paths.get( "pom.xml" ) ); filter.setFeature( "http://xml.org/sax/features/namespaces", true ); return filter; } diff --git a/maven-xml/src/test/java/org/apache/maven/xml/filter/ParentXMLFilterTest.java b/maven-xml/src/test/java/org/apache/maven/xml/filter/ParentXMLFilterTest.java new file mode 100644 index 000000000000..aa70b0db9a97 --- /dev/null +++ b/maven-xml/src/test/java/org/apache/maven/xml/filter/ParentXMLFilterTest.java @@ -0,0 +1,185 @@ +package org.apache.maven.xml.filter; + +/* + * 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 static org.junit.Assert.assertEquals; + +import java.nio.file.Paths; +import java.util.Optional; + +import javax.xml.parsers.ParserConfigurationException; +import javax.xml.transform.TransformerException; + +import org.junit.Test; +import org.xml.sax.SAXException; +import org.xml.sax.XMLFilter; + +public class ParentXMLFilterTest extends AbstractXMLFilterTests +{ + @Override + protected XMLFilter getFilter() + throws TransformerException, SAXException, ParserConfigurationException + { + ParentXMLFilter filter = new ParentXMLFilter( x -> Optional.of( new RelativeProject( "GROUPID", + "ARTIFACTID", + "1.0.0" ) ) ); + filter.setProjectPath( Paths.get( "pom.xml").toAbsolutePath() ); + + return filter; + } + + @Test + public void testMinimum() throws Exception + { + String input = ""; + String expected = input; + String actual = transform( input ); + assertEquals( expected, actual ); + } + + @Test + public void testNoRelativePath() throws Exception + { + String input = "" + + "GROUPID" + + "ARTIFACTID" + + "VERSION" + + ""; + String expected = input; + + String actual = transform( input ); + + assertEquals( expected, actual ); + } + + @Test + public void testDefaultRelativePath() throws Exception + { + String input = "" + + "GROUPID" + + "ARTIFACTID" + + ""; + String expected = "" + + "GROUPID" + + "ARTIFACTID" + + "1.0.0" + + ""; + + String actual = transform( input ); + + assertEquals( expected, actual ); + } + + @Test + public void testNoVersion() throws Exception + { + String input = "" + + "GROUPID" + + "ARTIFACTID" + + "RELATIVEPATH" + + ""; + String expected = "" + + "GROUPID" + + "ARTIFACTID" + + "1.0.0" + + ""; + + String actual = transform( input ); + + assertEquals( expected, actual ); + } + + @Test + public void testInvalidRelativePath() throws Exception + { + ParentXMLFilter filter = new ParentXMLFilter( x -> Optional.ofNullable( null ) ); + filter.setProjectPath( Paths.get( "pom.xml").toAbsolutePath() ); + + String input = "" + + "GROUPID" + + "ARTIFACTID" + + "RELATIVEPATH" + + ""; + String expected = input; + + String actual = transform( input, filter ); + + assertEquals( expected, actual ); + } + + @Test + public void testRelativePathAndVersion() throws Exception + { + String input = "" + + "GROUPID" + + "ARTIFACTID" + + "RELATIVEPATH" + + "1.0.0" + + ""; + String expected = "" + + "GROUPID" + + "ARTIFACTID" + + "1.0.0" + + ""; + + String actual = transform( input ); + + assertEquals( expected, actual ); + } + + @Test + public void testWithWeirdNamespace() throws Exception + { + String input = "" + + "GROUPID" + + "ARTIFACTID" + + "RELATIVEPATH" + + ""; + String expected = "" + + "GROUPID" + + "ARTIFACTID" + + "1.0.0" + + ""; + + String actual = transform( input ); + + assertEquals( expected, actual ); + } + + + @Test + public void testIndent() throws Exception + { + String input = "\n" + + " GROUPID\n" + + " ARTIFACTID\n" + + " "; + // transformer is responsible for line separator and indents + String expected = "" + System.lineSeparator() + + " GROUPID" + System.lineSeparator() + + " ARTIFACTID" + System.lineSeparator() + + " 1.0.0" + System.lineSeparator() + + ""; + + String actual = transform( input ); + + assertEquals( expected, actual ); + } +} diff --git a/pom.xml b/pom.xml index bed263330fd6..5c23389235e5 100644 --- a/pom.xml +++ b/pom.xml @@ -47,8 +47,8 @@ under the License. 3.0.5 - 1.7 - 1.7 + 1.8 + 1.8 2.6.0 1.4 3.8.1 @@ -454,27 +454,6 @@ under the License. - - org.apache.maven.plugins - maven-enforcer-plugin - - - enforce-bytecode-version - - enforce - - - - - - org.apache.maven:maven-xml - - - - - - - org.codehaus.plexus plexus-component-metadata @@ -604,7 +583,7 @@ under the License. org.codehaus.mojo.signature - java17 + java18 1.0 From 712b95fe7d317e6714e5d82e0a7dfd4f39a6e9ae Mon Sep 17 00:00:00 2001 From: rfscholte Date: Thu, 29 Aug 2019 18:44:31 +0200 Subject: [PATCH 14/52] [MNG-6656] Support reactor managed versions --- .../maven/project/DefaultProjectBuilder.java | 2 + .../DefaultBuildPomXMLFilterFactory.java | 20 +++ .../model/building/DefaultModelBuilder.java | 17 +-- .../building/DefaultModelBuildingRequest.java | 16 ++ .../building/DefaultModelCacheManager.java | 27 +++- .../building/FilterModelBuildingRequest.java | 12 ++ .../model/building/ModelBuildingRequest.java | 5 +- .../model/building/ModelCacheManager.java | 3 + .../maven/model/building/ModelData.java | 21 --- .../xml/filter/BuildPomXMLFilterFactory.java | 14 +- .../maven/xml/filter/DependencyKey.java | 88 +++++++++++ .../maven/xml/filter/ParentXMLFilter.java | 2 +- .../filter/ReactorDependencyXMLFilter.java | 140 ++++++++++++++++++ .../maven/xml/filter/RelativeProject.java | 6 +- .../xml/filter/ConsumerPomXMLFilterTest.java | 6 + .../ReactorDependencyXMLFilterTest.java | 89 +++++++++++ 16 files changed, 427 insertions(+), 41 deletions(-) create mode 100644 maven-xml/src/main/java/org/apache/maven/xml/filter/DependencyKey.java create mode 100644 maven-xml/src/main/java/org/apache/maven/xml/filter/ReactorDependencyXMLFilter.java create mode 100644 maven-xml/src/test/java/org/apache/maven/xml/filter/ReactorDependencyXMLFilterTest.java 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 7e18f1ef3ce2..c3a0a8f9f549 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 @@ -164,6 +164,7 @@ private ProjectBuildingResult build( File pomFile, ModelSource modelSource, Inte request.setModelBuildingListener( listener ); request.setPomFile( pomFile ); + request.setTransformPom( true ); request.setModelSource( modelSource ); request.setLocationTracking( true ); @@ -437,6 +438,7 @@ private boolean build( List results, List request.setPomFile( pomFile ); request.setTwoPhaseBuilding( true ); request.setLocationTracking( true ); + request.setTransformPom( true ); DefaultModelBuildingListener listener = new DefaultModelBuildingListener( project, projectBuildingHelper, config.request ); diff --git a/maven-core/src/main/java/org/apache/maven/xml/internal/DefaultBuildPomXMLFilterFactory.java b/maven-core/src/main/java/org/apache/maven/xml/internal/DefaultBuildPomXMLFilterFactory.java index cdded2bca759..e1b5ab500535 100644 --- a/maven-core/src/main/java/org/apache/maven/xml/internal/DefaultBuildPomXMLFilterFactory.java +++ b/maven-core/src/main/java/org/apache/maven/xml/internal/DefaultBuildPomXMLFilterFactory.java @@ -32,6 +32,7 @@ import org.apache.maven.model.Model; import org.apache.maven.model.building.ModelCacheManager; import org.apache.maven.xml.filter.BuildPomXMLFilterFactory; +import org.apache.maven.xml.filter.DependencyKey; import org.apache.maven.xml.filter.RelativeProject; /** @@ -77,6 +78,14 @@ protected Function> getRelativePathMapper() { return p -> Optional.ofNullable( rawModelCache.get( p ) ).map( m -> toRelativeProject( m ) ); } + + @Override + protected Function getDependencyKeyToVersionMapper() + { + return k -> Optional.ofNullable( rawModelCache.get( k ) ) + .map( m -> toVersion( m ) ) + .orElse( null ); + } private RelativeProject toRelativeProject( final Model m ) { @@ -94,4 +103,15 @@ private RelativeProject toRelativeProject( final Model m ) return new RelativeProject( groupId, m.getArtifactId(), version ); } + + private String toVersion( final Model m ) + { + String version = m.getVersion(); + if ( version == null && m.getParent() != null ) + { + version = m.getParent().getVersion(); + } + + return version; + } } 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 0b0a615ea8c3..d60e68dda02b 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 @@ -300,10 +300,6 @@ public ModelBuildingResult build( ModelBuildingRequest request ) { inputModel = readModel( request.getModelSource(), request.getPomFile(), request, problems ); } - if ( modelCacheManager != null && request.getPomFile() != null ) - { - modelCacheManager.put( request.getPomFile().toPath(), inputModel ); - } problems.setRootModel( inputModel ); @@ -439,6 +435,11 @@ else if ( !parentIds.add( parentData.getId() ) ) resultData.setVersion( resultModel.getVersion() ); result.setEffectiveModel( resultModel ); + + if ( modelCacheManager != null && request.getPomFile() != null ) + { + modelCacheManager.put( request.getPomFile().toPath(), resultModel ); + } for ( ModelData currentData : lineage ) { @@ -765,7 +766,7 @@ private void assembleInheritance( List lineage, ModelBuildingRequest } // re-read model from file - if ( Boolean.getBoolean( "maven.experimental.buildconsumer" ) && !lineage.get( 0 ).isExternal() ) + if ( Boolean.getBoolean( "maven.experimental.buildconsumer" ) && request.isTransformPom() ) { try { @@ -805,6 +806,8 @@ private InputStream transformData( ModelData modelData ) // Should always be FileSource for reactor poms FileSource source = (FileSource) modelData.getSource(); + System.out.println( "transforming " + source.getFile() ); + final SAXSource transformSource = new SAXSource( buildPomXMLFilterFactory.get().get( source.getFile().toPath() ), new org.xml.sax.InputSource( modelData.getSource().getInputStream() ) ); @@ -1116,8 +1119,6 @@ private ModelData readParentLocally( Model childModel, ModelSource childSource, */ ModelData parentData = new ModelData( candidateSource, candidateModel, groupId, artifactId, version ); - - parentData.setExternal( false ); return parentData; } @@ -1235,8 +1236,6 @@ public int getValidationLevel() ModelData parentData = new ModelData( modelSource, parentModel, parent.getGroupId(), parent.getArtifactId(), parent.getVersion() ); - parentData.setExternal( true ); - return parentData; } 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 84a68f74c8fb..06128a8ec64c 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 @@ -72,6 +72,8 @@ public class DefaultModelBuildingRequest private ModelCache modelCache; private WorkspaceModelResolver workspaceResolver; + + private boolean transformPom; /** * Creates an empty request. @@ -101,6 +103,7 @@ public DefaultModelBuildingRequest( ModelBuildingRequest request ) setModelResolver( request.getModelResolver() ); setModelBuildingListener( request.getModelBuildingListener() ); setModelCache( request.getModelCache() ); + setTransformPom( request.isTransformPom() ); } @Override @@ -407,5 +410,18 @@ public ModelBuildingRequest setWorkspaceModelResolver( WorkspaceModelResolver wo this.workspaceResolver = workspaceResolver; return this; } + + @Override + public boolean isTransformPom() + { + return transformPom; + } + + @Override + public ModelBuildingRequest setTransformPom( boolean transformPom ) + { + this.transformPom = transformPom; + return this; + } } diff --git a/maven-model-builder/src/main/java/org/apache/maven/model/building/DefaultModelCacheManager.java b/maven-model-builder/src/main/java/org/apache/maven/model/building/DefaultModelCacheManager.java index 9a87805c158b..f33d71388e4e 100644 --- a/maven-model-builder/src/main/java/org/apache/maven/model/building/DefaultModelCacheManager.java +++ b/maven-model-builder/src/main/java/org/apache/maven/model/building/DefaultModelCacheManager.java @@ -28,6 +28,7 @@ import javax.inject.Singleton; import org.apache.maven.model.Model; +import org.apache.maven.xml.filter.DependencyKey; /** * @@ -38,18 +39,36 @@ @Singleton public class DefaultModelCacheManager implements ModelCacheManager { - private static final Map RAWMODELCACHE = Collections.synchronizedMap( new HashMap() ); + private static final Map MODELCACHE = Collections.synchronizedMap( new HashMap() ); + + private static final Map DEPKEYMODELCACHE = + Collections.synchronizedMap( new HashMap() ); @Override - public void put( Path p, Model t ) + public void put( Path p, Model m ) { - RAWMODELCACHE.put( p, t ); + MODELCACHE.put( p, m ); + + String groupId = m.getGroupId(); + if ( groupId == null && m.getParent() != null ) + { + groupId = m.getParent().getGroupId(); + } + + String artifactId = m.getArtifactId(); + DEPKEYMODELCACHE.put( new DependencyKey( groupId, artifactId ), m ); } @Override public Model get( Path p ) { - return RAWMODELCACHE.get( p ); + return MODELCACHE.get( p ); + } + + @Override + public Model get( DependencyKey k ) + { + return DEPKEYMODELCACHE.get( k ); } } 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 a51126f280ae..a9012a176030 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 @@ -282,4 +282,16 @@ public ModelBuildingRequest setWorkspaceModelResolver( WorkspaceModelResolver wo return this; } + @Override + public boolean isTransformPom() + { + return request.isTransformPom(); + } + + @Override + public ModelBuildingRequest setTransformPom( boolean transform ) + { + request.setTransformPom( transform ); + return this; + } } \ No newline at end of file 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 dce0c321d0c3..10aedc103e65 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 @@ -334,5 +334,8 @@ public interface ModelBuildingRequest WorkspaceModelResolver getWorkspaceModelResolver(); ModelBuildingRequest setWorkspaceModelResolver( WorkspaceModelResolver workspaceResolver ); - + + boolean isTransformPom(); + + ModelBuildingRequest setTransformPom( boolean transform ); } diff --git a/maven-model-builder/src/main/java/org/apache/maven/model/building/ModelCacheManager.java b/maven-model-builder/src/main/java/org/apache/maven/model/building/ModelCacheManager.java index 6619607d3be3..f28116fbfd4f 100644 --- a/maven-model-builder/src/main/java/org/apache/maven/model/building/ModelCacheManager.java +++ b/maven-model-builder/src/main/java/org/apache/maven/model/building/ModelCacheManager.java @@ -22,6 +22,7 @@ import java.nio.file.Path; import org.apache.maven.model.Model; +import org.apache.maven.xml.filter.DependencyKey; /** * Registers models for usage later on @@ -34,5 +35,7 @@ public interface ModelCacheManager void put( Path p, Model t ); Model get( Path p ); + + Model get( DependencyKey k ); } 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 2d093c6ba31e..5117602ca071 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 @@ -46,8 +46,6 @@ class ModelData private String version; - private boolean external = true; - /** * Creates a new container for the specified model. * @@ -201,25 +199,6 @@ public void setVersion( String version ) this.version = version; } - /** - * - * @return {@code false} if model is part of reactor, otherwise {@code true} - */ - public boolean isExternal() - { - return external; - } - - /** - * Set to {@code false} if model is part of reactor, otherwise {@code true} - * - * @param external - */ - public void setExternal( boolean external ) - { - this.external = external; - } - /** * Gets the effective identifier of the model in the form {@code ::}. * diff --git a/maven-xml/src/main/java/org/apache/maven/xml/filter/BuildPomXMLFilterFactory.java b/maven-xml/src/main/java/org/apache/maven/xml/filter/BuildPomXMLFilterFactory.java index 7a3f52ac0909..83eafe60e287 100644 --- a/maven-xml/src/main/java/org/apache/maven/xml/filter/BuildPomXMLFilterFactory.java +++ b/maven-xml/src/main/java/org/apache/maven/xml/filter/BuildPomXMLFilterFactory.java @@ -41,7 +41,15 @@ public final BuildPomXMLFilter get( Path projectFile ) throws SAXException, ParserConfigurationException { XMLReader parent = getParent(); - + + if ( getDependencyKeyToVersionMapper() != null ) + { + ReactorDependencyXMLFilter reactorDependencyXMLFilter = + new ReactorDependencyXMLFilter( getDependencyKeyToVersionMapper() ); + reactorDependencyXMLFilter.setParent( parent ); + parent = reactorDependencyXMLFilter; + } + if ( getRelativePathMapper() != null ) { ParentXMLFilter parentFilter = new ParentXMLFilter( getRelativePathMapper() ); @@ -60,7 +68,7 @@ public final BuildPomXMLFilter get( Path projectFile ) ciFriendlyFilter.setParent( parent ); parent = ciFriendlyFilter; } - + return new BuildPomXMLFilter( parent ); } @@ -82,4 +90,6 @@ protected XMLReader getParent() throws SAXException, ParserConfigurationExceptio * @return the mapper or {@code null} if relativePaths don't need to be mapped */ protected abstract Function> getRelativePathMapper(); + + protected abstract Function getDependencyKeyToVersionMapper(); } diff --git a/maven-xml/src/main/java/org/apache/maven/xml/filter/DependencyKey.java b/maven-xml/src/main/java/org/apache/maven/xml/filter/DependencyKey.java new file mode 100644 index 000000000000..bf91cf97255e --- /dev/null +++ b/maven-xml/src/main/java/org/apache/maven/xml/filter/DependencyKey.java @@ -0,0 +1,88 @@ +package org.apache.maven.xml.filter; + +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +import java.util.Objects; + +/** + * + * @author Robert Scholte + * @since 3.7.0 + */ +public class DependencyKey +{ + private final String groupId; + + private final String artifactId; + + public DependencyKey( String groupId, String artifactId ) + { + this.groupId = groupId; + this.artifactId = artifactId; + } + + public String getGroupId() + { + return groupId; + } + + public String getArtifactId() + { + return artifactId; + } + + @Override + public int hashCode() + { + return Objects.hash( artifactId, groupId ); + } + + @Override + public boolean equals( Object obj ) + { + if ( this == obj ) + { + return true; + } + if ( obj == null ) + { + return false; + } + if ( getClass() != obj.getClass() ) + { + return false; + } + + DependencyKey other = (DependencyKey) obj; + + if ( !Objects.equals( artifactId, other.artifactId ) ) + { + return false; + } + if ( !Objects.equals( groupId, other.groupId ) ) + { + return false; + } + + return true; + } + + +} diff --git a/maven-xml/src/main/java/org/apache/maven/xml/filter/ParentXMLFilter.java b/maven-xml/src/main/java/org/apache/maven/xml/filter/ParentXMLFilter.java index 244ecc576f1e..747a28300350 100644 --- a/maven-xml/src/main/java/org/apache/maven/xml/filter/ParentXMLFilter.java +++ b/maven-xml/src/main/java/org/apache/maven/xml/filter/ParentXMLFilter.java @@ -47,7 +47,7 @@ class ParentXMLFilter extends XMLFilterImpl { - private boolean parsingParent = false; + private boolean parsingParent; // states private String state; diff --git a/maven-xml/src/main/java/org/apache/maven/xml/filter/ReactorDependencyXMLFilter.java b/maven-xml/src/main/java/org/apache/maven/xml/filter/ReactorDependencyXMLFilter.java new file mode 100644 index 000000000000..a568df57cea1 --- /dev/null +++ b/maven-xml/src/main/java/org/apache/maven/xml/filter/ReactorDependencyXMLFilter.java @@ -0,0 +1,140 @@ +package org.apache.maven.xml.filter; + +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +import java.util.function.Function; + +import org.apache.maven.xml.SAXEventUtils; +import org.xml.sax.Attributes; +import org.xml.sax.SAXException; +import org.xml.sax.helpers.XMLFilterImpl; + +/** + * Will apply the version if the dependency is part of the reactor + * + * @author Robert Scholte + * @since 4.0.0 + */ +public class ReactorDependencyXMLFilter extends XMLFilterImpl +{ + private boolean parsingDependency; + + // states + private String state; + + private boolean hasVersion; + + private String groupId; + + private String artifactId; + + private final Function reactorVersionMapper; + + public ReactorDependencyXMLFilter( Function reactorVersionMapper ) + { + this.reactorVersionMapper = reactorVersionMapper; + } + + @Override + public void startElement( String uri, String localName, String qName, Attributes atts ) + throws SAXException + { + if ( !parsingDependency && "dependency".equals( localName ) ) + { + parsingDependency = true; + } + + if ( parsingDependency ) + { + state = localName; + + hasVersion |= "version".equals( localName ); + } + super.startElement( uri, localName, qName, atts ); + } + + @Override + public void characters( char[] ch, int start, int length ) + throws SAXException + { + if ( parsingDependency ) + { + final String eventState = state; + switch ( eventState ) + { + case "groupId": + groupId = new String( ch, start, length ); + break; + case "artifactId": + artifactId = new String( ch, start, length ); + break; + default: + break; + } + } + super.characters( ch, start, length ); + } + + @Override + public void endElement( String uri, final String localName, String qName ) + throws SAXException + { + if ( parsingDependency ) + { + switch ( localName ) + { + case "dependency": + if ( !hasVersion ) + { + String version = getVersion(); + + // dependency is not part of reactor, probably it is managed + if ( version != null ) + { + String versionQName = SAXEventUtils.renameQName( qName, "version" ); + super.startElement( uri, "version", versionQName, null ); + super.characters( version.toCharArray(), 0, version.length() ); + super.endElement( uri, "version", versionQName ); + } + } + parsingDependency = false; + + // reset + hasVersion = false; + groupId = null; + artifactId = null; + + break; + default: + break; + } + } + + super.endElement( uri, localName, qName ); + + state = "dependency"; + } + + private String getVersion() + { + return reactorVersionMapper.apply( new DependencyKey( groupId, artifactId ) ); + } + +} diff --git a/maven-xml/src/main/java/org/apache/maven/xml/filter/RelativeProject.java b/maven-xml/src/main/java/org/apache/maven/xml/filter/RelativeProject.java index bbceff36597d..a158d38ee215 100644 --- a/maven-xml/src/main/java/org/apache/maven/xml/filter/RelativeProject.java +++ b/maven-xml/src/main/java/org/apache/maven/xml/filter/RelativeProject.java @@ -26,11 +26,11 @@ */ public class RelativeProject { - private String groupId; + private final String groupId; - private String artifactId; + private final String artifactId; - private String version; + private final String version; public RelativeProject( String groupId, String artifactId, String version ) { diff --git a/maven-xml/src/test/java/org/apache/maven/xml/filter/ConsumerPomXMLFilterTest.java b/maven-xml/src/test/java/org/apache/maven/xml/filter/ConsumerPomXMLFilterTest.java index b02589e72285..5484ea6daaf2 100644 --- a/maven-xml/src/test/java/org/apache/maven/xml/filter/ConsumerPomXMLFilterTest.java +++ b/maven-xml/src/test/java/org/apache/maven/xml/filter/ConsumerPomXMLFilterTest.java @@ -63,6 +63,12 @@ protected Function> getRelativePathMapper() { return null; } + + @Override + protected Function getDependencyKeyToVersionMapper() + { + return null; + } }; Provider provider = new Provider() diff --git a/maven-xml/src/test/java/org/apache/maven/xml/filter/ReactorDependencyXMLFilterTest.java b/maven-xml/src/test/java/org/apache/maven/xml/filter/ReactorDependencyXMLFilterTest.java new file mode 100644 index 000000000000..6a5998ed7ac6 --- /dev/null +++ b/maven-xml/src/test/java/org/apache/maven/xml/filter/ReactorDependencyXMLFilterTest.java @@ -0,0 +1,89 @@ +package org.apache.maven.xml.filter; + +/* + * 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 static org.junit.Assert.*; + +import javax.xml.parsers.ParserConfigurationException; +import javax.xml.transform.TransformerException; + +import org.junit.Test; +import org.xml.sax.SAXException; +import org.xml.sax.XMLFilter; + +public class ReactorDependencyXMLFilterTest extends AbstractXMLFilterTests +{ + @Override + protected XMLFilter getFilter() + throws TransformerException, SAXException, ParserConfigurationException + { + return new ReactorDependencyXMLFilter( r -> "1.0.0" ); + } + + @Test + public void testDefaultDependency() throws Exception + { + String input = "" + + "GROUPID" + + "ARTIFACTID" + + "VERSION" + + ""; + String expected = input; + + String actual = transform( input ); + + assertEquals( expected, actual ); + } + + @Test + public void testManagedDependency() throws Exception + { + XMLFilter filter = new ReactorDependencyXMLFilter( r -> null ); + + String input = "" + + "GROUPID" + + "ARTIFACTID" + + ""; + String expected = input; + + String actual = transform( input, filter ); + + assertEquals( expected, actual ); + } + + @Test + public void testReactorDependency() throws Exception + { + String input = "" + + "GROUPID" + + "ARTIFACTID" + + ""; + String expected = "" + + "GROUPID" + + "ARTIFACTID" + + "1.0.0" + + ""; + + String actual = transform( input ); + + assertEquals( expected, actual ); + } + +} From b46a4c727026191977bea62f968a5b044f003cbc Mon Sep 17 00:00:00 2001 From: rfscholte Date: Tue, 10 Sep 2019 21:57:06 +0200 Subject: [PATCH 15/52] [MNG-6656] Update project versions --- apache-maven/pom.xml | 2 +- maven-artifact/pom.xml | 2 +- maven-builder-support/pom.xml | 2 +- maven-compat/pom.xml | 2 +- maven-core/pom.xml | 2 +- maven-embedder/pom.xml | 2 +- maven-model-builder/pom.xml | 2 +- maven-model/pom.xml | 2 +- maven-plugin-api/pom.xml | 2 +- maven-repository-metadata/pom.xml | 2 +- maven-resolver-provider/pom.xml | 2 +- maven-settings-builder/pom.xml | 2 +- maven-settings/pom.xml | 2 +- maven-slf4j-provider/pom.xml | 2 +- maven-xml/pom.xml | 2 +- pom.xml | 2 +- 16 files changed, 16 insertions(+), 16 deletions(-) diff --git a/apache-maven/pom.xml b/apache-maven/pom.xml index edbec830a36f..f57506afa0ea 100644 --- a/apache-maven/pom.xml +++ b/apache-maven/pom.xml @@ -25,7 +25,7 @@ under the License. org.apache.maven maven - 3.6.3-SNAPSHOT + 3.7.0-SNAPSHOT apache-maven diff --git a/maven-artifact/pom.xml b/maven-artifact/pom.xml index 834905ffd850..f9d78c862bfd 100644 --- a/maven-artifact/pom.xml +++ b/maven-artifact/pom.xml @@ -25,7 +25,7 @@ under the License. org.apache.maven maven - 3.6.3-SNAPSHOT + 3.7.0-SNAPSHOT maven-artifact diff --git a/maven-builder-support/pom.xml b/maven-builder-support/pom.xml index de4b9dbb6711..3a24e3d950d7 100644 --- a/maven-builder-support/pom.xml +++ b/maven-builder-support/pom.xml @@ -25,7 +25,7 @@ under the License. org.apache.maven maven - 3.6.3-SNAPSHOT + 3.7.0-SNAPSHOT maven-builder-support diff --git a/maven-compat/pom.xml b/maven-compat/pom.xml index 24bfbf1d4cff..058eeec7c0ab 100644 --- a/maven-compat/pom.xml +++ b/maven-compat/pom.xml @@ -25,7 +25,7 @@ under the License. org.apache.maven maven - 3.6.3-SNAPSHOT + 3.7.0-SNAPSHOT maven-compat diff --git a/maven-core/pom.xml b/maven-core/pom.xml index 7c9d48374208..c814a959d448 100644 --- a/maven-core/pom.xml +++ b/maven-core/pom.xml @@ -25,7 +25,7 @@ under the License. org.apache.maven maven - 3.6.3-SNAPSHOT + 3.7.0-SNAPSHOT maven-core diff --git a/maven-embedder/pom.xml b/maven-embedder/pom.xml index 9c00974dc35a..e308277e9583 100644 --- a/maven-embedder/pom.xml +++ b/maven-embedder/pom.xml @@ -25,7 +25,7 @@ under the License. org.apache.maven maven - 3.6.3-SNAPSHOT + 3.7.0-SNAPSHOT maven-embedder diff --git a/maven-model-builder/pom.xml b/maven-model-builder/pom.xml index a44089f235e7..d9e02f4ba87d 100644 --- a/maven-model-builder/pom.xml +++ b/maven-model-builder/pom.xml @@ -25,7 +25,7 @@ under the License. org.apache.maven maven - 3.6.3-SNAPSHOT + 3.7.0-SNAPSHOT maven-model-builder diff --git a/maven-model/pom.xml b/maven-model/pom.xml index a1505d429b29..59a4dd258947 100644 --- a/maven-model/pom.xml +++ b/maven-model/pom.xml @@ -25,7 +25,7 @@ under the License. org.apache.maven maven - 3.6.3-SNAPSHOT + 3.7.0-SNAPSHOT maven-model diff --git a/maven-plugin-api/pom.xml b/maven-plugin-api/pom.xml index 80470c3f4fee..a59bfed3090a 100644 --- a/maven-plugin-api/pom.xml +++ b/maven-plugin-api/pom.xml @@ -25,7 +25,7 @@ under the License. org.apache.maven maven - 3.6.3-SNAPSHOT + 3.7.0-SNAPSHOT maven-plugin-api diff --git a/maven-repository-metadata/pom.xml b/maven-repository-metadata/pom.xml index f3e6588152c3..9d94f166a901 100644 --- a/maven-repository-metadata/pom.xml +++ b/maven-repository-metadata/pom.xml @@ -25,7 +25,7 @@ under the License. org.apache.maven maven - 3.6.3-SNAPSHOT + 3.7.0-SNAPSHOT maven-repository-metadata diff --git a/maven-resolver-provider/pom.xml b/maven-resolver-provider/pom.xml index 3180d9a7551a..0f6825617d69 100644 --- a/maven-resolver-provider/pom.xml +++ b/maven-resolver-provider/pom.xml @@ -25,7 +25,7 @@ under the License. org.apache.maven maven - 3.6.3-SNAPSHOT + 3.7.0-SNAPSHOT maven-resolver-provider diff --git a/maven-settings-builder/pom.xml b/maven-settings-builder/pom.xml index a6ac8fb1a5d6..4c4b406b3fd8 100644 --- a/maven-settings-builder/pom.xml +++ b/maven-settings-builder/pom.xml @@ -25,7 +25,7 @@ under the License. org.apache.maven maven - 3.6.3-SNAPSHOT + 3.7.0-SNAPSHOT maven-settings-builder diff --git a/maven-settings/pom.xml b/maven-settings/pom.xml index 3636f0fc5bab..b4a6943bc84c 100644 --- a/maven-settings/pom.xml +++ b/maven-settings/pom.xml @@ -25,7 +25,7 @@ under the License. org.apache.maven maven - 3.6.3-SNAPSHOT + 3.7.0-SNAPSHOT maven-settings diff --git a/maven-slf4j-provider/pom.xml b/maven-slf4j-provider/pom.xml index fdf586088ad8..e0bd341fcaf6 100644 --- a/maven-slf4j-provider/pom.xml +++ b/maven-slf4j-provider/pom.xml @@ -25,7 +25,7 @@ under the License. org.apache.maven maven - 3.6.3-SNAPSHOT + 3.7.0-SNAPSHOT maven-slf4j-provider diff --git a/maven-xml/pom.xml b/maven-xml/pom.xml index 1c576907b20f..454188883102 100644 --- a/maven-xml/pom.xml +++ b/maven-xml/pom.xml @@ -26,7 +26,7 @@ under the License. org.apache.maven maven - 3.6.2-SNAPSHOT + 3.7.0-SNAPSHOT maven-xml Maven XML diff --git a/pom.xml b/pom.xml index 36007725b004..0a50d1722baf 100644 --- a/pom.xml +++ b/pom.xml @@ -30,7 +30,7 @@ under the License. maven - 3.6.3-SNAPSHOT + 3.7.0-SNAPSHOT pom Apache Maven From b19b05cbf2f30705dffb8c1a541d65096d967d11 Mon Sep 17 00:00:00 2001 From: rfscholte Date: Wed, 2 Oct 2019 23:08:34 +0200 Subject: [PATCH 16/52] [MNG-6656] Applying review comments --- ...DefaultRepositorySystemSessionFactory.java | 35 ++++++++------- .../DefaultBuildPomXMLFilterFactory.java | 2 +- maven-model-builder/pom.xml | 5 --- .../model/building/DefaultModelBuilder.java | 43 ++++++++++--------- .../building/DefaultModelCacheManager.java | 16 +++---- .../maven/model/building/ModelProblem.java | 3 +- .../StringSearchModelInterpolatorTest.java | 40 +++++++++-------- .../java/org/apache/maven/xml/SAXEvent.java | 2 +- .../org/apache/maven/xml/SAXEventFactory.java | 2 +- .../org/apache/maven/xml/SAXEventUtils.java | 9 +++- .../xml/filter/BuildPomXMLFilterFactory.java | 7 +-- .../xml/filter/ConsumerPomXMLFilter.java | 3 +- .../maven/xml/filter/DependencyKey.java | 6 ++- .../maven/xml/filter/ParentXMLFilter.java | 1 + .../filter/ReactorDependencyXMLFilter.java | 2 +- .../xml/filter/AbstractXMLFilterTests.java | 6 +-- .../xml/filter/ConsumerPomXMLFilterTest.java | 16 +++---- pom.xml | 6 --- 18 files changed, 106 insertions(+), 98 deletions(-) diff --git a/maven-core/src/main/java/org/apache/maven/internal/aether/DefaultRepositorySystemSessionFactory.java b/maven-core/src/main/java/org/apache/maven/internal/aether/DefaultRepositorySystemSessionFactory.java index e4f8439012ab..107c98b4ff82 100644 --- a/maven-core/src/main/java/org/apache/maven/internal/aether/DefaultRepositorySystemSessionFactory.java +++ b/maven-core/src/main/java/org/apache/maven/internal/aether/DefaultRepositorySystemSessionFactory.java @@ -31,12 +31,15 @@ import java.util.LinkedHashMap; import java.util.Map; import java.util.Properties; +import java.util.concurrent.Callable; +import java.util.concurrent.ExecutionException; +import java.util.concurrent.ExecutorService; +import java.util.concurrent.Executors; import javax.inject.Inject; import javax.inject.Named; import javax.inject.Provider; 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; @@ -54,6 +57,7 @@ import org.apache.maven.settings.crypto.DefaultSettingsDecryptionRequest; import org.apache.maven.settings.crypto.SettingsDecrypter; import org.apache.maven.settings.crypto.SettingsDecryptionResult; +import org.apache.maven.xml.Factories; import org.apache.maven.xml.filter.ConsumerPomXMLFilterFactory; import org.codehaus.plexus.configuration.xml.XmlPlexusConfiguration; import org.codehaus.plexus.logging.Logger; @@ -280,7 +284,7 @@ public Collection getTransformersForArtifact( final Artifact ar Collection transformers = new ArrayList<>(); if ( "pom".equals( artifact.getExtension() ) ) { - final TransformerFactory transformerFactory = TransformerFactory.newInstance(); + final TransformerFactory transformerFactory = Factories.newTransformerFactory(); transformers.add( new FileTransformer() { @@ -300,30 +304,29 @@ public InputStream transformData( File file ) } catch ( SAXException | ParserConfigurationException e ) { - e.printStackTrace(); throw new TransformException( "Failed to create a consumerPomXMLFilter", e ); } final StreamResult result = new StreamResult( pipedOutputStream ); - final Runnable runnable = new Runnable() + final Callable callable = () -> { - @Override - public void run() + try ( PipedOutputStream out = pipedOutputStream ) { - try ( PipedOutputStream out = pipedOutputStream ) - { - transformerFactory.newTransformer().transform( transformSource, result ); - } - catch ( TransformerException | IOException e ) - { - e.printStackTrace(); - throw new RuntimeException( e ); - } + transformerFactory.newTransformer().transform( transformSource, result ); } + return null; }; - new Thread( runnable ).start(); + ExecutorService executorService = Executors.newSingleThreadExecutor(); + try + { + executorService.submit( callable ).get(); + } + catch ( InterruptedException | ExecutionException e ) + { + throw new TransformException( "Failed to transform pom", e ); + } return pipedInputStream; } diff --git a/maven-core/src/main/java/org/apache/maven/xml/internal/DefaultBuildPomXMLFilterFactory.java b/maven-core/src/main/java/org/apache/maven/xml/internal/DefaultBuildPomXMLFilterFactory.java index e1b5ab500535..2728103de941 100644 --- a/maven-core/src/main/java/org/apache/maven/xml/internal/DefaultBuildPomXMLFilterFactory.java +++ b/maven-core/src/main/java/org/apache/maven/xml/internal/DefaultBuildPomXMLFilterFactory.java @@ -104,7 +104,7 @@ private RelativeProject toRelativeProject( final Model m ) return new RelativeProject( groupId, m.getArtifactId(), version ); } - private String toVersion( final Model m ) + private static String toVersion( final Model m ) { String version = m.getVersion(); if ( version == null && m.getParent() != null ) diff --git a/maven-model-builder/pom.xml b/maven-model-builder/pom.xml index d9e02f4ba87d..511957c5474c 100644 --- a/maven-model-builder/pom.xml +++ b/maven-model-builder/pom.xml @@ -88,11 +88,6 @@ under the License. xmlunit-matchers test - - org.powermock - powermock-reflect - test - 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 d60e68dda02b..5efb532faf51 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 @@ -36,12 +36,15 @@ import java.util.Map; import java.util.Objects; import java.util.Properties; +import java.util.concurrent.Callable; +import java.util.concurrent.ExecutionException; +import java.util.concurrent.ExecutorService; +import java.util.concurrent.Executors; import javax.inject.Inject; import javax.inject.Named; import javax.inject.Provider; import javax.inject.Singleton; -import javax.xml.crypto.dsig.TransformException; import javax.xml.parsers.ParserConfigurationException; import javax.xml.transform.TransformerException; import javax.xml.transform.TransformerFactory; @@ -88,6 +91,7 @@ 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.filter.BuildPomXMLFilterFactory; import org.codehaus.plexus.interpolation.MapBasedValueSource; import org.codehaus.plexus.interpolation.StringSearchInterpolator; @@ -770,7 +774,6 @@ private void assembleInheritance( List lineage, ModelBuildingRequest { try { - // TODO: parent might be part of reactor... better read all lineage items like this? Model parent = lineage.get( 1 ).getModel(); Model child = modelProcessor.read( transformData( lineage.get( 0 ) ), null ); @@ -781,10 +784,9 @@ private void assembleInheritance( List lineage, ModelBuildingRequest // overwrite child lineage.get( 0 ).setModel( child ); } - catch ( IOException | TransformException | SAXException | ParserConfigurationException e ) + catch ( IOException | TransformerException | SAXException | ParserConfigurationException e ) { - // this is second read, should not happen - e.printStackTrace(); + problems.add( new ModelProblemCollectorRequest( Severity.FATAL, Version.V37 ).setException( e ) ); } } else @@ -796,9 +798,9 @@ private void assembleInheritance( List lineage, ModelBuildingRequest } private InputStream transformData( ModelData modelData ) - throws IOException, TransformException, SAXException, ParserConfigurationException + throws IOException, TransformerException, SAXException, ParserConfigurationException { - final TransformerFactory transformerFactory = TransformerFactory.newInstance(); + final TransformerFactory transformerFactory = Factories.newTransformerFactory() ; final PipedOutputStream pipedOutputStream = new PipedOutputStream(); final PipedInputStream pipedInputStream = new PipedInputStream( pipedOutputStream ); @@ -806,7 +808,7 @@ private InputStream transformData( ModelData modelData ) // Should always be FileSource for reactor poms FileSource source = (FileSource) modelData.getSource(); - System.out.println( "transforming " + source.getFile() ); + // System.out.println( "transforming " + source.getFile() ); final SAXSource transformSource = new SAXSource( buildPomXMLFilterFactory.get().get( source.getFile().toPath() ), @@ -814,23 +816,24 @@ private InputStream transformData( ModelData modelData ) final StreamResult result = new StreamResult( pipedOutputStream ); - final Runnable runnable = new Runnable() + final Callable callable = () -> { - @Override - public void run() + try ( PipedOutputStream out = pipedOutputStream ) { - try ( PipedOutputStream out = pipedOutputStream ) - { - transformerFactory.newTransformer().transform( transformSource, result ); - } - catch ( TransformerException | IOException e ) - { - throw new RuntimeException( e ); - } + transformerFactory.newTransformer().transform( transformSource, result ); } + return null; }; - new Thread( runnable ).start(); + ExecutorService executorService = Executors.newSingleThreadExecutor(); + try + { + executorService.submit( callable ).get(); + } + catch ( InterruptedException | ExecutionException e ) + { + throw new TransformerException( "Failed to transform pom", e ); + } return pipedInputStream; } diff --git a/maven-model-builder/src/main/java/org/apache/maven/model/building/DefaultModelCacheManager.java b/maven-model-builder/src/main/java/org/apache/maven/model/building/DefaultModelCacheManager.java index f33d71388e4e..96ca4206586c 100644 --- a/maven-model-builder/src/main/java/org/apache/maven/model/building/DefaultModelCacheManager.java +++ b/maven-model-builder/src/main/java/org/apache/maven/model/building/DefaultModelCacheManager.java @@ -20,9 +20,8 @@ */ import java.nio.file.Path; -import java.util.Collections; -import java.util.HashMap; import java.util.Map; +import java.util.concurrent.ConcurrentHashMap; import javax.inject.Named; import javax.inject.Singleton; @@ -39,15 +38,14 @@ @Singleton public class DefaultModelCacheManager implements ModelCacheManager { - private static final Map MODELCACHE = Collections.synchronizedMap( new HashMap() ); + private final Map modelCache = new ConcurrentHashMap<>(); - private static final Map DEPKEYMODELCACHE = - Collections.synchronizedMap( new HashMap() ); + private final Map depKeyModelCache = new ConcurrentHashMap<>(); @Override public void put( Path p, Model m ) { - MODELCACHE.put( p, m ); + modelCache.put( p, m ); String groupId = m.getGroupId(); if ( groupId == null && m.getParent() != null ) @@ -56,19 +54,19 @@ public void put( Path p, Model m ) } String artifactId = m.getArtifactId(); - DEPKEYMODELCACHE.put( new DependencyKey( groupId, artifactId ), m ); + depKeyModelCache.put( new DependencyKey( groupId, artifactId ), m ); } @Override public Model get( Path p ) { - return MODELCACHE.get( p ); + return modelCache.get( p ); } @Override public Model get( DependencyKey k ) { - return DEPKEYMODELCACHE.get( k ); + return depKeyModelCache.get( k ); } } diff --git a/maven-model-builder/src/main/java/org/apache/maven/model/building/ModelProblem.java b/maven-model-builder/src/main/java/org/apache/maven/model/building/ModelProblem.java index 2c7a72e70a10..30b67249eaf2 100644 --- a/maven-model-builder/src/main/java/org/apache/maven/model/building/ModelProblem.java +++ b/maven-model-builder/src/main/java/org/apache/maven/model/building/ModelProblem.java @@ -50,7 +50,8 @@ enum Version BASE, V20, V30, - V31 + V31, + V37 } /** diff --git a/maven-model-builder/src/test/java/org/apache/maven/model/interpolation/StringSearchModelInterpolatorTest.java b/maven-model-builder/src/test/java/org/apache/maven/model/interpolation/StringSearchModelInterpolatorTest.java index b66abcade2a9..4cc2508f108c 100644 --- a/maven-model-builder/src/test/java/org/apache/maven/model/interpolation/StringSearchModelInterpolatorTest.java +++ b/maven-model-builder/src/test/java/org/apache/maven/model/interpolation/StringSearchModelInterpolatorTest.java @@ -19,25 +19,29 @@ * under the License. */ -import org.apache.maven.model.InputLocation; -import org.apache.maven.model.InputSource; -import org.apache.maven.model.Model; -import org.apache.maven.model.building.DefaultModelBuildingRequest; -import org.apache.maven.model.building.ModelBuildingRequest; -import org.apache.maven.model.building.SimpleProblemCollector; +import static org.apache.commons.lang3.reflect.FieldUtils.*; +import static org.hamcrest.CoreMatchers.anyOf; +import static org.hamcrest.CoreMatchers.is; +import static org.junit.Assert.assertThat; import java.io.File; -import java.util.*; +import java.util.ArrayList; +import java.util.Collections; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.Properties; import java.util.concurrent.Callable; import java.util.concurrent.CountDownLatch; import java.util.concurrent.Future; import java.util.concurrent.FutureTask; -import static org.hamcrest.CoreMatchers.anyOf; -import static org.hamcrest.CoreMatchers.is; -import static org.junit.Assert.assertThat; -import static org.powermock.reflect.Whitebox.getField; -import static org.powermock.reflect.Whitebox.getInternalState; +import org.apache.maven.model.InputLocation; +import org.apache.maven.model.InputSource; +import org.apache.maven.model.Model; +import org.apache.maven.model.building.DefaultModelBuildingRequest; +import org.apache.maven.model.building.ModelBuildingRequest; +import org.apache.maven.model.building.SimpleProblemCollector; /** * @author jdcasey @@ -395,8 +399,7 @@ public void testNotInterpolateObjectWithFile() //noinspection unchecked Map, ?> cache = - (Map, ?>) getField( StringSearchModelInterpolator.class, "CACHED_ENTRIES" ) - .get( null ); + (Map, ?>) readStaticField( StringSearchModelInterpolator.class, "CACHED_ENTRIES", true ); Object objCacheItem = cache.get( Object.class ); Object fileCacheItem = cache.get( File.class ); @@ -404,8 +407,8 @@ public void testNotInterpolateObjectWithFile() assertNotNull( objCacheItem ); assertNotNull( fileCacheItem ); - assertThat( ( (Object[]) getInternalState( objCacheItem, "fields" ) ).length, is( 0 ) ); - assertThat( ( (Object[]) getInternalState( fileCacheItem, "fields" ) ).length, is( 0 ) ); + assertThat( ( (Object[]) readField( objCacheItem, "fields", true ) ).length, is( 0 ) ); + assertThat( ( (Object[]) readField( fileCacheItem, "fields", true ) ).length, is( 0 ) ); } public void testNotInterpolateFile() @@ -427,14 +430,13 @@ public void testNotInterpolateFile() //noinspection unchecked Map, ?> cache = - (Map, ?>) getField( StringSearchModelInterpolator.class, "CACHED_ENTRIES" ) - .get( null ); + (Map, ?>) readStaticField( StringSearchModelInterpolator.class, "CACHED_ENTRIES", true ); Object fileCacheItem = cache.get( File.class ); assertNotNull( fileCacheItem ); - assertThat( ( (Object[]) getInternalState( fileCacheItem, "fields" ) ).length, is( 0 ) ); + assertThat( ( (Object[]) readField( fileCacheItem, "fields", true ) ).length, is( 0 ) ); } diff --git a/maven-xml/src/main/java/org/apache/maven/xml/SAXEvent.java b/maven-xml/src/main/java/org/apache/maven/xml/SAXEvent.java index 07da2808b4a0..11aad6dec52f 100644 --- a/maven-xml/src/main/java/org/apache/maven/xml/SAXEvent.java +++ b/maven-xml/src/main/java/org/apache/maven/xml/SAXEvent.java @@ -25,7 +25,7 @@ * Command pattern to gather events which can be executed later on. * * @author Robert Scholte - * @since + * @since 3.7.0 */ @FunctionalInterface public interface SAXEvent diff --git a/maven-xml/src/main/java/org/apache/maven/xml/SAXEventFactory.java b/maven-xml/src/main/java/org/apache/maven/xml/SAXEventFactory.java index 42739e120bbb..6d525f696124 100644 --- a/maven-xml/src/main/java/org/apache/maven/xml/SAXEventFactory.java +++ b/maven-xml/src/main/java/org/apache/maven/xml/SAXEventFactory.java @@ -27,7 +27,7 @@ * Factory for SAXEvents * * @author Robert Scholte - * @since 4.0.0 + * @since 3.7.0 */ public final class SAXEventFactory { diff --git a/maven-xml/src/main/java/org/apache/maven/xml/SAXEventUtils.java b/maven-xml/src/main/java/org/apache/maven/xml/SAXEventUtils.java index 06f4f26d98d9..2f3644d0a23c 100644 --- a/maven-xml/src/main/java/org/apache/maven/xml/SAXEventUtils.java +++ b/maven-xml/src/main/java/org/apache/maven/xml/SAXEventUtils.java @@ -23,7 +23,7 @@ * Utility class for SAXEvents * * @author Robert Scholte - * @since 4.0.0 + * @since 3.7.0 */ public final class SAXEventUtils { @@ -31,6 +31,13 @@ private SAXEventUtils() { } + /** + * Returns the newLocalName prefixed with the namespace of the oldQName if present + * + * @param oldQName the QName, used for its namespace + * @param newLocalName the preferred localName + * @return the new QName + */ public static String renameQName( String oldQName, String newLocalName ) { return oldQName.replaceFirst( "[^:]+$", newLocalName ); diff --git a/maven-xml/src/main/java/org/apache/maven/xml/filter/BuildPomXMLFilterFactory.java b/maven-xml/src/main/java/org/apache/maven/xml/filter/BuildPomXMLFilterFactory.java index 83eafe60e287..1df17baa7682 100644 --- a/maven-xml/src/main/java/org/apache/maven/xml/filter/BuildPomXMLFilterFactory.java +++ b/maven-xml/src/main/java/org/apache/maven/xml/filter/BuildPomXMLFilterFactory.java @@ -24,8 +24,8 @@ import java.util.function.Function; import javax.xml.parsers.ParserConfigurationException; -import javax.xml.parsers.SAXParserFactory; +import org.apache.maven.xml.Factories; import org.xml.sax.SAXException; import org.xml.sax.XMLReader; @@ -74,12 +74,13 @@ public final BuildPomXMLFilter get( Path projectFile ) protected XMLReader getParent() throws SAXException, ParserConfigurationException { - XMLReader xmlReader = SAXParserFactory.newInstance().newSAXParser().getXMLReader(); + XMLReader xmlReader = Factories.newXMLReader(); xmlReader.setFeature( "http://xml.org/sax/features/namespaces", true ); return xmlReader; } - // For CIFriendly + // getters for the 3 magic properties of CIFriendly versions ( https://maven.apache.org/maven-ci-friendly.html ) + protected abstract Optional getChangelist(); protected abstract Optional getRevision(); diff --git a/maven-xml/src/main/java/org/apache/maven/xml/filter/ConsumerPomXMLFilter.java b/maven-xml/src/main/java/org/apache/maven/xml/filter/ConsumerPomXMLFilter.java index 9975c224f7ee..8993d1dba4c9 100644 --- a/maven-xml/src/main/java/org/apache/maven/xml/filter/ConsumerPomXMLFilter.java +++ b/maven-xml/src/main/java/org/apache/maven/xml/filter/ConsumerPomXMLFilter.java @@ -27,9 +27,8 @@ * This often means stripping of build-specific information. * When extra information is required during filtering it is probably a member of the BuildPomXMLFilter * - * This filter is used at 2 locations: + * This filter is used at 1 locations: * - {@link org.apache.maven.internal.aether.DefaultRepositorySystemSessionFactory} when publishing pom files. - * - TODO ???Class when a reactor module is used as dependency. This ensures consistency of dependency handling * * @author Robert Scholte * @since 3.7.0 diff --git a/maven-xml/src/main/java/org/apache/maven/xml/filter/DependencyKey.java b/maven-xml/src/main/java/org/apache/maven/xml/filter/DependencyKey.java index bf91cf97255e..6b5e905012ed 100644 --- a/maven-xml/src/main/java/org/apache/maven/xml/filter/DependencyKey.java +++ b/maven-xml/src/main/java/org/apache/maven/xml/filter/DependencyKey.java @@ -31,11 +31,15 @@ public class DependencyKey private final String groupId; private final String artifactId; + + private final int hashCode; public DependencyKey( String groupId, String artifactId ) { this.groupId = groupId; this.artifactId = artifactId; + + this.hashCode = Objects.hash( artifactId, groupId ); } public String getGroupId() @@ -51,7 +55,7 @@ public String getArtifactId() @Override public int hashCode() { - return Objects.hash( artifactId, groupId ); + return hashCode; } @Override diff --git a/maven-xml/src/main/java/org/apache/maven/xml/filter/ParentXMLFilter.java b/maven-xml/src/main/java/org/apache/maven/xml/filter/ParentXMLFilter.java index 747a28300350..7bb744d3e2ed 100644 --- a/maven-xml/src/main/java/org/apache/maven/xml/filter/ParentXMLFilter.java +++ b/maven-xml/src/main/java/org/apache/maven/xml/filter/ParentXMLFilter.java @@ -43,6 +43,7 @@ *

          * * @author Robert Scholte + * @since 3.7.0 */ class ParentXMLFilter extends XMLFilterImpl diff --git a/maven-xml/src/main/java/org/apache/maven/xml/filter/ReactorDependencyXMLFilter.java b/maven-xml/src/main/java/org/apache/maven/xml/filter/ReactorDependencyXMLFilter.java index a568df57cea1..fa8b1e533352 100644 --- a/maven-xml/src/main/java/org/apache/maven/xml/filter/ReactorDependencyXMLFilter.java +++ b/maven-xml/src/main/java/org/apache/maven/xml/filter/ReactorDependencyXMLFilter.java @@ -30,7 +30,7 @@ * Will apply the version if the dependency is part of the reactor * * @author Robert Scholte - * @since 4.0.0 + * @since 3.7.0 */ public class ReactorDependencyXMLFilter extends XMLFilterImpl { diff --git a/maven-xml/src/test/java/org/apache/maven/xml/filter/AbstractXMLFilterTests.java b/maven-xml/src/test/java/org/apache/maven/xml/filter/AbstractXMLFilterTests.java index e406f6c9e544..0d9b7791e398 100644 --- a/maven-xml/src/test/java/org/apache/maven/xml/filter/AbstractXMLFilterTests.java +++ b/maven-xml/src/test/java/org/apache/maven/xml/filter/AbstractXMLFilterTests.java @@ -25,7 +25,6 @@ import java.io.Writer; import javax.xml.parsers.ParserConfigurationException; -import javax.xml.parsers.SAXParserFactory; import javax.xml.transform.OutputKeys; import javax.xml.transform.Transformer; import javax.xml.transform.TransformerException; @@ -33,6 +32,7 @@ import javax.xml.transform.sax.SAXSource; import javax.xml.transform.stream.StreamResult; +import org.apache.maven.xml.Factories; import org.xml.sax.InputSource; import org.xml.sax.SAXException; import org.xml.sax.XMLFilter; @@ -50,7 +50,7 @@ private void setParent( XMLFilter filter ) throws SAXException, ParserConfigurat { if( filter.getParent() == null ) { - filter.setParent( SAXParserFactory.newInstance().newSAXParser().getXMLReader() ); + filter.setParent( Factories.newXMLReader() ); filter.setFeature( "http://xml.org/sax/features/namespaces", true ); } } @@ -82,7 +82,7 @@ protected String transform( Reader input, XMLFilter filter ) Writer writer = new StringWriter(); StreamResult result = new StreamResult( writer ); - TransformerFactory transformerFactory = TransformerFactory.newInstance(); + TransformerFactory transformerFactory = Factories.newTransformerFactory(); Transformer transformer = transformerFactory.newTransformer(); transformer.setOutputProperty( OutputKeys.OMIT_XML_DECLARATION, "yes" ); diff --git a/maven-xml/src/test/java/org/apache/maven/xml/filter/ConsumerPomXMLFilterTest.java b/maven-xml/src/test/java/org/apache/maven/xml/filter/ConsumerPomXMLFilterTest.java index 5484ea6daaf2..4ed4ab682bdf 100644 --- a/maven-xml/src/test/java/org/apache/maven/xml/filter/ConsumerPomXMLFilterTest.java +++ b/maven-xml/src/test/java/org/apache/maven/xml/filter/ConsumerPomXMLFilterTest.java @@ -119,10 +119,10 @@ public void testAllFilters() throws Exception { @Test public void testMe() throws Exception { String input = "\r\n" + - "\r\n" + + "\r\n" + " 4.0.0\r\n" + " org.sonatype.mavenbook.multispring\r\n" + " parent\r\n" + @@ -141,10 +141,10 @@ public void testMe() throws Exception { " \r\n" + ""; String expected = "\r\n" + - "\r\n" + + "\r\n" + " 4.0.0\r\n" + " org.sonatype.mavenbook.multispring\r\n" + " parent\r\n" + diff --git a/pom.xml b/pom.xml index 0a50d1722baf..805cb06e23fd 100644 --- a/pom.xml +++ b/pom.xml @@ -67,7 +67,6 @@ under the License. 1.4.1 1.7.25 2.6.2 - 1.7.4 true apache-maven @@ -431,11 +430,6 @@ under the License. ${xmlunitVersion} test - - org.powermock - powermock-reflect - ${powermockVersion} - From c52f383c4b4d06adb8800d5cd88227bbbec19a2f Mon Sep 17 00:00:00 2001 From: rfscholte Date: Fri, 11 Oct 2019 15:20:57 +0200 Subject: [PATCH 17/52] [MNG-6656] Support LexicalHandler --- ...DefaultRepositorySystemSessionFactory.java | 5 +- .../xml/filter/ConsumerPomXMLFilter.java | 73 ----- .../maven/xml/filter/FastForwardFilter.java | 128 -------- .../maven/xml/filter/ModulesXMLFilter.java | 102 ------- .../xml/filter/RelativePathXMLFilter.java | 98 ------- .../DefaultBuildPomXMLFilterFactory.java | 8 +- .../DefaultConsumerPomXMLFilterFactory.java | 2 +- .../xml/filter/AbstractXMLFilterTests.java | 80 ----- .../xml/filter/ConsumerPomXMLFilterTest.java | 64 ---- .../xml/filter/ModulesXMLFilterTest.java | 62 ---- .../xml/filter/RelativePathXMLFilterTest.java | 61 ---- .../model/building/DefaultModelBuilder.java | 2 +- .../building/DefaultModelCacheManager.java | 2 +- .../model/building/ModelCacheManager.java | 2 +- .../java/org/apache/maven/xml/Factories.java | 118 ++++++++ .../apache/maven/xml/{ => sax}/SAXEvent.java | 2 +- .../maven/xml/{ => sax}/SAXEventFactory.java | 63 +++- .../maven/xml/{ => sax}/SAXEventUtils.java | 2 +- .../sax/filter/AbstractEventXMLFilter.java | 272 +++++++++++++++++ .../xml/sax/filter/AbstractSAXFilter.java | 130 ++++++++ .../{ => sax}/filter/BuildPomXMLFilter.java | 8 +- .../filter/BuildPomXMLFilterFactory.java | 31 +- .../{ => sax}/filter/CiFriendlyXMLFilter.java | 5 +- .../filter/ConsumerPomXMLFilter.java | 8 +- .../filter/ConsumerPomXMLFilterFactory.java | 11 +- .../xml/{ => sax}/filter/DependencyKey.java | 2 +- .../{ => sax}/filter/FastForwardFilter.java | 8 +- .../{ => sax}/filter/ModulesXMLFilter.java | 19 +- .../xml/{ => sax}/filter/ParentXMLFilter.java | 146 ++------- .../filter/ReactorDependencyXMLFilter.java | 22 +- .../filter/RelativePathXMLFilter.java | 75 +++-- .../xml/{ => sax}/filter/RelativeProject.java | 2 +- .../xml/filter/ConsumerPomXMLFilterTest.java | 168 ----------- .../maven/xml/sax/LexicalHandlerVerifier.java | 277 ++++++++++++++++++ .../maven/xml/sax/SAXEventUtilsTest.java | 31 +- .../filter/AbstractXMLFilterTests.java | 50 +++- .../sax/filter/ConsumerPomXMLFilterTest.java | 252 ++++++++++++++++ .../filter/ModulesXMLFilterTest.java | 40 +-- .../{ => sax}/filter/ParentXMLFilterTest.java | 34 ++- .../ReactorDependencyXMLFilterTest.java | 36 ++- .../filter/RelativePathXMLFilterTest.java | 9 +- 41 files changed, 1379 insertions(+), 1131 deletions(-) delete mode 100644 maven-core/src/main/java/org/apache/maven/xml/filter/ConsumerPomXMLFilter.java delete mode 100644 maven-core/src/main/java/org/apache/maven/xml/filter/FastForwardFilter.java delete mode 100644 maven-core/src/main/java/org/apache/maven/xml/filter/ModulesXMLFilter.java delete mode 100644 maven-core/src/main/java/org/apache/maven/xml/filter/RelativePathXMLFilter.java delete mode 100644 maven-core/src/test/java/org/apache/maven/xml/filter/AbstractXMLFilterTests.java delete mode 100644 maven-core/src/test/java/org/apache/maven/xml/filter/ConsumerPomXMLFilterTest.java delete mode 100644 maven-core/src/test/java/org/apache/maven/xml/filter/ModulesXMLFilterTest.java delete mode 100644 maven-core/src/test/java/org/apache/maven/xml/filter/RelativePathXMLFilterTest.java create mode 100644 maven-xml/src/main/java/org/apache/maven/xml/Factories.java rename maven-xml/src/main/java/org/apache/maven/xml/{ => sax}/SAXEvent.java (96%) rename maven-xml/src/main/java/org/apache/maven/xml/{ => sax}/SAXEventFactory.java (65%) rename maven-xml/src/main/java/org/apache/maven/xml/{ => sax}/SAXEventUtils.java (97%) create mode 100644 maven-xml/src/main/java/org/apache/maven/xml/sax/filter/AbstractEventXMLFilter.java create mode 100644 maven-xml/src/main/java/org/apache/maven/xml/sax/filter/AbstractSAXFilter.java rename maven-xml/src/main/java/org/apache/maven/xml/{ => sax}/filter/BuildPomXMLFilter.java (87%) rename maven-xml/src/main/java/org/apache/maven/xml/{ => sax}/filter/BuildPomXMLFilterFactory.java (66%) rename maven-xml/src/main/java/org/apache/maven/xml/{ => sax}/filter/CiFriendlyXMLFilter.java (95%) rename maven-xml/src/main/java/org/apache/maven/xml/{ => sax}/filter/ConsumerPomXMLFilter.java (87%) rename maven-xml/src/main/java/org/apache/maven/xml/{ => sax}/filter/ConsumerPomXMLFilterFactory.java (83%) rename maven-xml/src/main/java/org/apache/maven/xml/{ => sax}/filter/DependencyKey.java (98%) rename maven-xml/src/main/java/org/apache/maven/xml/{ => sax}/filter/FastForwardFilter.java (94%) rename maven-xml/src/main/java/org/apache/maven/xml/{ => sax}/filter/ModulesXMLFilter.java (85%) rename maven-xml/src/main/java/org/apache/maven/xml/{ => sax}/filter/ParentXMLFilter.java (59%) rename maven-xml/src/main/java/org/apache/maven/xml/{ => sax}/filter/ReactorDependencyXMLFilter.java (90%) rename maven-xml/src/main/java/org/apache/maven/xml/{ => sax}/filter/RelativePathXMLFilter.java (57%) rename maven-xml/src/main/java/org/apache/maven/xml/{ => sax}/filter/RelativeProject.java (97%) delete mode 100644 maven-xml/src/test/java/org/apache/maven/xml/filter/ConsumerPomXMLFilterTest.java create mode 100644 maven-xml/src/test/java/org/apache/maven/xml/sax/LexicalHandlerVerifier.java rename maven-core/src/main/java/org/apache/maven/xml/filter/BuildPomXMLFilter.java => maven-xml/src/test/java/org/apache/maven/xml/sax/SAXEventUtilsTest.java (63%) rename maven-xml/src/test/java/org/apache/maven/xml/{ => sax}/filter/AbstractXMLFilterTests.java (57%) create mode 100644 maven-xml/src/test/java/org/apache/maven/xml/sax/filter/ConsumerPomXMLFilterTest.java rename maven-xml/src/test/java/org/apache/maven/xml/{ => sax}/filter/ModulesXMLFilterTest.java (67%) rename maven-xml/src/test/java/org/apache/maven/xml/{ => sax}/filter/ParentXMLFilterTest.java (86%) rename maven-xml/src/test/java/org/apache/maven/xml/{ => sax}/filter/ReactorDependencyXMLFilterTest.java (66%) rename maven-xml/src/test/java/org/apache/maven/xml/{ => sax}/filter/RelativePathXMLFilterTest.java (95%) diff --git a/maven-core/src/main/java/org/apache/maven/internal/aether/DefaultRepositorySystemSessionFactory.java b/maven-core/src/main/java/org/apache/maven/internal/aether/DefaultRepositorySystemSessionFactory.java index 107c98b4ff82..3eaad6f63824 100644 --- a/maven-core/src/main/java/org/apache/maven/internal/aether/DefaultRepositorySystemSessionFactory.java +++ b/maven-core/src/main/java/org/apache/maven/internal/aether/DefaultRepositorySystemSessionFactory.java @@ -40,6 +40,7 @@ import javax.inject.Named; import javax.inject.Provider; import javax.xml.parsers.ParserConfigurationException; +import javax.xml.transform.TransformerConfigurationException; import javax.xml.transform.TransformerFactory; import javax.xml.transform.sax.SAXSource; import javax.xml.transform.stream.StreamResult; @@ -58,7 +59,7 @@ import org.apache.maven.settings.crypto.SettingsDecrypter; import org.apache.maven.settings.crypto.SettingsDecryptionResult; import org.apache.maven.xml.Factories; -import org.apache.maven.xml.filter.ConsumerPomXMLFilterFactory; +import org.apache.maven.xml.sax.filter.ConsumerPomXMLFilterFactory; import org.codehaus.plexus.configuration.xml.XmlPlexusConfiguration; import org.codehaus.plexus.logging.Logger; import org.codehaus.plexus.util.xml.Xpp3Dom; @@ -302,7 +303,7 @@ public InputStream transformData( File file ) new SAXSource( consumerPomXMLFilterFactory.get().get( file.toPath() ), new InputSource( new FileReader( file ) ) ); } - catch ( SAXException | ParserConfigurationException e ) + catch ( SAXException | ParserConfigurationException | TransformerConfigurationException e ) { throw new TransformException( "Failed to create a consumerPomXMLFilter", e ); } diff --git a/maven-core/src/main/java/org/apache/maven/xml/filter/ConsumerPomXMLFilter.java b/maven-core/src/main/java/org/apache/maven/xml/filter/ConsumerPomXMLFilter.java deleted file mode 100644 index 8709b9c0a15d..000000000000 --- a/maven-core/src/main/java/org/apache/maven/xml/filter/ConsumerPomXMLFilter.java +++ /dev/null @@ -1,73 +0,0 @@ -package org.apache.maven.xml.filter; - -/* - * 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 javax.xml.parsers.ParserConfigurationException; -import javax.xml.parsers.SAXParserFactory; - -import org.xml.sax.SAXException; -import org.xml.sax.XMLFilter; -import org.xml.sax.XMLReader; - -import org.xml.sax.helpers.XMLFilterImpl; - -/** - * XML Filter to transform pom.xml to consumer pom. - * This often means stripping of build-specific information. - * - * This filter is used at 2 locations: - * - {@link org.apache.maven.internal.aether.DefaultRepositorySystemSessionFactory} when publishing pom files. - * - TODO ???Class when a reactor module is used as dependency. This ensures consistency of dependency handling - * - * @author Robert Scholte - * @since 3.7.0 - */ -public class ConsumerPomXMLFilter extends XMLFilterImpl -{ - private final XMLFilter rootFilter; - - public ConsumerPomXMLFilter() throws SAXException, ParserConfigurationException - { - this( SAXParserFactory.newInstance().newSAXParser().getXMLReader() ); - } - - public ConsumerPomXMLFilter( XMLReader parent ) - { - rootFilter = new BuildPomXMLFilter( parent ); - - // Ensure that xs:any elements aren't touched by next filters - XMLFilter filter = new FastForwardFilter( rootFilter ); - - // Strip modules - filter = new ModulesXMLFilter( filter ); - // Adjust relativePath - filter = new RelativePathXMLFilter( filter ); - - // maybe more to follow - - super.setParent( filter ); - } - - @Override - public void setParent( XMLReader parent ) - { - rootFilter.setParent( parent ); - } -} diff --git a/maven-core/src/main/java/org/apache/maven/xml/filter/FastForwardFilter.java b/maven-core/src/main/java/org/apache/maven/xml/filter/FastForwardFilter.java deleted file mode 100644 index df68167a1394..000000000000 --- a/maven-core/src/main/java/org/apache/maven/xml/filter/FastForwardFilter.java +++ /dev/null @@ -1,128 +0,0 @@ -package org.apache.maven.xml.filter; - -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ - -import java.util.ArrayDeque; -import java.util.Deque; - -import org.xml.sax.Attributes; -import org.xml.sax.ContentHandler; -import org.xml.sax.SAXException; -import org.xml.sax.XMLFilter; -import org.xml.sax.XMLReader; -import org.xml.sax.helpers.XMLFilterImpl; - -/** - * This filter will skip all following filters and write directly to the output. - * Should be used in case of a DOM that should not be effected by other filters, even though the elements match - * - * @author Robert Scholte - * @since 4.0.0 - */ -class FastForwardFilter extends XMLFilterImpl -{ - /** - * DOM elements of pom - * - *
            - *
          • execution.configuration
          • - *
          • plugin.configuration
          • - *
          • plugin.goals
          • - *
          • profile.reports
          • - *
          • project.reports
          • - *
          • reportSet.configuration
          • - *
              - */ - private final Deque state = new ArrayDeque<>(); - - private int domDepth = 0; - - private ContentHandler originalHandler; - - FastForwardFilter() - { - super(); - } - - FastForwardFilter( XMLReader parent ) - { - super( parent ); - } - - @Override - public void startElement( String uri, String localName, String qName, Attributes atts ) - throws SAXException - { - super.startElement( uri, localName, qName, atts ); - if ( domDepth > 0 ) - { - domDepth++; - } - else - { - final String key = state.peek() + '.' + localName; - switch ( key ) - { - case "execution.configuration": - case "plugin.configuration": - case "plugin.goals": - case "profile.reports": - case "project.reports": - case "reportSet.configuration": - domDepth++; - - originalHandler = getContentHandler(); - - ContentHandler outputContentHandler = getContentHandler(); - while ( outputContentHandler instanceof XMLFilter ) - { - outputContentHandler = ( (XMLFilter) outputContentHandler ).getContentHandler(); - } - setContentHandler( outputContentHandler ); - break; - default: - break; - } - state.push( localName ); - } - } - - @Override - public void endElement( String uri, String localName, String qName ) - throws SAXException - { - if ( domDepth > 0 ) - { - domDepth--; - - if ( domDepth == 0 ) - { - setContentHandler( originalHandler ); - } - } - else - { - state.pop(); - } - super.endElement( uri, localName, qName ); - } - - -} \ No newline at end of file diff --git a/maven-core/src/main/java/org/apache/maven/xml/filter/ModulesXMLFilter.java b/maven-core/src/main/java/org/apache/maven/xml/filter/ModulesXMLFilter.java deleted file mode 100644 index 9e7b6fdbe5de..000000000000 --- a/maven-core/src/main/java/org/apache/maven/xml/filter/ModulesXMLFilter.java +++ /dev/null @@ -1,102 +0,0 @@ -package org.apache.maven.xml.filter; - -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ - -import org.xml.sax.Attributes; -import org.xml.sax.SAXException; -import org.xml.sax.XMLReader; -import org.xml.sax.helpers.XMLFilterImpl; - -/** - * Remove all modules, this is just buildtime information - * - * @author Robert Scholte - * @since 3.7.0 - */ -class ModulesXMLFilter - extends XMLFilterImpl -{ - /** - * Using 3 to also remove whitespace-block after closing tag - * -1 none - * 1 started - * 2 ended - */ - int modulesStatus = -1; - - ModulesXMLFilter() - { - super(); - } - - ModulesXMLFilter( XMLReader parent ) - { - super( parent ); - } - - @Override - public void startElement( String uri, String localName, String qName, Attributes atts ) - throws SAXException - { - if ( modulesStatus == -1 && "modules".equals( localName ) ) - { - modulesStatus = 1; - } - else if ( modulesStatus == 2 ) - { - modulesStatus = -1; - } - - if ( modulesStatus != 1 ) - { - super.startElement( uri, localName, qName, atts ); - } - } - - @Override - public void endElement( String uri, String localName, String qName ) - throws SAXException - { - if ( modulesStatus == 1 && "modules".equals( localName ) ) - { - modulesStatus = 2; - } - else if ( modulesStatus == 2 ) - { - modulesStatus = -1; - } - - if ( modulesStatus == -1 ) - { - super.endElement( uri, localName, qName ); - } - } - - @Override - public void characters( char[] ch, int start, int length ) - throws SAXException - { - if ( modulesStatus == -1 ) - { - super.characters( ch, start, length ); - } - } - -} diff --git a/maven-core/src/main/java/org/apache/maven/xml/filter/RelativePathXMLFilter.java b/maven-core/src/main/java/org/apache/maven/xml/filter/RelativePathXMLFilter.java deleted file mode 100644 index 8548ddd73d9c..000000000000 --- a/maven-core/src/main/java/org/apache/maven/xml/filter/RelativePathXMLFilter.java +++ /dev/null @@ -1,98 +0,0 @@ -package org.apache.maven.xml.filter; - -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ - -import org.xml.sax.Attributes; -import org.xml.sax.SAXException; -import org.xml.sax.XMLReader; -import org.xml.sax.helpers.XMLFilterImpl; - -/** - * Remove content from relativePath - * - * TODO fix indentation of closing parent tag - * - * @author Robert Scholte - * @since 3.7.0 - */ -class RelativePathXMLFilter - extends XMLFilterImpl -{ - /** - * Using 3 to also remove whitespace-block after closing tag - * -1 none - * 1 started - * 2 ended - */ - int relativePathStatus = -1; - - RelativePathXMLFilter() - { - super(); - } - - RelativePathXMLFilter( XMLReader parent ) - { - super( parent ); - } - - @Override - public void startElement( String uri, String localName, String qName, Attributes atts ) - throws SAXException - { - if ( relativePathStatus == -1 && "relativePath".equals( localName ) ) - { - relativePathStatus = 1; - } - else if ( relativePathStatus == 2 ) - { - relativePathStatus = -1; - } - - super.startElement( uri, localName, qName, atts ); - } - - @Override - public void endElement( String uri, String localName, String qName ) - throws SAXException - { - if ( relativePathStatus == 1 && "relativePath".equals( localName ) ) - { - relativePathStatus = 2; - } - else if ( relativePathStatus == 2 ) - { - relativePathStatus = -1; - } - - super.endElement( uri, localName, qName ); - } - - @Override - public void characters( char[] ch, int start, int length ) - throws SAXException - { - if ( relativePathStatus != 1 ) - { - super.characters( ch, start, length ); - } - } - -} diff --git a/maven-core/src/main/java/org/apache/maven/xml/internal/DefaultBuildPomXMLFilterFactory.java b/maven-core/src/main/java/org/apache/maven/xml/internal/DefaultBuildPomXMLFilterFactory.java index 2728103de941..d359eb65ea8b 100644 --- a/maven-core/src/main/java/org/apache/maven/xml/internal/DefaultBuildPomXMLFilterFactory.java +++ b/maven-core/src/main/java/org/apache/maven/xml/internal/DefaultBuildPomXMLFilterFactory.java @@ -31,9 +31,9 @@ import org.apache.maven.execution.MavenSession; import org.apache.maven.model.Model; import org.apache.maven.model.building.ModelCacheManager; -import org.apache.maven.xml.filter.BuildPomXMLFilterFactory; -import org.apache.maven.xml.filter.DependencyKey; -import org.apache.maven.xml.filter.RelativeProject; +import org.apache.maven.xml.sax.filter.BuildPomXMLFilterFactory; +import org.apache.maven.xml.sax.filter.DependencyKey; +import org.apache.maven.xml.sax.filter.RelativeProject; /** * @@ -87,7 +87,7 @@ protected Function getDependencyKeyToVersionMapper() .orElse( null ); } - private RelativeProject toRelativeProject( final Model m ) + private static RelativeProject toRelativeProject( final Model m ) { String groupId = m.getGroupId(); if ( groupId == null && m.getParent() != null ) 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 af05bc392344..489019fd6c69 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 @@ -22,7 +22,7 @@ import javax.inject.Named; import javax.inject.Singleton; -import org.apache.maven.xml.filter.ConsumerPomXMLFilterFactory; +import org.apache.maven.xml.sax.filter.ConsumerPomXMLFilterFactory; /** * diff --git a/maven-core/src/test/java/org/apache/maven/xml/filter/AbstractXMLFilterTests.java b/maven-core/src/test/java/org/apache/maven/xml/filter/AbstractXMLFilterTests.java deleted file mode 100644 index 69fc33ba8f59..000000000000 --- a/maven-core/src/test/java/org/apache/maven/xml/filter/AbstractXMLFilterTests.java +++ /dev/null @@ -1,80 +0,0 @@ -package org.apache.maven.xml.filter; - -import java.io.Reader; - -/* - * 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.StringReader; -import java.io.StringWriter; -import java.io.Writer; - -import javax.xml.transform.OutputKeys; -import javax.xml.transform.Transformer; -import javax.xml.transform.TransformerException; -import javax.xml.transform.TransformerFactory; -import javax.xml.transform.sax.SAXSource; -import javax.xml.transform.stream.StreamResult; - -import org.xml.sax.InputSource; -import org.xml.sax.SAXException; -import org.xml.sax.XMLFilter; -import org.xml.sax.XMLReader; -import org.xml.sax.helpers.XMLReaderFactory; - -public class AbstractXMLFilterTests -{ - - public AbstractXMLFilterTests() - { - super(); - } - - protected String transform( String input, XMLFilter filter ) - throws TransformerException, SAXException - { - return transform( new StringReader( input ), filter ); - } - - protected String transform( Reader input, XMLFilter filter ) - throws TransformerException, SAXException - { - XMLReader reader = XMLReaderFactory.createXMLReader(); - - XMLFilter parent = filter; - while ( parent.getParent() instanceof XMLFilter ) - { - parent = (XMLFilter) parent.getParent(); - } - parent.setParent( reader ); - - Writer writer = new StringWriter(); - StreamResult result = new StreamResult( writer ); - - TransformerFactory transformerFactory = TransformerFactory.newInstance(); - Transformer transformer = transformerFactory.newTransformer(); - transformer.setOutputProperty( OutputKeys.OMIT_XML_DECLARATION, "yes" ); - - SAXSource transformSource = new SAXSource( filter, new InputSource( input ) ); - - transformer.transform( transformSource, result ); - - return writer.toString(); - } -} \ No newline at end of file diff --git a/maven-core/src/test/java/org/apache/maven/xml/filter/ConsumerPomXMLFilterTest.java b/maven-core/src/test/java/org/apache/maven/xml/filter/ConsumerPomXMLFilterTest.java deleted file mode 100644 index b3d44db91b6b..000000000000 --- a/maven-core/src/test/java/org/apache/maven/xml/filter/ConsumerPomXMLFilterTest.java +++ /dev/null @@ -1,64 +0,0 @@ -package org.apache.maven.xml.filter; - -/* - * 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 static org.xmlunit.assertj.XmlAssert.assertThat; - -import org.junit.Before; -import org.junit.Test; - -public class ConsumerPomXMLFilterTest extends AbstractXMLFilterTests -{ - private ConsumerPomXMLFilter filter; - - @Before - public void setup() throws Exception { - filter = new ConsumerPomXMLFilter(); - } - - @Test - public void testAllFilters() throws Exception { - String input = "\n" - + " \n" - + " GROUPID\n" - + " PARENT\n" - + " VERSION\n" - + " ../pom.xml\n" - + " \n" - + " PROJECT\n" - + " \n" - + " ab\n" - + " ../cd\n" - + " \n" - + ""; - String expected = "\n" - + " \n" - + " GROUPID\n" - + " PARENT\n" - + " VERSION\n" - + " \n" - + " \n" - + " PROJECT\n" - + ""; - String actual = transform( input, filter ); - assertThat( actual ).and( expected ).ignoreWhitespace().areIdentical(); - } - -} diff --git a/maven-core/src/test/java/org/apache/maven/xml/filter/ModulesXMLFilterTest.java b/maven-core/src/test/java/org/apache/maven/xml/filter/ModulesXMLFilterTest.java deleted file mode 100644 index 353f1742d896..000000000000 --- a/maven-core/src/test/java/org/apache/maven/xml/filter/ModulesXMLFilterTest.java +++ /dev/null @@ -1,62 +0,0 @@ -package org.apache.maven.xml.filter; - -/* - * 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 static org.xmlunit.assertj.XmlAssert.assertThat; - -import org.junit.Before; -import org.junit.Test; - -public class ModulesXMLFilterTest extends AbstractXMLFilterTests { - - private ModulesXMLFilter filter; - - @Before - public void setup() { - filter = new ModulesXMLFilter(); - } - - @Test - public void testEmptyModules() throws Exception { - String input = ""; - String expected = ""; - String actual = transform( input, filter ); - assertThat( actual ).and( expected ).areIdentical(); - } - - @Test - public void testSetOfModules() throws Exception { - String input = "" - + "ab" - + "../cd" - + ""; - String expected = ""; - String actual = transform( input, filter ); - assertThat( actual ).and( expected ).areIdentical(); - } - - @Test - public void testNoModules() throws Exception { - String input = "NAME"; - String expected = input; - String actual = transform( input, filter ); - assertThat( actual ).and( expected ).areIdentical(); - } -} diff --git a/maven-core/src/test/java/org/apache/maven/xml/filter/RelativePathXMLFilterTest.java b/maven-core/src/test/java/org/apache/maven/xml/filter/RelativePathXMLFilterTest.java deleted file mode 100644 index 298197dd1c81..000000000000 --- a/maven-core/src/test/java/org/apache/maven/xml/filter/RelativePathXMLFilterTest.java +++ /dev/null @@ -1,61 +0,0 @@ -package org.apache.maven.xml.filter; - -import static org.xmlunit.assertj.XmlAssert.assertThat; - -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ - -import org.junit.Before; -import org.junit.Test; - -public class RelativePathXMLFilterTest extends AbstractXMLFilterTests -{ - private RelativePathXMLFilter filter; - - @Before - public void setup() { - filter = new RelativePathXMLFilter(); - } - - @Test - public void testRelativePath() throws Exception - { - String input = "\n" - + " \n" - + " GROUPID\n" - + " PARENT\n" - + " VERSION\n" - + " ../pom.xml\n" - + " \n" - + " PROJECT\n" - + ""; - String expected = "\n" - + " \n" - + " GROUPID\n" - + " PARENT\n" - + " VERSION\n" - + " \n" - + " \n" - + " PROJECT\n" - + ""; - String actual = transform( input, filter ); - assertThat( actual ).and( expected ).areIdentical(); - } - -} 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 5efb532faf51..bc13d33e3a5d 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 @@ -92,7 +92,7 @@ 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.filter.BuildPomXMLFilterFactory; +import org.apache.maven.xml.sax.filter.BuildPomXMLFilterFactory; import org.codehaus.plexus.interpolation.MapBasedValueSource; import org.codehaus.plexus.interpolation.StringSearchInterpolator; import org.eclipse.sisu.Nullable; diff --git a/maven-model-builder/src/main/java/org/apache/maven/model/building/DefaultModelCacheManager.java b/maven-model-builder/src/main/java/org/apache/maven/model/building/DefaultModelCacheManager.java index 96ca4206586c..e205749ffb3f 100644 --- a/maven-model-builder/src/main/java/org/apache/maven/model/building/DefaultModelCacheManager.java +++ b/maven-model-builder/src/main/java/org/apache/maven/model/building/DefaultModelCacheManager.java @@ -27,7 +27,7 @@ import javax.inject.Singleton; import org.apache.maven.model.Model; -import org.apache.maven.xml.filter.DependencyKey; +import org.apache.maven.xml.sax.filter.DependencyKey; /** * diff --git a/maven-model-builder/src/main/java/org/apache/maven/model/building/ModelCacheManager.java b/maven-model-builder/src/main/java/org/apache/maven/model/building/ModelCacheManager.java index f28116fbfd4f..f6e651592ede 100644 --- a/maven-model-builder/src/main/java/org/apache/maven/model/building/ModelCacheManager.java +++ b/maven-model-builder/src/main/java/org/apache/maven/model/building/ModelCacheManager.java @@ -22,7 +22,7 @@ import java.nio.file.Path; import org.apache.maven.model.Model; -import org.apache.maven.xml.filter.DependencyKey; +import org.apache.maven.xml.sax.filter.DependencyKey; /** * Registers models for usage later on diff --git a/maven-xml/src/main/java/org/apache/maven/xml/Factories.java b/maven-xml/src/main/java/org/apache/maven/xml/Factories.java new file mode 100644 index 000000000000..eb2166a686e1 --- /dev/null +++ b/maven-xml/src/main/java/org/apache/maven/xml/Factories.java @@ -0,0 +1,118 @@ +package org.apache.maven.xml; + +/* + * 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 javax.xml.XMLConstants; +import javax.xml.parsers.ParserConfigurationException; +import javax.xml.parsers.SAXParser; +import javax.xml.parsers.SAXParserFactory; +import javax.xml.transform.TransformerFactory; + +import org.xml.sax.SAXException; +import org.xml.sax.SAXNotRecognizedException; +import org.xml.sax.SAXNotSupportedException; +import org.xml.sax.XMLReader; + +/** + * Creates XML related factories with OWASP advices applied + * + * @author Robert Scholte + * @since 3.7.0 + */ +public final class Factories +{ + private Factories() + { + } + + /** + * + * @return + * @see https://cheatsheetseries.owasp.org/cheatsheets/XML_External_Entity_Prevention_Cheat_Sheet.html#transformerfactory + */ + public static TransformerFactory newTransformerFactory() + { + TransformerFactory tf = TransformerFactory.newInstance(); + tf.setAttribute( XMLConstants.ACCESS_EXTERNAL_DTD, "" ); + tf.setAttribute( XMLConstants.ACCESS_EXTERNAL_STYLESHEET, "" ); + + return tf; + } + + public static SAXParserFactory newSAXParserFactory() + { + SAXParserFactory spf = SAXParserFactory.newInstance(); + + try + { + // Xerces 1 - http://xerces.apache.org/xerces-j/features.html#external-general-entities + // Xerces 2 - http://xerces.apache.org/xerces2-j/features.html#external-general-entities + + // Using the SAXParserFactory's setFeature + spf.setFeature( "http://xml.org/sax/features/external-general-entities", false ); + + // Xerces 2 only - http://xerces.apache.org/xerces-j/features.html#external-general-entities + spf.setFeature( "http://apache.org/xml/features/disallow-doctype-decl", true ); + } + catch ( ParserConfigurationException e ) + { + // Tried an unsupported feature. + } + catch ( SAXNotRecognizedException e ) + { + // Tried an unknown feature. + } + catch ( SAXNotSupportedException e ) + { + // Tried a feature known to the parser but unsupported. + } + return spf; + } + + public static SAXParser newSAXParser() throws ParserConfigurationException, SAXException + { + SAXParser saxParser = newSAXParserFactory().newSAXParser(); + + return saxParser; + } + + public static XMLReader newXMLReader() throws SAXException, ParserConfigurationException + { + XMLReader reader = newSAXParser().getXMLReader(); + + try + { + // Xerces 1 - http://xerces.apache.org/xerces-j/features.html#external-general-entities + // Xerces 2 - http://xerces.apache.org/xerces2-j/features.html#external-general-entities + + // Using the XMLReader's setFeature + reader.setFeature( "http://xml.org/sax/features/external-general-entities", false ); + } + catch ( SAXNotRecognizedException e ) + { + // Tried an unknown feature. + } + catch ( SAXNotSupportedException e ) + { + // Tried a feature known to the parser but unsupported. + } + return reader; + } +} diff --git a/maven-xml/src/main/java/org/apache/maven/xml/SAXEvent.java b/maven-xml/src/main/java/org/apache/maven/xml/sax/SAXEvent.java similarity index 96% rename from maven-xml/src/main/java/org/apache/maven/xml/SAXEvent.java rename to maven-xml/src/main/java/org/apache/maven/xml/sax/SAXEvent.java index 11aad6dec52f..81269570ad60 100644 --- a/maven-xml/src/main/java/org/apache/maven/xml/SAXEvent.java +++ b/maven-xml/src/main/java/org/apache/maven/xml/sax/SAXEvent.java @@ -1,4 +1,4 @@ -package org.apache.maven.xml; +package org.apache.maven.xml.sax; /* * Licensed to the Apache Software Foundation (ASF) under one diff --git a/maven-xml/src/main/java/org/apache/maven/xml/SAXEventFactory.java b/maven-xml/src/main/java/org/apache/maven/xml/sax/SAXEventFactory.java similarity index 65% rename from maven-xml/src/main/java/org/apache/maven/xml/SAXEventFactory.java rename to maven-xml/src/main/java/org/apache/maven/xml/sax/SAXEventFactory.java index 6d525f696124..84e13e5fad58 100644 --- a/maven-xml/src/main/java/org/apache/maven/xml/SAXEventFactory.java +++ b/maven-xml/src/main/java/org/apache/maven/xml/sax/SAXEventFactory.java @@ -1,4 +1,4 @@ -package org.apache.maven.xml; +package org.apache.maven.xml.sax; /* * Licensed to the Apache Software Foundation (ASF) under one @@ -22,6 +22,7 @@ import org.xml.sax.Attributes; import org.xml.sax.ContentHandler; import org.xml.sax.Locator; +import org.xml.sax.ext.LexicalHandler; /** * Factory for SAXEvents @@ -32,25 +33,19 @@ public final class SAXEventFactory { private final ContentHandler contentHandler; + + private final LexicalHandler lexicalHandler; - protected SAXEventFactory( ContentHandler contentHandler ) + protected SAXEventFactory( ContentHandler contentHandler, LexicalHandler lexicalHandler ) { this.contentHandler = contentHandler; + this.lexicalHandler = lexicalHandler; } public SAXEvent characters( final char[] ch, final int start, final int length ) { - final char[] txt; - if ( start > 0 ) - { - txt = new char[length]; - System.arraycopy( ch, start, txt, 0, length ); - } - else - { - txt = ch; - } - + final char[] txt = new char[length]; + System.arraycopy( ch, start, txt, 0, length ); return () -> contentHandler.characters( txt, 0, length ); } @@ -104,8 +99,46 @@ public SAXEvent startPrefixMapping( final String prefix, final String uri ) return () -> contentHandler.startPrefixMapping( prefix, uri ); } - public static SAXEventFactory newInstance( ContentHandler handler ) + public static SAXEventFactory newInstance( ContentHandler contentHandler, LexicalHandler lexicalHandler ) + { + return new SAXEventFactory( contentHandler, lexicalHandler ); + } + + public SAXEvent startDTD( String name, String publicId, String systemId ) + { + return () -> lexicalHandler.startDTD( name, publicId, systemId ); + } + + public SAXEvent endDTD() + { + return () -> lexicalHandler.endDTD(); + } + + public SAXEvent startEntity( String name ) + { + return () -> lexicalHandler.startEntity( name ); + } + + public SAXEvent endEntity( String name ) + { + return () -> lexicalHandler.endEntity( name ); + + } + + public SAXEvent startCDATA() + { + return () -> lexicalHandler.startCDATA(); + } + + public SAXEvent endCDATA() + { + return () -> lexicalHandler.endCDATA(); + } + + public SAXEvent comment( char[] ch, int start, int length ) { - return new SAXEventFactory( handler ); + final char[] txt = new char[length]; + System.arraycopy( ch, start, txt, 0, length ); + return () -> lexicalHandler.comment( txt, 0, length ); } } diff --git a/maven-xml/src/main/java/org/apache/maven/xml/SAXEventUtils.java b/maven-xml/src/main/java/org/apache/maven/xml/sax/SAXEventUtils.java similarity index 97% rename from maven-xml/src/main/java/org/apache/maven/xml/SAXEventUtils.java rename to maven-xml/src/main/java/org/apache/maven/xml/sax/SAXEventUtils.java index 2f3644d0a23c..483bb7d8b7fc 100644 --- a/maven-xml/src/main/java/org/apache/maven/xml/SAXEventUtils.java +++ b/maven-xml/src/main/java/org/apache/maven/xml/sax/SAXEventUtils.java @@ -1,4 +1,4 @@ -package org.apache.maven.xml; +package org.apache.maven.xml.sax; /* * Licensed to the Apache Software Foundation (ASF) under one diff --git a/maven-xml/src/main/java/org/apache/maven/xml/sax/filter/AbstractEventXMLFilter.java b/maven-xml/src/main/java/org/apache/maven/xml/sax/filter/AbstractEventXMLFilter.java new file mode 100644 index 000000000000..d52cb7c64d37 --- /dev/null +++ b/maven-xml/src/main/java/org/apache/maven/xml/sax/filter/AbstractEventXMLFilter.java @@ -0,0 +1,272 @@ +package org.apache.maven.xml.sax.filter; + +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import org.apache.maven.xml.sax.SAXEvent; +import org.apache.maven.xml.sax.SAXEventFactory; +import org.xml.sax.Attributes; +import org.xml.sax.Locator; +import org.xml.sax.SAXException; +import org.xml.sax.XMLReader; +import org.xml.sax.ext.LexicalHandler; + +/** + * Builds up a list of SAXEvents, which will be executed with {@link #executeEvents()} + * + * @author Robert Scholte + * @since 3.7.0 + */ +abstract class AbstractEventXMLFilter extends AbstractSAXFilter +{ + private List saxEvents = new ArrayList<>(); + + private SAXEventFactory eventFactory; + + // characters BEFORE startElement must get state of startingElement + // this way removing based on state keeps formatting + private SAXEvent characters; + + // map of characters AFTER starting element, will be cleaned up after closeElement + private Map charactersMap = new HashMap<>(); + + protected abstract boolean isParsing(); + + protected abstract String getState(); + + protected boolean acceptEvent( String state ) + { + return true; + } + +// protected final void applyCharacters() throws SAXException +// { +// if ( characters != null ) +// { +// processEvent( characters ); +// } +// } + + AbstractEventXMLFilter() + { + super(); + } + + AbstractEventXMLFilter( T parent ) + { + setParent( parent ); + } + + private SAXEventFactory getEventFactory() + { + if ( eventFactory == null ) + { + eventFactory = SAXEventFactory.newInstance( getContentHandler(), getLexicalHandler() ); + } + return eventFactory; + } + + private void processEvent( final SAXEvent event ) + throws SAXException + { + if ( isParsing() ) + { + final String eventState = getState(); + final SAXEvent charactersEvent = characters; + + if ( charactersEvent != null ) + { + saxEvents.add( () -> + { + if ( acceptEvent( eventState ) ) + { + charactersEvent.execute(); + } + } ); + characters = null; + } + + saxEvents.add( () -> + { + if ( acceptEvent( eventState ) ) + { + event.execute(); + } + } ); + } + else + { + event.execute(); + } + } + + protected final void executeEvents() throws SAXException + { + final String eventState = getState(); + final SAXEvent charactersEvent = characters; + if ( charactersEvent != null ) + { + saxEvents.add( () -> + { + if ( acceptEvent( eventState ) ) + { + charactersEvent.execute(); + } + } ); + characters = null; + } + + // not with streams due to checked SAXException + for ( SAXEvent saxEvent : saxEvents ) + { + saxEvent.execute(); + } + } + + @Override + public void setDocumentLocator( Locator locator ) + { + try + { + processEvent( getEventFactory().setDocumentLocator( locator ) ); + } + catch ( SAXException e ) + { + // noop, setDocumentLocator can never throw a SAXException + } + } + + @Override + public void startDocument() throws SAXException + { + processEvent( getEventFactory().startDocument() ); + } + + @Override + public void endDocument() throws SAXException + { + processEvent( getEventFactory().endDocument() ); + } + + @Override + public void startPrefixMapping( String prefix, String uri ) throws SAXException + { + processEvent( getEventFactory().startPrefixMapping( prefix, uri ) ); + } + + @Override + public void endPrefixMapping( String prefix ) throws SAXException + { + processEvent( getEventFactory().endPrefixMapping( prefix ) ); + } + + @Override + public void startElement( String uri, String localName, String qName, Attributes atts ) throws SAXException + { + processEvent( getEventFactory().startElement( uri, localName, qName, atts ) ); + } + + @Override + public void endElement( String uri, String localName, String qName ) throws SAXException + { + processEvent( getEventFactory().endElement( uri, localName, qName ) ); + } + + @Override + public void characters( char[] ch, int start, int length ) throws SAXException + { + if ( isParsing() ) + { + this.characters = getEventFactory().characters( ch, start, length ); + this.charactersMap.put( getState(), characters ); + } + else + { + super.characters( ch, start, length ); + } + } + + @Override + public void ignorableWhitespace( char[] ch, int start, int length ) throws SAXException + { + processEvent( getEventFactory().ignorableWhitespace( ch, start, length ) ); + } + + @Override + public void processingInstruction( String target, String data ) throws SAXException + { + processEvent( getEventFactory().processingInstruction( target, data ) ); + } + + @Override + public void skippedEntity( String name ) throws SAXException + { + processEvent( getEventFactory().skippedEntity( name ) ); + } + + @Override + public void startDTD( String name, String publicId, String systemId ) throws SAXException + { + processEvent( getEventFactory().startCDATA() ); + } + + @Override + public void endDTD() throws SAXException + { + processEvent( getEventFactory().endDTD() ); + } + + @Override + public void startEntity( String name ) throws SAXException + { + processEvent( getEventFactory().startEntity( name ) ); + } + + @Override + public void endEntity( String name ) throws SAXException + { + processEvent( getEventFactory().endEntity( name ) ); + } + + @Override + public void startCDATA() + throws SAXException + { + processEvent( getEventFactory().startCDATA() ); + } + + @Override + public void endCDATA() + throws SAXException + { + processEvent( getEventFactory().endCDATA() ); + } + + @Override + public void comment( char[] ch, int start, int length ) + throws SAXException + { + processEvent( getEventFactory().comment( ch, start, length ) ); + } +} diff --git a/maven-xml/src/main/java/org/apache/maven/xml/sax/filter/AbstractSAXFilter.java b/maven-xml/src/main/java/org/apache/maven/xml/sax/filter/AbstractSAXFilter.java new file mode 100644 index 000000000000..89de519c5963 --- /dev/null +++ b/maven-xml/src/main/java/org/apache/maven/xml/sax/filter/AbstractSAXFilter.java @@ -0,0 +1,130 @@ +package org.apache.maven.xml.sax.filter; + +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +import org.xml.sax.SAXException; +import org.xml.sax.XMLReader; +import org.xml.sax.ext.LexicalHandler; +import org.xml.sax.helpers.XMLFilterImpl; + +/** + * XMLFilter with LexicalHandler. + * Since some filters collect events before processing them, the LexicalHandler events must be collected too. + * Otherwise the LexicalHandler events might end up before all collected XMLReader events. + * + * @author Robert Scholte + * @since 3.7.0 + */ +public class AbstractSAXFilter extends XMLFilterImpl implements LexicalHandler +{ + private LexicalHandler lexicalHandler; + + AbstractSAXFilter() + { + super(); + } + + public AbstractSAXFilter( T parent ) + { + setParent( parent ); + setLexicalHandler( parent ); + } + + public LexicalHandler getLexicalHandler() + { + return lexicalHandler; + } + + public void setLexicalHandler( LexicalHandler lexicalHandler ) + { + this.lexicalHandler = lexicalHandler; + } + + @Override + public void startDTD( String name, String publicId, String systemId ) + throws SAXException + { + if ( lexicalHandler != null ) + { + lexicalHandler.startDTD( name, publicId, systemId ); + } + } + + @Override + public void endDTD() + throws SAXException + { + if ( lexicalHandler != null ) + { + lexicalHandler.endDTD(); + } + } + + @Override + public void startEntity( String name ) + throws SAXException + { + if ( lexicalHandler != null ) + { + lexicalHandler.startEntity( name ); + } + } + + @Override + public void endEntity( String name ) + throws SAXException + { + if ( lexicalHandler != null ) + { + lexicalHandler.endEntity( name ); + } + } + + @Override + public void startCDATA() + throws SAXException + { + if ( lexicalHandler != null ) + { + lexicalHandler.startCDATA(); + } + } + + @Override + public void endCDATA() + throws SAXException + { + if ( lexicalHandler != null ) + { + lexicalHandler.endCDATA(); + } + } + + @Override + public void comment( char[] ch, int start, int length ) + throws SAXException + { + if ( lexicalHandler != null ) + { + lexicalHandler.comment( ch, start, length ); + } + } + +} diff --git a/maven-xml/src/main/java/org/apache/maven/xml/filter/BuildPomXMLFilter.java b/maven-xml/src/main/java/org/apache/maven/xml/sax/filter/BuildPomXMLFilter.java similarity index 87% rename from maven-xml/src/main/java/org/apache/maven/xml/filter/BuildPomXMLFilter.java rename to maven-xml/src/main/java/org/apache/maven/xml/sax/filter/BuildPomXMLFilter.java index ab846a080a4b..041d5c18bccf 100644 --- a/maven-xml/src/main/java/org/apache/maven/xml/filter/BuildPomXMLFilter.java +++ b/maven-xml/src/main/java/org/apache/maven/xml/sax/filter/BuildPomXMLFilter.java @@ -1,4 +1,4 @@ -package org.apache.maven.xml.filter; +package org.apache.maven.xml.sax.filter; /* * Licensed to the Apache Software Foundation (ASF) under one @@ -20,7 +20,7 @@ */ import org.xml.sax.XMLReader; -import org.xml.sax.helpers.XMLFilterImpl; +import org.xml.sax.ext.LexicalHandler; /** * Filter to adjust pom on filesystem before being processed for effective pom. @@ -32,14 +32,14 @@ * @author Robert Scholte * @since 3.7.0 */ -public class BuildPomXMLFilter extends XMLFilterImpl +public class BuildPomXMLFilter extends AbstractSAXFilter { BuildPomXMLFilter() { super(); } - BuildPomXMLFilter( XMLReader parent ) + BuildPomXMLFilter( T parent ) { super( parent ); } diff --git a/maven-xml/src/main/java/org/apache/maven/xml/filter/BuildPomXMLFilterFactory.java b/maven-xml/src/main/java/org/apache/maven/xml/sax/filter/BuildPomXMLFilterFactory.java similarity index 66% rename from maven-xml/src/main/java/org/apache/maven/xml/filter/BuildPomXMLFilterFactory.java rename to maven-xml/src/main/java/org/apache/maven/xml/sax/filter/BuildPomXMLFilterFactory.java index 1df17baa7682..d1156739e251 100644 --- a/maven-xml/src/main/java/org/apache/maven/xml/filter/BuildPomXMLFilterFactory.java +++ b/maven-xml/src/main/java/org/apache/maven/xml/sax/filter/BuildPomXMLFilterFactory.java @@ -1,4 +1,4 @@ -package org.apache.maven.xml.filter; +package org.apache.maven.xml.sax.filter; /* * Licensed to the Apache Software Foundation (ASF) under one @@ -24,12 +24,18 @@ import java.util.function.Function; import javax.xml.parsers.ParserConfigurationException; +import javax.xml.transform.TransformerConfigurationException; +import javax.xml.transform.TransformerFactory; +import javax.xml.transform.sax.SAXTransformerFactory; import org.apache.maven.xml.Factories; import org.xml.sax.SAXException; import org.xml.sax.XMLReader; +import org.xml.sax.ext.LexicalHandler; /** + * Base class for third parties to extend. When annotating it with Named("somecustomname"), + * Maven will pick this up as instead of the DefaultBuildPomXMLFilterFactory * * @author Robert Scholte * @@ -38,15 +44,18 @@ public abstract class BuildPomXMLFilterFactory { public final BuildPomXMLFilter get( Path projectFile ) - throws SAXException, ParserConfigurationException + throws SAXException, ParserConfigurationException, TransformerConfigurationException { - XMLReader parent = getParent(); + AbstractSAXFilter parent = new AbstractSAXFilter(); + parent.setParent( getXMLReader() ); + parent.setLexicalHandler( getLexicalHander() ); if ( getDependencyKeyToVersionMapper() != null ) { ReactorDependencyXMLFilter reactorDependencyXMLFilter = new ReactorDependencyXMLFilter( getDependencyKeyToVersionMapper() ); reactorDependencyXMLFilter.setParent( parent ); + reactorDependencyXMLFilter.setLexicalHandler( parent ); parent = reactorDependencyXMLFilter; } @@ -55,6 +64,7 @@ public final BuildPomXMLFilter get( Path projectFile ) ParentXMLFilter parentFilter = new ParentXMLFilter( getRelativePathMapper() ); parentFilter.setProjectPath( projectFile.getParent() ); parentFilter.setParent( parent ); + parentFilter.setLexicalHandler( parent ); parent = parentFilter; } @@ -66,19 +76,32 @@ public final BuildPomXMLFilter get( Path projectFile ) if ( ciFriendlyFilter.isSet() ) { ciFriendlyFilter.setParent( parent ); + ciFriendlyFilter.setLexicalHandler( parent ); parent = ciFriendlyFilter; } return new BuildPomXMLFilter( parent ); } - protected XMLReader getParent() throws SAXException, ParserConfigurationException + protected XMLReader getXMLReader() throws SAXException, ParserConfigurationException { XMLReader xmlReader = Factories.newXMLReader(); xmlReader.setFeature( "http://xml.org/sax/features/namespaces", true ); return xmlReader; } + protected LexicalHandler getLexicalHander() throws TransformerConfigurationException + { + TransformerFactory transformerFactory = Factories.newTransformerFactory(); + if ( transformerFactory instanceof SAXTransformerFactory ) + { + SAXTransformerFactory saxTransformerFactory = (SAXTransformerFactory) transformerFactory; + return saxTransformerFactory.newTransformerHandler(); + } + throw new TransformerConfigurationException( "Failed to get LexicalHandler via TransformerFactory:" + + " it is not an instance of SAXTransformerFactory" ); + } + // getters for the 3 magic properties of CIFriendly versions ( https://maven.apache.org/maven-ci-friendly.html ) protected abstract Optional getChangelist(); diff --git a/maven-xml/src/main/java/org/apache/maven/xml/filter/CiFriendlyXMLFilter.java b/maven-xml/src/main/java/org/apache/maven/xml/sax/filter/CiFriendlyXMLFilter.java similarity index 95% rename from maven-xml/src/main/java/org/apache/maven/xml/filter/CiFriendlyXMLFilter.java rename to maven-xml/src/main/java/org/apache/maven/xml/sax/filter/CiFriendlyXMLFilter.java index 7f8c206232ed..a13e4d432fc7 100644 --- a/maven-xml/src/main/java/org/apache/maven/xml/filter/CiFriendlyXMLFilter.java +++ b/maven-xml/src/main/java/org/apache/maven/xml/sax/filter/CiFriendlyXMLFilter.java @@ -1,4 +1,4 @@ -package org.apache.maven.xml.filter; +package org.apache.maven.xml.sax.filter; /* * Licensed to the Apache Software Foundation (ASF) under one @@ -22,7 +22,6 @@ import java.util.function.Function; import org.xml.sax.SAXException; -import org.xml.sax.helpers.XMLFilterImpl; /** * Resolves all ci-friendly properties occurrences @@ -31,7 +30,7 @@ * @since 3.7.0 */ class CiFriendlyXMLFilter - extends XMLFilterImpl + extends AbstractSAXFilter { private Function replaceChain = Function.identity(); diff --git a/maven-xml/src/main/java/org/apache/maven/xml/filter/ConsumerPomXMLFilter.java b/maven-xml/src/main/java/org/apache/maven/xml/sax/filter/ConsumerPomXMLFilter.java similarity index 87% rename from maven-xml/src/main/java/org/apache/maven/xml/filter/ConsumerPomXMLFilter.java rename to maven-xml/src/main/java/org/apache/maven/xml/sax/filter/ConsumerPomXMLFilter.java index 8993d1dba4c9..1c227a733a28 100644 --- a/maven-xml/src/main/java/org/apache/maven/xml/filter/ConsumerPomXMLFilter.java +++ b/maven-xml/src/main/java/org/apache/maven/xml/sax/filter/ConsumerPomXMLFilter.java @@ -1,4 +1,4 @@ -package org.apache.maven.xml.filter; +package org.apache.maven.xml.sax.filter; /* * Licensed to the Apache Software Foundation (ASF) under one @@ -20,7 +20,7 @@ */ import org.xml.sax.XMLReader; -import org.xml.sax.helpers.XMLFilterImpl; +import org.xml.sax.ext.LexicalHandler; /** * XML Filter to transform pom.xml to consumer pom. @@ -33,9 +33,9 @@ * @author Robert Scholte * @since 3.7.0 */ -public class ConsumerPomXMLFilter extends XMLFilterImpl +public class ConsumerPomXMLFilter extends AbstractSAXFilter { - ConsumerPomXMLFilter( XMLReader filter ) + ConsumerPomXMLFilter( T filter ) { super( filter ); } diff --git a/maven-xml/src/main/java/org/apache/maven/xml/filter/ConsumerPomXMLFilterFactory.java b/maven-xml/src/main/java/org/apache/maven/xml/sax/filter/ConsumerPomXMLFilterFactory.java similarity index 83% rename from maven-xml/src/main/java/org/apache/maven/xml/filter/ConsumerPomXMLFilterFactory.java rename to maven-xml/src/main/java/org/apache/maven/xml/sax/filter/ConsumerPomXMLFilterFactory.java index dfea9ba06aa5..612ddb9ead91 100644 --- a/maven-xml/src/main/java/org/apache/maven/xml/filter/ConsumerPomXMLFilterFactory.java +++ b/maven-xml/src/main/java/org/apache/maven/xml/sax/filter/ConsumerPomXMLFilterFactory.java @@ -1,4 +1,4 @@ -package org.apache.maven.xml.filter; +package org.apache.maven.xml.sax.filter; /* * Licensed to the Apache Software Foundation (ASF) under one @@ -24,10 +24,9 @@ import javax.inject.Inject; import javax.inject.Provider; import javax.xml.parsers.ParserConfigurationException; +import javax.xml.transform.TransformerConfigurationException; import org.xml.sax.SAXException; -import org.xml.sax.XMLFilter; -import org.xml.sax.XMLReader; /** * @@ -50,12 +49,12 @@ public ConsumerPomXMLFilterFactory() } public final ConsumerPomXMLFilter get( Path projectPath ) - throws SAXException, ParserConfigurationException + throws SAXException, ParserConfigurationException, TransformerConfigurationException { - XMLFilter parent = buildPomXMLFilterFactory.get().get( projectPath ); + BuildPomXMLFilter parent = buildPomXMLFilterFactory.get().get( projectPath ); // Ensure that xs:any elements aren't touched by next filters - XMLReader filter = new FastForwardFilter( parent ); + AbstractSAXFilter filter = new FastForwardFilter( parent ); // Strip modules filter = new ModulesXMLFilter( filter ); diff --git a/maven-xml/src/main/java/org/apache/maven/xml/filter/DependencyKey.java b/maven-xml/src/main/java/org/apache/maven/xml/sax/filter/DependencyKey.java similarity index 98% rename from maven-xml/src/main/java/org/apache/maven/xml/filter/DependencyKey.java rename to maven-xml/src/main/java/org/apache/maven/xml/sax/filter/DependencyKey.java index 6b5e905012ed..1168351744fa 100644 --- a/maven-xml/src/main/java/org/apache/maven/xml/filter/DependencyKey.java +++ b/maven-xml/src/main/java/org/apache/maven/xml/sax/filter/DependencyKey.java @@ -1,4 +1,4 @@ -package org.apache.maven.xml.filter; +package org.apache.maven.xml.sax.filter; /* * Licensed to the Apache Software Foundation (ASF) under one diff --git a/maven-xml/src/main/java/org/apache/maven/xml/filter/FastForwardFilter.java b/maven-xml/src/main/java/org/apache/maven/xml/sax/filter/FastForwardFilter.java similarity index 94% rename from maven-xml/src/main/java/org/apache/maven/xml/filter/FastForwardFilter.java rename to maven-xml/src/main/java/org/apache/maven/xml/sax/filter/FastForwardFilter.java index 6e03a3459d42..0100e6bffd00 100644 --- a/maven-xml/src/main/java/org/apache/maven/xml/filter/FastForwardFilter.java +++ b/maven-xml/src/main/java/org/apache/maven/xml/sax/filter/FastForwardFilter.java @@ -1,4 +1,4 @@ -package org.apache.maven.xml.filter; +package org.apache.maven.xml.sax.filter; /* * Licensed to the Apache Software Foundation (ASF) under one @@ -27,7 +27,7 @@ import org.xml.sax.SAXException; import org.xml.sax.XMLFilter; import org.xml.sax.XMLReader; -import org.xml.sax.helpers.XMLFilterImpl; +import org.xml.sax.ext.LexicalHandler; /** * This filter will skip all following filters and write directly to the output. @@ -36,7 +36,7 @@ * @author Robert Scholte * @since 3.7.0 */ -class FastForwardFilter extends XMLFilterImpl +class FastForwardFilter extends AbstractSAXFilter { /** * DOM elements of pom @@ -61,7 +61,7 @@ class FastForwardFilter extends XMLFilterImpl super(); } - FastForwardFilter( XMLReader parent ) + FastForwardFilter( T parent ) { super( parent ); } diff --git a/maven-xml/src/main/java/org/apache/maven/xml/filter/ModulesXMLFilter.java b/maven-xml/src/main/java/org/apache/maven/xml/sax/filter/ModulesXMLFilter.java similarity index 85% rename from maven-xml/src/main/java/org/apache/maven/xml/filter/ModulesXMLFilter.java rename to maven-xml/src/main/java/org/apache/maven/xml/sax/filter/ModulesXMLFilter.java index 9e7b6fdbe5de..16ca2edb35c7 100644 --- a/maven-xml/src/main/java/org/apache/maven/xml/filter/ModulesXMLFilter.java +++ b/maven-xml/src/main/java/org/apache/maven/xml/sax/filter/ModulesXMLFilter.java @@ -1,4 +1,4 @@ -package org.apache.maven.xml.filter; +package org.apache.maven.xml.sax.filter; /* * Licensed to the Apache Software Foundation (ASF) under one @@ -22,7 +22,7 @@ import org.xml.sax.Attributes; import org.xml.sax.SAXException; import org.xml.sax.XMLReader; -import org.xml.sax.helpers.XMLFilterImpl; +import org.xml.sax.ext.LexicalHandler; /** * Remove all modules, this is just buildtime information @@ -31,7 +31,7 @@ * @since 3.7.0 */ class ModulesXMLFilter - extends XMLFilterImpl + extends AbstractSAXFilter { /** * Using 3 to also remove whitespace-block after closing tag @@ -46,7 +46,7 @@ class ModulesXMLFilter super(); } - ModulesXMLFilter( XMLReader parent ) + ModulesXMLFilter( T parent ) { super( parent ); } @@ -98,5 +98,14 @@ public void characters( char[] ch, int start, int length ) super.characters( ch, start, length ); } } - + + @Override + public void comment( char[] ch, int start, int length ) + throws SAXException + { + if ( modulesStatus != 1 ) + { + super.comment( ch, start, length ); + } + } } diff --git a/maven-xml/src/main/java/org/apache/maven/xml/filter/ParentXMLFilter.java b/maven-xml/src/main/java/org/apache/maven/xml/sax/filter/ParentXMLFilter.java similarity index 59% rename from maven-xml/src/main/java/org/apache/maven/xml/filter/ParentXMLFilter.java rename to maven-xml/src/main/java/org/apache/maven/xml/sax/filter/ParentXMLFilter.java index 7bb744d3e2ed..9cb6ff28210d 100644 --- a/maven-xml/src/main/java/org/apache/maven/xml/filter/ParentXMLFilter.java +++ b/maven-xml/src/main/java/org/apache/maven/xml/sax/filter/ParentXMLFilter.java @@ -1,4 +1,4 @@ -package org.apache.maven.xml.filter; +package org.apache.maven.xml.sax.filter; /* * Licensed to the Apache Software Foundation (ASF) under one @@ -22,19 +22,13 @@ import java.nio.file.Path; import java.nio.file.Paths; -import java.util.ArrayList; -import java.util.List; import java.util.Objects; import java.util.Optional; import java.util.function.Function; -import org.apache.maven.xml.SAXEvent; -import org.apache.maven.xml.SAXEventFactory; -import org.apache.maven.xml.SAXEventUtils; +import org.apache.maven.xml.sax.SAXEventUtils; import org.xml.sax.Attributes; -import org.xml.sax.Locator; import org.xml.sax.SAXException; -import org.xml.sax.helpers.XMLFilterImpl; /** *

              @@ -46,7 +40,7 @@ * @since 3.7.0 */ class ParentXMLFilter - extends XMLFilterImpl + extends AbstractEventXMLFilter { private boolean parsingParent; @@ -63,12 +57,6 @@ class ParentXMLFilter private Optional resolvedParent; - private char[] linebreak; - - private List saxEvents = new ArrayList<>(); - - private SAXEventFactory eventFactory; - private final Function> relativePathMapper; private Path projectPath; @@ -88,36 +76,24 @@ public void setProjectPath( Path projectPath ) this.projectPath = projectPath; } - private SAXEventFactory getEventFactory() + @Override + protected boolean isParsing() { - if ( eventFactory == null ) - { - eventFactory = SAXEventFactory.newInstance( getContentHandler() ); - } - return eventFactory; + return parsingParent; } - private void processEvent( final SAXEvent event ) - throws SAXException + @Override + protected String getState() { - if ( parsingParent ) - { - final String eventState = state; - - saxEvents.add( () -> - { - if ( !( "relativePath".equals( eventState ) && resolvedParent.isPresent() ) ) - { - event.execute(); - } - } ); - } - else - { - event.execute(); - } + return state; } + @Override + protected boolean acceptEvent( String eventState ) + { + return !( "relativePath".equals( eventState ) && resolvedParent.isPresent() ); + } + @Override public void startElement( String uri, final String localName, String qName, Attributes atts ) throws SAXException @@ -134,7 +110,7 @@ public void startElement( String uri, final String localName, String qName, Attr hasVersion |= "version".equals( localName ); } - processEvent( getEventFactory().startElement( uri, localName, qName, atts ) ); + super.startElement( uri, localName, qName, atts ); } @Override @@ -157,9 +133,6 @@ public void characters( char[] ch, int start, int length ) break; } } - - linebreak = new char[l]; - System.arraycopy( ch, start, linebreak, 0, l ); break; case "relativePath": relativePath = new String( ch, start, length ); @@ -175,14 +148,7 @@ public void characters( char[] ch, int start, int length ) } } - processEvent( getEventFactory().characters( ch, start, length ) ); - } - - @Override - public void endDocument() - throws SAXException - { - processEvent( getEventFactory().endDocument() ); + super.characters( ch, start, length ); } @Override @@ -200,30 +166,20 @@ public void endElement( String uri, final String localName, String qName ) resolveRelativePath( Paths.get( Objects.toString( relativePath, "../pom.xml" ) ) ); } - // not with streams due to checked SAXException - for ( SAXEvent saxEvent : saxEvents ) - { - saxEvent.execute(); - } - if ( !hasVersion && resolvedParent.isPresent() ) { String versionQName = SAXEventUtils.renameQName( qName, "version" ); - getEventFactory().startElement( uri, "version", versionQName, null ).execute(); + super.startElement( uri, "version", versionQName, null ); String resolvedParentVersion = resolvedParent.get().getVersion(); - getEventFactory().characters( resolvedParentVersion.toCharArray(), 0, - resolvedParentVersion.length() ).execute(); - - getEventFactory().endElement( uri, "version", versionQName ).execute(); + super.characters( resolvedParentVersion.toCharArray(), 0, + resolvedParentVersion.length() ); - if ( linebreak != null ) - { - getEventFactory().characters( linebreak, 0, linebreak.length ).execute(); - } + super.endElement( uri, "version", versionQName ); } + executeEvents(); parsingParent = false; break; @@ -232,68 +188,12 @@ public void endElement( String uri, final String localName, String qName ) } } - processEvent( getEventFactory().endElement( uri, localName, qName ) ); + super.endElement( uri, localName, qName ); // for this simple structure resetting to parent it sufficient state = "parent"; } - @Override - public void endPrefixMapping( String prefix ) - throws SAXException - { - processEvent( getEventFactory().endPrefixMapping( prefix ) ); - } - - @Override - public void ignorableWhitespace( char[] ch, int start, int length ) - throws SAXException - { - processEvent( getEventFactory().ignorableWhitespace( ch, start, length ) ); - } - - @Override - public void processingInstruction( String target, String data ) - throws SAXException - { - processEvent( getEventFactory().processingInstruction( target, data ) ); - - } - - @Override - public void setDocumentLocator( Locator locator ) - { - try - { - processEvent( getEventFactory().setDocumentLocator( locator ) ); - } - catch ( SAXException e ) - { - // noop - } - } - - @Override - public void skippedEntity( String name ) - throws SAXException - { - processEvent( getEventFactory().skippedEntity( name ) ); - } - - @Override - public void startDocument() - throws SAXException - { - processEvent( getEventFactory().startDocument() ); - } - - @Override - public void startPrefixMapping( String prefix, String uri ) - throws SAXException - { - processEvent( getEventFactory().startPrefixMapping( prefix, uri ) ); - } - protected Optional resolveRelativePath( Path relativePath ) { Optional mappedProject = diff --git a/maven-xml/src/main/java/org/apache/maven/xml/filter/ReactorDependencyXMLFilter.java b/maven-xml/src/main/java/org/apache/maven/xml/sax/filter/ReactorDependencyXMLFilter.java similarity index 90% rename from maven-xml/src/main/java/org/apache/maven/xml/filter/ReactorDependencyXMLFilter.java rename to maven-xml/src/main/java/org/apache/maven/xml/sax/filter/ReactorDependencyXMLFilter.java index fa8b1e533352..b37092f6b9e6 100644 --- a/maven-xml/src/main/java/org/apache/maven/xml/filter/ReactorDependencyXMLFilter.java +++ b/maven-xml/src/main/java/org/apache/maven/xml/sax/filter/ReactorDependencyXMLFilter.java @@ -1,4 +1,4 @@ -package org.apache.maven.xml.filter; +package org.apache.maven.xml.sax.filter; /* * Licensed to the Apache Software Foundation (ASF) under one @@ -21,10 +21,9 @@ import java.util.function.Function; -import org.apache.maven.xml.SAXEventUtils; +import org.apache.maven.xml.sax.SAXEventUtils; import org.xml.sax.Attributes; import org.xml.sax.SAXException; -import org.xml.sax.helpers.XMLFilterImpl; /** * Will apply the version if the dependency is part of the reactor @@ -32,7 +31,7 @@ * @author Robert Scholte * @since 3.7.0 */ -public class ReactorDependencyXMLFilter extends XMLFilterImpl +public class ReactorDependencyXMLFilter extends AbstractEventXMLFilter { private boolean parsingDependency; @@ -109,11 +108,14 @@ public void endElement( String uri, final String localName, String qName ) if ( version != null ) { String versionQName = SAXEventUtils.renameQName( qName, "version" ); + super.startElement( uri, "version", versionQName, null ); super.characters( version.toCharArray(), 0, version.length() ); super.endElement( uri, "version", versionQName ); } } + super.executeEvents(); + parsingDependency = false; // reset @@ -136,5 +138,17 @@ private String getVersion() { return reactorVersionMapper.apply( new DependencyKey( groupId, artifactId ) ); } + + @Override + protected boolean isParsing() + { + return parsingDependency; + } + + @Override + protected String getState() + { + return state; + } } diff --git a/maven-xml/src/main/java/org/apache/maven/xml/filter/RelativePathXMLFilter.java b/maven-xml/src/main/java/org/apache/maven/xml/sax/filter/RelativePathXMLFilter.java similarity index 57% rename from maven-xml/src/main/java/org/apache/maven/xml/filter/RelativePathXMLFilter.java rename to maven-xml/src/main/java/org/apache/maven/xml/sax/filter/RelativePathXMLFilter.java index 5dc367fa993e..ebbc890347c2 100644 --- a/maven-xml/src/main/java/org/apache/maven/xml/filter/RelativePathXMLFilter.java +++ b/maven-xml/src/main/java/org/apache/maven/xml/sax/filter/RelativePathXMLFilter.java @@ -1,4 +1,4 @@ -package org.apache.maven.xml.filter; +package org.apache.maven.xml.sax.filter; /* * Licensed to the Apache Software Foundation (ASF) under one @@ -22,7 +22,7 @@ import org.xml.sax.Attributes; import org.xml.sax.SAXException; import org.xml.sax.XMLReader; -import org.xml.sax.helpers.XMLFilterImpl; +import org.xml.sax.ext.LexicalHandler; /** * Remove content from relativePath @@ -33,67 +33,78 @@ * @since 3.7.0 */ class RelativePathXMLFilter - extends XMLFilterImpl + extends AbstractEventXMLFilter { - /** - * Using 3 to also remove whitespace-block after closing tag - * -1 none - * 1 started - * 2 ended - */ - int relativePathStatus = -1; + private boolean parsingParent; + + private String state; RelativePathXMLFilter() { super(); } - RelativePathXMLFilter( XMLReader parent ) + RelativePathXMLFilter( T parent ) { super( parent ); } - + @Override - public void startElement( String uri, String localName, String qName, Attributes atts ) + public void startElement( String uri, final String localName, String qName, Attributes atts ) throws SAXException { - - if ( relativePathStatus == -1 && "relativePath".equals( localName ) ) + if ( !parsingParent && "parent".equals( localName ) ) { - relativePathStatus = 1; + parsingParent = true; } - else if ( relativePathStatus == 2 ) + + if ( parsingParent ) { - relativePathStatus = -1; + state = localName; } - + super.startElement( uri, localName, qName, atts ); } - + @Override public void endElement( String uri, String localName, String qName ) throws SAXException { - if ( relativePathStatus == 1 && "relativePath".equals( localName ) ) - { - relativePathStatus = 2; - } - else if ( relativePathStatus == 2 ) + if ( parsingParent ) { - relativePathStatus = -1; + switch ( localName ) + { + case "parent": + executeEvents(); + + parsingParent = false; + break; + default: + break; + } } super.endElement( uri, localName, qName ); + + // for this simple structure resetting to parent it sufficient + state = "parent"; } @Override - public void characters( char[] ch, int start, int length ) - throws SAXException + protected boolean isParsing() { - if ( relativePathStatus != 1 ) - { - super.characters( ch, start, length ); - } + return parsingParent; } + @Override + protected String getState() + { + return state; + } + + @Override + protected boolean acceptEvent( String state ) + { + return !"relativePath".equals( state ); + } } diff --git a/maven-xml/src/main/java/org/apache/maven/xml/filter/RelativeProject.java b/maven-xml/src/main/java/org/apache/maven/xml/sax/filter/RelativeProject.java similarity index 97% rename from maven-xml/src/main/java/org/apache/maven/xml/filter/RelativeProject.java rename to maven-xml/src/main/java/org/apache/maven/xml/sax/filter/RelativeProject.java index a158d38ee215..067e170b5a05 100644 --- a/maven-xml/src/main/java/org/apache/maven/xml/filter/RelativeProject.java +++ b/maven-xml/src/main/java/org/apache/maven/xml/sax/filter/RelativeProject.java @@ -1,4 +1,4 @@ -package org.apache.maven.xml.filter; +package org.apache.maven.xml.sax.filter; /* * Licensed to the Apache Software Foundation (ASF) under one diff --git a/maven-xml/src/test/java/org/apache/maven/xml/filter/ConsumerPomXMLFilterTest.java b/maven-xml/src/test/java/org/apache/maven/xml/filter/ConsumerPomXMLFilterTest.java deleted file mode 100644 index 4ed4ab682bdf..000000000000 --- a/maven-xml/src/test/java/org/apache/maven/xml/filter/ConsumerPomXMLFilterTest.java +++ /dev/null @@ -1,168 +0,0 @@ -package org.apache.maven.xml.filter; - -/* - * 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 static org.xmlunit.assertj.XmlAssert.assertThat; - -import java.nio.file.Path; -import java.nio.file.Paths; -import java.util.Optional; -import java.util.function.Function; - -import javax.inject.Provider; -import javax.xml.parsers.ParserConfigurationException; - -import org.junit.Test; -import org.xml.sax.SAXException; -import org.xml.sax.XMLFilter; - -public class ConsumerPomXMLFilterTest extends AbstractXMLFilterTests -{ - @Override - protected XMLFilter getFilter() throws SAXException, ParserConfigurationException - { - final BuildPomXMLFilterFactory buildPomXMLFilterFactory = new BuildPomXMLFilterFactory() - { - @Override - protected Optional getSha1() - { - return Optional.empty(); - } - - @Override - protected Optional getRevision() - { - return Optional.empty(); - } - - @Override - protected Optional getChangelist() - { - return Optional.of( "CL" ); - } - - @Override - protected Function> getRelativePathMapper() - { - return null; - } - - @Override - protected Function getDependencyKeyToVersionMapper() - { - return null; - } - }; - - Provider provider = new Provider() - { - - @Override - public BuildPomXMLFilterFactory get() - { - return buildPomXMLFilterFactory; - } - }; - - XMLFilter filter = new ConsumerPomXMLFilterFactory( provider ) - { - }.get( Paths.get( "pom.xml" ) ); - filter.setFeature( "http://xml.org/sax/features/namespaces", true ); - return filter; - } - - @Test - public void testAllFilters() throws Exception { - String input = "\n" - + " \n" - + " GROUPID\n" - + " PARENT\n" - + " VERSION\n" - + " ../pom.xml\n" - + " \n" - + " PROJECT\n" - + " \n" - + " ab\n" - + " ../cd\n" - + " \n" - + ""; - String expected = "\n" - + " \n" - + " GROUPID\n" - + " PARENT\n" - + " VERSION\n" - + " \n" - + " \n" - + " PROJECT\n" - + ""; - String actual = transform( input ); - assertThat( actual ).and( expected ).ignoreWhitespace().areIdentical(); - } - - @Test - public void testMe() throws Exception { - String input = "\r\n" + - "\r\n" + - " 4.0.0\r\n" + - " org.sonatype.mavenbook.multispring\r\n" + - " parent\r\n" + - " 0.9-${changelist}-SNAPSHOT\r\n" + - " pom\r\n" + - " Multi-Spring Chapter Parent Project\r\n" + - " \r\n" + - " simple-parent\r\n" + - " \r\n" + - " \r\n" + - " \r\n" + - " \r\n" + - " apache.snapshots\r\n" + - " http://repository.apache.org/snapshots/\r\n" + - " \r\n" + - " \r\n" + - ""; - String expected = "\r\n" + - "\r\n" + - " 4.0.0\r\n" + - " org.sonatype.mavenbook.multispring\r\n" + - " parent\r\n" + - " 0.9-CL-SNAPSHOT\r\n" + - " pom\r\n" + - " Multi-Spring Chapter Parent Project\r\n" + - " \r\n" + - " \r\n" + - " \r\n" + - " apache.snapshots\r\n" + - " http://repository.apache.org/snapshots/\r\n" + - " \r\n" + - " \r\n" + - ""; - String actual = transform( input ); - assertThat( actual ).and( expected ).ignoreWhitespace().areIdentical(); - } - - - -} diff --git a/maven-xml/src/test/java/org/apache/maven/xml/sax/LexicalHandlerVerifier.java b/maven-xml/src/test/java/org/apache/maven/xml/sax/LexicalHandlerVerifier.java new file mode 100644 index 000000000000..49eb7729c6eb --- /dev/null +++ b/maven-xml/src/test/java/org/apache/maven/xml/sax/LexicalHandlerVerifier.java @@ -0,0 +1,277 @@ +package org.apache.maven.xml.sax; + +/* + * 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 static org.xmlunit.assertj.XmlAssert.assertThat; + +import java.io.StringReader; +import java.io.StringWriter; +import java.io.Writer; +import java.util.Arrays; + +import javax.xml.transform.OutputKeys; +import javax.xml.transform.Source; +import javax.xml.transform.Transformer; +import javax.xml.transform.sax.SAXResult; +import javax.xml.transform.sax.SAXSource; +import javax.xml.transform.sax.SAXTransformerFactory; +import javax.xml.transform.sax.TransformerHandler; +import javax.xml.transform.stream.StreamResult; +import javax.xml.transform.stream.StreamSource; + +import org.apache.maven.xml.Factories; +import org.apache.maven.xml.sax.filter.AbstractSAXFilter; +import org.junit.Rule; +import org.junit.Test; +import org.junit.rules.ExpectedException; +import org.xml.sax.InputSource; +import org.xml.sax.SAXException; +import org.xml.sax.XMLFilter; +import org.xml.sax.XMLReader; +import org.xml.sax.ext.LexicalHandler; +import org.xml.sax.helpers.XMLFilterImpl; + +/** + * Some tests to help understand the chain of events regarding XMLFilters, XMLReaders, LexicalHandlers and Transformers + * + * @author Robert Scholte + * + */ +public class LexicalHandlerVerifier +{ + private static final String SAX_PROPERTIES_LEXICAL_HANDLER = "http://xml.org/sax/properties/lexical-handler"; + + @Rule + public ExpectedException expectedException = ExpectedException.none(); + + @Test + public void parseXmlReader() throws Exception + { + expectedException.expect( UnsupportedOperationException.class ); + expectedException.expectMessage( "LexicalHandlerVerifier" ); + + XMLReader reader = Factories.newXMLReader(); + reader.setProperty( SAX_PROPERTIES_LEXICAL_HANDLER, new UnsupportedOperationExceptionLexicalHandler() ); + + InputSource inputSource = new InputSource( new StringReader( "" ) ); + reader.parse( inputSource ); + } + + @Test + public void parseXmlFilter() throws Exception + { + expectedException.expect( UnsupportedOperationException.class ); + expectedException.expectMessage( "LexicalHandlerVerifier" ); + + XMLReader reader = Factories.newXMLReader(); + reader.setProperty( SAX_PROPERTIES_LEXICAL_HANDLER, new UnsupportedOperationExceptionLexicalHandler() ); + + XMLFilter filter = new XMLFilterImpl( reader ); + + InputSource inputSource = new InputSource( new StringReader( "" ) ); + filter.parse( inputSource ); + } + + @Test + public void transformXmlReader() throws Exception + { + Writer writer = new StringWriter(); + StreamResult result = new StreamResult( writer ); + + SAXTransformerFactory transformerFactory = (SAXTransformerFactory) Factories.newTransformerFactory(); + TransformerHandler transformerHandler = transformerFactory.newTransformerHandler(); + transformerHandler.setResult( result ); + Transformer transformer = transformerFactory.newTransformer(); + transformer.setOutputProperty( OutputKeys.OMIT_XML_DECLARATION, "yes" ); + + Source xmlSource = new StreamSource( new StringReader( "" ) ); + + SAXResult transformResult = new SAXResult( transformerHandler ); + transformResult.setLexicalHandler( new SortCommentLexicalHandler( transformerHandler ) ); + transformer.transform( xmlSource, transformResult ); + + assertThat( writer.toString() ).and( "" + + "" ).areIdentical(); + } + + @Test + public void transformXmlFilter() throws Exception + { + Writer writer = new StringWriter(); + StreamResult result = new StreamResult( writer ); + + SAXTransformerFactory transformerFactory = (SAXTransformerFactory) Factories.newTransformerFactory(); + TransformerHandler transformerHandler = transformerFactory.newTransformerHandler(); + transformerHandler.getTransformer().setOutputProperty( OutputKeys.OMIT_XML_DECLARATION, "yes" ); + transformerHandler.setResult( result ); + Transformer transformer = transformerFactory.newTransformer(); + + XMLReader reader = Factories.newXMLReader(); + // in wrong order result will be CONNENT --> + AbstractSAXFilter filter2 = new M2NLexicalXMLFilter(); + filter2.setParent( reader ); + filter2.setLexicalHandler( transformerHandler ); + + AbstractSAXFilter filter1 = new N2CLexicalXMLFilter( filter2 ); + + SAXSource transformSource = new SAXSource( filter1, new InputSource( new StringReader( "" ) ) ); + + SAXResult transformResult = new SAXResult( transformerHandler ); + transformResult.setLexicalHandler( filter1 ); + transformer.transform( transformSource, transformResult ); + + assertThat( writer.toString() ).and( "" ).areIdentical(); + } + + /** + * A LexicalHandler that'll throw an UnsupportedOperationException on every call. + * + * @author Robert Scholte + */ + static class UnsupportedOperationExceptionLexicalHandler implements LexicalHandler + { + @Override + public void startDTD( String name, String publicId, String systemId ) + throws SAXException + { + throw new UnsupportedOperationException( "LexicalHandlerVerifier" ); + } + + @Override + public void endDTD() + throws SAXException + { + throw new UnsupportedOperationException( "LexicalHandlerVerifier" ); + } + + @Override + public void startEntity( String name ) + throws SAXException + { + throw new UnsupportedOperationException( "LexicalHandlerVerifier" ); + } + + @Override + public void endEntity( String name ) + throws SAXException + { + throw new UnsupportedOperationException( "LexicalHandlerVerifier" ); + } + + @Override + public void startCDATA() + throws SAXException + { + throw new UnsupportedOperationException( "LexicalHandlerVerifier" ); + } + + @Override + public void endCDATA() + throws SAXException + { + throw new UnsupportedOperationException( "LexicalHandlerVerifier" ); + } + + @Override + public void comment( char[] ch, int start, int length ) + throws SAXException + { + throw new UnsupportedOperationException( "LexicalHandlerVerifier" ); + } + } + + /** + * Sorts the comment chars,will throw an UnsupportedOperationException on every other method + * + * @author Robert Scholte + * + */ + static class SortCommentLexicalHandler extends UnsupportedOperationExceptionLexicalHandler + { + private final LexicalHandler lexicalHandler; + + public SortCommentLexicalHandler( LexicalHandler lexicalHandler ) + { + this.lexicalHandler = lexicalHandler; + } + + + @Override + public void comment( char[] ch, int start, int length ) + throws SAXException + { + char[] chars = new String( ch, start, length ).toCharArray(); + Arrays.sort(chars); + lexicalHandler.comment( chars, 0, chars.length ); + } + } + + /** + * AbstractSAXFilter implements both XMLReader and LexicalHandler + * + * @author Robert Scholte + * + */ + static class N2CLexicalXMLFilter extends AbstractSAXFilter + { + public N2CLexicalXMLFilter() + { + super( null ); + } + + public N2CLexicalXMLFilter( T parent ) + { + super( parent ); + } + + @Override + public void comment( char[] ch, int start, int length ) + throws SAXException + { + super.comment( new String( ch, start, length ).replace( 'N', 'C' ).toCharArray(), start, length ); + } + } + + /** + * AbstractSAXFilter implements both XMLReader and LexicalHandler + * + * @author Robert Scholte + * + */ + static class M2NLexicalXMLFilter extends AbstractSAXFilter + { + public M2NLexicalXMLFilter() + { + super( null ); + } + + public M2NLexicalXMLFilter( T parent ) + { + super( parent ); + } + + @Override + public void comment( char[] ch, int start, int length ) + throws SAXException + { + super.comment( new String( ch, start, length ).replace( 'M', 'N' ).toCharArray(), start, length ); + } + } +} diff --git a/maven-core/src/main/java/org/apache/maven/xml/filter/BuildPomXMLFilter.java b/maven-xml/src/test/java/org/apache/maven/xml/sax/SAXEventUtilsTest.java similarity index 63% rename from maven-core/src/main/java/org/apache/maven/xml/filter/BuildPomXMLFilter.java rename to maven-xml/src/test/java/org/apache/maven/xml/sax/SAXEventUtilsTest.java index 60f0c4951d32..02e55dc5991d 100644 --- a/maven-core/src/main/java/org/apache/maven/xml/filter/BuildPomXMLFilter.java +++ b/maven-xml/src/test/java/org/apache/maven/xml/sax/SAXEventUtilsTest.java @@ -1,4 +1,4 @@ -package org.apache.maven.xml.filter; +package org.apache.maven.xml.sax; /* * Licensed to the Apache Software Foundation (ASF) under one @@ -19,26 +19,25 @@ * under the License. */ -import org.xml.sax.XMLReader; -import org.xml.sax.helpers.XMLFilterImpl; +import static org.junit.Assert.assertThat; -/** - * Filter to adjust pom on filesystem before being processed for effective pom. - * - * @author Robert Scholte - * @since 3.7.0 - */ -public class BuildPomXMLFilter extends XMLFilterImpl +import org.apache.maven.xml.sax.SAXEventUtils; + +import static org.hamcrest.CoreMatchers.is; + +import org.junit.Test; + +public class SAXEventUtilsTest { - public BuildPomXMLFilter() + @Test + public void replaceWithNamespace() { - super(); + assertThat( SAXEventUtils.renameQName( "org:bar", "com" ), is( "org:com" ) ); } - public BuildPomXMLFilter( XMLReader parent ) + @Test + public void replaceWithoutNamespace() { - super( parent ); + assertThat( SAXEventUtils.renameQName( "bar", "com" ), is( "com" ) ); } - - } diff --git a/maven-xml/src/test/java/org/apache/maven/xml/filter/AbstractXMLFilterTests.java b/maven-xml/src/test/java/org/apache/maven/xml/sax/filter/AbstractXMLFilterTests.java similarity index 57% rename from maven-xml/src/test/java/org/apache/maven/xml/filter/AbstractXMLFilterTests.java rename to maven-xml/src/test/java/org/apache/maven/xml/sax/filter/AbstractXMLFilterTests.java index 0d9b7791e398..4fa3b0d63919 100644 --- a/maven-xml/src/test/java/org/apache/maven/xml/filter/AbstractXMLFilterTests.java +++ b/maven-xml/src/test/java/org/apache/maven/xml/sax/filter/AbstractXMLFilterTests.java @@ -1,4 +1,4 @@ -package org.apache.maven.xml.filter; +package org.apache.maven.xml.sax.filter; /* * Licensed to the Apache Software Foundation (ASF) under one @@ -28,14 +28,17 @@ import javax.xml.transform.OutputKeys; import javax.xml.transform.Transformer; import javax.xml.transform.TransformerException; -import javax.xml.transform.TransformerFactory; +import javax.xml.transform.sax.SAXResult; import javax.xml.transform.sax.SAXSource; +import javax.xml.transform.sax.SAXTransformerFactory; +import javax.xml.transform.sax.TransformerHandler; import javax.xml.transform.stream.StreamResult; import org.apache.maven.xml.Factories; +import org.apache.maven.xml.sax.filter.AbstractSAXFilter; import org.xml.sax.InputSource; import org.xml.sax.SAXException; -import org.xml.sax.XMLFilter; +import org.xml.sax.XMLReader; public abstract class AbstractXMLFilterTests { @@ -44,16 +47,26 @@ public AbstractXMLFilterTests() super(); } - protected abstract XMLFilter getFilter() throws TransformerException, SAXException, ParserConfigurationException; + protected abstract AbstractSAXFilter getFilter() throws TransformerException, SAXException, ParserConfigurationException; - private void setParent( XMLFilter filter ) throws SAXException, ParserConfigurationException + private void setParent( AbstractSAXFilter filter ) throws SAXException, ParserConfigurationException { if( filter.getParent() == null ) { - filter.setParent( Factories.newXMLReader() ); + XMLReader r = Factories.newXMLReader(); + + filter.setParent( r ); filter.setFeature( "http://xml.org/sax/features/namespaces", true ); } } + + protected String omitXmlDeclaration() { + return "yes"; + } + + protected String indentAmount() { + return null; + } protected String transform( String input ) throws TransformerException, SAXException, ParserConfigurationException @@ -63,32 +76,43 @@ protected String transform( String input ) protected String transform( Reader input ) throws TransformerException, SAXException, ParserConfigurationException { - XMLFilter filter = getFilter(); + AbstractSAXFilter filter = getFilter(); setParent( filter ); + return transform( input, filter ); } - protected String transform( String input, XMLFilter filter ) + protected String transform( String input, AbstractSAXFilter filter ) throws TransformerException, SAXException, ParserConfigurationException { setParent( filter ); return transform( new StringReader( input ), filter ); } - protected String transform( Reader input, XMLFilter filter ) + protected String transform( Reader input, AbstractSAXFilter filter ) throws TransformerException, SAXException, ParserConfigurationException { - Writer writer = new StringWriter(); StreamResult result = new StreamResult( writer ); - TransformerFactory transformerFactory = Factories.newTransformerFactory(); + SAXTransformerFactory transformerFactory = (SAXTransformerFactory) Factories.newTransformerFactory(); + TransformerHandler transformerHandler = transformerFactory.newTransformerHandler(); + filter.setLexicalHandler( transformerHandler ); + transformerHandler.getTransformer().setOutputProperty( OutputKeys.OMIT_XML_DECLARATION, omitXmlDeclaration() ); + if ( indentAmount() != null ) + { + transformerHandler.getTransformer().setOutputProperty( OutputKeys.INDENT, "yes" ); + transformerHandler.getTransformer().setOutputProperty( "{http://xml.apache.org/xslt}indent-amount", + indentAmount() ); + } + transformerHandler.setResult( result ); Transformer transformer = transformerFactory.newTransformer(); - transformer.setOutputProperty( OutputKeys.OMIT_XML_DECLARATION, "yes" ); SAXSource transformSource = new SAXSource( filter, new InputSource( input ) ); - transformer.transform( transformSource, result ); + SAXResult transformResult = new SAXResult( transformerHandler ); + transformResult.setLexicalHandler( filter ); + transformer.transform( transformSource, transformResult ); return writer.toString(); } 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 new file mode 100644 index 000000000000..50abfc8ff0dd --- /dev/null +++ b/maven-xml/src/test/java/org/apache/maven/xml/sax/filter/ConsumerPomXMLFilterTest.java @@ -0,0 +1,252 @@ +package org.apache.maven.xml.sax.filter; + +/* + * 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 static org.xmlunit.assertj.XmlAssert.assertThat; + +import java.nio.file.Path; +import java.nio.file.Paths; +import java.util.Optional; +import java.util.function.Function; + +import javax.inject.Provider; +import javax.xml.parsers.ParserConfigurationException; +import javax.xml.transform.TransformerConfigurationException; + +import org.apache.maven.xml.sax.filter.AbstractSAXFilter; +import org.apache.maven.xml.sax.filter.BuildPomXMLFilterFactory; +import org.apache.maven.xml.sax.filter.ConsumerPomXMLFilter; +import org.apache.maven.xml.sax.filter.ConsumerPomXMLFilterFactory; +import org.apache.maven.xml.sax.filter.DependencyKey; +import org.apache.maven.xml.sax.filter.RelativeProject; +import org.junit.Test; +import org.xml.sax.SAXException; + +public class ConsumerPomXMLFilterTest extends AbstractXMLFilterTests +{ + @Override + protected String omitXmlDeclaration() + { + return "no"; + } + + @Override + protected AbstractSAXFilter getFilter() throws SAXException, ParserConfigurationException, TransformerConfigurationException + { + final BuildPomXMLFilterFactory buildPomXMLFilterFactory = new BuildPomXMLFilterFactory() + { + @Override + protected Optional getSha1() + { + return Optional.empty(); + } + + @Override + protected Optional getRevision() + { + return Optional.empty(); + } + + @Override + protected Optional getChangelist() + { + return Optional.of( "CL" ); + } + + @Override + protected Function> getRelativePathMapper() + { + return null; + } + + @Override + protected Function getDependencyKeyToVersionMapper() + { + return null; + } + }; + + Provider provider = new Provider() + { + + @Override + public BuildPomXMLFilterFactory get() + { + return buildPomXMLFilterFactory; + } + }; + + ConsumerPomXMLFilter filter = new ConsumerPomXMLFilterFactory( provider ) + { + }.get( Paths.get( "pom.xml" ) ); + filter.setFeature( "http://xml.org/sax/features/namespaces", true ); + return filter; + } + + @Test + public void aggregatorWithParent() throws Exception { + String input = "\n" + + " \n" + + " GROUPID\n" + + " PARENT\n" + + " VERSION\n" + + " ../pom.xml\n" + + " \n" + + " PROJECT\n" + + " \n" + + " ab\n" + + " ../cd\n" + + " \n" + + ""; + String expected = "\n" + + " \n" + + " GROUPID\n" + + " PARENT\n" + + " VERSION\n" + + " \n" + + " PROJECT\n" + + ""; + String actual = transform( input ); + assertThat( actual ).and( expected ).ignoreWhitespace().areIdentical(); + } + + @Test + public void aggregatorWithCliFriendlyVersion() throws Exception { + String input = "\n" + + "\n" + + " 4.0.0\n" + + " org.sonatype.mavenbook.multispring\n" + + " parent\n" + + " 0.9-${changelist}-SNAPSHOT\n" + + " pom\n" + + " Multi-Spring Chapter Parent Project\n" + + " \n" + + " simple-parent\n" + + " \n" + + " \n" + + " \n" + + " \n" + + " apache.snapshots\n" + + " http://repository.apache.org/snapshots/\n" + + " \n" + + " \n" + + ""; + String expected = "\n" + + "\n" + + " 4.0.0\n" + + " org.sonatype.mavenbook.multispring\n" + + " parent\n" + + " 0.9-CL-SNAPSHOT\n" + + " pom\n" + + " Multi-Spring Chapter Parent Project\n" + + " \n" + + " \n" + + " \n" + + " apache.snapshots\n" + + " http://repository.apache.org/snapshots/\n" + + " \n" + + " \n" + + ""; + String actual = transform( input ); + assertThat( actual ).and( expected ).ignoreWhitespace().areIdentical(); + } + + @Test + public void licenseHeader() throws Exception { + String input = "\n" + + "\n" + + "\n" + + "\n" + + "\n" + + " 4.0.0\n" + + " \n" + + " org.apache.maven\n" + + " maven\n" + + " 3.7.0-SNAPSHOT\n" + + " \n" + + " maven-xml\n" + + " Maven XML\n" + + " \n" + + " \n" + + " 1.8\n" + + " 1.8\n" + + " \n" + + "\n" + + " \n" + + " \n" + + " \n" + + " org.codehaus.mojo\n" + + " animal-sniffer-maven-plugin\n" + + " \n" + + " \n" + + " org.codehaus.mojo.signature\n" + + " java18\n" + + " 1.0\n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " javax.inject\n" + + " javax.inject\n" + + " true\n" + + " \n" + + " \n" + + " org.xmlunit\n" + + " xmlunit-assertj\n" + + " test\n" + + " \n" + + " \n" + + ""; + String expected = input; + + String actual = transform( input ); + assertThat( actual ).and( expected ).areIdentical(); + } + +} diff --git a/maven-xml/src/test/java/org/apache/maven/xml/filter/ModulesXMLFilterTest.java b/maven-xml/src/test/java/org/apache/maven/xml/sax/filter/ModulesXMLFilterTest.java similarity index 67% rename from maven-xml/src/test/java/org/apache/maven/xml/filter/ModulesXMLFilterTest.java rename to maven-xml/src/test/java/org/apache/maven/xml/sax/filter/ModulesXMLFilterTest.java index 63880ed27008..a3477dfffc71 100644 --- a/maven-xml/src/test/java/org/apache/maven/xml/filter/ModulesXMLFilterTest.java +++ b/maven-xml/src/test/java/org/apache/maven/xml/sax/filter/ModulesXMLFilterTest.java @@ -1,4 +1,4 @@ -package org.apache.maven.xml.filter; +package org.apache.maven.xml.sax.filter; /* * Licensed to the Apache Software Foundation (ASF) under one @@ -21,32 +21,19 @@ import static org.xmlunit.assertj.XmlAssert.assertThat; -import javax.xml.parsers.SAXParserFactory; - -import org.junit.Before; +import org.apache.maven.xml.sax.filter.ModulesXMLFilter; import org.junit.Test; -import org.xml.sax.XMLFilter; -import org.xml.sax.XMLReader; public class ModulesXMLFilterTest extends AbstractXMLFilterTests { - private ModulesXMLFilter filter; - @Override - protected XMLFilter getFilter() + protected ModulesXMLFilter getFilter() { return new ModulesXMLFilter(); } - @Before - public void setup() throws Exception { - XMLReader xmlReader = SAXParserFactory.newInstance().newSAXParser().getXMLReader(); - filter = new ModulesXMLFilter( xmlReader ); - filter.setFeature( "http://xml.org/sax/features/namespaces", true ); - } - @Test - public void testEmptyModules() throws Exception { + public void emptyModules() throws Exception { String input = ""; String expected = ""; String actual = transform( input ); @@ -54,7 +41,7 @@ public void testEmptyModules() throws Exception { } @Test - public void testSetOfModules() throws Exception { + public void setOfModules() throws Exception { String input = "" + "ab" + "../cd" @@ -65,10 +52,25 @@ public void testSetOfModules() throws Exception { } @Test - public void testNoModules() throws Exception { + public void noModules() throws Exception { String input = "NAME"; String expected = input; String actual = transform( input ); assertThat( actual ).and( expected ).areIdentical(); } + + @Test + public void comment() throws Exception { + + String input = "" + + "" + + "ab" + + "../cd" + + "" + + "" + + ""; + String expected = ""; + String actual = transform( input ); + assertThat( actual ).and( expected ).areIdentical(); + } } diff --git a/maven-xml/src/test/java/org/apache/maven/xml/filter/ParentXMLFilterTest.java b/maven-xml/src/test/java/org/apache/maven/xml/sax/filter/ParentXMLFilterTest.java similarity index 86% rename from maven-xml/src/test/java/org/apache/maven/xml/filter/ParentXMLFilterTest.java rename to maven-xml/src/test/java/org/apache/maven/xml/sax/filter/ParentXMLFilterTest.java index aa70b0db9a97..8f25c102b371 100644 --- a/maven-xml/src/test/java/org/apache/maven/xml/filter/ParentXMLFilterTest.java +++ b/maven-xml/src/test/java/org/apache/maven/xml/sax/filter/ParentXMLFilterTest.java @@ -1,4 +1,4 @@ -package org.apache.maven.xml.filter; +package org.apache.maven.xml.sax.filter; /* * Licensed to the Apache Software Foundation (ASF) under one @@ -27,14 +27,15 @@ import javax.xml.parsers.ParserConfigurationException; import javax.xml.transform.TransformerException; +import org.apache.maven.xml.sax.filter.ParentXMLFilter; +import org.apache.maven.xml.sax.filter.RelativeProject; import org.junit.Test; import org.xml.sax.SAXException; -import org.xml.sax.XMLFilter; public class ParentXMLFilterTest extends AbstractXMLFilterTests { @Override - protected XMLFilter getFilter() + protected ParentXMLFilter getFilter() throws TransformerException, SAXException, ParserConfigurationException { ParentXMLFilter filter = new ParentXMLFilter( x -> Optional.of( new RelativeProject( "GROUPID", @@ -162,24 +163,27 @@ public void testWithWeirdNamespace() throws Exception assertEquals( expected, actual ); } - @Test - public void testIndent() throws Exception + public void comment() throws Exception { - String input = "\n" - + " GROUPID\n" - + " ARTIFACTID\n" - + " "; - // transformer is responsible for line separator and indents - String expected = "" + System.lineSeparator() - + " GROUPID" + System.lineSeparator() - + " ARTIFACTID" + System.lineSeparator() - + " 1.0.0" + System.lineSeparator() - + ""; + String input = "" + + "GROUPID" + + "ARTIFACTID" + + "" + + "" + + ""; + String expected = "" + + "GROUPID" + + "ARTIFACTID" + + "" + + "1.0.0" + + "" + + ""; String actual = transform( input ); assertEquals( expected, actual ); } + } diff --git a/maven-xml/src/test/java/org/apache/maven/xml/filter/ReactorDependencyXMLFilterTest.java b/maven-xml/src/test/java/org/apache/maven/xml/sax/filter/ReactorDependencyXMLFilterTest.java similarity index 66% rename from maven-xml/src/test/java/org/apache/maven/xml/filter/ReactorDependencyXMLFilterTest.java rename to maven-xml/src/test/java/org/apache/maven/xml/sax/filter/ReactorDependencyXMLFilterTest.java index 6a5998ed7ac6..9cf713c40ff7 100644 --- a/maven-xml/src/test/java/org/apache/maven/xml/filter/ReactorDependencyXMLFilterTest.java +++ b/maven-xml/src/test/java/org/apache/maven/xml/sax/filter/ReactorDependencyXMLFilterTest.java @@ -1,4 +1,4 @@ -package org.apache.maven.xml.filter; +package org.apache.maven.xml.sax.filter; /* * Licensed to the Apache Software Foundation (ASF) under one @@ -19,19 +19,19 @@ * under the License. */ -import static org.junit.Assert.*; +import static org.xmlunit.assertj.XmlAssert.*; import javax.xml.parsers.ParserConfigurationException; import javax.xml.transform.TransformerException; +import org.apache.maven.xml.sax.filter.ReactorDependencyXMLFilter; import org.junit.Test; import org.xml.sax.SAXException; -import org.xml.sax.XMLFilter; public class ReactorDependencyXMLFilterTest extends AbstractXMLFilterTests { @Override - protected XMLFilter getFilter() + protected ReactorDependencyXMLFilter getFilter() throws TransformerException, SAXException, ParserConfigurationException { return new ReactorDependencyXMLFilter( r -> "1.0.0" ); @@ -49,13 +49,13 @@ public void testDefaultDependency() throws Exception String actual = transform( input ); - assertEquals( expected, actual ); + assertThat( actual ).isEqualTo( expected ); } @Test public void testManagedDependency() throws Exception { - XMLFilter filter = new ReactorDependencyXMLFilter( r -> null ); + ReactorDependencyXMLFilter filter = new ReactorDependencyXMLFilter( r -> null ); String input = "" + "GROUPID" @@ -65,7 +65,7 @@ public void testManagedDependency() throws Exception String actual = transform( input, filter ); - assertEquals( expected, actual ); + assertThat( actual ).isEqualTo( expected ); } @Test @@ -83,7 +83,27 @@ public void testReactorDependency() throws Exception String actual = transform( input ); - assertEquals( expected, actual ); + assertThat( actual ).isEqualTo( expected ); + } + + @Test + public void testReactorDependencyLF() throws Exception + { + String input = "\n" + + " GROUPID\n" + + " ARTIFACTID\n" + + " " + + ""; + String expected = "\n" + + " GROUPID\n" + + " ARTIFACTID\n" + + " \n" + + " 1.0.0\n" + + ""; + + String actual = transform( input ); + + assertThat( actual ).and( expected ).ignoreWhitespace().areIdentical(); } } diff --git a/maven-xml/src/test/java/org/apache/maven/xml/filter/RelativePathXMLFilterTest.java b/maven-xml/src/test/java/org/apache/maven/xml/sax/filter/RelativePathXMLFilterTest.java similarity index 95% rename from maven-xml/src/test/java/org/apache/maven/xml/filter/RelativePathXMLFilterTest.java rename to maven-xml/src/test/java/org/apache/maven/xml/sax/filter/RelativePathXMLFilterTest.java index 1fed1cadf500..00655b38f721 100644 --- a/maven-xml/src/test/java/org/apache/maven/xml/filter/RelativePathXMLFilterTest.java +++ b/maven-xml/src/test/java/org/apache/maven/xml/sax/filter/RelativePathXMLFilterTest.java @@ -1,4 +1,4 @@ -package org.apache.maven.xml.filter; +package org.apache.maven.xml.sax.filter; /* * Licensed to the Apache Software Foundation (ASF) under one @@ -21,13 +21,13 @@ import static org.xmlunit.assertj.XmlAssert.assertThat; +import org.apache.maven.xml.sax.filter.RelativePathXMLFilter; import org.junit.Test; -import org.xml.sax.XMLFilter; public class RelativePathXMLFilterTest extends AbstractXMLFilterTests { @Override - protected XMLFilter getFilter() + protected RelativePathXMLFilter getFilter() { return new RelativePathXMLFilter(); } @@ -49,7 +49,6 @@ public void testRelativePath() throws Exception + " GROUPID\n" + " PARENT\n" + " VERSION\n" - + " \n" + " \n" + " PROJECT\n" + ""; @@ -78,7 +77,6 @@ public void testRelativePathNS() throws Exception + " GROUPID\n" + " PARENT\n" + " VERSION\n" - + " \n" + " \n" + " PROJECT\n" + ""; @@ -107,7 +105,6 @@ public void testRelativePathPasNS() throws Exception + " GROUPID\n" + " PARENT\n" + " VERSION\n" - + " \n" + " \n" + " PROJECT\n" + ""; From 24955e7ce383c7ad0c64b2de95c7f5a395c43d10 Mon Sep 17 00:00:00 2001 From: rfscholte Date: Sun, 13 Oct 2019 13:49:47 +0200 Subject: [PATCH 18/52] [MNG-6656] Introduce Features class --- ...DefaultRepositorySystemSessionFactory.java | 3 +- .../org/apache/maven/feature/Features.java | 63 +++++++++++++++++++ .../model/building/DefaultModelBuilder.java | 3 +- .../validation/DefaultModelValidator.java | 3 +- 4 files changed, 69 insertions(+), 3 deletions(-) create mode 100644 maven-model-builder/src/main/java/org/apache/maven/feature/Features.java diff --git a/maven-core/src/main/java/org/apache/maven/internal/aether/DefaultRepositorySystemSessionFactory.java b/maven-core/src/main/java/org/apache/maven/internal/aether/DefaultRepositorySystemSessionFactory.java index 3eaad6f63824..94b2e353de3d 100644 --- a/maven-core/src/main/java/org/apache/maven/internal/aether/DefaultRepositorySystemSessionFactory.java +++ b/maven-core/src/main/java/org/apache/maven/internal/aether/DefaultRepositorySystemSessionFactory.java @@ -50,6 +50,7 @@ import org.apache.maven.bridge.MavenRepositorySystem; import org.apache.maven.eventspy.internal.EventSpyDispatcher; import org.apache.maven.execution.MavenExecutionRequest; +import org.apache.maven.feature.Features; import org.apache.maven.repository.internal.MavenRepositorySystemUtils; import org.apache.maven.settings.Mirror; import org.apache.maven.settings.Proxy; @@ -268,7 +269,7 @@ else if ( request.isUpdateSnapshots() ) mavenRepositorySystem.injectProxy( session, request.getPluginArtifactRepositories() ); mavenRepositorySystem.injectAuthentication( session, request.getPluginArtifactRepositories() ); - if ( Boolean.getBoolean( "maven.experimental.buildconsumer" ) ) + if ( Features.buildConsumer().isActive() ) { session.setFileTransformerManager( newFileTransformerManager() ); } diff --git a/maven-model-builder/src/main/java/org/apache/maven/feature/Features.java b/maven-model-builder/src/main/java/org/apache/maven/feature/Features.java new file mode 100644 index 000000000000..d4461d8e64b5 --- /dev/null +++ b/maven-model-builder/src/main/java/org/apache/maven/feature/Features.java @@ -0,0 +1,63 @@ +package org.apache.maven.feature; + +/* + * 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. + */ + +/** + * Centralized class for feature information + * + * @author Robert Scholte + * @since 3.7.0 + */ +public final class Features +{ + private Features() + { + } + + private static final Feature BUILDCONSUMER = new Feature( "maven.experimental.buildconsumer", "false" ); + + public static Feature buildConsumer() + { + return BUILDCONSUMER; + } + + /** + * Represents some feature + * + * @author Robert Scholte + * @since 3.7.0 + */ + public static class Feature + { + private final boolean active; + + Feature( String name, String defaultValue ) + { + active = "true".equals( System.getProperty( name, defaultValue ) ); + } + + public boolean isActive() + { + return active; + } + + } + +} 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 bc13d33e3a5d..6d2bb7e39af5 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 @@ -55,6 +55,7 @@ import org.apache.maven.artifact.versioning.InvalidVersionSpecificationException; import org.apache.maven.artifact.versioning.VersionRange; import org.apache.maven.building.FileSource; +import org.apache.maven.feature.Features; import org.apache.maven.model.Activation; import org.apache.maven.model.Build; import org.apache.maven.model.Dependency; @@ -770,7 +771,7 @@ private void assembleInheritance( List lineage, ModelBuildingRequest } // re-read model from file - if ( Boolean.getBoolean( "maven.experimental.buildconsumer" ) && request.isTransformPom() ) + if ( Features.buildConsumer().isActive() && request.isTransformPom() ) { try { diff --git a/maven-model-builder/src/main/java/org/apache/maven/model/validation/DefaultModelValidator.java b/maven-model-builder/src/main/java/org/apache/maven/model/validation/DefaultModelValidator.java index 15a55878bdc8..86670eb47f11 100644 --- a/maven-model-builder/src/main/java/org/apache/maven/model/validation/DefaultModelValidator.java +++ b/maven-model-builder/src/main/java/org/apache/maven/model/validation/DefaultModelValidator.java @@ -19,6 +19,7 @@ * under the License. */ +import org.apache.maven.feature.Features; import org.apache.maven.model.Activation; import org.apache.maven.model.ActivationFile; import org.apache.maven.model.Build; @@ -99,7 +100,7 @@ public void validateRawModel( Model m, ModelBuildingRequest request, ModelProble parent ); // resolvedModel will assign version based on relativePath - if ( !Boolean.getBoolean( "maven.experimental.buildconsumer" ) ) + if ( !Features.buildConsumer().isActive() ) { validateStringNotEmpty( "parent.version", problems, Severity.FATAL, Version.BASE, parent.getVersion(), parent ); From 87601ecee7e0b631f98d12f1e43751008a46a67e Mon Sep 17 00:00:00 2001 From: rfscholte Date: Mon, 14 Oct 2019 20:40:01 +0200 Subject: [PATCH 19/52] [MNG-6656] Fix bug in AbstractEventXMLFilter (removed processed events) --- .../sax/filter/AbstractEventXMLFilter.java | 10 +++-- .../ReactorDependencyXMLFilterTest.java | 38 +++++++++++++++++++ 2 files changed, 45 insertions(+), 3 deletions(-) diff --git a/maven-xml/src/main/java/org/apache/maven/xml/sax/filter/AbstractEventXMLFilter.java b/maven-xml/src/main/java/org/apache/maven/xml/sax/filter/AbstractEventXMLFilter.java index d52cb7c64d37..633c53325641 100644 --- a/maven-xml/src/main/java/org/apache/maven/xml/sax/filter/AbstractEventXMLFilter.java +++ b/maven-xml/src/main/java/org/apache/maven/xml/sax/filter/AbstractEventXMLFilter.java @@ -1,5 +1,7 @@ package org.apache.maven.xml.sax.filter; +import java.util.ArrayDeque; + /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file @@ -21,8 +23,10 @@ import java.util.ArrayList; import java.util.HashMap; +import java.util.Iterator; import java.util.List; import java.util.Map; +import java.util.Queue; import org.apache.maven.xml.sax.SAXEvent; import org.apache.maven.xml.sax.SAXEventFactory; @@ -40,7 +44,7 @@ */ abstract class AbstractEventXMLFilter extends AbstractSAXFilter { - private List saxEvents = new ArrayList<>(); + private Queue saxEvents = new ArrayDeque<>(); private SAXEventFactory eventFactory; @@ -138,9 +142,9 @@ protected final void executeEvents() throws SAXException } // not with streams due to checked SAXException - for ( SAXEvent saxEvent : saxEvents ) + while( !saxEvents.isEmpty() ) { - saxEvent.execute(); + saxEvents.poll().execute(); } } diff --git a/maven-xml/src/test/java/org/apache/maven/xml/sax/filter/ReactorDependencyXMLFilterTest.java b/maven-xml/src/test/java/org/apache/maven/xml/sax/filter/ReactorDependencyXMLFilterTest.java index 9cf713c40ff7..43679820700b 100644 --- a/maven-xml/src/test/java/org/apache/maven/xml/sax/filter/ReactorDependencyXMLFilterTest.java +++ b/maven-xml/src/test/java/org/apache/maven/xml/sax/filter/ReactorDependencyXMLFilterTest.java @@ -106,4 +106,42 @@ public void testReactorDependencyLF() throws Exception assertThat( actual ).and( expected ).ignoreWhitespace().areIdentical(); } + @Test + public void multipleDependencies() throws Exception { + String input = "\n" + + " 4.0.0\n" + + " tests.project\n" + + " duplicate-plugin-defs-merged\n" + + " 1\n" + + " \n" + + " \n" + + " \n" + + " maven-compiler-plugin\n" + + " \n" + + " \n" + + " group\n" + + " first\n" + + " 1\n" + + " \n" + + " \n" + + " \n" + + " \n" + + " maven-compiler-plugin\n" + + " \n" + + " \n" + + " group\n" + + " second\n" + + " 1\n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + ""; + String expected = input; + + String actual = transform( input ); + + assertThat( actual ).and( expected ).areIdentical(); + } } From 91f87994a4fb93aa7f90e82c69eb73b05a9302b6 Mon Sep 17 00:00:00 2001 From: rfscholte Date: Tue, 15 Oct 2019 00:12:17 +0200 Subject: [PATCH 20/52] [MNG-6656] Enable maven.experimental.buildconsumer by default --- .../project/AbstractMavenProjectTestCase.java | 35 +++++- .../maven/project/ProjectClasspathTest.java | 1 + .../maven/project/DefaultProjectBuilder.java | 2 +- .../AbstractCoreMavenComponentTestCase.java | 24 ++-- .../project/AbstractMavenProjectTestCase.java | 33 ++++- .../DefaultMavenProjectBuilderTest.java | 16 ++- .../maven/project/PomConstructionTest.java | 14 ++- .../maven/project/ProjectBuilderTest.java | 8 ++ .../repository/TestRepositorySystem.java | 4 +- .../PomConstructionWithSettingsTest.java | 27 +++- .../org/apache/maven/feature/Features.java | 2 +- .../model/building/DefaultModelBuilder.java | 119 ++++++++++-------- .../validation/DefaultModelValidatorTest.java | 12 +- .../sax/filter/AbstractEventXMLFilter.java | 8 +- .../maven/xml/sax/filter/ParentXMLFilter.java | 8 +- .../xml/sax/filter/ParentXMLFilterTest.java | 3 + 16 files changed, 215 insertions(+), 101 deletions(-) diff --git a/maven-compat/src/test/java/org/apache/maven/project/AbstractMavenProjectTestCase.java b/maven-compat/src/test/java/org/apache/maven/project/AbstractMavenProjectTestCase.java index 7e3f7e6b58ac..7aa65856b04c 100644 --- a/maven-compat/src/test/java/org/apache/maven/project/AbstractMavenProjectTestCase.java +++ b/maven-compat/src/test/java/org/apache/maven/project/AbstractMavenProjectTestCase.java @@ -23,11 +23,13 @@ import java.util.Arrays; import org.apache.maven.artifact.repository.ArtifactRepository; -import org.apache.maven.artifact.repository.layout.ArtifactRepositoryLayout; +import org.apache.maven.execution.DefaultMavenExecutionRequest; +import org.apache.maven.execution.MavenSession; import org.apache.maven.model.building.ModelBuildingException; import org.apache.maven.model.building.ModelProblem; import org.apache.maven.repository.RepositorySystem; import org.apache.maven.repository.internal.MavenRepositorySystemUtils; +import org.apache.maven.session.scope.internal.SessionScope; import org.codehaus.plexus.ContainerConfiguration; import org.codehaus.plexus.PlexusConstants; import org.codehaus.plexus.PlexusTestCase; @@ -42,6 +44,8 @@ public abstract class AbstractMavenProjectTestCase protected ProjectBuilder projectBuilder; protected RepositorySystem repositorySystem; + + private SessionScope sessionScope; @Override protected void customizeContainerConfiguration( ContainerConfiguration containerConfiguration ) @@ -67,12 +71,27 @@ protected void setUp() } repositorySystem = lookup( RepositorySystem.class ); + + } + + private void seedMavenSession( MavenSession mavenSession ) throws Exception + { + if ( sessionScope == null ) + { + sessionScope = lookup( SessionScope.class ); + sessionScope.enter(); + sessionScope.seed( MavenSession.class, mavenSession ); + } } @Override protected void tearDown() throws Exception { + if ( sessionScope != null ) + { + sessionScope.exit(); + } projectBuilder = null; super.tearDown(); @@ -121,11 +140,7 @@ protected static File getFileForClasspathResource( String resource ) protected ArtifactRepository getLocalRepository() throws Exception { - ArtifactRepositoryLayout repoLayout = lookup( ArtifactRepositoryLayout.class, "legacy" ); - - ArtifactRepository r = repositorySystem.createArtifactRepository( "local", "file://" + getLocalRepositoryPath().getAbsolutePath(), repoLayout, null, null ); - - return r; + return repositorySystem.createLocalRepository( getLocalRepositoryPath() ); } // ---------------------------------------------------------------------- @@ -142,6 +157,10 @@ protected MavenProject getProjectWithDependencies( File pom ) configuration.setResolveDependencies( true ); initRepoSession( configuration ); + seedMavenSession( new MavenSession( getContainer(), + configuration.getRepositorySession(), + new DefaultMavenExecutionRequest(), null ) ); + try { return projectBuilder.build( pom, configuration ).getProject(); @@ -170,6 +189,10 @@ protected MavenProject getProject( File pom ) ProjectBuildingRequest configuration = new DefaultProjectBuildingRequest(); configuration.setLocalRepository( getLocalRepository() ); initRepoSession( configuration ); + + seedMavenSession( new MavenSession( getContainer(), + configuration.getRepositorySession(), + new DefaultMavenExecutionRequest(), null ) ); return projectBuilder.build( pom, configuration ).getProject(); } diff --git a/maven-compat/src/test/java/org/apache/maven/project/ProjectClasspathTest.java b/maven-compat/src/test/java/org/apache/maven/project/ProjectClasspathTest.java index d7ae86e69706..59c6e0dd59f4 100644 --- a/maven-compat/src/test/java/org/apache/maven/project/ProjectClasspathTest.java +++ b/maven-compat/src/test/java/org/apache/maven/project/ProjectClasspathTest.java @@ -35,6 +35,7 @@ public class ProjectClasspathTest public void setUp() throws Exception { + super.setUp(); ArtifactResolver resolver = lookup( ArtifactResolver.class, "classpath" ); DefaultArtifactDescriptorReader pomReader = (DefaultArtifactDescriptorReader)lookup(ArtifactDescriptorReader.class); pomReader.setArtifactResolver( resolver ); 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 c3a0a8f9f549..ce6c9dced9e9 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 @@ -164,7 +164,7 @@ private ProjectBuildingResult build( File pomFile, ModelSource modelSource, Inte request.setModelBuildingListener( listener ); request.setPomFile( pomFile ); - request.setTransformPom( true ); + request.setTransformPom( pomFile != null ); request.setModelSource( modelSource ); request.setLocationTracking( true ); diff --git a/maven-core/src/test/java/org/apache/maven/AbstractCoreMavenComponentTestCase.java b/maven-core/src/test/java/org/apache/maven/AbstractCoreMavenComponentTestCase.java index 179b8f974180..0931d1b68ef1 100644 --- a/maven-core/src/test/java/org/apache/maven/AbstractCoreMavenComponentTestCase.java +++ b/maven-core/src/test/java/org/apache/maven/AbstractCoreMavenComponentTestCase.java @@ -44,10 +44,10 @@ import org.apache.maven.project.ProjectBuildingRequest; import org.apache.maven.repository.RepositorySystem; import org.apache.maven.repository.internal.MavenRepositorySystemUtils; +import org.apache.maven.session.scope.internal.SessionScope; import org.codehaus.plexus.ContainerConfiguration; import org.codehaus.plexus.PlexusConstants; import org.codehaus.plexus.PlexusTestCase; -import org.codehaus.plexus.component.annotations.Requirement; import org.codehaus.plexus.util.FileUtils; import org.eclipse.aether.DefaultRepositorySystemSession; import org.eclipse.aether.internal.impl.SimpleLocalRepositoryManagerFactory; @@ -56,12 +56,12 @@ public abstract class AbstractCoreMavenComponentTestCase extends PlexusTestCase { - @Requirement protected RepositorySystem repositorySystem; - @Requirement protected org.apache.maven.project.ProjectBuilder projectBuilder; + protected SessionScope sessionScope; + protected void setUp() throws Exception { @@ -144,9 +144,17 @@ protected MavenSession createMavenSession( File pom, Properties executionPropert .setRemoteRepositories( request.getRemoteRepositories() ) .setPluginArtifactRepositories( request.getPluginArtifactRepositories() ) .setSystemProperties( executionProperties ); + initRepoSession( configuration ); - List projects = new ArrayList<>(); + MavenSession session = + new MavenSession( getContainer(), configuration.getRepositorySession(), request, + new DefaultMavenExecutionResult() ); + sessionScope = lookup( SessionScope.class ); + sessionScope.enter(); + sessionScope.seed( MavenSession.class, session ); + + List projects = new ArrayList<>(); if ( pom != null ) { MavenProject project = projectBuilder.build( pom, configuration ).getProject(); @@ -172,15 +180,9 @@ protected MavenSession createMavenSession( File pom, Properties executionPropert project.setPluginArtifactRepositories( request.getPluginArtifactRepositories() ); projects.add( project ); } - - initRepoSession( configuration ); - - MavenSession session = - new MavenSession( getContainer(), configuration.getRepositorySession(), request, - new DefaultMavenExecutionResult() ); session.setProjects( projects ); session.setAllProjects( session.getProjects() ); - + return session; } diff --git a/maven-core/src/test/java/org/apache/maven/project/AbstractMavenProjectTestCase.java b/maven-core/src/test/java/org/apache/maven/project/AbstractMavenProjectTestCase.java index 9f836c28e646..82189e9fbd5f 100644 --- a/maven-core/src/test/java/org/apache/maven/project/AbstractMavenProjectTestCase.java +++ b/maven-core/src/test/java/org/apache/maven/project/AbstractMavenProjectTestCase.java @@ -23,11 +23,13 @@ import java.util.Arrays; import org.apache.maven.artifact.repository.ArtifactRepository; -import org.apache.maven.artifact.repository.layout.ArtifactRepositoryLayout; +import org.apache.maven.execution.DefaultMavenExecutionRequest; +import org.apache.maven.execution.MavenSession; import org.apache.maven.model.building.ModelBuildingException; import org.apache.maven.model.building.ModelProblem; import org.apache.maven.repository.RepositorySystem; import org.apache.maven.repository.internal.MavenRepositorySystemUtils; +import org.apache.maven.session.scope.internal.SessionScope; import org.codehaus.plexus.ContainerConfiguration; import org.codehaus.plexus.PlexusConstants; import org.codehaus.plexus.PlexusTestCase; @@ -42,6 +44,8 @@ public abstract class AbstractMavenProjectTestCase protected ProjectBuilder projectBuilder; protected RepositorySystem repositorySystem; + + private SessionScope sessionScope; @Override protected void customizeContainerConfiguration( ContainerConfiguration containerConfiguration ) @@ -67,12 +71,17 @@ protected void setUp() } repositorySystem = lookup( RepositorySystem.class ); + + sessionScope = lookup( SessionScope.class ); + sessionScope.enter(); } @Override protected void tearDown() throws Exception { + sessionScope.exit(); + projectBuilder = null; super.tearDown(); @@ -82,6 +91,11 @@ protected ProjectBuilder getProjectBuilder() { return projectBuilder; } + + protected final SessionScope getSessionScope() + { + return sessionScope; + } @Override protected String getCustomConfigurationName() @@ -119,11 +133,7 @@ protected static File getFileForClasspathResource( String resource ) protected ArtifactRepository getLocalRepository() throws Exception { - ArtifactRepositoryLayout repoLayout = lookup( ArtifactRepositoryLayout.class, "legacy" ); - - ArtifactRepository r = repositorySystem.createArtifactRepository( "local", "file://" + getLocalRepositoryPath().getAbsolutePath(), repoLayout, null, null ); - - return r; + return repositorySystem.createLocalRepository( getLocalRepositoryPath() ); } // ---------------------------------------------------------------------- @@ -138,6 +148,9 @@ protected MavenProject getProjectWithDependencies( File pom ) configuration.setProcessPlugins( false ); configuration.setResolveDependencies( true ); + sessionScope.seed( MavenSession.class, new MavenSession( getContainer(), + configuration.getRepositorySession(), + new DefaultMavenExecutionRequest(), null ) ); try { return projectBuilder.build( pom, configuration ).getProject(); @@ -164,6 +177,10 @@ protected MavenProject getProject( File pom ) { ProjectBuildingRequest configuration = newBuildingRequest(); + sessionScope.seed( MavenSession.class, new MavenSession( getContainer(), + configuration.getRepositorySession(), + new DefaultMavenExecutionRequest(), null ) ); + return projectBuilder.build( pom, configuration ).getProject(); } @@ -174,6 +191,10 @@ protected MavenProject getProjectFromRemoteRepository( final File pom ) configuration.setLocalRepository( this.getLocalRepository() ); configuration.setRemoteRepositories( Arrays.asList( this.repositorySystem.createDefaultRemoteRepository() ) ); initRepoSession( configuration ); + + sessionScope.seed( MavenSession.class, new MavenSession( getContainer(), + configuration.getRepositorySession(), + new DefaultMavenExecutionRequest(), null ) ); return projectBuilder.build( pom, configuration ).getProject(); } diff --git a/maven-core/src/test/java/org/apache/maven/project/DefaultMavenProjectBuilderTest.java b/maven-core/src/test/java/org/apache/maven/project/DefaultMavenProjectBuilderTest.java index 008c6d3bdc31..fa3501a8df45 100644 --- a/maven-core/src/test/java/org/apache/maven/project/DefaultMavenProjectBuilderTest.java +++ b/maven-core/src/test/java/org/apache/maven/project/DefaultMavenProjectBuilderTest.java @@ -28,12 +28,13 @@ import org.apache.maven.artifact.Artifact; import org.apache.maven.artifact.repository.ArtifactRepository; import org.apache.maven.artifact.repository.layout.ArtifactRepositoryLayout; +import org.apache.maven.execution.DefaultMavenExecutionRequest; +import org.apache.maven.execution.MavenSession; import org.codehaus.plexus.util.FileUtils; public class DefaultMavenProjectBuilderTest extends AbstractMavenProjectTestCase { - private List filesToDelete = new ArrayList<>(); private File localRepoDir; @@ -84,6 +85,11 @@ protected MavenProject getProject( Artifact pom, boolean allowStub ) configuration.setLocalRepository( getLocalRepository() ); initRepoSession( configuration ); + getSessionScope().seed( MavenSession.class, + new MavenSession( getContainer(), + configuration.getRepositorySession(), + new DefaultMavenExecutionRequest(), null ) ); + return projectBuilder.build( pom, allowStub, configuration ).getProject(); } @@ -225,6 +231,10 @@ public void testPartialResultUponBadDependencyDeclaration() ProjectBuildingRequest request = newBuildingRequest(); request.setProcessPlugins( false ); request.setResolveDependencies( true ); + + getSessionScope().seed( MavenSession.class, new MavenSession( getContainer(), + request.getRepositorySession(), + new DefaultMavenExecutionRequest(), null ) ); projectBuilder.build( pomFile, request ); fail( "Project building did not fail despite invalid POM" ); } @@ -249,6 +259,10 @@ public void testImportScopePomResolvesFromPropertyBasedRepository() ProjectBuildingRequest request = newBuildingRequest(); request.setProcessPlugins( false ); request.setResolveDependencies( true ); + + getSessionScope().seed( MavenSession.class, new MavenSession( getContainer(), + request.getRepositorySession(), + new DefaultMavenExecutionRequest(), null ) ); projectBuilder.build( pomFile, request ); } diff --git a/maven-core/src/test/java/org/apache/maven/project/PomConstructionTest.java b/maven-core/src/test/java/org/apache/maven/project/PomConstructionTest.java index 9e16ebc59487..a639a38d0aef 100644 --- a/maven-core/src/test/java/org/apache/maven/project/PomConstructionTest.java +++ b/maven-core/src/test/java/org/apache/maven/project/PomConstructionTest.java @@ -22,6 +22,7 @@ import static org.hamcrest.Matchers.endsWith; import static org.hamcrest.Matchers.lessThan; import static org.hamcrest.Matchers.startsWith; +import static org.junit.Assert.assertNotEquals; import static org.junit.Assert.assertThat; import java.io.File; @@ -32,19 +33,21 @@ import java.util.Properties; import org.apache.maven.artifact.repository.layout.DefaultRepositoryLayout; +import org.apache.maven.execution.DefaultMavenExecutionRequest; +import org.apache.maven.execution.MavenSession; import org.apache.maven.model.Plugin; import org.apache.maven.model.PluginExecution; import org.apache.maven.model.building.ModelBuildingRequest; import org.apache.maven.project.harness.PomTestWrapper; import org.apache.maven.repository.RepositorySystem; import org.apache.maven.repository.internal.MavenRepositorySystemUtils; +import org.apache.maven.session.scope.internal.SessionScope; import org.codehaus.plexus.ContainerConfiguration; import org.codehaus.plexus.PlexusConstants; import org.codehaus.plexus.PlexusTestCase; import org.eclipse.aether.DefaultRepositorySystemSession; import org.eclipse.aether.internal.impl.SimpleLocalRepositoryManagerFactory; import org.eclipse.aether.repository.LocalRepository; -import static org.junit.Assert.assertNotEquals; public class PomConstructionTest extends PlexusTestCase @@ -58,6 +61,8 @@ public class PomConstructionTest private DefaultProjectBuilder projectBuilder; private RepositorySystem repositorySystem; + + private SessionScope sessionScope; private File testDirectory; @@ -76,6 +81,8 @@ protected void setUp() new File( getBasedir(), BASE_MIXIN_DIR ); projectBuilder = (DefaultProjectBuilder) lookup( ProjectBuilder.class ); repositorySystem = lookup( RepositorySystem.class ); + sessionScope = lookup( SessionScope.class ); + sessionScope.enter(); } @Override @@ -83,6 +90,7 @@ protected void tearDown() throws Exception { projectBuilder = null; + sessionScope.exit(); super.tearDown(); } @@ -1873,6 +1881,10 @@ private PomTestWrapper buildPom( String pomPath, boolean lenientValidation, Prop LocalRepository localRepo = new LocalRepository( config.getLocalRepository().getBasedir() ); repoSession.setLocalRepositoryManager( new SimpleLocalRepositoryManagerFactory().newInstance( repoSession, localRepo ) ); config.setRepositorySession( repoSession ); + + sessionScope.seed( MavenSession.class, new MavenSession( getContainer(), + config.getRepositorySession(), + new DefaultMavenExecutionRequest(), null ) ); return new PomTestWrapper( pomFile, projectBuilder.build( pomFile, config ).getProject() ); } diff --git a/maven-core/src/test/java/org/apache/maven/project/ProjectBuilderTest.java b/maven-core/src/test/java/org/apache/maven/project/ProjectBuilderTest.java index 4833b0035119..efa8a4ca1d70 100644 --- a/maven-core/src/test/java/org/apache/maven/project/ProjectBuilderTest.java +++ b/maven-core/src/test/java/org/apache/maven/project/ProjectBuilderTest.java @@ -37,6 +37,7 @@ import org.apache.maven.model.building.FileModelSource; import org.apache.maven.model.building.ModelBuildingRequest; import org.apache.maven.model.building.ModelSource; +import org.apache.maven.session.scope.internal.SessionScope; import org.apache.maven.shared.utils.io.FileUtils; import com.google.common.io.Files; @@ -75,9 +76,16 @@ public void testBuildFromModelSource() ProjectBuildingRequest configuration = new DefaultProjectBuildingRequest(); configuration.setRepositorySession( mavenSession.getRepositorySession() ); ModelSource modelSource = new FileModelSource( pomFile ); + + SessionScope sessionScope = lookup( SessionScope.class ); + sessionScope.enter(); + sessionScope.seed( MavenSession.class, mavenSession ); + ProjectBuildingResult result = lookup( org.apache.maven.project.ProjectBuilder.class ).build( modelSource, configuration ); + sessionScope.exit(); + assertNotNull( result.getProject().getParentFile() ); } diff --git a/maven-core/src/test/java/org/apache/maven/repository/TestRepositorySystem.java b/maven-core/src/test/java/org/apache/maven/repository/TestRepositorySystem.java index 0e054c6a76f5..75da31140952 100644 --- a/maven-core/src/test/java/org/apache/maven/repository/TestRepositorySystem.java +++ b/maven-core/src/test/java/org/apache/maven/repository/TestRepositorySystem.java @@ -103,14 +103,14 @@ public Artifact createArtifactWithClassifier( String groupId, String artifactId, public ArtifactRepository createDefaultLocalRepository() throws InvalidRepositoryException { - return createLocalRepository( new File( System.getProperty( "basedir", "" ), "target/local-repo" ).getAbsoluteFile() ); + return createLocalRepository( new File( System.getProperty( "basedir", "." ), "target/local-repo" ).getAbsoluteFile() ); } public ArtifactRepository createDefaultRemoteRepository() throws InvalidRepositoryException { return new MavenArtifactRepository( DEFAULT_REMOTE_REPO_ID, "file://" - + new File( System.getProperty( "basedir", "" ), "src/test/remote-repo" ).toURI().getPath(), + + new File( System.getProperty( "basedir", "." ), "src/test/remote-repo" ).getAbsoluteFile().toURI().getPath(), new DefaultRepositoryLayout(), new ArtifactRepositoryPolicy(), new ArtifactRepositoryPolicy() ); } diff --git a/maven-core/src/test/java/org/apache/maven/settings/PomConstructionWithSettingsTest.java b/maven-core/src/test/java/org/apache/maven/settings/PomConstructionWithSettingsTest.java index 78d0da8de6e6..eb6270bb3573 100644 --- a/maven-core/src/test/java/org/apache/maven/settings/PomConstructionWithSettingsTest.java +++ b/maven-core/src/test/java/org/apache/maven/settings/PomConstructionWithSettingsTest.java @@ -19,7 +19,14 @@ * under the License. */ +import java.io.File; +import java.io.IOException; +import java.io.Reader; + import org.apache.maven.artifact.repository.layout.DefaultRepositoryLayout; +import org.apache.maven.execution.DefaultMavenExecutionRequest; +import org.apache.maven.execution.MavenExecutionRequest; +import org.apache.maven.execution.MavenSession; import org.apache.maven.model.Profile; import org.apache.maven.project.DefaultProjectBuilder; import org.apache.maven.project.DefaultProjectBuildingRequest; @@ -28,6 +35,7 @@ import org.apache.maven.project.harness.PomTestWrapper; import org.apache.maven.repository.RepositorySystem; import org.apache.maven.repository.internal.MavenRepositorySystemUtils; +import org.apache.maven.session.scope.internal.SessionScope; import org.apache.maven.settings.io.xpp3.SettingsXpp3Reader; import org.codehaus.plexus.ContainerConfiguration; import org.codehaus.plexus.PlexusConstants; @@ -38,10 +46,6 @@ import org.eclipse.aether.internal.impl.SimpleLocalRepositoryManagerFactory; import org.eclipse.aether.repository.LocalRepository; -import java.io.File; -import java.io.IOException; -import java.io.Reader; - public class PomConstructionWithSettingsTest extends PlexusTestCase { @@ -52,9 +56,11 @@ public class PomConstructionWithSettingsTest private DefaultProjectBuilder projectBuilder; private RepositorySystem repositorySystem; + + private SessionScope sessionScope; private File testDirectory; - + @Override protected void customizeContainerConfiguration( ContainerConfiguration containerConfiguration ) { @@ -69,6 +75,7 @@ protected void setUp() testDirectory = new File( getBasedir(), BASE_POM_DIR ); projectBuilder = (DefaultProjectBuilder) lookup( ProjectBuilder.class ); repositorySystem = lookup( RepositorySystem.class ); + sessionScope = lookup( SessionScope.class ); } @Override @@ -94,6 +101,7 @@ public void testPomAndSettingsInterpolation() throws Exception { PomTestWrapper pom = buildPom( "test-pom-and-settings-interpolation" ); + assertEquals( "applied", pom.getValue( "properties/settingsProfile" ) ); assertEquals( "applied", pom.getValue( "properties/pomProfile" ) ); assertEquals( "settings", pom.getValue( "properties/pomVsSettings" ) ); @@ -138,6 +146,15 @@ private PomTestWrapper buildPom( String pomPath ) repoSession.setLocalRepositoryManager( new SimpleLocalRepositoryManagerFactory().newInstance( repoSession, localRepo ) ); config.setRepositorySession( repoSession ); + + MavenExecutionRequest request = new DefaultMavenExecutionRequest(); + request.setActiveProfiles( settings.getActiveProfiles() ); + + sessionScope.enter(); + sessionScope.seed( MavenSession.class, + new MavenSession( getContainer(), + repoSession, + new DefaultMavenExecutionRequest(), null ) ); return new PomTestWrapper( pomFile, projectBuilder.build( pomFile, config ).getProject() ); } diff --git a/maven-model-builder/src/main/java/org/apache/maven/feature/Features.java b/maven-model-builder/src/main/java/org/apache/maven/feature/Features.java index d4461d8e64b5..48848c9abbe3 100644 --- a/maven-model-builder/src/main/java/org/apache/maven/feature/Features.java +++ b/maven-model-builder/src/main/java/org/apache/maven/feature/Features.java @@ -31,7 +31,7 @@ private Features() { } - private static final Feature BUILDCONSUMER = new Feature( "maven.experimental.buildconsumer", "false" ); + private static final Feature BUILDCONSUMER = new Feature( "maven.experimental.buildconsumer", "true" ); public static Feature buildConsumer() { 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 6d2bb7e39af5..fe3904b4b4d0 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 @@ -23,6 +23,8 @@ import static org.apache.maven.model.building.Result.newResult; import java.io.File; +import java.io.FileInputStream; +import java.io.FilterOutputStream; import java.io.IOException; import java.io.InputStream; import java.io.PipedInputStream; @@ -36,10 +38,6 @@ import java.util.Map; import java.util.Objects; import java.util.Properties; -import java.util.concurrent.Callable; -import java.util.concurrent.ExecutionException; -import java.util.concurrent.ExecutorService; -import java.util.concurrent.Executors; import javax.inject.Inject; import javax.inject.Named; @@ -54,7 +52,6 @@ import org.apache.maven.artifact.versioning.DefaultArtifactVersion; import org.apache.maven.artifact.versioning.InvalidVersionSpecificationException; import org.apache.maven.artifact.versioning.VersionRange; -import org.apache.maven.building.FileSource; import org.apache.maven.feature.Features; import org.apache.maven.model.Activation; import org.apache.maven.model.Build; @@ -304,6 +301,20 @@ public ModelBuildingResult build( ModelBuildingRequest request ) if ( inputModel == null ) { inputModel = readModel( request.getModelSource(), request.getPomFile(), request, problems ); + + if ( Features.buildConsumer().isActive() && request.isTransformPom() ) + { + try + { + inputModel = modelProcessor.read( transformData( request.getPomFile() ), null ); + + inputModel.setPomFile( request.getPomFile() ); + } + catch ( IOException | TransformerException | SAXException | ParserConfigurationException e ) + { + problems.add( new ModelProblemCollectorRequest( Severity.FATAL, Version.V37 ).setException( e ) ); + } + } } problems.setRootModel( inputModel ); @@ -763,78 +774,80 @@ private void checkPluginVersions( List lineage, ModelBuildingRequest private void assembleInheritance( List lineage, ModelBuildingRequest request, ModelProblemCollector problems ) { - for ( int i = lineage.size() - 2; i >= 1; i-- ) + for ( int i = lineage.size() - 2; i >= 0; i-- ) { Model parent = lineage.get( i + 1 ).getModel(); Model child = lineage.get( i ).getModel(); inheritanceAssembler.assembleModelInheritance( child, parent, request, problems ); } - - // re-read model from file - if ( Features.buildConsumer().isActive() && request.isTransformPom() ) - { - try - { - Model parent = lineage.get( 1 ).getModel(); - - Model child = modelProcessor.read( transformData( lineage.get( 0 ) ), null ); - inheritanceAssembler.assembleModelInheritance( child, parent, request, problems ); - - // sync pomfile, is transient - child.setPomFile( lineage.get( 0 ).getModel().getPomFile() ); - // overwrite child - lineage.get( 0 ).setModel( child ); - } - catch ( IOException | TransformerException | SAXException | ParserConfigurationException e ) - { - problems.add( new ModelProblemCollectorRequest( Severity.FATAL, Version.V37 ).setException( e ) ); - } - } - else - { - Model parent = lineage.get( 1 ).getModel(); - Model child = lineage.get( 0 ).getModel(); - inheritanceAssembler.assembleModelInheritance( child, parent, request, problems ); - } } - private InputStream transformData( ModelData modelData ) + private InputStream transformData( File pomFile ) throws IOException, TransformerException, SAXException, ParserConfigurationException { +// return modelData.getSource().getInputStream(); final TransformerFactory transformerFactory = Factories.newTransformerFactory() ; final PipedOutputStream pipedOutputStream = new PipedOutputStream(); final PipedInputStream pipedInputStream = new PipedInputStream( pipedOutputStream ); // Should always be FileSource for reactor poms - FileSource source = (FileSource) modelData.getSource(); +// FileSource source = (FileSource) modelData.getSource(); - // System.out.println( "transforming " + source.getFile() ); +// System.out.println( "transforming " + source.getFile() ); final SAXSource transformSource = - new SAXSource( buildPomXMLFilterFactory.get().get( source.getFile().toPath() ), - new org.xml.sax.InputSource( modelData.getSource().getInputStream() ) ); - - final StreamResult result = new StreamResult( pipedOutputStream ); + new SAXSource( buildPomXMLFilterFactory.get().get( pomFile.toPath() ), + new org.xml.sax.InputSource( new FileInputStream( pomFile ) ) ); + + FilterOutputStream fos = new FilterOutputStream( pipedOutputStream ) + { + @Override + public void write( byte[] b, int off, int len ) + throws IOException + { + System.out.write( b, off, len ); + super.write( b, off, len ); + } + } + ; + final StreamResult result = new StreamResult( fos ); - final Callable callable = () -> +//// final Callable 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() { - try ( PipedOutputStream out = pipedOutputStream ) + @Override + public void run() { - transformerFactory.newTransformer().transform( transformSource, result ); + try ( PipedOutputStream out = pipedOutputStream ) + { + transformerFactory.newTransformer().transform( transformSource, result ); + } + catch ( TransformerException | IOException e ) + { + throw new RuntimeException( e ); + } } - return null; }; - ExecutorService executorService = Executors.newSingleThreadExecutor(); - try - { - executorService.submit( callable ).get(); - } - catch ( InterruptedException | ExecutionException e ) - { - throw new TransformerException( "Failed to transform pom", e ); - } + new Thread( runnable ).start(); return pipedInputStream; } 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 3e07c57754a8..bf6b0888cee0 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 @@ -22,6 +22,7 @@ import java.io.InputStream; import java.util.List; +import org.apache.maven.feature.Features; import org.apache.maven.model.Model; import org.apache.maven.model.building.DefaultModelBuildingRequest; import org.apache.maven.model.building.ModelBuildingRequest; @@ -415,11 +416,18 @@ public void testIncompleteParent() { SimpleProblemCollector result = validateRaw( "incomplete-parent.xml" ); - assertViolations( result, 3, 0, 0 ); + if ( Features.buildConsumer().isActive() ) + { + assertViolations( result, 2, 0, 0 ); + } + else + { + assertViolations( result, 3, 0, 0 ); + assertTrue( result.getFatals().get( 2 ).contains( "parent.version" ) ); + } assertTrue( result.getFatals().get( 0 ).contains( "parent.groupId" ) ); assertTrue( result.getFatals().get( 1 ).contains( "parent.artifactId" ) ); - assertTrue( result.getFatals().get( 2 ).contains( "parent.version" ) ); } public void testHardCodedSystemPath() diff --git a/maven-xml/src/main/java/org/apache/maven/xml/sax/filter/AbstractEventXMLFilter.java b/maven-xml/src/main/java/org/apache/maven/xml/sax/filter/AbstractEventXMLFilter.java index 633c53325641..e56303242adf 100644 --- a/maven-xml/src/main/java/org/apache/maven/xml/sax/filter/AbstractEventXMLFilter.java +++ b/maven-xml/src/main/java/org/apache/maven/xml/sax/filter/AbstractEventXMLFilter.java @@ -1,7 +1,5 @@ package org.apache.maven.xml.sax.filter; -import java.util.ArrayDeque; - /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file @@ -21,10 +19,8 @@ * under the License. */ -import java.util.ArrayList; +import java.util.ArrayDeque; import java.util.HashMap; -import java.util.Iterator; -import java.util.List; import java.util.Map; import java.util.Queue; @@ -142,7 +138,7 @@ protected final void executeEvents() throws SAXException } // not with streams due to checked SAXException - while( !saxEvents.isEmpty() ) + while ( !saxEvents.isEmpty() ) { saxEvents.poll().execute(); } 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 9cb6ff28210d..2531798938bf 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 @@ -34,6 +34,8 @@ *

              * Transforms relativePath to version. * We could decide to simply allow {@code }, but let's require the GA for now for checking + * This filter does NOT remove the relativePath (which is done by {@link RelativePathXMLFilter}, it will only + * optionally include the version based on the path *

              * * @author Robert Scholte @@ -87,12 +89,6 @@ protected String getState() { return state; } - - @Override - protected boolean acceptEvent( String eventState ) - { - return !( "relativePath".equals( eventState ) && resolvedParent.isPresent() ); - } @Override public void startElement( String uri, final String localName, String qName, Attributes atts ) 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 8f25c102b371..f98f4ddbed7d 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 @@ -99,6 +99,7 @@ public void testNoVersion() throws Exception String expected = "" + "GROUPID" + "ARTIFACTID" + + "RELATIVEPATH" + "1.0.0" + ""; @@ -137,6 +138,7 @@ public void testRelativePathAndVersion() throws Exception String expected = "" + "GROUPID" + "ARTIFACTID" + + "RELATIVEPATH" + "1.0.0" + ""; @@ -156,6 +158,7 @@ public void testWithWeirdNamespace() throws Exception String expected = "" + "GROUPID" + "ARTIFACTID" + + "RELATIVEPATH" + "1.0.0" + ""; From 3ef3fa1dab989f9ccf4f52601d13c5624ebb9429 Mon Sep 17 00:00:00 2001 From: rfscholte Date: Wed, 16 Oct 2019 22:56:37 +0200 Subject: [PATCH 21/52] [MNG-6656] Clean up code based on reviews --- .../maven/project/DefaultProjectBuilder.java | 2 - .../model/building/DefaultModelBuilder.java | 56 ++++++++++++------- .../building/DefaultModelBuilderFactory.java | 2 + .../building/DefaultModelBuildingRequest.java | 17 ------ .../building/FilterModelBuildingRequest.java | 13 ----- .../model/building/ModelBuildingRequest.java | 4 -- .../apache/maven/xml/sax/SAXEventUtils.java | 6 +- .../sax/filter/AbstractEventXMLFilter.java | 8 --- .../xml/sax/filter/BuildPomXMLFilter.java | 3 + .../sax/filter/BuildPomXMLFilterFactory.java | 31 +++++++--- .../sax/filter/BuildPomXMLFilterListener.java | 40 +++++++++++++ 11 files changed, 110 insertions(+), 72 deletions(-) create mode 100644 maven-xml/src/main/java/org/apache/maven/xml/sax/filter/BuildPomXMLFilterListener.java 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 ce6c9dced9e9..7e18f1ef3ce2 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 @@ -164,7 +164,6 @@ private ProjectBuildingResult build( File pomFile, ModelSource modelSource, Inte request.setModelBuildingListener( listener ); request.setPomFile( pomFile ); - request.setTransformPom( pomFile != null ); request.setModelSource( modelSource ); request.setLocationTracking( true ); @@ -438,7 +437,6 @@ private boolean build( List results, List request.setPomFile( pomFile ); request.setTwoPhaseBuilding( true ); request.setLocationTracking( true ); - request.setTransformPom( true ); DefaultModelBuildingListener listener = new DefaultModelBuildingListener( project, projectBuildingHelper, config.request ); 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 fe3904b4b4d0..0e50073f75b1 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 @@ -27,8 +27,10 @@ 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; @@ -91,6 +93,7 @@ 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; import org.codehaus.plexus.interpolation.StringSearchInterpolator; import org.eclipse.sisu.Nullable; @@ -156,13 +159,17 @@ public class DefaultModelBuilder @Inject private ReportingConverter reportingConverter; + // Using provider so MavenSession can be used in the constructor @Inject - @Nullable private Provider buildPomXMLFilterFactory; @Inject @Nullable private ModelCacheManager modelCacheManager; + + @Inject + @Nullable + private BuildPomXMLFilterListener xmlFilterListener; public DefaultModelBuilder setModelProcessor( ModelProcessor modelProcessor ) { @@ -265,6 +272,12 @@ public DefaultModelBuilder setReportingConverter( ReportingConverter reportingCo this.reportingConverter = reportingConverter; return this; } + + public DefaultModelBuilder setBuildPomXMLFilterFactory( BuildPomXMLFilterFactory buildPomXMLFilterFactory ) + { + this.buildPomXMLFilterFactory = () -> buildPomXMLFilterFactory; + return this; + } @SuppressWarnings( "checkstyle:methodlength" ) @Override @@ -302,11 +315,11 @@ public ModelBuildingResult build( ModelBuildingRequest request ) { inputModel = readModel( request.getModelSource(), request.getPomFile(), request, problems ); - if ( Features.buildConsumer().isActive() && request.isTransformPom() ) + if ( Features.buildConsumer().isActive() && request.getPomFile() != null ) { try { - inputModel = modelProcessor.read( transformData( request.getPomFile() ), null ); + inputModel = modelProcessor.read( transformData( request.getPomFile().toPath() ), null ); inputModel.setPomFile( request.getPomFile() ); } @@ -782,36 +795,41 @@ private void assembleInheritance( List lineage, ModelBuildingRequest } } - private InputStream transformData( File pomFile ) + private InputStream transformData( final Path pomFile ) throws IOException, TransformerException, SAXException, ParserConfigurationException { -// return modelData.getSource().getInputStream(); final TransformerFactory transformerFactory = Factories.newTransformerFactory() ; final PipedOutputStream pipedOutputStream = new PipedOutputStream(); final PipedInputStream pipedInputStream = new PipedInputStream( pipedOutputStream ); // Should always be FileSource for reactor poms -// FileSource source = (FileSource) modelData.getSource(); - -// System.out.println( "transforming " + source.getFile() ); + // System.out.println( "transforming " + pomFile ); final SAXSource transformSource = - new SAXSource( buildPomXMLFilterFactory.get().get( pomFile.toPath() ), - new org.xml.sax.InputSource( new FileInputStream( pomFile ) ) ); + new SAXSource( buildPomXMLFilterFactory.get().get( pomFile ), + new org.xml.sax.InputSource( new FileInputStream( pomFile.toFile() ) ) ); - FilterOutputStream fos = new FilterOutputStream( pipedOutputStream ) + OutputStream out; + if ( xmlFilterListener != null ) { - @Override - public void write( byte[] b, int off, int len ) - throws IOException + out = new FilterOutputStream( pipedOutputStream ) { - System.out.write( b, off, len ); - super.write( b, off, len ); - } + @Override + public void write( byte[] b, int off, int len ) + throws IOException + { + super.write( b, off, len ); + xmlFilterListener.write( pomFile, b, off, len ); + } + }; } - ; - final StreamResult result = new StreamResult( fos ); + else + { + out = pipedOutputStream; + } + + final StreamResult result = new StreamResult( out ); //// final Callable callable = () -> //// { 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 4240574ff214..cd499ebc49d1 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 @@ -64,6 +64,7 @@ import org.apache.maven.model.superpom.SuperPomProvider; import org.apache.maven.model.validation.DefaultModelValidator; import org.apache.maven.model.validation.ModelValidator; +import org.apache.maven.xml.sax.filter.BuildPomXMLFilterFactory; /** * A factory to create model builder instances when no dependency injection is available. Note: This class is @@ -225,6 +226,7 @@ public DefaultModelBuilder newInstance() modelBuilder.setPluginConfigurationExpander( newPluginConfigurationExpander() ); modelBuilder.setReportConfigurationExpander( newReportConfigurationExpander() ); modelBuilder.setReportingConverter( newReportingConverter() ); + modelBuilder.setBuildPomXMLFilterFactory( new BuildPomXMLFilterFactory() ); return modelBuilder; } 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 06128a8ec64c..b7b54d8d0a79 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 @@ -72,8 +72,6 @@ public class DefaultModelBuildingRequest private ModelCache modelCache; private WorkspaceModelResolver workspaceResolver; - - private boolean transformPom; /** * Creates an empty request. @@ -103,7 +101,6 @@ public DefaultModelBuildingRequest( ModelBuildingRequest request ) setModelResolver( request.getModelResolver() ); setModelBuildingListener( request.getModelBuildingListener() ); setModelCache( request.getModelCache() ); - setTransformPom( request.isTransformPom() ); } @Override @@ -410,18 +407,4 @@ public ModelBuildingRequest setWorkspaceModelResolver( WorkspaceModelResolver wo this.workspaceResolver = workspaceResolver; return this; } - - @Override - public boolean isTransformPom() - { - return transformPom; - } - - @Override - public ModelBuildingRequest setTransformPom( boolean transformPom ) - { - this.transformPom = transformPom; - return this; - } - } 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 a9012a176030..527a257a6d17 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 @@ -281,17 +281,4 @@ public ModelBuildingRequest setWorkspaceModelResolver( WorkspaceModelResolver wo request.setWorkspaceModelResolver( workspaceResolver ); return this; } - - @Override - public boolean isTransformPom() - { - return request.isTransformPom(); - } - - @Override - public ModelBuildingRequest setTransformPom( boolean transform ) - { - request.setTransformPom( transform ); - return this; - } } \ No newline at end of file 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 10aedc103e65..b8ae4f8a398c 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 @@ -334,8 +334,4 @@ public interface ModelBuildingRequest WorkspaceModelResolver getWorkspaceModelResolver(); ModelBuildingRequest setWorkspaceModelResolver( WorkspaceModelResolver workspaceResolver ); - - boolean isTransformPom(); - - ModelBuildingRequest setTransformPom( boolean transform ); } diff --git a/maven-xml/src/main/java/org/apache/maven/xml/sax/SAXEventUtils.java b/maven-xml/src/main/java/org/apache/maven/xml/sax/SAXEventUtils.java index 483bb7d8b7fc..237ec44cb3a6 100644 --- a/maven-xml/src/main/java/org/apache/maven/xml/sax/SAXEventUtils.java +++ b/maven-xml/src/main/java/org/apache/maven/xml/sax/SAXEventUtils.java @@ -19,6 +19,8 @@ * under the License. */ +import java.util.regex.Pattern; + /** * Utility class for SAXEvents * @@ -27,6 +29,8 @@ */ public final class SAXEventUtils { + private static final Pattern PATTERN = Pattern.compile( "[^:]+$" ); + private SAXEventUtils() { } @@ -40,6 +44,6 @@ private SAXEventUtils() */ public static String renameQName( String oldQName, String newLocalName ) { - return oldQName.replaceFirst( "[^:]+$", newLocalName ); + return PATTERN.matcher( oldQName ).replaceFirst( newLocalName ); } } diff --git a/maven-xml/src/main/java/org/apache/maven/xml/sax/filter/AbstractEventXMLFilter.java b/maven-xml/src/main/java/org/apache/maven/xml/sax/filter/AbstractEventXMLFilter.java index e56303242adf..f718103b7080 100644 --- a/maven-xml/src/main/java/org/apache/maven/xml/sax/filter/AbstractEventXMLFilter.java +++ b/maven-xml/src/main/java/org/apache/maven/xml/sax/filter/AbstractEventXMLFilter.java @@ -60,14 +60,6 @@ protected boolean acceptEvent( String state ) return true; } -// protected final void applyCharacters() throws SAXException -// { -// if ( characters != null ) -// { -// processEvent( characters ); -// } -// } - AbstractEventXMLFilter() { super(); diff --git a/maven-xml/src/main/java/org/apache/maven/xml/sax/filter/BuildPomXMLFilter.java b/maven-xml/src/main/java/org/apache/maven/xml/sax/filter/BuildPomXMLFilter.java index 041d5c18bccf..14bcf704e384 100644 --- a/maven-xml/src/main/java/org/apache/maven/xml/sax/filter/BuildPomXMLFilter.java +++ b/maven-xml/src/main/java/org/apache/maven/xml/sax/filter/BuildPomXMLFilter.java @@ -44,6 +44,9 @@ BuildPomXMLFilter( T parent ) super( parent ); } + /** + * Don't allow overwriting parent + */ @Override public final void setParent( XMLReader parent ) { 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 d1156739e251..66c5fc942d25 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,7 +41,7 @@ * * @since 3.7.0 */ -public abstract class BuildPomXMLFilterFactory +public class BuildPomXMLFilterFactory { public final BuildPomXMLFilter get( Path projectFile ) throws SAXException, ParserConfigurationException, TransformerConfigurationException @@ -83,14 +83,14 @@ public final BuildPomXMLFilter get( Path projectFile ) return new BuildPomXMLFilter( parent ); } - protected XMLReader getXMLReader() throws SAXException, ParserConfigurationException + private XMLReader getXMLReader() throws SAXException, ParserConfigurationException { XMLReader xmlReader = Factories.newXMLReader(); xmlReader.setFeature( "http://xml.org/sax/features/namespaces", true ); return xmlReader; } - protected LexicalHandler getLexicalHander() throws TransformerConfigurationException + private LexicalHandler getLexicalHander() throws TransformerConfigurationException { TransformerFactory transformerFactory = Factories.newTransformerFactory(); if ( transformerFactory instanceof SAXTransformerFactory ) @@ -104,16 +104,31 @@ protected LexicalHandler getLexicalHander() throws TransformerConfigurationExcep // getters for the 3 magic properties of CIFriendly versions ( https://maven.apache.org/maven-ci-friendly.html ) - protected abstract Optional getChangelist(); + protected Optional getChangelist() + { + return Optional.empty(); + } - protected abstract Optional getRevision(); + protected Optional getRevision() + { + return Optional.empty(); + } - protected abstract Optional getSha1(); + protected Optional getSha1() + { + return Optional.empty(); + } /** * @return the mapper or {@code null} if relativePaths don't need to be mapped */ - protected abstract Function> getRelativePathMapper(); + protected Function> getRelativePathMapper() + { + return null; + } - protected abstract Function getDependencyKeyToVersionMapper(); + protected Function getDependencyKeyToVersionMapper() + { + return null; + } } diff --git a/maven-xml/src/main/java/org/apache/maven/xml/sax/filter/BuildPomXMLFilterListener.java b/maven-xml/src/main/java/org/apache/maven/xml/sax/filter/BuildPomXMLFilterListener.java new file mode 100644 index 000000000000..e984640594d0 --- /dev/null +++ b/maven-xml/src/main/java/org/apache/maven/xml/sax/filter/BuildPomXMLFilterListener.java @@ -0,0 +1,40 @@ +package org.apache.maven.xml.sax.filter; + +/* + * 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; + +/** + * + * @author Robert Scholte + * @since 3.7.0 + */ +public interface BuildPomXMLFilterListener +{ + /** + * Captures the result of the XML transformation + * + * @param pomFile the original to being transformed + * @param b the byte array + * @param off the offset + * @param len the length + */ + void write( Path pomFile, byte[] b, int off, int len ); +} From 729c93c6154fbf0d852ebd89613e3be1bd9c20f3 Mon Sep 17 00:00:00 2001 From: rfscholte Date: Sat, 19 Oct 2019 14:08:10 +0200 Subject: [PATCH 22/52] [MNG-6656] Fix deadlock --- ...DefaultRepositorySystemSessionFactory.java | 23 +++++++------------ 1 file changed, 8 insertions(+), 15 deletions(-) diff --git a/maven-core/src/main/java/org/apache/maven/internal/aether/DefaultRepositorySystemSessionFactory.java b/maven-core/src/main/java/org/apache/maven/internal/aether/DefaultRepositorySystemSessionFactory.java index 94b2e353de3d..526ed011d092 100644 --- a/maven-core/src/main/java/org/apache/maven/internal/aether/DefaultRepositorySystemSessionFactory.java +++ b/maven-core/src/main/java/org/apache/maven/internal/aether/DefaultRepositorySystemSessionFactory.java @@ -31,8 +31,6 @@ import java.util.LinkedHashMap; import java.util.Map; import java.util.Properties; -import java.util.concurrent.Callable; -import java.util.concurrent.ExecutionException; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; @@ -41,6 +39,7 @@ import javax.inject.Provider; 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; @@ -311,24 +310,18 @@ public InputStream transformData( File file ) final StreamResult result = new StreamResult( pipedOutputStream ); - final Callable callable = () -> + ExecutorService executorService = Executors.newSingleThreadExecutor(); + executorService.execute( () -> { 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 TransformException( "Failed to transform pom", e ); - } + catch ( TransformerException | IOException e ) + { + throw new RuntimeException( e ); + } + } ); return pipedInputStream; } From 61a3761537df98839c28a47b388b7e467ad242e4 Mon Sep 17 00:00:00 2001 From: rfscholte Date: Mon, 25 Nov 2019 08:30:40 +0100 Subject: [PATCH 23/52] [MNG-6656] Move post-processing of file to rawmodel to proper method --- .../model/building/DefaultModelBuilder.java | 28 +++++++++---------- 1 file changed, 14 insertions(+), 14 deletions(-) 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 0e50073f75b1..deb790e9e207 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 @@ -314,20 +314,6 @@ public ModelBuildingResult build( ModelBuildingRequest request ) if ( inputModel == null ) { inputModel = readModel( request.getModelSource(), request.getPomFile(), request, problems ); - - if ( Features.buildConsumer().isActive() && request.getPomFile() != null ) - { - try - { - inputModel = modelProcessor.read( transformData( request.getPomFile().toPath() ), null ); - - inputModel.setPomFile( request.getPomFile() ); - } - catch ( IOException | TransformerException | SAXException | ParserConfigurationException e ) - { - problems.add( new ModelProblemCollectorRequest( Severity.FATAL, Version.V37 ).setException( e ) ); - } - } } problems.setRootModel( inputModel ); @@ -680,6 +666,20 @@ private Model readModel( ModelSource modelSource, File pomFile, ModelBuildingReq { throw problems.newModelBuildingException(); } + + if ( Features.buildConsumer().isActive() && pomFile != null ) + { + try + { + model = modelProcessor.read( transformData( pomFile.toPath() ), null ); + + model.setPomFile( pomFile ); + } + catch ( IOException | TransformerException | SAXException | ParserConfigurationException e ) + { + problems.add( new ModelProblemCollectorRequest( Severity.FATAL, Version.V37 ).setException( e ) ); + } + } return model; } From 21be0b1f8c781ec2600c7e85816c94f2dd249e2e Mon Sep 17 00:00:00 2001 From: rfscholte Date: Fri, 29 Nov 2019 10:20:43 +0100 Subject: [PATCH 24/52] [MNG-6656] Don't post-process when model has errors --- .../org/apache/maven/model/building/DefaultModelBuilder.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) 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 deb790e9e207..8a46aed04c26 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 @@ -667,7 +667,7 @@ private Model readModel( ModelSource modelSource, File pomFile, ModelBuildingReq throw problems.newModelBuildingException(); } - if ( Features.buildConsumer().isActive() && pomFile != null ) + if ( !hasModelErrors( problems ) && Features.buildConsumer().isActive() && pomFile != null ) { try { From d373d3a3d4419c0e15a8c37f28a92f3920fc61f6 Mon Sep 17 00:00:00 2001 From: rfscholte Date: Fri, 13 Dec 2019 15:10:01 +0100 Subject: [PATCH 25/52] MNG-6656: Keep xml version + encoding after transformation --- ...DefaultRepositorySystemSessionFactory.java | 82 +++++++++++++++++-- 1 file changed, 73 insertions(+), 9 deletions(-) diff --git a/maven-core/src/main/java/org/apache/maven/internal/aether/DefaultRepositorySystemSessionFactory.java b/maven-core/src/main/java/org/apache/maven/internal/aether/DefaultRepositorySystemSessionFactory.java index 526ed011d092..77581d6068b2 100644 --- a/maven-core/src/main/java/org/apache/maven/internal/aether/DefaultRepositorySystemSessionFactory.java +++ b/maven-core/src/main/java/org/apache/maven/internal/aether/DefaultRepositorySystemSessionFactory.java @@ -20,7 +20,8 @@ */ import java.io.File; -import java.io.FileReader; +import java.io.FileInputStream; +import java.io.FileNotFoundException; import java.io.IOException; import java.io.InputStream; import java.io.PipedInputStream; @@ -38,10 +39,18 @@ import javax.inject.Named; import javax.inject.Provider; import javax.xml.parsers.ParserConfigurationException; +import javax.xml.stream.FactoryConfigurationError; +import javax.xml.stream.XMLInputFactory; +import javax.xml.stream.XMLStreamException; +import javax.xml.stream.XMLStreamReader; +import javax.xml.transform.OutputKeys; +import javax.xml.transform.Transformer; import javax.xml.transform.TransformerConfigurationException; import javax.xml.transform.TransformerException; -import javax.xml.transform.TransformerFactory; +import javax.xml.transform.sax.SAXResult; import javax.xml.transform.sax.SAXSource; +import javax.xml.transform.sax.SAXTransformerFactory; +import javax.xml.transform.sax.TransformerHandler; import javax.xml.transform.stream.StreamResult; import org.apache.maven.RepositoryUtils; @@ -59,6 +68,7 @@ import org.apache.maven.settings.crypto.SettingsDecrypter; import org.apache.maven.settings.crypto.SettingsDecryptionResult; import org.apache.maven.xml.Factories; +import org.apache.maven.xml.sax.filter.AbstractSAXFilter; import org.apache.maven.xml.sax.filter.ConsumerPomXMLFilterFactory; import org.codehaus.plexus.configuration.xml.XmlPlexusConfiguration; import org.codehaus.plexus.logging.Logger; @@ -285,8 +295,9 @@ public Collection getTransformersForArtifact( final Artifact ar Collection transformers = new ArrayList<>(); if ( "pom".equals( artifact.getExtension() ) ) { - final TransformerFactory transformerFactory = Factories.newTransformerFactory(); - + final SAXTransformerFactory transformerFactory = + (SAXTransformerFactory) Factories.newTransformerFactory(); + transformers.add( new FileTransformer() { @Override @@ -296,26 +307,33 @@ public InputStream transformData( File file ) final PipedOutputStream pipedOutputStream = new PipedOutputStream(); final PipedInputStream pipedInputStream = new PipedInputStream( pipedOutputStream ); + final TransformerHandler transformerHandler = + getTransformerHandler( transformerFactory, file ); + final SAXSource transformSource; try { + AbstractSAXFilter filter = consumerPomXMLFilterFactory.get().get( file.toPath() ); + filter.setLexicalHandler( transformerHandler ); + transformSource = - new SAXSource( consumerPomXMLFilterFactory.get().get( file.toPath() ), - new InputSource( new FileReader( file ) ) ); + new SAXSource( filter, new InputSource( new FileInputStream( file ) ) ); } catch ( SAXException | ParserConfigurationException | TransformerConfigurationException e ) { throw new TransformException( "Failed to create a consumerPomXMLFilter", e ); } - final StreamResult result = new StreamResult( pipedOutputStream ); + transformerHandler.setResult( new StreamResult( pipedOutputStream ) ); + + SAXResult transformResult = new SAXResult( transformerHandler ); ExecutorService executorService = Executors.newSingleThreadExecutor(); executorService.execute( () -> { try ( PipedOutputStream out = pipedOutputStream ) { - transformerFactory.newTransformer().transform( transformSource, result ); + transformerFactory.newTransformer().transform( transformSource, transformResult ); } catch ( TransformerException | IOException e ) { @@ -325,7 +343,7 @@ public InputStream transformData( File file ) return pipedInputStream; } - + @Override public Artifact transformArtifact( Artifact artifact ) { @@ -338,6 +356,52 @@ public Artifact transformArtifact( Artifact artifact ) }; } + private static TransformerHandler getTransformerHandler( SAXTransformerFactory transformerFactory, + File file ) + throws IOException, FileNotFoundException, TransformException + { + final TransformerHandler transformerHandler; + + // Keep same encoding+version + try ( FileInputStream input = new FileInputStream( file ) ) + { + XMLStreamReader streamReader = + XMLInputFactory.newFactory().createXMLStreamReader( input ); + + transformerHandler = transformerFactory.newTransformerHandler(); + + final String encoding = streamReader.getCharacterEncodingScheme(); + final String version = streamReader.getVersion(); + + Transformer transformer = transformerHandler.getTransformer(); + if ( encoding == null && version == null ) + { + transformer.setOutputProperty( OutputKeys.OMIT_XML_DECLARATION, "yes" ); + } + else + { + transformer.setOutputProperty( OutputKeys.OMIT_XML_DECLARATION, "no" ); + + if ( encoding != null ) + { + transformer.setOutputProperty( OutputKeys.ENCODING, encoding ); + } + if ( version != null ) + { + transformer.setOutputProperty( OutputKeys.VERSION, version ); + } + } + } + catch ( XMLStreamException + | FactoryConfigurationError + | TransformerConfigurationException e ) + { + throw new TransformException( "Failed to detect XML encoding and version", e ); + } + return transformerHandler; + } + + private String getUserAgent() { return "Apache-Maven/" + getMavenVersion() + " (Java " + System.getProperty( "java.version" ) + "; " From d9cc0e475952bc88f1187e00a0f0ff142f4c6f2a Mon Sep 17 00:00:00 2001 From: rfscholte Date: Wed, 18 Dec 2019 23:00:34 +0100 Subject: [PATCH 26/52] [MNG-6656] Improve ModelValidator --- .../maven/project/ProjectBuilderTest.java | 2 ++ .../model/building/DefaultModelBuilder.java | 4 +++ .../building/DefaultModelBuildingRequest.java | 14 +++++++++ .../building/FilterModelBuildingRequest.java | 13 ++++++++ .../model/building/ModelBuildingRequest.java | 15 +++++++++ .../validation/DefaultModelValidator.java | 31 ++++++++++++++----- .../model/validation/ModelValidator.java | 16 ++++++++-- .../validation/DefaultModelValidatorTest.java | 31 ++++++++++--------- 8 files changed, 101 insertions(+), 25 deletions(-) diff --git a/maven-core/src/test/java/org/apache/maven/project/ProjectBuilderTest.java b/maven-core/src/test/java/org/apache/maven/project/ProjectBuilderTest.java index efa8a4ca1d70..d402f96cf0d3 100644 --- a/maven-core/src/test/java/org/apache/maven/project/ProjectBuilderTest.java +++ b/maven-core/src/test/java/org/apache/maven/project/ProjectBuilderTest.java @@ -240,6 +240,7 @@ public void testReadInvalidPom() try { projectBuilder.build( pomFile, configuration ); + fail(); } catch ( InvalidArtifactRTException iarte ) { @@ -250,6 +251,7 @@ public void testReadInvalidPom() try { projectBuilder.build( Collections.singletonList( pomFile ), false, configuration ); + fail(); } catch ( ProjectBuildingException ex ) { 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 8a46aed04c26..5bfe617f9258 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 @@ -660,6 +660,10 @@ private Model readModel( ModelSource modelSource, File pomFile, ModelBuildingReq model.setPomFile( pomFile ); problems.setSource( model ); + + modelValidator.validateFileModel( model, request, problems ); + request.setFileModel( model ); + modelValidator.validateRawModel( model, request, problems ); if ( hasFatalErrors( problems ) ) 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 b7b54d8d0a79..3cf3a896ad01 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 @@ -38,6 +38,7 @@ public class DefaultModelBuildingRequest implements ModelBuildingRequest { + private transient Model fileModel; private Model rawModel; @@ -382,6 +383,19 @@ public DefaultModelBuildingRequest setModelCache( ModelCache modelCache ) return this; } + @Override + public Model getFileModel() + { + return fileModel; + } + + @Override + public ModelBuildingRequest setFileModel( Model fileModel ) + { + this.fileModel = fileModel; + return this; + } + @Override public Model getRawModel() { 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 527a257a6d17..fb38f167232b 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 @@ -256,6 +256,19 @@ public FilterModelBuildingRequest setModelCache( ModelCache modelCache ) return this; } + @Override + public Model getFileModel() + { + return request.getFileModel(); + } + + @Override + public ModelBuildingRequest setFileModel( Model fileModel ) + { + request.setFileModel( fileModel ); + return this; + } + @Override public Model getRawModel() { 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 b8ae4f8a398c..1e0b3dad60af 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,6 +63,21 @@ 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 + * @since 3.7.0 + */ + Model getFileModel(); + + /** + * + * @param fileModel + * @return This request, never {@code null}. + * @since 3.7.0 + */ + ModelBuildingRequest setFileModel( Model fileModel ); /** * Gets the raw model to build. If not set, model source will be used to load raw model. diff --git a/maven-model-builder/src/main/java/org/apache/maven/model/validation/DefaultModelValidator.java b/maven-model-builder/src/main/java/org/apache/maven/model/validation/DefaultModelValidator.java index 86670eb47f11..862c8ecf7b86 100644 --- a/maven-model-builder/src/main/java/org/apache/maven/model/validation/DefaultModelValidator.java +++ b/maven-model-builder/src/main/java/org/apache/maven/model/validation/DefaultModelValidator.java @@ -88,7 +88,7 @@ public class DefaultModelValidator private final Set validIds = new HashSet<>(); @Override - public void validateRawModel( Model m, ModelBuildingRequest request, ModelProblemCollector problems ) + public void validateFileModel( Model m, ModelBuildingRequest request, ModelProblemCollector problems ) { Parent parent = m.getParent(); if ( parent != null ) @@ -99,13 +99,6 @@ public void validateRawModel( Model m, ModelBuildingRequest request, ModelProble validateStringNotEmpty( "parent.artifactId", problems, Severity.FATAL, Version.BASE, parent.getArtifactId(), parent ); - // resolvedModel will assign version based on relativePath - if ( !Features.buildConsumer().isActive() ) - { - validateStringNotEmpty( "parent.version", problems, Severity.FATAL, Version.BASE, parent.getVersion(), - parent ); - } - if ( equals( parent.getGroupId(), m.getGroupId() ) && equals( parent.getArtifactId(), m.getArtifactId() ) ) { addViolation( problems, Severity.FATAL, Version.BASE, "parent.artifactId", null, @@ -225,6 +218,28 @@ public void validateRawModel( Model m, ModelBuildingRequest request, ModelProble } } } + + @Override + public void validateRawModel( Model m, ModelBuildingRequest request, ModelProblemCollector problems ) + { + Parent parent = m.getParent(); + + if ( parent != null ) + { + InputLocationTracker locationTracker; + if ( Features.buildConsumer().isActive() ) + { + locationTracker = request.getFileModel().getParent(); + } + else + { + locationTracker = parent; + } + + validateStringNotEmpty( "parent.version", problems, Severity.FATAL, Version.BASE, parent.getVersion(), + locationTracker ); + } + } private void validate30RawProfileActivation( ModelProblemCollector problems, Activation activation, String sourceHint, String prefix, String fieldName, diff --git a/maven-model-builder/src/main/java/org/apache/maven/model/validation/ModelValidator.java b/maven-model-builder/src/main/java/org/apache/maven/model/validation/ModelValidator.java index 84e3faddc5cd..198ba5ac5238 100644 --- a/maven-model-builder/src/main/java/org/apache/maven/model/validation/ModelValidator.java +++ b/maven-model-builder/src/main/java/org/apache/maven/model/validation/ModelValidator.java @@ -30,15 +30,27 @@ */ public interface ModelValidator { - /** - * Checks the specified (raw) model for missing or invalid values. The raw model is directly created from the POM + * Checks the specified file model for missing or invalid values. This model is directly created from the POM * file and has not been subjected to inheritance, interpolation or profile/default injection. * * @param model The model to validate, must not be {@code null}. * @param request The model building request that holds further settings, must not be {@code null}. * @param problems The container used to collect problems that were encountered, must not be {@code null}. */ + default void validateFileModel( Model model, ModelBuildingRequest request, ModelProblemCollector problems ) + { + // do nothing + } + + /** + * Checks the specified (raw) model for missing or invalid values. The raw model is the file model + buildpom filter + * transformation and has not been subjected to inheritance, interpolation or profile/default injection. + * + * @param model The model to validate, must not be {@code null}. + * @param request The model building request that holds further settings, must not be {@code null}. + * @param problems The container used to collect problems that were encountered, must not be {@code null}. + */ void validateRawModel( Model model, ModelBuildingRequest request, ModelProblemCollector problems ); /** 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 bf6b0888cee0..b90fcc6a7131 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 @@ -22,7 +22,6 @@ import java.io.InputStream; import java.util.List; -import org.apache.maven.feature.Features; import org.apache.maven.model.Model; import org.apache.maven.model.building.DefaultModelBuildingRequest; import org.apache.maven.model.building.ModelBuildingRequest; @@ -65,10 +64,14 @@ private SimpleProblemCollector validateEffective( String pom, int level ) throws Exception { ModelBuildingRequest request = new DefaultModelBuildingRequest().setValidationLevel( level ); + + Model model = read( pom ); - SimpleProblemCollector problems = new SimpleProblemCollector( read( pom ) ); + SimpleProblemCollector problems = new SimpleProblemCollector( model ); + + request.setFileModel( model ); - validator.validateEffectiveModel( problems.getModel(), request, problems ); + validator.validateEffectiveModel( model, request, problems ); return problems; } @@ -78,9 +81,15 @@ private SimpleProblemCollector validateRaw( String pom, int level ) { ModelBuildingRequest request = new DefaultModelBuildingRequest().setValidationLevel( level ); - SimpleProblemCollector problems = new SimpleProblemCollector( read( pom ) ); + Model model = read( pom ); + + SimpleProblemCollector problems = new SimpleProblemCollector( model ); - validator.validateRawModel( problems.getModel(), request, problems ); + validator.validateFileModel( model, request, problems ); + + request.setFileModel( model ); + + validator.validateRawModel( model, request, problems ); return problems; } @@ -416,18 +425,10 @@ public void testIncompleteParent() { SimpleProblemCollector result = validateRaw( "incomplete-parent.xml" ); - if ( Features.buildConsumer().isActive() ) - { - assertViolations( result, 2, 0, 0 ); - } - else - { - assertViolations( result, 3, 0, 0 ); - assertTrue( result.getFatals().get( 2 ).contains( "parent.version" ) ); - } - + assertViolations( result, 3, 0, 0 ); assertTrue( result.getFatals().get( 0 ).contains( "parent.groupId" ) ); assertTrue( result.getFatals().get( 1 ).contains( "parent.artifactId" ) ); + assertTrue( result.getFatals().get( 2 ).contains( "parent.version" ) ); } public void testHardCodedSystemPath() From 3d453bf25df69fecd645561f1d4b39732d52c5b1 Mon Sep 17 00:00:00 2001 From: rfscholte Date: Mon, 30 Dec 2019 15:23:16 +0100 Subject: [PATCH 27/52] [MNG-6656] Introduce custom ModelMerger to keep inputLocationTracker from fileModel in rawModel --- .../model/building/DefaultModelBuilder.java | 196 ++++++++++++++++-- .../building/DefaultModelBuilderFactory.java | 1 + .../validation/DefaultModelValidator.java | 35 ++-- .../building/FileToRawModelMergerTest.java | 82 ++++++++ .../validation/DefaultModelValidatorTest.java | 2 +- 5 files changed, 279 insertions(+), 37 deletions(-) create mode 100644 maven-model-builder/src/test/java/org/apache/maven/model/building/FileToRawModelMergerTest.java 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 5bfe617f9258..0e2f10a6bd01 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 @@ -57,15 +57,21 @@ import org.apache.maven.feature.Features; import org.apache.maven.model.Activation; import org.apache.maven.model.Build; +import org.apache.maven.model.BuildBase; +import org.apache.maven.model.CiManagement; import org.apache.maven.model.Dependency; import org.apache.maven.model.DependencyManagement; import org.apache.maven.model.InputLocation; import org.apache.maven.model.InputSource; import org.apache.maven.model.Model; +import org.apache.maven.model.ModelBase; import org.apache.maven.model.Parent; import org.apache.maven.model.Plugin; +import org.apache.maven.model.PluginContainer; import org.apache.maven.model.PluginManagement; import org.apache.maven.model.Profile; +import org.apache.maven.model.ReportPlugin; +import org.apache.maven.model.Reporting; import org.apache.maven.model.Repository; import org.apache.maven.model.building.ModelProblem.Severity; import org.apache.maven.model.building.ModelProblem.Version; @@ -75,6 +81,7 @@ import org.apache.maven.model.io.ModelParseException; import org.apache.maven.model.management.DependencyManagementInjector; import org.apache.maven.model.management.PluginManagementInjector; +import org.apache.maven.model.merge.ModelMerger; import org.apache.maven.model.normalization.ModelNormalizer; import org.apache.maven.model.path.ModelPathTranslator; import org.apache.maven.model.path.ModelUrlNormalizer; @@ -124,7 +131,7 @@ public class DefaultModelBuilder @Inject private ModelUrlNormalizer modelUrlNormalizer; - + @Inject private SuperPomProvider superPomProvider; @@ -164,12 +171,13 @@ public class DefaultModelBuilder private Provider buildPomXMLFilterFactory; @Inject - @Nullable private ModelCacheManager modelCacheManager; @Inject @Nullable private BuildPomXMLFilterListener xmlFilterListener; + + private ModelMerger modelMerger = new FileToRawModelMerger(); public DefaultModelBuilder setModelProcessor( ModelProcessor modelProcessor ) { @@ -278,6 +286,11 @@ public DefaultModelBuilder setBuildPomXMLFilterFactory( BuildPomXMLFilterFactory this.buildPomXMLFilterFactory = () -> buildPomXMLFilterFactory; return this; } + + public void setModelCacheManager( ModelCacheManager modelCacheManager ) + { + this.modelCacheManager = modelCacheManager; + } @SuppressWarnings( "checkstyle:methodlength" ) @Override @@ -451,7 +464,7 @@ else if ( !parentIds.add( parentData.getId() ) ) result.setEffectiveModel( resultModel ); - if ( modelCacheManager != null && request.getPomFile() != null ) + if ( request.getPomFile() != null ) { modelCacheManager.put( request.getPomFile().toPath(), resultModel ); } @@ -664,27 +677,33 @@ private Model readModel( ModelSource modelSource, File pomFile, ModelBuildingReq modelValidator.validateFileModel( model, request, problems ); request.setFileModel( model ); - modelValidator.validateRawModel( model, request, problems ); - - if ( hasFatalErrors( problems ) ) - { - throw problems.newModelBuildingException(); - } - - if ( !hasModelErrors( problems ) && Features.buildConsumer().isActive() && pomFile != null ) + if ( Features.buildConsumer().isActive() && pomFile != null ) { try { - model = modelProcessor.read( transformData( pomFile.toPath() ), null ); + Model rawModel = modelProcessor.read( transformData( pomFile.toPath() ), null ); model.setPomFile( pomFile ); + + // model with locationTrackers, required for proper feedback during validations + model = request.getFileModel().clone(); + + // Apply enriched data + modelMerger.merge( model, rawModel, false, null ); } catch ( IOException | TransformerException | SAXException | ParserConfigurationException e ) { - problems.add( new ModelProblemCollectorRequest( Severity.FATAL, Version.V37 ).setException( e ) ); + problems.add( new ModelProblemCollectorRequest( Severity.WARNING, Version.V37 ).setException( e ) ); } } + modelValidator.validateRawModel( model, request, problems ); + + if ( hasFatalErrors( problems ) ) + { + throw problems.newModelBuildingException(); + } + return model; } @@ -1537,4 +1556,155 @@ protected boolean hasFatalErrors( ModelProblemCollectorExt problems ) } } + /** + * As long is Maven controls the BuildPomXMLFilter, the entities that need merging is known. + * All others can simply be copied from source to target to restore the locationTracker + * + * @author Robert Scholte + * @since 3.7.0 + */ + class FileToRawModelMerger extends ModelMerger + { + @Override + protected void mergeBuild_Extensions( Build target, Build source, boolean sourceDominant, + Map context ) + { + // don't merge + } + + + @Override + protected void mergeBuildBase_Resources( BuildBase target, BuildBase source, boolean sourceDominant, + Map context ) + { + // don't merge + } + + @Override + protected void mergeBuildBase_TestResources( BuildBase target, BuildBase source, boolean sourceDominant, + Map context ) + { + // don't merge + } + + @Override + protected void mergeCiManagement_Notifiers( CiManagement target, CiManagement source, boolean sourceDominant, + Map context ) + { + // don't merge + } + + @Override + protected void mergeDependencyManagement_Dependencies( DependencyManagement target, DependencyManagement source, + boolean sourceDominant, Map context ) + { + Iterator sourceIterator = source.getDependencies().iterator(); + target.getDependencies().stream().forEach( t -> mergeDependency( t, sourceIterator.next(), sourceDominant, + context ) ); + } + + @Override + protected void mergeDependency_Exclusions( Dependency target, Dependency source, boolean sourceDominant, + Map context ) + { + // don't merge + } + + @Override + protected void mergeModel_Contributors( Model target, Model source, boolean sourceDominant, + Map context ) + { + // don't merge + } + + @Override + protected void mergeModel_Developers( Model target, Model source, boolean sourceDominant, + Map context ) + { + // don't merge + } + + @Override + protected void mergeModel_Licenses( Model target, Model source, boolean sourceDominant, + Map context ) + { + // don't merge + } + + @Override + protected void mergeModel_MailingLists( Model target, Model source, boolean sourceDominant, + Map context ) + { + // don't merge + } + + @Override + protected void mergeModel_Profiles( Model target, Model source, boolean sourceDominant, + Map context ) + { + Iterator sourceIterator = source.getProfiles().iterator(); + target.getProfiles().stream().forEach( t -> mergeProfile( t, sourceIterator.next(), sourceDominant, + context ) ); + } + + @Override + protected void mergeModelBase_Dependencies( ModelBase target, ModelBase source, boolean sourceDominant, + Map context ) + { + Iterator sourceIterator = source.getDependencies().iterator(); + target.getDependencies().stream().forEach( t -> mergeDependency( t, sourceIterator.next(), sourceDominant, + context ) ); + } + + @Override + protected void mergeModelBase_PluginRepositories( ModelBase target, ModelBase source, boolean sourceDominant, + Map context ) + { + target.setPluginRepositories( source.getPluginRepositories() ); + } + + @Override + protected void mergeModelBase_Repositories( ModelBase target, ModelBase source, boolean sourceDominant, + Map context ) + { + // don't merge + } + + @Override + protected void mergePlugin_Dependencies( Plugin target, Plugin source, boolean sourceDominant, + Map context ) + { + Iterator sourceIterator = source.getDependencies().iterator(); + target.getDependencies().stream().forEach( t -> mergeDependency( t, sourceIterator.next(), sourceDominant, + context ) ); + } + + @Override + protected void mergePlugin_Executions( Plugin target, Plugin source, boolean sourceDominant, + Map context ) + { + // don't merge + } + + @Override + protected void mergeReporting_Plugins( Reporting target, Reporting source, boolean sourceDominant, + Map context ) + { + // don't merge + } + + @Override + protected void mergeReportPlugin_ReportSets( ReportPlugin target, ReportPlugin source, boolean sourceDominant, + Map context ) + { + // don't merge + } + + @Override + protected void mergePluginContainer_Plugins( PluginContainer target, PluginContainer source, + boolean sourceDominant, Map context ) + { + // don't merge + } + } } 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 cd499ebc49d1..82cd7138877a 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 @@ -227,6 +227,7 @@ public DefaultModelBuilder newInstance() modelBuilder.setReportConfigurationExpander( newReportConfigurationExpander() ); modelBuilder.setReportingConverter( newReportingConverter() ); modelBuilder.setBuildPomXMLFilterFactory( new BuildPomXMLFilterFactory() ); + modelBuilder.setModelCacheManager( new DefaultModelCacheManager() ); return modelBuilder; } diff --git a/maven-model-builder/src/main/java/org/apache/maven/model/validation/DefaultModelValidator.java b/maven-model-builder/src/main/java/org/apache/maven/model/validation/DefaultModelValidator.java index 1280a48ab53f..f789333fe7c6 100644 --- a/maven-model-builder/src/main/java/org/apache/maven/model/validation/DefaultModelValidator.java +++ b/maven-model-builder/src/main/java/org/apache/maven/model/validation/DefaultModelValidator.java @@ -19,7 +19,6 @@ * under the License. */ -import org.apache.maven.feature.Features; import org.apache.maven.model.Activation; import org.apache.maven.model.ActivationFile; import org.apache.maven.model.Build; @@ -118,6 +117,17 @@ public void validateFileModel( Model m, ModelBuildingRequest request, ModelProbl if ( request.getValidationLevel() >= ModelBuildingRequest.VALIDATION_LEVEL_MAVEN_2_0 ) { + Set modules = new HashSet<>(); + for ( int i = 0, n = m.getModules().size(); i < n; i++ ) + { + String module = m.getModules().get( i ); + if ( !modules.add( module ) ) + { + addViolation( problems, Severity.ERROR, Version.V20, "modules.module[" + i + "]", null, + "specifies duplicate child module " + module, m.getLocation( "modules" ) ); + } + } + Severity errOn30 = getSeverity( request, ModelBuildingRequest.VALIDATION_LEVEL_MAVEN_3_0 ); // [MNG-6074] Maven should produce an error if no model version has been set in a POM file used to build an @@ -227,18 +237,8 @@ public void validateRawModel( Model m, ModelBuildingRequest request, ModelProble if ( parent != null ) { - InputLocationTracker locationTracker; - if ( Features.buildConsumer().isActive() ) - { - locationTracker = request.getFileModel().getParent(); - } - else - { - locationTracker = parent; - } - validateStringNotEmpty( "parent.version", problems, Severity.FATAL, Version.BASE, parent.getVersion(), - locationTracker ); + parent ); } } @@ -396,17 +396,6 @@ public void validateEffectiveModel( Model m, ModelBuildingRequest request, Model if ( request.getValidationLevel() >= ModelBuildingRequest.VALIDATION_LEVEL_MAVEN_2_0 ) { - Set modules = new HashSet<>(); - for ( int i = 0, n = m.getModules().size(); i < n; i++ ) - { - String module = m.getModules().get( i ); - if ( !modules.add( module ) ) - { - addViolation( problems, Severity.ERROR, Version.V20, "modules.module[" + i + "]", null, - "specifies duplicate child module " + module, m.getLocation( "modules" ) ); - } - } - Severity errOn31 = getSeverity( request, ModelBuildingRequest.VALIDATION_LEVEL_MAVEN_3_1 ); validateBannedCharacters( EMPTY, "version", problems, errOn31, Version.V20, m.getVersion(), null, m, diff --git a/maven-model-builder/src/test/java/org/apache/maven/model/building/FileToRawModelMergerTest.java b/maven-model-builder/src/test/java/org/apache/maven/model/building/FileToRawModelMergerTest.java new file mode 100644 index 000000000000..485dc4c83da7 --- /dev/null +++ b/maven-model-builder/src/test/java/org/apache/maven/model/building/FileToRawModelMergerTest.java @@ -0,0 +1,82 @@ +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 static org.hamcrest.Matchers.hasItems; +import static org.junit.Assert.assertThat; + +import java.lang.reflect.Method; +import java.lang.reflect.ParameterizedType; +import java.lang.reflect.Type; +import java.util.List; +import java.util.stream.Collectors; +import java.util.stream.Stream; + +import org.apache.maven.model.building.DefaultModelBuilder.FileToRawModelMerger; +import org.apache.maven.model.merge.ModelMerger; +import org.junit.Test; + +public class FileToRawModelMergerTest +{ + + /** + * Ensures that all list-merge methods are overridden + */ + @Test + public void testOverriddenMergeMethods() + { + List methodNames = + Stream.of( ModelMerger.class.getDeclaredMethods() ) + .filter( m -> m.getName().startsWith( "merge" ) ) + .filter( m -> + { + String baseName = m.getName().substring( 5 /* merge */ ); + String entity = baseName.substring( baseName.indexOf( '_' ) + 1 ); + try + { + Type returnType = m.getParameterTypes()[0].getMethod( "get" + entity ).getGenericReturnType(); + if ( returnType instanceof ParameterizedType ) + { + return !( (ParameterizedType) returnType ).getActualTypeArguments()[0].equals( String.class ); + } + else + { + return false; + } + } + catch ( ReflectiveOperationException | SecurityException e ) + { + return false; + } + } ) + .map( Method::getName ) + .collect( Collectors.toList() ); + + List overriddenMethods = + Stream.of( FileToRawModelMerger.class.getDeclaredMethods() ) + .map( Method::getName ) + .filter( m -> m.startsWith( "merge" ) ) + .collect( Collectors.toList() ); + + assertThat( overriddenMethods, hasItems( methodNames.toArray( new String[0] ) ) ); + } + + +} 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 b90fcc6a7131..d2a9e600db4d 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 @@ -376,7 +376,7 @@ public void testBadDependencyVersion() public void testDuplicateModule() throws Exception { - SimpleProblemCollector result = validate( "duplicate-module.xml" ); + SimpleProblemCollector result = validateRaw( "duplicate-module.xml" ); assertViolations( result, 0, 1, 0 ); From 3294a6b44f2b3d0b87a611fbaf82136ecd7b97eb Mon Sep 17 00:00:00 2001 From: rfscholte Date: Sat, 22 Feb 2020 16:55:35 +0100 Subject: [PATCH 28/52] [MNG-6656] Introduce ModelSourceTransformer --- .../maven/project/DefaultProjectBuilder.java | 9 +- .../maven/project/ProjectModelResolver.java | 6 +- .../maven/project/ReactorModelPool.java | 96 ++++++++++----- .../model/building/DefaultModelBuilder.java | 88 +------------- .../building/DefaultModelBuilderFactory.java | 6 + .../model/building/DefaultModelProcessor.java | 19 +++ .../DefaultModelSourceTransformer.java | 109 ++++++++++++++++++ .../maven/model/building/ModelProcessor.java | 19 +++ .../building/ModelSourceTransformer.java | 42 +++++++ 9 files changed, 274 insertions(+), 120 deletions(-) create mode 100644 maven-model-builder/src/main/java/org/apache/maven/model/building/DefaultModelSourceTransformer.java create mode 100644 maven-model-builder/src/main/java/org/apache/maven/model/building/ModelSourceTransformer.java 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 c5bf26cd2946..237ba04d96f6 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 List build( List pomFiles, boolean recursive List 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 List build( List pomFiles, boolean recursive 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 @@ static class InterimResult } - private void populateReactorModelPool( ReactorModelPool reactorModelPool, List interimResults ) + private void populateReactorModelPool( ReactorModelPool.Builder reactorModelPool, List 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 24b36dda310d..e927f775ae53 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.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 ModelSource resolveModel( String groupId, String artifactId, String versi 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 64b30dd90581..048a091f7921 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 @@ * 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> modelsByGa = new HashMap<>(); + + private final Map 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 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() ).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 @@ public boolean equals( Object obj ) 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 @@ public int hashCode() 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 98d27035a512..c635d05dca62 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 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.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.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 @@ private Model readModel( ModelSource modelSource, File pomFile, ModelBuildingReq { try { - Model rawModel = modelProcessor.read( transformData( pomFile.toPath() ), null ); + Model rawModel = modelProcessor.read( pomFile.toPath(), buildPomXMLFilterFactory.get() ); model.setPomFile( pomFile ); @@ -894,81 +883,6 @@ private void assembleInheritance( List lineage, ModelBuildingRequest 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 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 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 82cd7138877a..f84cc0d30d96 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 @@ protected ModelProcessor newModelProcessor() DefaultModelProcessor processor = new DefaultModelProcessor(); processor.setModelLocator( newModelLocator() ); processor.setModelReader( newModelReader() ); + processor.setTransformer( newTransformer() ); return processor; } @@ -200,6 +201,11 @@ protected ReportingConverter newReportingConverter() 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 76370ac4e42d..d87609b24061 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.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 DefaultModelProcessor setModelReader( ModelReader reader ) 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 Model read( InputStream input, Map options ) 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 000000000000..617108967f76 --- /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 c2c2ec061ab0..2adb2c03a00a 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 @@ 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/ModelSourceTransformer.java b/maven-model-builder/src/main/java/org/apache/maven/model/building/ModelSourceTransformer.java new file mode 100644 index 000000000000..5ee325239e62 --- /dev/null +++ b/maven-model-builder/src/main/java/org/apache/maven/model/building/ModelSourceTransformer.java @@ -0,0 +1,42 @@ +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.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; + +/** + * + * @author Robert Scholte + * @since 3.7.0 + */ +public interface ModelSourceTransformer +{ + + InputStream transform( Path pomFile, BuildPomXMLFilterFactory buildPomXMLFilterFactory ) throws IOException, TransformerConfigurationException, SAXException, ParserConfigurationException; + +} From 95b5b58100716d7a82d94a0f67eb935a78127a5a Mon Sep 17 00:00:00 2001 From: rfscholte Date: Mon, 24 Feb 2020 22:57:44 +0100 Subject: [PATCH 29/52] [MNG-6656] Refactor code, make sure it still works with non-xml poms --- ...DefaultRepositorySystemSessionFactory.java | 154 -------------- .../maven/project/DefaultProjectBuilder.java | 190 +++++++++++++++++- .../DefaultConsumerPomXMLFilterFactory.java | 10 +- .../DefaultBuildPomXMLFilterFactory.java | 36 ++-- .../model/building/DefaultModelBuilder.java | 5 +- .../building/DefaultModelBuilderFactory.java | 8 - .../building/DefaultModelBuildingRequest.java | 15 ++ .../model/building/DefaultModelProcessor.java | 20 -- .../DefaultModelSourceTransformer.java | 3 +- .../building/FilterModelBuildingRequest.java | 13 ++ .../model/building/ModelBuildingRequest.java | 4 + .../maven/model/building/ModelProcessor.java | 19 -- .../building/ModelSourceTransformer.java | 5 +- .../model/building/TransformerContext.java | 38 ++++ .../maven/model/io/DefaultModelReader.java | 7 + maven-xml/pom.xml | 26 --- .../sax/filter/BuildPomXMLFilterFactory.java | 11 +- .../filter/ConsumerPomXMLFilterFactory.java | 16 +- .../filter/ReactorDependencyXMLFilter.java | 10 +- .../sax/filter/ConsumerPomXMLFilterTest.java | 22 +- .../ReactorDependencyXMLFilterTest.java | 8 +- 21 files changed, 311 insertions(+), 309 deletions(-) rename {maven-core/src/main/java/org/apache/maven/xml/internal => maven-model-builder/src/main/java/org/apache/maven/model/building}/DefaultBuildPomXMLFilterFactory.java (70%) create mode 100644 maven-model-builder/src/main/java/org/apache/maven/model/building/TransformerContext.java diff --git a/maven-core/src/main/java/org/apache/maven/internal/aether/DefaultRepositorySystemSessionFactory.java b/maven-core/src/main/java/org/apache/maven/internal/aether/DefaultRepositorySystemSessionFactory.java index 77581d6068b2..e89b39ee4338 100644 --- a/maven-core/src/main/java/org/apache/maven/internal/aether/DefaultRepositorySystemSessionFactory.java +++ b/maven-core/src/main/java/org/apache/maven/internal/aether/DefaultRepositorySystemSessionFactory.java @@ -19,46 +19,21 @@ * under the License. */ -import java.io.File; -import java.io.FileInputStream; -import java.io.FileNotFoundException; import java.io.IOException; import java.io.InputStream; -import java.io.PipedInputStream; -import java.io.PipedOutputStream; -import java.util.ArrayList; -import java.util.Collection; -import java.util.Collections; import java.util.LinkedHashMap; import java.util.Map; import java.util.Properties; -import java.util.concurrent.ExecutorService; -import java.util.concurrent.Executors; import javax.inject.Inject; import javax.inject.Named; import javax.inject.Provider; -import javax.xml.parsers.ParserConfigurationException; -import javax.xml.stream.FactoryConfigurationError; -import javax.xml.stream.XMLInputFactory; -import javax.xml.stream.XMLStreamException; -import javax.xml.stream.XMLStreamReader; -import javax.xml.transform.OutputKeys; -import javax.xml.transform.Transformer; -import javax.xml.transform.TransformerConfigurationException; -import javax.xml.transform.TransformerException; -import javax.xml.transform.sax.SAXResult; -import javax.xml.transform.sax.SAXSource; -import javax.xml.transform.sax.SAXTransformerFactory; -import javax.xml.transform.sax.TransformerHandler; -import javax.xml.transform.stream.StreamResult; import org.apache.maven.RepositoryUtils; import org.apache.maven.artifact.handler.manager.ArtifactHandlerManager; import org.apache.maven.bridge.MavenRepositorySystem; import org.apache.maven.eventspy.internal.EventSpyDispatcher; import org.apache.maven.execution.MavenExecutionRequest; -import org.apache.maven.feature.Features; import org.apache.maven.repository.internal.MavenRepositorySystemUtils; import org.apache.maven.settings.Mirror; import org.apache.maven.settings.Proxy; @@ -67,8 +42,6 @@ import org.apache.maven.settings.crypto.DefaultSettingsDecryptionRequest; import org.apache.maven.settings.crypto.SettingsDecrypter; import org.apache.maven.settings.crypto.SettingsDecryptionResult; -import org.apache.maven.xml.Factories; -import org.apache.maven.xml.sax.filter.AbstractSAXFilter; import org.apache.maven.xml.sax.filter.ConsumerPomXMLFilterFactory; import org.codehaus.plexus.configuration.xml.XmlPlexusConfiguration; import org.codehaus.plexus.logging.Logger; @@ -76,24 +49,18 @@ import org.eclipse.aether.ConfigurationProperties; import org.eclipse.aether.DefaultRepositorySystemSession; import org.eclipse.aether.RepositorySystem; -import org.eclipse.aether.artifact.Artifact; import org.eclipse.aether.repository.LocalRepository; import org.eclipse.aether.repository.NoLocalRepositoryManagerException; import org.eclipse.aether.repository.RepositoryPolicy; import org.eclipse.aether.repository.WorkspaceReader; import org.eclipse.aether.resolution.ResolutionErrorPolicy; import org.eclipse.aether.spi.localrepo.LocalRepositoryManagerFactory; -import org.eclipse.aether.transform.FileTransformer; -import org.eclipse.aether.transform.FileTransformerManager; -import org.eclipse.aether.transform.TransformException; import org.eclipse.aether.util.repository.AuthenticationBuilder; import org.eclipse.aether.util.repository.DefaultAuthenticationSelector; import org.eclipse.aether.util.repository.DefaultMirrorSelector; import org.eclipse.aether.util.repository.DefaultProxySelector; import org.eclipse.aether.util.repository.SimpleResolutionErrorPolicy; import org.eclipse.sisu.Nullable; -import org.xml.sax.InputSource; -import org.xml.sax.SAXException; /** * @since 3.3.0 @@ -278,129 +245,8 @@ else if ( request.isUpdateSnapshots() ) mavenRepositorySystem.injectProxy( session, request.getPluginArtifactRepositories() ); mavenRepositorySystem.injectAuthentication( session, request.getPluginArtifactRepositories() ); - if ( Features.buildConsumer().isActive() ) - { - session.setFileTransformerManager( newFileTransformerManager() ); - } return session; } - - private FileTransformerManager newFileTransformerManager() - { - return new FileTransformerManager() - { - @Override - public Collection getTransformersForArtifact( final Artifact artifact ) - { - Collection transformers = new ArrayList<>(); - if ( "pom".equals( artifact.getExtension() ) ) - { - final SAXTransformerFactory transformerFactory = - (SAXTransformerFactory) Factories.newTransformerFactory(); - - transformers.add( new FileTransformer() - { - @Override - public InputStream transformData( File file ) - throws IOException, TransformException - { - final PipedOutputStream pipedOutputStream = new PipedOutputStream(); - final PipedInputStream pipedInputStream = new PipedInputStream( pipedOutputStream ); - - final TransformerHandler transformerHandler = - getTransformerHandler( transformerFactory, file ); - - final SAXSource transformSource; - try - { - AbstractSAXFilter filter = consumerPomXMLFilterFactory.get().get( file.toPath() ); - filter.setLexicalHandler( transformerHandler ); - - transformSource = - new SAXSource( filter, new InputSource( new FileInputStream( file ) ) ); - } - catch ( SAXException | ParserConfigurationException | TransformerConfigurationException e ) - { - throw new TransformException( "Failed to create a consumerPomXMLFilter", e ); - } - - transformerHandler.setResult( new StreamResult( pipedOutputStream ) ); - - SAXResult transformResult = new SAXResult( transformerHandler ); - - ExecutorService executorService = Executors.newSingleThreadExecutor(); - executorService.execute( () -> - { - try ( PipedOutputStream out = pipedOutputStream ) - { - transformerFactory.newTransformer().transform( transformSource, transformResult ); - } - catch ( TransformerException | IOException e ) - { - throw new RuntimeException( e ); - } - } ); - - return pipedInputStream; - } - - @Override - public Artifact transformArtifact( Artifact artifact ) - { - return artifact; - } - } ); - } - return Collections.unmodifiableCollection( transformers ); - } - }; - } - - private static TransformerHandler getTransformerHandler( SAXTransformerFactory transformerFactory, - File file ) - throws IOException, FileNotFoundException, TransformException - { - final TransformerHandler transformerHandler; - - // Keep same encoding+version - try ( FileInputStream input = new FileInputStream( file ) ) - { - XMLStreamReader streamReader = - XMLInputFactory.newFactory().createXMLStreamReader( input ); - - transformerHandler = transformerFactory.newTransformerHandler(); - - final String encoding = streamReader.getCharacterEncodingScheme(); - final String version = streamReader.getVersion(); - - Transformer transformer = transformerHandler.getTransformer(); - if ( encoding == null && version == null ) - { - transformer.setOutputProperty( OutputKeys.OMIT_XML_DECLARATION, "yes" ); - } - else - { - transformer.setOutputProperty( OutputKeys.OMIT_XML_DECLARATION, "no" ); - - if ( encoding != null ) - { - transformer.setOutputProperty( OutputKeys.ENCODING, encoding ); - } - if ( version != null ) - { - transformer.setOutputProperty( OutputKeys.VERSION, version ); - } - } - } - catch ( XMLStreamException - | FactoryConfigurationError - | TransformerConfigurationException e ) - { - throw new TransformException( "Failed to detect XML encoding and version", e ); - } - return transformerHandler; - } - private String getUserAgent() { 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 237ba04d96f6..68bab45e76f0 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 @@ -20,7 +20,13 @@ */ import java.io.File; +import java.io.FileInputStream; +import java.io.FileNotFoundException; import java.io.IOException; +import java.io.InputStream; +import java.io.PipedInputStream; +import java.io.PipedOutputStream; +import java.nio.file.Path; import java.util.AbstractMap; import java.util.ArrayList; import java.util.Arrays; @@ -32,6 +38,23 @@ import java.util.List; import java.util.Map; import java.util.Set; +import java.util.concurrent.ExecutorService; +import java.util.concurrent.Executors; + +import javax.xml.parsers.FactoryConfigurationError; +import javax.xml.parsers.ParserConfigurationException; +import javax.xml.stream.XMLInputFactory; +import javax.xml.stream.XMLStreamException; +import javax.xml.stream.XMLStreamReader; +import javax.xml.transform.OutputKeys; +import javax.xml.transform.Transformer; +import javax.xml.transform.TransformerConfigurationException; +import javax.xml.transform.TransformerException; +import javax.xml.transform.sax.SAXResult; +import javax.xml.transform.sax.SAXSource; +import javax.xml.transform.sax.SAXTransformerFactory; +import javax.xml.transform.sax.TransformerHandler; +import javax.xml.transform.stream.StreamResult; import org.apache.maven.RepositoryUtils; import org.apache.maven.artifact.Artifact; @@ -40,6 +63,7 @@ import org.apache.maven.artifact.repository.ArtifactRepository; import org.apache.maven.artifact.repository.LegacyLocalRepositoryManager; import org.apache.maven.bridge.MavenRepositorySystem; +import org.apache.maven.feature.Features; import org.apache.maven.model.Build; import org.apache.maven.model.Dependency; import org.apache.maven.model.DependencyManagement; @@ -49,6 +73,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.DefaultBuildPomXMLFilterFactory; import org.apache.maven.model.building.DefaultModelBuildingRequest; import org.apache.maven.model.building.DefaultModelProblem; import org.apache.maven.model.building.FileModelSource; @@ -60,13 +85,19 @@ import org.apache.maven.model.building.ModelProcessor; import org.apache.maven.model.building.ModelSource; import org.apache.maven.model.building.StringModelSource; +import org.apache.maven.model.building.TransformerContext; import org.apache.maven.model.resolution.ModelResolver; import org.apache.maven.repository.internal.ArtifactDescriptorUtils; +import org.apache.maven.xml.Factories; +import org.apache.maven.xml.sax.filter.AbstractSAXFilter; +import org.apache.maven.xml.sax.filter.BuildPomXMLFilterFactory; +import org.apache.maven.xml.sax.filter.ConsumerPomXMLFilterFactory; import org.codehaus.plexus.component.annotations.Component; import org.codehaus.plexus.component.annotations.Requirement; import org.codehaus.plexus.logging.Logger; import org.codehaus.plexus.util.Os; import org.codehaus.plexus.util.StringUtils; +import org.eclipse.aether.DefaultRepositorySystemSession; import org.eclipse.aether.RepositorySystemSession; import org.eclipse.aether.RequestTrace; import org.eclipse.aether.impl.RemoteRepositoryManager; @@ -75,6 +106,10 @@ import org.eclipse.aether.repository.WorkspaceRepository; import org.eclipse.aether.resolution.ArtifactRequest; import org.eclipse.aether.resolution.ArtifactResult; +import org.eclipse.aether.transform.FileTransformer; +import org.eclipse.aether.transform.TransformException; +import org.xml.sax.InputSource; +import org.xml.sax.SAXException; /** * DefaultProjectBuilder @@ -154,7 +189,7 @@ private ProjectBuildingResult build( File pomFile, ModelSource modelSource, Inte if ( project == null ) { - ModelBuildingRequest request = getModelBuildingRequest( config ); + ModelBuildingRequest request = getModelBuildingRequest( config, pomFile ); project = new MavenProject(); project.setFile( pomFile ); @@ -266,7 +301,7 @@ private List getProfileIds( List profiles ) return ids; } - private ModelBuildingRequest getModelBuildingRequest( InternalConfig config ) + private ModelBuildingRequest getModelBuildingRequest( InternalConfig config, File pomFile ) { ProjectBuildingRequest configuration = config.request; @@ -274,8 +309,41 @@ private ModelBuildingRequest getModelBuildingRequest( InternalConfig config ) RequestTrace trace = RequestTrace.newChild( null, configuration ).newChild( request ); + RepositorySystemSession repoSession; + if ( Features.buildConsumer().isActive() ) + { + TransformerContext context = new TransformerContext() + { + @Override + public String getUserProperty( String key ) + { + return config.session.getUserProperties().get( key ); + } + + @Override + public Model getRawModel( Path p ) + { + return config.modelPool.get( p ); + } + + @Override + public Model getRawModel( String groupId, String artifactId ) + { + return config.modelPool.get( groupId, artifactId, null ); + } + }; + request.setTransformerContext( context ); + + repoSession = new DefaultRepositorySystemSession( config.session ) + .setFileTransformerManager( a -> getTransformersForArtifact( a, context ) ); + } + else + { + repoSession = config.session; + } + ModelResolver resolver = - new ProjectModelResolver( config.session, trace, repoSystem, repositoryManager, config.repositories, + new ProjectModelResolver( repoSession, trace, repoSystem, repositoryManager, config.repositories, configuration.getRepositoryMerging(), config.modelPool ); request.setValidationLevel( configuration.getValidationLevel() ); @@ -430,7 +498,7 @@ private boolean build( List results, List { boolean noErrors = true; - ModelBuildingRequest request = getModelBuildingRequest( config ); + ModelBuildingRequest request = getModelBuildingRequest( config, pomFile ); MavenProject project = new MavenProject(); project.setFile( pomFile ); @@ -1044,6 +1112,120 @@ private String findProfilesXml( ModelBuildingResult result, Map p return null; } + + private Collection getTransformersForArtifact( final org.eclipse.aether.artifact.Artifact artifact, + TransformerContext context ) + { + Collection transformers = new ArrayList<>(); + if ( "pom".equals( artifact.getExtension() ) ) + { + final SAXTransformerFactory transformerFactory = + (SAXTransformerFactory) Factories.newTransformerFactory(); + + transformers.add( new FileTransformer() + { + @Override + public InputStream transformData( File file ) + throws IOException, TransformException + { + final PipedOutputStream pipedOutputStream = new PipedOutputStream(); + final PipedInputStream pipedInputStream = new PipedInputStream( pipedOutputStream ); + + final TransformerHandler transformerHandler = + getTransformerHandler( transformerFactory, file ); + + BuildPomXMLFilterFactory buildPomXmlFactory = new DefaultBuildPomXMLFilterFactory( context ); + + final SAXSource transformSource; + try + { + AbstractSAXFilter filter = + new ConsumerPomXMLFilterFactory( buildPomXmlFactory ).get( file.toPath() ); + filter.setLexicalHandler( transformerHandler ); + + transformSource = + new SAXSource( filter, new InputSource( new FileInputStream( file ) ) ); + } + catch ( SAXException | ParserConfigurationException | TransformerConfigurationException e ) + { + throw new TransformException( "Failed to create a consumerPomXMLFilter", e ); + } + + transformerHandler.setResult( new StreamResult( pipedOutputStream ) ); + + SAXResult transformResult = new SAXResult( transformerHandler ); + + ExecutorService executorService = Executors.newSingleThreadExecutor(); + executorService.execute( () -> + { + try ( PipedOutputStream out = pipedOutputStream ) + { + transformerFactory.newTransformer().transform( transformSource, transformResult ); + } + catch ( TransformerException | IOException e ) + { + throw new RuntimeException( e ); + } + } ); + + return pipedInputStream; + } + + @Override + public org.eclipse.aether.artifact.Artifact transformArtifact( + org.eclipse.aether.artifact.Artifact artifact ) + { + return artifact; + } + } ); + } + return Collections.unmodifiableCollection( transformers ); + } + + private static TransformerHandler getTransformerHandler( SAXTransformerFactory transformerFactory, + File file ) + throws IOException, FileNotFoundException, TransformException + { + final TransformerHandler transformerHandler; + + // Keep same encoding+version + try ( FileInputStream input = new FileInputStream( file ) ) + { + XMLStreamReader streamReader = + XMLInputFactory.newFactory().createXMLStreamReader( input ); + + transformerHandler = transformerFactory.newTransformerHandler(); + + final String encoding = streamReader.getCharacterEncodingScheme(); + final String version = streamReader.getVersion(); + + Transformer transformer = transformerHandler.getTransformer(); + if ( encoding == null && version == null ) + { + transformer.setOutputProperty( OutputKeys.OMIT_XML_DECLARATION, "yes" ); + } + else + { + transformer.setOutputProperty( OutputKeys.OMIT_XML_DECLARATION, "no" ); + + if ( encoding != null ) + { + transformer.setOutputProperty( OutputKeys.ENCODING, encoding ); + } + if ( version != null ) + { + transformer.setOutputProperty( OutputKeys.VERSION, version ); + } + } + } + catch ( XMLStreamException + | FactoryConfigurationError + | TransformerConfigurationException e ) + { + throw new TransformException( "Failed to detect XML encoding and version", e ); + } + return transformerHandler; + } /** * InternalConfig 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 489019fd6c69..5b13aa5cb497 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 @@ -19,9 +19,7 @@ * under the License. */ -import javax.inject.Named; -import javax.inject.Singleton; - +import org.apache.maven.xml.sax.filter.BuildPomXMLFilterFactory; import org.apache.maven.xml.sax.filter.ConsumerPomXMLFilterFactory; /** @@ -29,9 +27,11 @@ * @author Robert Scholte * @since 3.7.0 */ -@Named -@Singleton public class DefaultConsumerPomXMLFilterFactory extends ConsumerPomXMLFilterFactory { + public DefaultConsumerPomXMLFilterFactory( BuildPomXMLFilterFactory buildPomXMLFilterFactory ) + { + super( buildPomXMLFilterFactory ); + } } diff --git a/maven-core/src/main/java/org/apache/maven/xml/internal/DefaultBuildPomXMLFilterFactory.java b/maven-model-builder/src/main/java/org/apache/maven/model/building/DefaultBuildPomXMLFilterFactory.java similarity index 70% rename from maven-core/src/main/java/org/apache/maven/xml/internal/DefaultBuildPomXMLFilterFactory.java rename to maven-model-builder/src/main/java/org/apache/maven/model/building/DefaultBuildPomXMLFilterFactory.java index d359eb65ea8b..cc7b3b3f3da2 100644 --- a/maven-core/src/main/java/org/apache/maven/xml/internal/DefaultBuildPomXMLFilterFactory.java +++ b/maven-model-builder/src/main/java/org/apache/maven/model/building/DefaultBuildPomXMLFilterFactory.java @@ -1,4 +1,4 @@ -package org.apache.maven.xml.internal; +package org.apache.maven.model.building; /* * Licensed to the Apache Software Foundation (ASF) under one @@ -22,17 +22,11 @@ import java.nio.file.Path; import java.util.Optional; +import java.util.function.BiFunction; import java.util.function.Function; -import javax.inject.Inject; -import javax.inject.Named; -import javax.inject.Singleton; - -import org.apache.maven.execution.MavenSession; import org.apache.maven.model.Model; -import org.apache.maven.model.building.ModelCacheManager; import org.apache.maven.xml.sax.filter.BuildPomXMLFilterFactory; -import org.apache.maven.xml.sax.filter.DependencyKey; import org.apache.maven.xml.sax.filter.RelativeProject; /** @@ -40,49 +34,43 @@ * @author Robert Scholte * @since 3.7.0 */ -@Named -@Singleton public class DefaultBuildPomXMLFilterFactory extends BuildPomXMLFilterFactory { - private MavenSession session; - - @Inject - private ModelCacheManager rawModelCache; + private final TransformerContext context; - @Inject - public DefaultBuildPomXMLFilterFactory( MavenSession session ) + public DefaultBuildPomXMLFilterFactory( TransformerContext context ) { - this.session = session; + this.context = context; } - + @Override protected Optional getChangelist() { - return Optional.ofNullable( session.getUserProperties().getProperty( "changelist" ) ); + return Optional.ofNullable( context.getUserProperty( "changelist" ) ); } @Override protected Optional getRevision() { - return Optional.ofNullable( session.getUserProperties().getProperty( "revision" ) ); + return Optional.ofNullable( context.getUserProperty( "revision" ) ); } @Override protected Optional getSha1() { - return Optional.ofNullable( session.getUserProperties().getProperty( "sha1" ) ); + return Optional.ofNullable( context.getUserProperty( "sha1" ) ); } @Override protected Function> getRelativePathMapper() { - return p -> Optional.ofNullable( rawModelCache.get( p ) ).map( m -> toRelativeProject( m ) ); + return p -> Optional.ofNullable( context.getRawModel( p ) ).map( m -> toRelativeProject( m ) ); } @Override - protected Function getDependencyKeyToVersionMapper() + protected BiFunction getDependencyKeyToVersionMapper() { - return k -> Optional.ofNullable( rawModelCache.get( k ) ) + return (g,a) -> Optional.ofNullable( context.getRawModel( g, a ) ) .map( m -> toVersion( m ) ) .orElse( null ); } 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 c635d05dca62..4e71eb2a908e 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 @@ -27,6 +27,7 @@ import java.io.IOException; import java.util.ArrayList; import java.util.Collection; +import java.util.Collections; import java.util.HashMap; import java.util.Iterator; import java.util.LinkedHashSet; @@ -688,7 +689,7 @@ private Model readModel( ModelSource modelSource, File pomFile, ModelBuildingReq { try { - Model rawModel = modelProcessor.read( pomFile.toPath(), buildPomXMLFilterFactory.get() ); + Model rawModel = modelProcessor.read( pomFile, Collections.singletonMap( "transformerContext", buildPomXMLFilterFactory ) ); model.setPomFile( pomFile ); @@ -698,7 +699,7 @@ private Model readModel( ModelSource modelSource, File pomFile, ModelBuildingReq // Apply enriched data modelMerger.merge( model, rawModel, false, null ); } - catch ( IOException | TransformerException | SAXException | ParserConfigurationException e ) + catch ( IOException e ) { problems.add( new ModelProblemCollectorRequest( Severity.WARNING, Version.V37 ).setException( e ) ); } 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 f84cc0d30d96..cca02410f8b9 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 @@ -64,7 +64,6 @@ import org.apache.maven.model.superpom.SuperPomProvider; import org.apache.maven.model.validation.DefaultModelValidator; import org.apache.maven.model.validation.ModelValidator; -import org.apache.maven.xml.sax.filter.BuildPomXMLFilterFactory; /** * A factory to create model builder instances when no dependency injection is available. Note: This class is @@ -82,7 +81,6 @@ protected ModelProcessor newModelProcessor() DefaultModelProcessor processor = new DefaultModelProcessor(); processor.setModelLocator( newModelLocator() ); processor.setModelReader( newModelReader() ); - processor.setTransformer( newTransformer() ); return processor; } @@ -201,11 +199,6 @@ protected ReportingConverter newReportingConverter() return new DefaultReportingConverter(); } - protected ModelSourceTransformer newTransformer() - { - return new DefaultModelSourceTransformer(); - } - /** * Creates a new model builder instance. * @@ -232,7 +225,6 @@ public DefaultModelBuilder newInstance() modelBuilder.setPluginConfigurationExpander( newPluginConfigurationExpander() ); modelBuilder.setReportConfigurationExpander( newReportConfigurationExpander() ); modelBuilder.setReportingConverter( newReportingConverter() ); - modelBuilder.setBuildPomXMLFilterFactory( new BuildPomXMLFilterFactory() ); modelBuilder.setModelCacheManager( new DefaultModelCacheManager() ); return modelBuilder; 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 3cf3a896ad01..b347eb41bda0 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 @@ -73,6 +73,8 @@ public class DefaultModelBuildingRequest private ModelCache modelCache; private WorkspaceModelResolver workspaceResolver; + + private TransformerContext context; /** * Creates an empty request. @@ -421,4 +423,17 @@ public ModelBuildingRequest setWorkspaceModelResolver( WorkspaceModelResolver wo this.workspaceResolver = workspaceResolver; return this; } + + @Override + public TransformerContext getTransformerContext() + { + return context; + } + + @Override + public ModelBuildingRequest setTransformerContext( TransformerContext context ) + { + this.context = context; + return this; + } } 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 d87609b24061..9dfa8bd5d1bb 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,21 +23,16 @@ 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; /** * @@ -77,9 +72,6 @@ public class DefaultModelProcessor @Inject private ModelReader reader; - @Inject - private ModelSourceTransformer transformer; - public DefaultModelProcessor setModelLocator( ModelLocator locator ) { this.locator = locator; @@ -91,12 +83,6 @@ public DefaultModelProcessor setModelReader( ModelReader reader ) this.reader = reader; return this; } - - public DefaultModelProcessor setTransformer( ModelSourceTransformer transformer ) - { - this.transformer = transformer; - return this; - } @Override public File locatePom( File projectDirectory ) @@ -124,10 +110,4 @@ public Model read( InputStream input, Map options ) { 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 index 617108967f76..daf91ecca094 100644 --- 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 @@ -53,9 +53,10 @@ class DefaultModelSourceTransformer implements ModelSourceTransformer private BuildPomXMLFilterListener xmlFilterListener; @Override - public InputStream transform( Path pomFile, BuildPomXMLFilterFactory buildPomXMLFilterFactory ) + public InputStream transform( Path pomFile, TransformerContext context ) throws IOException, TransformerConfigurationException, SAXException, ParserConfigurationException { + final BuildPomXMLFilterFactory buildPomXMLFilterFactory = new DefaultBuildPomXMLFilterFactory( context ); final TransformerFactory transformerFactory = Factories.newTransformerFactory() ; final PipedOutputStream pipedOutputStream = new PipedOutputStream(); 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 fb38f167232b..1dd2643e1dac 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 @@ -294,4 +294,17 @@ public ModelBuildingRequest setWorkspaceModelResolver( WorkspaceModelResolver wo request.setWorkspaceModelResolver( workspaceResolver ); return this; } + + @Override + public TransformerContext getTransformerContext() + { + return request.getTransformerContext(); + } + + @Override + public ModelBuildingRequest setTransformerContext( TransformerContext context ) + { + request.setTransformerContext( context ); + return this; + } } \ No newline at end of file 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 1e0b3dad60af..0ae969436510 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 @@ -349,4 +349,8 @@ public interface ModelBuildingRequest WorkspaceModelResolver getWorkspaceModelResolver(); ModelBuildingRequest setWorkspaceModelResolver( WorkspaceModelResolver workspaceResolver ); + + TransformerContext getTransformerContext(); + + ModelBuildingRequest setTransformerContext( TransformerContext context ); } 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 2adb2c03a00a..c2c2ec061ab0 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,17 +1,5 @@ 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 @@ -33,8 +21,6 @@ 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 @@ -45,10 +31,5 @@ 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/ModelSourceTransformer.java b/maven-model-builder/src/main/java/org/apache/maven/model/building/ModelSourceTransformer.java index 5ee325239e62..b5050397718e 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 @@ -26,7 +26,6 @@ import javax.xml.parsers.ParserConfigurationException; import javax.xml.transform.TransformerConfigurationException; -import org.apache.maven.xml.sax.filter.BuildPomXMLFilterFactory; import org.xml.sax.SAXException; /** @@ -36,7 +35,5 @@ */ public interface ModelSourceTransformer { - - InputStream transform( Path pomFile, BuildPomXMLFilterFactory buildPomXMLFilterFactory ) throws IOException, TransformerConfigurationException, SAXException, ParserConfigurationException; - + InputStream transform( Path pomFile, TransformerContext context ) throws IOException, TransformerConfigurationException, SAXException, ParserConfigurationException; } 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 new file mode 100644 index 000000000000..cad2d25c54f4 --- /dev/null +++ b/maven-model-builder/src/main/java/org/apache/maven/model/building/TransformerContext.java @@ -0,0 +1,38 @@ +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 org.apache.maven.model.Model; + +/** + * + * @author Robert Scholte + * @since 3.7.0 + */ +public interface TransformerContext +{ + String getUserProperty( String key ); + + Model getRawModel( Path p ); + + Model getRawModel( String groupId, String artifactId ); +} 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 b0778d838e0e..2750ce0b7a96 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 @@ -27,11 +27,13 @@ import java.util.Map; import java.util.Objects; +import javax.inject.Inject; import javax.inject.Named; import javax.inject.Singleton; import org.apache.maven.model.InputSource; import org.apache.maven.model.Model; +import org.apache.maven.model.building.ModelSourceTransformer; import org.apache.maven.model.io.xpp3.MavenXpp3Reader; import org.apache.maven.model.io.xpp3.MavenXpp3ReaderEx; import org.codehaus.plexus.util.ReaderFactory; @@ -48,6 +50,11 @@ public class DefaultModelReader implements ModelReader { + @Inject + private ModelSourceTransformer transformer; + + + @Override public Model read( File input, Map options ) diff --git a/maven-xml/pom.xml b/maven-xml/pom.xml index 454188883102..eb285eb54ce9 100644 --- a/maven-xml/pom.xml +++ b/maven-xml/pom.xml @@ -31,33 +31,7 @@ under the License. maven-xml Maven XML - - 1.8 - 1.8 - - - - - - org.codehaus.mojo - animal-sniffer-maven-plugin - - - org.codehaus.mojo.signature - java18 - 1.0 - - - - - - - - javax.inject - javax.inject - true - org.xmlunit xmlunit-assertj 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 66c5fc942d25..2b8e16ddca6f 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 @@ -21,6 +21,7 @@ import java.nio.file.Path; import java.util.Optional; +import java.util.function.BiFunction; import java.util.function.Function; import javax.xml.parsers.ParserConfigurationException; @@ -43,6 +44,14 @@ */ public class BuildPomXMLFilterFactory { + /** + * + * @param projectFile will be used by ConsumerPomXMLFilter to get the right filter + * @return + * @throws SAXException + * @throws ParserConfigurationException + * @throws TransformerConfigurationException + */ public final BuildPomXMLFilter get( Path projectFile ) throws SAXException, ParserConfigurationException, TransformerConfigurationException { @@ -127,7 +136,7 @@ protected Function> getRelativePathMapper() return null; } - protected Function getDependencyKeyToVersionMapper() + protected BiFunction getDependencyKeyToVersionMapper() { return null; } 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 612ddb9ead91..2b2f542087d1 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 @@ -21,8 +21,6 @@ import java.nio.file.Path; -import javax.inject.Inject; -import javax.inject.Provider; import javax.xml.parsers.ParserConfigurationException; import javax.xml.transform.TransformerConfigurationException; @@ -33,17 +31,11 @@ * @author Robert Scholte * @since 3.7.0 */ -public abstract class ConsumerPomXMLFilterFactory +public class ConsumerPomXMLFilterFactory { - @Inject - private Provider buildPomXMLFilterFactory; + private BuildPomXMLFilterFactory buildPomXMLFilterFactory; - public ConsumerPomXMLFilterFactory() - { - } - - // For testing purpose - ConsumerPomXMLFilterFactory( Provider buildPomXMLFilterFactory ) + public ConsumerPomXMLFilterFactory( BuildPomXMLFilterFactory buildPomXMLFilterFactory ) { this.buildPomXMLFilterFactory = buildPomXMLFilterFactory; } @@ -51,7 +43,7 @@ public ConsumerPomXMLFilterFactory() public final ConsumerPomXMLFilter get( Path projectPath ) throws SAXException, ParserConfigurationException, TransformerConfigurationException { - BuildPomXMLFilter parent = buildPomXMLFilterFactory.get().get( projectPath ); + BuildPomXMLFilter parent = buildPomXMLFilterFactory.get( projectPath ); // Ensure that xs:any elements aren't touched by next filters AbstractSAXFilter filter = new FastForwardFilter( parent ); diff --git a/maven-xml/src/main/java/org/apache/maven/xml/sax/filter/ReactorDependencyXMLFilter.java b/maven-xml/src/main/java/org/apache/maven/xml/sax/filter/ReactorDependencyXMLFilter.java index b37092f6b9e6..6bc26631a78b 100644 --- a/maven-xml/src/main/java/org/apache/maven/xml/sax/filter/ReactorDependencyXMLFilter.java +++ b/maven-xml/src/main/java/org/apache/maven/xml/sax/filter/ReactorDependencyXMLFilter.java @@ -1,5 +1,7 @@ package org.apache.maven.xml.sax.filter; +import java.util.function.BiFunction; + /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file @@ -19,8 +21,6 @@ * under the License. */ -import java.util.function.Function; - import org.apache.maven.xml.sax.SAXEventUtils; import org.xml.sax.Attributes; import org.xml.sax.SAXException; @@ -44,9 +44,9 @@ public class ReactorDependencyXMLFilter extends AbstractEventXMLFilter private String artifactId; - private final Function reactorVersionMapper; + private final BiFunction reactorVersionMapper; - public ReactorDependencyXMLFilter( Function reactorVersionMapper ) + public ReactorDependencyXMLFilter( BiFunction reactorVersionMapper ) { this.reactorVersionMapper = reactorVersionMapper; } @@ -136,7 +136,7 @@ public void endElement( String uri, final String localName, String qName ) private String getVersion() { - return reactorVersionMapper.apply( new DependencyKey( groupId, artifactId ) ); + return reactorVersionMapper.apply( groupId, artifactId ); } @Override 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 50abfc8ff0dd..df1a8801e902 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 @@ -24,18 +24,12 @@ import java.nio.file.Path; import java.nio.file.Paths; import java.util.Optional; +import java.util.function.BiFunction; import java.util.function.Function; -import javax.inject.Provider; import javax.xml.parsers.ParserConfigurationException; import javax.xml.transform.TransformerConfigurationException; -import org.apache.maven.xml.sax.filter.AbstractSAXFilter; -import org.apache.maven.xml.sax.filter.BuildPomXMLFilterFactory; -import org.apache.maven.xml.sax.filter.ConsumerPomXMLFilter; -import org.apache.maven.xml.sax.filter.ConsumerPomXMLFilterFactory; -import org.apache.maven.xml.sax.filter.DependencyKey; -import org.apache.maven.xml.sax.filter.RelativeProject; import org.junit.Test; import org.xml.sax.SAXException; @@ -77,23 +71,13 @@ protected Function> getRelativePathMapper() } @Override - protected Function getDependencyKeyToVersionMapper() + protected BiFunction getDependencyKeyToVersionMapper() { return null; } }; - Provider provider = new Provider() - { - - @Override - public BuildPomXMLFilterFactory get() - { - return buildPomXMLFilterFactory; - } - }; - - ConsumerPomXMLFilter filter = new ConsumerPomXMLFilterFactory( provider ) + ConsumerPomXMLFilter filter = new ConsumerPomXMLFilterFactory( buildPomXMLFilterFactory ) { }.get( Paths.get( "pom.xml" ) ); filter.setFeature( "http://xml.org/sax/features/namespaces", true ); diff --git a/maven-xml/src/test/java/org/apache/maven/xml/sax/filter/ReactorDependencyXMLFilterTest.java b/maven-xml/src/test/java/org/apache/maven/xml/sax/filter/ReactorDependencyXMLFilterTest.java index 43679820700b..db6606cb6a68 100644 --- a/maven-xml/src/test/java/org/apache/maven/xml/sax/filter/ReactorDependencyXMLFilterTest.java +++ b/maven-xml/src/test/java/org/apache/maven/xml/sax/filter/ReactorDependencyXMLFilterTest.java @@ -18,13 +18,11 @@ * specific language governing permissions and limitations * under the License. */ - -import static org.xmlunit.assertj.XmlAssert.*; +import static org.xmlunit.assertj.XmlAssert.assertThat; import javax.xml.parsers.ParserConfigurationException; import javax.xml.transform.TransformerException; -import org.apache.maven.xml.sax.filter.ReactorDependencyXMLFilter; import org.junit.Test; import org.xml.sax.SAXException; @@ -34,7 +32,7 @@ public class ReactorDependencyXMLFilterTest extends AbstractXMLFilterTests protected ReactorDependencyXMLFilter getFilter() throws TransformerException, SAXException, ParserConfigurationException { - return new ReactorDependencyXMLFilter( r -> "1.0.0" ); + return new ReactorDependencyXMLFilter( (g, a) -> "1.0.0" ); } @Test @@ -55,7 +53,7 @@ public void testDefaultDependency() throws Exception @Test public void testManagedDependency() throws Exception { - ReactorDependencyXMLFilter filter = new ReactorDependencyXMLFilter( r -> null ); + ReactorDependencyXMLFilter filter = new ReactorDependencyXMLFilter( (g, a) -> null ); String input = "" + "GROUPID" From 0a8d8e655be77065171643e66927a24d306e08ea Mon Sep 17 00:00:00 2001 From: rfscholte Date: Mon, 24 Feb 2020 23:40:05 +0100 Subject: [PATCH 30/52] [MNG-6656] Fix checkstyle errors --- .../org/apache/maven/project/DefaultProjectBuilder.java | 3 ++- .../java/org/apache/maven/project/ReactorModelPool.java | 6 ++++-- .../org/apache/maven/project/PomConstructionTest.java | 4 ---- .../model/building/DefaultBuildPomXMLFilterFactory.java | 2 +- .../apache/maven/model/building/DefaultModelBuilder.java | 9 +++------ .../maven/model/building/ModelSourceTransformer.java | 3 ++- .../maven/xml/sax/filter/ReactorDependencyXMLFilter.java | 4 ++-- 7 files changed, 14 insertions(+), 17 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 68bab45e76f0..53ecfb782e27 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 @@ -661,7 +661,8 @@ static class InterimResult } - private void populateReactorModelPool( ReactorModelPool.Builder reactorModelPool, List interimResults ) + private void populateReactorModelPool( ReactorModelPool.Builder reactorModelPool, + List interimResults ) { for ( InterimResult interimResult : interimResults ) { 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 048a091f7921..741b150d1eb3 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 @@ -54,13 +54,15 @@ class ReactorModelPool * @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 + 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 ) -> { + .reduce( ( a, b ) -> + { throw new IllegalStateException( "Multiple modules with key " + a.getGroupId() + ':' + a.getArtifactId() ); } ).orElse( null ); diff --git a/maven-core/src/test/java/org/apache/maven/project/PomConstructionTest.java b/maven-core/src/test/java/org/apache/maven/project/PomConstructionTest.java index a639a38d0aef..bde7ee39b849 100644 --- a/maven-core/src/test/java/org/apache/maven/project/PomConstructionTest.java +++ b/maven-core/src/test/java/org/apache/maven/project/PomConstructionTest.java @@ -1882,10 +1882,6 @@ private PomTestWrapper buildPom( String pomPath, boolean lenientValidation, Prop repoSession.setLocalRepositoryManager( new SimpleLocalRepositoryManagerFactory().newInstance( repoSession, localRepo ) ); config.setRepositorySession( repoSession ); - sessionScope.seed( MavenSession.class, new MavenSession( getContainer(), - config.getRepositorySession(), - new DefaultMavenExecutionRequest(), null ) ); - return new PomTestWrapper( pomFile, projectBuilder.build( pomFile, config ).getProject() ); } 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 cc7b3b3f3da2..5fcf44fa16c5 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 @@ -70,7 +70,7 @@ protected Function> getRelativePathMapper() @Override protected BiFunction getDependencyKeyToVersionMapper() { - return (g,a) -> Optional.ofNullable( context.getRawModel( g, a ) ) + return (g, a) -> Optional.ofNullable( context.getRawModel( g, a ) ) .map( m -> toVersion( m ) ) .orElse( null ); } 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 4e71eb2a908e..5231acc82d47 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 @@ -40,8 +40,6 @@ import javax.inject.Named; import javax.inject.Provider; import javax.inject.Singleton; -import javax.xml.parsers.ParserConfigurationException; -import javax.xml.transform.TransformerException; import org.apache.maven.artifact.versioning.DefaultArtifactVersion; import org.apache.maven.artifact.versioning.InvalidVersionSpecificationException; @@ -96,7 +94,6 @@ import org.codehaus.plexus.interpolation.MapBasedValueSource; import org.codehaus.plexus.interpolation.StringSearchInterpolator; import org.eclipse.sisu.Nullable; -import org.xml.sax.SAXException; /** * @author Benjamin Bentmann @@ -677,9 +674,7 @@ private Model readModel( ModelSource modelSource, File pomFile, ModelBuildingReq .setMessage( "Non-readable POM " + modelSource.getLocation() + ": " + msg ).setException( e ) ); throw problems.newModelBuildingException(); } - model.setPomFile( pomFile ); - problems.setSource( model ); modelValidator.validateFileModel( model, request, problems ); @@ -689,7 +684,9 @@ private Model readModel( ModelSource modelSource, File pomFile, ModelBuildingReq { try { - Model rawModel = modelProcessor.read( pomFile, Collections.singletonMap( "transformerContext", buildPomXMLFilterFactory ) ); + Model rawModel = + modelProcessor.read( pomFile, + Collections.singletonMap( "transformerContext", buildPomXMLFilterFactory ) ); model.setPomFile( pomFile ); 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 b5050397718e..3d215f4dabb7 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 @@ -35,5 +35,6 @@ */ public interface ModelSourceTransformer { - InputStream transform( Path pomFile, TransformerContext context ) throws IOException, TransformerConfigurationException, SAXException, ParserConfigurationException; + InputStream transform( Path pomFile, TransformerContext context ) + throws IOException, TransformerConfigurationException, SAXException, ParserConfigurationException; } diff --git a/maven-xml/src/main/java/org/apache/maven/xml/sax/filter/ReactorDependencyXMLFilter.java b/maven-xml/src/main/java/org/apache/maven/xml/sax/filter/ReactorDependencyXMLFilter.java index 6bc26631a78b..6f80f5aceb42 100644 --- a/maven-xml/src/main/java/org/apache/maven/xml/sax/filter/ReactorDependencyXMLFilter.java +++ b/maven-xml/src/main/java/org/apache/maven/xml/sax/filter/ReactorDependencyXMLFilter.java @@ -1,7 +1,5 @@ package org.apache.maven.xml.sax.filter; -import java.util.function.BiFunction; - /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file @@ -21,6 +19,8 @@ * under the License. */ +import java.util.function.BiFunction; + import org.apache.maven.xml.sax.SAXEventUtils; import org.xml.sax.Attributes; import org.xml.sax.SAXException; From 1b0395eca71afb37905eda85cf07c0b4b72e5496 Mon Sep 17 00:00:00 2001 From: rfscholte Date: Wed, 26 Feb 2020 19:24:49 +0100 Subject: [PATCH 31/52] Revert tests with unneeded changes --- .../project/AbstractMavenProjectTestCase.java | 35 ++++--------------- .../maven/project/ProjectClasspathTest.java | 1 - .../AbstractCoreMavenComponentTestCase.java | 24 ++++++------- .../project/AbstractMavenProjectTestCase.java | 33 ++++------------- .../DefaultMavenProjectBuilderTest.java | 16 +-------- .../maven/project/PomConstructionTest.java | 12 ++----- .../maven/project/ProjectBuilderTest.java | 30 +++++----------- .../PomConstructionWithSettingsTest.java | 27 +++----------- .../model/building/DefaultModelProcessor.java | 3 +- .../maven/model/building/ModelData.java | 4 +-- 10 files changed, 44 insertions(+), 141 deletions(-) diff --git a/maven-compat/src/test/java/org/apache/maven/project/AbstractMavenProjectTestCase.java b/maven-compat/src/test/java/org/apache/maven/project/AbstractMavenProjectTestCase.java index 7aa65856b04c..7e3f7e6b58ac 100644 --- a/maven-compat/src/test/java/org/apache/maven/project/AbstractMavenProjectTestCase.java +++ b/maven-compat/src/test/java/org/apache/maven/project/AbstractMavenProjectTestCase.java @@ -23,13 +23,11 @@ import java.util.Arrays; import org.apache.maven.artifact.repository.ArtifactRepository; -import org.apache.maven.execution.DefaultMavenExecutionRequest; -import org.apache.maven.execution.MavenSession; +import org.apache.maven.artifact.repository.layout.ArtifactRepositoryLayout; import org.apache.maven.model.building.ModelBuildingException; import org.apache.maven.model.building.ModelProblem; import org.apache.maven.repository.RepositorySystem; import org.apache.maven.repository.internal.MavenRepositorySystemUtils; -import org.apache.maven.session.scope.internal.SessionScope; import org.codehaus.plexus.ContainerConfiguration; import org.codehaus.plexus.PlexusConstants; import org.codehaus.plexus.PlexusTestCase; @@ -44,8 +42,6 @@ public abstract class AbstractMavenProjectTestCase protected ProjectBuilder projectBuilder; protected RepositorySystem repositorySystem; - - private SessionScope sessionScope; @Override protected void customizeContainerConfiguration( ContainerConfiguration containerConfiguration ) @@ -71,27 +67,12 @@ protected void setUp() } repositorySystem = lookup( RepositorySystem.class ); - - } - - private void seedMavenSession( MavenSession mavenSession ) throws Exception - { - if ( sessionScope == null ) - { - sessionScope = lookup( SessionScope.class ); - sessionScope.enter(); - sessionScope.seed( MavenSession.class, mavenSession ); - } } @Override protected void tearDown() throws Exception { - if ( sessionScope != null ) - { - sessionScope.exit(); - } projectBuilder = null; super.tearDown(); @@ -140,7 +121,11 @@ protected static File getFileForClasspathResource( String resource ) protected ArtifactRepository getLocalRepository() throws Exception { - return repositorySystem.createLocalRepository( getLocalRepositoryPath() ); + ArtifactRepositoryLayout repoLayout = lookup( ArtifactRepositoryLayout.class, "legacy" ); + + ArtifactRepository r = repositorySystem.createArtifactRepository( "local", "file://" + getLocalRepositoryPath().getAbsolutePath(), repoLayout, null, null ); + + return r; } // ---------------------------------------------------------------------- @@ -157,10 +142,6 @@ protected MavenProject getProjectWithDependencies( File pom ) configuration.setResolveDependencies( true ); initRepoSession( configuration ); - seedMavenSession( new MavenSession( getContainer(), - configuration.getRepositorySession(), - new DefaultMavenExecutionRequest(), null ) ); - try { return projectBuilder.build( pom, configuration ).getProject(); @@ -189,10 +170,6 @@ protected MavenProject getProject( File pom ) ProjectBuildingRequest configuration = new DefaultProjectBuildingRequest(); configuration.setLocalRepository( getLocalRepository() ); initRepoSession( configuration ); - - seedMavenSession( new MavenSession( getContainer(), - configuration.getRepositorySession(), - new DefaultMavenExecutionRequest(), null ) ); return projectBuilder.build( pom, configuration ).getProject(); } diff --git a/maven-compat/src/test/java/org/apache/maven/project/ProjectClasspathTest.java b/maven-compat/src/test/java/org/apache/maven/project/ProjectClasspathTest.java index 59c6e0dd59f4..d7ae86e69706 100644 --- a/maven-compat/src/test/java/org/apache/maven/project/ProjectClasspathTest.java +++ b/maven-compat/src/test/java/org/apache/maven/project/ProjectClasspathTest.java @@ -35,7 +35,6 @@ public class ProjectClasspathTest public void setUp() throws Exception { - super.setUp(); ArtifactResolver resolver = lookup( ArtifactResolver.class, "classpath" ); DefaultArtifactDescriptorReader pomReader = (DefaultArtifactDescriptorReader)lookup(ArtifactDescriptorReader.class); pomReader.setArtifactResolver( resolver ); diff --git a/maven-core/src/test/java/org/apache/maven/AbstractCoreMavenComponentTestCase.java b/maven-core/src/test/java/org/apache/maven/AbstractCoreMavenComponentTestCase.java index 0931d1b68ef1..179b8f974180 100644 --- a/maven-core/src/test/java/org/apache/maven/AbstractCoreMavenComponentTestCase.java +++ b/maven-core/src/test/java/org/apache/maven/AbstractCoreMavenComponentTestCase.java @@ -44,10 +44,10 @@ import org.apache.maven.project.ProjectBuildingRequest; import org.apache.maven.repository.RepositorySystem; import org.apache.maven.repository.internal.MavenRepositorySystemUtils; -import org.apache.maven.session.scope.internal.SessionScope; import org.codehaus.plexus.ContainerConfiguration; import org.codehaus.plexus.PlexusConstants; import org.codehaus.plexus.PlexusTestCase; +import org.codehaus.plexus.component.annotations.Requirement; import org.codehaus.plexus.util.FileUtils; import org.eclipse.aether.DefaultRepositorySystemSession; import org.eclipse.aether.internal.impl.SimpleLocalRepositoryManagerFactory; @@ -56,12 +56,12 @@ public abstract class AbstractCoreMavenComponentTestCase extends PlexusTestCase { + @Requirement protected RepositorySystem repositorySystem; + @Requirement protected org.apache.maven.project.ProjectBuilder projectBuilder; - protected SessionScope sessionScope; - protected void setUp() throws Exception { @@ -144,17 +144,9 @@ protected MavenSession createMavenSession( File pom, Properties executionPropert .setRemoteRepositories( request.getRemoteRepositories() ) .setPluginArtifactRepositories( request.getPluginArtifactRepositories() ) .setSystemProperties( executionProperties ); - initRepoSession( configuration ); - MavenSession session = - new MavenSession( getContainer(), configuration.getRepositorySession(), request, - new DefaultMavenExecutionResult() ); - sessionScope = lookup( SessionScope.class ); - - sessionScope.enter(); - sessionScope.seed( MavenSession.class, session ); - List projects = new ArrayList<>(); + if ( pom != null ) { MavenProject project = projectBuilder.build( pom, configuration ).getProject(); @@ -180,9 +172,15 @@ protected MavenSession createMavenSession( File pom, Properties executionPropert project.setPluginArtifactRepositories( request.getPluginArtifactRepositories() ); projects.add( project ); } + + initRepoSession( configuration ); + + MavenSession session = + new MavenSession( getContainer(), configuration.getRepositorySession(), request, + new DefaultMavenExecutionResult() ); session.setProjects( projects ); session.setAllProjects( session.getProjects() ); - + return session; } diff --git a/maven-core/src/test/java/org/apache/maven/project/AbstractMavenProjectTestCase.java b/maven-core/src/test/java/org/apache/maven/project/AbstractMavenProjectTestCase.java index 82189e9fbd5f..9f836c28e646 100644 --- a/maven-core/src/test/java/org/apache/maven/project/AbstractMavenProjectTestCase.java +++ b/maven-core/src/test/java/org/apache/maven/project/AbstractMavenProjectTestCase.java @@ -23,13 +23,11 @@ import java.util.Arrays; import org.apache.maven.artifact.repository.ArtifactRepository; -import org.apache.maven.execution.DefaultMavenExecutionRequest; -import org.apache.maven.execution.MavenSession; +import org.apache.maven.artifact.repository.layout.ArtifactRepositoryLayout; import org.apache.maven.model.building.ModelBuildingException; import org.apache.maven.model.building.ModelProblem; import org.apache.maven.repository.RepositorySystem; import org.apache.maven.repository.internal.MavenRepositorySystemUtils; -import org.apache.maven.session.scope.internal.SessionScope; import org.codehaus.plexus.ContainerConfiguration; import org.codehaus.plexus.PlexusConstants; import org.codehaus.plexus.PlexusTestCase; @@ -44,8 +42,6 @@ public abstract class AbstractMavenProjectTestCase protected ProjectBuilder projectBuilder; protected RepositorySystem repositorySystem; - - private SessionScope sessionScope; @Override protected void customizeContainerConfiguration( ContainerConfiguration containerConfiguration ) @@ -71,17 +67,12 @@ protected void setUp() } repositorySystem = lookup( RepositorySystem.class ); - - sessionScope = lookup( SessionScope.class ); - sessionScope.enter(); } @Override protected void tearDown() throws Exception { - sessionScope.exit(); - projectBuilder = null; super.tearDown(); @@ -91,11 +82,6 @@ protected ProjectBuilder getProjectBuilder() { return projectBuilder; } - - protected final SessionScope getSessionScope() - { - return sessionScope; - } @Override protected String getCustomConfigurationName() @@ -133,7 +119,11 @@ protected static File getFileForClasspathResource( String resource ) protected ArtifactRepository getLocalRepository() throws Exception { - return repositorySystem.createLocalRepository( getLocalRepositoryPath() ); + ArtifactRepositoryLayout repoLayout = lookup( ArtifactRepositoryLayout.class, "legacy" ); + + ArtifactRepository r = repositorySystem.createArtifactRepository( "local", "file://" + getLocalRepositoryPath().getAbsolutePath(), repoLayout, null, null ); + + return r; } // ---------------------------------------------------------------------- @@ -148,9 +138,6 @@ protected MavenProject getProjectWithDependencies( File pom ) configuration.setProcessPlugins( false ); configuration.setResolveDependencies( true ); - sessionScope.seed( MavenSession.class, new MavenSession( getContainer(), - configuration.getRepositorySession(), - new DefaultMavenExecutionRequest(), null ) ); try { return projectBuilder.build( pom, configuration ).getProject(); @@ -177,10 +164,6 @@ protected MavenProject getProject( File pom ) { ProjectBuildingRequest configuration = newBuildingRequest(); - sessionScope.seed( MavenSession.class, new MavenSession( getContainer(), - configuration.getRepositorySession(), - new DefaultMavenExecutionRequest(), null ) ); - return projectBuilder.build( pom, configuration ).getProject(); } @@ -191,10 +174,6 @@ protected MavenProject getProjectFromRemoteRepository( final File pom ) configuration.setLocalRepository( this.getLocalRepository() ); configuration.setRemoteRepositories( Arrays.asList( this.repositorySystem.createDefaultRemoteRepository() ) ); initRepoSession( configuration ); - - sessionScope.seed( MavenSession.class, new MavenSession( getContainer(), - configuration.getRepositorySession(), - new DefaultMavenExecutionRequest(), null ) ); return projectBuilder.build( pom, configuration ).getProject(); } diff --git a/maven-core/src/test/java/org/apache/maven/project/DefaultMavenProjectBuilderTest.java b/maven-core/src/test/java/org/apache/maven/project/DefaultMavenProjectBuilderTest.java index fa3501a8df45..008c6d3bdc31 100644 --- a/maven-core/src/test/java/org/apache/maven/project/DefaultMavenProjectBuilderTest.java +++ b/maven-core/src/test/java/org/apache/maven/project/DefaultMavenProjectBuilderTest.java @@ -28,13 +28,12 @@ import org.apache.maven.artifact.Artifact; import org.apache.maven.artifact.repository.ArtifactRepository; import org.apache.maven.artifact.repository.layout.ArtifactRepositoryLayout; -import org.apache.maven.execution.DefaultMavenExecutionRequest; -import org.apache.maven.execution.MavenSession; import org.codehaus.plexus.util.FileUtils; public class DefaultMavenProjectBuilderTest extends AbstractMavenProjectTestCase { + private List filesToDelete = new ArrayList<>(); private File localRepoDir; @@ -85,11 +84,6 @@ protected MavenProject getProject( Artifact pom, boolean allowStub ) configuration.setLocalRepository( getLocalRepository() ); initRepoSession( configuration ); - getSessionScope().seed( MavenSession.class, - new MavenSession( getContainer(), - configuration.getRepositorySession(), - new DefaultMavenExecutionRequest(), null ) ); - return projectBuilder.build( pom, allowStub, configuration ).getProject(); } @@ -231,10 +225,6 @@ public void testPartialResultUponBadDependencyDeclaration() ProjectBuildingRequest request = newBuildingRequest(); request.setProcessPlugins( false ); request.setResolveDependencies( true ); - - getSessionScope().seed( MavenSession.class, new MavenSession( getContainer(), - request.getRepositorySession(), - new DefaultMavenExecutionRequest(), null ) ); projectBuilder.build( pomFile, request ); fail( "Project building did not fail despite invalid POM" ); } @@ -259,10 +249,6 @@ public void testImportScopePomResolvesFromPropertyBasedRepository() ProjectBuildingRequest request = newBuildingRequest(); request.setProcessPlugins( false ); request.setResolveDependencies( true ); - - getSessionScope().seed( MavenSession.class, new MavenSession( getContainer(), - request.getRepositorySession(), - new DefaultMavenExecutionRequest(), null ) ); projectBuilder.build( pomFile, request ); } diff --git a/maven-core/src/test/java/org/apache/maven/project/PomConstructionTest.java b/maven-core/src/test/java/org/apache/maven/project/PomConstructionTest.java index bde7ee39b849..9e16ebc59487 100644 --- a/maven-core/src/test/java/org/apache/maven/project/PomConstructionTest.java +++ b/maven-core/src/test/java/org/apache/maven/project/PomConstructionTest.java @@ -22,7 +22,6 @@ import static org.hamcrest.Matchers.endsWith; import static org.hamcrest.Matchers.lessThan; import static org.hamcrest.Matchers.startsWith; -import static org.junit.Assert.assertNotEquals; import static org.junit.Assert.assertThat; import java.io.File; @@ -33,21 +32,19 @@ import java.util.Properties; import org.apache.maven.artifact.repository.layout.DefaultRepositoryLayout; -import org.apache.maven.execution.DefaultMavenExecutionRequest; -import org.apache.maven.execution.MavenSession; import org.apache.maven.model.Plugin; import org.apache.maven.model.PluginExecution; import org.apache.maven.model.building.ModelBuildingRequest; import org.apache.maven.project.harness.PomTestWrapper; import org.apache.maven.repository.RepositorySystem; import org.apache.maven.repository.internal.MavenRepositorySystemUtils; -import org.apache.maven.session.scope.internal.SessionScope; import org.codehaus.plexus.ContainerConfiguration; import org.codehaus.plexus.PlexusConstants; import org.codehaus.plexus.PlexusTestCase; import org.eclipse.aether.DefaultRepositorySystemSession; import org.eclipse.aether.internal.impl.SimpleLocalRepositoryManagerFactory; import org.eclipse.aether.repository.LocalRepository; +import static org.junit.Assert.assertNotEquals; public class PomConstructionTest extends PlexusTestCase @@ -61,8 +58,6 @@ public class PomConstructionTest private DefaultProjectBuilder projectBuilder; private RepositorySystem repositorySystem; - - private SessionScope sessionScope; private File testDirectory; @@ -81,8 +76,6 @@ protected void setUp() new File( getBasedir(), BASE_MIXIN_DIR ); projectBuilder = (DefaultProjectBuilder) lookup( ProjectBuilder.class ); repositorySystem = lookup( RepositorySystem.class ); - sessionScope = lookup( SessionScope.class ); - sessionScope.enter(); } @Override @@ -90,7 +83,6 @@ protected void tearDown() throws Exception { projectBuilder = null; - sessionScope.exit(); super.tearDown(); } @@ -1881,7 +1873,7 @@ private PomTestWrapper buildPom( String pomPath, boolean lenientValidation, Prop LocalRepository localRepo = new LocalRepository( config.getLocalRepository().getBasedir() ); repoSession.setLocalRepositoryManager( new SimpleLocalRepositoryManagerFactory().newInstance( repoSession, localRepo ) ); config.setRepositorySession( repoSession ); - + return new PomTestWrapper( pomFile, projectBuilder.build( pomFile, config ).getProject() ); } diff --git a/maven-core/src/test/java/org/apache/maven/project/ProjectBuilderTest.java b/maven-core/src/test/java/org/apache/maven/project/ProjectBuilderTest.java index 7407b9a723a8..4833b0035119 100644 --- a/maven-core/src/test/java/org/apache/maven/project/ProjectBuilderTest.java +++ b/maven-core/src/test/java/org/apache/maven/project/ProjectBuilderTest.java @@ -26,8 +26,6 @@ import static org.junit.Assert.assertThat; 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.List; @@ -39,9 +37,9 @@ import org.apache.maven.model.building.FileModelSource; import org.apache.maven.model.building.ModelBuildingRequest; import org.apache.maven.model.building.ModelSource; -import org.apache.maven.session.scope.internal.SessionScope; import org.apache.maven.shared.utils.io.FileUtils; +import com.google.common.io.Files; public class ProjectBuilderTest extends AbstractCoreMavenComponentTestCase @@ -77,16 +75,9 @@ public void testBuildFromModelSource() ProjectBuildingRequest configuration = new DefaultProjectBuildingRequest(); configuration.setRepositorySession( mavenSession.getRepositorySession() ); ModelSource modelSource = new FileModelSource( pomFile ); - - SessionScope sessionScope = lookup( SessionScope.class ); - sessionScope.enter(); - sessionScope.seed( MavenSession.class, mavenSession ); - ProjectBuildingResult result = lookup( org.apache.maven.project.ProjectBuilder.class ).build( modelSource, configuration ); - sessionScope.exit(); - assertNotNull( result.getProject().getParentFile() ); } @@ -151,20 +142,19 @@ public void testReadModifiedPoms() throws Exception { String initialValue = System.setProperty( DefaultProjectBuilder.DISABLE_GLOBAL_MODEL_CACHE_SYSTEM_PROPERTY, Boolean.toString( true ) ); // TODO a similar test should be created to test the dependency management (basically all usages // of DefaultModelBuilder.getCache() are affected by MNG-6530 - - Path tempDir = Files.createTempDirectory( null ); - FileUtils.copyDirectoryStructure ( new File( "src/test/resources/projects/grandchild-check" ), tempDir.toFile() ); + File tempDir = Files.createTempDir(); + FileUtils.copyDirectoryStructure (new File( "src/test/resources/projects/grandchild-check"), tempDir ); try { MavenSession mavenSession = createMavenSession( null ); ProjectBuildingRequest configuration = new DefaultProjectBuildingRequest(); configuration.setRepositorySession( mavenSession.getRepositorySession() ); org.apache.maven.project.ProjectBuilder projectBuilder = lookup( org.apache.maven.project.ProjectBuilder.class ); - File child = new File( tempDir.toFile(), "child/pom.xml" ); + File child = new File( tempDir, "child/pom.xml" ); // build project once projectBuilder.build( child, configuration ); // modify parent - File parent = new File( tempDir.toFile(), "pom.xml" ); + File parent = new File( tempDir, "pom.xml" ); String parentContent = FileUtils.fileRead( parent ); parentContent = parentContent.replaceAll( "pom", "pomaddedValue" ); @@ -183,7 +173,7 @@ public void testReadModifiedPoms() throws Exception { { System.setProperty( DefaultProjectBuilder.DISABLE_GLOBAL_MODEL_CACHE_SYSTEM_PROPERTY, initialValue ); } - FileUtils.deleteDirectory( tempDir.toFile() ); + FileUtils.deleteDirectory( tempDir ); } } @@ -242,7 +232,6 @@ public void testReadInvalidPom() try { projectBuilder.build( pomFile, configuration ); - fail(); } catch ( InvalidArtifactRTException iarte ) { @@ -253,7 +242,6 @@ public void testReadInvalidPom() try { projectBuilder.build( Collections.singletonList( pomFile ), false, configuration ); - fail(); } catch ( ProjectBuildingException ex ) { @@ -315,7 +303,7 @@ private MavenProject findChildProject( List results ) return null; } - private void assertResultShowNoError( List results ) + private void assertResultShowNoError(List results) { for ( ProjectBuildingResult result : results ) { @@ -332,8 +320,8 @@ public void testBuildProperties() ProjectBuildingRequest configuration = new DefaultProjectBuildingRequest(); configuration.setRepositorySession( mavenSession.getRepositorySession() ); configuration.setResolveDependencies( true ); - List result = projectBuilder.build( Collections.singletonList( file ), true, configuration ); - MavenProject project = result.get( 0 ).getProject(); + List result = projectBuilder.build( Collections.singletonList(file), true, configuration ); + MavenProject project = result.get(0).getProject(); // verify a few typical parameters are not duplicated assertEquals( 1, project.getTestCompileSourceRoots().size() ); assertEquals( 1, project.getCompileSourceRoots().size() ); diff --git a/maven-core/src/test/java/org/apache/maven/settings/PomConstructionWithSettingsTest.java b/maven-core/src/test/java/org/apache/maven/settings/PomConstructionWithSettingsTest.java index eb6270bb3573..78d0da8de6e6 100644 --- a/maven-core/src/test/java/org/apache/maven/settings/PomConstructionWithSettingsTest.java +++ b/maven-core/src/test/java/org/apache/maven/settings/PomConstructionWithSettingsTest.java @@ -19,14 +19,7 @@ * under the License. */ -import java.io.File; -import java.io.IOException; -import java.io.Reader; - import org.apache.maven.artifact.repository.layout.DefaultRepositoryLayout; -import org.apache.maven.execution.DefaultMavenExecutionRequest; -import org.apache.maven.execution.MavenExecutionRequest; -import org.apache.maven.execution.MavenSession; import org.apache.maven.model.Profile; import org.apache.maven.project.DefaultProjectBuilder; import org.apache.maven.project.DefaultProjectBuildingRequest; @@ -35,7 +28,6 @@ import org.apache.maven.project.harness.PomTestWrapper; import org.apache.maven.repository.RepositorySystem; import org.apache.maven.repository.internal.MavenRepositorySystemUtils; -import org.apache.maven.session.scope.internal.SessionScope; import org.apache.maven.settings.io.xpp3.SettingsXpp3Reader; import org.codehaus.plexus.ContainerConfiguration; import org.codehaus.plexus.PlexusConstants; @@ -46,6 +38,10 @@ import org.eclipse.aether.internal.impl.SimpleLocalRepositoryManagerFactory; import org.eclipse.aether.repository.LocalRepository; +import java.io.File; +import java.io.IOException; +import java.io.Reader; + public class PomConstructionWithSettingsTest extends PlexusTestCase { @@ -56,11 +52,9 @@ public class PomConstructionWithSettingsTest private DefaultProjectBuilder projectBuilder; private RepositorySystem repositorySystem; - - private SessionScope sessionScope; private File testDirectory; - + @Override protected void customizeContainerConfiguration( ContainerConfiguration containerConfiguration ) { @@ -75,7 +69,6 @@ protected void setUp() testDirectory = new File( getBasedir(), BASE_POM_DIR ); projectBuilder = (DefaultProjectBuilder) lookup( ProjectBuilder.class ); repositorySystem = lookup( RepositorySystem.class ); - sessionScope = lookup( SessionScope.class ); } @Override @@ -101,7 +94,6 @@ public void testPomAndSettingsInterpolation() throws Exception { PomTestWrapper pom = buildPom( "test-pom-and-settings-interpolation" ); - assertEquals( "applied", pom.getValue( "properties/settingsProfile" ) ); assertEquals( "applied", pom.getValue( "properties/pomProfile" ) ); assertEquals( "settings", pom.getValue( "properties/pomVsSettings" ) ); @@ -146,15 +138,6 @@ private PomTestWrapper buildPom( String pomPath ) repoSession.setLocalRepositoryManager( new SimpleLocalRepositoryManagerFactory().newInstance( repoSession, localRepo ) ); config.setRepositorySession( repoSession ); - - MavenExecutionRequest request = new DefaultMavenExecutionRequest(); - request.setActiveProfiles( settings.getActiveProfiles() ); - - sessionScope.enter(); - sessionScope.seed( MavenSession.class, - new MavenSession( getContainer(), - repoSession, - new DefaultMavenExecutionRequest(), null ) ); return new PomTestWrapper( pomFile, projectBuilder.build( pomFile, config ).getProject() ); } 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 9dfa8bd5d1bb..76370ac4e42d 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 @@ -71,7 +71,7 @@ public class DefaultModelProcessor @Inject private ModelReader reader; - + public DefaultModelProcessor setModelLocator( ModelLocator locator ) { this.locator = locator; @@ -110,4 +110,5 @@ public Model read( InputStream input, Map options ) { return reader.read( input, options ); } + } 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 5117602ca071..1f39ad443b80 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 @@ -45,7 +45,7 @@ class ModelData private String artifactId; private String version; - + /** * Creates a new container for the specified model. * @@ -212,7 +212,7 @@ public String getId() return buffer.toString(); } - + @Override public String toString() { From 475fca2b8561e8b0ba8acab11b69607b3dbc61da Mon Sep 17 00:00:00 2001 From: rfscholte Date: Sat, 29 Feb 2020 16:18:41 +0100 Subject: [PATCH 32/52] [MNG-6656] Replace CacheManager with already existing ReactorModelPool --- ...DefaultRepositorySystemSessionFactory.java | 6 -- .../maven/project/DefaultProjectBuilder.java | 43 +++++------ .../maven/project/ProjectModelResolver.java | 46 ++++++------ .../maven/project/ReactorModelPool.java | 40 ++++++++--- .../DefaultConsumerPomXMLFilterFactory.java | 30 +++++++- .../DefaultBuildPomXMLFilterFactory.java | 5 ++ .../model/building/DefaultModelBuilder.java | 69 +++++++----------- .../building/DefaultModelBuilderFactory.java | 10 ++- .../building/DefaultModelCacheManager.java | 72 ------------------- .../DefaultModelSourceTransformer.java | 9 ++- .../model/building/ModelBuildingRequest.java | 2 + .../model/building/ModelCacheManager.java | 41 ----------- .../maven/model/io/DefaultModelReader.java | 35 ++++++++- .../DefaultInheritanceAssemblerTest.java | 4 +- .../sax/filter/BuildPomXMLFilterFactory.java | 12 ---- .../filter/ConsumerPomXMLFilterFactory.java | 31 ++++++++ .../sax/filter/ConsumerPomXMLFilterTest.java | 29 ++++---- 17 files changed, 227 insertions(+), 257 deletions(-) delete mode 100644 maven-model-builder/src/main/java/org/apache/maven/model/building/DefaultModelCacheManager.java delete mode 100644 maven-model-builder/src/main/java/org/apache/maven/model/building/ModelCacheManager.java diff --git a/maven-core/src/main/java/org/apache/maven/internal/aether/DefaultRepositorySystemSessionFactory.java b/maven-core/src/main/java/org/apache/maven/internal/aether/DefaultRepositorySystemSessionFactory.java index e89b39ee4338..2e6a8a5a5e3a 100644 --- a/maven-core/src/main/java/org/apache/maven/internal/aether/DefaultRepositorySystemSessionFactory.java +++ b/maven-core/src/main/java/org/apache/maven/internal/aether/DefaultRepositorySystemSessionFactory.java @@ -27,7 +27,6 @@ import javax.inject.Inject; import javax.inject.Named; -import javax.inject.Provider; import org.apache.maven.RepositoryUtils; import org.apache.maven.artifact.handler.manager.ArtifactHandlerManager; @@ -42,7 +41,6 @@ import org.apache.maven.settings.crypto.DefaultSettingsDecryptionRequest; import org.apache.maven.settings.crypto.SettingsDecrypter; import org.apache.maven.settings.crypto.SettingsDecryptionResult; -import org.apache.maven.xml.sax.filter.ConsumerPomXMLFilterFactory; import org.codehaus.plexus.configuration.xml.XmlPlexusConfiguration; import org.codehaus.plexus.logging.Logger; import org.codehaus.plexus.util.xml.Xpp3Dom; @@ -96,10 +94,6 @@ public class DefaultRepositorySystemSessionFactory @Inject MavenRepositorySystem mavenRepositorySystem; - @Inject - @Nullable - private Provider consumerPomXMLFilterFactory; - public DefaultRepositorySystemSession newRepositorySession( MavenExecutionRequest request ) { DefaultRepositorySystemSession session = MavenRepositorySystemUtils.newSession(); 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 53ecfb782e27..8d93ea458388 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 @@ -73,6 +73,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.DefaultBuildPomXMLFilterFactory; import org.apache.maven.model.building.DefaultModelBuildingRequest; import org.apache.maven.model.building.DefaultModelProblem; @@ -407,7 +408,16 @@ public ProjectBuildingResult build( Artifact artifact, boolean allowStubModel, P artifact.setResolved( true ); } - return build( localProject ? pomFile : null, new FileModelSource( pomFile ), config ); + if ( localProject ) + { + return build( pomFile, new FileModelSource( pomFile ), config ); + } + else + { + return build( null, new ArtifactModelSource( pomFile, artifact.getGroupId(), artifact.getArtifactId(), + artifact.getVersion() ), + config ); + } } private ModelSource createStubModelSource( Artifact artifact ) @@ -444,9 +454,7 @@ public List build( List pomFiles, boolean recursive boolean noErrors = build( results, interimResults, projectIndex, pomFiles, new LinkedHashSet<>(), true, recursive, - config ); - - populateReactorModelPool( poolBuilder, interimResults ); + config, poolBuilder ); ClassLoader oldContextClassLoader = Thread.currentThread().getContextClassLoader(); @@ -472,7 +480,8 @@ public List build( List pomFiles, boolean recursive @SuppressWarnings( "checkstyle:parameternumber" ) private boolean build( List results, List interimResults, Map projectIndex, List pomFiles, Set aggregatorFiles, - boolean isRoot, boolean recursive, InternalConfig config ) + boolean isRoot, boolean recursive, InternalConfig config, + ReactorModelPool.Builder poolBuilder ) { boolean noErrors = true; @@ -480,7 +489,8 @@ private boolean build( List results, List { aggregatorFiles.add( pomFile ); - if ( !build( results, interimResults, projectIndex, pomFile, aggregatorFiles, isRoot, recursive, config ) ) + if ( !build( results, interimResults, projectIndex, pomFile, aggregatorFiles, isRoot, recursive, config, + poolBuilder ) ) { noErrors = false; } @@ -494,7 +504,8 @@ private boolean build( List results, List @SuppressWarnings( "checkstyle:parameternumber" ) private boolean build( List results, List interimResults, Map projectIndex, File pomFile, Set aggregatorFiles, - boolean isRoot, boolean recursive, InternalConfig config ) + boolean isRoot, boolean recursive, InternalConfig config, + ReactorModelPool.Builder poolBuilder ) { boolean noErrors = true; @@ -531,6 +542,10 @@ private boolean build( List results, List } Model model = result.getEffectiveModel(); + + // move to here!! + poolBuilder.put( model.getPomFile().toPath(), result.getRawModel() ); + try { // first pass: build without building parent. @@ -625,7 +640,7 @@ private boolean build( List results, List interimResult.modules = new ArrayList<>(); if ( !build( results, interimResult.modules, projectIndex, moduleFiles, aggregatorFiles, false, - recursive, config ) ) + recursive, config, poolBuilder ) ) { noErrors = false; } @@ -661,18 +676,6 @@ static class InterimResult } - private void populateReactorModelPool( ReactorModelPool.Builder reactorModelPool, - List interimResults ) - { - for ( InterimResult interimResult : interimResults ) - { - Model model = interimResult.result.getEffectiveModel(); - reactorModelPool.put( model.getPomFile().toPath(), model ); - - populateReactorModelPool( reactorModelPool, interimResult.modules ); - } - } - private boolean build( List results, List projects, Map projectIndex, List interimResults, ProjectBuildingRequest request, Map profilesXmls, 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 e927f775ae53..3b027e5063c7 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 @@ -19,7 +19,6 @@ * under the License. */ -import java.io.File; import java.util.ArrayList; import java.util.Collections; import java.util.HashSet; @@ -32,6 +31,7 @@ import org.apache.maven.model.Model; import org.apache.maven.model.Parent; import org.apache.maven.model.Repository; +import org.apache.maven.model.building.ArtifactModelSource; import org.apache.maven.model.building.FileModelSource; import org.apache.maven.model.building.ModelSource; import org.apache.maven.model.resolution.InvalidRepositoryException; @@ -157,10 +157,10 @@ public void addRepository( final Repository repository, boolean replace ) private static void removeMatchingRepository( Iterable repositories, final String id ) { - Iterator iterator = repositories.iterator( ); + Iterator iterator = repositories.iterator( ); while ( iterator.hasNext() ) { - RemoteRepository next = ( RemoteRepository ) iterator.next(); + RemoteRepository next = iterator.next(); if ( next.getId().equals( id ) ) { iterator.remove(); @@ -176,34 +176,20 @@ public ModelResolver newCopy() public ModelSource resolveModel( String groupId, String artifactId, String version ) throws UnresolvableModelException { - File pomFile = null; + Artifact pomArtifact = new DefaultArtifact( groupId, artifactId, "", "pom", version ); - if ( modelPool != null ) + try { - pomFile = Optional.ofNullable( modelPool.get( groupId, artifactId, - version ) ).map( Model::getPomFile ) - .orElse( null ); + ArtifactRequest request = new ArtifactRequest( pomArtifact, repositories, context ); + request.setTrace( trace ); + pomArtifact = resolver.resolveArtifact( session, request ).getArtifact(); } - - if ( pomFile == null ) + catch ( ArtifactResolutionException e ) { - Artifact pomArtifact = new DefaultArtifact( groupId, artifactId, "", "pom", version ); - - try - { - ArtifactRequest request = new ArtifactRequest( pomArtifact, repositories, context ); - request.setTrace( trace ); - pomArtifact = resolver.resolveArtifact( session, request ).getArtifact(); - } - catch ( ArtifactResolutionException e ) - { - throw new UnresolvableModelException( e.getMessage(), groupId, artifactId, version, e ); - } - - pomFile = pomArtifact.getFile(); + throw new UnresolvableModelException( e.getMessage(), groupId, artifactId, version, e ); } - return new FileModelSource( pomFile ); + return new ArtifactModelSource( pomArtifact.getFile(), groupId, artifactId, version ); } @Override @@ -289,6 +275,16 @@ public ModelSource resolveModel( final Dependency dependency ) } dependency.setVersion( versionRangeResult.getHighestVersion().toString() ); + + if ( modelPool != null ) + { + Model model = Optional.ofNullable( modelPool.get( dependency.getGroupId(), dependency.getArtifactId(), + dependency.getVersion() ) ).orElse( null ); + if ( model != null ) + { + return new FileModelSource( model.getPomFile() ); + } + } return resolveModel( dependency.getGroupId(), dependency.getArtifactId(), dependency.getVersion() ); } 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 741b150d1eb3..64101104fa07 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 @@ -21,13 +21,13 @@ 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.HashSet; import java.util.Map; import java.util.NoSuchElementException; import java.util.Objects; +import java.util.Set; import org.apache.maven.model.Model; @@ -40,7 +40,7 @@ */ class ReactorModelPool { - private final Map> modelsByGa = new HashMap<>(); + private final Map> modelsByGa = new HashMap<>(); private final Map modelsByPath = new HashMap<>(); @@ -49,18 +49,16 @@ class ReactorModelPool * * @param groupId, never {@code null} * @param artifactId, never {@code null} - * @param version, might be {@code null} - * @return + * @param version, can be {@code null} + * @return the matching model * @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() ) ) + return modelsByGa.getOrDefault( new GAKey( groupId, artifactId ), Collections.emptySet() ).stream() + .filter( m -> version == null || version.equals( getVersion( m ) ) ) .reduce( ( a, b ) -> { throw new IllegalStateException( "Multiple modules with key " @@ -81,6 +79,16 @@ public Model get( Path path ) } return modelsByPath.get( pomFile ); } + + private String getVersion( Model model ) + { + String version = model.getVersion(); + if ( version == null && model.getParent() != null ) + { + version = model.getParent().getVersion(); + } + return version; + } static class Builder { @@ -89,8 +97,8 @@ static class Builder Builder put( Path pomFile, Model model ) { pool.modelsByPath.put( pomFile, model ); - pool.modelsByGa.computeIfAbsent( new GAKey( model.getGroupId(), model.getArtifactId() ), - k -> new ArrayList() ).add( model ); + pool.modelsByGa.computeIfAbsent( new GAKey( getGroupId( model ), model.getArtifactId() ), + k -> new HashSet() ).add( model ); return this; } @@ -98,6 +106,16 @@ ReactorModelPool build() { return pool; } + + private static String getGroupId( Model model ) + { + String groupId = model.getGroupId(); + if ( groupId == null && model.getParent() != null ) + { + groupId = model.getParent().getGroupId(); + } + return groupId; + } } private static final class GAKey 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 5b13aa5cb497..f686ac2d2f24 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 @@ -19,7 +19,10 @@ * under the License. */ -import org.apache.maven.xml.sax.filter.BuildPomXMLFilterFactory; +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; /** @@ -29,9 +32,32 @@ */ public class DefaultConsumerPomXMLFilterFactory extends ConsumerPomXMLFilterFactory { - public DefaultConsumerPomXMLFilterFactory( BuildPomXMLFilterFactory buildPomXMLFilterFactory ) + private final TransformerContext context; + + public DefaultConsumerPomXMLFilterFactory( DefaultBuildPomXMLFilterFactory buildPomXMLFilterFactory ) { super( buildPomXMLFilterFactory ); + this.context = buildPomXMLFilterFactory.getContext(); + } + + @Override + protected Optional getChangelist() + { + return Optional.ofNullable( context.getUserProperty( "changelist" ) ); + } + + @Override + protected Optional getRevision() + { + return Optional.ofNullable( context.getUserProperty( "revision" ) ); } + @Override + protected Optional getSha1() + { + return Optional.ofNullable( context.getUserProperty( "sha1" ) ); + } + + + } 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 5fcf44fa16c5..9489e3b71f5d 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 @@ -43,6 +43,11 @@ public DefaultBuildPomXMLFilterFactory( TransformerContext context ) this.context = context; } + public final TransformerContext getContext() + { + return context; + } + @Override protected Optional getChangelist() { 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 5231acc82d47..3b252967e5a2 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 @@ -38,7 +38,6 @@ import javax.inject.Inject; import javax.inject.Named; -import javax.inject.Provider; import javax.inject.Singleton; import org.apache.maven.artifact.versioning.DefaultArtifactVersion; @@ -89,8 +88,6 @@ 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.sax.filter.BuildPomXMLFilterFactory; -import org.apache.maven.xml.sax.filter.BuildPomXMLFilterListener; import org.codehaus.plexus.interpolation.MapBasedValueSource; import org.codehaus.plexus.interpolation.StringSearchInterpolator; import org.eclipse.sisu.Nullable; @@ -155,17 +152,6 @@ public class DefaultModelBuilder @Inject private ReportingConverter reportingConverter; - // Using provider so MavenSession can be used in the constructor - @Inject - private Provider buildPomXMLFilterFactory; - - @Inject - private ModelCacheManager modelCacheManager; - - @Inject - @Nullable - private BuildPomXMLFilterListener xmlFilterListener; - private ModelMerger modelMerger = new FileToRawModelMerger(); public DefaultModelBuilder setModelProcessor( ModelProcessor modelProcessor ) @@ -270,17 +256,6 @@ public DefaultModelBuilder setReportingConverter( ReportingConverter reportingCo return this; } - public DefaultModelBuilder setBuildPomXMLFilterFactory( BuildPomXMLFilterFactory buildPomXMLFilterFactory ) - { - this.buildPomXMLFilterFactory = () -> buildPomXMLFilterFactory; - return this; - } - - public void setModelCacheManager( ModelCacheManager modelCacheManager ) - { - this.modelCacheManager = modelCacheManager; - } - @SuppressWarnings( "checkstyle:methodlength" ) @Override public ModelBuildingResult build( ModelBuildingRequest request ) @@ -465,7 +440,7 @@ else if ( !parentIds.add( parentData.getId() ) ) if ( request.getPomFile() != null ) { - modelCacheManager.put( request.getPomFile().toPath(), resultModel ); + // request.getModelCache().put( request.getPomFile().toPath(), resultModel ); } for ( ModelData currentData : lineage ) @@ -686,7 +661,7 @@ private Model readModel( ModelSource modelSource, File pomFile, ModelBuildingReq { Model rawModel = modelProcessor.read( pomFile, - Collections.singletonMap( "transformerContext", buildPomXMLFilterFactory ) ); + Collections.singletonMap( "transformerContext", request.getTransformerContext() ) ); model.setPomFile( pomFile ); @@ -1007,12 +982,17 @@ private ModelData readParent( Model childModel, ModelSource childSource, ModelBu if ( parentData == null ) { - parentData = fromCache( request.getModelCache(), - parent.getGroupId(), parent.getArtifactId(), - parent.getVersion(), ModelCacheTag.RAW ); + ModelData candidateData = fromCache( request.getModelCache(), + parent.getGroupId(), parent.getArtifactId(), + parent.getVersion(), ModelCacheTag.RAW ); + - // ArtifactModelSource means repositorySource - if ( parentData == null || !( parentData.getSource() instanceof ArtifactModelSource ) ) + if ( candidateData != null && candidateData.getSource() instanceof ArtifactModelSource ) + { + // ArtifactModelSource means repositorySource + parentData = candidateData; + } + else { parentData = readParentExternally( childModel, request, problems ); @@ -1021,21 +1001,20 @@ private ModelData readParent( Model childModel, ModelSource childSource, ModelBu parentData.getVersion(), ModelCacheTag.RAW, parentData ); } } - - Model parentModel = parentData.getModel(); - - if ( !"pom".equals( parentModel.getPackaging() ) ) + + if ( parentData != null ) { - problems.add( new ModelProblemCollectorRequest( Severity.ERROR, Version.BASE ) - .setMessage( "Invalid packaging for parent POM " + ModelProblemUtils.toSourceHint( parentModel ) - + ", must be \"pom\" but is \"" + parentModel.getPackaging() + "\"" ) - .setLocation( parentModel.getLocation( "packaging" ) ) ); + Model parentModel = parentData.getModel(); + + if ( !"pom".equals( parentModel.getPackaging() ) ) + { + problems.add( new ModelProblemCollectorRequest( Severity.ERROR, Version.BASE ) + .setMessage( "Invalid packaging for parent POM " + ModelProblemUtils.toSourceHint( parentModel ) + + ", must be \"pom\" but is \"" + parentModel.getPackaging() + "\"" ) + .setLocation( parentModel.getLocation( "packaging" ) ) ); + } } } - else - { - parentData = null; - } return parentData; } @@ -1413,7 +1392,7 @@ private void importDependencyManagement( Model model, ModelBuildingRequest reque final ModelSource importSource; try { - importSource = modelResolver.resolveModel( groupId, artifactId, version ); + importSource = modelResolver.resolveModel( dependency ); } catch ( UnresolvableModelException e ) { 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 cca02410f8b9..daf56ca79e83 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 @@ -91,7 +91,9 @@ protected ModelLocator newModelLocator() protected ModelReader newModelReader() { - return new DefaultModelReader(); + DefaultModelReader reader = new DefaultModelReader(); + reader.setTransformer( newModelSourceTransformer() ); + return reader; } protected ProfileSelector newProfileSelector() @@ -199,6 +201,11 @@ protected ReportingConverter newReportingConverter() return new DefaultReportingConverter(); } + private ModelSourceTransformer newModelSourceTransformer() + { + return new DefaultModelSourceTransformer(); + } + /** * Creates a new model builder instance. * @@ -225,7 +232,6 @@ public DefaultModelBuilder newInstance() modelBuilder.setPluginConfigurationExpander( newPluginConfigurationExpander() ); modelBuilder.setReportConfigurationExpander( newReportConfigurationExpander() ); modelBuilder.setReportingConverter( newReportingConverter() ); - modelBuilder.setModelCacheManager( new DefaultModelCacheManager() ); return modelBuilder; } diff --git a/maven-model-builder/src/main/java/org/apache/maven/model/building/DefaultModelCacheManager.java b/maven-model-builder/src/main/java/org/apache/maven/model/building/DefaultModelCacheManager.java deleted file mode 100644 index e205749ffb3f..000000000000 --- a/maven-model-builder/src/main/java/org/apache/maven/model/building/DefaultModelCacheManager.java +++ /dev/null @@ -1,72 +0,0 @@ -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.Map; -import java.util.concurrent.ConcurrentHashMap; - -import javax.inject.Named; -import javax.inject.Singleton; - -import org.apache.maven.model.Model; -import org.apache.maven.xml.sax.filter.DependencyKey; - -/** - * - * @author Robert Scholte - * @since 3.7.0 - */ -@Named -@Singleton -public class DefaultModelCacheManager implements ModelCacheManager -{ - private final Map modelCache = new ConcurrentHashMap<>(); - - private final Map depKeyModelCache = new ConcurrentHashMap<>(); - - @Override - public void put( Path p, Model m ) - { - modelCache.put( p, m ); - - String groupId = m.getGroupId(); - if ( groupId == null && m.getParent() != null ) - { - groupId = m.getParent().getGroupId(); - } - - String artifactId = m.getArtifactId(); - depKeyModelCache.put( new DependencyKey( groupId, artifactId ), m ); - } - - @Override - public Model get( Path p ) - { - return modelCache.get( p ); - } - - @Override - public Model get( DependencyKey k ) - { - return depKeyModelCache.get( k ); - } - -} 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 index daf91ecca094..a9647543f7f3 100644 --- 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 @@ -44,16 +44,21 @@ import org.eclipse.sisu.Nullable; import org.xml.sax.SAXException; +/** + * + * @author Robert Scholte + * @since 3.7.0 + */ @Named @Singleton -class DefaultModelSourceTransformer implements ModelSourceTransformer +public class DefaultModelSourceTransformer implements ModelSourceTransformer { @Inject @Nullable private BuildPomXMLFilterListener xmlFilterListener; @Override - public InputStream transform( Path pomFile, TransformerContext context ) + public final InputStream transform( Path pomFile, TransformerContext context ) throws IOException, TransformerConfigurationException, SAXException, ParserConfigurationException { final BuildPomXMLFilterFactory buildPomXMLFilterFactory = new DefaultBuildPomXMLFilterFactory( context ); 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 0ae969436510..9523f4c9d0bc 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 @@ -353,4 +353,6 @@ public interface ModelBuildingRequest TransformerContext getTransformerContext(); ModelBuildingRequest setTransformerContext( TransformerContext context ); + + } diff --git a/maven-model-builder/src/main/java/org/apache/maven/model/building/ModelCacheManager.java b/maven-model-builder/src/main/java/org/apache/maven/model/building/ModelCacheManager.java deleted file mode 100644 index f6e651592ede..000000000000 --- a/maven-model-builder/src/main/java/org/apache/maven/model/building/ModelCacheManager.java +++ /dev/null @@ -1,41 +0,0 @@ -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 org.apache.maven.model.Model; -import org.apache.maven.xml.sax.filter.DependencyKey; - -/** - * Registers models for usage later on - * - * @author Robert Scholte - * @since 3.7.0 - */ -public interface ModelCacheManager -{ - void put( Path p, Model t ); - - Model get( Path p ); - - Model get( DependencyKey k ); - -} 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 2750ce0b7a96..86060aeffe58 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 @@ -30,15 +30,19 @@ 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.InputSource; import org.apache.maven.model.Model; import org.apache.maven.model.building.ModelSourceTransformer; +import org.apache.maven.model.building.TransformerContext; import org.apache.maven.model.io.xpp3.MavenXpp3Reader; import org.apache.maven.model.io.xpp3.MavenXpp3ReaderEx; import org.codehaus.plexus.util.ReaderFactory; import org.codehaus.plexus.util.xml.XmlStreamReader; import org.codehaus.plexus.util.xml.pull.XmlPullParserException; +import org.xml.sax.SAXException; /** * Handles deserialization of a model from some kind of textual format like XML. @@ -53,16 +57,41 @@ public class DefaultModelReader @Inject private ModelSourceTransformer transformer; - + public void setTransformer( ModelSourceTransformer transformer ) + { + this.transformer = transformer; + } - @Override public Model read( File input, Map options ) throws IOException { Objects.requireNonNull( input, "input cannot be null" ); - Model model = read( new FileInputStream( input ), options ); + TransformerContext context = null; + if ( options != null ) + { + context = (TransformerContext) options.get( "transformerContext" ); + } + + final InputStream is; + if ( context == null ) + { + is = new FileInputStream( input ); + } + else + { + try + { + is = transformer.transform( input.toPath(), context ); + } + catch ( TransformerConfigurationException | SAXException | ParserConfigurationException e ) + { + throw new IOException( "Failed to transform " + input, e ); + } + } + + Model model = read( is, options ); model.setPomFile( input ); diff --git a/maven-model-builder/src/test/java/org/apache/maven/model/inheritance/DefaultInheritanceAssemblerTest.java b/maven-model-builder/src/test/java/org/apache/maven/model/inheritance/DefaultInheritanceAssemblerTest.java index 09f930cb28e4..54c178e024d7 100644 --- a/maven-model-builder/src/test/java/org/apache/maven/model/inheritance/DefaultInheritanceAssemblerTest.java +++ b/maven-model-builder/src/test/java/org/apache/maven/model/inheritance/DefaultInheritanceAssemblerTest.java @@ -20,6 +20,7 @@ */ import org.apache.maven.model.Model; +import org.apache.maven.model.building.DefaultModelSourceTransformer; import org.apache.maven.model.building.SimpleProblemCollector; import org.apache.maven.model.io.DefaultModelReader; import org.apache.maven.model.io.DefaultModelWriter; @@ -41,7 +42,7 @@ public class DefaultInheritanceAssemblerTest extends TestCase { - private ModelReader reader; + private DefaultModelReader reader; private ModelWriter writer; @@ -54,6 +55,7 @@ protected void setUp() super.setUp(); reader = new DefaultModelReader(); + reader.setTransformer( new DefaultModelSourceTransformer() ); writer = new DefaultModelWriter(); assembler = new DefaultInheritanceAssembler(); } 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 2b8e16ddca6f..d86200f9fcde 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 @@ -76,18 +76,6 @@ public final BuildPomXMLFilter get( Path projectFile ) parentFilter.setLexicalHandler( parent ); parent = parentFilter; } - - CiFriendlyXMLFilter ciFriendlyFilter = new CiFriendlyXMLFilter(); - getChangelist().ifPresent( ciFriendlyFilter::setChangelist ); - getRevision().ifPresent( ciFriendlyFilter::setRevision ); - getSha1().ifPresent( ciFriendlyFilter::setSha1 ); - - if ( ciFriendlyFilter.isSet() ) - { - ciFriendlyFilter.setParent( parent ); - ciFriendlyFilter.setLexicalHandler( parent ); - parent = ciFriendlyFilter; - } return new BuildPomXMLFilter( parent ); } 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 2b2f542087d1..f7751d2b817b 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,6 +20,7 @@ */ import java.nio.file.Path; +import java.util.Optional; import javax.xml.parsers.ParserConfigurationException; import javax.xml.transform.TransformerConfigurationException; @@ -48,6 +49,18 @@ public final ConsumerPomXMLFilter get( Path projectPath ) // Ensure that xs:any elements aren't touched by next filters AbstractSAXFilter filter = new FastForwardFilter( parent ); + CiFriendlyXMLFilter ciFriendlyFilter = new CiFriendlyXMLFilter(); + getChangelist().ifPresent( ciFriendlyFilter::setChangelist ); + getRevision().ifPresent( ciFriendlyFilter::setRevision ); + getSha1().ifPresent( ciFriendlyFilter::setSha1 ); + + if ( ciFriendlyFilter.isSet() ) + { + ciFriendlyFilter.setParent( parent ); + ciFriendlyFilter.setLexicalHandler( parent ); + filter = ciFriendlyFilter; + } + // Strip modules filter = new ModulesXMLFilter( filter ); // Adjust relativePath @@ -55,4 +68,22 @@ public final ConsumerPomXMLFilter get( Path projectPath ) return new ConsumerPomXMLFilter( filter ); } + + // getters for the 3 magic properties of CIFriendly versions ( https://maven.apache.org/maven-ci-friendly.html ) + + protected Optional getChangelist() + { + return Optional.empty(); + } + + protected Optional getRevision() + { + return Optional.empty(); + } + + protected Optional getSha1() + { + return Optional.empty(); + } + } 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 df1a8801e902..03cc87d8864e 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,38 +47,37 @@ protected AbstractSAXFilter getFilter() throws SAXException, ParserConfiguration final BuildPomXMLFilterFactory buildPomXMLFilterFactory = new BuildPomXMLFilterFactory() { @Override - protected Optional getSha1() + protected Function> getRelativePathMapper() { - return Optional.empty(); + return null; } @Override - protected Optional getRevision() + protected BiFunction getDependencyKeyToVersionMapper() { - return Optional.empty(); + return null; } - + }; + + ConsumerPomXMLFilter filter = new ConsumerPomXMLFilterFactory( buildPomXMLFilterFactory ) + { @Override - protected Optional getChangelist() + protected Optional getSha1() { - return Optional.of( "CL" ); + return Optional.empty(); } @Override - protected Function> getRelativePathMapper() + protected Optional getRevision() { - return null; + return Optional.empty(); } @Override - protected BiFunction getDependencyKeyToVersionMapper() + protected Optional getChangelist() { - return null; + return Optional.of( "CL" ); } - }; - - ConsumerPomXMLFilter filter = new ConsumerPomXMLFilterFactory( buildPomXMLFilterFactory ) - { }.get( Paths.get( "pom.xml" ) ); filter.setFeature( "http://xml.org/sax/features/namespaces", true ); return filter; From a94e2d15c6e590cc008c8551d1e9ee4e44a250c9 Mon Sep 17 00:00:00 2001 From: rfscholte Date: Sat, 29 Feb 2020 21:05:12 +0100 Subject: [PATCH 33/52] Revert tests with unneeded changes --- .../maven/project/ProjectBuilderTest.java | 24 ++++++++++--------- 1 file changed, 13 insertions(+), 11 deletions(-) diff --git a/maven-core/src/test/java/org/apache/maven/project/ProjectBuilderTest.java b/maven-core/src/test/java/org/apache/maven/project/ProjectBuilderTest.java index 4833b0035119..6c7fbf913c37 100644 --- a/maven-core/src/test/java/org/apache/maven/project/ProjectBuilderTest.java +++ b/maven-core/src/test/java/org/apache/maven/project/ProjectBuilderTest.java @@ -26,6 +26,8 @@ import static org.junit.Assert.assertThat; 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.List; @@ -39,7 +41,6 @@ import org.apache.maven.model.building.ModelSource; import org.apache.maven.shared.utils.io.FileUtils; -import com.google.common.io.Files; public class ProjectBuilderTest extends AbstractCoreMavenComponentTestCase @@ -142,22 +143,23 @@ public void testReadModifiedPoms() throws Exception { String initialValue = System.setProperty( DefaultProjectBuilder.DISABLE_GLOBAL_MODEL_CACHE_SYSTEM_PROPERTY, Boolean.toString( true ) ); // TODO a similar test should be created to test the dependency management (basically all usages // of DefaultModelBuilder.getCache() are affected by MNG-6530 - File tempDir = Files.createTempDir(); - FileUtils.copyDirectoryStructure (new File( "src/test/resources/projects/grandchild-check"), tempDir ); + + Path tempDir = Files.createTempDirectory( null ); + FileUtils.copyDirectoryStructure ( new File( "src/test/resources/projects/grandchild-check" ), tempDir.toFile() ); try { MavenSession mavenSession = createMavenSession( null ); ProjectBuildingRequest configuration = new DefaultProjectBuildingRequest(); configuration.setRepositorySession( mavenSession.getRepositorySession() ); org.apache.maven.project.ProjectBuilder projectBuilder = lookup( org.apache.maven.project.ProjectBuilder.class ); - File child = new File( tempDir, "child/pom.xml" ); + File child = new File( tempDir.toFile(), "child/pom.xml" ); // build project once projectBuilder.build( child, configuration ); // modify parent - File parent = new File( tempDir, "pom.xml" ); + File parent = new File( tempDir.toFile(), "pom.xml" ); String parentContent = FileUtils.fileRead( parent ); parentContent = parentContent.replaceAll( "pom", - "pomaddedValue" ); + "pomaddedValue" ); FileUtils.fileWrite( parent, "UTF-8", parentContent ); // re-build pom with modified parent ProjectBuildingResult result = projectBuilder.build( child, configuration ); @@ -173,7 +175,7 @@ public void testReadModifiedPoms() throws Exception { { System.setProperty( DefaultProjectBuilder.DISABLE_GLOBAL_MODEL_CACHE_SYSTEM_PROPERTY, initialValue ); } - FileUtils.deleteDirectory( tempDir ); + FileUtils.deleteDirectory( tempDir.toFile() ); } } @@ -303,7 +305,7 @@ private MavenProject findChildProject( List results ) return null; } - private void assertResultShowNoError(List results) + private void assertResultShowNoError( List results ) { for ( ProjectBuildingResult result : results ) { @@ -320,12 +322,12 @@ public void testBuildProperties() ProjectBuildingRequest configuration = new DefaultProjectBuildingRequest(); configuration.setRepositorySession( mavenSession.getRepositorySession() ); configuration.setResolveDependencies( true ); - List result = projectBuilder.build( Collections.singletonList(file), true, configuration ); - MavenProject project = result.get(0).getProject(); + List result = projectBuilder.build( Collections.singletonList( file ), true, configuration ); + MavenProject project = result.get( 0 ).getProject(); // verify a few typical parameters are not duplicated assertEquals( 1, project.getTestCompileSourceRoots().size() ); assertEquals( 1, project.getCompileSourceRoots().size() ); assertEquals( 1, project.getMailingLists().size() ); assertEquals( 1, project.getResources().size() ); } -} +} \ No newline at end of file From 7ba7befae24fd0016f2bd95a0c3013f5ccc1d00e Mon Sep 17 00:00:00 2001 From: rfscholte Date: Sun, 1 Mar 2020 17:34:42 +0100 Subject: [PATCH 34/52] [MNG-6656] Clean up code --- ...DefaultRepositorySystemSessionFactory.java | 23 +++++++++---------- .../maven/project/DefaultProjectBuilder.java | 1 - .../maven/project/ProjectBuilderTest.java | 4 ++-- .../model/building/DefaultModelBuilder.java | 7 +----- 4 files changed, 14 insertions(+), 21 deletions(-) diff --git a/maven-core/src/main/java/org/apache/maven/internal/aether/DefaultRepositorySystemSessionFactory.java b/maven-core/src/main/java/org/apache/maven/internal/aether/DefaultRepositorySystemSessionFactory.java index 2e6a8a5a5e3a..8973b2000b74 100644 --- a/maven-core/src/main/java/org/apache/maven/internal/aether/DefaultRepositorySystemSessionFactory.java +++ b/maven-core/src/main/java/org/apache/maven/internal/aether/DefaultRepositorySystemSessionFactory.java @@ -19,15 +19,6 @@ * under the License. */ -import java.io.IOException; -import java.io.InputStream; -import java.util.LinkedHashMap; -import java.util.Map; -import java.util.Properties; - -import javax.inject.Inject; -import javax.inject.Named; - import org.apache.maven.RepositoryUtils; import org.apache.maven.artifact.handler.manager.ArtifactHandlerManager; import org.apache.maven.bridge.MavenRepositorySystem; @@ -60,6 +51,14 @@ import org.eclipse.aether.util.repository.SimpleResolutionErrorPolicy; import org.eclipse.sisu.Nullable; +import javax.inject.Inject; +import javax.inject.Named; +import java.io.IOException; +import java.io.InputStream; +import java.util.LinkedHashMap; +import java.util.Map; +import java.util.Properties; + /** * @since 3.3.0 */ @@ -93,7 +92,7 @@ public class DefaultRepositorySystemSessionFactory @Inject MavenRepositorySystem mavenRepositorySystem; - + public DefaultRepositorySystemSession newRepositorySession( MavenExecutionRequest request ) { DefaultRepositorySystemSession session = MavenRepositorySystemUtils.newSession(); @@ -241,7 +240,7 @@ else if ( request.isUpdateSnapshots() ) return session; } - + private String getUserAgent() { return "Apache-Maven/" + getMavenVersion() + " (Java " + System.getProperty( "java.version" ) + "; " @@ -268,4 +267,4 @@ private String getMavenVersion() return props.getProperty( "version", "unknown-version" ); } -} +} \ No newline at end of file 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 8d93ea458388..ece47190b519 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 @@ -543,7 +543,6 @@ private boolean build( List results, List Model model = result.getEffectiveModel(); - // move to here!! poolBuilder.put( model.getPomFile().toPath(), result.getRawModel() ); try diff --git a/maven-core/src/test/java/org/apache/maven/project/ProjectBuilderTest.java b/maven-core/src/test/java/org/apache/maven/project/ProjectBuilderTest.java index 6c7fbf913c37..538f887b02d2 100644 --- a/maven-core/src/test/java/org/apache/maven/project/ProjectBuilderTest.java +++ b/maven-core/src/test/java/org/apache/maven/project/ProjectBuilderTest.java @@ -159,7 +159,7 @@ public void testReadModifiedPoms() throws Exception { File parent = new File( tempDir.toFile(), "pom.xml" ); String parentContent = FileUtils.fileRead( parent ); parentContent = parentContent.replaceAll( "pom", - "pomaddedValue" ); + "pomaddedValue" ); FileUtils.fileWrite( parent, "UTF-8", parentContent ); // re-build pom with modified parent ProjectBuildingResult result = projectBuilder.build( child, configuration ); @@ -330,4 +330,4 @@ public void testBuildProperties() assertEquals( 1, project.getMailingLists().size() ); assertEquals( 1, project.getResources().size() ); } -} \ No newline at end of file +} 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 3b252967e5a2..ff7fb911a043 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 @@ -292,7 +292,7 @@ public ModelBuildingResult build( ModelBuildingRequest request ) { inputModel = readModel( request.getModelSource(), request.getPomFile(), request, problems ); } - + problems.setRootModel( inputModel ); ModelData resultData = new ModelData( request.getModelSource(), inputModel ); @@ -438,11 +438,6 @@ else if ( !parentIds.add( parentData.getId() ) ) result.setEffectiveModel( resultModel ); - if ( request.getPomFile() != null ) - { - // request.getModelCache().put( request.getPomFile().toPath(), resultModel ); - } - for ( ModelData currentData : lineage ) { String modelId = ( currentData != superData ) ? currentData.getId() : ""; From e0093d56bbfe31115b6d9027cede43848a4c4221 Mon Sep 17 00:00:00 2001 From: rfscholte Date: Tue, 3 Mar 2020 22:46:19 +0100 Subject: [PATCH 35/52] [MNG-6656] Changes based on review comments. Introduce AbstractModelSourceTransformer to have 1 class for transforming pom files. --- .../maven/project/DefaultProjectBuilder.java | 167 ++++++--------- .../maven/project/ReactorModelPool.java | 13 +- .../AbstractModelSourceTransformer.java | 194 ++++++++++++++++++ .../model/building/DefaultModelBuilder.java | 2 +- .../DefaultModelSourceTransformer.java | 60 ++---- .../building/ModelSourceTransformer.java | 7 +- .../model/building/TransformerException.java | 40 ++++ .../maven/model/io/DefaultModelReader.java | 6 +- .../sax/filter/ConsumerPomXMLFilterTest.java | 8 +- 9 files changed, 332 insertions(+), 165 deletions(-) create mode 100644 maven-model-builder/src/main/java/org/apache/maven/model/building/AbstractModelSourceTransformer.java create mode 100644 maven-model-builder/src/main/java/org/apache/maven/model/building/TransformerException.java 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 ece47190b519..4b9821af8355 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 @@ -20,12 +20,9 @@ */ import java.io.File; -import java.io.FileInputStream; -import java.io.FileNotFoundException; import java.io.IOException; import java.io.InputStream; -import java.io.PipedInputStream; -import java.io.PipedOutputStream; +import java.nio.file.Files; import java.nio.file.Path; import java.util.AbstractMap; import java.util.ArrayList; @@ -38,10 +35,7 @@ import java.util.List; import java.util.Map; import java.util.Set; -import java.util.concurrent.ExecutorService; -import java.util.concurrent.Executors; -import javax.xml.parsers.FactoryConfigurationError; import javax.xml.parsers.ParserConfigurationException; import javax.xml.stream.XMLInputFactory; import javax.xml.stream.XMLStreamException; @@ -49,12 +43,8 @@ import javax.xml.transform.OutputKeys; import javax.xml.transform.Transformer; import javax.xml.transform.TransformerConfigurationException; -import javax.xml.transform.TransformerException; -import javax.xml.transform.sax.SAXResult; -import javax.xml.transform.sax.SAXSource; import javax.xml.transform.sax.SAXTransformerFactory; import javax.xml.transform.sax.TransformerHandler; -import javax.xml.transform.stream.StreamResult; import org.apache.maven.RepositoryUtils; import org.apache.maven.artifact.Artifact; @@ -73,6 +63,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.AbstractModelSourceTransformer; import org.apache.maven.model.building.ArtifactModelSource; import org.apache.maven.model.building.DefaultBuildPomXMLFilterFactory; import org.apache.maven.model.building.DefaultModelBuildingRequest; @@ -91,7 +82,6 @@ import org.apache.maven.repository.internal.ArtifactDescriptorUtils; import org.apache.maven.xml.Factories; import org.apache.maven.xml.sax.filter.AbstractSAXFilter; -import org.apache.maven.xml.sax.filter.BuildPomXMLFilterFactory; import org.apache.maven.xml.sax.filter.ConsumerPomXMLFilterFactory; import org.codehaus.plexus.component.annotations.Component; import org.codehaus.plexus.component.annotations.Requirement; @@ -109,7 +99,6 @@ import org.eclipse.aether.resolution.ArtifactResult; import org.eclipse.aether.transform.FileTransformer; import org.eclipse.aether.transform.TransformException; -import org.xml.sax.InputSource; import org.xml.sax.SAXException; /** @@ -934,7 +923,7 @@ HashMap compute() DeploymentRepository r = project.getDistributionManagement().getRepository(); if ( !StringUtils.isEmpty( r.getId() ) && !StringUtils.isEmpty( r.getUrl() ) ) { - ArtifactRepository repo = repositorySystem.buildArtifactRepository( r ); + ArtifactRepository repo = MavenRepositorySystem.buildArtifactRepository( r ); repositorySystem.injectProxy( projectBuildingRequest.getRepositorySession(), Arrays.asList( repo ) ); repositorySystem.injectAuthentication( projectBuildingRequest.getRepositorySession(), @@ -958,7 +947,7 @@ HashMap compute() DeploymentRepository r = project.getDistributionManagement().getSnapshotRepository(); if ( !StringUtils.isEmpty( r.getId() ) && !StringUtils.isEmpty( r.getUrl() ) ) { - ArtifactRepository repo = repositorySystem.buildArtifactRepository( r ); + ArtifactRepository repo = MavenRepositorySystem.buildArtifactRepository( r ); repositorySystem.injectProxy( projectBuildingRequest.getRepositorySession(), Arrays.asList( repo ) ); repositorySystem.injectAuthentication( projectBuildingRequest.getRepositorySession(), @@ -1122,56 +1111,20 @@ private Collection getTransformersForArtifact( final org.eclips Collection transformers = new ArrayList<>(); if ( "pom".equals( artifact.getExtension() ) ) { - final SAXTransformerFactory transformerFactory = - (SAXTransformerFactory) Factories.newTransformerFactory(); - transformers.add( new FileTransformer() { @Override - public InputStream transformData( File file ) + public InputStream transformData( File pomFile ) throws IOException, TransformException { - final PipedOutputStream pipedOutputStream = new PipedOutputStream(); - final PipedInputStream pipedInputStream = new PipedInputStream( pipedOutputStream ); - - final TransformerHandler transformerHandler = - getTransformerHandler( transformerFactory, file ); - - BuildPomXMLFilterFactory buildPomXmlFactory = new DefaultBuildPomXMLFilterFactory( context ); - - final SAXSource transformSource; try { - AbstractSAXFilter filter = - new ConsumerPomXMLFilterFactory( buildPomXmlFactory ).get( file.toPath() ); - filter.setLexicalHandler( transformerHandler ); - - transformSource = - new SAXSource( filter, new InputSource( new FileInputStream( file ) ) ); - } - catch ( SAXException | ParserConfigurationException | TransformerConfigurationException e ) - { - throw new TransformException( "Failed to create a consumerPomXMLFilter", e ); + return new ConsumerModelSourceTransformer().transform( pomFile.toPath(), context ); } - - transformerHandler.setResult( new StreamResult( pipedOutputStream ) ); - - SAXResult transformResult = new SAXResult( transformerHandler ); - - ExecutorService executorService = Executors.newSingleThreadExecutor(); - executorService.execute( () -> + catch ( org.apache.maven.model.building.TransformerException e ) { - try ( PipedOutputStream out = pipedOutputStream ) - { - transformerFactory.newTransformer().transform( transformSource, transformResult ); - } - catch ( TransformerException | IOException e ) - { - throw new RuntimeException( e ); - } - } ); - - return pipedInputStream; + throw new TransformException( e ); + } } @Override @@ -1184,51 +1137,6 @@ public org.eclipse.aether.artifact.Artifact transformArtifact( } return Collections.unmodifiableCollection( transformers ); } - - private static TransformerHandler getTransformerHandler( SAXTransformerFactory transformerFactory, - File file ) - throws IOException, FileNotFoundException, TransformException - { - final TransformerHandler transformerHandler; - - // Keep same encoding+version - try ( FileInputStream input = new FileInputStream( file ) ) - { - XMLStreamReader streamReader = - XMLInputFactory.newFactory().createXMLStreamReader( input ); - - transformerHandler = transformerFactory.newTransformerHandler(); - - final String encoding = streamReader.getCharacterEncodingScheme(); - final String version = streamReader.getVersion(); - - Transformer transformer = transformerHandler.getTransformer(); - if ( encoding == null && version == null ) - { - transformer.setOutputProperty( OutputKeys.OMIT_XML_DECLARATION, "yes" ); - } - else - { - transformer.setOutputProperty( OutputKeys.OMIT_XML_DECLARATION, "no" ); - - if ( encoding != null ) - { - transformer.setOutputProperty( OutputKeys.ENCODING, encoding ); - } - if ( version != null ) - { - transformer.setOutputProperty( OutputKeys.VERSION, version ); - } - } - } - catch ( XMLStreamException - | FactoryConfigurationError - | TransformerConfigurationException e ) - { - throw new TransformException( "Failed to detect XML encoding and version", e ); - } - return transformerHandler; - } /** * InternalConfig @@ -1259,6 +1167,63 @@ class InternalConfig } + static class ConsumerModelSourceTransformer extends AbstractModelSourceTransformer + { + @Override + protected AbstractSAXFilter getSAXFilter( Path pomFile, TransformerContext context ) + throws TransformerConfigurationException, SAXException, ParserConfigurationException + { + return new ConsumerPomXMLFilterFactory( new DefaultBuildPomXMLFilterFactory( context ) ).get( pomFile ); + } + + @Override + protected TransformerHandler getTransformerHandler( Path pomFile ) + throws IOException, org.apache.maven.model.building.TransformerException + { + final TransformerHandler transformerHandler; + + final SAXTransformerFactory transformerFactory = + (SAXTransformerFactory) Factories.newTransformerFactory(); + + // Keep same encoding+version + try ( InputStream input = Files.newInputStream( pomFile ) ) + { + XMLStreamReader streamReader = + XMLInputFactory.newFactory().createXMLStreamReader( input ); + + transformerHandler = transformerFactory.newTransformerHandler(); + + final String encoding = streamReader.getCharacterEncodingScheme(); + final String version = streamReader.getVersion(); + + Transformer transformer = transformerHandler.getTransformer(); + if ( encoding == null && version == null ) + { + transformer.setOutputProperty( OutputKeys.OMIT_XML_DECLARATION, "yes" ); + } + else + { + transformer.setOutputProperty( OutputKeys.OMIT_XML_DECLARATION, "no" ); + + if ( encoding != null ) + { + transformer.setOutputProperty( OutputKeys.ENCODING, encoding ); + } + if ( version != null ) + { + transformer.setOutputProperty( OutputKeys.VERSION, version ); + } + } + } + catch ( XMLStreamException | TransformerConfigurationException e ) + { + throw new org.apache.maven.model.building.TransformerException( + "Failed to detect XML encoding and version", e ); + } + return transformerHandler; + } + } + private ReactorModelCache getModelCache() { return this.modelCache; 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 64101104fa07..3a788e6e8579 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 @@ -36,7 +36,7 @@ * reactor when building another project's effective model. * * @author Benjamin Bentmann - * @Robert Scholte + * @author Robert Scholte */ class ReactorModelPool { @@ -45,12 +45,12 @@ class ReactorModelPool private final Map modelsByPath = new HashMap<>(); /** - * This used to be the only method, which + * Get the model by its GAV or (since 3.7.0) by its GA if there is only one. * * @param groupId, never {@code null} * @param artifactId, never {@code null} * @param version, can be {@code null} - * @return the matching model + * @return the matching model or {@code null} * @throws IllegalStateException if version was null and multiple modules share the same groupId + artifactId * @throws NoSuchElementException if model could not be found */ @@ -66,6 +66,13 @@ public Model get( String groupId, String artifactId, String version ) } ).orElse( null ); } + /** + * Find model by path, useful when location the parent by relativePath + * + * @param path + * @return the matching model or {@code null} + * @since 3.7.0 + */ public Model get( Path path ) { final Path pomFile; diff --git a/maven-model-builder/src/main/java/org/apache/maven/model/building/AbstractModelSourceTransformer.java b/maven-model-builder/src/main/java/org/apache/maven/model/building/AbstractModelSourceTransformer.java new file mode 100644 index 000000000000..db26715bb8c9 --- /dev/null +++ b/maven-model-builder/src/main/java/org/apache/maven/model/building/AbstractModelSourceTransformer.java @@ -0,0 +1,194 @@ +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.FilterInputStream; +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.concurrent.atomic.AtomicInteger; + +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.SAXResult; +import javax.xml.transform.sax.SAXSource; +import javax.xml.transform.sax.TransformerHandler; +import javax.xml.transform.stream.StreamResult; + +import org.apache.maven.xml.Factories; +import org.apache.maven.xml.sax.filter.AbstractSAXFilter; +import org.xml.sax.SAXException; + +/** + * + * @author Robert Scholte + * @since 3.7.0 + */ +public abstract class AbstractModelSourceTransformer + implements ModelSourceTransformer +{ + private static final AtomicInteger TRANSFORM_THREAD_COUNTER = new AtomicInteger(); + + private final TransformerFactory transformerFactory = Factories.newTransformerFactory(); + + protected abstract AbstractSAXFilter getSAXFilter( Path pomFile, TransformerContext context ) + throws TransformerConfigurationException, SAXException, ParserConfigurationException; + + protected OutputStream filterOutputStream( OutputStream outputStream, Path pomFile ) + { + return outputStream; + } + + protected TransformerHandler getTransformerHandler( Path pomFile ) + throws IOException, org.apache.maven.model.building.TransformerException + { + return null; + } + + @Override + public final InputStream transform( Path pomFile, TransformerContext context ) + throws IOException, org.apache.maven.model.building.TransformerException + { + final TransformerHandler transformerHandler = getTransformerHandler( pomFile ); + + final AbstractSAXFilter filter; + try + { + filter = getSAXFilter( pomFile, context ); + filter.setLexicalHandler( transformerHandler ); + } + catch ( TransformerConfigurationException | SAXException | ParserConfigurationException e ) + { + throw new org.apache.maven.model.building.TransformerException( e ); + } + + final SAXSource transformSource = + new SAXSource( filter, + new org.xml.sax.InputSource( new FileInputStream( pomFile.toFile() ) ) ); + + final PipedOutputStream pout = new PipedOutputStream(); + final PipedInputStream pipedInputStream = new PipedInputStream( pout ); + + OutputStream out = filterOutputStream( pout, pomFile ); + + final javax.xml.transform.Result result; + if ( transformerHandler == null ) + { + result = new StreamResult( out ); + } + else + { + transformerHandler.setResult( new StreamResult( out ) ); + result = new SAXResult( transformerHandler ); + } + + IOExceptionHandler eh = new IOExceptionHandler(); + + Thread transformThread = new Thread( () -> + { + try ( PipedOutputStream pos = pout ) + { + transformerFactory.newTransformer().transform( transformSource, result ); + } + catch ( TransformerException | IOException e ) + { + eh.uncaughtException( Thread.currentThread(), e ); + } + }, "TransformThread-" + TRANSFORM_THREAD_COUNTER.incrementAndGet() ); + transformThread.setUncaughtExceptionHandler( eh ); + transformThread.setDaemon( true ); + transformThread.start(); + + return new ThreadAwareInputStream( pipedInputStream, eh ); + } + + private static class IOExceptionHandler + implements Thread.UncaughtExceptionHandler, AutoCloseable + { + private volatile Throwable cause; + + @Override + public void uncaughtException( Thread t, Throwable e ) + { + try + { + throw e; + } + catch ( TransformerException | IOException | RuntimeException | Error allGood ) + { + // all good + this.cause = e; + } + catch ( Throwable notGood ) + { + throw new AssertionError( "Unexpected Exception", e ); + } + } + + @Override + public void close() + throws IOException + { + if ( cause != null ) + { + try + { + throw cause; + } + catch ( IOException | RuntimeException | Error e ) + { + throw e; + } + catch ( Throwable t ) + { + throw new AssertionError(); + } + } + } + } + + private class ThreadAwareInputStream + extends FilterInputStream + { + final IOExceptionHandler h; + + protected ThreadAwareInputStream( InputStream in, IOExceptionHandler h ) + { + super( in ); + this.h = h; + } + + @Override + public void close() + throws IOException + { + try ( IOExceptionHandler eh = h ) + { + super.close(); + } + } + } +} 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 ff7fb911a043..9b6c5d8f4647 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 @@ -1551,7 +1551,7 @@ protected boolean hasFatalErrors( ModelProblemCollectorExt problems ) } /** - * As long is Maven controls the BuildPomXMLFilter, the entities that need merging is known. + * As long as Maven controls the BuildPomXMLFilter, the entities that need merging are known. * All others can simply be copied from source to target to restore the locationTracker * * @author Robert Scholte 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 index a9647543f7f3..f410551df199 100644 --- 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 @@ -19,13 +19,9 @@ * 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; @@ -33,12 +29,8 @@ 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.AbstractSAXFilter; import org.apache.maven.xml.sax.filter.BuildPomXMLFilterFactory; import org.apache.maven.xml.sax.filter.BuildPomXMLFilterListener; import org.eclipse.sisu.Nullable; @@ -51,30 +43,27 @@ */ @Named @Singleton -public class DefaultModelSourceTransformer implements ModelSourceTransformer +public class DefaultModelSourceTransformer extends AbstractModelSourceTransformer { @Inject @Nullable private BuildPomXMLFilterListener xmlFilterListener; - @Override - public final InputStream transform( Path pomFile, TransformerContext context ) - throws IOException, TransformerConfigurationException, SAXException, ParserConfigurationException + protected AbstractSAXFilter getSAXFilter( Path pomFile, TransformerContext context ) + throws TransformerConfigurationException, SAXException, ParserConfigurationException { - final BuildPomXMLFilterFactory buildPomXMLFilterFactory = new DefaultBuildPomXMLFilterFactory( context ); - final TransformerFactory transformerFactory = Factories.newTransformerFactory() ; + BuildPomXMLFilterFactory buildPomXMLFilterFactory = new DefaultBuildPomXMLFilterFactory( context ); - 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() ) ) ); - + return buildPomXMLFilterFactory.get( pomFile ); + } + + @Override + protected OutputStream filterOutputStream( OutputStream outputStream, Path pomFile ) + { OutputStream out; if ( xmlFilterListener != null ) { - out = new FilterOutputStream( pipedOutputStream ) + out = new FilterOutputStream( outputStream ) { @Override public void write( byte[] b, int off, int len ) @@ -87,29 +76,8 @@ public void write( byte[] b, int off, int len ) } else { - out = pipedOutputStream; + out = outputStream; } - - 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; + return out; } } 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 3d215f4dabb7..2aa3ddb48dcf 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 @@ -23,11 +23,6 @@ import java.io.InputStream; import java.nio.file.Path; -import javax.xml.parsers.ParserConfigurationException; -import javax.xml.transform.TransformerConfigurationException; - -import org.xml.sax.SAXException; - /** * * @author Robert Scholte @@ -36,5 +31,5 @@ public interface ModelSourceTransformer { InputStream transform( Path pomFile, TransformerContext context ) - throws IOException, TransformerConfigurationException, SAXException, ParserConfigurationException; + throws IOException, TransformerException; } diff --git a/maven-model-builder/src/main/java/org/apache/maven/model/building/TransformerException.java b/maven-model-builder/src/main/java/org/apache/maven/model/building/TransformerException.java new file mode 100644 index 000000000000..6c89d67b2c57 --- /dev/null +++ b/maven-model-builder/src/main/java/org/apache/maven/model/building/TransformerException.java @@ -0,0 +1,40 @@ +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. + */ + +/** + * + * @author Robert Scholte + * @since 3.7.0 + */ +public class TransformerException extends Exception +{ + + public TransformerException( Exception e ) + { + super ( e ); + } + + public TransformerException( String message, Throwable exception ) + { + super( message, exception ); + } + +} 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 86060aeffe58..ea0a55d77cd8 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 @@ -30,19 +30,17 @@ 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.InputSource; import org.apache.maven.model.Model; import org.apache.maven.model.building.ModelSourceTransformer; import org.apache.maven.model.building.TransformerContext; +import org.apache.maven.model.building.TransformerException; import org.apache.maven.model.io.xpp3.MavenXpp3Reader; import org.apache.maven.model.io.xpp3.MavenXpp3ReaderEx; import org.codehaus.plexus.util.ReaderFactory; import org.codehaus.plexus.util.xml.XmlStreamReader; import org.codehaus.plexus.util.xml.pull.XmlPullParserException; -import org.xml.sax.SAXException; /** * Handles deserialization of a model from some kind of textual format like XML. @@ -85,7 +83,7 @@ public Model read( File input, Map options ) { is = transformer.transform( input.toPath(), context ); } - catch ( TransformerConfigurationException | SAXException | ParserConfigurationException e ) + catch ( TransformerException e ) { throw new IOException( "Failed to transform " + input, e ); } 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 03cc87d8864e..16d458b79ada 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 @@ -36,10 +36,10 @@ public class ConsumerPomXMLFilterTest extends AbstractXMLFilterTests { @Override - protected String omitXmlDeclaration() - { - return "no"; - } + protected String omitXmlDeclaration() + { + return "no"; + } @Override protected AbstractSAXFilter getFilter() throws SAXException, ParserConfigurationException, TransformerConfigurationException From 447f33e0e3ab11a314dbc545a8cfc8cdf393a7fc Mon Sep 17 00:00:00 2001 From: rfscholte Date: Sat, 14 Mar 2020 13:47:06 +0100 Subject: [PATCH 36/52] [MNG-6656] Process review comments --- .../model/building/DefaultModelBuilder.java | 1 + .../maven/model/io/DefaultModelReader.java | 9 ++- .../xml/sax/filter/ModulesXMLFilter.java | 76 +++++++++---------- .../xml/sax/filter/RelativePathXMLFilter.java | 4 +- .../xml/sax/filter/ModulesXMLFilterTest.java | 19 +++++ 5 files changed, 65 insertions(+), 44 deletions(-) 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 6245c8a0d755..77a117da7acc 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 @@ -540,6 +540,7 @@ public Result buildRawModel( File pomFile, int validationLevel, } } + @SuppressWarnings( "checkstyle:methodlength" ) private Model readModel( ModelSource modelSource, File pomFile, ModelBuildingRequest request, DefaultModelProblemCollector problems ) throws ModelBuildingException 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 ea0a55d77cd8..7224207b13f9 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 @@ -89,11 +89,14 @@ public Model read( File input, Map options ) } } - Model model = read( is, options ); + try ( InputStream in = is ) + { + Model model = read( is, options ); - model.setPomFile( input ); + model.setPomFile( input ); - return model; + return model; + } } @Override diff --git a/maven-xml/src/main/java/org/apache/maven/xml/sax/filter/ModulesXMLFilter.java b/maven-xml/src/main/java/org/apache/maven/xml/sax/filter/ModulesXMLFilter.java index 16ca2edb35c7..261c853f9c41 100644 --- a/maven-xml/src/main/java/org/apache/maven/xml/sax/filter/ModulesXMLFilter.java +++ b/maven-xml/src/main/java/org/apache/maven/xml/sax/filter/ModulesXMLFilter.java @@ -31,15 +31,11 @@ * @since 3.7.0 */ class ModulesXMLFilter - extends AbstractSAXFilter + extends AbstractEventXMLFilter { - /** - * Using 3 to also remove whitespace-block after closing tag - * -1 none - * 1 started - * 2 ended - */ - int modulesStatus = -1; + private boolean parsingModules; + + private String state; ModulesXMLFilter() { @@ -55,57 +51,61 @@ ModulesXMLFilter( T parent ) public void startElement( String uri, String localName, String qName, Attributes atts ) throws SAXException { - if ( modulesStatus == -1 && "modules".equals( localName ) ) - { - modulesStatus = 1; - } - else if ( modulesStatus == 2 ) + if ( !parsingModules && "modules".equals( localName ) ) { - modulesStatus = -1; + parsingModules = true; } - if ( modulesStatus != 1 ) + if ( parsingModules ) { - super.startElement( uri, localName, qName, atts ); + state = localName; } + + super.startElement( uri, localName, qName, atts ); } - + @Override public void endElement( String uri, String localName, String qName ) throws SAXException { - if ( modulesStatus == 1 && "modules".equals( localName ) ) + if ( parsingModules ) { - modulesStatus = 2; + switch ( localName ) + { + case "modules": + executeEvents(); + + parsingModules = false; + break; + default: + super.endElement( uri, localName, qName ); + break; + } } - else if ( modulesStatus == 2 ) - { - modulesStatus = -1; - } - - if ( modulesStatus == -1 ) + else { super.endElement( uri, localName, qName ); } + + // for this simple structure resetting to modules it sufficient + state = "modules"; + } + + @Override + protected boolean isParsing() + { + return parsingModules; } @Override - public void characters( char[] ch, int start, int length ) - throws SAXException + protected String getState() { - if ( modulesStatus == -1 ) - { - super.characters( ch, start, length ); - } + return state; } - + @Override - public void comment( char[] ch, int start, int length ) - throws SAXException + protected boolean acceptEvent( String state ) { - if ( modulesStatus != 1 ) - { - super.comment( ch, start, length ); - } + return false; } } diff --git a/maven-xml/src/main/java/org/apache/maven/xml/sax/filter/RelativePathXMLFilter.java b/maven-xml/src/main/java/org/apache/maven/xml/sax/filter/RelativePathXMLFilter.java index ebbc890347c2..25f2137be521 100644 --- a/maven-xml/src/main/java/org/apache/maven/xml/sax/filter/RelativePathXMLFilter.java +++ b/maven-xml/src/main/java/org/apache/maven/xml/sax/filter/RelativePathXMLFilter.java @@ -25,9 +25,7 @@ import org.xml.sax.ext.LexicalHandler; /** - * Remove content from relativePath - * - * TODO fix indentation of closing parent tag + * Remove relativePath element, has no value for consumer pom * * @author Robert Scholte * @since 3.7.0 diff --git a/maven-xml/src/test/java/org/apache/maven/xml/sax/filter/ModulesXMLFilterTest.java b/maven-xml/src/test/java/org/apache/maven/xml/sax/filter/ModulesXMLFilterTest.java index a3477dfffc71..552b72140717 100644 --- a/maven-xml/src/test/java/org/apache/maven/xml/sax/filter/ModulesXMLFilterTest.java +++ b/maven-xml/src/test/java/org/apache/maven/xml/sax/filter/ModulesXMLFilterTest.java @@ -73,4 +73,23 @@ public void comment() throws Exception { String actual = transform( input ); assertThat( actual ).and( expected ).areIdentical(); } + + @Test + public void setOfModulesLF() throws Exception { + String input = "\n" + + "\n" + + " \n" + + " ab\n" + + " ../cd\n" + + " \n" + + "\n" + + "\n"; + String expected = "\n" + + "\n" + + " \n" + + "\n" + + "\n"; + String actual = transform( input ); + assertThat( actual ).and( expected ).areIdentical(); + } } From f998d903d346d833b16addf7dcefe02fc3bdd9f4 Mon Sep 17 00:00:00 2001 From: rfscholte Date: Sun, 5 Apr 2020 16:48:35 +0200 Subject: [PATCH 37/52] [MNG-6656] restore publishing valid consumer poms. Improve Exception Handling --- .../ConsumerModelSourceTransformer.java | 110 ++++++++++++++++++ ...DefaultRepositorySystemSessionFactory.java | 50 +++++++- .../maven/project/DefaultProjectBuilder.java | 54 ++------- .../AbstractModelSourceTransformer.java | 2 +- .../DefaultBuildPomXMLFilterFactory.java | 18 --- .../sax/filter/BuildPomXMLFilterFactory.java | 17 --- 6 files changed, 166 insertions(+), 85 deletions(-) create mode 100644 maven-core/src/main/java/org/apache/maven/internal/aether/ConsumerModelSourceTransformer.java 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 new file mode 100644 index 000000000000..0f92f66f46ed --- /dev/null +++ b/maven-core/src/main/java/org/apache/maven/internal/aether/ConsumerModelSourceTransformer.java @@ -0,0 +1,110 @@ +package org.apache.maven.internal.aether; + +/* + * 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.IOException; +import java.io.InputStream; +import java.nio.file.Files; +import java.nio.file.Path; + +import javax.xml.parsers.ParserConfigurationException; +import javax.xml.stream.XMLInputFactory; +import javax.xml.stream.XMLStreamException; +import javax.xml.stream.XMLStreamReader; +import javax.xml.transform.OutputKeys; +import javax.xml.transform.Transformer; +import javax.xml.transform.TransformerConfigurationException; +import javax.xml.transform.sax.SAXTransformerFactory; +import javax.xml.transform.sax.TransformerHandler; + +import org.apache.maven.model.building.AbstractModelSourceTransformer; +import org.apache.maven.model.building.DefaultBuildPomXMLFilterFactory; +import org.apache.maven.model.building.TransformerContext; +import org.apache.maven.xml.Factories; +import org.apache.maven.xml.internal.DefaultConsumerPomXMLFilterFactory; +import org.apache.maven.xml.sax.filter.AbstractSAXFilter; +import org.xml.sax.SAXException; + +class ConsumerModelSourceTransformer extends AbstractModelSourceTransformer +{ + @Override + protected AbstractSAXFilter getSAXFilter( Path pomFile, TransformerContext context ) + throws TransformerConfigurationException, SAXException, ParserConfigurationException + { + return new DefaultConsumerPomXMLFilterFactory( new DefaultBuildPomXMLFilterFactory( context ) ).get( pomFile ); + } + + /** + * This transformer will ensure that encoding and version are kept. + * However, it cannot prevent: + *
                + *
              • line-endings will be unix-style(LF)
              • + *
              • attributes will be on one line
              • + *
              • Unnecessary whitespace before the rootelement will be remove
              • + *
              + */ + @Override + protected TransformerHandler getTransformerHandler( Path pomFile ) + throws IOException, org.apache.maven.model.building.TransformerException + { + final TransformerHandler transformerHandler; + + final SAXTransformerFactory transformerFactory = + (SAXTransformerFactory) Factories.newTransformerFactory(); + + // Keep same encoding+version + try ( InputStream input = Files.newInputStream( pomFile ) ) + { + XMLStreamReader streamReader = + XMLInputFactory.newFactory().createXMLStreamReader( input ); + + transformerHandler = transformerFactory.newTransformerHandler(); + + final String encoding = streamReader.getCharacterEncodingScheme(); + final String version = streamReader.getVersion(); + + Transformer transformer = transformerHandler.getTransformer(); + if ( encoding == null && version == null ) + { + transformer.setOutputProperty( OutputKeys.OMIT_XML_DECLARATION, "yes" ); + } + else + { + transformer.setOutputProperty( OutputKeys.OMIT_XML_DECLARATION, "no" ); + + if ( encoding != null ) + { + transformer.setOutputProperty( OutputKeys.ENCODING, encoding ); + } + if ( version != null ) + { + transformer.setOutputProperty( OutputKeys.VERSION, version ); + } + } + } + catch ( XMLStreamException | TransformerConfigurationException e ) + { + throw new org.apache.maven.model.building.TransformerException( + "Failed to detect XML encoding and version", e ); + } + return transformerHandler; + } + +} diff --git a/maven-core/src/main/java/org/apache/maven/internal/aether/DefaultRepositorySystemSessionFactory.java b/maven-core/src/main/java/org/apache/maven/internal/aether/DefaultRepositorySystemSessionFactory.java index 8973b2000b74..d0dd442edad4 100644 --- a/maven-core/src/main/java/org/apache/maven/internal/aether/DefaultRepositorySystemSessionFactory.java +++ b/maven-core/src/main/java/org/apache/maven/internal/aether/DefaultRepositorySystemSessionFactory.java @@ -24,6 +24,8 @@ import org.apache.maven.bridge.MavenRepositorySystem; import org.apache.maven.eventspy.internal.EventSpyDispatcher; import org.apache.maven.execution.MavenExecutionRequest; +import org.apache.maven.feature.Features; +import org.apache.maven.model.building.TransformerContext; import org.apache.maven.repository.internal.MavenRepositorySystemUtils; import org.apache.maven.settings.Mirror; import org.apache.maven.settings.Proxy; @@ -44,6 +46,8 @@ import org.eclipse.aether.repository.WorkspaceReader; import org.eclipse.aether.resolution.ResolutionErrorPolicy; import org.eclipse.aether.spi.localrepo.LocalRepositoryManagerFactory; +import org.eclipse.aether.transform.FileTransformer; +import org.eclipse.aether.transform.TransformException; import org.eclipse.aether.util.repository.AuthenticationBuilder; import org.eclipse.aether.util.repository.DefaultAuthenticationSelector; import org.eclipse.aether.util.repository.DefaultMirrorSelector; @@ -53,8 +57,13 @@ import javax.inject.Inject; import javax.inject.Named; + +import java.io.File; import java.io.IOException; import java.io.InputStream; +import java.util.ArrayList; +import java.util.Collection; +import java.util.Collections; import java.util.LinkedHashMap; import java.util.Map; import java.util.Properties; @@ -96,7 +105,6 @@ public class DefaultRepositorySystemSessionFactory public DefaultRepositorySystemSession newRepositorySession( MavenExecutionRequest request ) { DefaultRepositorySystemSession session = MavenRepositorySystemUtils.newSession(); - session.setCache( request.getRepositoryCache() ); Map configProps = new LinkedHashMap<>(); @@ -139,7 +147,6 @@ else if ( request.isUpdateSnapshots() ) session.setLocalRepositoryManager( simpleLocalRepoMgrFactory.newInstance( session, localRepo ) ); logger.info( "Disabling enhanced local repository: using legacy is strongly discouraged to ensure" + " build reproducibility." ); - } catch ( NoLocalRepositoryManagerException e ) { @@ -238,6 +245,12 @@ else if ( request.isUpdateSnapshots() ) mavenRepositorySystem.injectProxy( session, request.getPluginArtifactRepositories() ); mavenRepositorySystem.injectAuthentication( session, request.getPluginArtifactRepositories() ); + if ( Features.buildConsumer().isActive() ) + { + session.setFileTransformerManager( a -> getTransformersForArtifact( a, + (TransformerContext) session.getData().get( TransformerContext.class ) ) ); + } + return session; } @@ -266,5 +279,38 @@ private String getMavenVersion() return props.getProperty( "version", "unknown-version" ); } + + private Collection getTransformersForArtifact( final org.eclipse.aether.artifact.Artifact artifact, + TransformerContext context ) + { + Collection transformers = new ArrayList<>(); + if ( "pom".equals( artifact.getExtension() ) ) + { + transformers.add( new FileTransformer() + { + @Override + public InputStream transformData( File pomFile ) + throws IOException, TransformException + { + try + { + return new ConsumerModelSourceTransformer().transform( pomFile.toPath(), context ); + } + catch ( org.apache.maven.model.building.TransformerException e ) + { + throw new TransformException( e ); + } + } + + @Override + public org.eclipse.aether.artifact.Artifact transformArtifact( + org.eclipse.aether.artifact.Artifact artifact ) + { + return artifact; + } + } ); + } + return Collections.unmodifiableCollection( transformers ); + } } \ No newline at end of file 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 4b9821af8355..265633d925d5 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 @@ -88,7 +88,6 @@ import org.codehaus.plexus.logging.Logger; import org.codehaus.plexus.util.Os; import org.codehaus.plexus.util.StringUtils; -import org.eclipse.aether.DefaultRepositorySystemSession; import org.eclipse.aether.RepositorySystemSession; import org.eclipse.aether.RequestTrace; import org.eclipse.aether.impl.RemoteRepositoryManager; @@ -97,8 +96,6 @@ import org.eclipse.aether.repository.WorkspaceRepository; import org.eclipse.aether.resolution.ArtifactRequest; import org.eclipse.aether.resolution.ArtifactResult; -import org.eclipse.aether.transform.FileTransformer; -import org.eclipse.aether.transform.TransformException; import org.xml.sax.SAXException; /** @@ -299,7 +296,6 @@ private ModelBuildingRequest getModelBuildingRequest( InternalConfig config, Fil RequestTrace trace = RequestTrace.newChild( null, configuration ).newChild( request ); - RepositorySystemSession repoSession; if ( Features.buildConsumer().isActive() ) { TransformerContext context = new TransformerContext() @@ -313,27 +309,24 @@ public String getUserProperty( String key ) @Override public Model getRawModel( Path p ) { - return config.modelPool.get( p ); + ReactorModelPool pool = config.modelPool; + return pool != null ? pool.get( p ) : null; } @Override public Model getRawModel( String groupId, String artifactId ) { - return config.modelPool.get( groupId, artifactId, null ); + ReactorModelPool pool = config.modelPool; + return pool != null ? pool.get( groupId, artifactId, null ) : null; } }; - request.setTransformerContext( context ); + config.session.getData().set( TransformerContext.class, context ); - repoSession = new DefaultRepositorySystemSession( config.session ) - .setFileTransformerManager( a -> getTransformersForArtifact( a, context ) ); - } - else - { - repoSession = config.session; + request.setTransformerContext( context ); } ModelResolver resolver = - new ProjectModelResolver( repoSession, trace, repoSystem, repositoryManager, config.repositories, + new ProjectModelResolver( config.session, trace, repoSystem, repositoryManager, config.repositories, configuration.getRepositoryMerging(), config.modelPool ); request.setValidationLevel( configuration.getValidationLevel() ); @@ -1104,39 +1097,6 @@ private String findProfilesXml( ModelBuildingResult result, Map p return null; } - - private Collection getTransformersForArtifact( final org.eclipse.aether.artifact.Artifact artifact, - TransformerContext context ) - { - Collection transformers = new ArrayList<>(); - if ( "pom".equals( artifact.getExtension() ) ) - { - transformers.add( new FileTransformer() - { - @Override - public InputStream transformData( File pomFile ) - throws IOException, TransformException - { - try - { - return new ConsumerModelSourceTransformer().transform( pomFile.toPath(), context ); - } - catch ( org.apache.maven.model.building.TransformerException e ) - { - throw new TransformException( e ); - } - } - - @Override - public org.eclipse.aether.artifact.Artifact transformArtifact( - org.eclipse.aether.artifact.Artifact artifact ) - { - return artifact; - } - } ); - } - return Collections.unmodifiableCollection( transformers ); - } /** * InternalConfig diff --git a/maven-model-builder/src/main/java/org/apache/maven/model/building/AbstractModelSourceTransformer.java b/maven-model-builder/src/main/java/org/apache/maven/model/building/AbstractModelSourceTransformer.java index db26715bb8c9..e0767fbec578 100644 --- a/maven-model-builder/src/main/java/org/apache/maven/model/building/AbstractModelSourceTransformer.java +++ b/maven-model-builder/src/main/java/org/apache/maven/model/building/AbstractModelSourceTransformer.java @@ -164,7 +164,7 @@ public void close() } catch ( Throwable t ) { - throw new AssertionError(); + throw new AssertionError( "Failed to transform pom", t ); } } } 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 9489e3b71f5d..3de90decbba9 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 @@ -48,24 +48,6 @@ public final TransformerContext getContext() return context; } - @Override - protected Optional getChangelist() - { - return Optional.ofNullable( context.getUserProperty( "changelist" ) ); - } - - @Override - protected Optional getRevision() - { - return Optional.ofNullable( context.getUserProperty( "revision" ) ); - } - - @Override - protected Optional getSha1() - { - return Optional.ofNullable( context.getUserProperty( "sha1" ) ); - } - @Override protected Function> getRelativePathMapper() { 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 d86200f9fcde..910bc1603a0f 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 @@ -99,23 +99,6 @@ private LexicalHandler getLexicalHander() throws TransformerConfigurationExcepti + " it is not an instance of SAXTransformerFactory" ); } - // getters for the 3 magic properties of CIFriendly versions ( https://maven.apache.org/maven-ci-friendly.html ) - - protected Optional getChangelist() - { - return Optional.empty(); - } - - protected Optional getRevision() - { - return Optional.empty(); - } - - protected Optional getSha1() - { - return Optional.empty(); - } - /** * @return the mapper or {@code null} if relativePaths don't need to be mapped */ From cc5e28e935f6fae1b1ccc5116b4d0462022fb621 Mon Sep 17 00:00:00 2001 From: rfscholte Date: Mon, 6 Apr 2020 20:17:31 +0200 Subject: [PATCH 38/52] [MNG-6656] Align version in parent --- .../sax/filter/AbstractEventXMLFilter.java | 43 +++++++++++++---- .../maven/xml/sax/filter/ParentXMLFilter.java | 46 +++++++++---------- .../xml/sax/filter/ParentXMLFilterTest.java | 23 ++++++++++ 3 files changed, 80 insertions(+), 32 deletions(-) diff --git a/maven-xml/src/main/java/org/apache/maven/xml/sax/filter/AbstractEventXMLFilter.java b/maven-xml/src/main/java/org/apache/maven/xml/sax/filter/AbstractEventXMLFilter.java index f718103b7080..d23bdec0085f 100644 --- a/maven-xml/src/main/java/org/apache/maven/xml/sax/filter/AbstractEventXMLFilter.java +++ b/maven-xml/src/main/java/org/apache/maven/xml/sax/filter/AbstractEventXMLFilter.java @@ -20,8 +20,6 @@ */ import java.util.ArrayDeque; -import java.util.HashMap; -import java.util.Map; import java.util.Queue; import org.apache.maven.xml.sax.SAXEvent; @@ -45,11 +43,10 @@ abstract class AbstractEventXMLFilter extends AbstractSAXFilter private SAXEventFactory eventFactory; // characters BEFORE startElement must get state of startingElement - // this way removing based on state keeps formatting + // this way removing based on state keeps correct formatting private SAXEvent characters; - // map of characters AFTER starting element, will be cleaned up after closeElement - private Map charactersMap = new HashMap<>(); + private boolean lockCharacters = false; protected abstract boolean isParsing(); @@ -87,7 +84,7 @@ private void processEvent( final SAXEvent event ) final String eventState = getState(); final SAXEvent charactersEvent = characters; - if ( charactersEvent != null ) + if ( !lockCharacters && charactersEvent != null ) { saxEvents.add( () -> { @@ -112,7 +109,20 @@ private void processEvent( final SAXEvent event ) event.execute(); } } - + + /** + * Should be used to include extra events before a closing element. + * This is a lightweight solution to keep the correct indentation. + * + * @return + */ + protected Includer include() + { + this.lockCharacters = true; + + return () -> lockCharacters = false; + } + protected final void executeEvents() throws SAXException { final String eventState = getState(); @@ -188,10 +198,13 @@ public void endElement( String uri, String localName, String qName ) throws SAXE @Override public void characters( char[] ch, int start, int length ) throws SAXException { - if ( isParsing() ) + if ( lockCharacters ) + { + processEvent( getEventFactory().characters( ch, start, length ) ); + } + else if ( isParsing() ) { this.characters = getEventFactory().characters( ch, start, length ); - this.charactersMap.put( getState(), characters ); } else { @@ -261,4 +274,16 @@ public void comment( char[] ch, int start, int length ) { processEvent( getEventFactory().comment( ch, start, length ) ); } + + /** + * AutoCloseable with a close method that doesn't throw an exception + * + * @author Robert Scholte + * + */ + @FunctionalInterface + protected interface Includer extends AutoCloseable + { + void close(); + } } 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 2531798938bf..df43ec1ef7d6 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 @@ -49,6 +49,9 @@ class ParentXMLFilter // states private String state; + // whiteSpace after , to be used to position + private String parentWhitespace = ""; + private String groupId; private String artifactId; @@ -120,15 +123,7 @@ public void characters( char[] ch, int start, int length ) switch ( eventState ) { case "parent": - int l; - for ( l = length ; l >= 0; l-- ) - { - int i = start + l - 1; - if ( ch[i] == '\n' || ch[i] == '\r' ) - { - break; - } - } + parentWhitespace = new String( ch, start, length ); break; case "relativePath": relativePath = new String( ch, start, length ); @@ -164,30 +159,35 @@ public void endElement( String uri, final String localName, String qName ) if ( !hasVersion && resolvedParent.isPresent() ) { - String versionQName = SAXEventUtils.renameQName( qName, "version" ); - - super.startElement( uri, "version", versionQName, null ); - - String resolvedParentVersion = resolvedParent.get().getVersion(); - - super.characters( resolvedParentVersion.toCharArray(), 0, - resolvedParentVersion.length() ); - - super.endElement( uri, "version", versionQName ); + try ( Includer i = super.include() ) + { + super.characters( parentWhitespace.toCharArray(), 0, + parentWhitespace.length() ); + + String versionQName = SAXEventUtils.renameQName( qName, "version" ); + + super.startElement( uri, "version", versionQName, null ); + + String resolvedParentVersion = resolvedParent.get().getVersion(); + + super.characters( resolvedParentVersion.toCharArray(), 0, + resolvedParentVersion.length() ); + + super.endElement( uri, "version", versionQName ); + } } - executeEvents(); + super.executeEvents(); parsingParent = false; break; default: + // marker? break; } } super.endElement( uri, localName, qName ); - - // for this simple structure resetting to parent it sufficient - state = "parent"; + state = ""; } protected Optional resolveRelativePath( Path relativePath ) 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 f98f4ddbed7d..bb0022249394 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 @@ -189,4 +189,27 @@ public void comment() throws Exception assertEquals( expected, actual ); } + @Test + public void testIndent() throws Exception + { + String input = "\n" + + " \n" + + " GROUPID\n" + + " ARTIFACTID\n" + + " \n" + + " \n" + + ""; + String expected = "" + System.lineSeparator() + + " " + System.lineSeparator() + + " GROUPID" + System.lineSeparator() + + " ARTIFACTID" + System.lineSeparator() + + " " + System.lineSeparator() + + " 1.0.0" + System.lineSeparator() + + " " + System.lineSeparator() + + ""; + + String actual = transform( input ); + + assertEquals( expected, actual ); + } } From 1af5ee7a36335e87f49553ee4ea8dc02a2fbb2b6 Mon Sep 17 00:00:00 2001 From: rfscholte Date: Tue, 5 May 2020 11:51:20 +0200 Subject: [PATCH 39/52] [MNG-6656] Move creation of TransformerContext to proper location Fix indentation for reactor dependencies --- .../maven/project/DefaultProjectBuilder.java | 57 +++++++++---------- .../filter/ReactorDependencyXMLFilter.java | 23 ++++++-- 2 files changed, 44 insertions(+), 36 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 265633d925d5..9645ca1b76fc 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 @@ -296,35 +296,6 @@ private ModelBuildingRequest getModelBuildingRequest( InternalConfig config, Fil RequestTrace trace = RequestTrace.newChild( null, configuration ).newChild( request ); - if ( Features.buildConsumer().isActive() ) - { - TransformerContext context = new TransformerContext() - { - @Override - public String getUserProperty( String key ) - { - return config.session.getUserProperties().get( key ); - } - - @Override - public Model getRawModel( Path p ) - { - ReactorModelPool pool = config.modelPool; - return pool != null ? pool.get( p ) : null; - } - - @Override - public Model getRawModel( String groupId, String artifactId ) - { - ReactorModelPool pool = config.modelPool; - return pool != null ? pool.get( groupId, artifactId, null ) : null; - } - }; - config.session.getData().set( TransformerContext.class, context ); - - request.setTransformerContext( context ); - } - ModelResolver resolver = new ProjectModelResolver( config.session, trace, repoSystem, repositoryManager, config.repositories, configuration.getRepositoryMerging(), config.modelPool ); @@ -339,6 +310,7 @@ public Model getRawModel( String groupId, String artifactId ) request.setBuildStartTime( configuration.getBuildStartTime() ); request.setModelResolver( resolver ); request.setModelCache( config.modelCache ); + request.setTransformerContext( (TransformerContext) config.session.getData().get( TransformerContext.class ) ); return request; } @@ -427,7 +399,32 @@ public List build( List pomFiles, boolean recursive List interimResults = new ArrayList<>(); ReactorModelPool.Builder poolBuilder = new ReactorModelPool.Builder(); - ReactorModelPool modelPool = poolBuilder.build(); + 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.class, context ); + } InternalConfig config = new InternalConfig( request, modelPool, useGlobalModelCache() ? getModelCache() : new ReactorModelCache() ); diff --git a/maven-xml/src/main/java/org/apache/maven/xml/sax/filter/ReactorDependencyXMLFilter.java b/maven-xml/src/main/java/org/apache/maven/xml/sax/filter/ReactorDependencyXMLFilter.java index 6f80f5aceb42..38f8fb8d2192 100644 --- a/maven-xml/src/main/java/org/apache/maven/xml/sax/filter/ReactorDependencyXMLFilter.java +++ b/maven-xml/src/main/java/org/apache/maven/xml/sax/filter/ReactorDependencyXMLFilter.java @@ -37,6 +37,9 @@ public class ReactorDependencyXMLFilter extends AbstractEventXMLFilter // states private String state; + + // whiteSpace after , to be used to position + private String dependencyWhitespace = ""; private boolean hasVersion; @@ -78,6 +81,9 @@ public void characters( char[] ch, int start, int length ) final String eventState = state; switch ( eventState ) { + case "dependency": + dependencyWhitespace = new String( ch, start, length ); + break; case "groupId": groupId = new String( ch, start, length ); break; @@ -107,11 +113,16 @@ public void endElement( String uri, final String localName, String qName ) // dependency is not part of reactor, probably it is managed if ( version != null ) { - String versionQName = SAXEventUtils.renameQName( qName, "version" ); - - super.startElement( uri, "version", versionQName, null ); - super.characters( version.toCharArray(), 0, version.length() ); - super.endElement( uri, "version", versionQName ); + try ( Includer i = super.include() ) + { + super.characters( dependencyWhitespace.toCharArray(), 0, + dependencyWhitespace.length() ); + String versionQName = SAXEventUtils.renameQName( qName, "version" ); + + super.startElement( uri, "version", versionQName, null ); + super.characters( version.toCharArray(), 0, version.length() ); + super.endElement( uri, "version", versionQName ); + } } } super.executeEvents(); @@ -131,7 +142,7 @@ public void endElement( String uri, final String localName, String qName ) super.endElement( uri, localName, qName ); - state = "dependency"; + state = ""; } private String getVersion() From 51b74adb8aea1f32b8db7584b4370f8424bb3ddd Mon Sep 17 00:00:00 2001 From: rfscholte Date: Sat, 6 Jun 2020 13:05:23 +0200 Subject: [PATCH 40/52] Fix lineseparator in comments --- apache-maven/maven-wrapper.pom | 5 + .../ConsumerModelSourceTransformer.java | 1 + ...DefaultRepositorySystemSessionFactory.java | 2 +- .../maven/project/DefaultProjectBuilder.java | 79 +------------ .../AbstractModelSourceTransformer.java | 4 +- .../model/building/TransformerContext.java | 2 + maven-xml/pom.xml | 8 +- .../xml/sax/ext/CommentRenormalizer.java | 108 ++++++++++++++++++ .../xml/sax/ext/CommentRenormalizerTest.java | 84 ++++++++++++++ 9 files changed, 213 insertions(+), 80 deletions(-) create mode 100644 maven-xml/src/main/java/org/apache/maven/xml/sax/ext/CommentRenormalizer.java create mode 100644 maven-xml/src/test/java/org/apache/maven/xml/sax/ext/CommentRenormalizerTest.java diff --git a/apache-maven/maven-wrapper.pom b/apache-maven/maven-wrapper.pom index f2bcc7fc141b..fc6755cff306 100644 --- a/apache-maven/maven-wrapper.pom +++ b/apache-maven/maven-wrapper.pom @@ -33,7 +33,12 @@ under the License. Apache Maven Wrapper Distribution The Apache Maven Wrapper distribution in zip and tar.gz formats. + + ${artifactId}-${project.version} + + + ${distributionFileName} 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 0f92f66f46ed..8ca0ca667a1f 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 @@ -81,6 +81,7 @@ protected TransformerHandler getTransformerHandler( Path pomFile ) final String version = streamReader.getVersion(); Transformer transformer = transformerHandler.getTransformer(); + transformer.setOutputProperty( OutputKeys.METHOD, "xml" ); if ( encoding == null && version == null ) { transformer.setOutputProperty( OutputKeys.OMIT_XML_DECLARATION, "yes" ); diff --git a/maven-core/src/main/java/org/apache/maven/internal/aether/DefaultRepositorySystemSessionFactory.java b/maven-core/src/main/java/org/apache/maven/internal/aether/DefaultRepositorySystemSessionFactory.java index d0dd442edad4..928d200277da 100644 --- a/maven-core/src/main/java/org/apache/maven/internal/aether/DefaultRepositorySystemSessionFactory.java +++ b/maven-core/src/main/java/org/apache/maven/internal/aether/DefaultRepositorySystemSessionFactory.java @@ -248,7 +248,7 @@ else if ( request.isUpdateSnapshots() ) if ( Features.buildConsumer().isActive() ) { session.setFileTransformerManager( a -> getTransformersForArtifact( a, - (TransformerContext) session.getData().get( TransformerContext.class ) ) ); + (TransformerContext) session.getData().get( TransformerContext.KEY ) ) ); } return session; 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 0def9e3467fe..f09941b1f238 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,8 +21,6 @@ import java.io.File; import java.io.IOException; -import java.io.InputStream; -import java.nio.file.Files; import java.nio.file.Path; import java.util.AbstractMap; import java.util.ArrayList; @@ -40,16 +38,6 @@ import javax.inject.Named; import javax.inject.Singleton; -import javax.xml.parsers.ParserConfigurationException; -import javax.xml.stream.XMLInputFactory; -import javax.xml.stream.XMLStreamException; -import javax.xml.stream.XMLStreamReader; -import javax.xml.transform.OutputKeys; -import javax.xml.transform.Transformer; -import javax.xml.transform.TransformerConfigurationException; -import javax.xml.transform.sax.SAXTransformerFactory; -import javax.xml.transform.sax.TransformerHandler; - import org.apache.maven.RepositoryUtils; import org.apache.maven.artifact.Artifact; import org.apache.maven.artifact.InvalidArtifactRTException; @@ -67,9 +55,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.AbstractModelSourceTransformer; import org.apache.maven.model.building.ArtifactModelSource; -import org.apache.maven.model.building.DefaultBuildPomXMLFilterFactory; import org.apache.maven.model.building.DefaultModelBuildingRequest; import org.apache.maven.model.building.DefaultModelProblem; import org.apache.maven.model.building.FileModelSource; @@ -84,9 +70,6 @@ import org.apache.maven.model.building.TransformerContext; import org.apache.maven.model.resolution.ModelResolver; import org.apache.maven.repository.internal.ArtifactDescriptorUtils; -import org.apache.maven.xml.Factories; -import org.apache.maven.xml.sax.filter.AbstractSAXFilter; -import org.apache.maven.xml.sax.filter.ConsumerPomXMLFilterFactory; import org.codehaus.plexus.logging.Logger; import org.codehaus.plexus.util.Os; import org.codehaus.plexus.util.StringUtils; @@ -98,7 +81,6 @@ import org.eclipse.aether.repository.WorkspaceRepository; import org.eclipse.aether.resolution.ArtifactRequest; import org.eclipse.aether.resolution.ArtifactResult; -import org.xml.sax.SAXException; /** * DefaultProjectBuilder @@ -313,7 +295,7 @@ private ModelBuildingRequest getModelBuildingRequest( InternalConfig config, Fil request.setBuildStartTime( configuration.getBuildStartTime() ); request.setModelResolver( resolver ); request.setModelCache( config.modelCache ); - request.setTransformerContext( (TransformerContext) config.session.getData().get( TransformerContext.class ) ); + request.setTransformerContext( (TransformerContext) config.session.getData().get( TransformerContext.KEY ) ); return request; } @@ -426,7 +408,7 @@ public Model getRawModel( String groupId, String artifactId ) return modelPool.get( groupId, artifactId, null ); } }; - request.getRepositorySession().getData().set( TransformerContext.class, context ); + request.getRepositorySession().getData().set( TransformerContext.KEY, context ); } InternalConfig config = new InternalConfig( request, modelPool, @@ -1127,63 +1109,6 @@ class InternalConfig } - static class ConsumerModelSourceTransformer extends AbstractModelSourceTransformer - { - @Override - protected AbstractSAXFilter getSAXFilter( Path pomFile, TransformerContext context ) - throws TransformerConfigurationException, SAXException, ParserConfigurationException - { - return new ConsumerPomXMLFilterFactory( new DefaultBuildPomXMLFilterFactory( context ) ).get( pomFile ); - } - - @Override - protected TransformerHandler getTransformerHandler( Path pomFile ) - throws IOException, org.apache.maven.model.building.TransformerException - { - final TransformerHandler transformerHandler; - - final SAXTransformerFactory transformerFactory = - (SAXTransformerFactory) Factories.newTransformerFactory(); - - // Keep same encoding+version - try ( InputStream input = Files.newInputStream( pomFile ) ) - { - XMLStreamReader streamReader = - XMLInputFactory.newFactory().createXMLStreamReader( input ); - - transformerHandler = transformerFactory.newTransformerHandler(); - - final String encoding = streamReader.getCharacterEncodingScheme(); - final String version = streamReader.getVersion(); - - Transformer transformer = transformerHandler.getTransformer(); - if ( encoding == null && version == null ) - { - transformer.setOutputProperty( OutputKeys.OMIT_XML_DECLARATION, "yes" ); - } - else - { - transformer.setOutputProperty( OutputKeys.OMIT_XML_DECLARATION, "no" ); - - if ( encoding != null ) - { - transformer.setOutputProperty( OutputKeys.ENCODING, encoding ); - } - if ( version != null ) - { - transformer.setOutputProperty( OutputKeys.VERSION, version ); - } - } - } - catch ( XMLStreamException | TransformerConfigurationException e ) - { - throw new org.apache.maven.model.building.TransformerException( - "Failed to detect XML encoding and version", e ); - } - return transformerHandler; - } - } - private ReactorModelCache getModelCache() { return this.modelCache; diff --git a/maven-model-builder/src/main/java/org/apache/maven/model/building/AbstractModelSourceTransformer.java b/maven-model-builder/src/main/java/org/apache/maven/model/building/AbstractModelSourceTransformer.java index e0767fbec578..6fedadaf6a4b 100644 --- a/maven-model-builder/src/main/java/org/apache/maven/model/building/AbstractModelSourceTransformer.java +++ b/maven-model-builder/src/main/java/org/apache/maven/model/building/AbstractModelSourceTransformer.java @@ -39,6 +39,7 @@ import javax.xml.transform.stream.StreamResult; import org.apache.maven.xml.Factories; +import org.apache.maven.xml.sax.ext.CommentRenormalizer; import org.apache.maven.xml.sax.filter.AbstractSAXFilter; import org.xml.sax.SAXException; @@ -101,8 +102,9 @@ public final InputStream transform( Path pomFile, TransformerContext context ) } else { + result = new SAXResult( transformerHandler ); + ( (SAXResult) result ).setLexicalHandler( new CommentRenormalizer( transformerHandler ) ); transformerHandler.setResult( new StreamResult( out ) ); - result = new SAXResult( transformerHandler ); } IOExceptionHandler eh = new IOExceptionHandler(); 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 cad2d25c54f4..f0122201e894 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 @@ -30,6 +30,8 @@ */ public interface TransformerContext { + Object KEY = TransformerContext.class; + String getUserProperty( String key ); Model getRawModel( Path p ); diff --git a/maven-xml/pom.xml b/maven-xml/pom.xml index eb285eb54ce9..6b98f1230c21 100644 --- a/maven-xml/pom.xml +++ b/maven-xml/pom.xml @@ -30,12 +30,18 @@ under the License. maven-xml Maven XML - + org.xmlunit xmlunit-assertj test + + org.mockito + mockito-core + test + +
              \ No newline at end of file diff --git a/maven-xml/src/main/java/org/apache/maven/xml/sax/ext/CommentRenormalizer.java b/maven-xml/src/main/java/org/apache/maven/xml/sax/ext/CommentRenormalizer.java new file mode 100644 index 000000000000..3ae19a46a0d1 --- /dev/null +++ b/maven-xml/src/main/java/org/apache/maven/xml/sax/ext/CommentRenormalizer.java @@ -0,0 +1,108 @@ +package org.apache.maven.xml.sax.ext; + +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +import org.xml.sax.SAXException; +import org.xml.sax.ext.LexicalHandler; + +/** + * During parsing the line separators are transformed to \n + * Unlike characters(), comments don't use the systems line separator for serialization. + * Hence use this class in the LexicalHandler chain to do so + * + * @author Robert Scholte + * @since 3.7.0 + */ +public class CommentRenormalizer implements LexicalHandler +{ + private final LexicalHandler lexicalHandler; + + private final String lineSeparator; + + public CommentRenormalizer( LexicalHandler lexicalHandler ) + { + this( lexicalHandler, System.lineSeparator() ); + } + + // for testing purpose + CommentRenormalizer( LexicalHandler lexicalHandler, String lineSeparator ) + { + this.lexicalHandler = lexicalHandler; + this.lineSeparator = lineSeparator; + } + + @Override + public void comment( char[] ch, int start, int length ) + throws SAXException + { + if ( "\n".equals( lineSeparator ) ) + { + lexicalHandler.comment( ch, start, length ); + } + else + { + char[] ca = new String( ch, start, length ).replaceAll( "\n", lineSeparator ).toCharArray(); + + lexicalHandler.comment( ca, 0, ca.length ); + } + } + + @Override + public void startDTD( String name, String publicId, String systemId ) + throws SAXException + { + lexicalHandler.startDTD( name, publicId, systemId ); + } + + @Override + public void endDTD() + throws SAXException + { + lexicalHandler.endDTD(); + } + + @Override + public void startEntity( String name ) + throws SAXException + { + lexicalHandler.startEntity( name ); + } + + @Override + public void endEntity( String name ) + throws SAXException + { + lexicalHandler.endEntity( name ); + } + + @Override + public void startCDATA() + throws SAXException + { + lexicalHandler.startCDATA(); + } + + @Override + public void endCDATA() + throws SAXException + { + lexicalHandler.endCDATA(); + } +} diff --git a/maven-xml/src/test/java/org/apache/maven/xml/sax/ext/CommentRenormalizerTest.java b/maven-xml/src/test/java/org/apache/maven/xml/sax/ext/CommentRenormalizerTest.java new file mode 100644 index 000000000000..b6bc381c7b87 --- /dev/null +++ b/maven-xml/src/test/java/org/apache/maven/xml/sax/ext/CommentRenormalizerTest.java @@ -0,0 +1,84 @@ +package org.apache.maven.xml.sax.ext; + +/* + * 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 static org.mockito.Mockito.mock; +import static org.mockito.Mockito.verify; + +import java.util.Arrays; +import java.util.Collection; + +import org.junit.Test; +import org.junit.runner.RunWith; +import org.junit.runners.Parameterized; +import org.junit.runners.Parameterized.Parameters; +import org.xml.sax.ext.LexicalHandler; + +@RunWith( Parameterized.class ) +public class CommentRenormalizerTest +{ + private LexicalHandler lexicalHandler; + + private final String lineSeparator; + + @Parameters + public static Collection data() { + return Arrays.asList(new Object[][] { + { "\n" }, + { "\r\n" }, + { "\r" } + }); + } + + public CommentRenormalizerTest( String lineSeparator ) + { + this.lineSeparator = lineSeparator; + this.lexicalHandler = mock( LexicalHandler.class ); + } + + @Test + public void singleLine() + throws Exception + { + CommentRenormalizer commentRenormalizer = new CommentRenormalizer( lexicalHandler, lineSeparator ); + + char[] ch = "single line".toCharArray(); + + commentRenormalizer.comment( ch, 0, ch.length ); + + verify( lexicalHandler ).comment( ch, 0, ch.length ); + } + + @Test + public void multiLine() + throws Exception + { + CommentRenormalizer commentRenormalizer = new CommentRenormalizer( lexicalHandler, lineSeparator ); + + String text = "I%sam%sthe%sbest%s"; + + char[] chIn = String.format( text, "\n", "\n", "\n", "\n" ).toCharArray(); + char[] chOut = String.format( text, lineSeparator, lineSeparator, lineSeparator, lineSeparator ).toCharArray(); + + commentRenormalizer.comment( chIn, 0, chIn.length ); + + verify( lexicalHandler ).comment( chOut, 0, chOut.length ); + } +} From 2717ebce2ea11343674a76b34dcff34a07da06e9 Mon Sep 17 00:00:00 2001 From: rfscholte Date: Sat, 6 Jun 2020 13:44:04 +0200 Subject: [PATCH 41/52] Fix Jenkinsfile --- Jenkinsfile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Jenkinsfile b/Jenkinsfile index 278a19df1f9f..111b5dedd606 100644 --- a/Jenkinsfile +++ b/Jenkinsfile @@ -60,7 +60,7 @@ node(jenkinsEnv.nodeSelection(osNode)) { ]) { // For now: maven-wrapper contains 2 poms sharing the same outputDirectory, so separate clean sh "mvn clean" - sh "mvn ${MAVEN_GOAL} -B -U -e -fae -V -Dmaven.test.failure.ignore=true -P versionlessMavenDist" + sh "mvn ${MAVEN_GOAL} -B -U -e -fae -V -Dmaven.test.failure.ignore=true -DdistributionFileName=${project.artifactId}" } dir ('apache-maven/target') { stash includes: 'apache-maven-bin.zip,apache-maven-wrapper-*.zip', name: 'maven-dist' From d0a3b92b4eb231c4d23241e814e7c2c7a4a1f6e1 Mon Sep 17 00:00:00 2001 From: rfscholte Date: Sat, 6 Jun 2020 13:48:04 +0200 Subject: [PATCH 42/52] Don't try to resolve ${project.artifactId} --- Jenkinsfile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Jenkinsfile b/Jenkinsfile index 111b5dedd606..ec19bd8accd7 100644 --- a/Jenkinsfile +++ b/Jenkinsfile @@ -60,7 +60,7 @@ node(jenkinsEnv.nodeSelection(osNode)) { ]) { // For now: maven-wrapper contains 2 poms sharing the same outputDirectory, so separate clean sh "mvn clean" - sh "mvn ${MAVEN_GOAL} -B -U -e -fae -V -Dmaven.test.failure.ignore=true -DdistributionFileName=${project.artifactId}" + sh "mvn ${MAVEN_GOAL} -B -U -e -fae -V -Dmaven.test.failure.ignore=true" + ' -DdistributionFileName=${project.artifactId}' } dir ('apache-maven/target') { stash includes: 'apache-maven-bin.zip,apache-maven-wrapper-*.zip', name: 'maven-dist' From 3fda5cc0744662819886c21a0a057bf92341fd26 Mon Sep 17 00:00:00 2001 From: rfscholte Date: Sat, 6 Jun 2020 13:51:50 +0200 Subject: [PATCH 43/52] trying to escape $ --- Jenkinsfile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Jenkinsfile b/Jenkinsfile index ec19bd8accd7..6237825ca54a 100644 --- a/Jenkinsfile +++ b/Jenkinsfile @@ -60,7 +60,7 @@ node(jenkinsEnv.nodeSelection(osNode)) { ]) { // For now: maven-wrapper contains 2 poms sharing the same outputDirectory, so separate clean sh "mvn clean" - sh "mvn ${MAVEN_GOAL} -B -U -e -fae -V -Dmaven.test.failure.ignore=true" + ' -DdistributionFileName=${project.artifactId}' + sh "mvn ${MAVEN_GOAL} -B -U -e -fae -V -Dmaven.test.failure.ignore=true -DdistributionFileName=\${project.artifactId}" } dir ('apache-maven/target') { stash includes: 'apache-maven-bin.zip,apache-maven-wrapper-*.zip', name: 'maven-dist' From ee27a044cb9d728049d5f2bb6e865fb9caea2a9a Mon Sep 17 00:00:00 2001 From: rfscholte Date: Sat, 6 Jun 2020 13:55:43 +0200 Subject: [PATCH 44/52] trying with triple double quotes --- Jenkinsfile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Jenkinsfile b/Jenkinsfile index 6237825ca54a..9a5e7d5fd511 100644 --- a/Jenkinsfile +++ b/Jenkinsfile @@ -60,7 +60,7 @@ node(jenkinsEnv.nodeSelection(osNode)) { ]) { // For now: maven-wrapper contains 2 poms sharing the same outputDirectory, so separate clean sh "mvn clean" - sh "mvn ${MAVEN_GOAL} -B -U -e -fae -V -Dmaven.test.failure.ignore=true -DdistributionFileName=\${project.artifactId}" + sh """mvn ${MAVEN_GOAL} -B -U -e -fae -V -Dmaven.test.failure.ignore=true -DdistributionFileName=${project.artifactId}""" } dir ('apache-maven/target') { stash includes: 'apache-maven-bin.zip,apache-maven-wrapper-*.zip', name: 'maven-dist' From 5101ea0388569e9ab84d0bc34b19c222abf9776d Mon Sep 17 00:00:00 2001 From: rfscholte Date: Sat, 6 Jun 2020 14:08:47 +0200 Subject: [PATCH 45/52] try as system property --- Jenkinsfile | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Jenkinsfile b/Jenkinsfile index 9a5e7d5fd511..02bbfdd7b5d6 100644 --- a/Jenkinsfile +++ b/Jenkinsfile @@ -49,7 +49,7 @@ node(jenkinsEnv.nodeSelection(osNode)) { stage('Build / Unit Test') { String jdkName = jenkinsEnv.jdkFromVersion(buildOs, buildJdk) String mvnName = jenkinsEnv.mvnFromVersion(buildOs, buildMvn) - withMaven(jdk: jdkName, maven: mvnName, mavenLocalRepo:"${WORK_DIR}/.repository", options:[ + withMaven(jdk: jdkName, maven: mvnName, mavenLocalRepo:"${WORK_DIR}/.repository", mavenOpts:'-DdistributionFileName=${project.artifactId}', options:[ artifactsPublisher(disabled: false), junitPublisher(ignoreAttachments: false), findbugsPublisher(disabled: false), @@ -60,7 +60,7 @@ node(jenkinsEnv.nodeSelection(osNode)) { ]) { // For now: maven-wrapper contains 2 poms sharing the same outputDirectory, so separate clean sh "mvn clean" - sh """mvn ${MAVEN_GOAL} -B -U -e -fae -V -Dmaven.test.failure.ignore=true -DdistributionFileName=${project.artifactId}""" + sh "mvn ${MAVEN_GOAL} -B -U -e -fae -V -Dmaven.test.failure.ignore=true" } dir ('apache-maven/target') { stash includes: 'apache-maven-bin.zip,apache-maven-wrapper-*.zip', name: 'maven-dist' From 82bc06d49f86e3cadf7ac9a8e363cb783fcdfb92 Mon Sep 17 00:00:00 2001 From: rfscholte Date: Sat, 6 Jun 2020 15:17:42 +0200 Subject: [PATCH 46/52] Restore Jenkins file --- Jenkinsfile | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Jenkinsfile b/Jenkinsfile index 02bbfdd7b5d6..278a19df1f9f 100644 --- a/Jenkinsfile +++ b/Jenkinsfile @@ -49,7 +49,7 @@ node(jenkinsEnv.nodeSelection(osNode)) { stage('Build / Unit Test') { String jdkName = jenkinsEnv.jdkFromVersion(buildOs, buildJdk) String mvnName = jenkinsEnv.mvnFromVersion(buildOs, buildMvn) - withMaven(jdk: jdkName, maven: mvnName, mavenLocalRepo:"${WORK_DIR}/.repository", mavenOpts:'-DdistributionFileName=${project.artifactId}', options:[ + withMaven(jdk: jdkName, maven: mvnName, mavenLocalRepo:"${WORK_DIR}/.repository", options:[ artifactsPublisher(disabled: false), junitPublisher(ignoreAttachments: false), findbugsPublisher(disabled: false), @@ -60,7 +60,7 @@ node(jenkinsEnv.nodeSelection(osNode)) { ]) { // For now: maven-wrapper contains 2 poms sharing the same outputDirectory, so separate clean sh "mvn clean" - sh "mvn ${MAVEN_GOAL} -B -U -e -fae -V -Dmaven.test.failure.ignore=true" + sh "mvn ${MAVEN_GOAL} -B -U -e -fae -V -Dmaven.test.failure.ignore=true -P versionlessMavenDist" } dir ('apache-maven/target') { stash includes: 'apache-maven-bin.zip,apache-maven-wrapper-*.zip', name: 'maven-dist' From 8b3f47a4f5ac0e857fd1be8a7c90a56879943508 Mon Sep 17 00:00:00 2001 From: rfscholte Date: Sat, 6 Jun 2020 21:58:31 +0200 Subject: [PATCH 47/52] Pass sessionData --- .../aether/DefaultRepositorySystemSessionFactory.java | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/maven-core/src/main/java/org/apache/maven/internal/aether/DefaultRepositorySystemSessionFactory.java b/maven-core/src/main/java/org/apache/maven/internal/aether/DefaultRepositorySystemSessionFactory.java index 928d200277da..acd1fce51403 100644 --- a/maven-core/src/main/java/org/apache/maven/internal/aether/DefaultRepositorySystemSessionFactory.java +++ b/maven-core/src/main/java/org/apache/maven/internal/aether/DefaultRepositorySystemSessionFactory.java @@ -40,6 +40,7 @@ import org.eclipse.aether.ConfigurationProperties; import org.eclipse.aether.DefaultRepositorySystemSession; import org.eclipse.aether.RepositorySystem; +import org.eclipse.aether.SessionData; import org.eclipse.aether.repository.LocalRepository; import org.eclipse.aether.repository.NoLocalRepositoryManagerException; import org.eclipse.aether.repository.RepositoryPolicy; @@ -247,8 +248,7 @@ else if ( request.isUpdateSnapshots() ) if ( Features.buildConsumer().isActive() ) { - session.setFileTransformerManager( a -> getTransformersForArtifact( a, - (TransformerContext) session.getData().get( TransformerContext.KEY ) ) ); + session.setFileTransformerManager( a -> getTransformersForArtifact( a, session.getData() ) ); } return session; @@ -281,8 +281,9 @@ private String getMavenVersion() } private Collection getTransformersForArtifact( final org.eclipse.aether.artifact.Artifact artifact, - TransformerContext context ) + final SessionData sessionData ) { + TransformerContext context = (TransformerContext) sessionData.get( TransformerContext.KEY ); Collection transformers = new ArrayList<>(); if ( "pom".equals( artifact.getExtension() ) ) { From be5d23d8d6cd4d51a98a87ef473b70cdb9205de2 Mon Sep 17 00:00:00 2001 From: rfscholte Date: Sun, 7 Jun 2020 14:25:50 +0200 Subject: [PATCH 48/52] Prevent NPE --- .../aether/DefaultRepositorySystemSessionFactory.java | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/maven-core/src/main/java/org/apache/maven/internal/aether/DefaultRepositorySystemSessionFactory.java b/maven-core/src/main/java/org/apache/maven/internal/aether/DefaultRepositorySystemSessionFactory.java index acd1fce51403..d90c1d8a0aa3 100644 --- a/maven-core/src/main/java/org/apache/maven/internal/aether/DefaultRepositorySystemSessionFactory.java +++ b/maven-core/src/main/java/org/apache/maven/internal/aether/DefaultRepositorySystemSessionFactory.java @@ -285,7 +285,9 @@ private Collection getTransformersForArtifact( final org.eclips { TransformerContext context = (TransformerContext) sessionData.get( TransformerContext.KEY ); Collection transformers = new ArrayList<>(); - if ( "pom".equals( artifact.getExtension() ) ) + + // In case of install:install-file there's no transformer context, as the goal is unrelated to the lifecycle. + if ( "pom".equals( artifact.getExtension() ) && context != null ) { transformers.add( new FileTransformer() { From 020b5037d513d69c4daadc1118dbc408d3bc3089 Mon Sep 17 00:00:00 2001 From: rfscholte Date: Sun, 7 Jun 2020 19:47:27 +0200 Subject: [PATCH 49/52] Adjust apache-maven-wrapper pom for IT --- apache-maven/maven-wrapper.pom | 5 ----- 1 file changed, 5 deletions(-) diff --git a/apache-maven/maven-wrapper.pom b/apache-maven/maven-wrapper.pom index fc6755cff306..f2bcc7fc141b 100644 --- a/apache-maven/maven-wrapper.pom +++ b/apache-maven/maven-wrapper.pom @@ -33,12 +33,7 @@ under the License. Apache Maven Wrapper Distribution The Apache Maven Wrapper distribution in zip and tar.gz formats. - - ${artifactId}-${project.version} - - - ${distributionFileName} From cc620d2f0cea7cd40aee60b3a72582c5c4fde3f1 Mon Sep 17 00:00:00 2001 From: rfscholte Date: Tue, 16 Jun 2020 21:39:50 +0200 Subject: [PATCH 50/52] Adjust code based on review comments --- .../ConsumerModelSourceTransformer.java | 3 +- ...DefaultRepositorySystemSessionFactory.java | 9 +- .../maven/project/DefaultProjectBuilder.java | 10 +- .../maven/project/ProjectModelResolver.java | 6 +- .../maven/project/ReactorModelPool.java | 3 - .../DefaultConsumerPomXMLFilterFactory.java | 2 + .../AbstractModelSourceTransformer.java | 2 + ....java => BuildModelSourceTransformer.java} | 3 +- .../building/DefaultModelBuildingRequest.java | 2 +- .../model/building/TransformerContext.java | 26 +- .../DefaultInheritanceAssemblerTest.java | 21 +- .../sax/filter/BuildPomXMLFilterFactory.java | 4 +- .../sax/filter/BuildPomXMLFilterListener.java | 2 + .../maven/xml/sax/LexicalHandlerVerifier.java | 277 ------------------ 14 files changed, 66 insertions(+), 304 deletions(-) rename maven-model-builder/src/main/java/org/apache/maven/model/building/{DefaultModelSourceTransformer.java => BuildModelSourceTransformer.java} (95%) delete mode 100644 maven-xml/src/test/java/org/apache/maven/xml/sax/LexicalHandlerVerifier.java 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 8ca0ca667a1f..728c78e7eb0a 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 @@ -55,9 +55,8 @@ protected AbstractSAXFilter getSAXFilter( Path pomFile, TransformerContext conte * This transformer will ensure that encoding and version are kept. * However, it cannot prevent: *
                - *
              • line-endings will be unix-style(LF)
              • *
              • attributes will be on one line
              • - *
              • Unnecessary whitespace before the rootelement will be remove
              • + *
              • Unnecessary whitespace before the rootelement will be removed
              • *
              */ @Override diff --git a/maven-core/src/main/java/org/apache/maven/internal/aether/DefaultRepositorySystemSessionFactory.java b/maven-core/src/main/java/org/apache/maven/internal/aether/DefaultRepositorySystemSessionFactory.java index d90c1d8a0aa3..28f75cdce81e 100644 --- a/maven-core/src/main/java/org/apache/maven/internal/aether/DefaultRepositorySystemSessionFactory.java +++ b/maven-core/src/main/java/org/apache/maven/internal/aether/DefaultRepositorySystemSessionFactory.java @@ -26,6 +26,7 @@ import org.apache.maven.execution.MavenExecutionRequest; import org.apache.maven.feature.Features; import org.apache.maven.model.building.TransformerContext; +import org.apache.maven.model.building.TransformerException; import org.apache.maven.repository.internal.MavenRepositorySystemUtils; import org.apache.maven.settings.Mirror; import org.apache.maven.settings.Proxy; @@ -41,6 +42,7 @@ import org.eclipse.aether.DefaultRepositorySystemSession; import org.eclipse.aether.RepositorySystem; import org.eclipse.aether.SessionData; +import org.eclipse.aether.artifact.Artifact; import org.eclipse.aether.repository.LocalRepository; import org.eclipse.aether.repository.NoLocalRepositoryManagerException; import org.eclipse.aether.repository.RepositoryPolicy; @@ -280,7 +282,7 @@ private String getMavenVersion() return props.getProperty( "version", "unknown-version" ); } - private Collection getTransformersForArtifact( final org.eclipse.aether.artifact.Artifact artifact, + private Collection getTransformersForArtifact( final Artifact artifact, final SessionData sessionData ) { TransformerContext context = (TransformerContext) sessionData.get( TransformerContext.KEY ); @@ -299,15 +301,14 @@ public InputStream transformData( File pomFile ) { return new ConsumerModelSourceTransformer().transform( pomFile.toPath(), context ); } - catch ( org.apache.maven.model.building.TransformerException e ) + catch ( TransformerException e ) { throw new TransformException( e ); } } @Override - public org.eclipse.aether.artifact.Artifact transformArtifact( - org.eclipse.aether.artifact.Artifact artifact ) + public Artifact transformArtifact( Artifact artifact ) { return artifact; } 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 f09941b1f238..624f6ade9d90 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 @@ -161,7 +161,7 @@ private ProjectBuildingResult build( File pomFile, ModelSource modelSource, Inte if ( project == null ) { - ModelBuildingRequest request = getModelBuildingRequest( config, pomFile ); + ModelBuildingRequest request = getModelBuildingRequest( config ); project = new MavenProject(); project.setFile( pomFile ); @@ -273,7 +273,7 @@ private List getProfileIds( List profiles ) return ids; } - private ModelBuildingRequest getModelBuildingRequest( InternalConfig config, File pomFile ) + private ModelBuildingRequest getModelBuildingRequest( InternalConfig config ) { ProjectBuildingRequest configuration = config.request; @@ -444,7 +444,7 @@ public Model getRawModel( String groupId, String artifactId ) @SuppressWarnings( "checkstyle:parameternumber" ) private boolean build( List results, List interimResults, Map projectIndex, List pomFiles, Set aggregatorFiles, - boolean isRoot, boolean recursive, InternalConfig config, + boolean root, boolean recursive, InternalConfig config, ReactorModelPool.Builder poolBuilder ) { boolean noErrors = true; @@ -453,7 +453,7 @@ private boolean build( List results, List { aggregatorFiles.add( pomFile ); - if ( !build( results, interimResults, projectIndex, pomFile, aggregatorFiles, isRoot, recursive, config, + if ( !build( results, interimResults, projectIndex, pomFile, aggregatorFiles, root, recursive, config, poolBuilder ) ) { noErrors = false; @@ -473,7 +473,7 @@ private boolean build( List results, List { boolean noErrors = true; - ModelBuildingRequest request = getModelBuildingRequest( config, pomFile ); + ModelBuildingRequest request = getModelBuildingRequest( config ); MavenProject project = new MavenProject(); project.setFile( pomFile ); 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 3b027e5063c7..bcc3730e72bb 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 @@ -24,7 +24,6 @@ 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; @@ -278,8 +277,9 @@ public ModelSource resolveModel( final Dependency dependency ) if ( modelPool != null ) { - Model model = Optional.ofNullable( modelPool.get( dependency.getGroupId(), dependency.getArtifactId(), - dependency.getVersion() ) ).orElse( null ); + Model model = + modelPool.get( dependency.getGroupId(), dependency.getArtifactId(), dependency.getVersion() ); + if ( model != null ) { return new FileModelSource( model.getPomFile() ); 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 3a788e6e8579..b96b14b7fed5 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 @@ -25,7 +25,6 @@ import java.util.HashMap; import java.util.HashSet; import java.util.Map; -import java.util.NoSuchElementException; import java.util.Objects; import java.util.Set; @@ -52,10 +51,8 @@ class ReactorModelPool * @param version, can be {@code null} * @return the matching model or {@code null} * @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 { return modelsByGa.getOrDefault( new GAKey( groupId, artifactId ), Collections.emptySet() ).stream() .filter( m -> version == null || version.equals( getVersion( m ) ) ) 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 f686ac2d2f24..f49e62d32b0b 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 @@ -26,6 +26,8 @@ import org.apache.maven.xml.sax.filter.ConsumerPomXMLFilterFactory; /** + * The default implementation of the {@link ConsumerPomXMLFilterFactory} + * It will provide several values for the consumer pom based on its context. * * @author Robert Scholte * @since 3.7.0 diff --git a/maven-model-builder/src/main/java/org/apache/maven/model/building/AbstractModelSourceTransformer.java b/maven-model-builder/src/main/java/org/apache/maven/model/building/AbstractModelSourceTransformer.java index 6fedadaf6a4b..0cf6f7a9abac 100644 --- a/maven-model-builder/src/main/java/org/apache/maven/model/building/AbstractModelSourceTransformer.java +++ b/maven-model-builder/src/main/java/org/apache/maven/model/building/AbstractModelSourceTransformer.java @@ -44,6 +44,8 @@ import org.xml.sax.SAXException; /** + * Offers a transformation implementation based on PipelineStreams. + * Subclasses are responsible for providing the right SAXFilter. * * @author Robert Scholte * @since 3.7.0 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/BuildModelSourceTransformer.java similarity index 95% rename from maven-model-builder/src/main/java/org/apache/maven/model/building/DefaultModelSourceTransformer.java rename to maven-model-builder/src/main/java/org/apache/maven/model/building/BuildModelSourceTransformer.java index f410551df199..dbf9211e9ee6 100644 --- 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/BuildModelSourceTransformer.java @@ -37,13 +37,14 @@ import org.xml.sax.SAXException; /** + * ModelSourceTransformer for the build pom * * @author Robert Scholte * @since 3.7.0 */ @Named @Singleton -public class DefaultModelSourceTransformer extends AbstractModelSourceTransformer +class BuildModelSourceTransformer extends AbstractModelSourceTransformer { @Inject @Nullable 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 b347eb41bda0..2012bb1a578f 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 @@ -38,7 +38,7 @@ public class DefaultModelBuildingRequest implements ModelBuildingRequest { - private transient Model fileModel; + private Model fileModel; private Model rawModel; 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 f0122201e894..2f763a2a9001 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 @@ -24,17 +24,41 @@ import org.apache.maven.model.Model; /** + * Context used to transform a pom file. + * * * @author Robert Scholte * @since 3.7.0 */ public interface TransformerContext { + /** + * Key to get the TransformerContext from the SessionData + */ Object KEY = TransformerContext.class; + /** + * Get the value of the commandline argument {@code -Dkey=value} + * @param key + * @return + */ String getUserProperty( String key ); + /** + * Get the model based on the path, will be used to resolve the parent based on relativePath + * + * @param p the path + * @return the model, otherwise {@code null} + */ Model getRawModel( Path p ); - Model getRawModel( String groupId, String artifactId ); + /** + * Get the model from the reactor based on the groupId and artifactId, will be used for reactor dependencies + * + * @param groupId the groupId + * @param artifactId the artifactId + * @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; } diff --git a/maven-model-builder/src/test/java/org/apache/maven/model/inheritance/DefaultInheritanceAssemblerTest.java b/maven-model-builder/src/test/java/org/apache/maven/model/inheritance/DefaultInheritanceAssemblerTest.java index 54c178e024d7..992447180c3b 100644 --- a/maven-model-builder/src/test/java/org/apache/maven/model/inheritance/DefaultInheritanceAssemblerTest.java +++ b/maven-model-builder/src/test/java/org/apache/maven/model/inheritance/DefaultInheritanceAssemblerTest.java @@ -20,19 +20,24 @@ */ import org.apache.maven.model.Model; -import org.apache.maven.model.building.DefaultModelSourceTransformer; +import org.apache.maven.model.building.AbstractModelSourceTransformer; import org.apache.maven.model.building.SimpleProblemCollector; +import org.apache.maven.model.building.TransformerContext; import org.apache.maven.model.io.DefaultModelReader; import org.apache.maven.model.io.DefaultModelWriter; -import org.apache.maven.model.io.ModelReader; import org.apache.maven.model.io.ModelWriter; - +import org.apache.maven.xml.sax.filter.AbstractSAXFilter; +import org.xml.sax.SAXException; import org.xmlunit.matchers.CompareMatcher; import junit.framework.TestCase; import java.io.File; import java.io.IOException; +import java.nio.file.Path; + +import javax.xml.parsers.ParserConfigurationException; +import javax.xml.transform.TransformerConfigurationException; import static org.junit.Assert.assertThat; @@ -55,7 +60,15 @@ protected void setUp() super.setUp(); reader = new DefaultModelReader(); - reader.setTransformer( new DefaultModelSourceTransformer() ); + reader.setTransformer( new AbstractModelSourceTransformer() + { + @Override + protected AbstractSAXFilter getSAXFilter( Path pomFile, TransformerContext context ) + throws TransformerConfigurationException, SAXException, ParserConfigurationException + { + return null; + } + } ); writer = new DefaultModelWriter(); assembler = new DefaultInheritanceAssembler(); } 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 910bc1603a0f..6f3f3198c9a1 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 @@ -35,11 +35,9 @@ import org.xml.sax.ext.LexicalHandler; /** - * Base class for third parties to extend. When annotating it with Named("somecustomname"), - * Maven will pick this up as instead of the DefaultBuildPomXMLFilterFactory + * Base implementation for providing the BuildPomXML. * * @author Robert Scholte - * * @since 3.7.0 */ public class BuildPomXMLFilterFactory diff --git a/maven-xml/src/main/java/org/apache/maven/xml/sax/filter/BuildPomXMLFilterListener.java b/maven-xml/src/main/java/org/apache/maven/xml/sax/filter/BuildPomXMLFilterListener.java index e984640594d0..b97c757330dd 100644 --- a/maven-xml/src/main/java/org/apache/maven/xml/sax/filter/BuildPomXMLFilterListener.java +++ b/maven-xml/src/main/java/org/apache/maven/xml/sax/filter/BuildPomXMLFilterListener.java @@ -22,10 +22,12 @@ import java.nio.file.Path; /** + * Listener can be used to capture the result of the build pom * * @author Robert Scholte * @since 3.7.0 */ +@FunctionalInterface public interface BuildPomXMLFilterListener { /** diff --git a/maven-xml/src/test/java/org/apache/maven/xml/sax/LexicalHandlerVerifier.java b/maven-xml/src/test/java/org/apache/maven/xml/sax/LexicalHandlerVerifier.java deleted file mode 100644 index 49eb7729c6eb..000000000000 --- a/maven-xml/src/test/java/org/apache/maven/xml/sax/LexicalHandlerVerifier.java +++ /dev/null @@ -1,277 +0,0 @@ -package org.apache.maven.xml.sax; - -/* - * 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 static org.xmlunit.assertj.XmlAssert.assertThat; - -import java.io.StringReader; -import java.io.StringWriter; -import java.io.Writer; -import java.util.Arrays; - -import javax.xml.transform.OutputKeys; -import javax.xml.transform.Source; -import javax.xml.transform.Transformer; -import javax.xml.transform.sax.SAXResult; -import javax.xml.transform.sax.SAXSource; -import javax.xml.transform.sax.SAXTransformerFactory; -import javax.xml.transform.sax.TransformerHandler; -import javax.xml.transform.stream.StreamResult; -import javax.xml.transform.stream.StreamSource; - -import org.apache.maven.xml.Factories; -import org.apache.maven.xml.sax.filter.AbstractSAXFilter; -import org.junit.Rule; -import org.junit.Test; -import org.junit.rules.ExpectedException; -import org.xml.sax.InputSource; -import org.xml.sax.SAXException; -import org.xml.sax.XMLFilter; -import org.xml.sax.XMLReader; -import org.xml.sax.ext.LexicalHandler; -import org.xml.sax.helpers.XMLFilterImpl; - -/** - * Some tests to help understand the chain of events regarding XMLFilters, XMLReaders, LexicalHandlers and Transformers - * - * @author Robert Scholte - * - */ -public class LexicalHandlerVerifier -{ - private static final String SAX_PROPERTIES_LEXICAL_HANDLER = "http://xml.org/sax/properties/lexical-handler"; - - @Rule - public ExpectedException expectedException = ExpectedException.none(); - - @Test - public void parseXmlReader() throws Exception - { - expectedException.expect( UnsupportedOperationException.class ); - expectedException.expectMessage( "LexicalHandlerVerifier" ); - - XMLReader reader = Factories.newXMLReader(); - reader.setProperty( SAX_PROPERTIES_LEXICAL_HANDLER, new UnsupportedOperationExceptionLexicalHandler() ); - - InputSource inputSource = new InputSource( new StringReader( "" ) ); - reader.parse( inputSource ); - } - - @Test - public void parseXmlFilter() throws Exception - { - expectedException.expect( UnsupportedOperationException.class ); - expectedException.expectMessage( "LexicalHandlerVerifier" ); - - XMLReader reader = Factories.newXMLReader(); - reader.setProperty( SAX_PROPERTIES_LEXICAL_HANDLER, new UnsupportedOperationExceptionLexicalHandler() ); - - XMLFilter filter = new XMLFilterImpl( reader ); - - InputSource inputSource = new InputSource( new StringReader( "" ) ); - filter.parse( inputSource ); - } - - @Test - public void transformXmlReader() throws Exception - { - Writer writer = new StringWriter(); - StreamResult result = new StreamResult( writer ); - - SAXTransformerFactory transformerFactory = (SAXTransformerFactory) Factories.newTransformerFactory(); - TransformerHandler transformerHandler = transformerFactory.newTransformerHandler(); - transformerHandler.setResult( result ); - Transformer transformer = transformerFactory.newTransformer(); - transformer.setOutputProperty( OutputKeys.OMIT_XML_DECLARATION, "yes" ); - - Source xmlSource = new StreamSource( new StringReader( "" ) ); - - SAXResult transformResult = new SAXResult( transformerHandler ); - transformResult.setLexicalHandler( new SortCommentLexicalHandler( transformerHandler ) ); - transformer.transform( xmlSource, transformResult ); - - assertThat( writer.toString() ).and( "" - + "" ).areIdentical(); - } - - @Test - public void transformXmlFilter() throws Exception - { - Writer writer = new StringWriter(); - StreamResult result = new StreamResult( writer ); - - SAXTransformerFactory transformerFactory = (SAXTransformerFactory) Factories.newTransformerFactory(); - TransformerHandler transformerHandler = transformerFactory.newTransformerHandler(); - transformerHandler.getTransformer().setOutputProperty( OutputKeys.OMIT_XML_DECLARATION, "yes" ); - transformerHandler.setResult( result ); - Transformer transformer = transformerFactory.newTransformer(); - - XMLReader reader = Factories.newXMLReader(); - // in wrong order result will be CONNENT --> - AbstractSAXFilter filter2 = new M2NLexicalXMLFilter(); - filter2.setParent( reader ); - filter2.setLexicalHandler( transformerHandler ); - - AbstractSAXFilter filter1 = new N2CLexicalXMLFilter( filter2 ); - - SAXSource transformSource = new SAXSource( filter1, new InputSource( new StringReader( "" ) ) ); - - SAXResult transformResult = new SAXResult( transformerHandler ); - transformResult.setLexicalHandler( filter1 ); - transformer.transform( transformSource, transformResult ); - - assertThat( writer.toString() ).and( "" ).areIdentical(); - } - - /** - * A LexicalHandler that'll throw an UnsupportedOperationException on every call. - * - * @author Robert Scholte - */ - static class UnsupportedOperationExceptionLexicalHandler implements LexicalHandler - { - @Override - public void startDTD( String name, String publicId, String systemId ) - throws SAXException - { - throw new UnsupportedOperationException( "LexicalHandlerVerifier" ); - } - - @Override - public void endDTD() - throws SAXException - { - throw new UnsupportedOperationException( "LexicalHandlerVerifier" ); - } - - @Override - public void startEntity( String name ) - throws SAXException - { - throw new UnsupportedOperationException( "LexicalHandlerVerifier" ); - } - - @Override - public void endEntity( String name ) - throws SAXException - { - throw new UnsupportedOperationException( "LexicalHandlerVerifier" ); - } - - @Override - public void startCDATA() - throws SAXException - { - throw new UnsupportedOperationException( "LexicalHandlerVerifier" ); - } - - @Override - public void endCDATA() - throws SAXException - { - throw new UnsupportedOperationException( "LexicalHandlerVerifier" ); - } - - @Override - public void comment( char[] ch, int start, int length ) - throws SAXException - { - throw new UnsupportedOperationException( "LexicalHandlerVerifier" ); - } - } - - /** - * Sorts the comment chars,will throw an UnsupportedOperationException on every other method - * - * @author Robert Scholte - * - */ - static class SortCommentLexicalHandler extends UnsupportedOperationExceptionLexicalHandler - { - private final LexicalHandler lexicalHandler; - - public SortCommentLexicalHandler( LexicalHandler lexicalHandler ) - { - this.lexicalHandler = lexicalHandler; - } - - - @Override - public void comment( char[] ch, int start, int length ) - throws SAXException - { - char[] chars = new String( ch, start, length ).toCharArray(); - Arrays.sort(chars); - lexicalHandler.comment( chars, 0, chars.length ); - } - } - - /** - * AbstractSAXFilter implements both XMLReader and LexicalHandler - * - * @author Robert Scholte - * - */ - static class N2CLexicalXMLFilter extends AbstractSAXFilter - { - public N2CLexicalXMLFilter() - { - super( null ); - } - - public N2CLexicalXMLFilter( T parent ) - { - super( parent ); - } - - @Override - public void comment( char[] ch, int start, int length ) - throws SAXException - { - super.comment( new String( ch, start, length ).replace( 'N', 'C' ).toCharArray(), start, length ); - } - } - - /** - * AbstractSAXFilter implements both XMLReader and LexicalHandler - * - * @author Robert Scholte - * - */ - static class M2NLexicalXMLFilter extends AbstractSAXFilter - { - public M2NLexicalXMLFilter() - { - super( null ); - } - - public M2NLexicalXMLFilter( T parent ) - { - super( parent ); - } - - @Override - public void comment( char[] ch, int start, int length ) - throws SAXException - { - super.comment( new String( ch, start, length ).replace( 'M', 'N' ).toCharArray(), start, length ); - } - } -} From 1737d23574f7361450c2a94dd135f085c9bf8e45 Mon Sep 17 00:00:00 2001 From: rfscholte Date: Tue, 16 Jun 2020 21:40:35 +0200 Subject: [PATCH 51/52] ReAdd DefaultModelSourceTransformer --- .../DefaultModelSourceTransformer.java | 43 +++++++++++++++++++ 1 file changed, 43 insertions(+) create mode 100644 maven-model-builder/src/main/java/org/apache/maven/model/building/DefaultModelSourceTransformer.java 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 000000000000..50ad04b572e5 --- /dev/null +++ b/maven-model-builder/src/main/java/org/apache/maven/model/building/DefaultModelSourceTransformer.java @@ -0,0 +1,43 @@ +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.IOException; +import java.io.InputStream; +import java.nio.file.Files; +import java.nio.file.Path; + +/** + * Default ModelSourceTransformer, provides pomFile as inputStream and ignores the context + * + * @author Robert Scholte + * @since 3.7.0 + */ +public class DefaultModelSourceTransformer implements ModelSourceTransformer +{ + + @Override + public InputStream transform( Path pomFile, TransformerContext context ) + throws IOException, TransformerException + { + return Files.newInputStream( pomFile ); + } + +} From e082e6efa87355889120bbf5dd852b4d915e030f Mon Sep 17 00:00:00 2001 From: rfscholte Date: Wed, 17 Jun 2020 09:00:53 +0200 Subject: [PATCH 52/52] Adjust code based on review comments --- .../maven/model/building/AbstractModelSourceTransformer.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/maven-model-builder/src/main/java/org/apache/maven/model/building/AbstractModelSourceTransformer.java b/maven-model-builder/src/main/java/org/apache/maven/model/building/AbstractModelSourceTransformer.java index 0cf6f7a9abac..31b88bfa7d7a 100644 --- a/maven-model-builder/src/main/java/org/apache/maven/model/building/AbstractModelSourceTransformer.java +++ b/maven-model-builder/src/main/java/org/apache/maven/model/building/AbstractModelSourceTransformer.java @@ -168,7 +168,8 @@ public void close() } catch ( Throwable t ) { - throw new AssertionError( "Failed to transform pom", t ); + // Any checked exception + throw new RuntimeException( "Failed to transform pom", t ); } } }