1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19 package org.apache.maven.internal.transformation;
20
21 import javax.inject.Named;
22 import javax.inject.Singleton;
23
24 import java.io.IOException;
25 import java.io.InputStream;
26 import java.nio.file.Files;
27 import java.nio.file.Path;
28 import java.nio.file.Paths;
29 import java.nio.file.StandardCopyOption;
30 import java.util.ArrayList;
31 import java.util.Collection;
32 import java.util.function.BiConsumer;
33
34 import org.apache.maven.feature.Features;
35 import org.apache.maven.model.building.DefaultBuildPomXMLFilterFactory;
36 import org.apache.maven.model.building.TransformerContext;
37 import org.apache.maven.model.transform.RawToConsumerPomXMLFilterFactory;
38 import org.apache.maven.model.transform.pull.XmlUtils;
39 import org.apache.maven.project.MavenProject;
40 import org.apache.maven.project.artifact.ProjectArtifact;
41 import org.codehaus.plexus.util.ReaderFactory;
42 import org.codehaus.plexus.util.xml.XmlStreamReader;
43 import org.codehaus.plexus.util.xml.pull.EntityReplacementMap;
44 import org.codehaus.plexus.util.xml.pull.MXParser;
45 import org.codehaus.plexus.util.xml.pull.XmlPullParser;
46 import org.codehaus.plexus.util.xml.pull.XmlPullParserException;
47 import org.eclipse.aether.RepositorySystemSession;
48 import org.eclipse.aether.artifact.Artifact;
49 import org.eclipse.aether.artifact.DefaultArtifact;
50 import org.eclipse.aether.deployment.DeployRequest;
51 import org.eclipse.aether.installation.InstallRequest;
52
53
54
55
56
57
58 @Singleton
59 @Named("consumer-pom")
60 public final class ConsumerPomArtifactTransformer {
61
62 private static final String CONSUMER_POM_CLASSIFIER = "consumer";
63
64 public void injectTransformedArtifacts(MavenProject project, RepositorySystemSession session) throws IOException {
65 if (isActive(session)) {
66 Path generatedFile;
67 String buildDirectory =
68 project.getBuild() != null ? project.getBuild().getDirectory() : null;
69 if (buildDirectory == null) {
70 generatedFile = Files.createTempFile(CONSUMER_POM_CLASSIFIER, "pom");
71 } else {
72 Path buildDir = Paths.get(buildDirectory);
73 Files.createDirectories(buildDir);
74 generatedFile = Files.createTempFile(buildDir, CONSUMER_POM_CLASSIFIER, "pom");
75 }
76 project.addAttachedArtifact(new ConsumerPomArtifact(project, generatedFile, session));
77 }
78 }
79
80 public InstallRequest remapInstallArtifacts(RepositorySystemSession session, InstallRequest request) {
81 if (isActive(session) && consumerPomPresent(request.getArtifacts())) {
82 request.setArtifacts(replacePom(request.getArtifacts()));
83 }
84 return request;
85 }
86
87 public DeployRequest remapDeployArtifacts(RepositorySystemSession session, DeployRequest request) {
88 if (isActive(session) && consumerPomPresent(request.getArtifacts())) {
89 request.setArtifacts(replacePom(request.getArtifacts()));
90 }
91 return request;
92 }
93
94 private boolean isActive(RepositorySystemSession session) {
95 return Features.buildConsumer(session.getUserProperties()).isActive();
96 }
97
98 private boolean consumerPomPresent(Collection<Artifact> artifacts) {
99 return artifacts.stream().anyMatch(a -> CONSUMER_POM_CLASSIFIER.equals(a.getClassifier()));
100 }
101
102 private Collection<Artifact> replacePom(Collection<Artifact> artifacts) {
103 ArrayList<Artifact> result = new ArrayList<>(artifacts.size());
104 for (Artifact artifact : artifacts) {
105 if (CONSUMER_POM_CLASSIFIER.equals(artifact.getClassifier())) {
106
107 DefaultArtifact remapped = new DefaultArtifact(
108 artifact.getGroupId(),
109 artifact.getArtifactId(),
110 "",
111 artifact.getExtension(),
112 artifact.getVersion(),
113 artifact.getProperties(),
114 artifact.getFile());
115 result.add(remapped);
116 } else if ("".equals(artifact.getClassifier())
117 && (artifact.getExtension().equals("pom"))
118 || artifact.getExtension().startsWith("pom.")) {
119
120 continue;
121 } else {
122
123 result.add(artifact);
124 }
125 }
126 return result;
127 }
128
129
130
131
132 private static class ConsumerPomArtifact extends TransformedArtifact {
133
134 private ConsumerPomArtifact(MavenProject mavenProject, Path target, RepositorySystemSession session) {
135 super(
136 new ProjectArtifact(mavenProject),
137 () -> mavenProject.getFile().toPath(),
138 CONSUMER_POM_CLASSIFIER,
139 "pom",
140 target,
141 transformer(session));
142 }
143
144 private static BiConsumer<Path, Path> transformer(RepositorySystemSession session) {
145 TransformerContext context = (TransformerContext) session.getData().get(TransformerContext.KEY);
146 return (src, dest) -> {
147 try (InputStream inputStream = transform(src, context)) {
148 Files.createDirectories(dest.getParent());
149 Files.copy(inputStream, dest, StandardCopyOption.REPLACE_EXISTING);
150 } catch (XmlPullParserException | IOException e) {
151 throw new RuntimeException(e);
152 }
153 };
154 }
155 }
156
157
158
159
160 static InputStream transform(Path pomFile, TransformerContext context) throws IOException, XmlPullParserException {
161 XmlStreamReader reader = ReaderFactory.newXmlReader(Files.newInputStream(pomFile));
162 XmlPullParser parser = new MXParser(EntityReplacementMap.defaultEntityReplacementMap);
163 parser.setInput(reader);
164 parser = new RawToConsumerPomXMLFilterFactory(new DefaultBuildPomXMLFilterFactory(context, true))
165 .get(parser, pomFile);
166
167 return XmlUtils.writeDocument(reader, parser);
168 }
169 }