diff --git a/apache-maven/src/main/appended-resources/licenses/unrecognized-stax2-api-4.2.1.txt b/apache-maven/src/main/appended-resources/licenses/unrecognized-stax2-api-4.2.1.txt new file mode 100644 index 0000000000..df1288e781 --- /dev/null +++ b/apache-maven/src/main/appended-resources/licenses/unrecognized-stax2-api-4.2.1.txt @@ -0,0 +1,3 @@ +Copyright (c) 2008 FasterXML LLC info@fasterxml.com + +This source code is licensed under standard BSD license, which is compatible with all Free and Open Software (OSS) licenses. \ No newline at end of file diff --git a/apache-maven/src/test/java/org/apache/maven/settings/GlobalSettingsTest.java b/apache-maven/src/test/java/org/apache/maven/settings/GlobalSettingsTest.java index a8819f87b6..14373a2536 100644 --- a/apache-maven/src/test/java/org/apache/maven/settings/GlobalSettingsTest.java +++ b/apache-maven/src/test/java/org/apache/maven/settings/GlobalSettingsTest.java @@ -23,7 +23,7 @@ import java.nio.file.Files; import org.apache.maven.api.settings.InputSource; -import org.apache.maven.settings.v4.SettingsXpp3ReaderEx; +import org.apache.maven.settings.v4.SettingsStaxReader; import org.junit.jupiter.api.Test; import static org.junit.jupiter.api.Assertions.assertTrue; @@ -43,7 +43,7 @@ void testValidGlobalSettings() throws Exception { assertTrue(globalSettingsFile.isFile(), globalSettingsFile.getAbsolutePath()); try (InputStream is = Files.newInputStream(globalSettingsFile.toPath())) { - new SettingsXpp3ReaderEx().read(is, true, new InputSource(globalSettingsFile.getAbsolutePath())); + new SettingsStaxReader().read(is, true, new InputSource(globalSettingsFile.getAbsolutePath())); } } } diff --git a/maven-bom/pom.xml b/maven-bom/pom.xml index d0345bbac7..086801759e 100644 --- a/maven-bom/pom.xml +++ b/maven-bom/pom.xml @@ -147,6 +147,11 @@ under the License. maven-slf4j-wrapper ${project.version} + + org.apache.maven + maven-xml-impl + ${project.version} + diff --git a/maven-compat/src/main/java/org/apache/maven/artifact/repository/metadata/AbstractRepositoryMetadata.java b/maven-compat/src/main/java/org/apache/maven/artifact/repository/metadata/AbstractRepositoryMetadata.java index b9502a7f4d..b8d2537ae8 100644 --- a/maven-compat/src/main/java/org/apache/maven/artifact/repository/metadata/AbstractRepositoryMetadata.java +++ b/maven-compat/src/main/java/org/apache/maven/artifact/repository/metadata/AbstractRepositoryMetadata.java @@ -18,20 +18,20 @@ */ package org.apache.maven.artifact.repository.metadata; +import javax.xml.stream.XMLStreamException; + import java.io.File; import java.io.IOException; -import java.io.Reader; -import java.io.Writer; +import java.io.InputStream; +import java.io.OutputStream; +import java.nio.file.Files; import org.apache.maven.artifact.Artifact; import org.apache.maven.artifact.metadata.ArtifactMetadata; import org.apache.maven.artifact.repository.ArtifactRepository; import org.apache.maven.artifact.repository.ArtifactRepositoryPolicy; -import org.apache.maven.artifact.repository.metadata.io.xpp3.MetadataXpp3Reader; -import org.apache.maven.artifact.repository.metadata.io.xpp3.MetadataXpp3Writer; -import org.codehaus.plexus.util.ReaderFactory; -import org.codehaus.plexus.util.WriterFactory; -import org.codehaus.plexus.util.xml.pull.XmlPullParserException; +import org.apache.maven.artifact.repository.metadata.io.MetadataStaxReader; +import org.apache.maven.artifact.repository.metadata.io.MetadataStaxWriter; /** * Shared methods of the repository metadata handling. @@ -59,15 +59,13 @@ public void storeInLocalRepository(ArtifactRepository localRepository, ArtifactR throws RepositoryMetadataStoreException { try { updateRepositoryMetadata(localRepository, remoteRepository); - } catch (IOException | XmlPullParserException e) { + } catch (IOException | XMLStreamException e) { throw new RepositoryMetadataStoreException("Error updating group repository metadata", e); } } protected void updateRepositoryMetadata(ArtifactRepository localRepository, ArtifactRepository remoteRepository) - throws IOException, XmlPullParserException { - MetadataXpp3Reader mappingReader = new MetadataXpp3Reader(); - + throws IOException, XMLStreamException { Metadata metadata = null; File metadataFile = new File( @@ -85,8 +83,8 @@ protected void updateRepositoryMetadata(ArtifactRepository localRepository, Arti // to delete on exit } } else if (metadataFile.exists()) { - try (Reader reader = ReaderFactory.newXmlReader(metadataFile)) { - metadata = mappingReader.read(reader, false); + try (InputStream input = Files.newInputStream(metadataFile.toPath())) { + metadata = new Metadata(new MetadataStaxReader().read(input, false)); } } @@ -110,10 +108,9 @@ protected void updateRepositoryMetadata(ArtifactRepository localRepository, Arti if (changed || !metadataFile.exists()) { metadataFile.getParentFile().mkdirs(); - try (Writer writer = WriterFactory.newXmlWriter(metadataFile)) { - MetadataXpp3Writer mappingWriter = new MetadataXpp3Writer(); - - mappingWriter.write(writer, metadata); + try (OutputStream output = Files.newOutputStream(metadataFile.toPath())) { + MetadataStaxWriter mappingWriter = new MetadataStaxWriter(); + mappingWriter.write(output, metadata.getDelegate()); } } else { metadataFile.setLastModified(System.currentTimeMillis()); diff --git a/maven-compat/src/main/java/org/apache/maven/artifact/repository/metadata/DefaultRepositoryMetadataManager.java b/maven-compat/src/main/java/org/apache/maven/artifact/repository/metadata/DefaultRepositoryMetadataManager.java index 04b6f36354..0cf593ca9f 100644 --- a/maven-compat/src/main/java/org/apache/maven/artifact/repository/metadata/DefaultRepositoryMetadataManager.java +++ b/maven-compat/src/main/java/org/apache/maven/artifact/repository/metadata/DefaultRepositoryMetadataManager.java @@ -21,6 +21,7 @@ import javax.inject.Inject; import javax.inject.Named; import javax.inject.Singleton; +import javax.xml.stream.XMLStreamException; import java.io.File; import java.io.FileNotFoundException; @@ -38,14 +39,13 @@ import org.apache.maven.artifact.repository.ArtifactRepositoryPolicy; import org.apache.maven.artifact.repository.DefaultRepositoryRequest; import org.apache.maven.artifact.repository.RepositoryRequest; -import org.apache.maven.artifact.repository.metadata.io.xpp3.MetadataXpp3Reader; -import org.apache.maven.artifact.repository.metadata.io.xpp3.MetadataXpp3Writer; +import org.apache.maven.artifact.repository.metadata.io.MetadataStaxReader; +import org.apache.maven.artifact.repository.metadata.io.MetadataStaxWriter; import org.apache.maven.repository.legacy.UpdateCheckManager; import org.apache.maven.repository.legacy.WagonManager; import org.apache.maven.wagon.ResourceDoesNotExistException; import org.apache.maven.wagon.TransferFailedException; import org.codehaus.plexus.logging.AbstractLogEnabled; -import org.codehaus.plexus.util.xml.pull.XmlPullParserException; /** * @author Jason van Zyl @@ -270,13 +270,11 @@ private boolean loadMetadata( */ protected Metadata readMetadata(File mappingFile) throws RepositoryMetadataReadException { - MetadataXpp3Reader mappingReader = new MetadataXpp3Reader(); try (InputStream in = Files.newInputStream(mappingFile.toPath())) { - Metadata result = mappingReader.read(in, false); - return result; + return new Metadata(new MetadataStaxReader().read(in, false)); } catch (FileNotFoundException e) { throw new RepositoryMetadataReadException("Cannot read metadata from '" + mappingFile + "'", e); - } catch (IOException | XmlPullParserException e) { + } catch (IOException | XMLStreamException e) { throw new RepositoryMetadataReadException( "Cannot read metadata from '" + mappingFile + "': " + e.getMessage(), e); } @@ -311,8 +309,8 @@ private void fixTimestamp(File metadataFile, Metadata metadata, Metadata referen getLogger().debug("Repairing metadata in " + metadataFile); try (OutputStream out = Files.newOutputStream(metadataFile.toPath())) { - new MetadataXpp3Writer().write(out, metadata); - } catch (IOException e) { + new MetadataStaxWriter().write(out, metadata.getDelegate()); + } catch (IOException | XMLStreamException e) { String msg = "Could not write fixed metadata to " + metadataFile + ": " + e.getMessage(); if (getLogger().isDebugEnabled()) { getLogger().warn(msg, e); diff --git a/maven-compat/src/main/java/org/apache/maven/project/interpolation/AbstractStringBasedModelInterpolator.java b/maven-compat/src/main/java/org/apache/maven/project/interpolation/AbstractStringBasedModelInterpolator.java index 3745157e03..739994bf75 100644 --- a/maven-compat/src/main/java/org/apache/maven/project/interpolation/AbstractStringBasedModelInterpolator.java +++ b/maven-compat/src/main/java/org/apache/maven/project/interpolation/AbstractStringBasedModelInterpolator.java @@ -19,6 +19,7 @@ package org.apache.maven.project.interpolation; import javax.inject.Inject; +import javax.xml.stream.XMLStreamException; import java.io.File; import java.io.IOException; @@ -32,8 +33,8 @@ import java.util.Properties; import org.apache.maven.model.Model; -import org.apache.maven.model.io.xpp3.MavenXpp3Reader; -import org.apache.maven.model.io.xpp3.MavenXpp3Writer; +import org.apache.maven.model.v4.MavenStaxReader; +import org.apache.maven.model.v4.MavenStaxWriter; import org.apache.maven.project.DefaultProjectBuilderConfiguration; import org.apache.maven.project.ProjectBuilderConfiguration; import org.apache.maven.project.path.PathTranslator; @@ -52,7 +53,6 @@ import org.codehaus.plexus.logging.Logger; import org.codehaus.plexus.personality.plexus.lifecycle.phase.Initializable; import org.codehaus.plexus.personality.plexus.lifecycle.phase.InitializationException; -import org.codehaus.plexus.util.xml.pull.XmlPullParserException; /** * Use a regular expression search to find and resolve expressions within the POM. @@ -130,10 +130,10 @@ public Model interpolate(Model model, File projectDir, ProjectBuilderConfigurati throws ModelInterpolationException { StringWriter sWriter = new StringWriter(1024); - MavenXpp3Writer writer = new MavenXpp3Writer(); + MavenStaxWriter writer = new MavenStaxWriter(); try { - writer.write(sWriter, model); - } catch (IOException e) { + writer.write(sWriter, model.getDelegate()); + } catch (IOException | XMLStreamException e) { throw new ModelInterpolationException("Cannot serialize project model for interpolation.", e); } @@ -142,10 +142,10 @@ public Model interpolate(Model model, File projectDir, ProjectBuilderConfigurati StringReader sReader = new StringReader(serializedModel); - MavenXpp3Reader modelReader = new MavenXpp3Reader(); + MavenStaxReader modelReader = new MavenStaxReader(); try { - model = modelReader.read(sReader); - } catch (IOException | XmlPullParserException e) { + model = new Model(modelReader.read(sReader)); + } catch (XMLStreamException e) { throw new ModelInterpolationException( "Cannot read project model from interpolating filter of serialized version.", e); } diff --git a/maven-compat/src/main/java/org/apache/maven/toolchain/DefaultToolchainsBuilder.java b/maven-compat/src/main/java/org/apache/maven/toolchain/DefaultToolchainsBuilder.java index 848d78b27c..46040ba72e 100644 --- a/maven-compat/src/main/java/org/apache/maven/toolchain/DefaultToolchainsBuilder.java +++ b/maven-compat/src/main/java/org/apache/maven/toolchain/DefaultToolchainsBuilder.java @@ -22,11 +22,11 @@ import javax.inject.Singleton; import java.io.File; -import java.io.Reader; +import java.io.InputStream; +import java.nio.file.Files; import org.apache.maven.toolchain.model.PersistedToolchains; -import org.apache.maven.toolchain.v4.MavenToolchainsXpp3Reader; -import org.codehaus.plexus.util.ReaderFactory; +import org.apache.maven.toolchain.v4.MavenToolchainsStaxReader; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -44,8 +44,8 @@ public PersistedToolchains build(File userToolchainsFile) throws MisconfiguredTo PersistedToolchains toolchains = null; if (userToolchainsFile != null && userToolchainsFile.isFile()) { - try (Reader in = ReaderFactory.newXmlReader(userToolchainsFile)) { - toolchains = new PersistedToolchains(new MavenToolchainsXpp3Reader().read(in)); + try (InputStream in = Files.newInputStream(userToolchainsFile.toPath())) { + toolchains = new PersistedToolchains(new MavenToolchainsStaxReader().read(in)); } catch (Exception e) { throw new MisconfiguredToolchainException( "Cannot read toolchains file at " + userToolchainsFile.getAbsolutePath(), e); diff --git a/maven-core/src/main/java/org/apache/maven/artifact/repository/metadata/io/DefaultMetadataReader.java b/maven-core/src/main/java/org/apache/maven/artifact/repository/metadata/io/DefaultMetadataReader.java index cf5b284657..a7b68ac101 100644 --- a/maven-core/src/main/java/org/apache/maven/artifact/repository/metadata/io/DefaultMetadataReader.java +++ b/maven-core/src/main/java/org/apache/maven/artifact/repository/metadata/io/DefaultMetadataReader.java @@ -20,6 +20,7 @@ import javax.inject.Named; import javax.inject.Singleton; +import javax.xml.stream.XMLStreamException; import java.io.File; import java.io.IOException; @@ -29,9 +30,7 @@ import java.util.Objects; import org.apache.maven.artifact.repository.metadata.Metadata; -import org.apache.maven.artifact.repository.metadata.io.xpp3.MetadataXpp3Reader; import org.codehaus.plexus.util.ReaderFactory; -import org.codehaus.plexus.util.xml.pull.XmlPullParserException; /** * Handles deserialization of metadata from some kind of textual format like XML. @@ -52,9 +51,13 @@ public Metadata read(Reader input, Map options) throws IOException { Objects.requireNonNull(input, "input cannot be null"); try (Reader in = input) { - return new MetadataXpp3Reader().read(in, isStrict(options)); - } catch (XmlPullParserException e) { - throw new MetadataParseException(e.getMessage(), e.getLineNumber(), e.getColumnNumber(), e); + return new Metadata(new MetadataStaxReader().read(in, isStrict(options))); + } catch (XMLStreamException e) { + throw new MetadataParseException( + e.getMessage(), + e.getLocation().getLineNumber(), + e.getLocation().getColumnNumber(), + e); } } @@ -62,9 +65,13 @@ public Metadata read(InputStream input, Map options) throws IOExcepti Objects.requireNonNull(input, "input cannot be null"); try (InputStream in = input) { - return new MetadataXpp3Reader().read(in, isStrict(options)); - } catch (XmlPullParserException e) { - throw new MetadataParseException(e.getMessage(), e.getLineNumber(), e.getColumnNumber(), e); + return new Metadata(new MetadataStaxReader().read(in, isStrict(options))); + } catch (XMLStreamException e) { + throw new MetadataParseException( + e.getMessage(), + e.getLocation().getLineNumber(), + e.getLocation().getColumnNumber(), + e); } } 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 d2ed147e91..215597d6eb 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 @@ -236,7 +236,7 @@ public DefaultRepositorySystemSession newRepositorySession(MavenExecutionRequest authSelector.add(server.getId(), authBuilder.build()); if (server.getConfiguration() != null) { - XmlNode dom = ((org.codehaus.plexus.util.xml.Xpp3Dom) server.getConfiguration()).getDom(); + XmlNode dom = server.getDelegate().getConfiguration(); List children = dom.getChildren().stream() .filter(c -> !"wagonProvider".equals(c.getName())) .collect(Collectors.toList()); diff --git a/maven-core/src/main/java/org/apache/maven/internal/impl/DefaultModelXmlFactory.java b/maven-core/src/main/java/org/apache/maven/internal/impl/DefaultModelXmlFactory.java index 7bfa586c5a..a3acaa6757 100644 --- a/maven-core/src/main/java/org/apache/maven/internal/impl/DefaultModelXmlFactory.java +++ b/maven-core/src/main/java/org/apache/maven/internal/impl/DefaultModelXmlFactory.java @@ -37,9 +37,8 @@ import org.apache.maven.api.services.xml.XmlReaderRequest; import org.apache.maven.api.services.xml.XmlWriterException; import org.apache.maven.api.services.xml.XmlWriterRequest; -import org.apache.maven.model.v4.MavenXpp3ReaderEx; -import org.apache.maven.model.v4.MavenXpp3WriterEx; -import org.codehaus.plexus.util.xml.XmlStreamReader; +import org.apache.maven.model.v4.MavenStaxReader; +import org.apache.maven.model.v4.MavenStaxWriter; import static org.apache.maven.internal.impl.Utils.nonNull; @@ -61,16 +60,21 @@ public Model read(@Nonnull XmlReaderRequest request) throws XmlReaderException { if (request.getModelId() != null || request.getLocation() != null) { source = new InputSource(request.getModelId(), request.getLocation()); } - MavenXpp3ReaderEx xml = new MavenXpp3ReaderEx(); + MavenStaxReader xml = new MavenStaxReader(); xml.setAddDefaultEntities(request.isAddDefaultEntities()); - if (path != null) { - reader = new XmlStreamReader(path.toFile()); - } else if (url != null) { - reader = new XmlStreamReader(url); - } else if (inputStream != null) { - reader = new XmlStreamReader(inputStream); + if (inputStream != null) { + return xml.read(inputStream, request.isStrict(), source); + } else if (reader != null) { + return xml.read(reader, request.isStrict(), source); + } else if (path != null) { + try (InputStream is = Files.newInputStream(path)) { + return xml.read(is, request.isStrict(), source); + } + } else { + try (InputStream is = url.openStream()) { + return xml.read(is, request.isStrict(), source); + } } - return xml.read(reader, request.isStrict(), source); } catch (Exception e) { throw new XmlReaderException("Unable to read model", e); } @@ -88,12 +92,12 @@ public void write(XmlWriterRequest request) throws XmlWriterException { } try { if (writer != null) { - new MavenXpp3WriterEx().write(writer, content); + new MavenStaxWriter().write(writer, content); } else if (outputStream != null) { - new MavenXpp3WriterEx().write(outputStream, content); + new MavenStaxWriter().write(outputStream, content); } else { try (OutputStream os = Files.newOutputStream(path)) { - new MavenXpp3WriterEx().write(outputStream, content); + new MavenStaxWriter().write(outputStream, content); } } } catch (Exception e) { diff --git a/maven-core/src/main/java/org/apache/maven/internal/impl/DefaultSettingsXmlFactory.java b/maven-core/src/main/java/org/apache/maven/internal/impl/DefaultSettingsXmlFactory.java index 811fd3c6b2..cb75d643e4 100644 --- a/maven-core/src/main/java/org/apache/maven/internal/impl/DefaultSettingsXmlFactory.java +++ b/maven-core/src/main/java/org/apache/maven/internal/impl/DefaultSettingsXmlFactory.java @@ -35,8 +35,8 @@ import org.apache.maven.api.services.xml.XmlWriterRequest; import org.apache.maven.api.settings.InputSource; import org.apache.maven.api.settings.Settings; -import org.apache.maven.settings.v4.SettingsXpp3ReaderEx; -import org.apache.maven.settings.v4.SettingsXpp3Writer; +import org.apache.maven.settings.v4.SettingsStaxReader; +import org.apache.maven.settings.v4.SettingsStaxWriter; @Named @Singleton @@ -54,7 +54,7 @@ public Settings read(@Nonnull XmlReaderRequest request) throws XmlReaderExceptio if (request.getModelId() != null || request.getLocation() != null) { source = new InputSource(request.getLocation()); } - SettingsXpp3ReaderEx xml = new SettingsXpp3ReaderEx(); + SettingsStaxReader xml = new SettingsStaxReader(); xml.setAddDefaultEntities(request.isAddDefaultEntities()); if (reader != null) { return xml.read(reader, request.isStrict(), source); @@ -77,9 +77,9 @@ public void write(XmlWriterRequest request) throws XmlWriterException } try { if (writer != null) { - new SettingsXpp3Writer().write(writer, content); + new SettingsStaxWriter().write(writer, content); } else { - new SettingsXpp3Writer().write(outputStream, content); + new SettingsStaxWriter().write(outputStream, content); } } catch (Exception e) { throw new XmlWriterException("Unable to write settings", e); diff --git a/maven-core/src/main/java/org/apache/maven/internal/impl/DefaultToolchainsXmlFactory.java b/maven-core/src/main/java/org/apache/maven/internal/impl/DefaultToolchainsXmlFactory.java index e289cd208f..a39bacc5ea 100644 --- a/maven-core/src/main/java/org/apache/maven/internal/impl/DefaultToolchainsXmlFactory.java +++ b/maven-core/src/main/java/org/apache/maven/internal/impl/DefaultToolchainsXmlFactory.java @@ -35,8 +35,8 @@ import org.apache.maven.api.services.xml.XmlWriterException; import org.apache.maven.api.services.xml.XmlWriterRequest; import org.apache.maven.api.toolchain.PersistedToolchains; -import org.apache.maven.toolchain.v4.MavenToolchainsXpp3Reader; -import org.apache.maven.toolchain.v4.MavenToolchainsXpp3Writer; +import org.apache.maven.toolchain.v4.MavenToolchainsStaxReader; +import org.apache.maven.toolchain.v4.MavenToolchainsStaxWriter; @Named @Singleton @@ -54,7 +54,7 @@ public PersistedToolchains read(@Nonnull XmlReaderRequest request) throws XmlRea if (request.getModelId() != null || request.getLocation() != null) { source = new InputSource(request.getModelId(), request.getLocation()); } - MavenToolchainsXpp3Reader xml = new MavenToolchainsXpp3Reader(); + MavenToolchainsStaxReader xml = new MavenToolchainsStaxReader(); xml.setAddDefaultEntities(request.isAddDefaultEntities()); if (reader != null) { return xml.read(reader, request.isStrict()); @@ -77,9 +77,9 @@ public void write(XmlWriterRequest request) throws XmlWrite } try { if (writer != null) { - new MavenToolchainsXpp3Writer().write(writer, content); + new MavenToolchainsStaxWriter().write(writer, content); } else { - new MavenToolchainsXpp3Writer().write(outputStream, content); + new MavenToolchainsStaxWriter().write(outputStream, content); } } catch (Exception e) { throw new XmlWriterException("Unable to write toolchains", e); diff --git a/maven-core/src/main/java/org/apache/maven/internal/transformation/ConsumerPomArtifactTransformer.java b/maven-core/src/main/java/org/apache/maven/internal/transformation/ConsumerPomArtifactTransformer.java index b1ffc10e82..4f7f515c9e 100644 --- a/maven-core/src/main/java/org/apache/maven/internal/transformation/ConsumerPomArtifactTransformer.java +++ b/maven-core/src/main/java/org/apache/maven/internal/transformation/ConsumerPomArtifactTransformer.java @@ -21,6 +21,8 @@ import javax.annotation.PreDestroy; import javax.inject.Named; import javax.inject.Singleton; +import javax.xml.stream.XMLStreamException; +import javax.xml.stream.XMLStreamReader; import java.io.IOException; import java.io.InputStream; @@ -38,15 +40,10 @@ import org.apache.maven.model.building.DefaultBuildPomXMLFilterFactory; import org.apache.maven.model.building.TransformerContext; import org.apache.maven.model.transform.RawToConsumerPomXMLFilterFactory; -import org.apache.maven.model.transform.pull.XmlUtils; +import org.apache.maven.model.transform.stax.XmlUtils; import org.apache.maven.project.MavenProject; import org.apache.maven.project.artifact.ProjectArtifact; -import org.codehaus.plexus.util.ReaderFactory; -import org.codehaus.plexus.util.xml.XmlStreamReader; -import org.codehaus.plexus.util.xml.pull.EntityReplacementMap; -import org.codehaus.plexus.util.xml.pull.MXParser; -import org.codehaus.plexus.util.xml.pull.XmlPullParser; -import org.codehaus.plexus.util.xml.pull.XmlPullParserException; +import org.codehaus.stax2.XMLInputFactory2; import org.eclipse.aether.RepositorySystemSession; import org.eclipse.aether.artifact.Artifact; import org.eclipse.aether.artifact.DefaultArtifact; @@ -175,7 +172,7 @@ private static BiConsumer transformer(RepositorySystemSession sessio try (InputStream inputStream = transform(src, context)) { Files.createDirectories(dest.getParent()); Files.copy(inputStream, dest, StandardCopyOption.REPLACE_EXISTING); - } catch (XmlPullParserException | IOException e) { + } catch (XMLStreamException | IOException e) { throw new RuntimeException(e); } }; @@ -185,13 +182,14 @@ private static BiConsumer transformer(RepositorySystemSession sessio /** * The actual transformation: visible for testing. */ - static InputStream transform(Path pomFile, TransformerContext context) throws IOException, XmlPullParserException { - XmlStreamReader reader = ReaderFactory.newXmlReader(Files.newInputStream(pomFile)); - XmlPullParser parser = new MXParser(EntityReplacementMap.defaultEntityReplacementMap); - parser.setInput(reader); - parser = new RawToConsumerPomXMLFilterFactory(new DefaultBuildPomXMLFilterFactory(context, true)) - .get(parser, pomFile); - - return XmlUtils.writeDocument(reader, parser); + static InputStream transform(Path pomFile, TransformerContext context) throws IOException, XMLStreamException { + try (InputStream input = Files.newInputStream(pomFile)) { + XMLInputFactory2 factory = new com.ctc.wstx.stax.WstxInputFactory(); + factory.configureForRoundTripping(); + XMLStreamReader reader = factory.createXMLStreamReader(input); + reader = new RawToConsumerPomXMLFilterFactory(new DefaultBuildPomXMLFilterFactory(context, true)) + .get(reader, pomFile); + return XmlUtils.writeDocument(reader); + } } } diff --git a/maven-core/src/main/java/org/apache/maven/lifecycle/internal/DefaultLifecycleExecutionPlanCalculator.java b/maven-core/src/main/java/org/apache/maven/lifecycle/internal/DefaultLifecycleExecutionPlanCalculator.java index bb23ebdc76..41449e0068 100644 --- a/maven-core/src/main/java/org/apache/maven/lifecycle/internal/DefaultLifecycleExecutionPlanCalculator.java +++ b/maven-core/src/main/java/org/apache/maven/lifecycle/internal/DefaultLifecycleExecutionPlanCalculator.java @@ -21,6 +21,7 @@ import javax.inject.Inject; import javax.inject.Named; import javax.inject.Singleton; +import javax.xml.stream.XMLStreamException; import java.io.IOException; import java.util.ArrayList; @@ -60,7 +61,6 @@ import org.apache.maven.plugin.version.PluginVersionResolutionException; import org.apache.maven.project.MavenProject; import org.codehaus.plexus.util.StringUtils; -import org.codehaus.plexus.util.xml.pull.XmlPullParserException; /** * NOTE: This class is not part of any public api and can be changed or deleted without prior notice. @@ -290,8 +290,9 @@ private Map> calculateLifecycleMappings( private void finalizeMojoConfiguration(MojoExecution mojoExecution) { MojoDescriptor mojoDescriptor = mojoExecution.getMojoDescriptor(); - org.codehaus.plexus.util.xml.Xpp3Dom config = mojoExecution.getConfiguration(); - XmlNode executionConfiguration = config != null ? config.getDom() : null; + XmlNode executionConfiguration = mojoExecution.getConfiguration() != null + ? mojoExecution.getConfiguration().getDom() + : null; if (executionConfiguration == null) { executionConfiguration = new XmlNodeImpl("configuration"); } @@ -462,7 +463,7 @@ private void injectLifecycleOverlay( try { lifecycleOverlay = pluginDescriptor.getLifecycleMapping(forkedLifecycle); - } catch (IOException | XmlPullParserException e) { + } catch (IOException | XMLStreamException e) { throw new PluginDescriptorParsingException(pluginDescriptor.getPlugin(), pluginDescriptor.getSource(), e); } diff --git a/maven-core/src/main/java/org/apache/maven/project/ExtensionDescriptorBuilder.java b/maven-core/src/main/java/org/apache/maven/project/ExtensionDescriptorBuilder.java index d8feb92197..af9fbeeebc 100644 --- a/maven-core/src/main/java/org/apache/maven/project/ExtensionDescriptorBuilder.java +++ b/maven-core/src/main/java/org/apache/maven/project/ExtensionDescriptorBuilder.java @@ -18,20 +18,21 @@ */ package org.apache.maven.project; -import java.io.BufferedInputStream; +import javax.xml.stream.XMLStreamException; +import javax.xml.stream.XMLStreamReader; + import java.io.File; -import java.io.FileInputStream; import java.io.IOException; import java.io.InputStream; +import java.nio.file.Files; import java.util.ArrayList; import java.util.List; import java.util.jar.JarFile; import java.util.zip.ZipEntry; +import com.ctc.wstx.stax.WstxInputFactory; import org.apache.maven.api.xml.XmlNode; import org.apache.maven.internal.xml.XmlNodeBuilder; -import org.codehaus.plexus.util.ReaderFactory; -import org.codehaus.plexus.util.xml.pull.XmlPullParserException; /** * Creates an extension descriptor from some XML stream. @@ -71,7 +72,7 @@ public ExtensionDescriptor build(File extensionJar) throws IOException { File pluginXml = new File(extensionJar, getExtensionDescriptorLocation()); if (pluginXml.canRead()) { - try (InputStream is = new BufferedInputStream(new FileInputStream(pluginXml))) { + try (InputStream is = Files.newInputStream(pluginXml.toPath())) { extensionDescriptor = build(is); } } @@ -88,8 +89,9 @@ public ExtensionDescriptor build(InputStream is) throws IOException { XmlNode dom; try { - dom = XmlNodeBuilder.build(ReaderFactory.newXmlReader(is)); - } catch (XmlPullParserException e) { + XMLStreamReader reader = WstxInputFactory.newFactory().createXMLStreamReader(is); + dom = XmlNodeBuilder.build(reader); + } catch (XMLStreamException e) { throw new IOException(e.getMessage(), e); } diff --git a/maven-core/src/main/resources/META-INF/maven/extension.xml b/maven-core/src/main/resources/META-INF/maven/extension.xml index d4936cf405..e79e7e0bc5 100644 --- a/maven-core/src/main/resources/META-INF/maven/extension.xml +++ b/maven-core/src/main/resources/META-INF/maven/extension.xml @@ -144,6 +144,9 @@ under the License. org.apache.maven:maven-api-toolchain org.apache.maven:maven-api-xml + com.fasterxml:aalto-xml + org.codehaus.woodstox:stax2-api + classworlds:classworlds org.codehaus.plexus:plexus-classworlds org.codehaus.plexus:plexus-component-api diff --git a/maven-core/src/test/java/org/apache/maven/configuration/DefaultBeanConfiguratorPathTest.java b/maven-core/src/test/java/org/apache/maven/configuration/DefaultBeanConfiguratorPathTest.java index 1beeb43abb..5caada2ce2 100644 --- a/maven-core/src/test/java/org/apache/maven/configuration/DefaultBeanConfiguratorPathTest.java +++ b/maven-core/src/test/java/org/apache/maven/configuration/DefaultBeanConfiguratorPathTest.java @@ -18,8 +18,9 @@ */ package org.apache.maven.configuration; +import javax.xml.stream.XMLStreamException; + import java.io.File; -import java.io.IOException; import java.io.StringReader; import java.nio.file.Path; import java.nio.file.Paths; @@ -27,7 +28,6 @@ import org.apache.maven.configuration.internal.DefaultBeanConfigurator; import org.apache.maven.internal.xml.XmlNodeBuilder; import org.codehaus.plexus.util.xml.Xpp3Dom; -import org.codehaus.plexus.util.xml.pull.XmlPullParserException; import org.junit.jupiter.api.AfterEach; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; @@ -53,8 +53,10 @@ void tearDown() throws Exception { private Xpp3Dom toConfig(String xml) { try { - return new Xpp3Dom(XmlNodeBuilder.build(new StringReader("" + xml + ""))); - } catch (XmlPullParserException | IOException e) { + return new Xpp3Dom(XmlNodeBuilder.build( + new StringReader("" + xml + ""), + (XmlNodeBuilder.InputLocationBuilderStax) null)); + } catch (XMLStreamException e) { throw new IllegalArgumentException(e); } } diff --git a/maven-core/src/test/java/org/apache/maven/configuration/DefaultBeanConfiguratorTest.java b/maven-core/src/test/java/org/apache/maven/configuration/DefaultBeanConfiguratorTest.java index abca92facf..fabb6be6f4 100644 --- a/maven-core/src/test/java/org/apache/maven/configuration/DefaultBeanConfiguratorTest.java +++ b/maven-core/src/test/java/org/apache/maven/configuration/DefaultBeanConfiguratorTest.java @@ -18,14 +18,14 @@ */ package org.apache.maven.configuration; +import javax.xml.stream.XMLStreamException; + import java.io.File; -import java.io.IOException; import java.io.StringReader; import org.apache.maven.configuration.internal.DefaultBeanConfigurator; import org.apache.maven.internal.xml.XmlNodeBuilder; import org.codehaus.plexus.util.xml.Xpp3Dom; -import org.codehaus.plexus.util.xml.pull.XmlPullParserException; import org.junit.jupiter.api.AfterEach; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; @@ -51,8 +51,10 @@ void tearDown() throws Exception { private Xpp3Dom toConfig(String xml) { try { - return new Xpp3Dom(XmlNodeBuilder.build(new StringReader("" + xml + ""))); - } catch (XmlPullParserException | IOException e) { + return new Xpp3Dom(XmlNodeBuilder.build( + new StringReader("" + xml + ""), + (XmlNodeBuilder.InputLocationBuilderStax) null)); + } catch (XMLStreamException e) { throw new IllegalArgumentException(e); } } 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 2edf9a6887..50254bda92 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 @@ -105,7 +105,7 @@ void testVersionlessManagedDependency() throws Exception { e.getResults(), contains(projectBuildingResultWithProblemMessage( "'dependencies.dependency.version' for org.apache.maven.its:a:jar is missing"))); - assertThat(e.getResults(), contains(projectBuildingResultWithLocation(17, 9))); + assertThat(e.getResults(), contains(projectBuildingResultWithLocation(5, 9))); } @Test @@ -234,7 +234,7 @@ void testReadInvalidPom() throws Exception { // single project build entry point Exception ex = assertThrows(Exception.class, () -> projectBuilder.build(pomFile, configuration)); - assertThat(ex.getMessage(), containsString("expected START_TAG or END_TAG not TEXT")); + assertThat(ex.getMessage(), containsString("Received non-all-whitespace CHARACTERS or CDATA event")); // multi projects build entry point ProjectBuildingException pex = assertThrows( @@ -245,7 +245,7 @@ void testReadInvalidPom() throws Exception { assertThat(pex.getResults().get(0).getProblems().size(), greaterThan(0)); assertThat( pex.getResults(), - contains(projectBuildingResultWithProblemMessage("expected START_TAG or END_TAG not TEXT"))); + contains(projectBuildingResultWithProblemMessage("expected START_TAG or END_TAG not CHARACTERS"))); } @Test diff --git a/maven-embedder/pom.xml b/maven-embedder/pom.xml index 6b2ab7931f..7541fc0fdb 100644 --- a/maven-embedder/pom.xml +++ b/maven-embedder/pom.xml @@ -178,14 +178,22 @@ under the License. src/main/mdo/core-extensions.mdo + + + + + + + packageModelV4=org.apache.maven.cli.internal.extension.model + packageToolV4=org.apache.maven.cli.internal.extension.io + + ${project.basedir}/../src/mdo modello - java - xpp3-reader - xpp3-writer + velocity diff --git a/maven-embedder/src/main/java/org/apache/maven/cli/MavenCli.java b/maven-embedder/src/main/java/org/apache/maven/cli/MavenCli.java index 59456f0431..5070deffa1 100644 --- a/maven-embedder/src/main/java/org/apache/maven/cli/MavenCli.java +++ b/maven-embedder/src/main/java/org/apache/maven/cli/MavenCli.java @@ -18,10 +18,10 @@ */ package org.apache.maven.cli; -import java.io.BufferedInputStream; +import javax.xml.stream.XMLStreamException; + import java.io.Console; import java.io.File; -import java.io.FileInputStream; import java.io.FileNotFoundException; import java.io.FileOutputStream; import java.io.IOException; @@ -56,8 +56,8 @@ import org.apache.maven.cli.event.DefaultEventSpyContext; import org.apache.maven.cli.event.ExecutionEventLogger; import org.apache.maven.cli.internal.BootstrapCoreExtensionManager; +import org.apache.maven.cli.internal.extension.io.CoreExtensionsStaxReader; import org.apache.maven.cli.internal.extension.model.CoreExtension; -import org.apache.maven.cli.internal.extension.model.io.xpp3.CoreExtensionsXpp3Reader; import org.apache.maven.cli.jansi.JansiMessageBuilderFactory; import org.apache.maven.cli.jansi.MessageUtils; import org.apache.maven.cli.logging.Slf4jConfiguration; @@ -108,7 +108,6 @@ import org.codehaus.plexus.interpolation.StringSearchInterpolator; import org.codehaus.plexus.logging.LoggerManager; import org.codehaus.plexus.util.StringUtils; -import org.codehaus.plexus.util.xml.pull.XmlPullParserException; import org.eclipse.aether.DefaultRepositoryCache; import org.eclipse.aether.transfer.TransferListener; import org.slf4j.ILoggerFactory; @@ -795,12 +794,11 @@ protected void configure() { } private List readCoreExtensionsDescriptor(File extensionsFile) - throws IOException, XmlPullParserException { - CoreExtensionsXpp3Reader parser = new CoreExtensionsXpp3Reader(); + throws IOException, XMLStreamException { + CoreExtensionsStaxReader parser = new CoreExtensionsStaxReader(); - try (InputStream is = new BufferedInputStream(new FileInputStream(extensionsFile))) { - - return parser.read(is).getExtensions(); + try (InputStream is = Files.newInputStream(extensionsFile.toPath())) { + return parser.read(is, true).getExtensions(); } } diff --git a/maven-model-builder/src/main/java/org/apache/maven/model/building/BuildModelSourceTransformer.java b/maven-model-builder/src/main/java/org/apache/maven/model/building/BuildModelSourceTransformer.java index 56adfdec96..b85e65def3 100644 --- a/maven-model-builder/src/main/java/org/apache/maven/model/building/BuildModelSourceTransformer.java +++ b/maven-model-builder/src/main/java/org/apache/maven/model/building/BuildModelSourceTransformer.java @@ -20,12 +20,12 @@ import javax.inject.Named; import javax.inject.Singleton; +import javax.xml.stream.XMLStreamReader; import java.io.IOException; import java.nio.file.Path; import org.apache.maven.model.transform.BuildToRawPomXMLFilterFactory; -import org.codehaus.plexus.util.xml.pull.XmlPullParser; /** * ModelSourceTransformer for the build pom @@ -37,7 +37,7 @@ @Singleton class BuildModelSourceTransformer implements ModelSourceTransformer { @Override - public XmlPullParser transform(XmlPullParser parser, Path pomFile, TransformerContext context) + public XMLStreamReader transform(XMLStreamReader parser, Path pomFile, TransformerContext context) throws IOException, TransformerException { BuildToRawPomXMLFilterFactory buildPomXMLFilterFactory = new DefaultBuildPomXMLFilterFactory(context, false); 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 40c91d7076..e3be583719 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 @@ -18,11 +18,11 @@ */ package org.apache.maven.model.building; +import javax.xml.stream.XMLStreamReader; + import java.io.IOException; import java.nio.file.Path; -import org.codehaus.plexus.util.xml.pull.XmlPullParser; - /** * Default ModelSourceTransformer, provides pomFile as inputStream and ignores the context * @@ -32,7 +32,7 @@ public class DefaultModelSourceTransformer implements ModelSourceTransformer { @Override - public XmlPullParser transform(XmlPullParser parser, Path pomFile, TransformerContext context) + public XMLStreamReader transform(XMLStreamReader parser, Path pomFile, TransformerContext context) throws IOException, TransformerException { return parser; } 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 22bd0be619..127a869c55 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 @@ -18,15 +18,15 @@ */ package org.apache.maven.model.building; +import javax.xml.stream.XMLStreamReader; + import java.io.IOException; import java.nio.file.Path; -import org.codehaus.plexus.util.xml.pull.XmlPullParser; - /** * The ModelSourceTransformer is a way to transform the local pom while streaming the input. * - * The {@link #transform(XmlPullParser, Path, TransformerContext)} method uses a Path on purpose, to ensure the + * The {@link #transform(XMLStreamReader, Path, TransformerContext)} method uses a Path on purpose, to ensure the * local pom is the original source. * * @author Robert Scholte @@ -42,6 +42,6 @@ public interface ModelSourceTransformer { * @throws IOException if an I/O error occurs * @throws TransformerException if the transformation fails */ - XmlPullParser transform(XmlPullParser parser, Path pomFile, TransformerContext context) + XMLStreamReader transform(XMLStreamReader parser, Path pomFile, TransformerContext context) throws IOException, TransformerException; } 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 82f6328055..4c96b949f7 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 @@ -21,11 +21,16 @@ import javax.inject.Inject; import javax.inject.Named; import javax.inject.Singleton; +import javax.xml.stream.Location; +import javax.xml.stream.XMLInputFactory; +import javax.xml.stream.XMLStreamException; +import javax.xml.stream.XMLStreamReader; import java.io.File; import java.io.IOException; import java.io.InputStream; import java.io.Reader; +import java.nio.file.Files; import java.nio.file.Path; import java.util.Map; import java.util.Objects; @@ -34,14 +39,7 @@ 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.v4.MavenXpp3Reader; -import org.apache.maven.model.v4.MavenXpp3ReaderEx; -import org.codehaus.plexus.util.ReaderFactory; -import org.codehaus.plexus.util.xml.XmlStreamReader; -import org.codehaus.plexus.util.xml.pull.EntityReplacementMap; -import org.codehaus.plexus.util.xml.pull.MXParser; -import org.codehaus.plexus.util.xml.pull.XmlPullParser; -import org.codehaus.plexus.util.xml.pull.XmlPullParserException; +import org.apache.maven.model.v4.MavenStaxReader; /** * Handles deserialization of a model from some kind of textual format like XML. @@ -62,7 +60,7 @@ public DefaultModelReader(ModelSourceTransformer transformer) { public Model read(File input, Map options) throws IOException { Objects.requireNonNull(input, "input cannot be null"); - try (XmlStreamReader in = ReaderFactory.newXmlReader(input)) { + try (InputStream in = Files.newInputStream(input.toPath())) { Model model = read(in, input.toPath(), options); model.setPomFile(input); @@ -84,8 +82,8 @@ public Model read(Reader input, Map options) throws IOException { public Model read(InputStream input, Map options) throws IOException { Objects.requireNonNull(input, "input cannot be null"); - try (XmlStreamReader in = ReaderFactory.newXmlReader(input)) { - return read(in, null, options); + try (InputStream in = input) { + return read(input, null, options); } } @@ -104,13 +102,14 @@ private TransformerContext getTransformerContext(Map options) { return (TransformerContext) value; } - private Model read(Reader reader, Path pomFile, Map options) throws IOException { + private Model read(InputStream input, Path pomFile, Map options) throws IOException { try { - XmlPullParser parser = new MXParser(EntityReplacementMap.defaultEntityReplacementMap); - parser.setInput(reader); + XMLInputFactory factory = new com.ctc.wstx.stax.WstxInputFactory(); + factory.setProperty(XMLInputFactory.IS_REPLACING_ENTITY_REFERENCES, false); + XMLStreamReader parser = factory.createXMLStreamReader(input); TransformerContext context = getTransformerContext(options); - XmlPullParser transformingParser = + XMLStreamReader transformingParser = context != null ? transformer.transform(parser, pomFile, context) : parser; InputSource source = getSource(options); @@ -120,8 +119,13 @@ private Model read(Reader reader, Path pomFile, Map options) throws I } else { return readModel(transformingParser, strict); } - } catch (XmlPullParserException e) { - throw new ModelParseException(e.getMessage(), e.getLineNumber(), e.getColumnNumber(), e); + } catch (XMLStreamException e) { + Location location = e.getLocation(); + throw new ModelParseException( + e.getMessage(), + location != null ? location.getLineNumber() : -1, + location != null ? location.getColumnNumber() : -1, + e); } catch (IOException e) { throw e; } catch (Exception e) { @@ -129,14 +133,46 @@ private Model read(Reader reader, Path pomFile, Map options) throws I } } - private Model readModel(XmlPullParser parser, boolean strict) throws XmlPullParserException, IOException { - MavenXpp3Reader mr = new MavenXpp3Reader(); - return new Model(mr.read(parser, strict)); + private Model read(Reader reader, Path pomFile, Map options) throws IOException { + try { + XMLInputFactory factory = new com.ctc.wstx.stax.WstxInputFactory(); + factory.setProperty(XMLInputFactory.IS_REPLACING_ENTITY_REFERENCES, false); + XMLStreamReader parser = factory.createXMLStreamReader(reader); + + TransformerContext context = getTransformerContext(options); + XMLStreamReader transformingParser = + context != null ? transformer.transform(parser, pomFile, context) : parser; + + InputSource source = getSource(options); + boolean strict = isStrict(options); + if (source != null) { + return readModelEx(transformingParser, source, strict); + } else { + return readModel(transformingParser, strict); + } + } catch (XMLStreamException e) { + Location location = e.getLocation(); + throw new ModelParseException( + e.getMessage(), + location != null ? location.getLineNumber() : -1, + location != null ? location.getColumnNumber() : -1, + e); + } catch (IOException e) { + throw e; + } catch (Exception e) { + throw new IOException("Unable to transform pom", e); + } } - private Model readModelEx(XmlPullParser parser, InputSource source, boolean strict) - throws XmlPullParserException, IOException { - MavenXpp3ReaderEx mr = new MavenXpp3ReaderEx(); + private Model readModel(XMLStreamReader parser, boolean strict) throws XMLStreamException, IOException { + MavenStaxReader mr = new MavenStaxReader(); + mr.setAddLocationInformation(false); + return new Model(mr.read(parser, strict, null)); + } + + private Model readModelEx(XMLStreamReader parser, InputSource source, boolean strict) + throws XMLStreamException, IOException { + MavenStaxReader mr = new MavenStaxReader(); return new Model(mr.read( parser, strict, new org.apache.maven.api.model.InputSource(source.getModelId(), source.getLocation()))); } diff --git a/maven-model-builder/src/main/java/org/apache/maven/model/plugin/DefaultPluginConfigurationExpander.java b/maven-model-builder/src/main/java/org/apache/maven/model/plugin/DefaultPluginConfigurationExpander.java index 72643644de..0f331cd762 100644 --- a/maven-model-builder/src/main/java/org/apache/maven/model/plugin/DefaultPluginConfigurationExpander.java +++ b/maven-model-builder/src/main/java/org/apache/maven/model/plugin/DefaultPluginConfigurationExpander.java @@ -23,6 +23,7 @@ import java.util.List; +import org.apache.maven.api.xml.XmlNode; import org.apache.maven.model.Build; import org.apache.maven.model.Model; import org.apache.maven.model.Plugin; @@ -30,7 +31,6 @@ import org.apache.maven.model.PluginManagement; import org.apache.maven.model.building.ModelBuildingRequest; import org.apache.maven.model.building.ModelProblemCollector; -import org.codehaus.plexus.util.xml.Xpp3Dom; /** * Handles expansion of general build plugin configuration into individual executions. @@ -58,16 +58,13 @@ public void expandPluginConfiguration(Model model, ModelBuildingRequest request, private void expand(List plugins) { for (Plugin plugin : plugins) { - Xpp3Dom pluginConfiguration = (Xpp3Dom) plugin.getConfiguration(); + XmlNode pluginConfiguration = plugin.getDelegate().getConfiguration(); if (pluginConfiguration != null) { for (PluginExecution execution : plugin.getExecutions()) { - Xpp3Dom executionConfiguration = (Xpp3Dom) execution.getConfiguration(); - - executionConfiguration = - Xpp3Dom.mergeXpp3Dom(executionConfiguration, new Xpp3Dom(pluginConfiguration)); - - execution.setConfiguration(executionConfiguration); + XmlNode executionConfiguration = execution.getDelegate().getConfiguration(); + executionConfiguration = XmlNode.merge(executionConfiguration, pluginConfiguration); + execution.update(execution.getDelegate().withConfiguration(executionConfiguration)); } } } diff --git a/maven-model-builder/src/main/java/org/apache/maven/model/plugin/DefaultReportConfigurationExpander.java b/maven-model-builder/src/main/java/org/apache/maven/model/plugin/DefaultReportConfigurationExpander.java index 87c14a48f5..0c7a81131d 100644 --- a/maven-model-builder/src/main/java/org/apache/maven/model/plugin/DefaultReportConfigurationExpander.java +++ b/maven-model-builder/src/main/java/org/apache/maven/model/plugin/DefaultReportConfigurationExpander.java @@ -21,13 +21,13 @@ import javax.inject.Named; import javax.inject.Singleton; +import org.apache.maven.api.xml.XmlNode; import org.apache.maven.model.Model; import org.apache.maven.model.ReportPlugin; import org.apache.maven.model.ReportSet; import org.apache.maven.model.Reporting; import org.apache.maven.model.building.ModelBuildingRequest; import org.apache.maven.model.building.ModelProblemCollector; -import org.codehaus.plexus.util.xml.Xpp3Dom; /** * Handles expansion of general report plugin configuration into individual report sets. @@ -44,13 +44,13 @@ public void expandPluginConfiguration(Model model, ModelBuildingRequest request, if (reporting != null) { for (ReportPlugin reportPlugin : reporting.getPlugins()) { - Xpp3Dom parentDom = (Xpp3Dom) reportPlugin.getConfiguration(); + XmlNode parentDom = reportPlugin.getDelegate().getConfiguration(); if (parentDom != null) { for (ReportSet execution : reportPlugin.getReportSets()) { - Xpp3Dom childDom = (Xpp3Dom) execution.getConfiguration(); - childDom = Xpp3Dom.mergeXpp3Dom(childDom, new Xpp3Dom(parentDom)); - execution.setConfiguration(childDom); + XmlNode childDom = execution.getDelegate().getConfiguration(); + childDom = XmlNode.merge(childDom, parentDom); + execution.update(execution.getDelegate().withConfiguration(childDom)); } } } diff --git a/maven-model-builder/src/main/java/org/apache/maven/model/root/DefaultRootLocator.java b/maven-model-builder/src/main/java/org/apache/maven/model/root/DefaultRootLocator.java index 4b4a36a22a..0321e7b86e 100644 --- a/maven-model-builder/src/main/java/org/apache/maven/model/root/DefaultRootLocator.java +++ b/maven-model-builder/src/main/java/org/apache/maven/model/root/DefaultRootLocator.java @@ -19,14 +19,15 @@ package org.apache.maven.model.root; import javax.inject.Named; +import javax.xml.stream.XMLStreamException; +import javax.xml.stream.XMLStreamReader; import java.io.IOException; import java.io.InputStream; import java.nio.file.Files; import java.nio.file.Path; -import org.codehaus.plexus.util.xml.pull.MXParser; -import org.codehaus.plexus.util.xml.pull.XmlPullParserException; +import com.ctc.wstx.stax.WstxInputFactory; @Named public class DefaultRootLocator implements RootLocator { @@ -38,16 +39,16 @@ public boolean isRootDirectory(Path dir) { // we're too early to use the modelProcessor ... Path pom = dir.resolve("pom.xml"); try (InputStream is = Files.newInputStream(pom)) { - MXParser parser = new MXParser(); - parser.setInput(is, null); - if (parser.nextTag() == MXParser.START_TAG && parser.getName().equals("project")) { + XMLStreamReader parser = new WstxInputFactory().createXMLStreamReader(is); + if (parser.nextTag() == XMLStreamReader.START_ELEMENT + && parser.getLocalName().equals("project")) { for (int i = 0; i < parser.getAttributeCount(); i++) { - if ("root".equals(parser.getAttributeName(i))) { + if ("root".equals(parser.getAttributeLocalName(i))) { return Boolean.parseBoolean(parser.getAttributeValue(i)); } } } - } catch (IOException | XmlPullParserException e) { + } catch (IOException | XMLStreamException e) { // The root locator can be used very early during the setup of Maven, // even before the arguments from the command line are parsed. Any exception // that would happen here should cause the build to fail at a later stage 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 70733f1d26..a18b8b1bf3 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 @@ -18,6 +18,8 @@ */ package org.apache.maven.model.inheritance; +import javax.xml.stream.XMLStreamReader; + import java.io.File; import java.io.IOException; import java.nio.file.Path; @@ -30,7 +32,6 @@ import org.apache.maven.model.io.DefaultModelReader; import org.apache.maven.model.io.DefaultModelWriter; import org.apache.maven.model.io.ModelWriter; -import org.codehaus.plexus.util.xml.pull.XmlPullParser; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; import org.xmlunit.matchers.CompareMatcher; @@ -53,7 +54,7 @@ class DefaultInheritanceAssemblerTest { void setUp() throws Exception { reader = new DefaultModelReader(new AbstractModelSourceTransformer() { @Override - public XmlPullParser transform(XmlPullParser parser, Path pomFile, TransformerContext context) + public XMLStreamReader transform(XMLStreamReader parser, Path pomFile, TransformerContext context) throws IOException, TransformerException { return null; } diff --git a/maven-model-transform/pom.xml b/maven-model-transform/pom.xml index a44707576d..50a90c7ec4 100644 --- a/maven-model-transform/pom.xml +++ b/maven-model-transform/pom.xml @@ -32,6 +32,14 @@ under the License. org.codehaus.plexus plexus-xml + + org.codehaus.woodstox + stax2-api + + + com.fasterxml.woodstox + woodstox-core + org.junit.jupiter junit-jupiter-params diff --git a/maven-model-transform/src/main/java/org/apache/maven/model/transform/BuildToRawPomXMLFilterFactory.java b/maven-model-transform/src/main/java/org/apache/maven/model/transform/BuildToRawPomXMLFilterFactory.java index 1a4a5022a4..219fd89b8e 100644 --- a/maven-model-transform/src/main/java/org/apache/maven/model/transform/BuildToRawPomXMLFilterFactory.java +++ b/maven-model-transform/src/main/java/org/apache/maven/model/transform/BuildToRawPomXMLFilterFactory.java @@ -18,13 +18,13 @@ */ package org.apache.maven.model.transform; +import javax.xml.stream.XMLStreamReader; + import java.nio.file.Path; import java.util.Optional; import java.util.function.BiFunction; import java.util.function.Function; -import org.codehaus.plexus.util.xml.pull.XmlPullParser; - /** * Base implementation for providing the BuildToRawPomXML. * @@ -46,10 +46,10 @@ public BuildToRawPomXMLFilterFactory(boolean consume) { * * @param projectFile will be used by ConsumerPomXMLFilter to get the right filter */ - public final XmlPullParser get(XmlPullParser orgParser, Path projectFile) { + public final XMLStreamReader get(XMLStreamReader orgParser, Path projectFile) { // Ensure that xs:any elements aren't touched by next filters - XmlPullParser parser = orgParser instanceof FastForwardFilter ? orgParser : new FastForwardFilter(orgParser); + XMLStreamReader parser = orgParser instanceof FastForwardFilter ? orgParser : new FastForwardFilter(orgParser); if (getDependencyKeyToVersionMapper() != null) { parser = new ReactorDependencyXMLFilter(parser, getDependencyKeyToVersionMapper()); diff --git a/maven-model-transform/src/main/java/org/apache/maven/model/transform/CiFriendlyXMLFilter.java b/maven-model-transform/src/main/java/org/apache/maven/model/transform/CiFriendlyXMLFilter.java index 8ffedcb7d5..3ec76255b4 100644 --- a/maven-model-transform/src/main/java/org/apache/maven/model/transform/CiFriendlyXMLFilter.java +++ b/maven-model-transform/src/main/java/org/apache/maven/model/transform/CiFriendlyXMLFilter.java @@ -18,11 +18,12 @@ */ package org.apache.maven.model.transform; +import javax.xml.stream.XMLStreamReader; + import java.util.List; import java.util.function.Function; -import org.apache.maven.model.transform.pull.NodeBufferingParser; -import org.codehaus.plexus.util.xml.pull.XmlPullParser; +import org.apache.maven.model.transform.stax.NodeBufferingParser; /** * Resolves all ci-friendly properties occurrences between version-tags @@ -36,8 +37,8 @@ class CiFriendlyXMLFilter extends NodeBufferingParser { private Function replaceChain = Function.identity(); - CiFriendlyXMLFilter(XmlPullParser xmlPullParser, boolean replace) { - super(xmlPullParser, "version"); + CiFriendlyXMLFilter(XMLStreamReader delegate, boolean replace) { + super(delegate, "version"); this.replace = replace; } @@ -66,7 +67,7 @@ public boolean isSet() { @Override protected void process(List buffer) { for (Event event : buffer) { - if (event.event == TEXT && replace && event.text.contains("${")) { + if (event.event == CHARACTERS && replace && event.text.contains("${")) { event.text = replaceChain.apply(event.text); } pushEvent(event); diff --git a/maven-model-transform/src/main/java/org/apache/maven/model/transform/FastForwardFilter.java b/maven-model-transform/src/main/java/org/apache/maven/model/transform/FastForwardFilter.java index 2ac0540c06..8c9af2c3d6 100644 --- a/maven-model-transform/src/main/java/org/apache/maven/model/transform/FastForwardFilter.java +++ b/maven-model-transform/src/main/java/org/apache/maven/model/transform/FastForwardFilter.java @@ -18,13 +18,13 @@ */ package org.apache.maven.model.transform; -import java.io.IOException; +import javax.xml.stream.XMLStreamException; +import javax.xml.stream.XMLStreamReader; + import java.util.ArrayDeque; import java.util.Deque; -import org.apache.maven.model.transform.pull.BufferingParser; -import org.codehaus.plexus.util.xml.pull.XmlPullParser; -import org.codehaus.plexus.util.xml.pull.XmlPullParserException; +import org.apache.maven.model.transform.stax.BufferingParser; /** * This filter will bypass all following filters and write directly to the output. @@ -52,27 +52,20 @@ class FastForwardFilter extends BufferingParser { private int domDepth = 0; - FastForwardFilter(XmlPullParser xmlPullParser) { - super(xmlPullParser); + FastForwardFilter(XMLStreamReader delegate) { + super(delegate); } @Override - public int next() throws XmlPullParserException, IOException { + public int next() throws XMLStreamException { int event = super.next(); filter(); return event; } - @Override - public int nextToken() throws XmlPullParserException, IOException { - int event = super.nextToken(); - filter(); - return event; - } - - protected void filter() throws XmlPullParserException, IOException { - if (xmlPullParser.getEventType() == START_TAG) { - String localName = xmlPullParser.getName(); + protected void filter() throws XMLStreamException { + if (delegate.getEventType() == START_ELEMENT) { + String localName = delegate.getLocalName(); if (domDepth > 0) { domDepth++; } else { @@ -94,7 +87,7 @@ protected void filter() throws XmlPullParserException, IOException { } } state.add(localName); - } else if (xmlPullParser.getEventType() == END_TAG) { + } else if (delegate.getEventType() == END_ELEMENT) { if (domDepth > 0) { if (--domDepth == 0) { bypass(false); diff --git a/maven-model-transform/src/main/java/org/apache/maven/model/transform/ModelVersionXMLFilter.java b/maven-model-transform/src/main/java/org/apache/maven/model/transform/ModelVersionXMLFilter.java index c0e71eb653..645030aeee 100644 --- a/maven-model-transform/src/main/java/org/apache/maven/model/transform/ModelVersionXMLFilter.java +++ b/maven-model-transform/src/main/java/org/apache/maven/model/transform/ModelVersionXMLFilter.java @@ -18,57 +18,63 @@ */ package org.apache.maven.model.transform; +import javax.xml.stream.XMLStreamReader; + import java.util.List; import java.util.regex.Pattern; -import org.apache.maven.model.transform.pull.NodeBufferingParser; -import org.codehaus.plexus.util.xml.pull.XmlPullParser; +import org.apache.maven.model.transform.stax.NodeBufferingParser; public class ModelVersionXMLFilter extends NodeBufferingParser { private static final Pattern S_FILTER = Pattern.compile("\\s+"); public static final String NAMESPACE_PREFIX = "http://maven.apache.org/POM/"; - public ModelVersionXMLFilter(XmlPullParser xmlPullParser) { - super(xmlPullParser, "project"); + public ModelVersionXMLFilter(XMLStreamReader delegate) { + super(delegate, "project"); } @Override protected void process(List buffer) { - if (buffer.stream().noneMatch(e -> e.event == XmlPullParser.START_TAG && "modelVersion".equals(e.name))) { + if (buffer.stream().noneMatch(e -> e.event == START_ELEMENT && "modelVersion".equals(e.name))) { String namespace = null; + String prefix = null; for (int pos = 0; pos < buffer.size(); pos++) { Event e = buffer.get(pos); if (namespace != null) { - if (e.event == XmlPullParser.START_TAG) { + if (e.event == START_ELEMENT) { Event prev = buffer.get(pos - 1); - if (prev.event != TEXT || !S_FILTER.matcher(prev.text).matches()) { + if (prev.event != CHARACTERS + || !S_FILTER.matcher(prev.text).matches()) { prev = null; } Event pmse = new Event(); - pmse.event = START_TAG; + pmse.event = START_ELEMENT; pmse.name = "modelVersion"; pmse.namespace = namespace; + pmse.prefix = prefix; buffer.add(pos++, pmse); Event pmve = new Event(); - pmve.event = TEXT; + pmve.event = CHARACTERS; pmve.text = namespace.substring(NAMESPACE_PREFIX.length()); buffer.add(pos++, pmve); Event pmee = new Event(); - pmee.event = END_TAG; + pmee.event = END_ELEMENT; pmee.name = "modelVersion"; pmee.namespace = namespace; + pmee.prefix = prefix; buffer.add(pos++, pmee); if (prev != null) { buffer.add(pos++, prev); } break; } - } else if (e.event == XmlPullParser.START_TAG + } else if (e.event == START_ELEMENT && "project".equals(e.name) && e.namespace != null && e.namespace.startsWith(NAMESPACE_PREFIX)) { namespace = e.namespace; + prefix = e.prefix; } } } diff --git a/maven-model-transform/src/main/java/org/apache/maven/model/transform/ModulesXMLFilter.java b/maven-model-transform/src/main/java/org/apache/maven/model/transform/ModulesXMLFilter.java index af06ef9a78..c8add2c863 100644 --- a/maven-model-transform/src/main/java/org/apache/maven/model/transform/ModulesXMLFilter.java +++ b/maven-model-transform/src/main/java/org/apache/maven/model/transform/ModulesXMLFilter.java @@ -18,10 +18,11 @@ */ package org.apache.maven.model.transform; +import javax.xml.stream.XMLStreamReader; + import java.util.List; -import org.apache.maven.model.transform.pull.NodeBufferingParser; -import org.codehaus.plexus.util.xml.pull.XmlPullParser; +import org.apache.maven.model.transform.stax.NodeBufferingParser; /** * Remove all modules, this is just buildtime information @@ -31,8 +32,8 @@ * @since 4.0.0 */ class ModulesXMLFilter extends NodeBufferingParser { - ModulesXMLFilter(XmlPullParser xmlPullParser) { - super(xmlPullParser, "modules"); + ModulesXMLFilter(XMLStreamReader delegate) { + super(delegate, "modules"); } protected void process(List buffer) { diff --git a/maven-model-transform/src/main/java/org/apache/maven/model/transform/ParentXMLFilter.java b/maven-model-transform/src/main/java/org/apache/maven/model/transform/ParentXMLFilter.java index 37160fd352..d483405f99 100644 --- a/maven-model-transform/src/main/java/org/apache/maven/model/transform/ParentXMLFilter.java +++ b/maven-model-transform/src/main/java/org/apache/maven/model/transform/ParentXMLFilter.java @@ -18,6 +18,8 @@ */ package org.apache.maven.model.transform; +import javax.xml.stream.XMLStreamReader; + import java.nio.file.Files; import java.nio.file.Path; import java.nio.file.Paths; @@ -27,8 +29,7 @@ import java.util.function.Function; import java.util.regex.Pattern; -import org.apache.maven.model.transform.pull.NodeBufferingParser; -import org.codehaus.plexus.util.xml.pull.XmlPullParser; +import org.apache.maven.model.transform.stax.NodeBufferingParser; /** *

@@ -54,8 +55,8 @@ class ParentXMLFilter extends NodeBufferingParser { * @param relativePathMapper */ ParentXMLFilter( - XmlPullParser parser, Function> relativePathMapper, Path projectPath) { - super(parser, "parent"); + XMLStreamReader delegate, Function> relativePathMapper, Path projectPath) { + super(delegate, "parent"); this.relativePathMapper = relativePathMapper; this.projectPath = projectPath; } @@ -71,11 +72,11 @@ protected void process(List buffer) { boolean hasRelativePath = false; for (int i = 0; i < buffer.size(); i++) { Event event = buffer.get(i); - if (event.event == START_TAG) { + if (event.event == START_ELEMENT) { tagName = event.name; hasVersion |= "version".equals(tagName); hasRelativePath |= "relativePath".equals(tagName); - } else if (event.event == TEXT) { + } else if (event.event == CHARACTERS) { if (S_FILTER.matcher(event.text).matches()) { if (whitespaceAfterParentStart.isEmpty()) { whitespaceAfterParentStart = event.text; @@ -89,7 +90,7 @@ protected void process(List buffer) { } else if ("version".equals(tagName)) { version = nullSafeAppend(version, event.text); } - } else if (event.event == END_TAG && "parent".equals(event.name)) { + } else if (event.event == END_ELEMENT && "parent".equals(event.name)) { Optional resolvedParent; if (!hasVersion && (!hasRelativePath || relativePath != null)) { Path relPath = Paths.get(Objects.toString(relativePath, "../pom.xml")); @@ -98,23 +99,23 @@ protected void process(List buffer) { resolvedParent = Optional.empty(); } if (!hasVersion && resolvedParent.isPresent()) { - int pos = buffer.get(i - 1).event == TEXT ? i - 1 : i; + int pos = buffer.get(i - 1).event == CHARACTERS ? i - 1 : i; Event e = new Event(); - e.event = TEXT; + e.event = CHARACTERS; e.text = whitespaceAfterParentStart; buffer.add(pos++, e); e = new Event(); - e.event = START_TAG; + e.event = START_ELEMENT; e.namespace = buffer.get(0).namespace; e.prefix = buffer.get(0).prefix; e.name = "version"; buffer.add(pos++, e); e = new Event(); - e.event = TEXT; + e.event = CHARACTERS; e.text = resolvedParent.get().getVersion(); buffer.add(pos++, e); e = new Event(); - e.event = END_TAG; + e.event = END_ELEMENT; e.name = "version"; e.namespace = buffer.get(0).namespace; e.prefix = buffer.get(0).prefix; diff --git a/maven-model-transform/src/main/java/org/apache/maven/model/transform/RawToConsumerPomXMLFilterFactory.java b/maven-model-transform/src/main/java/org/apache/maven/model/transform/RawToConsumerPomXMLFilterFactory.java index 617d7d91f0..9b10654acd 100644 --- a/maven-model-transform/src/main/java/org/apache/maven/model/transform/RawToConsumerPomXMLFilterFactory.java +++ b/maven-model-transform/src/main/java/org/apache/maven/model/transform/RawToConsumerPomXMLFilterFactory.java @@ -18,9 +18,9 @@ */ package org.apache.maven.model.transform; -import java.nio.file.Path; +import javax.xml.stream.XMLStreamReader; -import org.codehaus.plexus.util.xml.pull.XmlPullParser; +import java.nio.file.Path; /** * @author Guillaume Nodet @@ -34,9 +34,9 @@ public RawToConsumerPomXMLFilterFactory(BuildToRawPomXMLFilterFactory buildPomXM this.buildPomXMLFilterFactory = buildPomXMLFilterFactory; } - public final XmlPullParser get(XmlPullParser orgParser, Path projectPath) { + public final XMLStreamReader get(XMLStreamReader orgParser, Path projectPath) { // Ensure that xs:any elements aren't touched by next filters - XmlPullParser parser = orgParser instanceof FastForwardFilter ? orgParser : new FastForwardFilter(orgParser); + XMLStreamReader parser = orgParser instanceof FastForwardFilter ? orgParser : new FastForwardFilter(orgParser); parser = buildPomXMLFilterFactory.get(parser, projectPath); diff --git a/maven-model-transform/src/main/java/org/apache/maven/model/transform/ReactorDependencyXMLFilter.java b/maven-model-transform/src/main/java/org/apache/maven/model/transform/ReactorDependencyXMLFilter.java index 186383f1c2..269b921788 100644 --- a/maven-model-transform/src/main/java/org/apache/maven/model/transform/ReactorDependencyXMLFilter.java +++ b/maven-model-transform/src/main/java/org/apache/maven/model/transform/ReactorDependencyXMLFilter.java @@ -18,12 +18,13 @@ */ package org.apache.maven.model.transform; +import javax.xml.stream.XMLStreamReader; + import java.util.List; import java.util.function.BiFunction; import java.util.regex.Pattern; -import org.apache.maven.model.transform.pull.NodeBufferingParser; -import org.codehaus.plexus.util.xml.pull.XmlPullParser; +import org.apache.maven.model.transform.stax.NodeBufferingParser; /** * Will apply the version if the dependency is part of the reactor @@ -38,8 +39,8 @@ public class ReactorDependencyXMLFilter extends NodeBufferingParser { private static final Pattern S_FILTER = Pattern.compile("\\s+"); public ReactorDependencyXMLFilter( - XmlPullParser xmlPullParser, BiFunction reactorVersionMapper) { - super(xmlPullParser, "dependency"); + XMLStreamReader delegate, BiFunction reactorVersionMapper) { + super(delegate, "dependency"); this.reactorVersionMapper = reactorVersionMapper; } @@ -52,10 +53,10 @@ protected void process(List buffer) { String tagName = null; for (int i = 0; i < buffer.size(); i++) { Event event = buffer.get(i); - if (event.event == START_TAG) { + if (event.event == START_ELEMENT) { tagName = event.name; hasVersion |= "version".equals(tagName); - } else if (event.event == TEXT) { + } else if (event.event == CHARACTERS) { if (S_FILTER.matcher(event.text).matches()) { if (dependencyWhitespace.isEmpty()) { dependencyWhitespace = event.text; @@ -65,26 +66,26 @@ protected void process(List buffer) { } else if ("artifactId".equals(tagName)) { artifactId = nullSafeAppend(artifactId, event.text); } - } else if (event.event == END_TAG && "dependency".equals(event.name)) { + } else if (event.event == END_ELEMENT && "dependency".equals(event.name)) { String version = reactorVersionMapper.apply(groupId, artifactId); if (!hasVersion && version != null) { - int pos = buffer.get(i - 1).event == TEXT ? i - 1 : i; + int pos = buffer.get(i - 1).event == CHARACTERS ? i - 1 : i; Event e = new Event(); - e.event = TEXT; + e.event = CHARACTERS; e.text = dependencyWhitespace; buffer.add(pos++, e); e = new Event(); - e.event = START_TAG; + e.event = START_ELEMENT; e.namespace = buffer.get(0).namespace; e.prefix = buffer.get(0).prefix; e.name = "version"; buffer.add(pos++, e); e = new Event(); - e.event = TEXT; + e.event = CHARACTERS; e.text = version; buffer.add(pos++, e); e = new Event(); - e.event = END_TAG; + e.event = END_ELEMENT; e.name = "version"; e.namespace = buffer.get(0).namespace; e.prefix = buffer.get(0).prefix; diff --git a/maven-model-transform/src/main/java/org/apache/maven/model/transform/RelativePathXMLFilter.java b/maven-model-transform/src/main/java/org/apache/maven/model/transform/RelativePathXMLFilter.java index f785ab3498..b40d7d2bce 100644 --- a/maven-model-transform/src/main/java/org/apache/maven/model/transform/RelativePathXMLFilter.java +++ b/maven-model-transform/src/main/java/org/apache/maven/model/transform/RelativePathXMLFilter.java @@ -18,11 +18,12 @@ */ package org.apache.maven.model.transform; +import javax.xml.stream.XMLStreamReader; + import java.util.List; import java.util.regex.Pattern; -import org.apache.maven.model.transform.pull.NodeBufferingParser; -import org.codehaus.plexus.util.xml.pull.XmlPullParser; +import org.apache.maven.model.transform.stax.NodeBufferingParser; /** * Remove relativePath element, has no value for consumer pom @@ -35,23 +36,23 @@ public class RelativePathXMLFilter extends NodeBufferingParser { private static final Pattern S_FILTER = Pattern.compile("\\s+"); - public RelativePathXMLFilter(XmlPullParser xmlPullParser) { - super(xmlPullParser, "parent"); + public RelativePathXMLFilter(XMLStreamReader delegate) { + super(delegate, "parent"); } protected void process(List buffer) { boolean skip = false; Event prev = null; for (Event event : buffer) { - if (event.event == START_TAG && "relativePath".equals(event.name)) { + if (event.event == START_ELEMENT && "relativePath".equals(event.name)) { skip = true; if (prev != null - && prev.event == TEXT + && prev.event == CHARACTERS && S_FILTER.matcher(prev.text).matches()) { prev = null; } event = null; - } else if (event.event == END_TAG && "relativePath".equals(event.name)) { + } else if (event.event == END_ELEMENT && "relativePath".equals(event.name)) { skip = false; event = null; } else if (skip) { diff --git a/maven-model-transform/src/main/java/org/apache/maven/model/transform/RootXMLFilter.java b/maven-model-transform/src/main/java/org/apache/maven/model/transform/RootXMLFilter.java index af40c5c54d..d506ff23b9 100644 --- a/maven-model-transform/src/main/java/org/apache/maven/model/transform/RootXMLFilter.java +++ b/maven-model-transform/src/main/java/org/apache/maven/model/transform/RootXMLFilter.java @@ -18,12 +18,14 @@ */ package org.apache.maven.model.transform; -import java.io.IOException; +import javax.xml.stream.XMLStreamException; +import javax.xml.stream.XMLStreamReader; + +import java.util.ArrayDeque; +import java.util.Deque; import java.util.stream.Stream; -import org.apache.maven.model.transform.pull.BufferingParser; -import org.codehaus.plexus.util.xml.pull.XmlPullParser; -import org.codehaus.plexus.util.xml.pull.XmlPullParserException; +import org.apache.maven.model.transform.stax.BufferingParser; /** * Remove the root attribute on the model @@ -32,14 +34,18 @@ * @since 4.0.0 */ class RootXMLFilter extends BufferingParser { - RootXMLFilter(XmlPullParser xmlPullParser) { - super(xmlPullParser); + + final Deque elements = new ArrayDeque<>(); + + RootXMLFilter(XMLStreamReader delegate) { + super(delegate); } @Override - protected boolean accept() throws XmlPullParserException, IOException { - if (xmlPullParser.getEventType() == XmlPullParser.START_TAG) { - if (xmlPullParser.getDepth() == 1 && "project".equals(xmlPullParser.getName())) { + protected boolean accept() throws XMLStreamException { + if (delegate.getEventType() == START_ELEMENT) { + elements.push(delegate.getLocalName()); + if (elements.size() == 1 && "project".equals(delegate.getLocalName())) { Event event = bufferEvent(); event.attributes = Stream.of(event.attributes) .filter(a -> !"root".equals(a.name)) @@ -47,6 +53,8 @@ protected boolean accept() throws XmlPullParserException, IOException { pushEvent(event); return false; } + } else if (delegate.getEventType() == END_ELEMENT) { + elements.pop(); } return true; } diff --git a/maven-model-transform/src/main/java/org/apache/maven/model/transform/pull/BufferingParser.java b/maven-model-transform/src/main/java/org/apache/maven/model/transform/pull/BufferingParser.java deleted file mode 100644 index b283a39319..0000000000 --- a/maven-model-transform/src/main/java/org/apache/maven/model/transform/pull/BufferingParser.java +++ /dev/null @@ -1,509 +0,0 @@ -/* - * 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. - */ -package org.apache.maven.model.transform.pull; - -import java.io.IOException; -import java.io.InputStream; -import java.io.Reader; -import java.util.ArrayDeque; -import java.util.Arrays; -import java.util.Deque; -import java.util.Objects; -import java.util.regex.Pattern; - -import org.codehaus.plexus.util.xml.pull.XmlPullParser; -import org.codehaus.plexus.util.xml.pull.XmlPullParserException; - -/** - * An xml pull parser filter base implementation. - * - * @author Guillaume Nodet - * @since 4.0.0 - */ -public class BufferingParser implements XmlPullParser { - - private static final Pattern WHITESPACE_REGEX = Pattern.compile("[ \r\t\n]+"); - - protected XmlPullParser xmlPullParser; - protected Deque events; - protected Event current; - protected boolean bypass; - - @SuppressWarnings("checkstyle:VisibilityModifier") - public static class Event { - public int event; - public String name; - public String prefix; - public String namespace; - public boolean empty; - public String text; - public Attribute[] attributes; - public Namespace[] namespaces; - public int columnNumber; - public int lineNumber; - - public String positionDescription() { - return " " + TYPES[event] + " @" + lineNumber + ":" + columnNumber; - } - - @Override - public String toString() { - switch (event) { - case START_DOCUMENT: - case END_DOCUMENT: - return "Event{event=" + TYPES[event] + "'}"; - case PROCESSING_INSTRUCTION: - case TEXT: - case CDSECT: - case ENTITY_REF: - case COMMENT: - case IGNORABLE_WHITESPACE: - return "Event{event=" + TYPES[event] + ", text='" + text + "'}"; - case START_TAG: - return "Event{" + "event=START_TAG" - + ", name='" - + name + '\'' + ", prefix='" - + prefix + '\'' + ", namespace='" - + namespace + '\'' + ", empty=" - + empty + ", attributes=" - + Arrays.toString(attributes) + ", namespaces=" - + Arrays.toString(namespaces) + '}'; - case END_TAG: - return "Event{" + "event=END_TAG" - + ", name='" - + name + '\'' + ", prefix='" - + prefix + '\'' + ", namespace='" - + namespace + '\'' + ", empty=" - + empty + ", namespaces=" - + Arrays.toString(namespaces) + '}'; - default: - return "Event{" + "event=" - + TYPES[event] + ", name='" - + name + '\'' + ", prefix='" - + prefix + '\'' + ", namespace='" - + namespace + '\'' + ", empty=" - + empty + ", text='" - + text + '\'' + ", attributes=" - + Arrays.toString(attributes) + ", namespaces=" - + Arrays.toString(namespaces) + '}'; - } - } - } - - @SuppressWarnings("checkstyle:VisibilityModifier") - public static class Namespace { - public String prefix; - public String uri; - } - - @SuppressWarnings("checkstyle:VisibilityModifier") - public static class Attribute { - public String name; - public String prefix; - public String namespace; - public String type; - public String value; - public boolean isDefault; - } - - public BufferingParser(XmlPullParser xmlPullParser) { - this.xmlPullParser = xmlPullParser; - } - - @Override - public void setFeature(String name, boolean state) throws XmlPullParserException { - xmlPullParser.setFeature(name, state); - } - - @Override - public boolean getFeature(String name) { - return xmlPullParser.getFeature(name); - } - - @Override - public void setProperty(String name, Object value) throws XmlPullParserException { - xmlPullParser.setProperty(name, value); - } - - @Override - public Object getProperty(String name) { - return xmlPullParser.getProperty(name); - } - - @Override - public void setInput(Reader in) throws XmlPullParserException { - xmlPullParser.setInput(in); - } - - @Override - public void setInput(InputStream inputStream, String inputEncoding) throws XmlPullParserException { - xmlPullParser.setInput(inputStream, inputEncoding); - } - - @Override - public String getInputEncoding() { - return xmlPullParser.getInputEncoding(); - } - - @Override - public void defineEntityReplacementText(String entityName, String replacementText) throws XmlPullParserException { - xmlPullParser.defineEntityReplacementText(entityName, replacementText); - } - - @Override - public int getNamespaceCount(int depth) throws XmlPullParserException { - // TODO: if (current != null) throw new IllegalStateException("Not supported during events replay"); - return xmlPullParser.getNamespaceCount(depth); - } - - @Override - public String getNamespacePrefix(int pos) throws XmlPullParserException { - // TODO: if (current != null) throw new IllegalStateException("Not supported during events replay"); - return xmlPullParser.getNamespacePrefix(pos); - } - - @Override - public String getNamespaceUri(int pos) throws XmlPullParserException { - // TODO: if (current != null) throw new IllegalStateException("Not supported during events replay"); - return xmlPullParser.getNamespaceUri(pos); - } - - @Override - public String getNamespace(String prefix) { - // TODO: if (current != null) throw new IllegalStateException("Not supported during events replay"); - return xmlPullParser.getNamespace(prefix); - } - - @Override - public int getDepth() { - // TODO: if (current != null) throw new IllegalStateException("Not supported during events replay"); - return xmlPullParser.getDepth(); - } - - @Override - public String getPositionDescription() { - if (current != null) { - return current.positionDescription(); - } - return xmlPullParser.getPositionDescription(); - } - - @Override - public int getLineNumber() { - if (current != null) { - return current.lineNumber; - } - return xmlPullParser.getLineNumber(); - } - - @Override - public int getColumnNumber() { - if (current != null) { - return current.columnNumber; - } - return xmlPullParser.getColumnNumber(); - } - - @Override - public boolean isWhitespace() throws XmlPullParserException { - if (current != null) { - if (current.event == TEXT || current.event == CDSECT) { - return WHITESPACE_REGEX.matcher(current.text).matches(); - } else if (current.event == IGNORABLE_WHITESPACE) { - return true; - } else { - throw new XmlPullParserException("no content available to check for whitespaces"); - } - } - return xmlPullParser.isWhitespace(); - } - - @Override - public String getText() { - return current != null ? current.text : xmlPullParser.getText(); - } - - @Override - public char[] getTextCharacters(int[] holderForStartAndLength) { - if (current != null) { - throw new IllegalStateException("Not supported during events replay"); - } - return xmlPullParser.getTextCharacters(holderForStartAndLength); - } - - @Override - public String getNamespace() { - return current != null ? current.namespace : xmlPullParser.getNamespace(); - } - - @Override - public String getName() { - return current != null ? current.name : xmlPullParser.getName(); - } - - @Override - public String getPrefix() { - return current != null ? current.prefix : xmlPullParser.getPrefix(); - } - - @Override - public boolean isEmptyElementTag() throws XmlPullParserException { - return current != null ? current.empty : xmlPullParser.isEmptyElementTag(); - } - - @Override - public int getAttributeCount() { - if (current != null) { - return current.attributes != null ? current.attributes.length : 0; - } else { - return xmlPullParser.getAttributeCount(); - } - } - - @Override - public String getAttributeNamespace(int index) { - if (current != null) { - return current.attributes[index].namespace; - } else { - return xmlPullParser.getAttributeNamespace(index); - } - } - - @Override - public String getAttributeName(int index) { - if (current != null) { - return current.attributes[index].name; - } else { - return xmlPullParser.getAttributeName(index); - } - } - - @Override - public String getAttributePrefix(int index) { - if (current != null) { - return current.attributes[index].prefix; - } else { - return xmlPullParser.getAttributePrefix(index); - } - } - - @Override - public String getAttributeType(int index) { - if (current != null) { - return current.attributes[index].type; - } else { - return xmlPullParser.getAttributeType(index); - } - } - - @Override - public boolean isAttributeDefault(int index) { - if (current != null) { - return current.attributes[index].isDefault; - } else { - return xmlPullParser.isAttributeDefault(index); - } - } - - @Override - public String getAttributeValue(int index) { - if (current != null) { - return current.attributes[index].value; - } else { - return xmlPullParser.getAttributeValue(index); - } - } - - @Override - public String getAttributeValue(String namespace, String name) { - if (current != null) { - if (current.attributes != null) { - for (Attribute attr : current.attributes) { - if (Objects.equals(namespace, attr.namespace) && Objects.equals(name, attr.name)) { - return attr.value; - } - } - } - return null; - } else { - return xmlPullParser.getAttributeValue(namespace, name); - } - } - - @Override - public void require(int type, String namespace, String name) throws XmlPullParserException, IOException { - if (current != null) { - throw new IllegalStateException("Not supported during events replay"); - } - xmlPullParser.require(type, namespace, name); - } - - @Override - public int getEventType() throws XmlPullParserException { - return current != null ? current.event : xmlPullParser.getEventType(); - } - - @Override - public int next() throws XmlPullParserException, IOException { - while (true) { - if (events != null && !events.isEmpty()) { - current = events.removeFirst(); - return current.event; - } else { - current = null; - } - if (getEventType() == END_DOCUMENT) { - throw new XmlPullParserException("already reached end of XML input", this, null); - } - int currentEvent = xmlPullParser.next(); - if (bypass() || accept()) { - return currentEvent; - } - } - } - - @Override - public int nextToken() throws XmlPullParserException, IOException { - while (true) { - if (events != null && !events.isEmpty()) { - current = events.removeFirst(); - return current.event; - } else { - current = null; - } - if (getEventType() == END_DOCUMENT) { - throw new XmlPullParserException("already reached end of XML input", this, null); - } - int currentEvent = xmlPullParser.nextToken(); - if (bypass() || accept()) { - return currentEvent; - } - } - } - - @Override - public int nextTag() throws XmlPullParserException, IOException { - int eventType = next(); - if (eventType == TEXT && isWhitespace()) { // skip whitespace - eventType = next(); - } - if (eventType != START_TAG && eventType != END_TAG) { - throw new XmlPullParserException("expected START_TAG or END_TAG not " + TYPES[getEventType()], this, null); - } - return eventType; - } - - @Override - public String nextText() throws XmlPullParserException, IOException { - int eventType = getEventType(); - if (eventType != START_TAG) { - throw new XmlPullParserException("parser must be on START_TAG to read next text", this, null); - } - eventType = next(); - if (eventType == TEXT) { - final String result = getText(); - eventType = next(); - if (eventType != END_TAG) { - throw new XmlPullParserException( - "TEXT must be immediately followed by END_TAG and not " + TYPES[getEventType()], this, null); - } - return result; - } else if (eventType == END_TAG) { - return ""; - } else { - throw new XmlPullParserException("parser must be on START_TAG or TEXT to read text", this, null); - } - } - - protected Event bufferEvent() throws XmlPullParserException { - Event event = new Event(); - XmlPullParser pp = xmlPullParser; - event.event = xmlPullParser.getEventType(); - event.columnNumber = xmlPullParser.getColumnNumber(); - event.lineNumber = xmlPullParser.getLineNumber(); - switch (event.event) { - case START_DOCUMENT: - case END_DOCUMENT: - break; - case START_TAG: - event.name = pp.getName(); - event.namespace = pp.getNamespace(); - event.prefix = pp.getPrefix(); - event.empty = pp.isEmptyElementTag(); - event.text = pp.getText(); - event.attributes = new Attribute[pp.getAttributeCount()]; - for (int i = 0; i < pp.getAttributeCount(); i++) { - Attribute attr = new Attribute(); - attr.name = pp.getAttributeName(i); - attr.namespace = pp.getAttributeNamespace(i); - attr.value = pp.getAttributeValue(i); - attr.type = pp.getAttributeType(i); - attr.isDefault = pp.isAttributeDefault(i); - event.attributes[i] = attr; - } - break; - case END_TAG: - event.name = pp.getName(); - event.namespace = pp.getNamespace(); - event.prefix = pp.getPrefix(); - event.text = pp.getText(); - break; - case TEXT: - case COMMENT: - case IGNORABLE_WHITESPACE: - case CDSECT: - case ENTITY_REF: - event.text = pp.getText(); - break; - default: - break; - } - return event; - } - - protected void pushEvent(Event event) { - if (events == null) { - events = new ArrayDeque<>(); - } - events.add(event); - } - - protected boolean accept() throws XmlPullParserException, IOException { - return true; - } - - public void bypass(boolean bypass) { - if (bypass && events != null && !events.isEmpty()) { - throw new IllegalStateException("Can not disable filter while processing"); - } - this.bypass = bypass; - } - - public boolean bypass() { - return bypass || (xmlPullParser instanceof BufferingParser && ((BufferingParser) xmlPullParser).bypass()); - } - - protected static String nullSafeAppend(String originalValue, String charSegment) { - if (originalValue == null) { - return charSegment; - } else { - return originalValue + charSegment; - } - } -} diff --git a/maven-model-transform/src/main/java/org/apache/maven/model/transform/pull/XmlUtils.java b/maven-model-transform/src/main/java/org/apache/maven/model/transform/pull/XmlUtils.java deleted file mode 100644 index a2f71aa55a..0000000000 --- a/maven-model-transform/src/main/java/org/apache/maven/model/transform/pull/XmlUtils.java +++ /dev/null @@ -1,118 +0,0 @@ -/* - * 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. - */ -package org.apache.maven.model.transform.pull; - -import java.io.ByteArrayInputStream; -import java.io.ByteArrayOutputStream; -import java.io.IOException; -import java.io.OutputStreamWriter; -import java.io.UnsupportedEncodingException; -import java.io.Writer; - -import org.codehaus.plexus.util.xml.XmlStreamReader; -import org.codehaus.plexus.util.xml.pull.MXSerializer; -import org.codehaus.plexus.util.xml.pull.XmlPullParser; -import org.codehaus.plexus.util.xml.pull.XmlPullParserException; -import org.codehaus.plexus.util.xml.pull.XmlSerializer; - -public class XmlUtils { - - public static ByteArrayInputStream writeDocument(XmlStreamReader reader, XmlPullParser parser) - throws IOException, XmlPullParserException { - ByteArrayOutputStream baos = new ByteArrayOutputStream(); - Writer writer = newWriter(reader, baos); - writeDocument(parser, writer); - return new ByteArrayInputStream(baos.toByteArray()); - } - - public static void writeDocument(XmlPullParser parser, Writer writer) throws IOException, XmlPullParserException { - XmlSerializer serializer = new MXSerializer(); - serializer.setOutput(writer); - - while (parser.nextToken() != XmlPullParser.END_DOCUMENT) { - switch (parser.getEventType()) { - case XmlPullParser.START_DOCUMENT: - serializer.startDocument(parser.getInputEncoding(), true); - break; - case XmlPullParser.END_DOCUMENT: - serializer.endDocument(); - case XmlPullParser.START_TAG: - int nsStart = parser.getNamespaceCount(parser.getDepth() - 1); - int nsEnd = parser.getNamespaceCount(parser.getDepth()); - for (int i = nsStart; i < nsEnd; i++) { - String prefix = parser.getNamespacePrefix(i); - String ns = parser.getNamespaceUri(i); - serializer.setPrefix(prefix, ns); - } - serializer.startTag(parser.getNamespace(), parser.getName()); - for (int i = 0; i < parser.getAttributeCount(); i++) { - serializer.attribute( - parser.getAttributeNamespace(i), - parser.getAttributeName(i), - parser.getAttributeValue(i)); - } - break; - case XmlPullParser.END_TAG: - serializer.endTag(parser.getNamespace(), parser.getName()); - break; - case XmlPullParser.TEXT: - serializer.text(normalize(parser.getText())); - break; - case XmlPullParser.CDSECT: - serializer.cdsect(parser.getText()); - break; - case XmlPullParser.ENTITY_REF: - serializer.entityRef(parser.getName()); - break; - case XmlPullParser.IGNORABLE_WHITESPACE: - serializer.ignorableWhitespace(normalize(parser.getText())); - break; - case XmlPullParser.PROCESSING_INSTRUCTION: - serializer.processingInstruction(parser.getText()); - break; - case XmlPullParser.COMMENT: - serializer.comment(normalize(parser.getText())); - break; - case XmlPullParser.DOCDECL: - serializer.docdecl(normalize(parser.getText())); - break; - default: - break; - } - } - - serializer.endDocument(); - } - - private static OutputStreamWriter newWriter(XmlStreamReader reader, ByteArrayOutputStream baos) - throws UnsupportedEncodingException { - if (reader.getEncoding() != null) { - return new OutputStreamWriter(baos, reader.getEncoding()); - } else { - return new OutputStreamWriter(baos); - } - } - - private static String normalize(String input) { - if (input.indexOf('\n') >= 0 && !"\n".equals(System.lineSeparator())) { - return input.replace("\n", System.lineSeparator()); - } - return input; - } -} diff --git a/maven-model-transform/src/main/java/org/apache/maven/model/transform/stax/BufferingParser.java b/maven-model-transform/src/main/java/org/apache/maven/model/transform/stax/BufferingParser.java new file mode 100644 index 0000000000..a83458f66d --- /dev/null +++ b/maven-model-transform/src/main/java/org/apache/maven/model/transform/stax/BufferingParser.java @@ -0,0 +1,523 @@ +/* + * 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. + */ +package org.apache.maven.model.transform.stax; + +import javax.xml.namespace.NamespaceContext; +import javax.xml.namespace.QName; +import javax.xml.stream.Location; +import javax.xml.stream.XMLStreamException; +import javax.xml.stream.XMLStreamReader; + +import java.util.ArrayDeque; +import java.util.Arrays; +import java.util.Deque; +import java.util.Objects; +import java.util.regex.Pattern; + +import org.codehaus.stax2.XMLStreamReader2; + +public class BufferingParser implements XMLStreamReader { + + private static final Pattern WHITESPACE_REGEX = Pattern.compile("[ \r\t\n]+"); + + private static final String[] TYPES = new String[] { + "", + "START_ELEMENT", + "END_ELEMENT", + "PROCESSING_INSTRUCTION", + "CHARACTERS", + "COMMENT", + "SPACE", + "START_DOCUMENT", + "END_DOCUMENT", + "ENTITY_REFERENCE", + "ATTRIBUTE", + "DTD", + "CDATA", + "NAMESPACE", + "NOTATION_DECLARATION", + "ENTITY_DECLARATION" + }; + + protected XMLStreamReader delegate; + protected Deque events; + protected Event current; + protected boolean bypass; + + @SuppressWarnings("checkstyle:VisibilityModifier") + public static class Event { + public int event; + public String name; + public String prefix; + public String namespace; + public boolean empty; + public String text; + public Attribute[] attributes; + public Namespace[] namespaces; + public int columnNumber; + public int lineNumber; + + public String positionDescription() { + return " " + TYPES[event] + " @" + lineNumber + ":" + columnNumber; + } + + @Override + public String toString() { + switch (event) { + case START_DOCUMENT: + case END_DOCUMENT: + return "Event{event=" + TYPES[event] + "'}"; + case PROCESSING_INSTRUCTION: + case CHARACTERS: + case CDATA: + case ENTITY_REFERENCE: + case COMMENT: + case SPACE: + return "Event{event=" + TYPES[event] + ", text='" + text + "'}"; + case START_ELEMENT: + return "Event{" + "event=START_TAG" + + ", name='" + + name + '\'' + ", prefix='" + + prefix + '\'' + ", namespace='" + + namespace + '\'' + ", empty=" + + empty + ", attributes=" + + Arrays.toString(attributes) + ", namespaces=" + + Arrays.toString(namespaces) + '}'; + case END_ELEMENT: + return "Event{" + "event=END_TAG" + + ", name='" + + name + '\'' + ", prefix='" + + prefix + '\'' + ", namespace='" + + namespace + '\'' + ", empty=" + + empty + ", namespaces=" + + Arrays.toString(namespaces) + '}'; + default: + return "Event{" + "event=" + + TYPES[event] + ", name='" + + name + '\'' + ", prefix='" + + prefix + '\'' + ", namespace='" + + namespace + '\'' + ", empty=" + + empty + ", text='" + + text + '\'' + ", attributes=" + + Arrays.toString(attributes) + ", namespaces=" + + Arrays.toString(namespaces) + '}'; + } + } + } + + @SuppressWarnings("checkstyle:VisibilityModifier") + public static class Namespace { + public String prefix; + public String uri; + } + + @SuppressWarnings("checkstyle:VisibilityModifier") + public static class Attribute { + public String name; + public String prefix; + public String namespace; + public String type; + public String value; + } + + public BufferingParser(XMLStreamReader delegate) { + this.delegate = delegate; + } + + @Override + public Object getProperty(String name) throws IllegalArgumentException { + return delegate.getProperty(name); + } + + @Override + public String getElementText() throws XMLStreamException { + return delegate.getElementText(); + } + + @Override + public boolean hasNext() throws XMLStreamException { + return delegate.hasNext(); + } + + @Override + public void close() throws XMLStreamException { + delegate.close(); + } + + @Override + public String getNamespaceURI(String prefix) { + return delegate.getNamespaceURI(prefix); + } + + @Override + public boolean isStartElement() { + return delegate.isStartElement(); + } + + @Override + public boolean isEndElement() { + return delegate.isEndElement(); + } + + @Override + public boolean isCharacters() { + return delegate.isCharacters(); + } + + @Override + public boolean isWhiteSpace() { + return delegate.isWhiteSpace(); + } + + @Override + public QName getAttributeName(int index) { + return delegate.getAttributeName(index); + } + + @Override + public boolean isAttributeSpecified(int index) { + return delegate.isAttributeSpecified(index); + } + + @Override + public int getNamespaceCount() { + return current != null + ? current.namespaces != null ? current.namespaces.length : 0 + : delegate.getNamespaceCount(); + } + + @Override + public String getNamespacePrefix(int index) { + return current != null ? current.namespaces[index].prefix : delegate.getNamespacePrefix(index); + } + + @Override + public String getNamespaceURI(int index) { + return current != null ? current.namespaces[index].uri : delegate.getNamespaceURI(index); + } + + @Override + public NamespaceContext getNamespaceContext() { + return delegate.getNamespaceContext(); + } + + @Override + public char[] getTextCharacters() { + return delegate.getTextCharacters(); + } + + @Override + public int getTextCharacters(int sourceStart, char[] target, int targetStart, int length) + throws XMLStreamException { + return delegate.getTextCharacters(sourceStart, target, targetStart, length); + } + + @Override + public int getTextStart() { + return delegate.getTextStart(); + } + + @Override + public int getTextLength() { + return delegate.getTextLength(); + } + + @Override + public String getEncoding() { + return delegate.getEncoding(); + } + + @Override + public boolean hasText() { + return delegate.hasText(); + } + + @Override + public Location getLocation() { + return delegate.getLocation(); + } + + @Override + public QName getName() { + return delegate.getName(); + } + + @Override + public boolean hasName() { + return delegate.hasName(); + } + + @Override + public String getVersion() { + return delegate.getVersion(); + } + + @Override + public boolean isStandalone() { + return delegate.isStandalone(); + } + + @Override + public boolean standaloneSet() { + return delegate.standaloneSet(); + } + + @Override + public String getCharacterEncodingScheme() { + return delegate.getCharacterEncodingScheme(); + } + + @Override + public String getPITarget() { + return delegate.getPITarget(); + } + + @Override + public String getPIData() { + return delegate.getPIData(); + } + + @Override + public String getText() { + return current != null ? current.text : delegate.getText(); + } + + @Override + public String getNamespaceURI() { + return current != null ? current.namespace : delegate.getNamespaceURI(); + } + + @Override + public String getLocalName() { + return current != null ? current.name : delegate.getLocalName(); + } + + @Override + public String getPrefix() { + return current != null ? current.prefix : delegate.getPrefix(); + } + + @Override + public int getAttributeCount() { + if (current != null) { + return current.attributes != null ? current.attributes.length : 0; + } else { + return delegate.getAttributeCount(); + } + } + + @Override + public String getAttributeNamespace(int index) { + if (current != null) { + return current.attributes[index].namespace; + } else { + return delegate.getAttributeNamespace(index); + } + } + + @Override + public String getAttributeLocalName(int index) { + if (current != null) { + return current.attributes[index].name; + } else { + return delegate.getAttributeLocalName(index); + } + } + + @Override + public String getAttributePrefix(int index) { + if (current != null) { + return current.attributes[index].prefix; + } else { + return delegate.getAttributePrefix(index); + } + } + + @Override + public String getAttributeType(int index) { + if (current != null) { + return current.attributes[index].type; + } else { + return delegate.getAttributeType(index); + } + } + + @Override + public String getAttributeValue(int index) { + if (current != null) { + return current.attributes[index].value; + } else { + return delegate.getAttributeValue(index); + } + } + + @Override + public String getAttributeValue(String namespace, String name) { + if (current != null) { + if (current.attributes != null) { + for (Attribute attr : current.attributes) { + if (Objects.equals(namespace, attr.namespace) && Objects.equals(name, attr.name)) { + return attr.value; + } + } + } + return null; + } else { + return delegate.getAttributeValue(namespace, name); + } + } + + @Override + public void require(int type, String namespace, String name) throws XMLStreamException { + if (current != null) { + throw new IllegalStateException("Not supported during events replay"); + } + delegate.require(type, namespace, name); + } + + @Override + public int getEventType() { + return current != null ? current.event : delegate.getEventType(); + } + + @Override + public int next() throws XMLStreamException { + while (true) { + if (events != null && !events.isEmpty()) { + current = events.removeFirst(); + return current.event; + } else { + current = null; + } + if (getEventType() == END_DOCUMENT) { + throw new XMLStreamException("already reached end of XML input", getLocation(), null); + } + int currentEvent = delegate.next(); + if (bypass() || accept()) { + return currentEvent; + } + } + } + + @Override + public int nextTag() throws XMLStreamException { + int eventType = next(); + while (eventType == CHARACTERS && isWhitespace() // skip whitespace + || eventType == COMMENT) { // skip comments + eventType = next(); + } + if (eventType != START_ELEMENT && eventType != END_ELEMENT) { + throw new XMLStreamException( + "expected START_TAG or END_TAG not " + TYPES[getEventType()], getLocation(), null); + } + return eventType; + } + + public boolean isWhitespace() throws XMLStreamException { + if (getEventType() == CHARACTERS || getEventType() == CDATA) { + return WHITESPACE_REGEX.matcher(getText()).matches(); + } else if (getEventType() == SPACE) { + return true; + } else { + throw new XMLStreamException("no content available to check for whitespaces"); + } + } + + protected Event bufferEvent() throws XMLStreamException { + Event event = new Event(); + XMLStreamReader pp = delegate; + event.event = delegate.getEventType(); + event.columnNumber = delegate.getLocation().getColumnNumber(); + event.lineNumber = delegate.getLocation().getLineNumber(); + switch (event.event) { + case START_DOCUMENT: + case END_DOCUMENT: + break; + case START_ELEMENT: + event.name = pp.getLocalName(); + event.namespace = pp.getNamespaceURI(); + event.prefix = pp.getPrefix(); + event.empty = (pp instanceof XMLStreamReader2) && ((XMLStreamReader2) pp).isEmptyElement(); + // event.text = pp.getText(); + event.attributes = new Attribute[pp.getAttributeCount()]; + for (int i = 0; i < pp.getAttributeCount(); i++) { + Attribute attr = new Attribute(); + attr.name = pp.getAttributeLocalName(i); + attr.namespace = pp.getAttributeNamespace(i); + attr.value = pp.getAttributeValue(i); + attr.type = pp.getAttributeType(i); + event.attributes[i] = attr; + } + event.namespaces = new Namespace[pp.getNamespaceCount()]; + for (int i = 0; i < pp.getNamespaceCount(); i++) { + Namespace ns = new Namespace(); + ns.uri = pp.getNamespaceURI(i); + ns.prefix = pp.getNamespacePrefix(i); + event.namespaces[i] = ns; + } + break; + case END_ELEMENT: + event.name = pp.getLocalName(); + event.namespace = pp.getNamespaceURI(); + event.prefix = pp.getPrefix(); + // event.text = pp.getText(); + break; + case CHARACTERS: + case COMMENT: + case SPACE: + case CDATA: + case ENTITY_REFERENCE: + event.text = pp.getText(); + break; + default: + break; + } + return event; + } + + protected void pushEvent(Event event) { + if (events == null) { + events = new ArrayDeque<>(); + } + events.add(event); + } + + protected boolean accept() throws XMLStreamException { + return true; + } + + public void bypass(boolean bypass) { + if (bypass && events != null && !events.isEmpty()) { + throw new IllegalStateException("Can not disable filter while processing"); + } + this.bypass = bypass; + } + + public boolean bypass() { + return bypass || (delegate instanceof BufferingParser && ((BufferingParser) delegate).bypass()); + } + + protected static String nullSafeAppend(String originalValue, String charSegment) { + if (originalValue == null) { + return charSegment; + } else { + return originalValue + charSegment; + } + } +} diff --git a/maven-model-transform/src/main/java/org/apache/maven/model/transform/pull/NodeBufferingParser.java b/maven-model-transform/src/main/java/org/apache/maven/model/transform/stax/NodeBufferingParser.java similarity index 64% rename from maven-model-transform/src/main/java/org/apache/maven/model/transform/pull/NodeBufferingParser.java rename to maven-model-transform/src/main/java/org/apache/maven/model/transform/stax/NodeBufferingParser.java index ba9d5f9b62..b3742b9c3c 100644 --- a/maven-model-transform/src/main/java/org/apache/maven/model/transform/pull/NodeBufferingParser.java +++ b/maven-model-transform/src/main/java/org/apache/maven/model/transform/stax/NodeBufferingParser.java @@ -16,16 +16,15 @@ * specific language governing permissions and limitations * under the License. */ -package org.apache.maven.model.transform.pull; +package org.apache.maven.model.transform.stax; + +import javax.xml.stream.XMLStreamException; +import javax.xml.stream.XMLStreamReader; -import java.io.IOException; import java.util.ArrayList; import java.util.List; import java.util.Objects; -import org.codehaus.plexus.util.xml.pull.XmlPullParser; -import org.codehaus.plexus.util.xml.pull.XmlPullParserException; - /** * Buffer events while parsing a given element to allow some post-processing. * @@ -40,31 +39,29 @@ public abstract class NodeBufferingParser extends BufferingParser { private boolean buffering; - public NodeBufferingParser(XmlPullParser xmlPullParser, String nodeName) { + public NodeBufferingParser(XMLStreamReader xmlPullParser, String nodeName) { super(xmlPullParser); this.nodeName = Objects.requireNonNull(nodeName); } @Override - protected boolean accept() throws XmlPullParserException, IOException { - if (nodeName.equals(xmlPullParser.getName())) { - if (xmlPullParser.getEventType() == START_TAG && !buffering) { - buffer.add(bufferEvent()); - buffering = true; - return false; - } - if (xmlPullParser.getEventType() == END_TAG && buffering) { - buffer.add(bufferEvent()); - process(buffer); - buffering = false; - buffer.clear(); - return false; - } + protected boolean accept() throws XMLStreamException { + if (!buffering && delegate.getEventType() == START_ELEMENT && nodeName.equals(delegate.getLocalName())) { + buffer.add(bufferEvent()); + buffering = true; + return false; + } else if (buffering && delegate.getEventType() == END_ELEMENT && nodeName.equals(delegate.getLocalName())) { + buffer.add(bufferEvent()); + process(buffer); + buffering = false; + buffer.clear(); + return false; } else if (buffering) { buffer.add(bufferEvent()); return false; + } else { + return true; } - return true; } @Override diff --git a/maven-model-transform/src/main/java/org/apache/maven/model/transform/stax/XmlUtils.java b/maven-model-transform/src/main/java/org/apache/maven/model/transform/stax/XmlUtils.java new file mode 100644 index 0000000000..48e7a9b14d --- /dev/null +++ b/maven-model-transform/src/main/java/org/apache/maven/model/transform/stax/XmlUtils.java @@ -0,0 +1,187 @@ +/* + * 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. + */ +package org.apache.maven.model.transform.stax; + +import javax.xml.stream.XMLOutputFactory; +import javax.xml.stream.XMLStreamConstants; +import javax.xml.stream.XMLStreamException; +import javax.xml.stream.XMLStreamReader; +import javax.xml.stream.XMLStreamWriter; + +import java.io.ByteArrayInputStream; +import java.io.ByteArrayOutputStream; +import java.io.InputStream; +import java.io.OutputStream; +import java.util.ArrayDeque; +import java.util.Deque; + +import com.ctc.wstx.api.WstxOutputProperties; + +public class XmlUtils { + + public static InputStream writeDocument(XMLStreamReader parser) throws XMLStreamException { + ByteArrayOutputStream baos = new ByteArrayOutputStream(); + writeDocument(parser, baos); + return new ByteArrayInputStream(baos.toByteArray()); + } + + public static void writeDocument(XMLStreamReader parser, OutputStream output) throws XMLStreamException { + XMLOutputFactory factory = new com.ctc.wstx.stax.WstxOutputFactory(); + factory.setProperty(XMLOutputFactory.IS_REPAIRING_NAMESPACES, false); + factory.setProperty(WstxOutputProperties.P_USE_DOUBLE_QUOTES_IN_XML_DECL, true); + factory.setProperty(WstxOutputProperties.P_ADD_SPACE_AFTER_EMPTY_ELEM, true); + XMLStreamWriter serializer = factory.createXMLStreamWriter(output, parser.getCharacterEncodingScheme()); + copy(parser, serializer); + } + + private static String normalize(String input) { + if (input != null) { + return input.replace("\r\n", "\n"); + } + return input; + } + + /** + * Copies the reader to the writer. The start and end document methods must + * be handled on the writer manually. + */ + public static void copy(XMLStreamReader reader, XMLStreamWriter writer) throws XMLStreamException { + copy(reader, writer, false, false); + } + + public static void copy(XMLStreamReader reader, XMLStreamWriter writer, boolean fragment) + throws XMLStreamException { + copy(reader, writer, fragment, false); + } + + public static void copy(XMLStreamReader reader, XMLStreamWriter writer, boolean fragment, boolean isThreshold) + throws XMLStreamException { + // number of elements read in + int read = 0; + int elementCount = 0; + final Deque countStack = new ArrayDeque<>(); + int event = reader.getEventType(); + + while (true) { + switch (event) { + case XMLStreamConstants.START_ELEMENT: + read++; + if (isThreshold) { + elementCount++; + countStack.push(elementCount); + elementCount = 0; + } + writeStartElement(reader, writer); + break; + case XMLStreamConstants.END_ELEMENT: + if (read > 0) { + writer.writeEndElement(); + } + read--; + if (read < 0 && fragment) { + return; + } + if (isThreshold && !countStack.isEmpty()) { + elementCount = countStack.pop(); + } + break; + case XMLStreamConstants.CHARACTERS: + writer.writeCharacters(normalize(reader.getText())); + break; + case XMLStreamConstants.SPACE: + writer.writeCharacters(normalize(reader.getText())); + break; + case XMLStreamConstants.ENTITY_REFERENCE: + writer.writeEntityRef(reader.getLocalName()); + break; + case XMLStreamConstants.COMMENT: + writer.writeComment(normalize(reader.getText())); + break; + case XMLStreamConstants.CDATA: + writer.writeCData(normalize(reader.getText())); + break; + case XMLStreamConstants.START_DOCUMENT: + if (reader.getVersion() != null) { + writer.writeStartDocument(reader.getCharacterEncodingScheme(), reader.getVersion()); + } + break; + case XMLStreamConstants.END_DOCUMENT: + writer.writeEndDocument(); + return; + default: + break; + } + event = reader.next(); + } + } + + private static void writeStartElement(XMLStreamReader reader, XMLStreamWriter writer) throws XMLStreamException { + String uri = reader.getNamespaceURI(); + String prefix = reader.getPrefix(); + String local = reader.getLocalName(); + + if (prefix == null) { + prefix = ""; + } + + // Write out the element name + if (uri != null) { + if (prefix.isEmpty() && isEmpty(uri)) { + writer.writeStartElement(local); + } else { + writer.writeStartElement(prefix, local, uri); + } + } else { + writer.writeStartElement(local); + } + + // Write out the namespaces + for (int i = 0; i < reader.getNamespaceCount(); i++) { + String nsURI = reader.getNamespaceURI(i); + String nsPrefix = reader.getNamespacePrefix(i); + if (nsURI == null) { + nsURI = ""; + } + writer.writeNamespace(nsPrefix, nsURI); + writer.setPrefix(nsPrefix, nsURI); + } + + // Write out attributes + for (int i = 0; i < reader.getAttributeCount(); i++) { + String ns = reader.getAttributeNamespace(i); + String nsPrefix = reader.getAttributePrefix(i); + if (ns == null || ns.isEmpty()) { + writer.writeAttribute(reader.getAttributeLocalName(i), reader.getAttributeValue(i)); + } else if (nsPrefix == null || nsPrefix.isEmpty()) { + writer.writeAttribute( + reader.getAttributeNamespace(i), reader.getAttributeLocalName(i), reader.getAttributeValue(i)); + } else { + writer.writeAttribute( + reader.getAttributePrefix(i), + reader.getAttributeNamespace(i), + reader.getAttributeLocalName(i), + reader.getAttributeValue(i)); + } + } + } + + private static boolean isEmpty(String s) { + return s == null || s.isEmpty(); + } +} diff --git a/maven-model-transform/src/test/java/org/apache/maven/model/transform/AbstractXMLFilterTests.java b/maven-model-transform/src/test/java/org/apache/maven/model/transform/AbstractXMLFilterTests.java index b1d146a45a..9ed0e731d2 100644 --- a/maven-model-transform/src/test/java/org/apache/maven/model/transform/AbstractXMLFilterTests.java +++ b/maven-model-transform/src/test/java/org/apache/maven/model/transform/AbstractXMLFilterTests.java @@ -18,34 +18,32 @@ */ package org.apache.maven.model.transform; +import javax.xml.stream.XMLInputFactory; +import javax.xml.stream.XMLStreamException; +import javax.xml.stream.XMLStreamReader; + +import java.io.ByteArrayOutputStream; import java.io.IOException; import java.io.Reader; import java.io.StringReader; -import java.io.StringWriter; -import org.apache.maven.model.transform.pull.XmlUtils; -import org.codehaus.plexus.util.xml.pull.MXParser; -import org.codehaus.plexus.util.xml.pull.XmlPullParser; -import org.codehaus.plexus.util.xml.pull.XmlPullParserException; +import org.apache.maven.model.transform.stax.XmlUtils; public abstract class AbstractXMLFilterTests { - protected XmlPullParser getFilter(XmlPullParser parser) { + protected XMLStreamReader getFilter(XMLStreamReader parser) { throw new UnsupportedOperationException("Override one of the getFilter() methods"); } - protected String transform(String input) throws XmlPullParserException, IOException { + protected String transform(String input) throws XMLStreamException, IOException { return transform(new StringReader(input)); } - protected String transform(Reader input) throws XmlPullParserException, IOException { + protected String transform(Reader input) throws XMLStreamException, IOException { + XMLStreamReader parser = XMLInputFactory.newFactory().createXMLStreamReader(input); + XMLStreamReader filter = getFilter(parser); - MXParser parser = new MXParser(); - parser.setFeature(XmlPullParser.FEATURE_PROCESS_NAMESPACES, true); - parser.setInput(input); - XmlPullParser filter = getFilter(parser); - - StringWriter writer = new StringWriter(); - XmlUtils.writeDocument(filter, writer); - return writer.toString(); + ByteArrayOutputStream baos = new ByteArrayOutputStream(); + XmlUtils.writeDocument(filter, baos); + return baos.toString(); } } diff --git a/maven-model-transform/src/test/java/org/apache/maven/model/transform/CiFriendlyXMLFilterTest.java b/maven-model-transform/src/test/java/org/apache/maven/model/transform/CiFriendlyXMLFilterTest.java index 6a276376f2..e33b35e72e 100644 --- a/maven-model-transform/src/test/java/org/apache/maven/model/transform/CiFriendlyXMLFilterTest.java +++ b/maven-model-transform/src/test/java/org/apache/maven/model/transform/CiFriendlyXMLFilterTest.java @@ -18,14 +18,15 @@ */ package org.apache.maven.model.transform; -import org.codehaus.plexus.util.xml.pull.XmlPullParser; +import javax.xml.stream.XMLStreamReader; + import org.junit.jupiter.api.Test; import static org.junit.jupiter.api.Assertions.assertEquals; class CiFriendlyXMLFilterTest extends AbstractXMLFilterTests { @Override - protected CiFriendlyXMLFilter getFilter(XmlPullParser parser) { + protected CiFriendlyXMLFilter getFilter(XMLStreamReader parser) { CiFriendlyXMLFilter filter = new CiFriendlyXMLFilter(parser, true); filter.setChangelist("CHANGELIST"); diff --git a/maven-model-transform/src/test/java/org/apache/maven/model/transform/ConsumerPomXMLFilterTest.java b/maven-model-transform/src/test/java/org/apache/maven/model/transform/ConsumerPomXMLFilterTest.java index a3d3d9cb9f..9352984fe9 100644 --- a/maven-model-transform/src/test/java/org/apache/maven/model/transform/ConsumerPomXMLFilterTest.java +++ b/maven-model-transform/src/test/java/org/apache/maven/model/transform/ConsumerPomXMLFilterTest.java @@ -18,20 +18,21 @@ */ package org.apache.maven.model.transform; +import javax.xml.stream.XMLStreamReader; + 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 org.codehaus.plexus.util.xml.pull.XmlPullParser; import org.junit.jupiter.api.Test; import static org.xmlunit.assertj.XmlAssert.assertThat; class ConsumerPomXMLFilterTest extends AbstractXMLFilterTests { @Override - protected XmlPullParser getFilter(XmlPullParser orgParser) { + protected XMLStreamReader getFilter(XMLStreamReader orgParser) { final BuildToRawPomXMLFilterFactory buildPomXMLFilterFactory = new BuildToRawPomXMLFilterFactory(true) { @Override protected Function> getRelativePathMapper() { @@ -59,7 +60,7 @@ protected Optional getChangelist() { } }; - XmlPullParser parser = + XMLStreamReader parser = new RawToConsumerPomXMLFilterFactory(buildPomXMLFilterFactory).get(orgParser, Paths.get("pom.xml")); return parser; } diff --git a/maven-model-transform/src/test/java/org/apache/maven/model/transform/ModelVersionXMLFilterTest.java b/maven-model-transform/src/test/java/org/apache/maven/model/transform/ModelVersionXMLFilterTest.java index 2dee395405..c1b7120702 100644 --- a/maven-model-transform/src/test/java/org/apache/maven/model/transform/ModelVersionXMLFilterTest.java +++ b/maven-model-transform/src/test/java/org/apache/maven/model/transform/ModelVersionXMLFilterTest.java @@ -18,14 +18,15 @@ */ package org.apache.maven.model.transform; -import org.codehaus.plexus.util.xml.pull.XmlPullParser; +import javax.xml.stream.XMLStreamReader; + import org.junit.jupiter.api.Test; import static org.junit.jupiter.api.Assertions.assertEquals; class ModelVersionXMLFilterTest extends AbstractXMLFilterTests { @Override - protected XmlPullParser getFilter(XmlPullParser parser) { + protected XMLStreamReader getFilter(XMLStreamReader parser) { return new ModelVersionXMLFilter(parser); } diff --git a/maven-model-transform/src/test/java/org/apache/maven/model/transform/ModulesXMLFilterTest.java b/maven-model-transform/src/test/java/org/apache/maven/model/transform/ModulesXMLFilterTest.java index 39323a4bc5..a1e3601e3d 100644 --- a/maven-model-transform/src/test/java/org/apache/maven/model/transform/ModulesXMLFilterTest.java +++ b/maven-model-transform/src/test/java/org/apache/maven/model/transform/ModulesXMLFilterTest.java @@ -18,7 +18,8 @@ */ package org.apache.maven.model.transform; -import org.codehaus.plexus.util.xml.pull.XmlPullParser; +import javax.xml.stream.XMLStreamReader; + import org.junit.jupiter.api.Test; import static org.xmlunit.assertj.XmlAssert.assertThat; @@ -26,7 +27,7 @@ class ModulesXMLFilterTest extends AbstractXMLFilterTests { @Override - protected ModulesXMLFilter getFilter(XmlPullParser parser) { + protected ModulesXMLFilter getFilter(XMLStreamReader parser) { return new ModulesXMLFilter(parser); } diff --git a/maven-model-transform/src/test/java/org/apache/maven/model/transform/ParentXMLFilterTest.java b/maven-model-transform/src/test/java/org/apache/maven/model/transform/ParentXMLFilterTest.java index 2e253b7cdd..d27d604bed 100644 --- a/maven-model-transform/src/test/java/org/apache/maven/model/transform/ParentXMLFilterTest.java +++ b/maven-model-transform/src/test/java/org/apache/maven/model/transform/ParentXMLFilterTest.java @@ -18,19 +18,20 @@ */ package org.apache.maven.model.transform; +import javax.xml.stream.XMLStreamReader; + import java.nio.file.Path; import java.nio.file.Paths; import java.util.Optional; import java.util.function.Function; -import org.codehaus.plexus.util.xml.pull.XmlPullParser; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; import static org.junit.jupiter.api.Assertions.assertEquals; class ParentXMLFilterTest extends AbstractXMLFilterTests { - private Function filterCreator; + private Function filterCreator; @BeforeEach void reset() { @@ -38,21 +39,21 @@ void reset() { } @Override - protected XmlPullParser getFilter(XmlPullParser parser) { - Function filterCreator = + protected XMLStreamReader getFilter(XMLStreamReader parser) { + Function filterCreator = (this.filterCreator != null ? this.filterCreator : this::createFilter); return filterCreator.apply(parser); } - protected XmlPullParser createFilter(XmlPullParser parser) { + protected XMLStreamReader createFilter(XMLStreamReader parser) { return createFilter( parser, x -> Optional.of(new RelativeProject("GROUPID", "ARTIFACTID", "1.0.0")), Paths.get("pom.xml").toAbsolutePath()); } - protected XmlPullParser createFilter( - XmlPullParser parser, Function> pathMapper, Path projectPath) { + protected XMLStreamReader createFilter( + XMLStreamReader parser, Function> pathMapper, Path projectPath) { return new ParentXMLFilter(new FastForwardFilter(parser), pathMapper, projectPath); } @@ -154,12 +155,12 @@ void testDefaultRelativePath() throws Exception { + " ARTIFACTID\n" + " \n" + ""; - String expected = "" + System.lineSeparator() - + " " + System.lineSeparator() - + " GROUPID" + System.lineSeparator() - + " ARTIFACTID" + System.lineSeparator() - + " 1.0.0" + System.lineSeparator() - + " " + System.lineSeparator() + String expected = "\n" + + " \n" + + " GROUPID\n" + + " ARTIFACTID\n" + + " 1.0.0\n" + + " \n" + ""; String actual = transform(input); @@ -299,13 +300,13 @@ void testIndent() throws Exception { + " \n" + " \n" + ""; - String expected = "" + System.lineSeparator() - + " " + System.lineSeparator() - + " GROUPID" + System.lineSeparator() - + " ARTIFACTID" + System.lineSeparator() - + " " + System.lineSeparator() - + " 1.0.0" + System.lineSeparator() - + " " + System.lineSeparator() + String expected = "\n" + + " \n" + + " GROUPID\n" + + " ARTIFACTID\n" + + " \n" + + " 1.0.0\n" + + " \n" + ""; String actual = transform(input); diff --git a/maven-model-transform/src/test/java/org/apache/maven/model/transform/ReactorDependencyXMLFilterTest.java b/maven-model-transform/src/test/java/org/apache/maven/model/transform/ReactorDependencyXMLFilterTest.java index 4bad0e75a0..0621d8b844 100644 --- a/maven-model-transform/src/test/java/org/apache/maven/model/transform/ReactorDependencyXMLFilterTest.java +++ b/maven-model-transform/src/test/java/org/apache/maven/model/transform/ReactorDependencyXMLFilterTest.java @@ -18,9 +18,10 @@ */ package org.apache.maven.model.transform; +import javax.xml.stream.XMLStreamReader; + import java.util.function.BiFunction; -import org.codehaus.plexus.util.xml.pull.XmlPullParser; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; @@ -35,7 +36,7 @@ protected void reset() { } @Override - protected ReactorDependencyXMLFilter getFilter(XmlPullParser parser) { + protected ReactorDependencyXMLFilter getFilter(XMLStreamReader parser) { return new ReactorDependencyXMLFilter( parser, reactorVersionMapper != null ? reactorVersionMapper : (g, a) -> "1.0.0"); } diff --git a/maven-model-transform/src/test/java/org/apache/maven/model/transform/RelativePathXMLFilterTest.java b/maven-model-transform/src/test/java/org/apache/maven/model/transform/RelativePathXMLFilterTest.java index 6b114cfd10..2388521870 100644 --- a/maven-model-transform/src/test/java/org/apache/maven/model/transform/RelativePathXMLFilterTest.java +++ b/maven-model-transform/src/test/java/org/apache/maven/model/transform/RelativePathXMLFilterTest.java @@ -18,14 +18,15 @@ */ package org.apache.maven.model.transform; -import org.codehaus.plexus.util.xml.pull.XmlPullParser; +import javax.xml.stream.XMLStreamReader; + import org.junit.jupiter.api.Test; import static org.xmlunit.assertj.XmlAssert.assertThat; class RelativePathXMLFilterTest extends AbstractXMLFilterTests { @Override - protected RelativePathXMLFilter getFilter(XmlPullParser parser) { + protected RelativePathXMLFilter getFilter(XMLStreamReader parser) { return new RelativePathXMLFilter(parser); } diff --git a/maven-model/pom.xml b/maven-model/pom.xml index a1f9b108bc..95cfaafa27 100644 --- a/maven-model/pom.xml +++ b/maven-model/pom.xml @@ -46,6 +46,22 @@ under the License. org.codehaus.plexus plexus-xml + + org.openjdk.jmh + jmh-core + 1.36 + test + + + org.openjdk.jmh + jmh-generator-annprocess + 1.36 + test + + + com.fasterxml.woodstox + woodstox-core + @@ -61,6 +77,7 @@ under the License. src/main/mdo/maven.mdo + forcedIOModelVersion=4.0.0 packageModelV3=org.apache.maven.model packageModelV4=org.apache.maven.api.model packageToolV4=org.apache.maven.model.v4 @@ -104,6 +121,8 @@ under the License. + + diff --git a/maven-model/src/test/java/org/apache/maven/model/v4/ModelXmlTest.java b/maven-model/src/test/java/org/apache/maven/model/v4/ModelXmlTest.java index 7f46d59031..71fc8e7859 100644 --- a/maven-model/src/test/java/org/apache/maven/model/v4/ModelXmlTest.java +++ b/maven-model/src/test/java/org/apache/maven/model/v4/ModelXmlTest.java @@ -18,6 +18,8 @@ */ package org.apache.maven.model.v4; +import javax.xml.stream.XMLStreamException; + import java.io.IOException; import java.io.StringReader; import java.io.StringWriter; @@ -25,7 +27,6 @@ import java.util.Map; import org.apache.maven.api.model.Model; -import org.codehaus.plexus.util.xml.pull.XmlPullParserException; import org.junit.jupiter.api.Test; import static org.junit.jupiter.api.Assertions.assertEquals; @@ -55,7 +56,7 @@ String toXml(Model model) throws IOException { return sw.toString(); } - Model fromXml(String xml) throws IOException, XmlPullParserException { - return new MavenXpp3Reader().read(new StringReader(xml)); + Model fromXml(String xml) throws XMLStreamException { + return new MavenStaxReader().read(new StringReader(xml)); } } diff --git a/maven-model/src/test/java/org/apache/maven/model/v4/Xpp3DomPerfTest.java b/maven-model/src/test/java/org/apache/maven/model/v4/Xpp3DomPerfTest.java new file mode 100644 index 0000000000..52f5a2309b --- /dev/null +++ b/maven-model/src/test/java/org/apache/maven/model/v4/Xpp3DomPerfTest.java @@ -0,0 +1,117 @@ +/* + * 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. + */ +package org.apache.maven.model.v4; + +/* + * Copyright The Codehaus Foundation. + * + * Licensed 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.stream.XMLStreamException; + +import java.io.IOException; +import java.io.InputStream; +import java.nio.file.Files; +import java.nio.file.Path; +import java.nio.file.Paths; +import java.util.List; +import java.util.concurrent.TimeUnit; +import java.util.stream.Collectors; + +import org.apache.maven.api.model.InputSource; +import org.codehaus.plexus.util.xml.pull.XmlPullParserException; +import org.openjdk.jmh.annotations.*; +import org.openjdk.jmh.runner.Runner; +import org.openjdk.jmh.runner.RunnerException; +import org.openjdk.jmh.runner.options.Options; +import org.openjdk.jmh.runner.options.OptionsBuilder; + +/** + *

Xpp3DomPerfTest class.

+ */ +@BenchmarkMode(Mode.AverageTime) +@OutputTimeUnit(TimeUnit.MILLISECONDS) +@Warmup(iterations = 3) +@Measurement(time = 10) +public class Xpp3DomPerfTest { + @State(Scope.Benchmark) + public static class AdditionState { + List poms; + + @Setup(Level.Iteration) + public void setUp() throws IOException { + Path userHome = Paths.get(System.getProperty("user.home")); + poms = Files.walk(userHome.resolve(".m2/repository/org/apache/maven")) + .filter(p -> p.getFileName().toString().endsWith(".pom")) + .collect(Collectors.toList()); + } + } + + @Benchmark + public int readWithXpp3(AdditionState state) throws IOException, XmlPullParserException { + int i = 0; + for (Path pom : state.poms) { + try (InputStream is = Files.newInputStream(pom)) { + new MavenXpp3ReaderEx().read(is, true, new InputSource("id", pom.toString())); + i++; + } catch (XmlPullParserException e) { + throw new RuntimeException("Error parsing: " + pom, e); + } + } + return i; + } + + @Benchmark + public int readWithStax(AdditionState state) throws IOException, XMLStreamException { + int i = 0; + for (Path pom : state.poms) { + try (InputStream is = Files.newInputStream(pom)) { + MavenStaxReader reader = new MavenStaxReader(); + reader.setAddLocationInformation(false); + reader.read(is, true, new InputSource("id", pom.toString())); + i++; + } catch (XMLStreamException e) { + throw new RuntimeException("Error parsing: " + pom, e); + } + } + return i; + } + + /** + *

main.

+ * + * @param args a {@link String} object. + * @throws org.openjdk.jmh.runner.RunnerException if any. + */ + public static void main(String... args) throws RunnerException { + Options opts = new OptionsBuilder().forks(1).build(); + new Runner(opts).run(); + } +} diff --git a/maven-plugin-api/pom.xml b/maven-plugin-api/pom.xml index 274a62ef63..a7b982f479 100644 --- a/maven-plugin-api/pom.xml +++ b/maven-plugin-api/pom.xml @@ -78,11 +78,14 @@ under the License. + + packageModelV3=org.apache.maven.plugin.lifecycle packageModelV4=org.apache.maven.plugin.lifecycle - packageToolV4=org.apache.maven.plugin.lifecycle.io.xpp3 + packageToolV4=org.apache.maven.plugin.lifecycle.io + packageToolV4Xpp3=org.apache.maven.plugin.lifecycle.io.xpp3 diff --git a/maven-plugin-api/src/main/java/org/apache/maven/plugin/descriptor/PluginDescriptor.java b/maven-plugin-api/src/main/java/org/apache/maven/plugin/descriptor/PluginDescriptor.java index 1247e7dd43..0b90bdfbb8 100644 --- a/maven-plugin-api/src/main/java/org/apache/maven/plugin/descriptor/PluginDescriptor.java +++ b/maven-plugin-api/src/main/java/org/apache/maven/plugin/descriptor/PluginDescriptor.java @@ -18,13 +18,14 @@ */ package org.apache.maven.plugin.descriptor; +import javax.xml.stream.XMLStreamException; + import java.io.File; -import java.io.FileInputStream; import java.io.IOException; import java.io.InputStream; -import java.io.Reader; import java.net.MalformedURLException; import java.net.URL; +import java.nio.file.Files; import java.util.Collections; import java.util.HashMap; import java.util.List; @@ -37,11 +38,9 @@ import org.apache.maven.model.Plugin; import org.apache.maven.plugin.lifecycle.Lifecycle; import org.apache.maven.plugin.lifecycle.LifecycleConfiguration; -import org.apache.maven.plugin.lifecycle.io.xpp3.LifecycleMappingsXpp3Reader; +import org.apache.maven.plugin.lifecycle.io.LifecycleMappingsStaxReader; import org.codehaus.plexus.classworlds.realm.ClassRealm; import org.codehaus.plexus.component.repository.ComponentSetDescriptor; -import org.codehaus.plexus.util.ReaderFactory; -import org.codehaus.plexus.util.xml.pull.XmlPullParserException; /** * @author Jason van Zyl @@ -327,12 +326,12 @@ public void setPluginArtifact(Artifact pluginArtifact) { this.pluginArtifact = pluginArtifact; } - public Lifecycle getLifecycleMapping(String lifecycleId) throws IOException, XmlPullParserException { + public Lifecycle getLifecycleMapping(String lifecycleId) throws IOException, XMLStreamException { if (lifecycleMappings == null) { LifecycleConfiguration lifecycleConfiguration; - try (Reader reader = ReaderFactory.newXmlReader(getDescriptorStream(LIFECYCLE_DESCRIPTOR))) { - lifecycleConfiguration = new LifecycleMappingsXpp3Reader().read(reader); + try (InputStream input = getDescriptorStream(LIFECYCLE_DESCRIPTOR)) { + lifecycleConfiguration = new LifecycleMappingsStaxReader().read(input); } lifecycleMappings = new HashMap<>(); @@ -358,7 +357,7 @@ private InputStream getDescriptorStream(String descriptor) throws IOException { throw new IllegalStateException(e); } } else { - return new FileInputStream(new File(pluginFile, descriptor)); + return Files.newInputStream(new File(pluginFile, descriptor).toPath()); } } diff --git a/maven-plugin-api/src/main/java/org/apache/maven/plugin/descriptor/PluginDescriptorBuilder.java b/maven-plugin-api/src/main/java/org/apache/maven/plugin/descriptor/PluginDescriptorBuilder.java index 7c853f97bd..8613551ad1 100644 --- a/maven-plugin-api/src/main/java/org/apache/maven/plugin/descriptor/PluginDescriptorBuilder.java +++ b/maven-plugin-api/src/main/java/org/apache/maven/plugin/descriptor/PluginDescriptorBuilder.java @@ -18,20 +18,22 @@ */ package org.apache.maven.plugin.descriptor; -import java.io.IOException; +import javax.xml.stream.XMLStreamException; +import javax.xml.stream.XMLStreamReader; + import java.io.InputStream; import java.io.Reader; import java.util.ArrayList; import java.util.List; import java.util.Optional; +import com.ctc.wstx.stax.WstxInputFactory; import org.apache.maven.internal.xml.XmlNodeBuilder; import org.apache.maven.internal.xml.XmlPlexusConfiguration; import org.codehaus.plexus.component.repository.ComponentDependency; import org.codehaus.plexus.component.repository.ComponentRequirement; import org.codehaus.plexus.configuration.PlexusConfiguration; import org.codehaus.plexus.configuration.PlexusConfigurationException; -import org.codehaus.plexus.util.xml.pull.XmlPullParserException; /** * @author Jason van Zyl @@ -374,16 +376,18 @@ public MojoDescriptor buildComponentDescriptor(PlexusConfiguration c, PluginDesc public PlexusConfiguration buildConfiguration(Reader configuration) throws PlexusConfigurationException { try { - return XmlPlexusConfiguration.toPlexusConfiguration(XmlNodeBuilder.build(configuration)); - } catch (IOException | XmlPullParserException e) { + XMLStreamReader reader = WstxInputFactory.newFactory().createXMLStreamReader(configuration); + return XmlPlexusConfiguration.toPlexusConfiguration(XmlNodeBuilder.build(reader, true, null)); + } catch (XMLStreamException e) { throw new PlexusConfigurationException(e.getMessage(), e); } } public PlexusConfiguration buildConfiguration(InputStream configuration) throws PlexusConfigurationException { try { - return XmlPlexusConfiguration.toPlexusConfiguration(XmlNodeBuilder.build(configuration, null)); - } catch (IOException | XmlPullParserException e) { + XMLStreamReader reader = WstxInputFactory.newFactory().createXMLStreamReader(configuration); + return XmlPlexusConfiguration.toPlexusConfiguration(XmlNodeBuilder.build(reader, true, null)); + } catch (XMLStreamException e) { throw new PlexusConfigurationException(e.getMessage(), e); } } diff --git a/maven-repository-metadata/pom.xml b/maven-repository-metadata/pom.xml index 2373085c7f..7fe3083823 100644 --- a/maven-repository-metadata/pom.xml +++ b/maven-repository-metadata/pom.xml @@ -36,6 +36,14 @@ under the License. org.codehaus.plexus plexus-xml
+ + org.apache.maven + maven-xml-impl + + + com.fasterxml.woodstox + woodstox-core + org.apache.maven.resolver maven-resolver-api @@ -49,19 +57,50 @@ under the License. org.codehaus.modello modello-maven-plugin - 1.1.0 + 1.2.0 src/main/mdo/metadata.mdo + + forcedIOModelVersion=1.1.0 + packageModelV3=org.apache.maven.artifact.repository.metadata + packageModelV4=org.apache.maven.artifact.repository.metadata.v4 + packageToolV4=org.apache.maven.artifact.repository.metadata.io + + ${project.basedir}/../src/mdo modello - java - xpp3-reader - xpp3-writer + velocity + + 1.2.0 + + src/main/mdo/metadata.mdo + + + + + + + + + + modello-v3 + + velocity + + + 1.1.0 + + src/main/mdo/metadata.mdo + + + + +
diff --git a/maven-repository-metadata/src/main/java/org/apache/maven/artifact/repository/metadata/BaseObject.java b/maven-repository-metadata/src/main/java/org/apache/maven/artifact/repository/metadata/BaseObject.java new file mode 100644 index 0000000000..c206298e2b --- /dev/null +++ b/maven-repository-metadata/src/main/java/org/apache/maven/artifact/repository/metadata/BaseObject.java @@ -0,0 +1,61 @@ +/* + * 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. + */ +package org.apache.maven.artifact.repository.metadata; + +import java.io.Serializable; + +public abstract class BaseObject implements Serializable, Cloneable { + protected transient ChildrenTracking childrenTracking; + + protected Object delegate; + + public BaseObject() {} + + public BaseObject(Object delegate, BaseObject parent) { + this.delegate = delegate; + this.childrenTracking = parent != null ? parent::replace : null; + } + + public BaseObject(Object delegate, ChildrenTracking parent) { + this.delegate = delegate; + this.childrenTracking = parent; + } + + public Object getDelegate() { + return delegate; + } + + public void update(Object newDelegate) { + if (delegate != newDelegate) { + if (childrenTracking != null) { + childrenTracking.replace(delegate, newDelegate); + } + delegate = newDelegate; + } + } + + protected boolean replace(Object oldDelegate, Object newDelegate) { + return false; + } + + @FunctionalInterface + protected interface ChildrenTracking { + boolean replace(Object oldDelegate, Object newDelegate); + } +} diff --git a/maven-repository-metadata/src/main/mdo/metadata.mdo b/maven-repository-metadata/src/main/mdo/metadata.mdo index 6ce381d4a8..32fa412556 100644 --- a/maven-repository-metadata/src/main/mdo/metadata.mdo +++ b/maven-repository-metadata/src/main/mdo/metadata.mdo @@ -19,7 +19,7 @@ under the License. repository-metadata Metadata @@ -35,11 +35,11 @@ under the License. - + Metadata 1.0.0+ - + modelVersion 1.1.0+ String @@ -86,7 +86,7 @@ under the License. - 1.0.0+ + 1.0.0/1.1.0 - 1.0.0+ + 1.0.0/1.1.0 options) throws IOException { try (InputStream in = Files.newInputStream(input.toPath())) { InputSource source = new InputSource(input.toString()); - return new Settings(new SettingsXpp3ReaderEx().read(in, isStrict(options), source)); - } catch (XmlPullParserException e) { - throw new SettingsParseException(e.getMessage(), e.getLineNumber(), e.getColumnNumber(), e); + return new Settings(new SettingsStaxReader().read(in, isStrict(options), source)); + } catch (XMLStreamException e) { + throw new SettingsParseException( + e.getMessage(), + e.getLocation().getLineNumber(), + e.getLocation().getColumnNumber(), + e); } } @@ -61,9 +65,13 @@ public Settings read(Reader input, Map options) throws IOException { try (Reader in = input) { InputSource source = (InputSource) options.get(InputSource.class.getName()); - return new Settings(new SettingsXpp3ReaderEx().read(in, isStrict(options), source)); - } catch (XmlPullParserException e) { - throw new SettingsParseException(e.getMessage(), e.getLineNumber(), e.getColumnNumber(), e); + return new Settings(new SettingsStaxReader().read(in, isStrict(options), source)); + } catch (XMLStreamException e) { + throw new SettingsParseException( + e.getMessage(), + e.getLocation().getLineNumber(), + e.getLocation().getColumnNumber(), + e); } } @@ -73,9 +81,13 @@ public Settings read(InputStream input, Map options) throws IOExcepti try (InputStream in = input) { InputSource source = (InputSource) options.get(InputSource.class.getName()); - return new Settings(new SettingsXpp3ReaderEx().read(in, isStrict(options), source)); - } catch (XmlPullParserException e) { - throw new SettingsParseException(e.getMessage(), e.getLineNumber(), e.getColumnNumber(), e); + return new Settings(new SettingsStaxReader().read(in, isStrict(options), source)); + } catch (XMLStreamException e) { + throw new SettingsParseException( + e.getMessage(), + e.getLocation().getLineNumber(), + e.getLocation().getColumnNumber(), + e); } } diff --git a/maven-settings-builder/src/main/java/org/apache/maven/settings/io/DefaultSettingsWriter.java b/maven-settings-builder/src/main/java/org/apache/maven/settings/io/DefaultSettingsWriter.java index e654eafb20..e6b5bffe29 100644 --- a/maven-settings-builder/src/main/java/org/apache/maven/settings/io/DefaultSettingsWriter.java +++ b/maven-settings-builder/src/main/java/org/apache/maven/settings/io/DefaultSettingsWriter.java @@ -20,18 +20,18 @@ import javax.inject.Named; import javax.inject.Singleton; +import javax.xml.stream.XMLStreamException; import java.io.File; import java.io.IOException; import java.io.OutputStream; -import java.io.OutputStreamWriter; import java.io.Writer; +import java.nio.file.Files; import java.util.Map; import java.util.Objects; import org.apache.maven.settings.Settings; -import org.apache.maven.settings.v4.SettingsXpp3Writer; -import org.codehaus.plexus.util.xml.XmlStreamWriter; +import org.apache.maven.settings.v4.SettingsStaxWriter; /** * Handles serialization of settings into the default textual format. @@ -49,7 +49,7 @@ public void write(File output, Map options, Settings settings) t output.getParentFile().mkdirs(); - write(new XmlStreamWriter(output), options, settings); + write(Files.newOutputStream(output.toPath()), options, settings); } @Override @@ -58,7 +58,9 @@ public void write(Writer output, Map options, Settings settings) Objects.requireNonNull(settings, "settings cannot be null"); try (Writer out = output) { - new SettingsXpp3Writer().write(out, settings.getDelegate()); + new SettingsStaxWriter().write(out, settings.getDelegate()); + } catch (XMLStreamException e) { + throw new IOException("Error writing settings", e); } } @@ -67,14 +69,10 @@ public void write(OutputStream output, Map options, Settings set Objects.requireNonNull(output, "output cannot be null"); Objects.requireNonNull(settings, "settings cannot be null"); - String encoding = settings.getModelEncoding(); - // TODO Use StringUtils here - if (encoding == null || encoding.length() <= 0) { - encoding = "UTF-8"; - } - - try (Writer out = new OutputStreamWriter(output, encoding)) { - write(out, options, settings); + try (OutputStream out = output) { + new SettingsStaxWriter().write(out, settings.getDelegate()); + } catch (XMLStreamException e) { + throw new IOException("Error writing settings", e); } } } diff --git a/maven-settings/pom.xml b/maven-settings/pom.xml index 50bfeba193..a971382d0d 100644 --- a/maven-settings/pom.xml +++ b/maven-settings/pom.xml @@ -46,6 +46,10 @@ under the License. org.codehaus.plexus plexus-xml + + com.fasterxml.woodstox + woodstox-core + @@ -61,6 +65,7 @@ under the License. src/main/mdo/settings.mdo + forcedIOModelVersion=1.2.0 packageModelV3=org.apache.maven.settings packageModelV4=org.apache.maven.api.settings packageToolV4=org.apache.maven.settings.v4 @@ -78,9 +83,9 @@ under the License. - - + + locationTracking=true diff --git a/maven-settings/src/main/java/org/apache/maven/settings/io/xpp3/SettingsXpp3Reader.java b/maven-settings/src/main/java/org/apache/maven/settings/io/xpp3/SettingsXpp3Reader.java index 4bedb113e6..f0f9f24a1f 100644 --- a/maven-settings/src/main/java/org/apache/maven/settings/io/xpp3/SettingsXpp3Reader.java +++ b/maven-settings/src/main/java/org/apache/maven/settings/io/xpp3/SettingsXpp3Reader.java @@ -28,6 +28,7 @@ import org.codehaus.plexus.util.xml.pull.XmlPullParser; import org.codehaus.plexus.util.xml.pull.XmlPullParserException; +@Deprecated public class SettingsXpp3Reader { private boolean addDefaultEntities = true; diff --git a/maven-settings/src/main/java/org/apache/maven/settings/io/xpp3/SettingsXpp3Writer.java b/maven-settings/src/main/java/org/apache/maven/settings/io/xpp3/SettingsXpp3Writer.java index 26c750c072..f1c53ac588 100644 --- a/maven-settings/src/main/java/org/apache/maven/settings/io/xpp3/SettingsXpp3Writer.java +++ b/maven-settings/src/main/java/org/apache/maven/settings/io/xpp3/SettingsXpp3Writer.java @@ -24,6 +24,7 @@ import org.apache.maven.settings.Settings; +@Deprecated public class SettingsXpp3Writer { // --------------------------/ // - Class/Member Variables -/ diff --git a/maven-toolchain-builder/src/main/java/org/apache/maven/toolchain/io/DefaultToolchainsReader.java b/maven-toolchain-builder/src/main/java/org/apache/maven/toolchain/io/DefaultToolchainsReader.java index 6c6297fa67..f33ee3e19f 100644 --- a/maven-toolchain-builder/src/main/java/org/apache/maven/toolchain/io/DefaultToolchainsReader.java +++ b/maven-toolchain-builder/src/main/java/org/apache/maven/toolchain/io/DefaultToolchainsReader.java @@ -20,6 +20,7 @@ import javax.inject.Named; import javax.inject.Singleton; +import javax.xml.stream.XMLStreamException; import java.io.File; import java.io.IOException; @@ -30,8 +31,7 @@ import java.util.Objects; import org.apache.maven.toolchain.model.PersistedToolchains; -import org.apache.maven.toolchain.v4.MavenToolchainsXpp3Reader; -import org.codehaus.plexus.util.xml.pull.XmlPullParserException; +import org.apache.maven.toolchain.v4.MavenToolchainsStaxReader; /** * Handles deserialization of toolchains from the default textual format. @@ -48,9 +48,13 @@ public PersistedToolchains read(File input, Map options) throws IOExc Objects.requireNonNull(input, "input cannot be null"); try (InputStream in = Files.newInputStream(input.toPath())) { - return new PersistedToolchains(new MavenToolchainsXpp3Reader().read(in, isStrict(options))); - } catch (XmlPullParserException e) { - throw new ToolchainsParseException(e.getMessage(), e.getLineNumber(), e.getColumnNumber(), e); + return new PersistedToolchains(new MavenToolchainsStaxReader().read(in, isStrict(options))); + } catch (XMLStreamException e) { + throw new ToolchainsParseException( + e.getMessage(), + e.getLocation().getLineNumber(), + e.getLocation().getColumnNumber(), + e); } } @@ -59,9 +63,13 @@ public PersistedToolchains read(Reader input, Map options) throws IOE Objects.requireNonNull(input, "input cannot be null"); try (Reader in = input) { - return new PersistedToolchains(new MavenToolchainsXpp3Reader().read(in, isStrict(options))); - } catch (XmlPullParserException e) { - throw new ToolchainsParseException(e.getMessage(), e.getLineNumber(), e.getColumnNumber(), e); + return new PersistedToolchains(new MavenToolchainsStaxReader().read(in, isStrict(options))); + } catch (XMLStreamException e) { + throw new ToolchainsParseException( + e.getMessage(), + e.getLocation().getLineNumber(), + e.getLocation().getColumnNumber(), + e); } } @@ -70,9 +78,13 @@ public PersistedToolchains read(InputStream input, Map options) throw Objects.requireNonNull(input, "input cannot be null"); try (InputStream in = input) { - return new PersistedToolchains(new MavenToolchainsXpp3Reader().read(in, isStrict(options))); - } catch (XmlPullParserException e) { - throw new ToolchainsParseException(e.getMessage(), e.getLineNumber(), e.getColumnNumber(), e); + return new PersistedToolchains(new MavenToolchainsStaxReader().read(in, isStrict(options))); + } catch (XMLStreamException e) { + throw new ToolchainsParseException( + e.getMessage(), + e.getLocation().getLineNumber(), + e.getLocation().getColumnNumber(), + e); } } diff --git a/maven-toolchain-builder/src/main/java/org/apache/maven/toolchain/io/DefaultToolchainsWriter.java b/maven-toolchain-builder/src/main/java/org/apache/maven/toolchain/io/DefaultToolchainsWriter.java index 7f831df52f..88db296be9 100644 --- a/maven-toolchain-builder/src/main/java/org/apache/maven/toolchain/io/DefaultToolchainsWriter.java +++ b/maven-toolchain-builder/src/main/java/org/apache/maven/toolchain/io/DefaultToolchainsWriter.java @@ -20,6 +20,7 @@ import javax.inject.Named; import javax.inject.Singleton; +import javax.xml.stream.XMLStreamException; import java.io.IOException; import java.io.Writer; @@ -27,7 +28,7 @@ import java.util.Objects; import org.apache.maven.toolchain.model.PersistedToolchains; -import org.apache.maven.toolchain.v4.MavenToolchainsXpp3Writer; +import org.apache.maven.toolchain.v4.MavenToolchainsStaxWriter; /** * Handles serialization of toolchains into the default textual format. @@ -45,7 +46,9 @@ public void write(Writer output, Map options, PersistedToolchain Objects.requireNonNull(toolchains, "toolchains cannot be null"); try (Writer out = output) { - new MavenToolchainsXpp3Writer().write(out, toolchains.getDelegate()); + new MavenToolchainsStaxWriter().write(out, toolchains.getDelegate()); + } catch (XMLStreamException e) { + throw new IOException("Error writing toolchains", e); } } } diff --git a/maven-toolchain-builder/src/test/resources/org/apache/maven/toolchain/merge/toolchains-jdks-extend.xml b/maven-toolchain-builder/src/test/resources/org/apache/maven/toolchain/merge/toolchains-jdks-extend.xml index 64de88afd5..637ace9aef 100644 --- a/maven-toolchain-builder/src/test/resources/org/apache/maven/toolchain/merge/toolchains-jdks-extend.xml +++ b/maven-toolchain-builder/src/test/resources/org/apache/maven/toolchain/merge/toolchains-jdks-extend.xml @@ -1,4 +1,4 @@ - +