[MNG-7830] Switch from plexus-xml to stax / woodstox (#1185)

This commit is contained in:
Guillaume Nodet 2023-06-29 12:03:50 +02:00 committed by GitHub
parent 00e1793550
commit e39142b77a
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
88 changed files with 3036 additions and 1105 deletions

View File

@ -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.

View File

@ -23,7 +23,7 @@ import java.io.InputStream;
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 @@ class GlobalSettingsTest {
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()));
}
}
}

View File

@ -147,6 +147,11 @@ under the License.
<artifactId>maven-slf4j-wrapper</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>org.apache.maven</groupId>
<artifactId>maven-xml-impl</artifactId>
<version>${project.version}</version>
</dependency>
</dependencies>
</dependencyManagement>

View File

@ -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 abstract class AbstractRepositoryMetadata implements RepositoryMetadata {
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 @@ public abstract class AbstractRepositoryMetadata implements RepositoryMetadata {
// 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 @@ public abstract class AbstractRepositoryMetadata implements RepositoryMetadata {
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());

View File

@ -21,6 +21,7 @@ package org.apache.maven.artifact.repository.metadata;
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.ArtifactRepository;
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 @@ public class DefaultRepositoryMetadataManager extends AbstractLogEnabled impleme
*/
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 @@ public class DefaultRepositoryMetadataManager extends AbstractLogEnabled impleme
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);

View File

@ -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.Map;
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.AbstractLogEnabled;
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 abstract class AbstractStringBasedModelInterpolator extends AbstractLogEn
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 abstract class AbstractStringBasedModelInterpolator extends AbstractLogEn
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);
}

View File

@ -22,11 +22,11 @@ import javax.inject.Named;
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 class DefaultToolchainsBuilder implements ToolchainsBuilder {
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);

View File

@ -20,6 +20,7 @@ package org.apache.maven.artifact.repository.metadata.io;
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.Map;
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 class DefaultMetadataReader implements MetadataReader {
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 class DefaultMetadataReader implements MetadataReader {
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);
}
}

View File

@ -236,7 +236,7 @@ public class DefaultRepositorySystemSessionFactory {
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<XmlNode> children = dom.getChildren().stream()
.filter(c -> !"wagonProvider".equals(c.getName()))
.collect(Collectors.toList());

View File

@ -37,9 +37,8 @@ import org.apache.maven.api.services.xml.XmlReaderException;
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 class DefaultModelXmlFactory implements ModelXmlFactory {
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);
}
}
} catch (Exception e) {
throw new XmlReaderException("Unable to read model", e);
}
@ -88,12 +92,12 @@ public class DefaultModelXmlFactory implements ModelXmlFactory {
}
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) {

View File

@ -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.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 class DefaultSettingsXmlFactory implements SettingsXmlFactory {
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 class DefaultSettingsXmlFactory implements SettingsXmlFactory {
}
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);

View File

@ -35,8 +35,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.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 class DefaultToolchainsXmlFactory implements ToolchainsXmlFactory {
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 class DefaultToolchainsXmlFactory implements ToolchainsXmlFactory {
}
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);

View File

@ -21,6 +21,8 @@ package org.apache.maven.internal.transformation;
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.feature.Features;
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 @@ public final class ConsumerPomArtifactTransformer {
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 @@ public final class ConsumerPomArtifactTransformer {
/**
* 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);
}
}
}

View File

@ -21,6 +21,7 @@ package org.apache.maven.lifecycle.internal;
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.prefix.NoPluginFoundForPrefixException;
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;
/**
* <strong>NOTE:</strong> This class is not part of any public api and can be changed or deleted without prior notice.
@ -290,8 +290,9 @@ public class DefaultLifecycleExecutionPlanCalculator implements LifecycleExecuti
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 @@ public class DefaultLifecycleExecutionPlanCalculator implements LifecycleExecuti
try {
lifecycleOverlay = pluginDescriptor.getLifecycleMapping(forkedLifecycle);
} catch (IOException | XmlPullParserException e) {
} catch (IOException | XMLStreamException e) {
throw new PluginDescriptorParsingException(pluginDescriptor.getPlugin(), pluginDescriptor.getSource(), e);
}

View File

@ -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 class ExtensionDescriptorBuilder {
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 class ExtensionDescriptorBuilder {
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);
}

View File

@ -144,6 +144,9 @@ under the License.
<exportedArtifact>org.apache.maven:maven-api-toolchain</exportedArtifact>
<exportedArtifact>org.apache.maven:maven-api-xml</exportedArtifact>
<exportedArtifact>com.fasterxml:aalto-xml</exportedArtifact>
<exportedArtifact>org.codehaus.woodstox:stax2-api</exportedArtifact>
<exportedArtifact>classworlds:classworlds</exportedArtifact>
<exportedArtifact>org.codehaus.plexus:plexus-classworlds</exportedArtifact>
<exportedArtifact>org.codehaus.plexus:plexus-component-api</exportedArtifact>

View File

@ -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 java.nio.file.Paths;
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 @@ class DefaultBeanConfiguratorPathTest {
private Xpp3Dom toConfig(String xml) {
try {
return new Xpp3Dom(XmlNodeBuilder.build(new StringReader("<configuration>" + xml + "</configuration>")));
} catch (XmlPullParserException | IOException e) {
return new Xpp3Dom(XmlNodeBuilder.build(
new StringReader("<configuration>" + xml + "</configuration>"),
(XmlNodeBuilder.InputLocationBuilderStax) null));
} catch (XMLStreamException e) {
throw new IllegalArgumentException(e);
}
}

View File

@ -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 @@ class DefaultBeanConfiguratorTest {
private Xpp3Dom toConfig(String xml) {
try {
return new Xpp3Dom(XmlNodeBuilder.build(new StringReader("<configuration>" + xml + "</configuration>")));
} catch (XmlPullParserException | IOException e) {
return new Xpp3Dom(XmlNodeBuilder.build(
new StringReader("<configuration>" + xml + "</configuration>"),
(XmlNodeBuilder.InputLocationBuilderStax) null));
} catch (XMLStreamException e) {
throw new IllegalArgumentException(e);
}
}

View File

@ -105,7 +105,7 @@ class ProjectBuilderTest extends AbstractCoreMavenComponentTestCase {
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 @@ class ProjectBuilderTest extends AbstractCoreMavenComponentTestCase {
// 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 @@ class ProjectBuilderTest extends AbstractCoreMavenComponentTestCase {
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

View File

@ -178,14 +178,22 @@ under the License.
<models>
<model>src/main/mdo/core-extensions.mdo</model>
</models>
<templates>
<template>model.vm</template>
<template>reader-stax.vm</template>
<template>writer-stax.vm</template>
</templates>
<params>
<param>packageModelV4=org.apache.maven.cli.internal.extension.model</param>
<param>packageToolV4=org.apache.maven.cli.internal.extension.io</param>
</params>
<velocityBasedir>${project.basedir}/../src/mdo</velocityBasedir>
</configuration>
<executions>
<execution>
<id>modello</id>
<goals>
<goal>java</goal>
<goal>xpp3-reader</goal>
<goal>xpp3-writer</goal>
<goal>velocity</goal>
</goals>
</execution>
</executions>

View File

@ -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.configuration.SettingsXmlConfigurationProcessor;
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.BasicInterpolator;
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 @@ public class MavenCli {
}
private List<CoreExtension> 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();
}
}

View File

@ -20,12 +20,12 @@ package org.apache.maven.model.building;
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 @@ import org.codehaus.plexus.util.xml.pull.XmlPullParser;
@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);

View File

@ -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 @@ import org.codehaus.plexus.util.xml.pull.XmlPullParser;
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;
}

View File

@ -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;
}

View File

@ -21,11 +21,16 @@ package org.apache.maven.model.io;
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.InputSource;
import org.apache.maven.model.Model;
import org.apache.maven.model.building.ModelSourceTransformer;
import org.apache.maven.model.building.TransformerContext;
import org.apache.maven.model.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 class DefaultModelReader implements ModelReader {
public Model read(File input, Map<String, ?> 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 class DefaultModelReader implements ModelReader {
public Model read(InputStream input, Map<String, ?> 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 @@ public class DefaultModelReader implements ModelReader {
return (TransformerContext) value;
}
private Model read(Reader reader, Path pomFile, Map<String, ?> options) throws IOException {
private Model read(InputStream input, Path pomFile, Map<String, ?> 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 @@ public class DefaultModelReader implements ModelReader {
} 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 @@ public class DefaultModelReader implements ModelReader {
}
}
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<String, ?> 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())));
}

View File

@ -23,6 +23,7 @@ import javax.inject.Singleton;
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.PluginExecution;
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 class DefaultPluginConfigurationExpander implements PluginConfigurationEx
private void expand(List<Plugin> 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));
}
}
}

View File

@ -21,13 +21,13 @@ package org.apache.maven.model.plugin;
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 class DefaultReportConfigurationExpander implements ReportConfigurationEx
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));
}
}
}

View File

@ -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 class DefaultRootLocator implements RootLocator {
// 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

View File

@ -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.building.TransformerException;
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;
}

View File

@ -32,6 +32,14 @@ under the License.
<groupId>org.codehaus.plexus</groupId>
<artifactId>plexus-xml</artifactId>
</dependency>
<dependency>
<groupId>org.codehaus.woodstox</groupId>
<artifactId>stax2-api</artifactId>
</dependency>
<dependency>
<groupId>com.fasterxml.woodstox</groupId>
<artifactId>woodstox-core</artifactId>
</dependency>
<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter-params</artifactId>

View File

@ -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 class BuildToRawPomXMLFilterFactory {
*
* @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());

View File

@ -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<String, String> 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 @@ class CiFriendlyXMLFilter extends NodeBufferingParser {
@Override
protected void process(List<Event> 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);

View File

@ -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 @@ class FastForwardFilter extends BufferingParser {
}
}
state.add(localName);
} else if (xmlPullParser.getEventType() == END_TAG) {
} else if (delegate.getEventType() == END_ELEMENT) {
if (domDepth > 0) {
if (--domDepth == 0) {
bypass(false);

View File

@ -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<Event> 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;
}
}
}

View File

@ -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 @@ import org.codehaus.plexus.util.xml.pull.XmlPullParser;
* @since 4.0.0
*/
class ModulesXMLFilter extends NodeBufferingParser {
ModulesXMLFilter(XmlPullParser xmlPullParser) {
super(xmlPullParser, "modules");
ModulesXMLFilter(XMLStreamReader delegate) {
super(delegate, "modules");
}
protected void process(List<Event> buffer) {

View File

@ -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.Optional;
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;
/**
* <p>
@ -54,8 +55,8 @@ class ParentXMLFilter extends NodeBufferingParser {
* @param relativePathMapper
*/
ParentXMLFilter(
XmlPullParser parser, Function<Path, Optional<RelativeProject>> relativePathMapper, Path projectPath) {
super(parser, "parent");
XMLStreamReader delegate, Function<Path, Optional<RelativeProject>> relativePathMapper, Path projectPath) {
super(delegate, "parent");
this.relativePathMapper = relativePathMapper;
this.projectPath = projectPath;
}
@ -71,11 +72,11 @@ class ParentXMLFilter extends NodeBufferingParser {
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 @@ class ParentXMLFilter extends NodeBufferingParser {
} 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<RelativeProject> resolvedParent;
if (!hasVersion && (!hasRelativePath || relativePath != null)) {
Path relPath = Paths.get(Objects.toString(relativePath, "../pom.xml"));
@ -98,23 +99,23 @@ class ParentXMLFilter extends NodeBufferingParser {
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;

View File

@ -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 class RawToConsumerPomXMLFilterFactory {
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);

View File

@ -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<String, String, String> reactorVersionMapper) {
super(xmlPullParser, "dependency");
XMLStreamReader delegate, BiFunction<String, String, String> reactorVersionMapper) {
super(delegate, "dependency");
this.reactorVersionMapper = reactorVersionMapper;
}
@ -52,10 +53,10 @@ public class ReactorDependencyXMLFilter extends NodeBufferingParser {
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 @@ public class ReactorDependencyXMLFilter extends NodeBufferingParser {
} 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;

View File

@ -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<Event> 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) {

View File

@ -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 @@ import org.codehaus.plexus.util.xml.pull.XmlPullParserException;
* @since 4.0.0
*/
class RootXMLFilter extends BufferingParser {
RootXMLFilter(XmlPullParser xmlPullParser) {
super(xmlPullParser);
final Deque<String> 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 @@ class RootXMLFilter extends BufferingParser {
pushEvent(event);
return false;
}
} else if (delegate.getEventType() == END_ELEMENT) {
elements.pop();
}
return true;
}

View File

@ -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<Event> 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;
}
}
}

View File

@ -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;
}
}

View File

@ -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<Event> 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;
}
}
}

View File

@ -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,32 +39,30 @@ 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) {
protected boolean accept() throws XMLStreamException {
if (!buffering && delegate.getEventType() == START_ELEMENT && nodeName.equals(delegate.getLocalName())) {
buffer.add(bufferEvent());
buffering = true;
return false;
}
if (xmlPullParser.getEventType() == END_TAG && buffering) {
} 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;
}
}
@Override
public boolean bypass() {

View File

@ -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<Integer> 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();
}
}

View File

@ -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();
}
}

View File

@ -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");

View File

@ -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<Path, Optional<RelativeProject>> getRelativePathMapper() {
@ -59,7 +60,7 @@ class ConsumerPomXMLFilterTest extends AbstractXMLFilterTests {
}
};
XmlPullParser parser =
XMLStreamReader parser =
new RawToConsumerPomXMLFilterFactory(buildPomXMLFilterFactory).get(orgParser, Paths.get("pom.xml"));
return parser;
}

View File

@ -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);
}

View File

@ -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 @@ import static org.xmlunit.assertj.XmlAssert.assertThat;
class ModulesXMLFilterTest extends AbstractXMLFilterTests {
@Override
protected ModulesXMLFilter getFilter(XmlPullParser parser) {
protected ModulesXMLFilter getFilter(XMLStreamReader parser) {
return new ModulesXMLFilter(parser);
}

View File

@ -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<XmlPullParser, XmlPullParser> filterCreator;
private Function<XMLStreamReader, XMLStreamReader> filterCreator;
@BeforeEach
void reset() {
@ -38,21 +39,21 @@ class ParentXMLFilterTest extends AbstractXMLFilterTests {
}
@Override
protected XmlPullParser getFilter(XmlPullParser parser) {
Function<XmlPullParser, XmlPullParser> filterCreator =
protected XMLStreamReader getFilter(XMLStreamReader parser) {
Function<XMLStreamReader, XMLStreamReader> 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<Path, Optional<RelativeProject>> pathMapper, Path projectPath) {
protected XMLStreamReader createFilter(
XMLStreamReader parser, Function<Path, Optional<RelativeProject>> pathMapper, Path projectPath) {
return new ParentXMLFilter(new FastForwardFilter(parser), pathMapper, projectPath);
}
@ -154,12 +155,12 @@ class ParentXMLFilterTest extends AbstractXMLFilterTests {
+ " <artifactId>ARTIFACTID</artifactId>\n"
+ " </parent>\n"
+ "</project>";
String expected = "<project>" + System.lineSeparator()
+ " <parent>" + System.lineSeparator()
+ " <groupId>GROUPID</groupId>" + System.lineSeparator()
+ " <artifactId>ARTIFACTID</artifactId>" + System.lineSeparator()
+ " <version>1.0.0</version>" + System.lineSeparator()
+ " </parent>" + System.lineSeparator()
String expected = "<project>\n"
+ " <parent>\n"
+ " <groupId>GROUPID</groupId>\n"
+ " <artifactId>ARTIFACTID</artifactId>\n"
+ " <version>1.0.0</version>\n"
+ " </parent>\n"
+ "</project>";
String actual = transform(input);
@ -299,13 +300,13 @@ class ParentXMLFilterTest extends AbstractXMLFilterTests {
+ " <!--version here-->\n"
+ " </parent>\n"
+ "</project>";
String expected = "<project>" + System.lineSeparator()
+ " <parent>" + System.lineSeparator()
+ " <groupId>GROUPID</groupId>" + System.lineSeparator()
+ " <artifactId>ARTIFACTID</artifactId>" + System.lineSeparator()
+ " <!--version here-->" + System.lineSeparator()
+ " <version>1.0.0</version>" + System.lineSeparator()
+ " </parent>" + System.lineSeparator()
String expected = "<project>\n"
+ " <parent>\n"
+ " <groupId>GROUPID</groupId>\n"
+ " <artifactId>ARTIFACTID</artifactId>\n"
+ " <!--version here-->\n"
+ " <version>1.0.0</version>\n"
+ " </parent>\n"
+ "</project>";
String actual = transform(input);

View File

@ -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 @@ class ReactorDependencyXMLFilterTest extends AbstractXMLFilterTests {
}
@Override
protected ReactorDependencyXMLFilter getFilter(XmlPullParser parser) {
protected ReactorDependencyXMLFilter getFilter(XMLStreamReader parser) {
return new ReactorDependencyXMLFilter(
parser, reactorVersionMapper != null ? reactorVersionMapper : (g, a) -> "1.0.0");
}

View File

@ -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);
}

View File

@ -46,6 +46,22 @@ under the License.
<groupId>org.codehaus.plexus</groupId>
<artifactId>plexus-xml</artifactId>
</dependency>
<dependency>
<groupId>org.openjdk.jmh</groupId>
<artifactId>jmh-core</artifactId>
<version>1.36</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.openjdk.jmh</groupId>
<artifactId>jmh-generator-annprocess</artifactId>
<version>1.36</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>com.fasterxml.woodstox</groupId>
<artifactId>woodstox-core</artifactId>
</dependency>
</dependencies>
<build>
@ -61,6 +77,7 @@ under the License.
<model>src/main/mdo/maven.mdo</model>
</models>
<params>
<param>forcedIOModelVersion=4.0.0</param>
<param>packageModelV3=org.apache.maven.model</param>
<param>packageModelV4=org.apache.maven.api.model</param>
<param>packageToolV4=org.apache.maven.model.v4</param>
@ -104,6 +121,8 @@ under the License.
<template>reader-ex.vm</template>
<template>writer.vm</template>
<template>writer-ex.vm</template>
<template>reader-stax.vm</template>
<template>writer-stax.vm</template>
</templates>
</configuration>
</execution>

View File

@ -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.LinkedHashMap;
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 @@ class ModelXmlTest {
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));
}
}

View File

@ -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;
/**
* <p>Xpp3DomPerfTest class.</p>
*/
@BenchmarkMode(Mode.AverageTime)
@OutputTimeUnit(TimeUnit.MILLISECONDS)
@Warmup(iterations = 3)
@Measurement(time = 10)
public class Xpp3DomPerfTest {
@State(Scope.Benchmark)
public static class AdditionState {
List<Path> 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;
}
/**
* <p>main.</p>
*
* @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();
}
}

View File

@ -78,11 +78,14 @@ under the License.
<template>model.vm</template>
<template>reader.vm</template>
<template>writer.vm</template>
<template>reader-stax.vm</template>
<template>writer-stax.vm</template>
</templates>
<params>
<param>packageModelV3=org.apache.maven.plugin.lifecycle</param>
<param>packageModelV4=org.apache.maven.plugin.lifecycle</param>
<param>packageToolV4=org.apache.maven.plugin.lifecycle.io.xpp3</param>
<param>packageToolV4=org.apache.maven.plugin.lifecycle.io</param>
<param>packageToolV4Xpp3=org.apache.maven.plugin.lifecycle.io.xpp3</param>
</params>
</configuration>
</execution>

View File

@ -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.artifact.ArtifactUtils;
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 class PluginDescriptor extends ComponentSetDescriptor implements Cloneabl
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 @@ public class PluginDescriptor extends ComponentSetDescriptor implements Cloneabl
throw new IllegalStateException(e);
}
} else {
return new FileInputStream(new File(pluginFile, descriptor));
return Files.newInputStream(new File(pluginFile, descriptor).toPath());
}
}

View File

@ -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 class PluginDescriptorBuilder {
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);
}
}

View File

@ -36,6 +36,14 @@ under the License.
<groupId>org.codehaus.plexus</groupId>
<artifactId>plexus-xml</artifactId>
</dependency>
<dependency>
<groupId>org.apache.maven</groupId>
<artifactId>maven-xml-impl</artifactId>
</dependency>
<dependency>
<groupId>com.fasterxml.woodstox</groupId>
<artifactId>woodstox-core</artifactId>
</dependency>
<dependency>
<groupId>org.apache.maven.resolver</groupId>
<artifactId>maven-resolver-api</artifactId>
@ -49,19 +57,50 @@ under the License.
<groupId>org.codehaus.modello</groupId>
<artifactId>modello-maven-plugin</artifactId>
<configuration>
<version>1.1.0</version>
<version>1.2.0</version>
<models>
<model>src/main/mdo/metadata.mdo</model>
</models>
<params>
<param>forcedIOModelVersion=1.1.0</param>
<param>packageModelV3=org.apache.maven.artifact.repository.metadata</param>
<param>packageModelV4=org.apache.maven.artifact.repository.metadata.v4</param>
<param>packageToolV4=org.apache.maven.artifact.repository.metadata.io</param>
</params>
<velocityBasedir>${project.basedir}/../src/mdo</velocityBasedir>
</configuration>
<executions>
<execution>
<id>modello</id>
<goals>
<goal>java</goal>
<goal>xpp3-reader</goal>
<goal>xpp3-writer</goal>
<goal>velocity</goal>
</goals>
<configuration>
<version>1.2.0</version>
<models>
<model>src/main/mdo/metadata.mdo</model>
</models>
<templates>
<template>model.vm</template>
<template>reader-stax.vm</template>
<template>writer-stax.vm</template>
</templates>
</configuration>
</execution>
<execution>
<id>modello-v3</id>
<goals>
<goal>velocity</goal>
</goals>
<configuration>
<version>1.1.0</version>
<models>
<model>src/main/mdo/metadata.mdo</model>
</models>
<templates>
<template>model-v3.vm</template>
</templates>
</configuration>
</execution>
</executions>
</plugin>

View File

@ -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);
}
}

View File

@ -19,7 +19,7 @@ under the License.
<model xmlns="http://codehaus-plexus.github.io/MODELLO/1.4.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://codehaus-plexus.github.io/MODELLO/1.4.0 http://codehaus-plexus.github.io/modello/xsd/modello-1.4.0.xsd"
xsd.namespace="http://maven.apache.org/METADATA/${version}"
xml.namespace="http://maven.apache.org/METADATA/${version}"
xml.schemaLocation="https://maven.apache.org/xsd/repository-metadata-${version}.xsd">
<id>repository-metadata</id>
<name>Metadata</name>
@ -35,11 +35,11 @@ under the License.
</default>
</defaults>
<classes>
<class rootElement="true" java.clone="deep">
<class rootElement="true" xml.tagName="metadata" java.clone="deep">
<name>Metadata</name>
<version>1.0.0+</version>
<fields>
<field xml.attribute="true">
<field xml.attribute="true" xml.tagName="modelVersion">
<name>modelVersion</name>
<version>1.1.0+</version>
<type>String</type>
@ -86,7 +86,7 @@ under the License.
</fields>
<codeSegments>
<codeSegment>
<version>1.0.0+</version>
<version>1.0.0/1.1.0</version>
<code><![CDATA[
private String getSnapshotVersionKey( SnapshotVersion sv )
{
@ -299,7 +299,7 @@ under the License.
</fields>
<codeSegments>
<codeSegment>
<version>1.0.0+</version>
<version>1.0.0/1.1.0</version>
<code><![CDATA[
public void updateTimestamp()
{

View File

@ -18,12 +18,21 @@
*/
package org.apache.maven.artifact.repository.metadata;
import javax.xml.stream.XMLInputFactory;
import javax.xml.stream.XMLOutputFactory;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.GregorianCalendar;
import java.util.TimeZone;
import com.ctc.wstx.stax.WstxInputFactory;
import com.ctc.wstx.stax.WstxOutputFactory;
import org.apache.maven.artifact.repository.metadata.io.MetadataStaxReader;
import org.apache.maven.artifact.repository.metadata.io.MetadataStaxWriter;
import org.eclipse.aether.artifact.Artifact;
import org.eclipse.aether.artifact.DefaultArtifact;
import org.junit.jupiter.api.BeforeEach;
@ -31,6 +40,7 @@ import org.junit.jupiter.api.Test;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertFalse;
import static org.junit.jupiter.api.Assertions.assertNotNull;
import static org.junit.jupiter.api.Assertions.assertTrue;
class MetadataTest {
@ -209,6 +219,22 @@ class MetadataTest {
}
/*-- END test "groupId/artifactId/version" metadata ---*/
@Test
void testRoundtrip() throws Exception {
System.setProperty(XMLInputFactory.class.getName(), WstxInputFactory.class.getName());
System.setProperty(XMLOutputFactory.class.getName(), WstxOutputFactory.class.getName());
Metadata source = new Metadata(org.apache.maven.artifact.repository.metadata.v4.Metadata.newBuilder(
createMetadataFromArtifact(artifact).getDelegate(), true)
.modelEncoding("UTF-16")
.build());
ByteArrayOutputStream baos = new ByteArrayOutputStream();
new MetadataStaxWriter().write(baos, source.getDelegate());
Metadata source2 =
new Metadata(new MetadataStaxReader().read(new ByteArrayInputStream(baos.toByteArray()), true));
assertNotNull(source2);
}
/*-- START helper methods to populate metadata objects ---*/
private static final String SNAPSHOT = "SNAPSHOT";

View File

@ -22,8 +22,8 @@ import javax.inject.Inject;
import javax.inject.Named;
import javax.inject.Singleton;
import java.io.FileInputStream;
import java.io.InputStream;
import java.nio.file.Files;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
@ -33,7 +33,7 @@ import java.util.Objects;
import org.apache.maven.artifact.ArtifactUtils;
import org.apache.maven.artifact.repository.metadata.Versioning;
import org.apache.maven.artifact.repository.metadata.io.xpp3.MetadataXpp3Reader;
import org.apache.maven.artifact.repository.metadata.io.MetadataStaxReader;
import org.eclipse.aether.RepositoryEvent;
import org.eclipse.aether.RepositoryEvent.EventType;
import org.eclipse.aether.RepositorySystemSession;
@ -202,9 +202,10 @@ public class DefaultVersionRangeResolver implements VersionRangeResolver {
syncContext.acquire(null, Collections.singleton(metadata));
if (metadata.getFile() != null && metadata.getFile().exists()) {
try (InputStream in = new FileInputStream(metadata.getFile())) {
versioning =
new MetadataXpp3Reader().read(in, false).getVersioning();
try (InputStream in =
Files.newInputStream(metadata.getFile().toPath())) {
versioning = new Versioning(
new MetadataStaxReader().read(in, false).getVersioning());
}
}
}

View File

@ -23,9 +23,9 @@ import javax.inject.Named;
import javax.inject.Singleton;
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.Collections;
import java.util.HashMap;
@ -36,7 +36,7 @@ import java.util.Objects;
import org.apache.maven.artifact.repository.metadata.Snapshot;
import org.apache.maven.artifact.repository.metadata.SnapshotVersion;
import org.apache.maven.artifact.repository.metadata.Versioning;
import org.apache.maven.artifact.repository.metadata.io.xpp3.MetadataXpp3Reader;
import org.apache.maven.artifact.repository.metadata.io.MetadataStaxReader;
import org.codehaus.plexus.util.StringUtils;
import org.eclipse.aether.RepositoryCache;
import org.eclipse.aether.RepositoryEvent;
@ -245,9 +245,10 @@ public class DefaultVersionResolver implements VersionResolver {
syncContext.acquire(null, Collections.singleton(metadata));
if (metadata.getFile() != null && metadata.getFile().exists()) {
try (InputStream in = new FileInputStream(metadata.getFile())) {
versioning =
new MetadataXpp3Reader().read(in, false).getVersioning();
try (InputStream in =
Files.newInputStream(metadata.getFile().toPath())) {
versioning = new Versioning(
new MetadataStaxReader().read(in, false).getVersioning());
/*
NOTE: Users occasionally misuse the id "local" for remote repos which screws up the metadata

View File

@ -18,20 +18,20 @@
*/
package org.apache.maven.repository.internal;
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 java.util.Collections;
import java.util.Date;
import java.util.Map;
import org.apache.maven.artifact.repository.metadata.Metadata;
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;
import org.eclipse.aether.RepositoryException;
import org.eclipse.aether.metadata.AbstractMetadata;
import org.eclipse.aether.metadata.MergeableMetadata;
@ -86,20 +86,18 @@ abstract class MavenMetadata extends AbstractMetadata implements MergeableMetada
return new Metadata();
}
try (Reader reader = ReaderFactory.newXmlReader(metadataFile)) {
return new MetadataXpp3Reader().read(reader, false);
} catch (IOException e) {
throw new RepositoryException("Could not read metadata " + metadataFile + ": " + e.getMessage(), e);
} catch (XmlPullParserException e) {
try (InputStream input = Files.newInputStream(metadataFile.toPath())) {
return new Metadata(new MetadataStaxReader().read(input, false));
} catch (IOException | XMLStreamException e) {
throw new RepositoryException("Could not parse metadata " + metadataFile + ": " + e.getMessage(), e);
}
}
private void write(File metadataFile, Metadata metadata) throws RepositoryException {
metadataFile.getParentFile().mkdirs();
try (Writer writer = WriterFactory.newXmlWriter(metadataFile)) {
new MetadataXpp3Writer().write(writer, metadata);
} catch (IOException e) {
try (OutputStream output = Files.newOutputStream(metadataFile.toPath())) {
new MetadataStaxWriter().write(output, metadata.getDelegate());
} catch (IOException | XMLStreamException e) {
throw new RepositoryException("Could not write metadata " + metadataFile + ": " + e.getMessage(), e);
}
}

View File

@ -20,6 +20,7 @@ package org.apache.maven.settings.io;
import javax.inject.Named;
import javax.inject.Singleton;
import javax.xml.stream.XMLStreamException;
import java.io.File;
import java.io.IOException;
@ -31,8 +32,7 @@ import java.util.Objects;
import org.apache.maven.api.settings.InputSource;
import org.apache.maven.settings.Settings;
import org.apache.maven.settings.v4.SettingsXpp3ReaderEx;
import org.codehaus.plexus.util.xml.pull.XmlPullParserException;
import org.apache.maven.settings.v4.SettingsStaxReader;
/**
* Handles deserialization of settings from the default textual format.
@ -49,9 +49,13 @@ public class DefaultSettingsReader implements SettingsReader {
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 class DefaultSettingsReader implements SettingsReader {
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 class DefaultSettingsReader implements SettingsReader {
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);
}
}

View File

@ -20,18 +20,18 @@ package org.apache.maven.settings.io;
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 class DefaultSettingsWriter implements SettingsWriter {
output.getParentFile().mkdirs();
write(new XmlStreamWriter(output), options, settings);
write(Files.newOutputStream(output.toPath()), options, settings);
}
@Override
@ -58,7 +58,9 @@ public class DefaultSettingsWriter implements SettingsWriter {
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 class DefaultSettingsWriter implements SettingsWriter {
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);
}
}
}

View File

@ -46,6 +46,10 @@ under the License.
<groupId>org.codehaus.plexus</groupId>
<artifactId>plexus-xml</artifactId>
</dependency>
<dependency>
<groupId>com.fasterxml.woodstox</groupId>
<artifactId>woodstox-core</artifactId>
</dependency>
</dependencies>
<build>
@ -61,6 +65,7 @@ under the License.
<model>src/main/mdo/settings.mdo</model>
</models>
<params>
<param>forcedIOModelVersion=1.2.0</param>
<param>packageModelV3=org.apache.maven.settings</param>
<param>packageModelV4=org.apache.maven.api.settings</param>
<param>packageToolV4=org.apache.maven.settings.v4</param>
@ -78,9 +83,9 @@ under the License.
<template>merger.vm</template>
<template>transformer.vm</template>
<template>reader.vm</template>
<template>reader-ex.vm</template>
<template>writer.vm</template>
<template>writer-ex.vm</template>
<template>reader-stax.vm</template>
<template>writer-stax.vm</template>
</templates>
<params combine.children="append">
<param>locationTracking=true</param>

View File

@ -28,6 +28,7 @@ import org.codehaus.plexus.util.xml.pull.MXParser;
import org.codehaus.plexus.util.xml.pull.XmlPullParser;
import org.codehaus.plexus.util.xml.pull.XmlPullParserException;
@Deprecated
public class SettingsXpp3Reader {
private boolean addDefaultEntities = true;

View File

@ -24,6 +24,7 @@ import java.io.Writer;
import org.apache.maven.settings.Settings;
@Deprecated
public class SettingsXpp3Writer {
// --------------------------/
// - Class/Member Variables -/

View File

@ -20,6 +20,7 @@ package org.apache.maven.toolchain.io;
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.Map;
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 class DefaultToolchainsReader implements ToolchainsReader {
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 class DefaultToolchainsReader implements ToolchainsReader {
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 class DefaultToolchainsReader implements ToolchainsReader {
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);
}
}

View File

@ -20,6 +20,7 @@ package org.apache.maven.toolchain.io;
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.Map;
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 class DefaultToolchainsWriter implements ToolchainsWriter {
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);
}
}
}

View File

@ -1,4 +1,4 @@
<?xml version="1.0" encoding="UTF8"?>
<?xml version="1.0" encoding="UTF-8"?>
<!--
Licensed to the Apache Software Foundation (ASF) under one

View File

@ -1,4 +1,4 @@
<?xml version="1.0" encoding="UTF8"?>
<?xml version="1.0" encoding="UTF-8"?>
<!--
Licensed to the Apache Software Foundation (ASF) under one

View File

@ -1,4 +1,4 @@
<?xml version="1.0" encoding="UTF8"?>
<?xml version="1.0" encoding="UTF-8"?>
<!--
Licensed to the Apache Software Foundation (ASF) under one

View File

@ -45,6 +45,10 @@ under the License.
<groupId>org.codehaus.plexus</groupId>
<artifactId>plexus-xml</artifactId>
</dependency>
<dependency>
<groupId>com.fasterxml.woodstox</groupId>
<artifactId>woodstox-core</artifactId>
</dependency>
</dependencies>
<build>
@ -71,8 +75,8 @@ under the License.
<templates>
<template>model-v3.vm</template>
<template>merger.vm</template>
<template>reader.vm</template>
<template>writer.vm</template>
<template>reader-stax.vm</template>
<template>writer-stax.vm</template>
</templates>
<params>
<param>packageModelV3=org.apache.maven.toolchain.model</param>

View File

@ -39,6 +39,10 @@ under the License.
<groupId>org.eclipse.sisu</groupId>
<artifactId>org.eclipse.sisu.plexus</artifactId>
</dependency>
<dependency>
<groupId>com.fasterxml.woodstox</groupId>
<artifactId>woodstox-core</artifactId>
</dependency>
<dependency>
<groupId>org.codehaus.plexus</groupId>
<artifactId>plexus-xml</artifactId>

View File

@ -18,6 +18,9 @@
*/
package org.apache.maven.internal.xml;
import javax.xml.stream.XMLStreamException;
import javax.xml.stream.XMLStreamReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.Reader;
@ -26,6 +29,7 @@ import java.util.HashMap;
import java.util.List;
import java.util.Map;
import com.ctc.wstx.stax.WstxInputFactory;
import org.apache.maven.api.xml.XmlNode;
import org.codehaus.plexus.util.xml.pull.MXParser;
import org.codehaus.plexus.util.xml.pull.XmlPullParser;
@ -39,7 +43,7 @@ public class XmlNodeBuilder {
private static final boolean DEFAULT_TRIM = true;
public static XmlNodeImpl build(Reader reader) throws XmlPullParserException, IOException {
return build(reader, null);
return build(reader, (InputLocationBuilder) null);
}
/**
@ -155,6 +159,90 @@ public class XmlNodeBuilder {
throw new IllegalStateException("End of document found before returning to 0 depth");
}
public static XmlNodeImpl build(Reader reader, InputLocationBuilderStax locationBuilder) throws XMLStreamException {
XMLStreamReader parser = WstxInputFactory.newFactory().createXMLStreamReader(reader);
return build(parser, DEFAULT_TRIM, locationBuilder);
}
public static XmlNodeImpl build(XMLStreamReader parser) throws XMLStreamException {
return build(parser, DEFAULT_TRIM, null);
}
public static XmlNodeImpl build(XMLStreamReader parser, InputLocationBuilderStax locationBuilder)
throws XMLStreamException {
return build(parser, DEFAULT_TRIM, locationBuilder);
}
public static XmlNodeImpl build(XMLStreamReader parser, boolean trim, InputLocationBuilderStax locationBuilder)
throws XMLStreamException {
boolean spacePreserve = false;
String name = null;
String value = null;
Object location = null;
Map<String, String> attrs = null;
List<XmlNode> children = null;
int eventType = parser.getEventType();
int lastStartTag = -1;
while (eventType != XMLStreamReader.END_DOCUMENT) {
if (eventType == XMLStreamReader.START_ELEMENT) {
lastStartTag = parser.getLocation().getLineNumber() * 1000
+ parser.getLocation().getColumnNumber();
if (name == null) {
int namespacesSize = parser.getNamespaceCount();
name = parser.getLocalName();
String pfx = parser.getPrefix();
if (pfx != null && !pfx.isEmpty()) {
name = pfx + ":" + name;
}
location = locationBuilder != null ? locationBuilder.toInputLocation(parser) : null;
int attributesSize = parser.getAttributeCount();
if (attributesSize > 0 || namespacesSize > 0) {
attrs = new HashMap<>();
for (int i = 0; i < namespacesSize; i++) {
String prefix = parser.getNamespacePrefix(i);
String namespace = parser.getNamespaceURI(i);
attrs.put("xmlns:" + prefix, namespace);
}
for (int i = 0; i < attributesSize; i++) {
String aname = parser.getAttributeLocalName(i);
String avalue = parser.getAttributeValue(i);
String apfx = parser.getAttributePrefix(i);
if (apfx != null && !apfx.isEmpty()) {
aname = apfx + ":" + aname;
}
attrs.put(aname, avalue);
spacePreserve = spacePreserve || ("xml:space".equals(aname) && "preserve".equals(avalue));
}
}
} else {
if (children == null) {
children = new ArrayList<>();
}
XmlNode child = build(parser, trim, locationBuilder);
children.add(child);
}
} else if (eventType == XMLStreamReader.CHARACTERS || eventType == XMLStreamReader.CDATA) {
String text = parser.getText();
value = value != null ? value + text : text;
} else if (eventType == XMLStreamReader.END_ELEMENT) {
boolean emptyTag = lastStartTag
== parser.getLocation().getLineNumber() * 1000
+ parser.getLocation().getColumnNumber();
if (value != null && trim && !spacePreserve) {
value = value.trim();
}
return new XmlNodeImpl(
name,
children == null ? (value != null ? value : emptyTag ? null : "") : null,
attrs,
children,
location);
}
eventType = parser.next();
}
throw new IllegalStateException("End of document found before returning to 0 depth");
}
/**
* Input location builder interface, to be implemented to choose how to store data.
*
@ -163,4 +251,8 @@ public class XmlNodeBuilder {
public interface InputLocationBuilder {
Object toInputLocation(XmlPullParser parser);
}
public interface InputLocationBuilderStax {
Object toInputLocation(XMLStreamReader parser);
}
}

View File

@ -18,7 +18,11 @@
*/
package org.apache.maven.internal.xml;
import javax.xml.stream.XMLStreamException;
import javax.xml.stream.XMLStreamReader;
import java.io.IOException;
import java.io.Reader;
import java.io.StringReader;
import java.util.ArrayList;
import java.util.HashMap;
@ -29,8 +33,6 @@ import java.util.stream.Collectors;
import org.apache.maven.api.xml.XmlNode;
import org.codehaus.plexus.util.xml.Xpp3Dom;
import org.codehaus.plexus.util.xml.Xpp3DomBuilder;
import org.codehaus.plexus.util.xml.pull.XmlPullParser;
import org.codehaus.plexus.util.xml.pull.XmlPullParserException;
import org.junit.jupiter.api.Test;
import static org.junit.jupiter.api.Assertions.assertEquals;
@ -241,7 +243,7 @@ class XmlNodeImplTest {
}
@Test
void testPreserveDominantBlankValue() throws XmlPullParserException, IOException {
void testPreserveDominantBlankValue() throws XMLStreamException, IOException {
String lhs = "<parameter xml:space=\"preserve\"> </parameter>";
String rhs = "<parameter>recessive</parameter>";
@ -254,7 +256,7 @@ class XmlNodeImplTest {
}
@Test
void testPreserveDominantEmptyNode() throws XmlPullParserException, IOException {
void testPreserveDominantEmptyNode() throws XMLStreamException, IOException {
String lhs = "<parameter></parameter>";
String rhs = "<parameter>recessive</parameter>";
@ -267,7 +269,7 @@ class XmlNodeImplTest {
}
@Test
void testPreserveDominantEmptyNode2() throws XmlPullParserException, IOException {
void testPreserveDominantEmptyNode2() throws XMLStreamException, IOException {
String lhs = "<parameter/>";
String rhs = "<parameter>recessive</parameter>";
@ -442,14 +444,11 @@ class XmlNodeImplTest {
/**
* <p>testEqualsIsNullSafe.</p>
*
* @throws org.codehaus.plexus.util.xml.pull.XmlPullParserException if any.
* @throws java.io.IOException if any.
*/
@Test
void testEqualsIsNullSafe() throws XmlPullParserException, IOException {
void testEqualsIsNullSafe() throws XMLStreamException, IOException {
String testDom = "<configuration><items thing='blah'><item>one</item><item>two</item></items></configuration>";
Xpp3Dom dom = Xpp3DomBuilder.build(new StringReader(testDom));
XmlNode dom = toXmlNode(testDom);
Map<String, String> attributes = new HashMap<>();
attributes.put("nullValue", null);
@ -464,19 +463,14 @@ class XmlNodeImplTest {
/**
* <p>testShouldOverwritePluginConfigurationSubItemsByDefault.</p>
*
* @throws org.codehaus.plexus.util.xml.pull.XmlPullParserException if any.
* @throws java.io.IOException if any.
*/
@Test
void testShouldOverwritePluginConfigurationSubItemsByDefault() throws XmlPullParserException, IOException {
void testShouldOverwritePluginConfigurationSubItemsByDefault() throws XMLStreamException, IOException {
String parentConfigStr = "<configuration><items><item>one</item><item>two</item></items></configuration>";
XmlNode parentConfig =
XmlNodeBuilder.build(new StringReader(parentConfigStr), new FixedInputLocationBuilder("parent"));
XmlNode parentConfig = toXmlNode(parentConfigStr, new FixedInputLocationBuilder("parent"));
String childConfigStr = "<configuration><items><item>three</item></items></configuration>";
XmlNode childConfig =
XmlNodeBuilder.build(new StringReader(childConfigStr), new FixedInputLocationBuilder("child"));
XmlNode childConfig = toXmlNode(childConfigStr, new FixedInputLocationBuilder("child"));
XmlNode result = XmlNode.merge(childConfig, parentConfig);
XmlNode items = result.getChild("items");
@ -490,20 +484,15 @@ class XmlNodeImplTest {
/**
* <p>testShouldMergePluginConfigurationSubItemsWithMergeAttributeSet.</p>
*
* @throws org.codehaus.plexus.util.xml.pull.XmlPullParserException if any.
* @throws java.io.IOException if any.
*/
@Test
void testShouldMergePluginConfigurationSubItemsWithMergeAttributeSet() throws XmlPullParserException, IOException {
void testShouldMergePluginConfigurationSubItemsWithMergeAttributeSet() throws XMLStreamException, IOException {
String parentConfigStr = "<configuration><items><item>one</item><item>two</item></items></configuration>";
XmlNode parentConfig =
XmlNodeBuilder.build(new StringReader(parentConfigStr), new FixedInputLocationBuilder("parent"));
XmlNode parentConfig = toXmlNode(parentConfigStr, new FixedInputLocationBuilder("parent"));
String childConfigStr =
"<configuration><items combine.children=\"append\"><item>three</item></items></configuration>";
XmlNode childConfig =
XmlNodeBuilder.build(new StringReader(childConfigStr), new FixedInputLocationBuilder("child"));
XmlNode childConfig = toXmlNode(childConfigStr, new FixedInputLocationBuilder("child"));
XmlNode result = XmlNode.merge(childConfig, parentConfig);
XmlNode items = result.getChild("items");
@ -562,14 +551,11 @@ class XmlNodeImplTest {
/**
* <p>testDupeChildren.</p>
*
* @throws java.io.IOException if any.
* @throws org.codehaus.plexus.util.xml.pull.XmlPullParserException if any.
*/
@Test
void testDupeChildren() throws IOException, XmlPullParserException {
void testDupeChildren() throws IOException, XMLStreamException {
String dupes = "<configuration><foo>x</foo><foo>y</foo></configuration>";
Xpp3Dom dom = Xpp3DomBuilder.build(new StringReader(dupes));
XmlNode dom = toXmlNode(new StringReader(dupes));
assertNotNull(dom);
assertEquals("y", dom.getChild("foo").getValue());
}
@ -611,7 +597,7 @@ class XmlNodeImplTest {
}
@Test
void testMergeCombineChildrenAppendOnRecessive() throws XmlPullParserException, IOException {
void testMergeCombineChildrenAppendOnRecessive() throws XMLStreamException, IOException {
String dominant = "<relocations>\n" + " <relocation>\n"
+ " <pattern>org.apache.shiro.crypto.CipherService</pattern>\n"
+ " <shadedPattern>org.apache.shiro.crypto.cipher.CipherService</shadedPattern>\n"
@ -634,8 +620,8 @@ class XmlNodeImplTest {
+ " </relocation>\n"
+ "</relocations>";
XmlNodeImpl d = XmlNodeBuilder.build(new StringReader(dominant));
XmlNodeImpl r = XmlNodeBuilder.build(new StringReader(recessive));
XmlNode d = toXmlNode(dominant);
XmlNode r = toXmlNode(recessive);
XmlNode m = d.merge(r);
assertEquals(expected, m.toString().replaceAll("\r\n", "\n"));
}
@ -652,23 +638,32 @@ class XmlNodeImplTest {
.orElse(null);
}
private static XmlNode toXmlNode(String xml) throws XmlPullParserException, IOException {
private static XmlNode toXmlNode(String xml) throws XMLStreamException, IOException {
return toXmlNode(xml, null);
}
private static XmlNode toXmlNode(String xml, XmlNodeBuilder.InputLocationBuilder locationBuilder)
throws XmlPullParserException, IOException {
return XmlNodeBuilder.build(new StringReader(xml), locationBuilder);
private static XmlNode toXmlNode(String xml, XmlNodeBuilder.InputLocationBuilderStax locationBuilder)
throws XMLStreamException, IOException {
return toXmlNode(new StringReader(xml), locationBuilder);
}
private static class FixedInputLocationBuilder implements XmlNodeBuilder.InputLocationBuilder {
private static XmlNode toXmlNode(Reader reader) throws XMLStreamException, IOException {
return toXmlNode(reader, null);
}
private static XmlNode toXmlNode(Reader reader, XmlNodeBuilder.InputLocationBuilderStax locationBuilder)
throws XMLStreamException, IOException {
return XmlNodeBuilder.build(reader, locationBuilder);
}
private static class FixedInputLocationBuilder implements XmlNodeBuilder.InputLocationBuilderStax {
private final Object location;
public FixedInputLocationBuilder(Object location) {
this.location = location;
}
public Object toInputLocation(XmlPullParser parser) {
public Object toInputLocation(XMLStreamReader parser) {
return location;
}
}

10
pom.xml
View File

@ -404,6 +404,16 @@ under the License.
<artifactId>plexus-cipher</artifactId>
<version>${cipherVersion}</version>
</dependency>
<dependency>
<groupId>com.fasterxml.woodstox</groupId>
<artifactId>woodstox-core</artifactId>
<version>6.5.1</version>
</dependency>
<dependency>
<groupId>org.codehaus.woodstox</groupId>
<artifactId>stax2-api</artifactId>
<version>4.2.1</version>
</dependency>
<dependency>
<groupId>org.xmlunit</groupId>
<artifactId>xmlunit-assertj</artifactId>

View File

@ -18,7 +18,11 @@
*#
#parse ( "common.vm" )
#
#if( ${packageToolV4Xpp3} )
#set ( $package = "${packageToolV4Xpp3}" )
#else
#set ( $package = "${packageToolV4}" )
#end
#set ( $className = "${model.name}Xpp3ReaderEx" )
#
#set ( $root = $model.getClass( $model.getRoot($version), $version ) )
@ -59,6 +63,7 @@ import org.codehaus.plexus.util.xml.pull.MXParser;
import org.codehaus.plexus.util.xml.pull.XmlPullParser;
import org.codehaus.plexus.util.xml.pull.XmlPullParserException;
@Deprecated
@Generated
public class ${className} {

View File

@ -18,7 +18,11 @@
*#
#parse ( "common.vm" )
#
#if( ${packageToolV4Xpp3} )
#set ( $package = "${packageToolV4Xpp3}" )
#else
#set ( $package = "${packageToolV4}" )
#end
#set ( $className = "${model.name}Xpp3Reader" )
#
#set ( $root = $model.getClass( $model.getRoot($version), $version ) )
@ -57,6 +61,7 @@ import org.codehaus.plexus.util.xml.pull.MXParser;
import org.codehaus.plexus.util.xml.pull.XmlPullParser;
import org.codehaus.plexus.util.xml.pull.XmlPullParserException;
@Deprecated
@Generated
public class ${className} {

918
src/mdo/reader-stax.vm Normal file
View File

@ -0,0 +1,918 @@
#*
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.
*#
#parse ( "common.vm" )
#
#set ( $package = "${packageToolV4}" )
#set ( $className = "${model.name}StaxReader" )
#
#set ( $root = $model.getClass( $model.getRoot($version), $version ) )
#set ( $rootXml = $Helper.xmlClassMetadata( $root ) )
#set ( $rootTag = $rootXml.tagName )
#set ( $rootUcapName = $Helper.capitalise( $root.name ) )
#set ( $rootLcapName = $Helper.uncapitalise( $root.name ) )
#
#MODELLO-VELOCITY#SAVE-OUTPUT-TO ${package.replace('.','/')}/${className}.java
// =================== DO NOT EDIT THIS FILE ====================
// Generated by Modello Velocity from ${template}
// template, any modifications will be overwritten.
// ==============================================================
package ${package};
import java.io.IOException;
import java.io.InputStream;
import java.io.Reader;
import java.text.DateFormat;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Date;
import java.util.HashMap;
import java.util.HashSet;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;
import org.apache.maven.api.annotations.Generated;
#if ( $locationTracking )
import ${packageModelV4}.InputSource;
import ${packageModelV4}.InputLocation;
#end
#foreach ( $class in $model.allClasses )
import ${packageModelV4}.${class.name};
#end
import org.apache.maven.internal.xml.XmlNodeBuilder;
import org.apache.maven.api.xml.XmlNode;
import javax.xml.stream.XMLInputFactory;
import javax.xml.stream.XMLStreamException;
import javax.xml.stream.XMLStreamReader;
import javax.xml.transform.stream.StreamSource;
@Generated
public class ${className} {
private static final Map<String, String> DEFAULT_ENTITIES;
static {
Map<String, String> entities = new HashMap<>();
entities.put("nbsp", "\u00a0");
entities.put("iexcl", "\u00a1");
entities.put("cent", "\u00a2");
entities.put("pound", "\u00a3");
entities.put("curren", "\u00a4");
entities.put("yen", "\u00a5");
entities.put("brvbar", "\u00a6");
entities.put("sect", "\u00a7");
entities.put("uml", "\u00a8");
entities.put("copy", "\u00a9");
entities.put("ordf", "\u00aa");
entities.put("laquo", "\u00ab");
entities.put("not", "\u00ac");
entities.put("shy", "\u00ad");
entities.put("reg", "\u00ae");
entities.put("macr", "\u00af");
entities.put("deg", "\u00b0");
entities.put("plusmn", "\u00b1");
entities.put("sup2", "\u00b2");
entities.put("sup3", "\u00b3");
entities.put("acute", "\u00b4");
entities.put("micro", "\u00b5");
entities.put("para", "\u00b6");
entities.put("middot", "\u00b7");
entities.put("cedil", "\u00b8");
entities.put("sup1", "\u00b9");
entities.put("ordm", "\u00ba");
entities.put("raquo", "\u00bb");
entities.put("frac14", "\u00bc");
entities.put("frac12", "\u00bd");
entities.put("frac34", "\u00be");
entities.put("iquest", "\u00bf");
entities.put("Agrave", "\u00c0");
entities.put("Aacute", "\u00c1");
entities.put("Acirc", "\u00c2");
entities.put("Atilde", "\u00c3");
entities.put("Auml", "\u00c4");
entities.put("Aring", "\u00c5");
entities.put("AElig", "\u00c6");
entities.put("Ccedil", "\u00c7");
entities.put("Egrave", "\u00c8");
entities.put("Eacute", "\u00c9");
entities.put("Ecirc", "\u00ca");
entities.put("Euml", "\u00cb");
entities.put("Igrave", "\u00cc");
entities.put("Iacute", "\u00cd");
entities.put("Icirc", "\u00ce");
entities.put("Iuml", "\u00cf");
entities.put("ETH", "\u00d0");
entities.put("Ntilde", "\u00d1");
entities.put("Ograve", "\u00d2");
entities.put("Oacute", "\u00d3");
entities.put("Ocirc", "\u00d4");
entities.put("Otilde", "\u00d5");
entities.put("Ouml", "\u00d6");
entities.put("times", "\u00d7");
entities.put("Oslash", "\u00d8");
entities.put("Ugrave", "\u00d9");
entities.put("Uacute", "\u00da");
entities.put("Ucirc", "\u00db");
entities.put("Uuml", "\u00dc");
entities.put("Yacute", "\u00dd");
entities.put("THORN", "\u00de");
entities.put("szlig", "\u00df");
entities.put("agrave", "\u00e0");
entities.put("aacute", "\u00e1");
entities.put("acirc", "\u00e2");
entities.put("atilde", "\u00e3");
entities.put("auml", "\u00e4");
entities.put("aring", "\u00e5");
entities.put("aelig", "\u00e6");
entities.put("ccedil", "\u00e7");
entities.put("egrave", "\u00e8");
entities.put("eacute", "\u00e9");
entities.put("ecirc", "\u00ea");
entities.put("euml", "\u00eb");
entities.put("igrave", "\u00ec");
entities.put("iacute", "\u00ed");
entities.put("icirc", "\u00ee");
entities.put("iuml", "\u00ef");
entities.put("eth", "\u00f0");
entities.put("ntilde", "\u00f1");
entities.put("ograve", "\u00f2");
entities.put("oacute", "\u00f3");
entities.put("ocirc", "\u00f4");
entities.put("otilde", "\u00f5");
entities.put("ouml", "\u00f6");
entities.put("divide", "\u00f7");
entities.put("oslash", "\u00f8");
entities.put("ugrave", "\u00f9");
entities.put("uacute", "\u00fa");
entities.put("ucirc", "\u00fb");
entities.put("uuml", "\u00fc");
entities.put("yacute", "\u00fd");
entities.put("thorn", "\u00fe");
entities.put("yuml", "\u00ff");
// ----------------------------------------------------------------------
// Special entities
// ----------------------------------------------------------------------
entities.put("OElig", "\u0152");
entities.put("oelig", "\u0153");
entities.put("Scaron", "\u0160");
entities.put("scaron", "\u0161");
entities.put("Yuml", "\u0178");
entities.put("circ", "\u02c6");
entities.put("tilde", "\u02dc");
entities.put("ensp", "\u2002");
entities.put("emsp", "\u2003");
entities.put("thinsp", "\u2009");
entities.put("zwnj", "\u200c");
entities.put("zwj", "\u200d");
entities.put("lrm", "\u200e");
entities.put("rlm", "\u200f");
entities.put("ndash", "\u2013");
entities.put("mdash", "\u2014");
entities.put("lsquo", "\u2018");
entities.put("rsquo", "\u2019");
entities.put("sbquo", "\u201a");
entities.put("ldquo", "\u201c");
entities.put("rdquo", "\u201d");
entities.put("bdquo", "\u201e");
entities.put("dagger", "\u2020");
entities.put("Dagger", "\u2021");
entities.put("permil", "\u2030");
entities.put("lsaquo", "\u2039");
entities.put("rsaquo", "\u203a");
entities.put("euro", "\u20ac");
// ----------------------------------------------------------------------
// Symbol entities
// ----------------------------------------------------------------------
entities.put("fnof", "\u0192");
entities.put("Alpha", "\u0391");
entities.put("Beta", "\u0392");
entities.put("Gamma", "\u0393");
entities.put("Delta", "\u0394");
entities.put("Epsilon", "\u0395");
entities.put("Zeta", "\u0396");
entities.put("Eta", "\u0397");
entities.put("Theta", "\u0398");
entities.put("Iota", "\u0399");
entities.put("Kappa", "\u039a");
entities.put("Lambda", "\u039b");
entities.put("Mu", "\u039c");
entities.put("Nu", "\u039d");
entities.put("Xi", "\u039e");
entities.put("Omicron", "\u039f");
entities.put("Pi", "\u03a0");
entities.put("Rho", "\u03a1");
entities.put("Sigma", "\u03a3");
entities.put("Tau", "\u03a4");
entities.put("Upsilon", "\u03a5");
entities.put("Phi", "\u03a6");
entities.put("Chi", "\u03a7");
entities.put("Psi", "\u03a8");
entities.put("Omega", "\u03a9");
entities.put("alpha", "\u03b1");
entities.put("beta", "\u03b2");
entities.put("gamma", "\u03b3");
entities.put("delta", "\u03b4");
entities.put("epsilon", "\u03b5");
entities.put("zeta", "\u03b6");
entities.put("eta", "\u03b7");
entities.put("theta", "\u03b8");
entities.put("iota", "\u03b9");
entities.put("kappa", "\u03ba");
entities.put("lambda", "\u03bb");
entities.put("mu", "\u03bc");
entities.put("nu", "\u03bd");
entities.put("xi", "\u03be");
entities.put("omicron", "\u03bf");
entities.put("pi", "\u03c0");
entities.put("rho", "\u03c1");
entities.put("sigmaf", "\u03c2");
entities.put("sigma", "\u03c3");
entities.put("tau", "\u03c4");
entities.put("upsilon", "\u03c5");
entities.put("phi", "\u03c6");
entities.put("chi", "\u03c7");
entities.put("psi", "\u03c8");
entities.put("omega", "\u03c9");
entities.put("thetasym", "\u03d1");
entities.put("upsih", "\u03d2");
entities.put("piv", "\u03d6");
entities.put("bull", "\u2022");
entities.put("hellip", "\u2026");
entities.put("prime", "\u2032");
entities.put("Prime", "\u2033");
entities.put("oline", "\u203e");
entities.put("frasl", "\u2044");
entities.put("weierp", "\u2118");
entities.put("image", "\u2111");
entities.put("real", "\u211c");
entities.put("trade", "\u2122");
entities.put("alefsym", "\u2135");
entities.put("larr", "\u2190");
entities.put("uarr", "\u2191");
entities.put("rarr", "\u2192");
entities.put("darr", "\u2193");
entities.put("harr", "\u2194");
entities.put("crarr", "\u21b5");
entities.put("lArr", "\u21d0");
entities.put("uArr", "\u21d1");
entities.put("rArr", "\u21d2");
entities.put("dArr", "\u21d3");
entities.put("hArr", "\u21d4");
entities.put("forall", "\u2200");
entities.put("part", "\u2202");
entities.put("exist", "\u2203");
entities.put("empty", "\u2205");
entities.put("nabla", "\u2207");
entities.put("isin", "\u2208");
entities.put("notin", "\u2209");
entities.put("ni", "\u220b");
entities.put("prod", "\u220f");
entities.put("sum", "\u2211");
entities.put("minus", "\u2212");
entities.put("lowast", "\u2217");
entities.put("radic", "\u221a");
entities.put("prop", "\u221d");
entities.put("infin", "\u221e");
entities.put("ang", "\u2220");
entities.put("and", "\u2227");
entities.put("or", "\u2228");
entities.put("cap", "\u2229");
entities.put("cup", "\u222a");
entities.put("int", "\u222b");
entities.put("there4", "\u2234");
entities.put("sim", "\u223c");
entities.put("cong", "\u2245");
entities.put("asymp", "\u2248");
entities.put("ne", "\u2260");
entities.put("equiv", "\u2261");
entities.put("le", "\u2264");
entities.put("ge", "\u2265");
entities.put("sub", "\u2282");
entities.put("sup", "\u2283");
entities.put("nsub", "\u2284");
entities.put("sube", "\u2286");
entities.put("supe", "\u2287");
entities.put("oplus", "\u2295");
entities.put("otimes", "\u2297");
entities.put("perp", "\u22a5");
entities.put("sdot", "\u22c5");
entities.put("lceil", "\u2308");
entities.put("rceil", "\u2309");
entities.put("lfloor", "\u230a");
entities.put("rfloor", "\u230b");
entities.put("lang", "\u2329");
entities.put("rang", "\u232a");
entities.put("loz", "\u25ca");
entities.put("spades", "\u2660");
entities.put("clubs", "\u2663");
entities.put("hearts", "\u2665");
entities.put("diams", "\u2666");
DEFAULT_ENTITIES = Collections.unmodifiableMap(entities);
}
private boolean addDefaultEntities = true;
#if ( $locationTracking )
private boolean addLocationInformation = true;
#end
private final ContentTransformer contentTransformer;
public ${className}() {
this((s, f) -> s);
}
public ${className}(ContentTransformer contentTransformer) {
this.contentTransformer = contentTransformer;
}
/**
* Returns the state of the "add default entities" flag.
*
* @return boolean
*/
public boolean getAddDefaultEntities() {
return addDefaultEntities;
} //-- boolean getAddDefaultEntities()
/**
* Sets the state of the "add default entities" flag.
*
* @param addDefaultEntities a addDefaultEntities object.
*/
public void setAddDefaultEntities(boolean addDefaultEntities) {
this.addDefaultEntities = addDefaultEntities;
} //-- void setAddDefaultEntities(boolean)
#if ( $locationTracking )
/**
* Returns the state of the "add location information" flag.
*
* @return boolean
*/
public boolean getAddLocationInformation() {
return addLocationInformation;
} //-- boolean getAddLocationInformation()
/**
* Sets the state of the "add location information" flag.
*
* @param addLocationInformation a addLocationInformation object.
*/
public void setAddLocationInformation(boolean addLocationInformation) {
this.addLocationInformation = addLocationInformation;
} //-- void setAddLocationInformation(boolean)
#end
public ${root.name} read(Reader reader) throws XMLStreamException {
#if ( $locationTracking )
return read(reader, true, null);
#else
return read(reader, true);
#end
}
/**
* @param reader a reader object.
* @param strict a strict object.
* @throws XMLStreamException XMLStreamException if
* any.
* @return ${root.name}
*/
#if ( $locationTracking )
public ${root.name} read(Reader reader, boolean strict, InputSource source) throws XMLStreamException {
#else
public ${root.name} read(Reader reader, boolean strict) throws XMLStreamException {
#end
XMLInputFactory factory = new com.ctc.wstx.stax.WstxInputFactory();
factory.setProperty(XMLInputFactory.IS_REPLACING_ENTITY_REFERENCES, false);
#if ( $locationTracking )
StreamSource streamSource = new StreamSource(reader, source != null ? source.getLocation() : null);
#else
StreamSource streamSource = new StreamSource(reader);
#end
XMLStreamReader parser = factory.createXMLStreamReader(streamSource);
#if ( $locationTracking )
return read(parser, strict, source);
#else
return read(parser, strict);
#end
} //-- ${root.name} read(Reader, boolean)
public ${root.name} read(InputStream in) throws XMLStreamException {
#if ( $locationTracking )
return read(in, true, null);
#else
return read(in, true);
#end
}
/**
* Method read.
*
* @param in a in object.
* @param strict a strict object.
* @throws XMLStreamException XMLStreamException if
* any.
* @return ${root.name}
*/
#if ( $locationTracking )
public ${root.name} read(InputStream in, boolean strict, InputSource source) throws XMLStreamException {
#else
public ${root.name} read(InputStream in, boolean strict) throws XMLStreamException {
#end
XMLInputFactory factory = new com.ctc.wstx.stax.WstxInputFactory();
factory.setProperty(XMLInputFactory.IS_REPLACING_ENTITY_REFERENCES, false);
#if ( $locationTracking )
StreamSource streamSource = new StreamSource(in, source != null ? source.getLocation() : null);
#else
StreamSource streamSource = new StreamSource(in);
#end
XMLStreamReader parser = factory.createXMLStreamReader(streamSource);
#if ( $locationTracking )
return read(parser, strict, source);
#else
return read(parser, strict);
#end
} //-- ${root.name} read(InputStream, boolean)
/**
* Method read.
*
* @param parser a parser object.
* @param strict a strict object.
* @throws XMLStreamException XMLStreamException if
* any.
* @return ${root.name}
*/
#if ( $locationTracking )
public ${root.name} read(XMLStreamReader parser, boolean strict, InputSource source) throws XMLStreamException {
#else
public ${root.name} read(XMLStreamReader parser, boolean strict) throws XMLStreamException {
#end
$rootUcapName $rootLcapName = null;
int eventType = parser.getEventType();
boolean parsed = false;
while (eventType != XMLStreamReader.END_DOCUMENT) {
if (eventType == XMLStreamReader.START_ELEMENT) {
if (strict && ! "${rootTag}".equals(parser.getLocalName())) {
throw new XMLStreamException("Expected root element '${rootTag}' but found '" + parser.getName() + "'", parser.getLocation(), null);
} else if (parsed) {
// fallback, already expected a XMLStreamException due to invalid XML
throw new XMLStreamException("Duplicated tag: '${rootTag}'", parser.getLocation(), null);
}
#if ( $locationTracking )
$rootLcapName = parse${rootUcapName}(parser, strict, source);
#else
$rootLcapName = parse${rootUcapName}(parser, strict);
#end
parsed = true;
}
eventType = parser.next();
}
if (parsed) {
return $rootLcapName;
}
throw new XMLStreamException("Expected root element '${rootTag}' but found no element at all: invalid XML document", parser.getLocation(), null);
} //-- ${root.name} read(XMLStreamReader, boolean)
#foreach ( $class in $model.allClasses )
#if ( $class.name != "InputSource" && $class.name != "InputLocation" )
#set ( $classUcapName = $Helper.capitalise( $class.name ) )
#set ( $classLcapName = $Helper.uncapitalise( $class.name ) )
#set ( $ancestors = $Helper.ancestors( $class ) )
#set ( $allFields = $Helper.xmlFields( $class ) )
#if ( $locationTracking )
private ${classUcapName} parse${classUcapName}(XMLStreamReader parser, boolean strict, InputSource source) throws XMLStreamException {
#else
private ${classUcapName} parse${classUcapName}(XMLStreamReader parser, boolean strict) throws XMLStreamException {
#end
String tagName = parser.getLocalName();
${classUcapName}.Builder ${classLcapName} = ${classUcapName}.newBuilder(true);
#if ( $locationTracking )
if (addLocationInformation){
${classLcapName}.location("", new InputLocation(parser.getLocation().getLineNumber(), parser.getLocation().getColumnNumber(), source));
}
#end
for (int i = parser.getAttributeCount() - 1; i >= 0; i--) {
String name = parser.getAttributeLocalName(i);
String ns = parser.getAttributeNamespace(i);
String value = parser.getAttributeValue(i);
if ("http://www.w3.org/2001/XMLSchema-instance".equals(ns)) {
// just ignore attributes with non-default namespace (for example: xmlns:xsi)
#if ( $class == $root )
} else if ("xmlns".equals(name)) {
// ignore xmlns attribute in root class, which is a reserved attribute name
#end
#foreach ( $field in $allFields )
#if ( $Helper.xmlFieldMetadata( $field ).attribute )
#set ( $fieldTagName = $Helper.xmlFieldMetadata( $field ).tagName )
#set ( $fieldCapName = $Helper.capitalise( $field.name ) )
} else if ("$fieldTagName".equals(name)) {
#if ( $locationTracking )
if (addLocationInformation) {
${classLcapName}.location(name, new InputLocation(parser.getLocation().getLineNumber(), parser.getLocation().getColumnNumber(), source));
}
#end
#if ( $field.type == "String" )
${classLcapName}.${field.name}(interpolatedTrimmed(value, "$fieldTagName"));
#elseif ( $field.type == "boolean" || $field.type == "Boolean" )
${classLcapName}.${field.name}(getBooleanValue(interpolatedTrimmed(value, "$fieldTagName"), "$fieldTagName", parser, ${field.defaultValue}));
#else
// TODO: type=${field.type} to=${field.to} multiplicity=${field.multiplicity}
#end
#end
#end
} else {
checkUnknownAttribute(parser, name, tagName, strict);
}
}
Set<String> parsed = new HashSet<>();
#foreach ( $field in $allFields )
#if ( $Helper.isFlatItems( $field ) )
List<$field.to> ${field.name} = new ArrayList<>();
#end
#end
while ((strict ? parser.nextTag() : nextTag(parser)) == XMLStreamReader.START_ELEMENT) {
String childName = checkDuplicate(parser.getLocalName(), parser, parsed);
#if ( $locationTracking )
int line = addLocationInformation ? parser.getLocation().getLineNumber() : -1;
int column = addLocationInformation ? parser.getLocation().getColumnNumber() : -1;
Map<Object, InputLocation> locations = null;
#end
switch (childName) {
#set( $ift = "if" )
#foreach ( $field in $allFields )
#if ( ! $Helper.xmlFieldMetadata( $field ).attribute && ! $Helper.xmlFieldMetadata( $field ).transient )
#set ( $fieldTagName = $Helper.xmlFieldMetadata( $field ).tagName )
#if ( ! $fieldTagName )
#set ( $fieldTagName = $field.name )
#end
#if ( $Helper.isFlatItems( $field ) )
#set ( $fieldTagName = $Helper.singular( $fieldTagName ) )
#end
#set ( $fieldCapName = $Helper.capitalise($field.name))
case "${fieldTagName}": {
#if ( $field.type == "String" )
${classLcapName}.${field.name}(interpolatedTrimmed(nextText(parser, strict), "${fieldTagName}"));
break;
#elseif ( $field.type == "boolean" || $field.type == "Boolean" )
${classLcapName}.${field.name}(getBooleanValue(interpolatedTrimmed(nextText(parser, strict), "${fieldTagName}"), "${fieldTagName}", parser, ${field.defaultValue}));
break;
#elseif ( $field.type == "int" )
${classLcapName}.${field.name}(getIntegerValue(interpolatedTrimmed(nextText(parser, strict), "${fieldTagName}"), "${fieldTagName}", parser, strict, ${field.defaultValue}));
break;
#elseif ( $field.type == "DOM" )
${classLcapName}.${field.name}(buildXmlNode(parser));
break;
#elseif ( $field.type == "java.util.List" && $field.to == "String" && $field.multiplicity == "*" )
List<String> ${field.name} = new ArrayList<>();
#if ( $locationTracking )
locations = new HashMap<>();
#end
while (parser.nextTag() == XMLStreamReader.START_ELEMENT) {
if ("${Helper.singular($fieldTagName)}".equals(parser.getLocalName())) {
#if ( $locationTracking )
if (addLocationInformation) {
locations.put(Integer.valueOf(locations.size()), new InputLocation(parser.getLocation().getLineNumber(), parser.getLocation().getColumnNumber(), source));
}
#end
${field.name}.add(interpolatedTrimmed(nextText(parser, strict), "${fieldTagName}"));
} else {
checkUnknownElement(parser, strict);
}
}
${classLcapName}.${field.name}(${field.name});
break;
#elseif ( $field.type == "java.util.Properties" && $field.to == "String" && $field.multiplicity == "*" )
Map<String, String> ${field.name} = new LinkedHashMap<>();
#if ( $locationTracking )
locations = new HashMap<>();
#end
while (parser.nextTag() == XMLStreamReader.START_ELEMENT) {
String key = parser.getLocalName();
String value = nextText(parser, strict).trim();
#if ( $locationTracking )
if (addLocationInformation) {
locations.put(key, new InputLocation(parser.getLocation().getLineNumber(), parser.getLocation().getColumnNumber(), source));
}
#end
${field.name}.put(key, value);
}
${classLcapName}.${field.name}(${field.name});
break;
#elseif ( $field.to && $field.multiplicity == "1" )
#if ( $locationTracking )
${classLcapName}.${field.name}(parse${field.toClass.name}(parser, strict, source));
#else
${classLcapName}.${field.name}(parse${field.toClass.name}(parser, strict));
#end
break;
#elseif ( $field.to && $field.multiplicity == "*" && $Helper.isFlatItems( $field ) )
${field.name}.add(parse${field.toClass.name}(parser, strict));
break;
#elseif ( $field.to && $field.multiplicity == "*" )
List<$field.to> ${field.name} = new ArrayList<>();
while (parser.nextTag() == XMLStreamReader.START_ELEMENT) {
if ("${Helper.singular($fieldTagName)}".equals(parser.getLocalName())) {
#if ( $locationTracking )
${field.name}.add(parse${field.toClass.name}(parser, strict, source));
#else
${field.name}.add(parse${field.toClass.name}(parser, strict));
#end
} else {
checkUnknownElement(parser, strict);
}
}
${classLcapName}.${field.name}(${field.name});
break;
#else
// TODO: type=${field.type} to=${field.to} multiplicity=${field.multiplicity}
break;
#end
}
#set( $ift = "else if" )
#end
#end
default: {
checkUnknownElement(parser, strict);
break;
}
}
#if ( $locationTracking )
if (addLocationInformation) {
${classLcapName}.location(childName, new InputLocation(line, column, source, locations));
}
#end
}
#foreach ( $field in $allFields )
#if ( $Helper.isFlatItems( $field ) )
${classLcapName}.${field.name}(${field.name});
#end
#end
#if ( $class == $root )
${classLcapName}.modelEncoding(parser.getEncoding());
#end
return ${classLcapName}.build();
}
#end
#end
private String checkDuplicate(String tagName, XMLStreamReader parser, Set<String> parsed) throws XMLStreamException {
#set( $aliases = { } )
#set( $flats = { } )
#foreach( $class in $model.allClasses )
#foreach ( $field in $class.getFields($version) )
#set ( $fieldTagName = $Helper.xmlFieldMetadata( $field ).tagName )
#if ( ! $fieldTagName )
#set ( $fieldTagName = $field.name )
#end
#if ( $field.alias )
#set ( $dummy = $aliases.put( $field.alias, $fieldTagName ) )
#end
#if ( $Helper.isFlatItems( $field ) )
#set ( $fieldTagName = $Helper.singular($fieldTagName) )
#set ( $dummy = $flats.put( $fieldTagName, "" ) )
#end
#end
#end
#if ( ! ${aliases.isEmpty()} )
switch (tagName) {
#foreach( $entry in $aliases.entrySet() )
case "${entry.key}":
tagName = "${entry.value}";
break;
#end
}
#end
#if ( ! ${flats.isEmpty()} )
switch (tagName) {
#foreach( $entry in $flats.entrySet() )
case "${entry.key}":
#end
break;
default:
if (!parsed.add(tagName)) {
throw new XMLStreamException("Duplicated tag: '" + tagName + "'", parser.getLocation(), null);
}
}
#end
return tagName;
}
/**
* Method checkUnknownAttribute.
*
* @param parser a parser object.
* @param strict a strict object.
* @param tagName a tagName object.
* @param attribute a attribute object.
* @throws XMLStreamException XMLStreamException if
* any.
* @throws IOException IOException if any.
*/
private void checkUnknownAttribute(XMLStreamReader parser, String attribute, String tagName, boolean strict) throws XMLStreamException {
// strictXmlAttributes = true for model: if strict == true, not only elements are checked but attributes too
if (strict) {
throw new XMLStreamException("Unknown attribute '" + attribute + "' for tag '" + tagName + "'", parser.getLocation(), null);
}
} //-- void checkUnknownAttribute(XMLStreamReader, String, String, boolean)
/**
* Method checkUnknownElement.
*
* @param parser a parser object.
* @param strict a strict object.
* @throws XMLStreamException XMLStreamException if
* any.
* @throws IOException IOException if any.
*/
private void checkUnknownElement(XMLStreamReader parser, boolean strict) throws XMLStreamException {
if (strict) {
throw new XMLStreamException("Unrecognised tag: '" + parser.getName() + "'", parser.getLocation(), null);
}
for (int unrecognizedTagCount = 1; unrecognizedTagCount > 0;) {
int eventType = nextTag(parser);
if (eventType == XMLStreamReader.START_ELEMENT) {
unrecognizedTagCount++;
} else if (eventType == XMLStreamReader.END_ELEMENT) {
unrecognizedTagCount--;
}
}
} //-- void checkUnknownElement(XMLStreamReader, boolean)
/**
* Method getTrimmedValue.
*
* @param s a s object.
* @return String
*/
private String getTrimmedValue(String s) {
if (s != null) {
s = s.trim();
}
return s;
} //-- String getTrimmedValue(String)
/**
* Method interpolatedTrimmed.
*
* @param value a value object.
* @param context a context object.
* @return String
*/
private String interpolatedTrimmed(String value, String context) {
return getTrimmedValue(contentTransformer.transform(value, context));
} //-- String interpolatedTrimmed(String, String)
/**
* Method nextTag.
*
* @param parser a parser object.
* @throws IOException IOException if any.
* @throws XMLStreamException XMLStreamException if
* any.
* @return int
*/
private int nextTag(XMLStreamReader parser) throws XMLStreamException {
while (true) {
int next = parser.next();
switch (next) {
case XMLStreamReader.SPACE:
case XMLStreamReader.COMMENT:
case XMLStreamReader.PROCESSING_INSTRUCTION:
case XMLStreamReader.CDATA:
case XMLStreamReader.CHARACTERS:
continue;
case XMLStreamReader.START_ELEMENT:
case XMLStreamReader.END_ELEMENT:
return next;
}
}
} //-- int nextTag(XMLStreamReader)
private String nextText(XMLStreamReader parser, boolean strict) throws XMLStreamException {
int eventType = parser.getEventType();
if (eventType != XMLStreamReader.START_ELEMENT) {
throw new XMLStreamException("parser must be on START_ELEMENT to read next text", parser.getLocation(), null);
}
eventType = parser.next();
StringBuilder result = new StringBuilder();
while (true) {
if (eventType == XMLStreamReader.CHARACTERS || eventType == XMLStreamReader.CDATA) {
result.append(parser.getText());
} else if (eventType == XMLStreamReader.ENTITY_REFERENCE) {
String val = null;
if (strict) {
throw new XMLStreamException("Entities are not supported in strict mode", parser.getLocation(), null);
} else if (addDefaultEntities) {
val = DEFAULT_ENTITIES.get(parser.getLocalName());
}
if (val != null) {
result.append(val);
} else {
result.append("&").append(parser.getLocalName()).append(";");
}
} else if (eventType != XMLStreamReader.COMMENT) {
break;
}
eventType = parser.next();
}
if (eventType != XMLStreamReader.END_ELEMENT) {
throw new XMLStreamException(
"TEXT must be immediately followed by END_ELEMENT and not " + eventType /*TODO: TYPES[eventType]*/, parser.getLocation(), null);
}
return result.toString();
}
private XmlNode buildXmlNode(XMLStreamReader parser) throws XMLStreamException {
return XmlNodeBuilder.build(parser);
}
#foreach ( $class in $model.allClasses )
#foreach ( $field in $class.getFields($version) )
#if ( $field.type == "boolean" || $field.type == "Boolean" )
#set ( $hasBooleanField = true )
#elseif ( $field.type == "int" || $field.type == "Integer" )
#set ( $hasIntegerField = true )
#end
#end
#end
#if ( $hasBooleanField )
/**
* Method getBooleanValue.
*
* @param s a s object.
* @param defaultValue a defaultValue object.
* @param parser a parser object.
* @param attribute a attribute object.
* @throws XMLStreamException XMLStreamException if
* any.
* @return boolean
*/
private boolean getBooleanValue(String s, String attribute, XMLStreamReader parser, boolean defaultValue) throws XMLStreamException {
if (s != null && s.length() != 0) {
return Boolean.valueOf(s).booleanValue();
}
return defaultValue;
} //-- boolean getBooleanValue(String, String, XMLStreamReader, String)
#end
#if ( $hasIntegerField )
/**
* Method getIntegerValue.
*
* @param s a s object.
* @param strict a strict object.
* @param parser a parser object.
* @param attribute a attribute object.
* @throws XMLStreamException XMLStreamException if
* any.
* @return int
*/
private int getIntegerValue(String s, String attribute, XMLStreamReader parser, boolean strict, int defaultValue) throws XMLStreamException {
if (s != null) {
try {
return Integer.valueOf(s).intValue();
} catch (NumberFormatException nfe) {
if (strict) {
throw new XMLStreamException("Unable to parse element '" + attribute + "', must be an integer", parser.getLocation(), nfe);
}
}
}
return defaultValue;
} //-- int getIntegerValue(String, String, XMLStreamReader, boolean)
#end
public static interface ContentTransformer {
/**
* Interpolate the value read from the xpp3 document
* @param source The source value
* @param fieldName A description of the field being interpolated. The implementation may use this to
* log stuff.
* @return The interpolated value.
*/
String transform(String source, String fieldName);
}
}

View File

@ -18,7 +18,11 @@
*#
#parse ( "common.vm" )
#
#if( ${packageToolV4Xpp3} )
#set ( $package = "${packageToolV4Xpp3}" )
#else
#set ( $package = "${packageToolV4}" )
#end
#set ( $className = "${model.name}Xpp3Reader" )
#
#set ( $root = $model.getClass( $model.getRoot($version), $version ) )
@ -58,6 +62,7 @@ import org.codehaus.plexus.util.xml.pull.MXParser;
import org.codehaus.plexus.util.xml.pull.XmlPullParser;
import org.codehaus.plexus.util.xml.pull.XmlPullParserException;
@Deprecated
@Generated
public class ${className} {

View File

@ -18,7 +18,11 @@
*#
#parse ( "common.vm" )
#
#if( ${packageToolV4Xpp3} )
#set ( $package = "${packageToolV4Xpp3}" )
#else
#set ( $package = "${packageToolV4}" )
#end
#set ( $className = "${model.name}Xpp3WriterEx" )
#
#set ( $root = $model.getClass( $model.getRoot($version), $version ) )
@ -66,6 +70,7 @@ import org.codehaus.plexus.util.xml.pull.XmlPullParser;
import org.codehaus.plexus.util.xml.pull.XmlPullParserException;
import org.codehaus.plexus.util.xml.pull.XmlSerializer;
@Deprecated
@Generated
public class ${className} {

414
src/mdo/writer-stax.vm Normal file
View File

@ -0,0 +1,414 @@
#*
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.
*#
#parse ( "common.vm" )
#
#set ( $package = "${packageToolV4}" )
#set ( $className = "${model.name}StaxWriter" )
#
#set ( $root = $model.getClass( $model.getRoot($version), $version ) )
#set ( $xmlModelMetadata = $model.getMetadata( "org.codehaus.modello.plugins.xml.metadata.XmlModelMetadata" ) )
#if ( $forcedIOModelVersion )
#set ( $Version = $model.class.classLoader.loadClass( "org.codehaus.modello.model.Version" ) )
#set ( $ioVersion = $Version.getConstructor( $package.class ).newInstance( $forcedIOModelVersion ) )
#else
#set ( $ioVersion = $version )
#end
#set ( $namespace = $xmlModelMetadata.getNamespace($ioVersion) )
#set ( $schemaLocation = $xmlModelMetadata.getSchemaLocation($ioVersion) )
#set ( $rootXml = $Helper.xmlClassMetadata( $root ) )
#set ( $rootTag = $rootXml.tagName )
#set ( $rootUcapName = $Helper.capitalise( $root.name ) )
#set ( $rootLcapName = $Helper.uncapitalise( $root.name ) )
#
#MODELLO-VELOCITY#SAVE-OUTPUT-TO ${package.replace('.','/')}/${className}.java
// =================== DO NOT EDIT THIS FILE ====================
// Generated by Modello Velocity from ${template}
// template, any modifications will be overwritten.
// ==============================================================
package ${package};
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.Reader;
import java.io.Writer;
import java.text.DateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.Properties;
import java.util.Set;
import javax.xml.stream.XMLOutputFactory;
import javax.xml.stream.XMLStreamException;
import javax.xml.stream.XMLStreamWriter;
import org.apache.maven.api.annotations.Generated;
#if ( $locationTracking )
import ${packageModelV4}.InputLocation;
import ${packageModelV4}.InputLocationTracker;
#end
import org.apache.maven.api.xml.XmlNode;
import org.apache.maven.internal.xml.XmlNodeBuilder;
#foreach ( $class in $model.allClasses )
#if ( $class.name != "InputLocation" )
import ${packageModelV4}.${class.name};
#end
#end
@Generated
public class ${className} {
//--------------------------/
//- Class/Member Variables -/
//--------------------------/
/**
* Field NAMESPACE.
*/
private static final String NAMESPACE = "${namespace}";
/**
* XSI namespace
*/
private static final String XSI_NAMESPACE = "http://www.w3.org/2001/XMLSchema-instance";
/**
* Field fileComment.
*/
private String fileComment = null;
#if ( $locationTracking )
/**
* Field stringFormatter.
*/
protected InputLocation.StringFormatter stringFormatter;
#end
//-----------/
//- Methods -/
//-----------/
/**
* Method setFileComment.
*
* @param fileComment a fileComment object.
*/
public void setFileComment(String fileComment) {
this.fileComment = fileComment;
} //-- void setFileComment(String)
#if ( $locationTracking )
/**
* Method setStringFormatter.
*
* @param stringFormatter
*/
public void setStringFormatter(InputLocation.StringFormatter stringFormatter) {
this.stringFormatter = stringFormatter;
} //-- void setStringFormatter(InputLocation.StringFormatter)
#end
/**
* Method write.
*
* @param writer a writer object
* @param ${rootLcapName} a ${root.name} object
* @throws IOException IOException if any
*/
public void write(Writer writer, ${root.name} ${rootLcapName}) throws IOException, XMLStreamException {
XMLOutputFactory factory = new com.ctc.wstx.stax.WstxOutputFactory();
factory.setProperty(XMLOutputFactory.IS_REPAIRING_NAMESPACES, false);
XMLStreamWriter serializer = factory.createXMLStreamWriter(writer);
serializer.writeStartDocument(${rootLcapName}.getModelEncoding(), null);
write${root.name}("$rootTag", ${rootLcapName}, serializer);
serializer.writeEndDocument();
} //-- void write(Writer, ${root.name})
/**
* Method write.
*
* @param stream a stream object
* @param ${rootLcapName} a ${root.name} object
* @throws IOException IOException if any
*/
public void write(OutputStream stream, ${root.name} ${rootLcapName}) throws IOException, XMLStreamException {
XMLOutputFactory factory = new com.ctc.wstx.stax.WstxOutputFactory();
factory.setProperty(XMLOutputFactory.IS_REPAIRING_NAMESPACES, false);
XMLStreamWriter serializer = factory.createXMLStreamWriter(stream, ${rootLcapName}.getModelEncoding());
serializer.writeStartDocument(${rootLcapName}.getModelEncoding(), null);
write${root.name}("$rootTag", ${rootLcapName}, serializer);
serializer.writeEndDocument();
} //-- void write(OutputStream, ${root.name})
/**
* Method writeDomToSerializer.
*
* @param dom a dom object.
* @param serializer a serializer object.
* @throws IOException IOException if any.
*/
protected void writeDomToSerializer(org.apache.maven.api.xml.XmlNode dom, XMLStreamWriter serializer) throws IOException, XMLStreamException {
serializer.writeStartElement(NAMESPACE, dom.getName());
for (Map.Entry<String, String> attribute : dom.getAttributes().entrySet()) {
serializer.writeAttribute(NAMESPACE, attribute.getKey(), attribute.getValue());
}
for (XmlNode aChild : dom.getChildren()) {
writeDomToSerializer(aChild, serializer);
}
String value = dom.getValue();
if (value != null) {
serializer.writeCharacters(value);
}
serializer.writeEndElement();
} //-- void writeDomToSerializer(org.apache.maven.api.xml.XmlNode, XMLStreamWriter)
#foreach ( $class in $model.allClasses )
#if ( $class.name != "InputSource" && $class.name != "InputLocation" )
#set ( $classUcapName = $Helper.capitalise( $class.name ) )
#set ( $classLcapName = $Helper.uncapitalise( $class.name ) )
#set ( $allFields = $Helper.xmlFields( $class ) )
private void write${classUcapName}(String tagName, ${classUcapName} ${classLcapName}, XMLStreamWriter serializer)
throws IOException, XMLStreamException {
if (${classLcapName} != null) {
#if ( $class == $root )
if (this.fileComment != null) {
serializer.writeComment(this.fileComment);
}
serializer.writeStartElement("", tagName, NAMESPACE);
serializer.writeNamespace("", NAMESPACE);
serializer.writeNamespace("xsi", XSI_NAMESPACE);
serializer.writeAttribute(XSI_NAMESPACE, "schemaLocation", NAMESPACE + " ${schemaLocation}");
#else
serializer.writeStartElement(NAMESPACE, tagName);
#end
#foreach ( $field in $allFields )
#if ( $Helper.xmlFieldMetadata( $field ).attribute )
#set ( $fieldTagName = $Helper.xmlFieldMetadata( $field ).tagName )
#set ( $fieldCapName = $Helper.capitalise( $field.name ) )
#if ( $field.type == "String" )
writeAttr("$fieldTagName", ${classLcapName}.get${fieldCapName}(), serializer);
#elseif ( $field.type == "boolean" )
#set ( $def = ${field.defaultValue} )
#if ( ${def} == "true" )
writeAttr("$fieldTagName", ${classLcapName}.is${fieldCapName}() ? null : "false", serializer);
#else
writeAttr("$fieldTagName", ${classLcapName}.is${fieldCapName}() ? "true" : null, serializer);
#end
#else
// TODO: type=${field.type} to=${field.to} multiplicity=${field.multiplicity}
#end
#end
#end
#foreach ( $field in $allFields )
#if ( ! $Helper.xmlFieldMetadata( $field ).attribute && ! $Helper.xmlFieldMetadata( $field ).transient )
#set ( $fieldTagName = $Helper.xmlFieldMetadata( $field ).tagName )
#if ( ! $fieldTagName )
#set ( $fieldTagName = $field.name )
#end
#set ( $fieldCapName = $Helper.capitalise( $field.name ) )
#set ( $def = ${field.defaultValue} )
#if ( $locationTracking )
#set ( $loctrac = ", ${classLcapName}" )
#set ( $loctracnull = ", null" )
#else
#set ( $loctrac = "" )
#set ( $loctracnull = "" )
#end
#if ( $field.type == "String" )
#if ( ! $def )
writeTag("$fieldTagName", null, ${classLcapName}.get${fieldCapName}(), serializer${loctrac});
#else
writeTag("$fieldTagName", "${def}", ${classLcapName}.get${fieldCapName}(), serializer${loctrac});
#end
#elseif ( $field.type == "boolean" || $field.type == "Boolean" )
#if ( ${def} == "true" )
writeTag("$fieldTagName", "${def}", ${classLcapName}.is${fieldCapName}() ? null : "false", serializer${loctrac});
#else
writeTag("$fieldTagName", "${def}", ${classLcapName}.is${fieldCapName}() ? "true" : null, serializer${loctrac});
#end
#elseif ( $field.type == "int" )
writeTag("$fieldTagName", "${def}", Integer.toString(${classLcapName}.get${fieldCapName}()), serializer${loctrac});
#elseif ( $field.type == "DOM" )
writeDom(${classLcapName}.get${fieldCapName}(), serializer);
#elseif ( $field.type == "java.util.List" && $field.to == "String" && $field.multiplicity == "*" )
#set( $singularField = ${Helper.singular($fieldTagName)} )
writeList("$fieldTagName", ${classLcapName}.get${fieldCapName}(), serializer${loctrac},
t -> writeTag("$singularField", null, t, serializer${loctracnull}));
#elseif ( $field.type == "java.util.Properties" && $field.to == "String" && $field.multiplicity == "*" )
writeProperties("$fieldTagName", ${classLcapName}.get${fieldCapName}(), serializer${loctrac});
#elseif ( $field.to && $field.multiplicity == "1" )
write${field.to}("$fieldTagName", ${classLcapName}.get${fieldCapName}(), serializer);
#elseif ( $field.to && $field.multiplicity == "*" )
#set( $singularField = ${Helper.singular($fieldTagName)} )
writeList("$fieldTagName", $Helper.isFlatItems($field), ${classLcapName}.get${fieldCapName}(), serializer${loctrac},
t -> write${field.to}("$singularField", t, serializer));
#else
// TODO: name=${field.name} type=${field.type} to=${field.to} multiplicity=${field.multiplicity}
#end
#end
#end
serializer.writeEndElement();
#if ( $locationTracking )
writeLocationTracking(${classLcapName}, "", serializer);
#end
}
}
#end
#end
@FunctionalInterface
private interface ElementWriter<T> {
public void write(T t) throws IOException, XMLStreamException;
}
#if ( $locationTracking )
private <T> void writeList(String tagName, List<T> list, XMLStreamWriter serializer, InputLocationTracker locationTracker, ElementWriter<T> writer) throws IOException, XMLStreamException {
writeList(tagName, false, list, serializer, locationTracker, writer);
#else
private <T> void writeList(String tagName, List<T> list, XMLStreamWriter serializer, ElementWriter<T> writer) throws IOException, XMLStreamException {
writeList(tagName, false, list, serializer, writer);
#end
}
#if ( $locationTracking )
private <T> void writeList(String tagName, boolean flat, List<T> list, XMLStreamWriter serializer, InputLocationTracker locationTracker, ElementWriter<T> writer) throws IOException, XMLStreamException {
#else
private <T> void writeList(String tagName, boolean flat, List<T> list, XMLStreamWriter serializer, ElementWriter<T> writer) throws IOException, XMLStreamException {
#end
if (list != null && !list.isEmpty()) {
if (!flat) {
serializer.writeStartElement(NAMESPACE, tagName);
}
int index = 0;
#if ( $locationTracking )
InputLocation location = locationTracker != null ? locationTracker.getLocation(tagName) : null;
#end
for (T t : list) {
writer.write(t);
#if ( $locationTracking )
writeLocationTracking(location, Integer.valueOf(index++), serializer);
#end
}
if (!flat) {
serializer.writeEndElement();
#if ( $locationTracking )
writeLocationTracking(locationTracker, tagName, serializer);
#end
}
}
}
#if ( $locationTracking )
private <T> void writeProperties(String tagName, Map<String, String> props, XMLStreamWriter serializer, InputLocationTracker locationTracker) throws IOException, XMLStreamException {
#else
private <T> void writeProperties(String tagName, Map<String, String> props, XMLStreamWriter serializer) throws IOException, XMLStreamException {
#end
if (props != null && !props.isEmpty()) {
serializer.writeStartElement(NAMESPACE, tagName);
#if ( $locationTracking )
InputLocation location = locationTracker != null ? locationTracker.getLocation(tagName) : null;
#end
for (Map.Entry<String, String> entry : props.entrySet()) {
String key = entry.getKey();
#if ( $locationTracking )
writeTag(key, null, entry.getValue(), serializer, null);
writeLocationTracking(location, key, serializer);
#else
writeTag(key, null, entry.getValue(), serializer);
#end
}
serializer.writeEndElement();
#if ( $locationTracking )
writeLocationTracking(locationTracker, tagName, serializer);
#end
}
}
private void writeDom(XmlNode dom, XMLStreamWriter serializer) throws IOException, XMLStreamException {
if (dom != null) {
serializer.writeStartElement(NAMESPACE, dom.getName());
for (Map.Entry<String, String> attr : dom.getAttributes().entrySet()) {
serializer.writeAttribute(NAMESPACE, attr.getKey(), attr.getValue());
}
for (XmlNode child : dom.getChildren()) {
writeDom(child, serializer);
}
String value = dom.getValue();
if (value != null) {
serializer.writeCharacters(value);
}
serializer.writeEndElement();
}
}
#if ( $locationTracking )
private void writeTag(String tagName, String defaultValue, String value, XMLStreamWriter serializer, InputLocationTracker locationTracker) throws IOException, XMLStreamException {
#else
private void writeTag(String tagName, String defaultValue, String value, XMLStreamWriter serializer) throws IOException, XMLStreamException {
#end
if (value != null && !Objects.equals(defaultValue, value)) {
serializer.writeStartElement(NAMESPACE, tagName);
serializer.writeCharacters(value);
serializer.writeEndElement();
#if ( $locationTracking )
writeLocationTracking(locationTracker, tagName, serializer);
#end
}
}
private void writeAttr(String attrName, String value, XMLStreamWriter serializer) throws IOException, XMLStreamException {
if (value != null) {
serializer.writeAttribute(attrName, value);
}
}
#if ( $locationTracking )
/**
* Method writeLocationTracking.
*
* @param locationTracker
* @param serializer
* @param key
* @throws IOException
*/
protected void writeLocationTracking(InputLocationTracker locationTracker, Object key, XMLStreamWriter serializer) throws IOException, XMLStreamException {
InputLocation location = (locationTracker == null) ? null : locationTracker.getLocation(key);
if (location != null) {
serializer.writeComment(toString(location));
}
} //-- void writeLocationTracking(InputLocationTracker, Object, XMLStreamWriter)
/**
* Method toString.
*
* @param location
* @return String
*/
protected String toString(InputLocation location) {
if (stringFormatter != null) {
return stringFormatter.toString(location);
}
return ' ' + location.getSource().toString() + ':' + location.getLineNumber() + ' ';
} //-- String toString(InputLocation)
#end
}

View File

@ -18,7 +18,11 @@
*#
#parse ( "common.vm" )
#
#if( ${packageToolV4Xpp3} )
#set ( $package = "${packageToolV4Xpp3}" )
#else
#set ( $package = "${packageToolV4}" )
#end
#set ( $className = "${model.name}Xpp3Writer" )
#
#set ( $root = $model.getClass( $model.getRoot($version), $version ) )
@ -62,6 +66,7 @@ import org.codehaus.plexus.util.xml.pull.XmlPullParser;
import org.codehaus.plexus.util.xml.pull.XmlPullParserException;
import org.codehaus.plexus.util.xml.pull.XmlSerializer;
@Deprecated
@Generated
public class ${className} {