mirror of https://github.com/apache/maven.git
[MNG-7877] Attach the build POM and simplify build/consumer implementation (#1240)
.. at the cost of loosing xml formatting in the consumer POMs
This commit is contained in:
parent
25488f9231
commit
c6380108b1
|
@ -33,6 +33,11 @@ import org.apache.maven.api.annotations.Nonnull;
|
|||
@Immutable
|
||||
public interface Repository {
|
||||
|
||||
/**
|
||||
* The reserved id for Maven Central
|
||||
*/
|
||||
String CENTRAL_ID = "central";
|
||||
|
||||
/**
|
||||
* Gets the identifier of this repository.
|
||||
*
|
||||
|
|
|
@ -132,11 +132,6 @@ under the License.
|
|||
<artifactId>maven-model-builder</artifactId>
|
||||
<version>${project.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.apache.maven</groupId>
|
||||
<artifactId>maven-model-transform</artifactId>
|
||||
<version>${project.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.apache.maven</groupId>
|
||||
<artifactId>maven-plugin-api</artifactId>
|
||||
|
|
|
@ -71,10 +71,6 @@ under the License.
|
|||
<groupId>org.apache.maven</groupId>
|
||||
<artifactId>maven-model-builder</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.apache.maven</groupId>
|
||||
<artifactId>maven-model-transform</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.apache.maven</groupId>
|
||||
<artifactId>maven-resolver-provider</artifactId>
|
||||
|
|
|
@ -19,31 +19,35 @@
|
|||
package org.apache.maven.internal.transformation;
|
||||
|
||||
import javax.annotation.PreDestroy;
|
||||
import javax.inject.Inject;
|
||||
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;
|
||||
import java.io.Writer;
|
||||
import java.lang.reflect.Method;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Path;
|
||||
import java.nio.file.Paths;
|
||||
import java.nio.file.StandardCopyOption;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.Set;
|
||||
import java.util.concurrent.CopyOnWriteArraySet;
|
||||
import java.util.function.BiConsumer;
|
||||
|
||||
import org.apache.maven.api.feature.Features;
|
||||
import org.apache.maven.model.building.DefaultBuildPomXMLFilterFactory;
|
||||
import org.apache.maven.api.model.Model;
|
||||
import org.apache.maven.model.building.FileModelSource;
|
||||
import org.apache.maven.model.building.ModelBuilder;
|
||||
import org.apache.maven.model.building.ModelBuildingRequest;
|
||||
import org.apache.maven.model.building.ModelCache;
|
||||
import org.apache.maven.model.building.Result;
|
||||
import org.apache.maven.model.building.TransformerContext;
|
||||
import org.apache.maven.model.transform.RawToConsumerPomXMLFilterFactory;
|
||||
import org.apache.maven.model.transform.stax.XmlUtils;
|
||||
import org.apache.maven.model.v4.MavenModelVersion;
|
||||
import org.apache.maven.model.v4.MavenStaxWriter;
|
||||
import org.apache.maven.project.MavenProject;
|
||||
import org.apache.maven.project.artifact.ProjectArtifact;
|
||||
import org.codehaus.stax2.XMLInputFactory2;
|
||||
import org.apache.maven.repository.internal.DefaultModelCache;
|
||||
import org.eclipse.aether.RepositorySystemSession;
|
||||
import org.eclipse.aether.artifact.Artifact;
|
||||
import org.eclipse.aether.artifact.DefaultArtifact;
|
||||
|
@ -61,32 +65,49 @@ public final class ConsumerPomArtifactTransformer {
|
|||
|
||||
private static final String CONSUMER_POM_CLASSIFIER = "consumer";
|
||||
|
||||
private static final String BUILD_POM_CLASSIFIER = "build";
|
||||
|
||||
private static final String NAMESPACE_FORMAT = "http://maven.apache.org/POM/%s";
|
||||
|
||||
private static final String SCHEMA_LOCATION_FORMAT = "https://maven.apache.org/xsd/maven-%s.xsd";
|
||||
|
||||
private final Set<Path> toDelete = new CopyOnWriteArraySet<>();
|
||||
|
||||
private final ModelBuilder modelBuilder;
|
||||
|
||||
@Inject
|
||||
ConsumerPomArtifactTransformer(ModelBuilder modelBuilder) {
|
||||
this.modelBuilder = modelBuilder;
|
||||
}
|
||||
|
||||
public void injectTransformedArtifacts(MavenProject project, RepositorySystemSession session) throws IOException {
|
||||
if (project.getFile() == null) {
|
||||
// If there is no build POM there is no reason to inject artifacts for the consumer POM.
|
||||
return;
|
||||
}
|
||||
if (Features.buildConsumer(session.getUserProperties())) {
|
||||
Path generatedFile;
|
||||
String buildDirectory =
|
||||
project.getBuild() != null ? project.getBuild().getDirectory() : null;
|
||||
if (buildDirectory == null) {
|
||||
generatedFile = Files.createTempFile(CONSUMER_POM_CLASSIFIER, "pom");
|
||||
} else {
|
||||
Path buildDir = Paths.get(buildDirectory);
|
||||
Path buildDir =
|
||||
project.getBuild() != null ? Paths.get(project.getBuild().getDirectory()) : null;
|
||||
if (buildDir != null) {
|
||||
Files.createDirectories(buildDir);
|
||||
generatedFile = Files.createTempFile(buildDir, CONSUMER_POM_CLASSIFIER, "pom");
|
||||
}
|
||||
deferDeleteFile(generatedFile);
|
||||
project.addAttachedArtifact(new ConsumerPomArtifact(project, generatedFile, session));
|
||||
Path consumer = buildDir != null
|
||||
? Files.createTempFile(buildDir, CONSUMER_POM_CLASSIFIER + "-", ".pom")
|
||||
: Files.createTempFile(CONSUMER_POM_CLASSIFIER + "-", ".pom");
|
||||
deferDeleteFile(consumer);
|
||||
|
||||
project.addAttachedArtifact(createConsumerPomArtifact(project, consumer, session));
|
||||
} else if (project.getModel().isRoot()) {
|
||||
throw new IllegalStateException(
|
||||
"The use of the root attribute on the model requires the buildconsumer feature to be active");
|
||||
}
|
||||
}
|
||||
|
||||
public ConsumerPomArtifact createConsumerPomArtifact(
|
||||
MavenProject project, Path consumer, RepositorySystemSession session) {
|
||||
return new ConsumerPomArtifact(project, consumer, session);
|
||||
}
|
||||
|
||||
private void deferDeleteFile(Path generatedFile) {
|
||||
toDelete.add(generatedFile.toAbsolutePath());
|
||||
}
|
||||
|
@ -117,75 +138,130 @@ public final class ConsumerPomArtifactTransformer {
|
|||
}
|
||||
|
||||
private boolean consumerPomPresent(Collection<Artifact> artifacts) {
|
||||
return artifacts.stream().anyMatch(a -> CONSUMER_POM_CLASSIFIER.equals(a.getClassifier()));
|
||||
return artifacts.stream()
|
||||
.anyMatch(a -> "pom".equals(a.getExtension()) && CONSUMER_POM_CLASSIFIER.equals(a.getClassifier()));
|
||||
}
|
||||
|
||||
private Collection<Artifact> replacePom(Collection<Artifact> artifacts) {
|
||||
ArrayList<Artifact> result = new ArrayList<>(artifacts.size());
|
||||
Artifact consumer = null;
|
||||
Artifact main = null;
|
||||
for (Artifact artifact : artifacts) {
|
||||
if (CONSUMER_POM_CLASSIFIER.equals(artifact.getClassifier())) {
|
||||
// if under CONSUMER_POM_CLASSIFIER, move it to "" classifier
|
||||
DefaultArtifact remapped = new DefaultArtifact(
|
||||
artifact.getGroupId(),
|
||||
artifact.getArtifactId(),
|
||||
"",
|
||||
artifact.getExtension(),
|
||||
artifact.getVersion(),
|
||||
artifact.getProperties(),
|
||||
artifact.getFile());
|
||||
result.add(remapped);
|
||||
} else if ("".equals(artifact.getClassifier())
|
||||
&& (artifact.getExtension().equals("pom"))
|
||||
|| artifact.getExtension().startsWith("pom.")) {
|
||||
// skip POM and POM subordinates
|
||||
continue;
|
||||
} else {
|
||||
// everything else: add as is
|
||||
result.add(artifact);
|
||||
if ("pom".equals(artifact.getExtension())) {
|
||||
if (CONSUMER_POM_CLASSIFIER.equals(artifact.getClassifier())) {
|
||||
consumer = artifact;
|
||||
} else if ("".equals(artifact.getClassifier())) {
|
||||
main = artifact;
|
||||
}
|
||||
}
|
||||
}
|
||||
return result;
|
||||
if (main != null && consumer != null) {
|
||||
ArrayList<Artifact> result = new ArrayList<>(artifacts);
|
||||
result.remove(main);
|
||||
result.remove(consumer);
|
||||
result.add(new DefaultArtifact(
|
||||
consumer.getGroupId(),
|
||||
consumer.getArtifactId(),
|
||||
"",
|
||||
consumer.getExtension(),
|
||||
consumer.getVersion(),
|
||||
consumer.getProperties(),
|
||||
consumer.getFile()));
|
||||
result.add(new DefaultArtifact(
|
||||
main.getGroupId(),
|
||||
main.getArtifactId(),
|
||||
BUILD_POM_CLASSIFIER,
|
||||
main.getExtension(),
|
||||
main.getVersion(),
|
||||
main.getProperties(),
|
||||
main.getFile()));
|
||||
artifacts = result;
|
||||
}
|
||||
return artifacts;
|
||||
}
|
||||
|
||||
/**
|
||||
* Consumer POM is transformed from original POM.
|
||||
*/
|
||||
private static class ConsumerPomArtifact extends TransformedArtifact {
|
||||
class ConsumerPomArtifact extends TransformedArtifact {
|
||||
|
||||
private ConsumerPomArtifact(MavenProject mavenProject, Path target, RepositorySystemSession session) {
|
||||
private MavenProject project;
|
||||
private RepositorySystemSession session;
|
||||
|
||||
ConsumerPomArtifact(MavenProject mavenProject, Path target, RepositorySystemSession session) {
|
||||
super(
|
||||
new ProjectArtifact(mavenProject),
|
||||
() -> mavenProject.getFile().toPath(),
|
||||
CONSUMER_POM_CLASSIFIER,
|
||||
"pom",
|
||||
target,
|
||||
transformer(session));
|
||||
target);
|
||||
this.project = mavenProject;
|
||||
this.session = session;
|
||||
}
|
||||
|
||||
private static BiConsumer<Path, Path> transformer(RepositorySystemSession session) {
|
||||
TransformerContext context = (TransformerContext) session.getData().get(TransformerContext.KEY);
|
||||
return (src, dest) -> {
|
||||
try (InputStream inputStream = transform(src, context)) {
|
||||
Files.createDirectories(dest.getParent());
|
||||
Files.copy(inputStream, dest, StandardCopyOption.REPLACE_EXISTING);
|
||||
} catch (XMLStreamException | IOException e) {
|
||||
@Override
|
||||
public void transform(Path src, Path dest) {
|
||||
Model model = project.getModel().getDelegate();
|
||||
transform(src, dest, model);
|
||||
}
|
||||
|
||||
void transform(Path src, Path dest, Model model) {
|
||||
Model consumer = null;
|
||||
String version;
|
||||
|
||||
// This is a bit of a hack, but all models are cached, so not sure why we'd need to parse it again
|
||||
ModelCache cache = DefaultModelCache.newInstance(session);
|
||||
Object modelData = cache.get(new FileModelSource(src.toFile()), "raw");
|
||||
if (modelData != null) {
|
||||
try {
|
||||
Method getModel = modelData.getClass().getMethod("getModel");
|
||||
getModel.setAccessible(true);
|
||||
org.apache.maven.model.Model cachedModel =
|
||||
(org.apache.maven.model.Model) getModel.invoke(modelData);
|
||||
consumer = cachedModel.getDelegate();
|
||||
} catch (Exception e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* The actual transformation: visible for testing.
|
||||
*/
|
||||
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);
|
||||
if (consumer == null) {
|
||||
TransformerContext context =
|
||||
(TransformerContext) session.getData().get(TransformerContext.KEY);
|
||||
Result<? extends org.apache.maven.model.Model> result = modelBuilder.buildRawModel(
|
||||
src.toFile(), ModelBuildingRequest.VALIDATION_LEVEL_MINIMAL, false, context);
|
||||
if (result.hasErrors()) {
|
||||
throw new IllegalStateException(
|
||||
"Unable to build POM " + src,
|
||||
result.getProblems().iterator().next().getException());
|
||||
}
|
||||
consumer = result.get().getDelegate();
|
||||
}
|
||||
|
||||
// raw to consumer transform
|
||||
consumer = consumer.withRoot(false).withModules(null);
|
||||
if (consumer.getParent() != null) {
|
||||
consumer = consumer.withParent(consumer.getParent().withRelativePath(null));
|
||||
}
|
||||
|
||||
if (!consumer.isPreserveModelVersion()) {
|
||||
consumer = consumer.withPreserveModelVersion(false);
|
||||
version = new MavenModelVersion().getModelVersion(consumer);
|
||||
consumer = consumer.withModelVersion(version);
|
||||
} else {
|
||||
version = consumer.getModelVersion();
|
||||
}
|
||||
|
||||
try {
|
||||
Files.createDirectories(dest.getParent());
|
||||
try (Writer w = Files.newBufferedWriter(dest)) {
|
||||
MavenStaxWriter writer = new MavenStaxWriter();
|
||||
writer.setNamespace(String.format(NAMESPACE_FORMAT, version));
|
||||
writer.setSchemaLocation(String.format(SCHEMA_LOCATION_FORMAT, version));
|
||||
writer.setAddLocationInformation(false);
|
||||
writer.write(w, consumer);
|
||||
}
|
||||
} catch (XMLStreamException | IOException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -23,7 +23,6 @@ import java.io.InputStream;
|
|||
import java.nio.file.Files;
|
||||
import java.nio.file.Path;
|
||||
import java.security.MessageDigest;
|
||||
import java.util.function.BiConsumer;
|
||||
import java.util.function.Supplier;
|
||||
|
||||
import org.apache.maven.artifact.Artifact;
|
||||
|
@ -42,12 +41,7 @@ abstract class TransformedArtifact extends DefaultArtifact {
|
|||
private final OnChangeTransformer onChangeTransformer;
|
||||
|
||||
TransformedArtifact(
|
||||
Artifact source,
|
||||
Supplier<Path> sourcePathProvider,
|
||||
String classifier,
|
||||
String extension,
|
||||
Path targetPath,
|
||||
BiConsumer<Path, Path> transformerConsumer) {
|
||||
Artifact source, Supplier<Path> sourcePathProvider, String classifier, String extension, Path targetPath) {
|
||||
super(
|
||||
source.getGroupId(),
|
||||
source.getArtifactId(),
|
||||
|
@ -58,7 +52,7 @@ abstract class TransformedArtifact extends DefaultArtifact {
|
|||
new TransformedArtifactHandler(
|
||||
classifier, extension, source.getArtifactHandler().getPackaging()));
|
||||
this.onChangeTransformer =
|
||||
new OnChangeTransformer(sourcePathProvider, targetPath, TransformedArtifact::sha1, transformerConsumer);
|
||||
new OnChangeTransformer(sourcePathProvider, targetPath, TransformedArtifact::sha1, this::transform);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -102,6 +96,8 @@ abstract class TransformedArtifact extends DefaultArtifact {
|
|||
}
|
||||
}
|
||||
|
||||
protected abstract void transform(Path src, Path dst);
|
||||
|
||||
private static class TransformedArtifactHandler implements ArtifactHandler {
|
||||
private final String classifier;
|
||||
|
||||
|
|
|
@ -131,7 +131,8 @@ public class DefaultProjectBuilder implements ProjectBuilder {
|
|||
|
||||
@Override
|
||||
public ProjectBuildingResult build(File pomFile, ProjectBuildingRequest request) throws ProjectBuildingException {
|
||||
return build(pomFile, new FileModelSource(pomFile), new InternalConfig(request, null, null));
|
||||
InternalConfig config = new InternalConfig(request, null, modelBuilder.newTransformerContextBuilder());
|
||||
return build(pomFile, new FileModelSource(pomFile), config);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -160,6 +161,7 @@ public class DefaultProjectBuilder implements ProjectBuilder {
|
|||
|
||||
DefaultModelBuildingListener listener =
|
||||
new DefaultModelBuildingListener(project, projectBuildingHelper, projectBuildingRequest);
|
||||
|
||||
request.setModelBuildingListener(listener);
|
||||
|
||||
request.setPomFile(pomFile);
|
||||
|
|
|
@ -1,34 +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.xml.internal;
|
||||
|
||||
import org.apache.maven.model.building.DefaultBuildPomXMLFilterFactory;
|
||||
import org.apache.maven.model.transform.RawToConsumerPomXMLFilterFactory;
|
||||
|
||||
/**
|
||||
* The default implementation of the {@link RawToConsumerPomXMLFilterFactory}
|
||||
* It will provide several values for the consumer pom based on its context.
|
||||
*
|
||||
* @since 4.0.0
|
||||
*/
|
||||
public class DefaultConsumerPomXMLFilterFactory extends RawToConsumerPomXMLFilterFactory {
|
||||
public DefaultConsumerPomXMLFilterFactory(DefaultBuildPomXMLFilterFactory buildPomXMLFilterFactory) {
|
||||
super(buildPomXMLFilterFactory);
|
||||
}
|
||||
}
|
|
@ -25,7 +25,10 @@ import java.nio.file.Path;
|
|||
import java.nio.file.Paths;
|
||||
|
||||
import org.apache.maven.model.Model;
|
||||
import org.apache.maven.model.building.DefaultModelBuilderFactory;
|
||||
import org.apache.maven.model.building.ModelBuilder;
|
||||
import org.apache.maven.model.building.TransformerContext;
|
||||
import org.apache.maven.model.v4.MavenStaxReader;
|
||||
import org.apache.maven.project.MavenProject;
|
||||
import org.eclipse.aether.RepositorySystemSession;
|
||||
import org.eclipse.aether.SessionData;
|
||||
|
@ -38,18 +41,30 @@ import static org.mockito.ArgumentMatchers.any;
|
|||
import static org.mockito.Mockito.when;
|
||||
|
||||
class ConsumerPomArtifactTransformerTest {
|
||||
|
||||
ModelBuilder modelBuilder = new DefaultModelBuilderFactory().newInstance();
|
||||
|
||||
@Test
|
||||
void transform() throws Exception {
|
||||
RepositorySystemSession systemSessionMock = Mockito.mock(RepositorySystemSession.class);
|
||||
SessionData sessionDataMock = Mockito.mock(SessionData.class);
|
||||
when(systemSessionMock.getData()).thenReturn(sessionDataMock);
|
||||
when(sessionDataMock.get(any())).thenReturn(new NoTransformerContext());
|
||||
|
||||
Path beforePomFile =
|
||||
Paths.get("src/test/resources/projects/transform/before.pom").toAbsolutePath();
|
||||
Path afterPomFile =
|
||||
Paths.get("src/test/resources/projects/transform/after.pom").toAbsolutePath();
|
||||
|
||||
try (InputStream expected = Files.newInputStream(afterPomFile);
|
||||
InputStream result =
|
||||
ConsumerPomArtifactTransformer.transform(beforePomFile, new NoTransformerContext())) {
|
||||
XmlAssert.assertThat(result).and(expected).areIdentical();
|
||||
Path tempFile = Files.createTempFile("", ".pom");
|
||||
Files.delete(tempFile);
|
||||
try (InputStream expected = Files.newInputStream(beforePomFile)) {
|
||||
Model model = new Model(new MavenStaxReader().read(expected));
|
||||
MavenProject project = new MavenProject(model);
|
||||
ConsumerPomArtifactTransformer t = new ConsumerPomArtifactTransformer(modelBuilder);
|
||||
t.createConsumerPomArtifact(project, tempFile, systemSessionMock)
|
||||
.transform(beforePomFile, tempFile, model.getDelegate());
|
||||
}
|
||||
XmlAssert.assertThat(afterPomFile.toFile()).and(tempFile.toFile()).areIdentical();
|
||||
}
|
||||
|
||||
@Test
|
||||
|
@ -61,7 +76,7 @@ class ConsumerPomArtifactTransformerTest {
|
|||
when(systemSessionMock.getData()).thenReturn(sessionDataMock);
|
||||
when(sessionDataMock.get(any())).thenReturn(new NoTransformerContext());
|
||||
|
||||
new ConsumerPomArtifactTransformer().injectTransformedArtifacts(emptyProject, systemSessionMock);
|
||||
new ConsumerPomArtifactTransformer(modelBuilder).injectTransformedArtifacts(emptyProject, systemSessionMock);
|
||||
|
||||
assertThat(emptyProject.getAttachedArtifacts()).isEmpty();
|
||||
}
|
||||
|
|
|
@ -0,0 +1,63 @@
|
|||
/*
|
||||
* 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;
|
||||
|
||||
import javax.inject.Inject;
|
||||
|
||||
import java.io.File;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
import org.apache.maven.bridge.MavenRepositorySystem;
|
||||
import org.apache.maven.execution.DefaultMavenExecutionRequest;
|
||||
import org.apache.maven.execution.MavenExecutionRequest;
|
||||
import org.apache.maven.internal.aether.DefaultRepositorySystemSessionFactory;
|
||||
import org.apache.maven.project.DefaultProjectBuildingRequest;
|
||||
import org.apache.maven.project.ProjectBuilder;
|
||||
import org.apache.maven.project.ProjectBuildingResult;
|
||||
import org.codehaus.plexus.testing.PlexusTest;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
|
||||
@PlexusTest
|
||||
public class ModelBuilderTest {
|
||||
|
||||
@Inject
|
||||
ProjectBuilder projectBuilder;
|
||||
|
||||
@Inject
|
||||
MavenRepositorySystem repositorySystem;
|
||||
|
||||
@Inject
|
||||
DefaultRepositorySystemSessionFactory repositorySessionFactory;
|
||||
|
||||
@Test
|
||||
void testModelBuilder() throws Exception {
|
||||
MavenExecutionRequest mavenRequest = new DefaultMavenExecutionRequest();
|
||||
mavenRequest.setLocalRepository(repositorySystem.createLocalRepository(new File("target/test-repo/")));
|
||||
|
||||
DefaultProjectBuildingRequest request = new DefaultProjectBuildingRequest();
|
||||
request.setRepositorySession(repositorySessionFactory.newRepositorySession(mavenRequest));
|
||||
List<ProjectBuildingResult> results = projectBuilder.build(
|
||||
Collections.singletonList(new File("src/test/resources/projects/tree/pom.xml")), true, request);
|
||||
|
||||
assertEquals(3, results.size());
|
||||
}
|
||||
}
|
|
@ -227,7 +227,7 @@ class ProjectBuilderTest extends AbstractCoreMavenComponentTestCase {
|
|||
File pomFile = new File("src/test/resources/projects/badPom.xml").getAbsoluteFile();
|
||||
MavenSession mavenSession = createMavenSession(null);
|
||||
ProjectBuildingRequest configuration = new DefaultProjectBuildingRequest();
|
||||
configuration.setValidationLevel(ModelBuildingRequest.VALIDATION_LEVEL_MINIMAL);
|
||||
configuration.setValidationLevel(ModelBuildingRequest.VALIDATION_LEVEL_STRICT);
|
||||
configuration.setRepositorySession(mavenSession.getRepositorySession());
|
||||
org.apache.maven.project.ProjectBuilder projectBuilder =
|
||||
getContainer().lookup(org.apache.maven.project.ProjectBuilder.class);
|
||||
|
@ -245,7 +245,8 @@ 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 CHARACTERS")));
|
||||
contains(projectBuildingResultWithProblemMessage(
|
||||
"Received non-all-whitespace CHARACTERS or CDATA event in nextTag()")));
|
||||
}
|
||||
|
||||
@Test
|
||||
|
|
|
@ -1,45 +1,18 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
|
||||
<!--
|
||||
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.
|
||||
-->
|
||||
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
<groupId>test</groupId>
|
||||
<artifactId>test</artifactId>
|
||||
<version>0.1-SNAPSHOT</version>
|
||||
<packaging>pom</packaging>
|
||||
|
||||
|
||||
|
||||
<build>
|
||||
<pluginManagement>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-compiler-plugin</artifactId>
|
||||
<version>2.1</version>
|
||||
<configuration>
|
||||
<source> 1.5 </source>
|
||||
<source>1.5</source>
|
||||
<target xml:space="preserve"> 1.5 </target>
|
||||
</configuration>
|
||||
</plugin>
|
||||
|
@ -47,7 +20,6 @@ under the License.
|
|||
</pluginManagement>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-compiler-plugin</artifactId>
|
||||
<executions>
|
||||
<execution>
|
||||
|
@ -57,10 +29,9 @@ under the License.
|
|||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
|
||||
<profiles>
|
||||
<profile>
|
||||
<id>default</id>
|
||||
<id>default-active</id>
|
||||
<activation>
|
||||
<activeByDefault>true</activeByDefault>
|
||||
</activation>
|
||||
|
@ -80,4 +51,4 @@ under the License.
|
|||
</properties>
|
||||
</profile>
|
||||
</profiles>
|
||||
</project>
|
||||
</project>
|
|
@ -19,10 +19,11 @@ specific language governing permissions and limitations
|
|||
under the License.
|
||||
-->
|
||||
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0"
|
||||
<project xmlns="http://maven.apache.org/POM/4.1.0"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.1.0 https://maven.apache.org/xsd/maven-4.1.0.xsd"
|
||||
root="true">
|
||||
<modelVersion>4.1.0</modelVersion>
|
||||
|
||||
<groupId>test</groupId>
|
||||
<artifactId>test</artifactId>
|
||||
|
@ -63,7 +64,7 @@ under the License.
|
|||
|
||||
<profiles>
|
||||
<profile>
|
||||
<id>default</id>
|
||||
<id>default-active</id>
|
||||
<activation>
|
||||
<activeByDefault>true</activeByDefault>
|
||||
</activation>
|
||||
|
|
|
@ -1,81 +0,0 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
|
||||
<!--
|
||||
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.
|
||||
-->
|
||||
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
<groupId>test</groupId>
|
||||
<artifactId>test</artifactId>
|
||||
<version>0.1-SNAPSHOT</version>
|
||||
<packaging>pom</packaging>
|
||||
|
||||
|
||||
|
||||
<build>
|
||||
<pluginManagement>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-compiler-plugin</artifactId>
|
||||
<version>2.1</version>
|
||||
<configuration>
|
||||
<source> 1.5 </source>
|
||||
<target xml:space="preserve"> 1.5 </target>
|
||||
</configuration>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</pluginManagement>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-compiler-plugin</artifactId>
|
||||
<executions>
|
||||
<execution>
|
||||
<id>test</id>
|
||||
</execution>
|
||||
</executions>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
|
||||
<profiles>
|
||||
<profile>
|
||||
<id>default-active</id>
|
||||
<activation>
|
||||
<activeByDefault>true</activeByDefault>
|
||||
</activation>
|
||||
<properties>
|
||||
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
|
||||
</properties>
|
||||
</profile>
|
||||
<profile>
|
||||
<id>file</id>
|
||||
<activation>
|
||||
<file>
|
||||
<exists>simple.xml</exists>
|
||||
</file>
|
||||
</activation>
|
||||
<properties>
|
||||
<profile.file>activated</profile.file>
|
||||
</properties>
|
||||
</profile>
|
||||
</profiles>
|
||||
</project>
|
|
@ -1,87 +0,0 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
|
||||
<!--
|
||||
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.
|
||||
-->
|
||||
|
||||
<project xmlns="http://maven.apache.org/POM/4.1.0"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.1.0 https://maven.apache.org/xsd/maven-4.1.0.xsd"
|
||||
root="true">
|
||||
<modelVersion>4.1.0</modelVersion>
|
||||
|
||||
<groupId>test</groupId>
|
||||
<artifactId>test</artifactId>
|
||||
<version>0.1-SNAPSHOT</version>
|
||||
<packaging>pom</packaging>
|
||||
|
||||
<modules>
|
||||
<module>lib</module> <!-- the library -->
|
||||
<module>app</module> <!-- the application -->
|
||||
</modules>
|
||||
|
||||
<build>
|
||||
<pluginManagement>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-compiler-plugin</artifactId>
|
||||
<version>2.1</version>
|
||||
<configuration>
|
||||
<source> 1.5 </source>
|
||||
<target xml:space="preserve"> 1.5 </target>
|
||||
</configuration>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</pluginManagement>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-compiler-plugin</artifactId>
|
||||
<executions>
|
||||
<execution>
|
||||
<id>test</id>
|
||||
</execution>
|
||||
</executions>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
|
||||
<profiles>
|
||||
<profile>
|
||||
<id>default-active</id>
|
||||
<activation>
|
||||
<activeByDefault>true</activeByDefault>
|
||||
</activation>
|
||||
<properties>
|
||||
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
|
||||
</properties>
|
||||
</profile>
|
||||
<profile>
|
||||
<id>file</id>
|
||||
<activation>
|
||||
<file>
|
||||
<exists>simple.xml</exists>
|
||||
</file>
|
||||
</activation>
|
||||
<properties>
|
||||
<profile.file>activated</profile.file>
|
||||
</properties>
|
||||
</profile>
|
||||
</profiles>
|
||||
</project>
|
|
@ -0,0 +1,16 @@
|
|||
<project xmlns="http://maven.apache.org/POM/4.0.0">
|
||||
|
||||
<parent>
|
||||
<groupId>org.apache.maven.ut</groupId>
|
||||
<artifactId>parent</artifactId>
|
||||
</parent>
|
||||
<artifactId>consumer</artifactId>
|
||||
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>org.apache.maven.ut</groupId>
|
||||
<artifactId>dep</artifactId>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
</project>
|
|
@ -0,0 +1,9 @@
|
|||
<project xmlns="http://maven.apache.org/POM/4.0.0">
|
||||
|
||||
<parent>
|
||||
<groupId>org.apache.maven.ut</groupId>
|
||||
<artifactId>parent</artifactId>
|
||||
</parent>
|
||||
<artifactId>dep</artifactId>
|
||||
|
||||
</project>
|
|
@ -0,0 +1,10 @@
|
|||
<project xmlns="http://maven.apache.org/POM/4.0.0">
|
||||
<groupId>org.apache.maven.ut</groupId>
|
||||
<artifactId>parent</artifactId>
|
||||
<version>1.0-SNAPSHOT</version>
|
||||
<packaging>pom</packaging>
|
||||
<modules>
|
||||
<module>dep</module>
|
||||
<module>consumer</module>
|
||||
</modules>
|
||||
</project>
|
|
@ -36,6 +36,10 @@ under the License.
|
|||
<groupId>org.apache.maven</groupId>
|
||||
<artifactId>maven-api-core</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.apache.maven</groupId>
|
||||
<artifactId>maven-api-spi</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.apache.maven</groupId>
|
||||
<artifactId>maven-xml-impl</artifactId>
|
||||
|
@ -64,10 +68,6 @@ under the License.
|
|||
<groupId>org.apache.maven</groupId>
|
||||
<artifactId>maven-builder-support</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.apache.maven</groupId>
|
||||
<artifactId>maven-model-transform</artifactId>
|
||||
</dependency>
|
||||
<!-- Testing -->
|
||||
<dependency>
|
||||
<groupId>org.eclipse.sisu</groupId>
|
||||
|
@ -105,6 +105,16 @@ under the License.
|
|||
<artifactId>xmlunit-matchers</artifactId>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.mockito</groupId>
|
||||
<artifactId>mockito-core</artifactId>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.xmlunit</groupId>
|
||||
<artifactId>xmlunit-assertj</artifactId>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
<build>
|
||||
|
|
|
@ -1,27 +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.building;
|
||||
|
||||
/**
|
||||
* Offers a transformation implementation based on PipelineStreams.
|
||||
* Subclasses are responsible for providing the right SAXFilter.
|
||||
*
|
||||
* @since 4.0.0
|
||||
*/
|
||||
public abstract class AbstractModelSourceTransformer implements ModelSourceTransformer {}
|
|
@ -20,12 +20,17 @@ 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.Files;
|
||||
import java.nio.file.Path;
|
||||
import java.nio.file.Paths;
|
||||
import java.util.Arrays;
|
||||
import java.util.Objects;
|
||||
import java.util.Optional;
|
||||
|
||||
import org.apache.maven.model.transform.BuildToRawPomXMLFilterFactory;
|
||||
import org.apache.maven.model.Dependency;
|
||||
import org.apache.maven.model.Model;
|
||||
import org.apache.maven.model.Parent;
|
||||
|
||||
/**
|
||||
* ModelSourceTransformer for the build pom
|
||||
|
@ -35,11 +40,150 @@ import org.apache.maven.model.transform.BuildToRawPomXMLFilterFactory;
|
|||
@Named
|
||||
@Singleton
|
||||
class BuildModelSourceTransformer implements ModelSourceTransformer {
|
||||
@Override
|
||||
public XMLStreamReader transform(XMLStreamReader parser, Path pomFile, TransformerContext context)
|
||||
throws IOException, TransformerException {
|
||||
BuildToRawPomXMLFilterFactory buildPomXMLFilterFactory = new DefaultBuildPomXMLFilterFactory(context, false);
|
||||
|
||||
return buildPomXMLFilterFactory.get(parser, pomFile);
|
||||
public static final String NAMESPACE_PREFIX = "http://maven.apache.org/POM/";
|
||||
|
||||
@Override
|
||||
public void transform(Path pomFile, TransformerContext context, Model model) {
|
||||
handleModelVersion(model);
|
||||
handleParent(pomFile, context, model);
|
||||
handleReactorDependencies(context, model);
|
||||
handleCiFriendlyVersion(context, model);
|
||||
}
|
||||
|
||||
//
|
||||
// Infer modelVersion from namespace URI
|
||||
//
|
||||
void handleModelVersion(Model model) {
|
||||
String namespace = model.getDelegate().getNamespaceUri();
|
||||
if (model.getModelVersion() == null && namespace != null && namespace.startsWith(NAMESPACE_PREFIX)) {
|
||||
model.setModelVersion(namespace.substring(NAMESPACE_PREFIX.length()));
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// Infer parent information
|
||||
//
|
||||
void handleParent(Path pomFile, TransformerContext context, Model model) {
|
||||
Parent parent = model.getParent();
|
||||
if (parent != null) {
|
||||
String version = parent.getVersion();
|
||||
String path = Optional.ofNullable(parent.getRelativePath()).orElse("..");
|
||||
if (version == null && !path.isEmpty()) {
|
||||
Optional<RelativeProject> resolvedParent = resolveRelativePath(
|
||||
pomFile.getParent(), context, Paths.get(path), parent.getGroupId(), parent.getArtifactId());
|
||||
resolvedParent.ifPresent(relativeProject -> parent.setVersion(relativeProject.getVersion()));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// CI friendly versions
|
||||
//
|
||||
void handleCiFriendlyVersion(TransformerContext context, Model model) {
|
||||
String version = model.getVersion();
|
||||
String modVersion = replaceCiFriendlyVersion(context, version);
|
||||
model.setVersion(modVersion);
|
||||
|
||||
Parent parent = model.getParent();
|
||||
if (parent != null) {
|
||||
version = parent.getVersion();
|
||||
modVersion = replaceCiFriendlyVersion(context, version);
|
||||
parent.setVersion(modVersion);
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// Infer inner reactor dependencies version
|
||||
//
|
||||
void handleReactorDependencies(TransformerContext context, Model model) {
|
||||
for (Dependency dep : model.getDependencies()) {
|
||||
if (dep.getVersion() == null) {
|
||||
Model depModel = context.getRawModel(dep.getGroupId(), dep.getArtifactId());
|
||||
if (depModel != null) {
|
||||
String v = depModel.getVersion();
|
||||
if (v == null && depModel.getParent() != null) {
|
||||
v = depModel.getParent().getVersion();
|
||||
}
|
||||
dep.setVersion(v);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
protected String replaceCiFriendlyVersion(TransformerContext context, String version) {
|
||||
if (version != null) {
|
||||
for (String key : Arrays.asList("changelist", "revision", "sha1")) {
|
||||
String val = context.getUserProperty(key);
|
||||
if (val != null) {
|
||||
version = version.replace("${" + key + "}", val);
|
||||
}
|
||||
}
|
||||
}
|
||||
return version;
|
||||
}
|
||||
|
||||
protected Optional<RelativeProject> resolveRelativePath(
|
||||
Path projectPath, TransformerContext context, Path relativePath, String groupId, String artifactId) {
|
||||
Path pomPath = projectPath.resolve(relativePath).normalize();
|
||||
if (Files.isDirectory(pomPath)) {
|
||||
pomPath = context.locate(pomPath);
|
||||
}
|
||||
|
||||
if (pomPath == null || !Files.isRegularFile(pomPath)) {
|
||||
return Optional.empty();
|
||||
}
|
||||
|
||||
Optional<RelativeProject> mappedProject = Optional.ofNullable(context.getRawModel(pomPath.normalize()))
|
||||
.map(BuildModelSourceTransformer::toRelativeProject);
|
||||
|
||||
if (mappedProject.isPresent()) {
|
||||
RelativeProject project = mappedProject.get();
|
||||
|
||||
if (Objects.equals(groupId, project.getGroupId()) && Objects.equals(artifactId, project.getArtifactId())) {
|
||||
return mappedProject;
|
||||
}
|
||||
}
|
||||
return Optional.empty();
|
||||
}
|
||||
|
||||
private static RelativeProject toRelativeProject(final org.apache.maven.model.Model m) {
|
||||
String groupId = m.getGroupId();
|
||||
if (groupId == null && m.getParent() != null) {
|
||||
groupId = m.getParent().getGroupId();
|
||||
}
|
||||
|
||||
String version = m.getVersion();
|
||||
if (version == null && m.getParent() != null) {
|
||||
version = m.getParent().getVersion();
|
||||
}
|
||||
|
||||
return new RelativeProject(groupId, m.getArtifactId(), version);
|
||||
}
|
||||
|
||||
static class RelativeProject {
|
||||
private final String groupId;
|
||||
|
||||
private final String artifactId;
|
||||
|
||||
private final String version;
|
||||
|
||||
RelativeProject(String groupId, String artifactId, String version) {
|
||||
this.groupId = groupId;
|
||||
this.artifactId = artifactId;
|
||||
this.version = version;
|
||||
}
|
||||
|
||||
public String getGroupId() {
|
||||
return groupId;
|
||||
}
|
||||
|
||||
public String getArtifactId() {
|
||||
return artifactId;
|
||||
}
|
||||
|
||||
public String getVersion() {
|
||||
return version;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,102 +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.building;
|
||||
|
||||
import java.nio.file.Path;
|
||||
import java.util.Optional;
|
||||
import java.util.function.BiFunction;
|
||||
import java.util.function.Function;
|
||||
|
||||
import org.apache.maven.model.Model;
|
||||
import org.apache.maven.model.transform.BuildToRawPomXMLFilterFactory;
|
||||
import org.apache.maven.model.transform.RelativeProject;
|
||||
|
||||
/**
|
||||
* A BuildPomXMLFilterFactory which is context aware
|
||||
*
|
||||
* @since 4.0.0
|
||||
*/
|
||||
public class DefaultBuildPomXMLFilterFactory extends BuildToRawPomXMLFilterFactory {
|
||||
private final TransformerContext context;
|
||||
|
||||
/**
|
||||
*
|
||||
* @param context a set of data to extract values from as required for the build pom
|
||||
* @param consume {@code true} if this factory is being used for creating the consumer pom, otherwise {@code false}
|
||||
*/
|
||||
public DefaultBuildPomXMLFilterFactory(TransformerContext context, boolean consume) {
|
||||
super(consume);
|
||||
this.context = context;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Function<Path, Optional<RelativeProject>> getRelativePathMapper() {
|
||||
return p -> Optional.ofNullable(context.getRawModel(p)).map(DefaultBuildPomXMLFilterFactory::toRelativeProject);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Function<Path, Path> getModelLocator() {
|
||||
return context::locate;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected BiFunction<String, String, String> getDependencyKeyToVersionMapper() {
|
||||
return (g, a) -> Optional.ofNullable(context.getRawModel(g, a))
|
||||
.map(DefaultBuildPomXMLFilterFactory::toVersion)
|
||||
.orElse(null);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Optional<String> getChangelist() {
|
||||
return Optional.ofNullable(context.getUserProperty("changelist"));
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Optional<String> getRevision() {
|
||||
return Optional.ofNullable(context.getUserProperty("revision"));
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Optional<String> getSha1() {
|
||||
return Optional.ofNullable(context.getUserProperty("sha1"));
|
||||
}
|
||||
|
||||
private static RelativeProject toRelativeProject(final Model m) {
|
||||
String groupId = m.getGroupId();
|
||||
if (groupId == null && m.getParent() != null) {
|
||||
groupId = m.getParent().getGroupId();
|
||||
}
|
||||
|
||||
String version = m.getVersion();
|
||||
if (version == null && m.getParent() != null) {
|
||||
version = m.getParent().getVersion();
|
||||
}
|
||||
|
||||
return new RelativeProject(groupId, m.getArtifactId(), version);
|
||||
}
|
||||
|
||||
private static String toVersion(final Model m) {
|
||||
String version = m.getVersion();
|
||||
if (version == null && m.getParent() != null) {
|
||||
version = m.getParent().getVersion();
|
||||
}
|
||||
|
||||
return version;
|
||||
}
|
||||
}
|
|
@ -67,7 +67,6 @@ import org.apache.maven.model.inheritance.InheritanceAssembler;
|
|||
import org.apache.maven.model.interpolation.ModelInterpolator;
|
||||
import org.apache.maven.model.interpolation.ModelVersionProcessor;
|
||||
import org.apache.maven.model.io.ModelParseException;
|
||||
import org.apache.maven.model.io.ModelReader;
|
||||
import org.apache.maven.model.management.DependencyManagementInjector;
|
||||
import org.apache.maven.model.management.PluginManagementInjector;
|
||||
import org.apache.maven.model.normalization.ModelNormalizer;
|
||||
|
@ -87,7 +86,6 @@ import org.apache.maven.model.resolution.ModelResolver;
|
|||
import org.apache.maven.model.resolution.UnresolvableModelException;
|
||||
import org.apache.maven.model.resolution.WorkspaceModelResolver;
|
||||
import org.apache.maven.model.superpom.SuperPomProvider;
|
||||
import org.apache.maven.model.v4.MavenMerger;
|
||||
import org.apache.maven.model.validation.ModelValidator;
|
||||
import org.codehaus.plexus.interpolation.InterpolationException;
|
||||
import org.codehaus.plexus.interpolation.MapBasedValueSource;
|
||||
|
@ -102,7 +100,6 @@ import static org.apache.maven.model.building.Result.newResult;
|
|||
@Named
|
||||
@Singleton
|
||||
public class DefaultModelBuilder implements ModelBuilder {
|
||||
private final MavenMerger modelMerger = new FileToRawModelMerger();
|
||||
|
||||
private final ModelProcessor modelProcessor;
|
||||
private final ModelValidator modelValidator;
|
||||
|
@ -122,6 +119,7 @@ public class DefaultModelBuilder implements ModelBuilder {
|
|||
private final ReportConfigurationExpander reportConfigurationExpander;
|
||||
private final ProfileActivationFilePathInterpolator profileActivationFilePathInterpolator;
|
||||
private final ModelVersionProcessor versionProcessor;
|
||||
private final ModelSourceTransformer transformer;
|
||||
|
||||
@SuppressWarnings("checkstyle:ParameterNumber")
|
||||
@Inject
|
||||
|
@ -143,7 +141,8 @@ public class DefaultModelBuilder implements ModelBuilder {
|
|||
PluginConfigurationExpander pluginConfigurationExpander,
|
||||
ReportConfigurationExpander reportConfigurationExpander,
|
||||
ProfileActivationFilePathInterpolator profileActivationFilePathInterpolator,
|
||||
ModelVersionProcessor versionProcessor) {
|
||||
ModelVersionProcessor versionProcessor,
|
||||
ModelSourceTransformer transformer) {
|
||||
this.modelProcessor = modelProcessor;
|
||||
this.modelValidator = modelValidator;
|
||||
this.modelNormalizer = modelNormalizer;
|
||||
|
@ -162,6 +161,7 @@ public class DefaultModelBuilder implements ModelBuilder {
|
|||
this.reportConfigurationExpander = reportConfigurationExpander;
|
||||
this.profileActivationFilePathInterpolator = profileActivationFilePathInterpolator;
|
||||
this.versionProcessor = versionProcessor;
|
||||
this.transformer = transformer;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -188,7 +188,8 @@ public class DefaultModelBuilder implements ModelBuilder {
|
|||
pluginConfigurationExpander,
|
||||
reportConfigurationExpander,
|
||||
profileActivationFilePathInterpolator,
|
||||
versionProcessor);
|
||||
versionProcessor,
|
||||
transformer);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -215,7 +216,8 @@ public class DefaultModelBuilder implements ModelBuilder {
|
|||
pluginConfigurationExpander,
|
||||
reportConfigurationExpander,
|
||||
profileActivationFilePathInterpolator,
|
||||
versionProcessor);
|
||||
versionProcessor,
|
||||
transformer);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -242,7 +244,8 @@ public class DefaultModelBuilder implements ModelBuilder {
|
|||
pluginConfigurationExpander,
|
||||
reportConfigurationExpander,
|
||||
profileActivationFilePathInterpolator,
|
||||
versionProcessor);
|
||||
versionProcessor,
|
||||
transformer);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -269,7 +272,8 @@ public class DefaultModelBuilder implements ModelBuilder {
|
|||
pluginConfigurationExpander,
|
||||
reportConfigurationExpander,
|
||||
profileActivationFilePathInterpolator,
|
||||
versionProcessor);
|
||||
versionProcessor,
|
||||
transformer);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -296,7 +300,8 @@ public class DefaultModelBuilder implements ModelBuilder {
|
|||
pluginConfigurationExpander,
|
||||
reportConfigurationExpander,
|
||||
profileActivationFilePathInterpolator,
|
||||
versionProcessor);
|
||||
versionProcessor,
|
||||
transformer);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -323,7 +328,8 @@ public class DefaultModelBuilder implements ModelBuilder {
|
|||
pluginConfigurationExpander,
|
||||
reportConfigurationExpander,
|
||||
profileActivationFilePathInterpolator,
|
||||
versionProcessor);
|
||||
versionProcessor,
|
||||
transformer);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -350,7 +356,8 @@ public class DefaultModelBuilder implements ModelBuilder {
|
|||
pluginConfigurationExpander,
|
||||
reportConfigurationExpander,
|
||||
profileActivationFilePathInterpolator,
|
||||
versionProcessor);
|
||||
versionProcessor,
|
||||
transformer);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -377,7 +384,8 @@ public class DefaultModelBuilder implements ModelBuilder {
|
|||
pluginConfigurationExpander,
|
||||
reportConfigurationExpander,
|
||||
profileActivationFilePathInterpolator,
|
||||
versionProcessor);
|
||||
versionProcessor,
|
||||
transformer);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -404,7 +412,8 @@ public class DefaultModelBuilder implements ModelBuilder {
|
|||
pluginConfigurationExpander,
|
||||
reportConfigurationExpander,
|
||||
profileActivationFilePathInterpolator,
|
||||
versionProcessor);
|
||||
versionProcessor,
|
||||
transformer);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -431,7 +440,8 @@ public class DefaultModelBuilder implements ModelBuilder {
|
|||
pluginConfigurationExpander,
|
||||
reportConfigurationExpander,
|
||||
profileActivationFilePathInterpolator,
|
||||
versionProcessor);
|
||||
versionProcessor,
|
||||
transformer);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -458,7 +468,8 @@ public class DefaultModelBuilder implements ModelBuilder {
|
|||
pluginConfigurationExpander,
|
||||
reportConfigurationExpander,
|
||||
profileActivationFilePathInterpolator,
|
||||
versionProcessor);
|
||||
versionProcessor,
|
||||
transformer);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -486,7 +497,8 @@ public class DefaultModelBuilder implements ModelBuilder {
|
|||
pluginConfigurationExpander,
|
||||
reportConfigurationExpander,
|
||||
profileActivationFilePathInterpolator,
|
||||
versionProcessor);
|
||||
versionProcessor,
|
||||
transformer);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -514,7 +526,8 @@ public class DefaultModelBuilder implements ModelBuilder {
|
|||
pluginConfigurationExpander,
|
||||
reportConfigurationExpander,
|
||||
profileActivationFilePathInterpolator,
|
||||
versionProcessor);
|
||||
versionProcessor,
|
||||
transformer);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -541,7 +554,8 @@ public class DefaultModelBuilder implements ModelBuilder {
|
|||
pluginConfigurationExpander,
|
||||
reportConfigurationExpander,
|
||||
profileActivationFilePathInterpolator,
|
||||
versionProcessor);
|
||||
versionProcessor,
|
||||
transformer);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -568,7 +582,8 @@ public class DefaultModelBuilder implements ModelBuilder {
|
|||
pluginConfigurationExpander,
|
||||
reportConfigurationExpander,
|
||||
profileActivationFilePathInterpolator,
|
||||
versionProcessor);
|
||||
versionProcessor,
|
||||
transformer);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -595,7 +610,8 @@ public class DefaultModelBuilder implements ModelBuilder {
|
|||
pluginConfigurationExpander,
|
||||
reportConfigurationExpander,
|
||||
profileActivationFilePathInterpolator,
|
||||
versionProcessor);
|
||||
versionProcessor,
|
||||
transformer);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -623,7 +639,8 @@ public class DefaultModelBuilder implements ModelBuilder {
|
|||
pluginConfigurationExpander,
|
||||
reportConfigurationExpander,
|
||||
profileActivationFilePathInterpolator,
|
||||
versionProcessor);
|
||||
versionProcessor,
|
||||
transformer);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -950,16 +967,31 @@ public class DefaultModelBuilder implements ModelBuilder {
|
|||
|
||||
@Override
|
||||
public Result<? extends Model> buildRawModel(File pomFile, int validationLevel, boolean locationTracking) {
|
||||
return buildRawModel(pomFile, validationLevel, locationTracking, null);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Result<? extends Model> buildRawModel(
|
||||
File pomFile, int validationLevel, boolean locationTracking, TransformerContext context) {
|
||||
final ModelBuildingRequest request = new DefaultModelBuildingRequest()
|
||||
.setValidationLevel(validationLevel)
|
||||
.setLocationTracking(locationTracking)
|
||||
.setModelSource(new FileModelSource(pomFile));
|
||||
final DefaultModelProblemCollector collector =
|
||||
new DefaultModelProblemCollector(new DefaultModelBuildingResult());
|
||||
DefaultModelProblemCollector problems = new DefaultModelProblemCollector(new DefaultModelBuildingResult());
|
||||
try {
|
||||
return newResult(readFileModel(request, collector), collector.getProblems());
|
||||
Model model = readFileModel(request, problems);
|
||||
|
||||
try {
|
||||
if (transformer != null && context != null) {
|
||||
transformer.transform(pomFile.toPath(), context, model);
|
||||
}
|
||||
} catch (TransformerException e) {
|
||||
problems.add(new ModelProblemCollectorRequest(Severity.FATAL, Version.V40).setException(e));
|
||||
}
|
||||
|
||||
return newResult(model, problems.getProblems());
|
||||
} catch (ModelBuildingException e) {
|
||||
return error(collector.getProblems());
|
||||
return error(problems.getProblems());
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1097,31 +1129,13 @@ public class DefaultModelBuilder implements ModelBuilder {
|
|||
rawModel = readFileModel(request, problems);
|
||||
File pomFile = ((FileModelSource) modelSource).getFile();
|
||||
|
||||
TransformerContext context = null;
|
||||
if (request.getTransformerContextBuilder() != null) {
|
||||
context = request.getTransformerContextBuilder().initialize(request, problems);
|
||||
}
|
||||
|
||||
try {
|
||||
// must implement TransformContext, but should use request to access properties/model cache
|
||||
Map<String, Object> options = new HashMap<>();
|
||||
if (request.isLocationTracking()) {
|
||||
org.apache.maven.api.model.InputLocation location =
|
||||
rawModel.getDelegate().getLocation("");
|
||||
if (location != null) {
|
||||
options.put(
|
||||
ModelProcessor.INPUT_SOURCE,
|
||||
new org.apache.maven.model.InputSource(location.getSource()));
|
||||
}
|
||||
if (request.getTransformerContextBuilder() != null) {
|
||||
TransformerContext context =
|
||||
request.getTransformerContextBuilder().initialize(request, problems);
|
||||
transformer.transform(pomFile.toPath(), context, rawModel);
|
||||
}
|
||||
options.put(ModelReader.TRANSFORMER_CONTEXT, context);
|
||||
Model transformedFileModel = modelProcessor.read(pomFile, options);
|
||||
// rawModel with locationTrackers, required for proper feedback during validations
|
||||
|
||||
// Apply enriched data
|
||||
rawModel = new Model(
|
||||
modelMerger.merge(rawModel.getDelegate(), transformedFileModel.getDelegate(), false, null));
|
||||
} catch (IOException e) {
|
||||
} catch (TransformerException e) {
|
||||
problems.add(new ModelProblemCollectorRequest(Severity.FATAL, Version.V40).setException(e));
|
||||
}
|
||||
} else if (request.getFileModel() == null) {
|
||||
|
@ -1613,7 +1627,8 @@ public class DefaultModelBuilder implements ModelBuilder {
|
|||
for (Iterator<Dependency> it = depMgmt.getDependencies().iterator(); it.hasNext(); ) {
|
||||
Dependency dependency = it.next();
|
||||
|
||||
if (!"pom".equals(dependency.getType()) || !"import".equals(dependency.getScope())) {
|
||||
if (!("pom".equals(dependency.getType()) && "import".equals(dependency.getScope()))
|
||||
|| "bom".equals(dependency.getType())) {
|
||||
continue;
|
||||
}
|
||||
|
||||
|
|
|
@ -73,7 +73,7 @@ import org.apache.maven.model.validation.ModelValidator;
|
|||
|
||||
/**
|
||||
* A factory to create model builder instances when no dependency injection is available. <em>Note:</em> This class is
|
||||
* only meant as a utility for developers that want to employ the model builder outside of the Maven build system, Maven
|
||||
* only meant as a utility for developers that want to employ the model builder outside the Maven build system, Maven
|
||||
* plugins should always acquire model builder instances via dependency injection. Developers might want to subclass
|
||||
* this factory to provide custom implementations for some of the components used by the model builder, or use the
|
||||
* builder API to inject custom instances.
|
||||
|
@ -99,6 +99,7 @@ public class DefaultModelBuilderFactory {
|
|||
private ReportConfigurationExpander reportConfigurationExpander;
|
||||
private ProfileActivationFilePathInterpolator profileActivationFilePathInterpolator;
|
||||
private ModelVersionProcessor versionProcessor;
|
||||
private ModelSourceTransformer transformer;
|
||||
|
||||
private RootLocator rootLocator;
|
||||
|
||||
|
@ -208,6 +209,11 @@ public class DefaultModelBuilderFactory {
|
|||
return this;
|
||||
}
|
||||
|
||||
public DefaultModelBuilderFactory setTransformer(ModelSourceTransformer transformer) {
|
||||
this.transformer = transformer;
|
||||
return this;
|
||||
}
|
||||
|
||||
protected ModelProcessor newModelProcessor() {
|
||||
return new DefaultModelProcessor(newModelLocator(), newModelReader());
|
||||
}
|
||||
|
@ -319,7 +325,7 @@ public class DefaultModelBuilderFactory {
|
|||
}
|
||||
|
||||
private ModelSourceTransformer newModelSourceTransformer() {
|
||||
return new DefaultModelSourceTransformer();
|
||||
return new BuildModelSourceTransformer();
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -348,7 +354,8 @@ public class DefaultModelBuilderFactory {
|
|||
profileActivationFilePathInterpolator != null
|
||||
? profileActivationFilePathInterpolator
|
||||
: newProfileActivationFilePathInterpolator(),
|
||||
versionProcessor != null ? versionProcessor : newModelVersionPropertiesProcessor());
|
||||
versionProcessor != null ? versionProcessor : newModelVersionPropertiesProcessor(),
|
||||
transformer != null ? transformer : newModelSourceTransformer());
|
||||
}
|
||||
|
||||
private static class StubLifecycleBindingsInjector implements LifecycleBindingsInjector {
|
||||
|
|
|
@ -81,7 +81,6 @@ public class DefaultModelProcessor implements ModelProcessor {
|
|||
|
||||
public Path locatePom(Path projectDirectory) {
|
||||
// Note that the ModelProcessor#locatePom never returns null
|
||||
// while the ModelParser#locatePom needs to return an existing path!
|
||||
Path pom = modelLocator.locatePom(projectDirectory.toFile()).toPath();
|
||||
if (!pom.equals(projectDirectory) && !pom.getParent().equals(projectDirectory)) {
|
||||
throw new IllegalArgumentException("The POM found does not belong to the given directory: " + pom);
|
||||
|
|
|
@ -1,38 +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.building;
|
||||
|
||||
import javax.xml.stream.XMLStreamReader;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.nio.file.Path;
|
||||
|
||||
/**
|
||||
* Default ModelSourceTransformer, provides pomFile as inputStream and ignores the context
|
||||
*
|
||||
* @since 4.0.0
|
||||
*/
|
||||
public class DefaultModelSourceTransformer implements ModelSourceTransformer {
|
||||
|
||||
@Override
|
||||
public XMLStreamReader transform(XMLStreamReader parser, Path pomFile, TransformerContext context)
|
||||
throws IOException, TransformerException {
|
||||
return parser;
|
||||
}
|
||||
}
|
|
@ -47,6 +47,11 @@ class DefaultTransformerContext implements TransformerContext {
|
|||
|
||||
Holder() {}
|
||||
|
||||
Holder(Model model) {
|
||||
this.model = Objects.requireNonNull(model);
|
||||
this.set = true;
|
||||
}
|
||||
|
||||
public static Model deref(Holder holder) {
|
||||
return holder != null ? holder.get() : null;
|
||||
}
|
||||
|
|
|
@ -55,5 +55,8 @@ public interface ModelBuilder {
|
|||
*/
|
||||
Result<? extends Model> buildRawModel(File pomFile, int validationLevel, boolean locationTracking);
|
||||
|
||||
Result<? extends Model> buildRawModel(
|
||||
File pomFile, int validationLevel, boolean locationTracking, TransformerContext context);
|
||||
|
||||
TransformerContextBuilder newTransformerContextBuilder();
|
||||
}
|
||||
|
|
|
@ -18,15 +18,14 @@
|
|||
*/
|
||||
package org.apache.maven.model.building;
|
||||
|
||||
import javax.xml.stream.XMLStreamReader;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.nio.file.Path;
|
||||
|
||||
import org.apache.maven.model.Model;
|
||||
|
||||
/**
|
||||
* The ModelSourceTransformer is a way to transform the local pom while streaming the input.
|
||||
*
|
||||
* The {@link #transform(XMLStreamReader, Path, TransformerContext)} method uses a Path on purpose, to ensure the
|
||||
* The {@link #transform(Path, TransformerContext, Model)} method uses a Path on purpose, to ensure the
|
||||
* local pom is the original source.
|
||||
*
|
||||
* @since 4.0.0
|
||||
|
@ -36,10 +35,8 @@ public interface ModelSourceTransformer {
|
|||
*
|
||||
* @param pomFile the pom file, cannot be null
|
||||
* @param context the context, cannot be null
|
||||
* @return the InputStream for the ModelReader
|
||||
* @throws IOException if an I/O error occurs
|
||||
* @param model the model to transform
|
||||
* @throws TransformerException if the transformation fails
|
||||
*/
|
||||
XMLStreamReader transform(XMLStreamReader parser, Path pomFile, TransformerContext context)
|
||||
throws IOException, TransformerException;
|
||||
void transform(Path pomFile, TransformerContext context, Model model) throws TransformerException;
|
||||
}
|
||||
|
|
|
@ -35,14 +35,15 @@ public interface TransformerContext {
|
|||
Object KEY = TransformerContext.class;
|
||||
|
||||
/**
|
||||
* Get the value of the commandline argument {@code -Dkey=value}
|
||||
* Get the value of the Maven user property.
|
||||
*
|
||||
* @param key
|
||||
* @return
|
||||
*/
|
||||
String getUserProperty(String key);
|
||||
|
||||
/**
|
||||
* Get the model based on the path, will be used to resolve the parent based on relativePath
|
||||
* Get the model based on the path when resolving the parent based on relativePath.
|
||||
*
|
||||
* @param pomFile the path to the pomFile
|
||||
* @return the model, otherwise {@code null}
|
||||
|
@ -50,7 +51,7 @@ public interface TransformerContext {
|
|||
Model getRawModel(Path pomFile);
|
||||
|
||||
/**
|
||||
* Get the model from the reactor based on the groupId and artifactId, will be used for reactor dependencies
|
||||
* Get the model from the reactor based on the groupId and artifactId when resolving reactor dependencies.
|
||||
*
|
||||
* @param groupId the groupId
|
||||
* @param artifactId the artifactId
|
||||
|
@ -59,5 +60,11 @@ public interface TransformerContext {
|
|||
*/
|
||||
Model getRawModel(String groupId, String artifactId);
|
||||
|
||||
/**
|
||||
* Locate the POM file inside the given directory.
|
||||
*
|
||||
* @param path
|
||||
* @return
|
||||
*/
|
||||
Path locate(Path path);
|
||||
}
|
||||
|
|
|
@ -38,7 +38,6 @@ import java.util.Objects;
|
|||
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.MavenStaxReader;
|
||||
|
||||
/**
|
||||
|
@ -96,28 +95,23 @@ public class DefaultModelReader implements ModelReader {
|
|||
return (InputSource) value;
|
||||
}
|
||||
|
||||
private TransformerContext getTransformerContext(Map<String, ?> options) {
|
||||
Object value = (options != null) ? options.get(TRANSFORMER_CONTEXT) : null;
|
||||
return (TransformerContext) value;
|
||||
}
|
||||
|
||||
private Model read(InputStream input, 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(input);
|
||||
|
||||
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);
|
||||
}
|
||||
MavenStaxReader mr = new MavenStaxReader();
|
||||
mr.setAddLocationInformation(source != null);
|
||||
Model model = new Model(mr.read(
|
||||
parser,
|
||||
strict,
|
||||
source != null
|
||||
? new org.apache.maven.api.model.InputSource(source.getModelId(), source.getLocation())
|
||||
: null));
|
||||
return model;
|
||||
} catch (XMLStreamException e) {
|
||||
Location location = e.getLocation();
|
||||
throw new ModelParseException(
|
||||
|
@ -125,8 +119,6 @@ public class DefaultModelReader implements ModelReader {
|
|||
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);
|
||||
}
|
||||
|
@ -138,17 +130,15 @@ public class DefaultModelReader implements ModelReader {
|
|||
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);
|
||||
}
|
||||
MavenStaxReader mr = new MavenStaxReader();
|
||||
mr.setAddLocationInformation(source != null);
|
||||
Model model = new Model(mr.read(
|
||||
parser,
|
||||
strict,
|
||||
new org.apache.maven.api.model.InputSource(source.getModelId(), source.getLocation())));
|
||||
return model;
|
||||
} catch (XMLStreamException e) {
|
||||
Location location = e.getLocation();
|
||||
throw new ModelParseException(
|
||||
|
@ -156,23 +146,8 @@ public class DefaultModelReader implements ModelReader {
|
|||
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 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())));
|
||||
}
|
||||
}
|
||||
|
|
|
@ -45,12 +45,6 @@ public interface ModelReader {
|
|||
*/
|
||||
String INPUT_SOURCE = "org.apache.maven.model.io.inputSource";
|
||||
|
||||
/**
|
||||
* The key for the option to provide a transformer context, which can be used to transform the input while reading
|
||||
* to get an advanced version of the model.
|
||||
*/
|
||||
String TRANSFORMER_CONTEXT = "transformerContext";
|
||||
|
||||
/**
|
||||
* Reads the model from the specified file.
|
||||
*
|
||||
|
|
|
@ -0,0 +1,150 @@
|
|||
/*
|
||||
* 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.building;
|
||||
|
||||
import java.beans.BeanInfo;
|
||||
import java.beans.Introspector;
|
||||
import java.beans.PropertyDescriptor;
|
||||
import java.nio.file.Path;
|
||||
import java.nio.file.Paths;
|
||||
import java.util.Collections;
|
||||
import java.util.Objects;
|
||||
|
||||
import org.apache.maven.model.Model;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.mockito.Mockito;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.assertTrue;
|
||||
|
||||
public class BuildModelSourceTransformerTest {
|
||||
|
||||
Path pomFile;
|
||||
TransformerContext context = org.mockito.Mockito.mock(TransformerContext.class);
|
||||
|
||||
@Test
|
||||
void testModelVersion() {
|
||||
Model initial = new Model(org.apache.maven.api.model.Model.newBuilder()
|
||||
.namespaceUri("http://maven.apache.org/POM/4.0.0")
|
||||
.build());
|
||||
Model expected = new Model(org.apache.maven.api.model.Model.newBuilder()
|
||||
.namespaceUri("http://maven.apache.org/POM/4.0.0")
|
||||
.modelVersion("4.0.0")
|
||||
.build());
|
||||
Model actual = transform(initial);
|
||||
assertTrue(equalsDeep(expected, actual));
|
||||
}
|
||||
|
||||
@Test
|
||||
void testParent() {
|
||||
Path root = Paths.get(".").toAbsolutePath().normalize();
|
||||
pomFile = root.resolve("child/pom.xml");
|
||||
Model parent = new Model(org.apache.maven.api.model.Model.newBuilder()
|
||||
.groupId("GROUPID")
|
||||
.artifactId("ARTIFACTID")
|
||||
.version("1.0-SNAPSHOT")
|
||||
.build());
|
||||
Mockito.when(context.getRawModel(root.resolve("pom.xml"))).thenReturn(parent);
|
||||
Mockito.when(context.locate(root)).thenReturn(root.resolve("pom.xml"));
|
||||
Model initial = new Model(org.apache.maven.api.model.Model.newBuilder()
|
||||
.parent(org.apache.maven.api.model.Parent.newBuilder()
|
||||
.groupId("GROUPID")
|
||||
.artifactId("ARTIFACTID")
|
||||
.build())
|
||||
.build());
|
||||
Model expected = new Model(org.apache.maven.api.model.Model.newBuilder()
|
||||
.parent(org.apache.maven.api.model.Parent.newBuilder()
|
||||
.groupId("GROUPID")
|
||||
.artifactId("ARTIFACTID")
|
||||
.version("1.0-SNAPSHOT")
|
||||
.build())
|
||||
.build());
|
||||
Model actual = transform(initial);
|
||||
assertTrue(equalsDeep(expected, actual));
|
||||
}
|
||||
|
||||
@Test
|
||||
void testReactorDependencies() {
|
||||
Model dep = new Model(org.apache.maven.api.model.Model.newBuilder()
|
||||
.groupId("GROUPID")
|
||||
.artifactId("ARTIFACTID")
|
||||
.version("1.0-SNAPSHOT")
|
||||
.build());
|
||||
Mockito.when(context.getRawModel("GROUPID", "ARTIFACTID")).thenReturn(dep);
|
||||
Model initial = new Model(org.apache.maven.api.model.Model.newBuilder()
|
||||
.dependencies(Collections.singleton(org.apache.maven.api.model.Dependency.newBuilder()
|
||||
.groupId("GROUPID")
|
||||
.artifactId("ARTIFACTID")
|
||||
.build()))
|
||||
.build());
|
||||
Model expected = new Model(org.apache.maven.api.model.Model.newBuilder()
|
||||
.dependencies(Collections.singleton(org.apache.maven.api.model.Dependency.newBuilder()
|
||||
.groupId("GROUPID")
|
||||
.artifactId("ARTIFACTID")
|
||||
.version("1.0-SNAPSHOT")
|
||||
.build()))
|
||||
.build());
|
||||
Model actual = transform(initial);
|
||||
assertTrue(equalsDeep(expected, actual));
|
||||
}
|
||||
|
||||
@Test
|
||||
void testCiFriendlyVersion() {
|
||||
Model initial = new Model(org.apache.maven.api.model.Model.newBuilder()
|
||||
.version("${revision}-${sha1}")
|
||||
.build());
|
||||
Mockito.when(context.getUserProperty("revision")).thenReturn("therev");
|
||||
Mockito.when(context.getUserProperty("sha1")).thenReturn("thesha");
|
||||
Model expected = new Model(org.apache.maven.api.model.Model.newBuilder()
|
||||
.version("therev-thesha")
|
||||
.build());
|
||||
Model actual = transform(initial);
|
||||
assertTrue(equalsDeep(expected, actual));
|
||||
}
|
||||
|
||||
Model transform(Model model) {
|
||||
Model transformed = model.clone();
|
||||
new BuildModelSourceTransformer().transform(pomFile, context, transformed);
|
||||
return transformed;
|
||||
}
|
||||
|
||||
public static boolean equalsDeep(Object m1, Object m2) {
|
||||
try {
|
||||
if (m1 == m2) {
|
||||
return true;
|
||||
}
|
||||
if (m1 == null || m2 == null) {
|
||||
return false;
|
||||
}
|
||||
if (!Objects.equals(m1.getClass(), m2.getClass())) {
|
||||
return false;
|
||||
}
|
||||
BeanInfo bean = Introspector.getBeanInfo(m1.getClass());
|
||||
for (PropertyDescriptor prop : bean.getPropertyDescriptors()) {
|
||||
Object p1 = prop.getReadMethod().invoke(m1);
|
||||
Object p2 = prop.getReadMethod().invoke(m2);
|
||||
if (!equalsDeep(p1, p2)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
} catch (Exception e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -18,17 +18,11 @@
|
|||
*/
|
||||
package org.apache.maven.model.inheritance;
|
||||
|
||||
import javax.xml.stream.XMLStreamReader;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.nio.file.Path;
|
||||
|
||||
import org.apache.maven.api.model.Model;
|
||||
import org.apache.maven.model.building.AbstractModelSourceTransformer;
|
||||
import org.apache.maven.model.building.SimpleProblemCollector;
|
||||
import org.apache.maven.model.building.TransformerContext;
|
||||
import org.apache.maven.model.building.TransformerException;
|
||||
import org.apache.maven.model.io.DefaultModelReader;
|
||||
import org.apache.maven.model.io.DefaultModelWriter;
|
||||
import org.apache.maven.model.io.ModelWriter;
|
||||
|
@ -51,13 +45,7 @@ class DefaultInheritanceAssemblerTest {
|
|||
|
||||
@BeforeEach
|
||||
void setUp() throws Exception {
|
||||
reader = new DefaultModelReader(new AbstractModelSourceTransformer() {
|
||||
@Override
|
||||
public XMLStreamReader transform(XMLStreamReader parser, Path pomFile, TransformerContext context)
|
||||
throws IOException, TransformerException {
|
||||
return null;
|
||||
}
|
||||
});
|
||||
reader = new DefaultModelReader(null);
|
||||
writer = new DefaultModelWriter();
|
||||
assembler = new DefaultInheritanceAssembler();
|
||||
}
|
||||
|
|
|
@ -1,64 +0,0 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!--
|
||||
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.
|
||||
-->
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<parent>
|
||||
<groupId>org.apache.maven</groupId>
|
||||
<artifactId>maven</artifactId>
|
||||
<version>4.0.0-alpha-8-SNAPSHOT</version>
|
||||
</parent>
|
||||
<artifactId>maven-model-transform</artifactId>
|
||||
<name>Maven Model XML Transform</name>
|
||||
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>org.apache.maven</groupId>
|
||||
<artifactId>maven-model</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<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>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.xmlunit</groupId>
|
||||
<artifactId>xmlunit-assertj</artifactId>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.mockito</groupId>
|
||||
<artifactId>mockito-core</artifactId>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
|
||||
</dependencies>
|
||||
</project>
|
|
@ -1,100 +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;
|
||||
|
||||
import javax.xml.stream.XMLStreamReader;
|
||||
|
||||
import java.nio.file.Path;
|
||||
import java.util.Optional;
|
||||
import java.util.function.BiFunction;
|
||||
import java.util.function.Function;
|
||||
|
||||
/**
|
||||
* Base implementation for providing the BuildToRawPomXML.
|
||||
*
|
||||
* @since 4.0.0
|
||||
*/
|
||||
public class BuildToRawPomXMLFilterFactory {
|
||||
private final boolean consume;
|
||||
|
||||
public BuildToRawPomXMLFilterFactory() {
|
||||
this(false);
|
||||
}
|
||||
|
||||
public BuildToRawPomXMLFilterFactory(boolean consume) {
|
||||
this.consume = consume;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param projectFile will be used by ConsumerPomXMLFilter to get the right filter
|
||||
*/
|
||||
public final XMLStreamReader get(XMLStreamReader orgParser, Path projectFile) {
|
||||
|
||||
// Ensure that xs:any elements aren't touched by next filters
|
||||
XMLStreamReader parser = orgParser instanceof FastForwardFilter ? orgParser : new FastForwardFilter(orgParser);
|
||||
|
||||
if (getDependencyKeyToVersionMapper() != null) {
|
||||
parser = new ReactorDependencyXMLFilter(parser, getDependencyKeyToVersionMapper());
|
||||
}
|
||||
|
||||
if (getRelativePathMapper() != null) {
|
||||
parser = new ParentXMLFilter(parser, getRelativePathMapper(), getModelLocator(), projectFile.getParent());
|
||||
}
|
||||
|
||||
CiFriendlyXMLFilter ciFriendlyFilter = new CiFriendlyXMLFilter(parser, consume);
|
||||
getChangelist().ifPresent(ciFriendlyFilter::setChangelist);
|
||||
getRevision().ifPresent(ciFriendlyFilter::setRevision);
|
||||
getSha1().ifPresent(ciFriendlyFilter::setSha1);
|
||||
parser = ciFriendlyFilter;
|
||||
|
||||
parser = new ModelVersionXMLFilter(parser);
|
||||
|
||||
return parser;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the mapper or {@code null} if relativePaths don't need to be mapped
|
||||
*/
|
||||
protected Function<Path, Optional<RelativeProject>> getRelativePathMapper() {
|
||||
return null;
|
||||
}
|
||||
|
||||
protected Function<Path, Path> getModelLocator() {
|
||||
return null;
|
||||
}
|
||||
|
||||
protected BiFunction<String, String, String> getDependencyKeyToVersionMapper() {
|
||||
return null;
|
||||
}
|
||||
|
||||
// getters for the 3 magic properties of CIFriendly versions ( https://maven.apache.org/maven-ci-friendly.html )
|
||||
|
||||
protected Optional<String> getChangelist() {
|
||||
return Optional.empty();
|
||||
}
|
||||
|
||||
protected Optional<String> getRevision() {
|
||||
return Optional.empty();
|
||||
}
|
||||
|
||||
protected Optional<String> getSha1() {
|
||||
return Optional.empty();
|
||||
}
|
||||
}
|
|
@ -1,74 +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;
|
||||
|
||||
import javax.xml.stream.XMLStreamReader;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.function.Function;
|
||||
|
||||
import org.apache.maven.model.transform.stax.NodeBufferingParser;
|
||||
|
||||
/**
|
||||
* Resolves all ci-friendly properties occurrences between version-tags
|
||||
*
|
||||
* @since 4.0.0
|
||||
*/
|
||||
class CiFriendlyXMLFilter extends NodeBufferingParser {
|
||||
private final boolean replace;
|
||||
|
||||
private Function<String, String> replaceChain = Function.identity();
|
||||
|
||||
CiFriendlyXMLFilter(XMLStreamReader delegate, boolean replace) {
|
||||
super(delegate, "version");
|
||||
this.replace = replace;
|
||||
}
|
||||
|
||||
public CiFriendlyXMLFilter setChangelist(String changelist) {
|
||||
replaceChain = replaceChain.andThen(t -> t.replace("${changelist}", changelist));
|
||||
return this;
|
||||
}
|
||||
|
||||
public CiFriendlyXMLFilter setRevision(String revision) {
|
||||
replaceChain = replaceChain.andThen(t -> t.replace("${revision}", revision));
|
||||
return this;
|
||||
}
|
||||
|
||||
public CiFriendlyXMLFilter setSha1(String sha1) {
|
||||
replaceChain = replaceChain.andThen(t -> t.replace("${sha1}", sha1));
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return {@code true} is any of the ci properties is set, otherwise {@code false}
|
||||
*/
|
||||
public boolean isSet() {
|
||||
return !replaceChain.equals(Function.identity());
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void process(List<Event> buffer) {
|
||||
for (Event event : buffer) {
|
||||
if (event.event == CHARACTERS && replace && event.text.contains("${")) {
|
||||
event.text = replaceChain.apply(event.text);
|
||||
}
|
||||
pushEvent(event);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,102 +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;
|
||||
|
||||
import javax.xml.stream.XMLStreamException;
|
||||
import javax.xml.stream.XMLStreamReader;
|
||||
|
||||
import java.util.ArrayDeque;
|
||||
import java.util.Deque;
|
||||
|
||||
import org.apache.maven.model.transform.stax.BufferingParser;
|
||||
|
||||
/**
|
||||
* This filter will bypass all following filters and write directly to the output.
|
||||
* Should be used in case of a DOM that should not be effected by other filters,
|
||||
* even though the elements match.
|
||||
*
|
||||
* @since 4.0.0
|
||||
*/
|
||||
class FastForwardFilter extends BufferingParser {
|
||||
/**
|
||||
* DOM elements of pom
|
||||
*
|
||||
* <ul>
|
||||
* <li>execution.configuration</li>
|
||||
* <li>plugin.configuration</li>
|
||||
* <li>plugin.goals</li>
|
||||
* <li>profile.reports</li>
|
||||
* <li>project.reports</li>
|
||||
* <li>reportSet.configuration</li>
|
||||
* <ul>
|
||||
*/
|
||||
private final Deque<String> state = new ArrayDeque<>();
|
||||
|
||||
private int domDepth = 0;
|
||||
|
||||
FastForwardFilter(XMLStreamReader delegate) {
|
||||
super(delegate);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int next() throws XMLStreamException {
|
||||
int event = super.next();
|
||||
filter();
|
||||
return event;
|
||||
}
|
||||
|
||||
protected void filter() throws XMLStreamException {
|
||||
if (delegate.getEventType() == START_ELEMENT) {
|
||||
String localName = delegate.getLocalName();
|
||||
if (domDepth > 0) {
|
||||
domDepth++;
|
||||
} else {
|
||||
final String key = state.peekLast() + '/' + localName;
|
||||
switch (key) {
|
||||
case "execution/configuration":
|
||||
case "plugin/configuration":
|
||||
case "plugin/goals":
|
||||
case "profile/reports":
|
||||
case "project/reports":
|
||||
case "reportSet/configuration":
|
||||
if (domDepth == 0) {
|
||||
bypass(true);
|
||||
}
|
||||
domDepth++;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
state.add(localName);
|
||||
} else if (delegate.getEventType() == END_ELEMENT) {
|
||||
if (domDepth > 0) {
|
||||
if (--domDepth == 0) {
|
||||
bypass(false);
|
||||
}
|
||||
}
|
||||
state.removeLast();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void bypass(boolean bypass) {
|
||||
this.bypass = bypass;
|
||||
}
|
||||
}
|
|
@ -1,113 +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;
|
||||
|
||||
import javax.xml.stream.XMLStreamException;
|
||||
import javax.xml.stream.XMLStreamReader;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import org.apache.maven.api.model.Model;
|
||||
import org.apache.maven.model.transform.stax.BufferingParser;
|
||||
import org.apache.maven.model.v4.MavenModelVersion;
|
||||
import org.apache.maven.model.v4.MavenStaxReader;
|
||||
|
||||
public class ModelVersionDowngradeXMLFilter extends BufferingParser {
|
||||
|
||||
public static final String NAMESPACE_PREFIX = "http://maven.apache.org/POM/";
|
||||
|
||||
private final List<Event> buffer = new ArrayList<>();
|
||||
|
||||
public ModelVersionDowngradeXMLFilter(XMLStreamReader delegate) {
|
||||
super(delegate);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean accept() throws XMLStreamException {
|
||||
Event e = bufferEvent();
|
||||
buffer.add(e);
|
||||
if (e.event == XMLStreamReader.END_DOCUMENT) {
|
||||
ReplayParser p = new ReplayParser(this);
|
||||
buffer.forEach(p::pushEvent);
|
||||
p.next();
|
||||
String version;
|
||||
Model model = new MavenStaxReader().read(p, false, null);
|
||||
if (model.isPreserveModelVersion()) {
|
||||
version = model.getModelVersion();
|
||||
} else {
|
||||
model = model.withPreserveModelVersion(false);
|
||||
version = new MavenModelVersion().getModelVersion(model);
|
||||
}
|
||||
int depth = 0;
|
||||
boolean isModelVersion = false;
|
||||
for (Event event : buffer) {
|
||||
event.namespace = NAMESPACE_PREFIX + version;
|
||||
// rewrite namespace
|
||||
if (event.namespaces != null) {
|
||||
for (int i = 0; i < event.namespaces.length; i++) {
|
||||
if (event.namespaces[i].uri.startsWith(NAMESPACE_PREFIX)) {
|
||||
event.namespaces[i].uri = event.namespace;
|
||||
}
|
||||
}
|
||||
}
|
||||
// rewrite xsi:schemaLocation attribute
|
||||
if (event.attributes != null) {
|
||||
for (Attribute attribute : event.attributes) {
|
||||
if (attribute.namespace.equals("http://www.w3.org/2001/XMLSchema-instance")
|
||||
&& attribute.name.equals("schemaLocation")) {
|
||||
attribute.value = attribute
|
||||
.value
|
||||
.replaceAll(
|
||||
"\\Q" + NAMESPACE_PREFIX + "\\E[0-9]\\.[0-9]\\.[0-9]",
|
||||
NAMESPACE_PREFIX + version)
|
||||
.replaceAll(
|
||||
"http(s?)://maven\\.apache\\.org/xsd/maven-[0-9]\\.[0-9]\\.[0-9]\\.xsd",
|
||||
"https://maven.apache.org/xsd/maven-" + version + ".xsd");
|
||||
}
|
||||
}
|
||||
}
|
||||
// Rewrite modelVersion
|
||||
if (event.event == XMLStreamReader.START_ELEMENT) {
|
||||
depth++;
|
||||
isModelVersion = depth == 2 && event.name.equals("modelVersion");
|
||||
}
|
||||
if (event.event == XMLStreamReader.CHARACTERS && isModelVersion) {
|
||||
event.text = version;
|
||||
}
|
||||
if (event.event == XMLStreamReader.END_ELEMENT) {
|
||||
depth--;
|
||||
isModelVersion = false;
|
||||
}
|
||||
pushEvent(event);
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
static class ReplayParser extends BufferingParser {
|
||||
ReplayParser(XMLStreamReader delegate) {
|
||||
super(delegate);
|
||||
}
|
||||
|
||||
public void pushEvent(Event e) {
|
||||
super.pushEvent(e);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,84 +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;
|
||||
|
||||
import javax.xml.stream.XMLStreamReader;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
import org.apache.maven.model.transform.stax.NodeBufferingParser;
|
||||
|
||||
public class ModelVersionXMLFilter extends NodeBufferingParser {
|
||||
|
||||
public static final String NAMESPACE_PREFIX = "http://maven.apache.org/POM/";
|
||||
|
||||
private static final Pattern S_FILTER = Pattern.compile("\\s+");
|
||||
|
||||
public ModelVersionXMLFilter(XMLStreamReader delegate) {
|
||||
super(delegate, "project");
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void process(List<Event> buffer) {
|
||||
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 == START_ELEMENT) {
|
||||
Event prev = buffer.get(pos - 1);
|
||||
if (prev.event != CHARACTERS
|
||||
|| !S_FILTER.matcher(prev.text).matches()) {
|
||||
prev = null;
|
||||
}
|
||||
Event pmse = new Event();
|
||||
pmse.event = START_ELEMENT;
|
||||
pmse.name = "modelVersion";
|
||||
pmse.namespace = namespace;
|
||||
pmse.prefix = prefix;
|
||||
buffer.add(pos++, pmse);
|
||||
Event pmve = new Event();
|
||||
pmve.event = CHARACTERS;
|
||||
pmve.text = namespace.substring(NAMESPACE_PREFIX.length());
|
||||
buffer.add(pos++, pmve);
|
||||
Event pmee = new Event();
|
||||
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 == START_ELEMENT
|
||||
&& "project".equals(e.name)
|
||||
&& e.namespace != null
|
||||
&& e.namespace.startsWith(NAMESPACE_PREFIX)) {
|
||||
namespace = e.namespace;
|
||||
prefix = e.prefix;
|
||||
}
|
||||
}
|
||||
}
|
||||
buffer.forEach(this::pushEvent);
|
||||
}
|
||||
}
|
|
@ -1,40 +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;
|
||||
|
||||
import javax.xml.stream.XMLStreamReader;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import org.apache.maven.model.transform.stax.NodeBufferingParser;
|
||||
|
||||
/**
|
||||
* Remove all modules, this is just buildtime information
|
||||
*
|
||||
* @since 4.0.0
|
||||
*/
|
||||
class ModulesXMLFilter extends NodeBufferingParser {
|
||||
ModulesXMLFilter(XMLStreamReader delegate) {
|
||||
super(delegate, "modules");
|
||||
}
|
||||
|
||||
protected void process(List<Event> buffer) {
|
||||
// Do nothing, as we want to delete those nodes completely
|
||||
}
|
||||
}
|
|
@ -1,151 +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;
|
||||
|
||||
import javax.xml.stream.XMLStreamReader;
|
||||
|
||||
import java.nio.file.Path;
|
||||
import java.nio.file.Paths;
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
import java.util.Optional;
|
||||
import java.util.function.Function;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
import org.apache.maven.model.transform.stax.NodeBufferingParser;
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* Transforms relativePath to version.
|
||||
* We could decide to simply allow {@code <parent/>}, but let's require the GA for now for checking
|
||||
* This filter does NOT remove the relativePath (which is done by {@link RelativePathXMLFilter}, it will only
|
||||
* optionally include the version based on the path
|
||||
* </p>
|
||||
*
|
||||
* @since 4.0.0
|
||||
*/
|
||||
class ParentXMLFilter extends NodeBufferingParser {
|
||||
|
||||
private final Function<Path, Optional<RelativeProject>> relativePathMapper;
|
||||
|
||||
private final Function<Path, Path> modelLocator;
|
||||
|
||||
private final Path projectPath;
|
||||
|
||||
private static final Pattern S_FILTER = Pattern.compile("\\s+");
|
||||
|
||||
/**
|
||||
* @param relativePathMapper
|
||||
*/
|
||||
ParentXMLFilter(
|
||||
XMLStreamReader delegate,
|
||||
Function<Path, Optional<RelativeProject>> relativePathMapper,
|
||||
Function<Path, Path> modelLocator,
|
||||
Path projectPath) {
|
||||
super(delegate, "parent");
|
||||
this.relativePathMapper = relativePathMapper;
|
||||
this.modelLocator = modelLocator;
|
||||
this.projectPath = projectPath;
|
||||
}
|
||||
|
||||
protected void process(List<Event> buffer) {
|
||||
String tagName = null;
|
||||
String groupId = null;
|
||||
String artifactId = null;
|
||||
String version = null;
|
||||
String relativePath = null;
|
||||
String whitespaceAfterParentStart = "";
|
||||
boolean hasVersion = false;
|
||||
boolean hasRelativePath = false;
|
||||
for (int i = 0; i < buffer.size(); i++) {
|
||||
Event event = buffer.get(i);
|
||||
if (event.event == START_ELEMENT) {
|
||||
tagName = event.name;
|
||||
hasVersion |= "version".equals(tagName);
|
||||
hasRelativePath |= "relativePath".equals(tagName);
|
||||
} else if (event.event == CHARACTERS) {
|
||||
if (S_FILTER.matcher(event.text).matches()) {
|
||||
if (whitespaceAfterParentStart.isEmpty()) {
|
||||
whitespaceAfterParentStart = event.text;
|
||||
}
|
||||
} else if ("groupId".equals(tagName)) {
|
||||
groupId = nullSafeAppend(groupId, event.text);
|
||||
} else if ("artifactId".equals(tagName)) {
|
||||
artifactId = nullSafeAppend(artifactId, event.text);
|
||||
} else if ("relativePath".equals(tagName)) {
|
||||
relativePath = nullSafeAppend(relativePath, event.text);
|
||||
} else if ("version".equals(tagName)) {
|
||||
version = nullSafeAppend(version, event.text);
|
||||
}
|
||||
} 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, ".."));
|
||||
resolvedParent = resolveRelativePath(relPath, groupId, artifactId);
|
||||
} else {
|
||||
resolvedParent = Optional.empty();
|
||||
}
|
||||
if (!hasVersion && resolvedParent.isPresent()) {
|
||||
int pos = buffer.get(i - 1).event == CHARACTERS ? i - 1 : i;
|
||||
Event e = new Event();
|
||||
e.event = CHARACTERS;
|
||||
e.text = whitespaceAfterParentStart;
|
||||
buffer.add(pos++, e);
|
||||
e = new Event();
|
||||
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 = CHARACTERS;
|
||||
e.text = resolvedParent.get().getVersion();
|
||||
buffer.add(pos++, e);
|
||||
e = new Event();
|
||||
e.event = END_ELEMENT;
|
||||
e.name = "version";
|
||||
e.namespace = buffer.get(0).namespace;
|
||||
e.prefix = buffer.get(0).prefix;
|
||||
buffer.add(pos++, e);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
buffer.forEach(this::pushEvent);
|
||||
}
|
||||
|
||||
protected Optional<RelativeProject> resolveRelativePath(Path relativePath, String groupId, String artifactId) {
|
||||
Path pomPath = modelLocator.apply(projectPath.resolve(relativePath).normalize());
|
||||
|
||||
if (pomPath == null) {
|
||||
return Optional.empty();
|
||||
}
|
||||
|
||||
Optional<RelativeProject> mappedProject = relativePathMapper.apply(pomPath.normalize());
|
||||
|
||||
if (mappedProject.isPresent()) {
|
||||
RelativeProject project = mappedProject.get();
|
||||
|
||||
if (Objects.equals(groupId, project.getGroupId()) && Objects.equals(artifactId, project.getArtifactId())) {
|
||||
return mappedProject;
|
||||
}
|
||||
}
|
||||
return Optional.empty();
|
||||
}
|
||||
}
|
|
@ -1,52 +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;
|
||||
|
||||
import javax.xml.stream.XMLStreamReader;
|
||||
|
||||
import java.nio.file.Path;
|
||||
|
||||
/**
|
||||
* @since 4.0.0
|
||||
*/
|
||||
public class RawToConsumerPomXMLFilterFactory {
|
||||
private BuildToRawPomXMLFilterFactory buildPomXMLFilterFactory;
|
||||
|
||||
public RawToConsumerPomXMLFilterFactory(BuildToRawPomXMLFilterFactory buildPomXMLFilterFactory) {
|
||||
this.buildPomXMLFilterFactory = buildPomXMLFilterFactory;
|
||||
}
|
||||
|
||||
public final XMLStreamReader get(XMLStreamReader orgParser, Path projectPath) {
|
||||
// Ensure that xs:any elements aren't touched by next filters
|
||||
XMLStreamReader parser = orgParser instanceof FastForwardFilter ? orgParser : new FastForwardFilter(orgParser);
|
||||
|
||||
parser = buildPomXMLFilterFactory.get(parser, projectPath);
|
||||
|
||||
// Remove root model attribute
|
||||
parser = new RootXMLFilter(parser);
|
||||
// Strip modules
|
||||
parser = new ModulesXMLFilter(parser);
|
||||
// Adjust relativePath
|
||||
parser = new RelativePathXMLFilter(parser);
|
||||
// Downgrade modelVersion if needed
|
||||
parser = new ModelVersionDowngradeXMLFilter(parser);
|
||||
|
||||
return parser;
|
||||
}
|
||||
}
|
|
@ -1,97 +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;
|
||||
|
||||
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.stax.NodeBufferingParser;
|
||||
|
||||
/**
|
||||
* Will apply the version if the dependency is part of the reactor
|
||||
*
|
||||
* @since 4.0.0
|
||||
*/
|
||||
public class ReactorDependencyXMLFilter extends NodeBufferingParser {
|
||||
private final BiFunction<String, String, String> reactorVersionMapper;
|
||||
|
||||
private static final Pattern S_FILTER = Pattern.compile("\\s+");
|
||||
|
||||
public ReactorDependencyXMLFilter(
|
||||
XMLStreamReader delegate, BiFunction<String, String, String> reactorVersionMapper) {
|
||||
super(delegate, "dependency");
|
||||
this.reactorVersionMapper = reactorVersionMapper;
|
||||
}
|
||||
|
||||
protected void process(List<Event> buffer) {
|
||||
// whiteSpace after <dependency>, to be used to position <version>
|
||||
String dependencyWhitespace = "";
|
||||
boolean hasVersion = false;
|
||||
String groupId = null;
|
||||
String artifactId = null;
|
||||
String tagName = null;
|
||||
for (int i = 0; i < buffer.size(); i++) {
|
||||
Event event = buffer.get(i);
|
||||
if (event.event == START_ELEMENT) {
|
||||
tagName = event.name;
|
||||
hasVersion |= "version".equals(tagName);
|
||||
} else if (event.event == CHARACTERS) {
|
||||
if (S_FILTER.matcher(event.text).matches()) {
|
||||
if (dependencyWhitespace.isEmpty()) {
|
||||
dependencyWhitespace = event.text;
|
||||
}
|
||||
} else if ("groupId".equals(tagName)) {
|
||||
groupId = nullSafeAppend(groupId, event.text);
|
||||
} else if ("artifactId".equals(tagName)) {
|
||||
artifactId = nullSafeAppend(artifactId, event.text);
|
||||
}
|
||||
} 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 == CHARACTERS ? i - 1 : i;
|
||||
Event e = new Event();
|
||||
e.event = CHARACTERS;
|
||||
e.text = dependencyWhitespace;
|
||||
buffer.add(pos++, e);
|
||||
e = new Event();
|
||||
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 = CHARACTERS;
|
||||
e.text = version;
|
||||
buffer.add(pos++, e);
|
||||
e = new Event();
|
||||
e.event = END_ELEMENT;
|
||||
e.name = "version";
|
||||
e.namespace = buffer.get(0).namespace;
|
||||
e.prefix = buffer.get(0).prefix;
|
||||
buffer.add(pos++, e);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
buffer.forEach(this::pushEvent);
|
||||
}
|
||||
}
|
|
@ -1,66 +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;
|
||||
|
||||
import javax.xml.stream.XMLStreamReader;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
import org.apache.maven.model.transform.stax.NodeBufferingParser;
|
||||
|
||||
/**
|
||||
* Remove relativePath element, has no value for consumer pom
|
||||
*
|
||||
* @since 4.0.0
|
||||
*/
|
||||
public class RelativePathXMLFilter extends NodeBufferingParser {
|
||||
|
||||
private static final Pattern S_FILTER = Pattern.compile("\\s+");
|
||||
|
||||
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_ELEMENT && "relativePath".equals(event.name)) {
|
||||
skip = true;
|
||||
if (prev != null
|
||||
&& prev.event == CHARACTERS
|
||||
&& S_FILTER.matcher(prev.text).matches()) {
|
||||
prev = null;
|
||||
}
|
||||
event = null;
|
||||
} else if (event.event == END_ELEMENT && "relativePath".equals(event.name)) {
|
||||
skip = false;
|
||||
event = null;
|
||||
} else if (skip) {
|
||||
event = null;
|
||||
}
|
||||
if (prev != null) {
|
||||
pushEvent(prev);
|
||||
}
|
||||
prev = event;
|
||||
}
|
||||
pushEvent(prev);
|
||||
}
|
||||
}
|
|
@ -1,49 +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;
|
||||
|
||||
/**
|
||||
*
|
||||
* @since 4.0.0
|
||||
*/
|
||||
public class RelativeProject {
|
||||
private final String groupId;
|
||||
|
||||
private final String artifactId;
|
||||
|
||||
private final String version;
|
||||
|
||||
public RelativeProject(String groupId, String artifactId, String version) {
|
||||
this.groupId = groupId;
|
||||
this.artifactId = artifactId;
|
||||
this.version = version;
|
||||
}
|
||||
|
||||
public String getGroupId() {
|
||||
return groupId;
|
||||
}
|
||||
|
||||
public String getArtifactId() {
|
||||
return artifactId;
|
||||
}
|
||||
|
||||
public String getVersion() {
|
||||
return version;
|
||||
}
|
||||
}
|
|
@ -1,60 +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;
|
||||
|
||||
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.stax.BufferingParser;
|
||||
|
||||
/**
|
||||
* Remove the root attribute on the model
|
||||
*
|
||||
* @since 4.0.0
|
||||
*/
|
||||
class RootXMLFilter extends BufferingParser {
|
||||
|
||||
final Deque<String> elements = new ArrayDeque<>();
|
||||
|
||||
RootXMLFilter(XMLStreamReader delegate) {
|
||||
super(delegate);
|
||||
}
|
||||
|
||||
@Override
|
||||
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))
|
||||
.toArray(Attribute[]::new);
|
||||
pushEvent(event);
|
||||
return false;
|
||||
}
|
||||
} else if (delegate.getEventType() == END_ELEMENT) {
|
||||
elements.pop();
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
|
@ -1,523 +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.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;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,72 +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.stax;
|
||||
|
||||
import javax.xml.stream.XMLStreamException;
|
||||
import javax.xml.stream.XMLStreamReader;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
|
||||
/**
|
||||
* Buffer events while parsing a given element to allow some post-processing.
|
||||
*
|
||||
* @since 4.0.0
|
||||
*/
|
||||
public abstract class NodeBufferingParser extends BufferingParser {
|
||||
|
||||
private final List<Event> buffer = new ArrayList<>();
|
||||
|
||||
private final String nodeName;
|
||||
|
||||
private boolean buffering;
|
||||
|
||||
public NodeBufferingParser(XMLStreamReader delegate, String nodeName) {
|
||||
super(delegate);
|
||||
this.nodeName = Objects.requireNonNull(nodeName);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean accept() throws XMLStreamException {
|
||||
if (!buffering && delegate.getEventType() == START_ELEMENT && nodeName.equals(delegate.getLocalName())) {
|
||||
buffer.add(bufferEvent());
|
||||
buffering = true;
|
||||
return false;
|
||||
} else if (buffering && delegate.getEventType() == END_ELEMENT && nodeName.equals(delegate.getLocalName())) {
|
||||
buffer.add(bufferEvent());
|
||||
process(buffer);
|
||||
buffering = false;
|
||||
buffer.clear();
|
||||
return false;
|
||||
} else if (buffering) {
|
||||
buffer.add(bufferEvent());
|
||||
return false;
|
||||
} else {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean bypass() {
|
||||
return !buffering && super.bypass();
|
||||
}
|
||||
|
||||
protected abstract void process(List<Event> buffer);
|
||||
}
|
|
@ -1,187 +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.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();
|
||||
}
|
||||
}
|
|
@ -1,73 +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.
|
||||
|
||||
-----
|
||||
Introduction
|
||||
-----
|
||||
Hervé Boutemy
|
||||
-----
|
||||
2021-04-04
|
||||
-----
|
||||
|
||||
Maven Model XML Transformer
|
||||
|
||||
Maven Model XML Transformer provides build/consumer <<<pom.xml>>> transformers.
|
||||
|
||||
In order to keep formatting, comments and every detail when transforming a build <<<pom.xml>>> to a consumer <<<pom.xml>>>, transformation happens directly on the stream of SAX events.
|
||||
|
||||
There are 3 states of a <<<pom.xml>>> content:
|
||||
|
||||
[[1]] the <<build>> <<<pom.xml>>>, as it is stored on disk during development and in source control, which can be simplified to ease source code maintenance,
|
||||
|
||||
[[2]] the <<raw>> content (usually not saved to a file), which is enriched from initial build content, to match Maven Model validation rules,
|
||||
|
||||
[[3]] the <<consumer>> <<<pom.xml>>>, as it is saved to local repository or remote repository, to be used as dependencies descriptor when consumed by a project.
|
||||
|
||||
[]
|
||||
|
||||
Transformation is implemented as two filters:
|
||||
|
||||
* <<build to raw>> in <<<BuildToRawPomXMLFilter>>> ({{{./apidocs/org/apache/maven/model/transform/BuildPomToRawXMLFilter.html}javadoc}}),
|
||||
with its <<<BuildToRawPomXMLFilterFactory>>> ({{{./xref/org/apache/maven/model/transform/BuildToRawPomXMLFilterFactory.html}source}}) assembling transformation steps,
|
||||
|
||||
* in a multi-module build, <<<parent>>>'s <<<version>>> is automatically added,
|
||||
|
||||
* in a multi-module build, dependencies <<<version>>> is automatically added for reactor modules,
|
||||
|
||||
* CI-friendly <<<$\{sha1}>>>, <<<$\{revision}>>> and <<<$\{changelist}>>> are properties are replaced with their value,
|
||||
|
||||
[]
|
||||
|
||||
* <<raw to consumer>> in <<<RawToConsumerPomXMLFilter>>> ({{{./apidocs/org/apache/maven/model/transform/RawToConsumerPomXMLFilter.html}javadoc}}),
|
||||
with its <<<RawToConsumerPomXMLFilterFactory>>> ({{{./xref/org/apache/maven/model/transform/RawToConsumerPomXMLFilterFactory.html}source}}) assembling transformation steps.
|
||||
|
||||
* <<<modules>>> is stripped because it only has a meaning at build time on disk, but not once mapped to repository format,
|
||||
|
||||
* <<<parent>>>'s <<<relativePath>>> is stripped because it only has a meaning at build time on disk, but not once mapped to repository format.
|
||||
|
||||
[]
|
||||
|
||||
[]
|
||||
|
||||
For Maven 4, every state of Maven Model remains with the same <<<maven-4.0.0.xsd>>> schema, but it the future Maven 5+:
|
||||
|
||||
* build model should evolve to add new features configuration in new <v5> model fields, or remove some old unused fields,
|
||||
|
||||
* consumer model should at least continue to produce a <<<maven-4.0.0.xsd>>>-compliant <<<pom.xml>>> for compatibility with the vast and diverse dependency consumers ecosystem,
|
||||
but may also produce in parallel new consumption formats (yet to be defined).
|
||||
|
||||
[]
|
|
@ -1,38 +0,0 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
|
||||
<!--
|
||||
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.
|
||||
-->
|
||||
|
||||
<project xmlns="http://maven.apache.org/DECORATION/1.8.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://maven.apache.org/DECORATION/1.8.0 http://maven.apache.org/xsd/decoration-1.8.0.xsd">
|
||||
|
||||
<edit>${project.scm.url}</edit>
|
||||
|
||||
<body>
|
||||
<menu name="Overview">
|
||||
<item name="Introduction" href="index.html"/>
|
||||
<item name="Javadocs" href="apidocs/index.html"/>
|
||||
<item name="Source Xref" href="xref/index.html"/>
|
||||
<!--item name="FAQ" href="faq.html"/-->
|
||||
</menu>
|
||||
|
||||
<menu ref="parent"/>
|
||||
<menu ref="reports"/>
|
||||
</body>
|
||||
</project>
|
|
@ -1,49 +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;
|
||||
|
||||
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 org.apache.maven.model.transform.stax.XmlUtils;
|
||||
|
||||
public abstract class AbstractXMLFilterTests {
|
||||
protected XMLStreamReader getFilter(XMLStreamReader parser) {
|
||||
throw new UnsupportedOperationException("Override one of the getFilter() methods");
|
||||
}
|
||||
|
||||
protected String transform(String input) throws XMLStreamException, IOException {
|
||||
return transform(new StringReader(input));
|
||||
}
|
||||
|
||||
protected String transform(Reader input) throws XMLStreamException, IOException {
|
||||
XMLStreamReader parser = XMLInputFactory.newFactory().createXMLStreamReader(input);
|
||||
XMLStreamReader filter = getFilter(parser);
|
||||
|
||||
ByteArrayOutputStream baos = new ByteArrayOutputStream();
|
||||
XmlUtils.writeDocument(filter, baos);
|
||||
return baos.toString();
|
||||
}
|
||||
}
|
|
@ -1,53 +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;
|
||||
|
||||
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(XMLStreamReader parser) {
|
||||
|
||||
CiFriendlyXMLFilter filter = new CiFriendlyXMLFilter(parser, true);
|
||||
filter.setChangelist("CHANGELIST");
|
||||
return filter;
|
||||
}
|
||||
|
||||
@Test
|
||||
void changelist() throws Exception {
|
||||
String input = "<project>"
|
||||
+ " <groupId>GROUPID</groupId>"
|
||||
+ " <artifactId>ARTIFACTID</artifactId>"
|
||||
+ "<version>${changelist}</version>"
|
||||
+ "</project>";
|
||||
String expected = "<project>"
|
||||
+ " <groupId>GROUPID</groupId>"
|
||||
+ " <artifactId>ARTIFACTID</artifactId>"
|
||||
+ "<version>CHANGELIST</version>"
|
||||
+ "</project>";
|
||||
|
||||
String actual = transform(input);
|
||||
|
||||
assertEquals(expected, actual);
|
||||
}
|
||||
}
|
|
@ -1,307 +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;
|
||||
|
||||
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.junit.jupiter.api.Test;
|
||||
|
||||
import static org.xmlunit.assertj.XmlAssert.assertThat;
|
||||
|
||||
class ConsumerPomXMLFilterTest extends AbstractXMLFilterTests {
|
||||
@Override
|
||||
protected XMLStreamReader getFilter(XMLStreamReader orgParser) {
|
||||
final BuildToRawPomXMLFilterFactory buildPomXMLFilterFactory = new BuildToRawPomXMLFilterFactory(true) {
|
||||
@Override
|
||||
protected Function<Path, Optional<RelativeProject>> getRelativePathMapper() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected BiFunction<String, String, String> getDependencyKeyToVersionMapper() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Optional<String> getSha1() {
|
||||
return Optional.empty();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Optional<String> getRevision() {
|
||||
return Optional.empty();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Optional<String> getChangelist() {
|
||||
return Optional.of("CL");
|
||||
}
|
||||
};
|
||||
|
||||
XMLStreamReader parser =
|
||||
new RawToConsumerPomXMLFilterFactory(buildPomXMLFilterFactory).get(orgParser, Paths.get("pom.xml"));
|
||||
return parser;
|
||||
}
|
||||
|
||||
@Test
|
||||
void aggregatorWithParent() throws Exception {
|
||||
String input = "<project>\n"
|
||||
+ " <parent>\n"
|
||||
+ " <groupId>GROUPID</groupId>\n"
|
||||
+ " <artifactId>PARENT</artifactId>\n"
|
||||
+ " <version>VERSION</version>\n"
|
||||
+ " <relativePath>../pom.xml</relativePath>\n"
|
||||
+ " </parent>\n"
|
||||
+ " <artifactId>PROJECT</artifactId>\n"
|
||||
+ " <modules>\n"
|
||||
+ " <module>ab</module>\n"
|
||||
+ " <module>../cd</module>\n"
|
||||
+ " </modules>\n"
|
||||
+ "</project>";
|
||||
String expected = "<project>\n"
|
||||
+ " <parent>\n"
|
||||
+ " <groupId>GROUPID</groupId>\n"
|
||||
+ " <artifactId>PARENT</artifactId>\n"
|
||||
+ " <version>VERSION</version>\n"
|
||||
+ " </parent>\n"
|
||||
+ " <artifactId>PROJECT</artifactId>\n"
|
||||
+ "</project>";
|
||||
String actual = transform(input);
|
||||
assertThat(actual).and(expected).ignoreWhitespace().areIdentical();
|
||||
}
|
||||
|
||||
@Test
|
||||
void aggregatorWithCliFriendlyVersion() throws Exception {
|
||||
String input = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n"
|
||||
+ "<project xmlns=\"http://maven.apache.org/POM/4.0.0\"\n"
|
||||
+ " xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"\n"
|
||||
+ " xsi:schemaLocation=\"http://maven.apache.org/POM/4.0.0\n"
|
||||
+ " http://maven.apache.org/xsd/maven-4.0.0.xsd\">\n"
|
||||
+ " <modelVersion>4.0.0</modelVersion>\n"
|
||||
+ " <groupId>org.sonatype.mavenbook.multispring</groupId>\n"
|
||||
+ " <artifactId>parent</artifactId>\n"
|
||||
+ " <version>0.9-${changelist}-SNAPSHOT</version>\n"
|
||||
+ " <packaging>pom</packaging>\n"
|
||||
+ " <name>Multi-Spring Chapter Parent Project</name>\n"
|
||||
+ " <modules>\n"
|
||||
+ " <module>simple-parent</module>\n"
|
||||
+ " </modules>\n"
|
||||
+ " \n"
|
||||
+ " <pluginRepositories>\n"
|
||||
+ " <pluginRepository>\n"
|
||||
+ " <id>apache.snapshots</id>\n"
|
||||
+ " <url>http://repository.apache.org/snapshots/</url>\n"
|
||||
+ " </pluginRepository>\n"
|
||||
+ " </pluginRepositories>\n"
|
||||
+ "</project>";
|
||||
String expected = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n"
|
||||
+ "<project xmlns=\"http://maven.apache.org/POM/4.0.0\"\n"
|
||||
+ " xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"\n"
|
||||
+ " xsi:schemaLocation=\"http://maven.apache.org/POM/4.0.0\n"
|
||||
+ " https://maven.apache.org/xsd/maven-4.0.0.xsd\">\n"
|
||||
+ " <modelVersion>4.0.0</modelVersion>\n"
|
||||
+ " <groupId>org.sonatype.mavenbook.multispring</groupId>\n"
|
||||
+ " <artifactId>parent</artifactId>\n"
|
||||
+ " <version>0.9-CL-SNAPSHOT</version>\n"
|
||||
+ " <packaging>pom</packaging>\n"
|
||||
+ " <name>Multi-Spring Chapter Parent Project</name>\n"
|
||||
+ " \n"
|
||||
+ " <pluginRepositories>\n"
|
||||
+ " <pluginRepository>\n"
|
||||
+ " <id>apache.snapshots</id>\n"
|
||||
+ " <url>http://repository.apache.org/snapshots/</url>\n"
|
||||
+ " </pluginRepository>\n"
|
||||
+ " </pluginRepositories>\n"
|
||||
+ "</project>";
|
||||
String actual = transform(input);
|
||||
assertThat(actual).and(expected).ignoreWhitespace().areIdentical();
|
||||
}
|
||||
|
||||
@Test
|
||||
void licenseHeader() throws Exception {
|
||||
String input = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n" + "\n"
|
||||
+ "<!--\n"
|
||||
+ "Licensed to the Apache Software Foundation (ASF) under one\n"
|
||||
+ "or more contributor license agreements. See the NOTICE file\n"
|
||||
+ "distributed with this work for additional information\n"
|
||||
+ "regarding copyright ownership. The ASF licenses this file\n"
|
||||
+ "to you under the Apache License, Version 2.0 (the\n"
|
||||
+ "\"License\"); you may not use this file except in compliance\n"
|
||||
+ "with the License. You may obtain a copy of the License at\n"
|
||||
+ "\n"
|
||||
+ " http://www.apache.org/licenses/LICENSE-2.0\n"
|
||||
+ "\n"
|
||||
+ "Unless required by applicable law or agreed to in writing,\n"
|
||||
+ "software distributed under the License is distributed on an\n"
|
||||
+ "\"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY\n"
|
||||
+ "KIND, either express or implied. See the License for the\n"
|
||||
+ "specific language governing permissions and limitations\n"
|
||||
+ "under the License.\n"
|
||||
+ "-->\n"
|
||||
+ "\n"
|
||||
+ "<project xmlns=\"http://maven.apache.org/POM/4.0.0\"\n"
|
||||
+ " xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"\n"
|
||||
+ " xsi:schemaLocation=\"http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd\">\n"
|
||||
+ " <modelVersion>4.0.0</modelVersion>\n"
|
||||
+ " <parent>\n"
|
||||
+ " <groupId>org.apache.maven</groupId>\n"
|
||||
+ " <artifactId>maven</artifactId>\n"
|
||||
+ " <version>4.0.0-SNAPSHOT</version>\n"
|
||||
+ " </parent>\n"
|
||||
+ " <artifactId>maven-xml</artifactId>\n"
|
||||
+ " <name>Maven XML</name>\n"
|
||||
+ " \n"
|
||||
+ " <properties>\n"
|
||||
+ " <maven.compiler.source>1.8</maven.compiler.source>\n"
|
||||
+ " <maven.compiler.target>1.8</maven.compiler.target>\n"
|
||||
+ " </properties>\n"
|
||||
+ "\n"
|
||||
+ " <build>\n"
|
||||
+ " <plugins>\n"
|
||||
+ " <plugin>\n"
|
||||
+ " <groupId>org.codehaus.mojo</groupId>\n"
|
||||
+ " <artifactId>animal-sniffer-maven-plugin</artifactId>\n"
|
||||
+ " <configuration>\n"
|
||||
+ " <signature>\n"
|
||||
+ " <groupId>org.codehaus.mojo.signature</groupId>\n"
|
||||
+ " <artifactId>java18</artifactId>\n"
|
||||
+ " <version>1.0</version>\n"
|
||||
+ " </signature>\n"
|
||||
+ " </configuration>\n"
|
||||
+ " </plugin>\n"
|
||||
+ " </plugins>\n"
|
||||
+ " </build>\n"
|
||||
+ " \n"
|
||||
+ " <dependencies>\n"
|
||||
+ " <dependency>\n"
|
||||
+ " <groupId>javax.inject</groupId>\n"
|
||||
+ " <artifactId>javax.inject</artifactId>\n"
|
||||
+ " <optional>true</optional>\n"
|
||||
+ " </dependency>\n"
|
||||
+ " <dependency>\n"
|
||||
+ " <groupId>org.xmlunit</groupId>\n"
|
||||
+ " <artifactId>xmlunit-assertj</artifactId>\n"
|
||||
+ " <scope>test</scope>\n"
|
||||
+ " </dependency>\n"
|
||||
+ " </dependencies>\n"
|
||||
+ "</project>";
|
||||
String expected = input;
|
||||
|
||||
String actual = transform(input);
|
||||
assertThat(actual).and(expected).areIdentical();
|
||||
}
|
||||
|
||||
@Test
|
||||
void lexicalHandler() throws Exception {
|
||||
String input = "<project><!--before--><modules>"
|
||||
+ "<!--pre-in-->"
|
||||
+ "<module><!--in-->ab</module>"
|
||||
+ "<module>../cd</module>"
|
||||
+ "<!--post-in-->"
|
||||
+ "</modules>"
|
||||
+ "<!--after--></project>";
|
||||
String expected = "<project><!--before--><!--after--></project>";
|
||||
String actual = transform(input);
|
||||
assertThat(actual).and(expected).areIdentical();
|
||||
}
|
||||
|
||||
@Test
|
||||
void downgradeModelVersion() throws Exception {
|
||||
String input = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n"
|
||||
+ "<project xmlns=\"http://maven.apache.org/POM/4.1.0\"\n"
|
||||
+ " xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"\n"
|
||||
+ " xsi:schemaLocation=\"http://maven.apache.org/POM/4.1.0\n"
|
||||
+ " http://maven.apache.org/xsd/maven-4.1.0.xsd\">\n"
|
||||
+ " <modelVersion>4.1.0</modelVersion>\n"
|
||||
+ " <groupId>org.sonatype.mavenbook.multispring</groupId>\n"
|
||||
+ " <artifactId>parent</artifactId>\n"
|
||||
+ " <version>0.9-SNAPSHOT</version>\n"
|
||||
+ " <packaging>pom</packaging>\n"
|
||||
+ "</project>";
|
||||
String expected = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n"
|
||||
+ "<project xmlns=\"http://maven.apache.org/POM/4.0.0\"\n"
|
||||
+ " xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"\n"
|
||||
+ " xsi:schemaLocation=\"http://maven.apache.org/POM/4.0.0\n"
|
||||
+ " https://maven.apache.org/xsd/maven-4.0.0.xsd\">\n"
|
||||
+ " <modelVersion>4.0.0</modelVersion>\n"
|
||||
+ " <groupId>org.sonatype.mavenbook.multispring</groupId>\n"
|
||||
+ " <artifactId>parent</artifactId>\n"
|
||||
+ " <version>0.9-SNAPSHOT</version>\n"
|
||||
+ " <packaging>pom</packaging>\n"
|
||||
+ "</project>";
|
||||
String actual = transform(input);
|
||||
assertThat(actual).and(expected).ignoreWhitespace().areIdentical();
|
||||
}
|
||||
|
||||
@Test
|
||||
void downgradeNotModelVersion() throws Exception {
|
||||
String input = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n"
|
||||
+ "<project xmlns=\"http://maven.apache.org/POM/4.1.0\"\n"
|
||||
+ " xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"\n"
|
||||
+ " xsi:schemaLocation=\"http://maven.apache.org/POM/4.1.0 http://maven.apache.org/xsd/maven-4.1.0.xsd\""
|
||||
+ " preserve.model.version=\"true\">\n"
|
||||
+ " <modelVersion>4.1.0</modelVersion>\n"
|
||||
+ " <groupId>org.sonatype.mavenbook.multispring</groupId>\n"
|
||||
+ " <artifactId>parent</artifactId>\n"
|
||||
+ " <version>0.9-SNAPSHOT</version>\n"
|
||||
+ " <packaging>pom</packaging>\n"
|
||||
+ " <build>"
|
||||
+ " <plugins>\n"
|
||||
+ " <plugin>\n"
|
||||
+ " <executions>\n"
|
||||
+ " <execution>\n"
|
||||
+ " <priority>1</priority>\n"
|
||||
+ " </execution>\n"
|
||||
+ " </executions>\n"
|
||||
+ " </plugin>\n"
|
||||
+ " </plugins>\n"
|
||||
+ " </build>\n"
|
||||
+ "</project>";
|
||||
String expected = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n"
|
||||
+ "<project xmlns=\"http://maven.apache.org/POM/4.1.0\"\n"
|
||||
+ " xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"\n"
|
||||
+ " preserve.model.version=\"true\""
|
||||
+ " xsi:schemaLocation=\"http://maven.apache.org/POM/4.1.0 https://maven.apache.org/xsd/maven-4.1.0.xsd\">\n"
|
||||
+ " <modelVersion>4.1.0</modelVersion>\n"
|
||||
+ " <groupId>org.sonatype.mavenbook.multispring</groupId>\n"
|
||||
+ " <artifactId>parent</artifactId>\n"
|
||||
+ " <version>0.9-SNAPSHOT</version>\n"
|
||||
+ " <packaging>pom</packaging>\n"
|
||||
+ " <build>"
|
||||
+ " <plugins>\n"
|
||||
+ " <plugin>\n"
|
||||
+ " <executions>\n"
|
||||
+ " <execution>\n"
|
||||
+ " <priority>1</priority>\n"
|
||||
+ " </execution>\n"
|
||||
+ " </executions>\n"
|
||||
+ " </plugin>\n"
|
||||
+ " </plugins>\n"
|
||||
+ " </build>\n"
|
||||
+ "</project>";
|
||||
String actual = transform(input);
|
||||
assertThat(actual).and(expected).ignoreWhitespace().areIdentical();
|
||||
}
|
||||
}
|
|
@ -1,72 +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;
|
||||
|
||||
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 XMLStreamReader getFilter(XMLStreamReader parser) {
|
||||
return new ModelVersionXMLFilter(parser);
|
||||
}
|
||||
|
||||
@Test
|
||||
void modelVersionWithDefaultPrefix() throws Exception {
|
||||
String input = "<project xmlns='http://maven.apache.org/POM/4.0.0'>"
|
||||
+ " <groupId>GROUPID</groupId>"
|
||||
+ " <artifactId>ARTIFACTID</artifactId>"
|
||||
+ " <version>VERSION</version>"
|
||||
+ "</project>";
|
||||
String expected = "<project xmlns=\"http://maven.apache.org/POM/4.0.0\">"
|
||||
+ " <modelVersion>4.0.0</modelVersion>"
|
||||
+ " <groupId>GROUPID</groupId>"
|
||||
+ " <artifactId>ARTIFACTID</artifactId>"
|
||||
+ " <version>VERSION</version>"
|
||||
+ "</project>";
|
||||
|
||||
// Check that the modelVersion is added
|
||||
assertEquals(expected, transform(input));
|
||||
// Check that the transformed POM is stable (modelVersion not added twice)
|
||||
assertEquals(expected, transform(expected));
|
||||
}
|
||||
|
||||
@Test
|
||||
void modelVersionWithPrefix() throws Exception {
|
||||
String input = "<maven:project xmlns:maven='http://maven.apache.org/POM/4.0.0'>"
|
||||
+ " <maven:groupId>GROUPID</maven:groupId>"
|
||||
+ " <maven:artifactId>ARTIFACTID</maven:artifactId>"
|
||||
+ " <maven:version>VERSION</maven:version>"
|
||||
+ "</maven:project>";
|
||||
String expected = "<maven:project xmlns:maven=\"http://maven.apache.org/POM/4.0.0\">"
|
||||
+ " <maven:modelVersion>4.0.0</maven:modelVersion>"
|
||||
+ " <maven:groupId>GROUPID</maven:groupId>"
|
||||
+ " <maven:artifactId>ARTIFACTID</maven:artifactId>"
|
||||
+ " <maven:version>VERSION</maven:version>"
|
||||
+ "</maven:project>";
|
||||
|
||||
// Check that the modelVersion is added
|
||||
assertEquals(expected, transform(input));
|
||||
// Check that the transformed POM is stable (modelVersion not added twice)
|
||||
assertEquals(expected, transform(expected));
|
||||
}
|
||||
}
|
|
@ -1,87 +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;
|
||||
|
||||
import javax.xml.stream.XMLStreamReader;
|
||||
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import static org.xmlunit.assertj.XmlAssert.assertThat;
|
||||
|
||||
class ModulesXMLFilterTest extends AbstractXMLFilterTests {
|
||||
|
||||
@Override
|
||||
protected ModulesXMLFilter getFilter(XMLStreamReader parser) {
|
||||
return new ModulesXMLFilter(parser);
|
||||
}
|
||||
|
||||
@Test
|
||||
void emptyModules() throws Exception {
|
||||
String input = "<project><modules/></project>";
|
||||
String expected = "<project/>";
|
||||
String actual = transform(input);
|
||||
assertThat(actual).and(expected).areIdentical();
|
||||
}
|
||||
|
||||
@Test
|
||||
void setOfModules() throws Exception {
|
||||
String input = "<project><modules>" + "<module>ab</module>" + "<module>../cd</module>" + "</modules></project>";
|
||||
String expected = "<project/>";
|
||||
String actual = transform(input);
|
||||
assertThat(actual).and(expected).areIdentical();
|
||||
}
|
||||
|
||||
@Test
|
||||
void noModules() throws Exception {
|
||||
String input = "<project><name>NAME</name></project>";
|
||||
String expected = input;
|
||||
String actual = transform(input);
|
||||
assertThat(actual).and(expected).areIdentical();
|
||||
}
|
||||
|
||||
@Test
|
||||
void comment() throws Exception {
|
||||
|
||||
String input = "<project><!--before--><modules>"
|
||||
+ "<!--pre-in-->"
|
||||
+ "<module><!--in-->ab</module>"
|
||||
+ "<module>../cd</module>"
|
||||
+ "<!--post-in-->"
|
||||
+ "</modules>"
|
||||
+ "<!--after--></project>";
|
||||
String expected = "<project><!--before--><!--after--></project>";
|
||||
String actual = transform(input);
|
||||
assertThat(actual).and(expected).areIdentical();
|
||||
}
|
||||
|
||||
@Test
|
||||
void setOfModulesLF() throws Exception {
|
||||
String input = "<project>\n"
|
||||
+ "\n"
|
||||
+ " <modules>\n"
|
||||
+ " <module>ab</module>\n"
|
||||
+ " <module>../cd</module>\n"
|
||||
+ " </modules>\n"
|
||||
+ "\n"
|
||||
+ "</project>\n";
|
||||
String expected = "<project>\n" + "\n" + " \n" + "\n" + "</project>\n";
|
||||
String actual = transform(input);
|
||||
assertThat(actual).and(expected).areIdentical();
|
||||
}
|
||||
}
|
|
@ -1,331 +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;
|
||||
|
||||
import javax.xml.stream.XMLStreamReader;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Path;
|
||||
import java.nio.file.Paths;
|
||||
import java.util.Optional;
|
||||
import java.util.function.Function;
|
||||
|
||||
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<XMLStreamReader, XMLStreamReader> filterCreator;
|
||||
private Path projectPath;
|
||||
|
||||
@BeforeEach
|
||||
void reset() throws IOException {
|
||||
filterCreator = null;
|
||||
projectPath = Paths.get("target/test-classes/" + getClass().getSimpleName() + "/child");
|
||||
Files.createDirectories(projectPath);
|
||||
if (!Files.isRegularFile(projectPath.resolve("../pom.xml"))) {
|
||||
Files.createFile(projectPath.resolve("../pom.xml"));
|
||||
}
|
||||
if (!Files.isRegularFile(projectPath.resolve("pom.xml"))) {
|
||||
Files.createFile(projectPath.resolve("pom.xml"));
|
||||
}
|
||||
Path relPath = projectPath.resolve("RELATIVEPATH");
|
||||
Files.createDirectories(relPath);
|
||||
if (!Files.isRegularFile(relPath.resolve("pom.xml"))) {
|
||||
Files.createFile(relPath.resolve("pom.xml"));
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected XMLStreamReader getFilter(XMLStreamReader parser) {
|
||||
Function<XMLStreamReader, XMLStreamReader> filterCreator =
|
||||
(this.filterCreator != null ? this.filterCreator : this::createFilter);
|
||||
return filterCreator.apply(parser);
|
||||
}
|
||||
|
||||
protected XMLStreamReader createFilter(XMLStreamReader parser) {
|
||||
return createFilter(
|
||||
parser, x -> Optional.of(new RelativeProject("GROUPID", "ARTIFACTID", "1.0.0")), projectPath);
|
||||
}
|
||||
|
||||
protected XMLStreamReader createFilter(
|
||||
XMLStreamReader parser, Function<Path, Optional<RelativeProject>> pathMapper, Path projectPath) {
|
||||
Function<Path, Path> locator = p -> p.resolve("pom.xml");
|
||||
return new ParentXMLFilter(new FastForwardFilter(parser), pathMapper, locator, projectPath);
|
||||
}
|
||||
|
||||
@Test
|
||||
void testWithFastForward() throws Exception {
|
||||
String input = "<project>"
|
||||
+ "<build>"
|
||||
+ "<plugins>"
|
||||
+ "<plugin>"
|
||||
+ "<configuration>"
|
||||
+ "<parent>"
|
||||
+ "<groupId>GROUPID</groupId>"
|
||||
+ "<artifactId>ARTIFACTID</artifactId>"
|
||||
+ "</parent>"
|
||||
+ "</configuration>"
|
||||
+ "</plugin>"
|
||||
+ "</plugins>"
|
||||
+ "</build>"
|
||||
+ "</project>";
|
||||
String expected = input;
|
||||
|
||||
String actual = transform(input);
|
||||
|
||||
assertEquals(expected, actual);
|
||||
}
|
||||
|
||||
@Test
|
||||
void testWithFastForwardAfterByPass() throws Exception {
|
||||
String input = "<project>"
|
||||
+ "<build>"
|
||||
+ "<plugins>"
|
||||
+ "<plugin>"
|
||||
+ "<configuration>"
|
||||
+ "<parent>"
|
||||
+ "<groupId>GROUPID</groupId>"
|
||||
+ "<artifactId>ARTIFACTID</artifactId>"
|
||||
+ "</parent>"
|
||||
+ "</configuration>"
|
||||
+ "</plugin>"
|
||||
+ "</plugins>"
|
||||
+ "</build>"
|
||||
+ "<parent>"
|
||||
+ "<groupId>GROUPID</groupId>"
|
||||
+ "<artifactId>ARTIFACTID</artifactId>"
|
||||
+ "</parent>"
|
||||
+ "</project>";
|
||||
String expected = "<project>"
|
||||
+ "<build>"
|
||||
+ "<plugins>"
|
||||
+ "<plugin>"
|
||||
+ "<configuration>"
|
||||
+ "<parent>"
|
||||
+ "<groupId>GROUPID</groupId>"
|
||||
+ "<artifactId>ARTIFACTID</artifactId>"
|
||||
+ "</parent>"
|
||||
+ "</configuration>"
|
||||
+ "</plugin>"
|
||||
+ "</plugins>"
|
||||
+ "</build>"
|
||||
+ "<parent>"
|
||||
+ "<groupId>GROUPID</groupId>"
|
||||
+ "<artifactId>ARTIFACTID</artifactId>"
|
||||
+ "<version>1.0.0</version>"
|
||||
+ "</parent>"
|
||||
+ "</project>";
|
||||
|
||||
String actual = transform(input);
|
||||
|
||||
assertEquals(expected, actual);
|
||||
}
|
||||
|
||||
@Test
|
||||
void testMinimum() throws Exception {
|
||||
String input = "<project><parent /></project>";
|
||||
String expected = input;
|
||||
String actual = transform(input);
|
||||
assertEquals(expected, actual);
|
||||
}
|
||||
|
||||
@Test
|
||||
void testNoRelativePath() throws Exception {
|
||||
String input = "<project><parent>"
|
||||
+ "<groupId>GROUPID</groupId>"
|
||||
+ "<artifactId>ARTIFACTID</artifactId>"
|
||||
+ "<version>VERSION</version>"
|
||||
+ "</parent></project>";
|
||||
String expected = input;
|
||||
|
||||
String actual = transform(input);
|
||||
|
||||
assertEquals(expected, actual);
|
||||
}
|
||||
|
||||
@Test
|
||||
void testDefaultRelativePath() throws Exception {
|
||||
String input = "<project>\n"
|
||||
+ " <parent>\n"
|
||||
+ " <groupId>GROUPID</groupId>\n"
|
||||
+ " <artifactId>ARTIFACTID</artifactId>\n"
|
||||
+ " </parent>\n"
|
||||
+ "</project>";
|
||||
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);
|
||||
|
||||
assertEquals(expected, actual);
|
||||
}
|
||||
|
||||
/**
|
||||
* An empty relative path means it must be downloaded from a repository.
|
||||
* That implies that the version cannot be solved (if missing, Maven should complain)
|
||||
*
|
||||
* @throws Exception
|
||||
*/
|
||||
@Test
|
||||
void testEmptyRelativePathNoVersion() throws Exception {
|
||||
String input = "<project><parent>"
|
||||
+ "<groupId>GROUPID</groupId>"
|
||||
+ "<artifactId>ARTIFACTID</artifactId>"
|
||||
+ "<relativePath></relativePath>"
|
||||
+ "</parent></project>";
|
||||
String expected = "<project><parent>"
|
||||
+ "<groupId>GROUPID</groupId>"
|
||||
+ "<artifactId>ARTIFACTID</artifactId>"
|
||||
+ "<relativePath />" // SAX optimization, however "" != null ...
|
||||
+ "</parent></project>";
|
||||
|
||||
String actual = transform(input);
|
||||
|
||||
assertEquals(expected, actual);
|
||||
}
|
||||
|
||||
@Test
|
||||
void testNoVersion() throws Exception {
|
||||
String input = "<project><parent>"
|
||||
+ "<groupId>GROUPID</groupId>"
|
||||
+ "<artifactId>ARTIFACTID</artifactId>"
|
||||
+ "<relativePath>RELATIVEPATH</relativePath>"
|
||||
+ "</parent></project>";
|
||||
String expected = "<project><parent>"
|
||||
+ "<groupId>GROUPID</groupId>"
|
||||
+ "<artifactId>ARTIFACTID</artifactId>"
|
||||
+ "<relativePath>RELATIVEPATH</relativePath>"
|
||||
+ "<version>1.0.0</version>"
|
||||
+ "</parent></project>";
|
||||
|
||||
String actual = transform(input);
|
||||
|
||||
assertEquals(expected, actual);
|
||||
}
|
||||
|
||||
@Test
|
||||
void testInvalidRelativePath() throws Exception {
|
||||
filterCreator = parser -> createFilter(
|
||||
parser, x -> Optional.ofNullable(null), Paths.get("pom.xml").toAbsolutePath());
|
||||
|
||||
String input = "<project><parent>"
|
||||
+ "<groupId>GROUPID</groupId>"
|
||||
+ "<artifactId>ARTIFACTID</artifactId>"
|
||||
+ "<relativePath>RELATIVEPATH</relativePath>"
|
||||
+ "</parent></project>";
|
||||
String expected = input;
|
||||
|
||||
String actual = transform(input);
|
||||
|
||||
assertEquals(expected, actual);
|
||||
}
|
||||
|
||||
@Test
|
||||
void testRelativePathAndVersion() throws Exception {
|
||||
String input = "<project><parent>"
|
||||
+ "<groupId>GROUPID</groupId>"
|
||||
+ "<artifactId>ARTIFACTID</artifactId>"
|
||||
+ "<relativePath>RELATIVEPATH</relativePath>"
|
||||
+ "<version>1.0.0</version>"
|
||||
+ "</parent></project>";
|
||||
String expected = "<project><parent>"
|
||||
+ "<groupId>GROUPID</groupId>"
|
||||
+ "<artifactId>ARTIFACTID</artifactId>"
|
||||
+ "<relativePath>RELATIVEPATH</relativePath>"
|
||||
+ "<version>1.0.0</version>"
|
||||
+ "</parent></project>";
|
||||
|
||||
String actual = transform(input);
|
||||
|
||||
assertEquals(expected, actual);
|
||||
}
|
||||
|
||||
@Test
|
||||
void testWithWeirdNamespace() throws Exception {
|
||||
String input = "<relativePath:project xmlns:relativePath=\"relativePath\">"
|
||||
+ "<relativePath:parent>"
|
||||
+ "<relativePath:groupId>GROUPID</relativePath:groupId>"
|
||||
+ "<relativePath:artifactId>ARTIFACTID</relativePath:artifactId>"
|
||||
+ "<relativePath:relativePath>RELATIVEPATH</relativePath:relativePath>"
|
||||
+ "</relativePath:parent></relativePath:project>";
|
||||
String expected = "<relativePath:project xmlns:relativePath=\"relativePath\">"
|
||||
+ "<relativePath:parent>"
|
||||
+ "<relativePath:groupId>GROUPID</relativePath:groupId>"
|
||||
+ "<relativePath:artifactId>ARTIFACTID</relativePath:artifactId>"
|
||||
+ "<relativePath:relativePath>RELATIVEPATH</relativePath:relativePath>"
|
||||
+ "<relativePath:version>1.0.0</relativePath:version>"
|
||||
+ "</relativePath:parent>"
|
||||
+ "</relativePath:project>";
|
||||
|
||||
String actual = transform(input);
|
||||
|
||||
assertEquals(expected, actual);
|
||||
}
|
||||
|
||||
@Test
|
||||
void comment() throws Exception {
|
||||
String input = "<project><!--before--><parent>"
|
||||
+ "<groupId>GROUPID</groupId>"
|
||||
+ "<artifactId>ARTIFACTID</artifactId>"
|
||||
+ "<!--version here-->"
|
||||
+ "</parent>"
|
||||
+ "</project>";
|
||||
String expected = "<project><!--before--><parent>"
|
||||
+ "<groupId>GROUPID</groupId>"
|
||||
+ "<artifactId>ARTIFACTID</artifactId>"
|
||||
+ "<!--version here-->"
|
||||
+ "<version>1.0.0</version>"
|
||||
+ "</parent>"
|
||||
+ "</project>";
|
||||
|
||||
String actual = transform(input);
|
||||
|
||||
assertEquals(expected, actual);
|
||||
}
|
||||
|
||||
@Test
|
||||
void testIndent() throws Exception {
|
||||
String input = "<project>\n"
|
||||
+ " <parent>\n"
|
||||
+ " <groupId>GROUPID</groupId>\n"
|
||||
+ " <artifactId>ARTIFACTID</artifactId>\n"
|
||||
+ " <!--version here-->\n"
|
||||
+ " </parent>\n"
|
||||
+ "</project>";
|
||||
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);
|
||||
|
||||
assertEquals(expected, actual);
|
||||
}
|
||||
}
|
|
@ -1,142 +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;
|
||||
|
||||
import javax.xml.stream.XMLStreamReader;
|
||||
|
||||
import java.util.function.BiFunction;
|
||||
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import static org.xmlunit.assertj.XmlAssert.assertThat;
|
||||
|
||||
class ReactorDependencyXMLFilterTest extends AbstractXMLFilterTests {
|
||||
private BiFunction<String, String, String> reactorVersionMapper;
|
||||
|
||||
@BeforeEach
|
||||
protected void reset() {
|
||||
reactorVersionMapper = null;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected ReactorDependencyXMLFilter getFilter(XMLStreamReader parser) {
|
||||
return new ReactorDependencyXMLFilter(
|
||||
parser, reactorVersionMapper != null ? reactorVersionMapper : (g, a) -> "1.0.0");
|
||||
}
|
||||
|
||||
@Test
|
||||
void testDefaultDependency() throws Exception {
|
||||
String input = "<dependency>"
|
||||
+ "<groupId>GROUPID</groupId>"
|
||||
+ "<artifactId>ARTIFACTID</artifactId>"
|
||||
+ "<version>VERSION</version>"
|
||||
+ "</dependency>";
|
||||
String expected = input;
|
||||
|
||||
String actual = transform(input);
|
||||
|
||||
assertThat(actual).isEqualTo(expected);
|
||||
}
|
||||
|
||||
@Test
|
||||
void testManagedDependency() throws Exception {
|
||||
reactorVersionMapper = (g, a) -> null;
|
||||
|
||||
String input =
|
||||
"<dependency>" + "<groupId>GROUPID</groupId>" + "<artifactId>ARTIFACTID</artifactId>" + "</dependency>";
|
||||
String expected = input;
|
||||
|
||||
String actual = transform(input);
|
||||
|
||||
assertThat(actual).isEqualTo(expected);
|
||||
}
|
||||
|
||||
@Test
|
||||
void testReactorDependency() throws Exception {
|
||||
String input =
|
||||
"<dependency>" + "<groupId>GROUPID</groupId>" + "<artifactId>ARTIFACTID</artifactId>" + "</dependency>";
|
||||
String expected = "<dependency>"
|
||||
+ "<groupId>GROUPID</groupId>"
|
||||
+ "<artifactId>ARTIFACTID</artifactId>"
|
||||
+ "<version>1.0.0</version>"
|
||||
+ "</dependency>";
|
||||
|
||||
String actual = transform(input);
|
||||
|
||||
assertThat(actual).isEqualTo(expected);
|
||||
}
|
||||
|
||||
@Test
|
||||
void testReactorDependencyLF() throws Exception {
|
||||
String input = "<dependency>\n"
|
||||
+ " <groupId>GROUPID</groupId>\n"
|
||||
+ " <artifactId>ARTIFACTID</artifactId>\n"
|
||||
+ " <!-- include version here --> "
|
||||
+ "</dependency>";
|
||||
String expected = "<dependency>\n"
|
||||
+ " <groupId>GROUPID</groupId>\n"
|
||||
+ " <artifactId>ARTIFACTID</artifactId>\n"
|
||||
+ " <!-- include version here -->\n"
|
||||
+ " <version>1.0.0</version>\n"
|
||||
+ "</dependency>";
|
||||
|
||||
String actual = transform(input);
|
||||
|
||||
assertThat(actual).and(expected).ignoreWhitespace().areIdentical();
|
||||
}
|
||||
|
||||
@Test
|
||||
void multipleDependencies() throws Exception {
|
||||
String input = "<project>\n" + " <modelVersion>4.0.0</modelVersion>\n"
|
||||
+ " <groupId>tests.project</groupId>\n"
|
||||
+ " <artifactId>duplicate-plugin-defs-merged</artifactId>\n"
|
||||
+ " <version>1</version>\n"
|
||||
+ " <build>\n"
|
||||
+ " <plugins>\n"
|
||||
+ " <plugin>\n"
|
||||
+ " <artifactId>maven-compiler-plugin</artifactId>\n"
|
||||
+ " <dependencies>\n"
|
||||
+ " <dependency>\n"
|
||||
+ " <groupId>group</groupId>\n"
|
||||
+ " <artifactId>first</artifactId>\n"
|
||||
+ " <version>1</version>\n"
|
||||
+ " </dependency>\n"
|
||||
+ " </dependencies>\n"
|
||||
+ " </plugin>\n"
|
||||
+ " <plugin>\n"
|
||||
+ " <artifactId>maven-compiler-plugin</artifactId>\n"
|
||||
+ " <dependencies>\n"
|
||||
+ " <dependency>\n"
|
||||
+ " <groupId>group</groupId>\n"
|
||||
+ " <artifactId>second</artifactId>\n"
|
||||
+ " <version>1</version>\n"
|
||||
+ " </dependency>\n"
|
||||
+ " </dependencies>\n"
|
||||
+ " </plugin>\n"
|
||||
+ " </plugins>\n"
|
||||
+ " </build>\n"
|
||||
+ "</project>";
|
||||
String expected = input;
|
||||
|
||||
String actual = transform(input);
|
||||
|
||||
assertThat(actual).and(expected).areIdentical();
|
||||
}
|
||||
}
|
|
@ -1,109 +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;
|
||||
|
||||
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(XMLStreamReader parser) {
|
||||
return new RelativePathXMLFilter(parser);
|
||||
}
|
||||
|
||||
@Test
|
||||
void testRelativePath() throws Exception {
|
||||
String input = "<project>\n"
|
||||
+ " <parent>\n"
|
||||
+ " <groupId>GROUPID</groupId>\n"
|
||||
+ " <artifactId>PARENT</artifactId>\n"
|
||||
+ " <version>VERSION</version>\n"
|
||||
+ " <relativePath>../pom.xml</relativePath>\n"
|
||||
+ " </parent>\n"
|
||||
+ " <artifactId>PROJECT</artifactId>\n"
|
||||
+ "</project>";
|
||||
String expected = "<project>\n"
|
||||
+ " <parent>\n"
|
||||
+ " <groupId>GROUPID</groupId>\n"
|
||||
+ " <artifactId>PARENT</artifactId>\n"
|
||||
+ " <version>VERSION</version>\n"
|
||||
+ " </parent>\n"
|
||||
+ " <artifactId>PROJECT</artifactId>\n"
|
||||
+ "</project>";
|
||||
String actual = transform(input);
|
||||
assertThat(actual).and(expected).areIdentical();
|
||||
}
|
||||
|
||||
@Test
|
||||
void testRelativePathNS() throws Exception {
|
||||
String input = "<project xmlns=\"http://maven.apache.org/POM/4.0.0\"\n"
|
||||
+ " xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"\n"
|
||||
+ " xsi:schemaLocation=\"http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd\">\n"
|
||||
+ " <parent>\n"
|
||||
+ " <groupId>GROUPID</groupId>\n"
|
||||
+ " <artifactId>PARENT</artifactId>\n"
|
||||
+ " <version>VERSION</version>\n"
|
||||
+ " <relativePath>../pom.xml</relativePath>\n"
|
||||
+ " </parent>\n"
|
||||
+ " <artifactId>PROJECT</artifactId>\n"
|
||||
+ "</project>";
|
||||
String expected = "<project xmlns=\"http://maven.apache.org/POM/4.0.0\"\n"
|
||||
+ " xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"\n"
|
||||
+ " xsi:schemaLocation=\"http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd\">\n"
|
||||
+ " <parent>\n"
|
||||
+ " <groupId>GROUPID</groupId>\n"
|
||||
+ " <artifactId>PARENT</artifactId>\n"
|
||||
+ " <version>VERSION</version>\n"
|
||||
+ " </parent>\n"
|
||||
+ " <artifactId>PROJECT</artifactId>\n"
|
||||
+ "</project>";
|
||||
String actual = transform(input);
|
||||
assertThat(actual).and(expected).areIdentical();
|
||||
}
|
||||
|
||||
@Test
|
||||
void testRelativePathPasNS() throws Exception {
|
||||
String input = "<p:project xmlns:p=\"http://maven.apache.org/POM/4.0.0\"\n"
|
||||
+ " xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"\n"
|
||||
+ " xsi:schemaLocation=\"http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd\">\n"
|
||||
+ " <p:parent>\n"
|
||||
+ " <p:groupId>GROUPID</p:groupId>\n"
|
||||
+ " <p:artifactId>PARENT</p:artifactId>\n"
|
||||
+ " <p:version>VERSION</p:version>\n"
|
||||
+ " <p:relativePath>../pom.xml</p:relativePath>\n"
|
||||
+ " </p:parent>\n"
|
||||
+ " <p:artifactId>PROJECT</p:artifactId>\n"
|
||||
+ "</p:project>";
|
||||
String expected = "<p:project xmlns:p=\"http://maven.apache.org/POM/4.0.0\"\n"
|
||||
+ " xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"\n"
|
||||
+ " xsi:schemaLocation=\"http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd\">\n"
|
||||
+ " <p:parent>\n"
|
||||
+ " <p:groupId>GROUPID</p:groupId>\n"
|
||||
+ " <p:artifactId>PARENT</p:artifactId>\n"
|
||||
+ " <p:version>VERSION</p:version>\n"
|
||||
+ " </p:parent>\n"
|
||||
+ " <p:artifactId>PROJECT</p:artifactId>\n"
|
||||
+ "</p:project>";
|
||||
String actual = transform(input);
|
||||
assertThat(actual).and(expected).areIdentical();
|
||||
}
|
||||
}
|
1
pom.xml
1
pom.xml
|
@ -105,7 +105,6 @@ under the License.
|
|||
<module>maven-builder-support</module>
|
||||
<module>maven-model</module>
|
||||
<module>maven-model-builder</module>
|
||||
<module>maven-model-transform</module>
|
||||
<module>api</module>
|
||||
<module>maven-xml-impl</module>
|
||||
<module>maven-core</module>
|
||||
|
|
|
@ -114,6 +114,7 @@ public class ${class.name}
|
|||
#end
|
||||
{
|
||||
#if ( $class == $root )
|
||||
final String namespaceUri;
|
||||
final String modelEncoding;
|
||||
#end
|
||||
#foreach ( $field in $class.getFields($version) )
|
||||
|
@ -138,6 +139,7 @@ public class ${class.name}
|
|||
*/
|
||||
${class.name}(
|
||||
#if ( $class == $root )
|
||||
String namespaceUri,
|
||||
String modelEncoding,
|
||||
#end
|
||||
#foreach ( $field in $allFields )
|
||||
|
@ -164,6 +166,7 @@ public class ${class.name}
|
|||
);
|
||||
#end
|
||||
#if ( $class == $root )
|
||||
this.namespaceUri = namespaceUri;
|
||||
this.modelEncoding = modelEncoding;
|
||||
#end
|
||||
#foreach ( $field in $class.getFields($version) )
|
||||
|
@ -200,6 +203,10 @@ public class ${class.name}
|
|||
|
||||
#end
|
||||
#if ( $class == $root )
|
||||
public String getNamespaceUri() {
|
||||
return namespaceUri;
|
||||
}
|
||||
|
||||
public String getModelEncoding() {
|
||||
return modelEncoding;
|
||||
}
|
||||
|
@ -349,6 +356,7 @@ public class ${class.name}
|
|||
{
|
||||
${class.name} base;
|
||||
#if ( $class == $root )
|
||||
String namespaceUri;
|
||||
String modelEncoding;
|
||||
#end
|
||||
#foreach ( $field in $class.getFields($version) )
|
||||
|
@ -389,6 +397,10 @@ public class ${class.name}
|
|||
Builder(${class.name} base, boolean forceCopy) {
|
||||
#if ( $class.superClass )
|
||||
super(base, forceCopy);
|
||||
#end
|
||||
#if ( $class == $root )
|
||||
this.namespaceUri = base.namespaceUri;
|
||||
this.modelEncoding = base.modelEncoding;
|
||||
#end
|
||||
if (forceCopy) {
|
||||
#foreach ( $field in $class.getFields($version) )
|
||||
|
@ -403,6 +415,12 @@ public class ${class.name}
|
|||
}
|
||||
|
||||
#if ( $class == $root )
|
||||
@Nonnull
|
||||
public Builder namespaceUri(String namespaceUri) {
|
||||
this.namespaceUri = namespaceUri;
|
||||
return this;
|
||||
}
|
||||
|
||||
@Nonnull
|
||||
public Builder modelEncoding(String modelEncoding) {
|
||||
this.modelEncoding = modelEncoding;
|
||||
|
@ -456,6 +474,7 @@ public class ${class.name}
|
|||
#end
|
||||
return new ${class.name}(
|
||||
#if ( $class == $root )
|
||||
namespaceUri != null ? namespaceUri : (base != null ? base.namespaceUri : ""),
|
||||
modelEncoding != null ? modelEncoding : (base != null ? base.modelEncoding : "UTF-8"),
|
||||
#end
|
||||
#foreach ( $field in $allFields )
|
||||
|
|
|
@ -676,6 +676,7 @@ public class ${className} {
|
|||
#end
|
||||
#end
|
||||
#if ( $class == $root )
|
||||
${classLcapName}.namespaceUri(parser.getNamespaceURI());
|
||||
${classLcapName}.modelEncoding(parser.getEncoding());
|
||||
#end
|
||||
return ${classLcapName}.build();
|
||||
|
|
|
@ -57,7 +57,6 @@ under the License.
|
|||
<area shape="rect" coords="244,381,406,421" alt="maven-settings-builder" href="maven-settings-builder/" />
|
||||
<area shape="rect" coords="278,447,371,486" alt="maven-settings" href="maven-settings/" />
|
||||
<area shape="rect" coords="387,512,540,553" alt="maven-model-builder" href="maven-model-builder/" />
|
||||
<area shape="rect" coords="304,578,485,619" alt="maven-model-transform" href="maven-model-transform/" />
|
||||
<area shape="rect" coords="492,577,594,619" alt="maven-model" href="maven-model/" />
|
||||
<area shape="rect" coords="71,0,222,41" alt="maven-slf4j-provider" href="maven-slf4j-provider/" />
|
||||
<area shape="rect" coords="73,66,220,108" alt="maven-slf4j-wrapper" href="maven-slf4j-wrapper/" />
|
||||
|
|
Loading…
Reference in New Issue