2424
2525import java .io .IOException ;
2626import java .io .InputStream ;
27+ import java .io .Writer ;
2728import java .nio .file .Files ;
2829import java .nio .file .Path ;
2930import java .nio .file .Paths ;
3233import java .util .Collection ;
3334import java .util .Set ;
3435import java .util .concurrent .CopyOnWriteArraySet ;
35- import java .util .function . BiConsumer ;
36+ import java .util .stream . Collectors ;
3637
38+ import org .apache .maven .api .model .Model ;
39+ import org .apache .maven .api .model .ModelBase ;
40+ import org .apache .maven .api .model .Profile ;
3741import org .apache .maven .feature .Features ;
3842import org .apache .maven .model .building .DefaultBuildPomXMLFilterFactory ;
3943import org .apache .maven .model .building .TransformerContext ;
4044import org .apache .maven .model .transform .RawToConsumerPomXMLFilterFactory ;
4145import org .apache .maven .model .transform .pull .XmlUtils ;
46+ import org .apache .maven .model .v4 .MavenXpp3Writer ;
4247import org .apache .maven .project .MavenProject ;
4348import org .apache .maven .project .artifact .ProjectArtifact ;
4449import org .codehaus .plexus .util .ReaderFactory ;
@@ -64,6 +69,8 @@ public final class ConsumerPomArtifactTransformer {
6469
6570 private static final String CONSUMER_POM_CLASSIFIER = "consumer" ;
6671
72+ private static final String BUILD_POM_CLASSIFIER = "build" ;
73+
6774 private final Set <Path > toDelete = new CopyOnWriteArraySet <>();
6875
6976 public void injectTransformedArtifacts (MavenProject project , RepositorySystemSession session ) throws IOException {
@@ -72,18 +79,23 @@ public void injectTransformedArtifacts(MavenProject project, RepositorySystemSes
7279 return ;
7380 }
7481 if (isActive (session )) {
75- Path generatedFile ;
76- String buildDirectory =
77- project .getBuild () != null ? project .getBuild ().getDirectory () : null ;
78- if (buildDirectory == null ) {
79- generatedFile = Files .createTempFile (CONSUMER_POM_CLASSIFIER , "pom" );
80- } else {
81- Path buildDir = Paths .get (buildDirectory );
82+ Path buildDir =
83+ project .getBuild () != null ? Paths .get (project .getBuild ().getDirectory ()) : null ;
84+ if (buildDir != null ) {
8285 Files .createDirectories (buildDir );
83- generatedFile = Files .createTempFile (buildDir , CONSUMER_POM_CLASSIFIER , "pom" );
8486 }
85- deferDeleteFile (generatedFile );
86- project .addAttachedArtifact (new ConsumerPomArtifact (project , generatedFile , session ));
87+ Path build = buildDir != null
88+ ? Files .createTempFile (buildDir , BUILD_POM_CLASSIFIER + "-" , ".pom" )
89+ : Files .createTempFile (BUILD_POM_CLASSIFIER + "-" , ".pom" );
90+ deferDeleteFile (build );
91+ project .addAttachedArtifact (new BuildPomArtifact (project , build , session ));
92+ if (!"pom" .equals (project .getPackaging ())) {
93+ Path consumer = buildDir != null
94+ ? Files .createTempFile (buildDir , CONSUMER_POM_CLASSIFIER + "-" , ".pom" )
95+ : Files .createTempFile (CONSUMER_POM_CLASSIFIER + "-" , ".pom" );
96+ deferDeleteFile (consumer );
97+ project .addAttachedArtifact (new ConsumerPomArtifact (project , consumer ));
98+ }
8799 } else if (project .getModel ().isRoot ()) {
88100 throw new IllegalStateException (
89101 "The use of the root attribute on the model requires the buildconsumer feature to be active" );
@@ -124,61 +136,130 @@ private boolean isActive(RepositorySystemSession session) {
124136 }
125137
126138 private boolean consumerPomPresent (Collection <Artifact > artifacts ) {
127- return artifacts .stream ().anyMatch (a -> CONSUMER_POM_CLASSIFIER .equals (a .getClassifier ()));
139+ return artifacts .stream ()
140+ .anyMatch (a -> "pom" .equals (a .getExtension ()) && BUILD_POM_CLASSIFIER .equals (a .getClassifier ()));
128141 }
129142
130143 private Collection <Artifact > replacePom (Collection <Artifact > artifacts ) {
131- ArrayList <Artifact > result = new ArrayList <>(artifacts .size ());
144+ Artifact consumer = null ;
145+ Artifact build = null ;
146+ Artifact main = null ;
132147 for (Artifact artifact : artifacts ) {
133- if (CONSUMER_POM_CLASSIFIER .equals (artifact .getClassifier ())) {
134- // if under CONSUMER_POM_CLASSIFIER, move it to "" classifier
135- DefaultArtifact remapped = new DefaultArtifact (
136- artifact .getGroupId (),
137- artifact .getArtifactId (),
148+ if ("pom" .equals (artifact .getExtension ())) {
149+ if (CONSUMER_POM_CLASSIFIER .equals (artifact .getClassifier ())) {
150+ consumer = artifact ;
151+ } else if (BUILD_POM_CLASSIFIER .equals (artifact .getClassifier ())) {
152+ build = artifact ;
153+ } else if ("" .equals (artifact .getClassifier ())) {
154+ main = artifact ;
155+ }
156+ }
157+ }
158+ if (main != null ) {
159+ if (consumer != null ) {
160+ ArrayList <Artifact > result = new ArrayList <>(artifacts );
161+ result .remove (main );
162+ result .remove (consumer );
163+ result .add (new DefaultArtifact (
164+ consumer .getGroupId (),
165+ consumer .getArtifactId (),
138166 "" ,
139- artifact .getExtension (),
140- artifact .getVersion (),
141- artifact .getProperties (),
142- artifact .getFile ());
143- result .add (remapped );
144- } else if ("" .equals (artifact .getClassifier ())
145- && (artifact .getExtension ().equals ("pom" ))
146- || artifact .getExtension ().startsWith ("pom." )) {
147- // skip POM and POM subordinates
148- continue ;
149- } else {
150- // everything else: add as is
151- result .add (artifact );
167+ consumer .getExtension (),
168+ consumer .getVersion (),
169+ consumer .getProperties (),
170+ consumer .getFile ()));
171+ artifacts = result ;
172+ } else if (build != null ) {
173+ ArrayList <Artifact > result = new ArrayList <>(artifacts );
174+ result .remove (main );
175+ result .remove (build );
176+ result .add (new DefaultArtifact (
177+ build .getGroupId (),
178+ build .getArtifactId (),
179+ "" ,
180+ build .getExtension (),
181+ build .getVersion (),
182+ build .getProperties (),
183+ build .getFile ()));
184+ artifacts = result ;
152185 }
153186 }
154- return result ;
187+ return artifacts ;
155188 }
156189
157190 /**
158191 * Consumer POM is transformed from original POM.
159192 */
160193 private static class ConsumerPomArtifact extends TransformedArtifact {
161194
162- private ConsumerPomArtifact (MavenProject mavenProject , Path target , RepositorySystemSession session ) {
195+ private MavenProject project ;
196+
197+ private ConsumerPomArtifact (MavenProject mavenProject , Path target ) {
163198 super (
164199 new ProjectArtifact (mavenProject ),
165200 () -> mavenProject .getFile ().toPath (),
166201 CONSUMER_POM_CLASSIFIER ,
167202 "pom" ,
168- target ,
169- transformer ( session )) ;
203+ target );
204+ this . project = mavenProject ;
170205 }
171206
172- private static BiConsumer <Path , Path > transformer (RepositorySystemSession session ) {
207+ @ Override
208+ public void transform (Path src , Path dest ) {
209+ Model model = project .getModel ().getDelegate ();
210+ boolean isBom = "bom" .equals (model .getPackaging ());
211+ Model .Builder builder =
212+ prune (Model .newBuilder (model , true ).root (false ).parent (null ), isBom );
213+ builder .profiles (model .getProfiles ().stream ()
214+ .map (p -> prune (Profile .newBuilder (p , true ), isBom ).build ())
215+ .collect (Collectors .toList ()));
216+
217+ Model consumer = builder .build ();
218+
219+ try (Writer w = Files .newBufferedWriter (dest )) {
220+ new MavenXpp3Writer ().write (w , consumer );
221+ } catch (IOException e ) {
222+ throw new RuntimeException (e );
223+ }
224+ }
225+
226+ private <T extends ModelBase .Builder > T prune (T builder , boolean isBom ) {
227+ builder .properties (null ).reporting (null ).pluginRepositories (null ).distributionManagement (null );
228+ if (isBom ) {
229+ builder .dependencies (null );
230+ } else {
231+ builder .dependencyManagement (null );
232+ }
233+ return builder ;
234+ }
235+ }
236+
237+ /**
238+ * Consumer POM is transformed from original POM.
239+ */
240+ private static class BuildPomArtifact extends TransformedArtifact {
241+
242+ private RepositorySystemSession session ;
243+
244+ private BuildPomArtifact (MavenProject mavenProject , Path target , RepositorySystemSession session ) {
245+ super (
246+ new ProjectArtifact (mavenProject ),
247+ () -> mavenProject .getFile ().toPath (),
248+ BUILD_POM_CLASSIFIER ,
249+ "pom" ,
250+ target );
251+ this .session = session ;
252+ }
253+
254+ @ Override
255+ public void transform (Path src , Path dest ) {
173256 TransformerContext context = (TransformerContext ) session .getData ().get (TransformerContext .KEY );
174- return (src , dest ) -> {
175- try (InputStream inputStream = transform (src , context )) {
176- Files .createDirectories (dest .getParent ());
177- Files .copy (inputStream , dest , StandardCopyOption .REPLACE_EXISTING );
178- } catch (XmlPullParserException | IOException e ) {
179- throw new RuntimeException (e );
180- }
181- };
257+ try (InputStream inputStream = ConsumerPomArtifactTransformer .transform (src , context )) {
258+ Files .createDirectories (dest .getParent ());
259+ Files .copy (inputStream , dest , StandardCopyOption .REPLACE_EXISTING );
260+ } catch (XmlPullParserException | IOException e ) {
261+ throw new RuntimeException (e );
262+ }
182263 }
183264 }
184265
0 commit comments