1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19 package org.apache.maven.plugins.assembly.filter;
20
21 import javax.inject.Named;
22
23 import java.io.BufferedReader;
24 import java.io.File;
25 import java.io.IOException;
26 import java.io.Reader;
27 import java.io.Writer;
28 import java.nio.file.Files;
29 import java.util.Collections;
30 import java.util.LinkedHashMap;
31 import java.util.List;
32 import java.util.Map;
33
34 import org.apache.commons.io.input.XmlStreamReader;
35 import org.apache.commons.io.output.XmlStreamWriter;
36 import org.codehaus.plexus.archiver.Archiver;
37 import org.codehaus.plexus.archiver.ArchiverException;
38 import org.codehaus.plexus.archiver.ResourceIterator;
39 import org.codehaus.plexus.archiver.UnArchiver;
40 import org.codehaus.plexus.components.io.fileselectors.FileInfo;
41 import org.codehaus.plexus.util.xml.Xpp3Dom;
42 import org.codehaus.plexus.util.xml.Xpp3DomBuilder;
43 import org.codehaus.plexus.util.xml.Xpp3DomWriter;
44 import org.codehaus.plexus.util.xml.pull.XmlPullParserException;
45
46
47
48
49
50
51
52 @Named("plexus")
53 public class ComponentsXmlArchiverFileFilter implements ContainerDescriptorHandler {
54 public static final String COMPONENTS_XML_PATH = "META-INF/plexus/components.xml";
55
56
57
58
59 Map<String, Xpp3Dom> components;
60
61 private boolean excludeOverride = false;
62
63 void addComponentsXml(final Reader componentsReader) throws XmlPullParserException, IOException {
64 Xpp3Dom newDom = Xpp3DomBuilder.build(componentsReader);
65
66 if (newDom != null) {
67 newDom = newDom.getChild("components");
68 }
69
70 if (newDom != null) {
71 final Xpp3Dom[] children = newDom.getChildren();
72
73 for (final Xpp3Dom component : children) {
74 if (components == null) {
75 components = new LinkedHashMap<>();
76 }
77
78 final String role = component.getChild("role").getValue();
79 final Xpp3Dom child = component.getChild("role-hint");
80 final String roleHint = child != null ? child.getValue() : "";
81
82 final String key = role + roleHint;
83 if (!components.containsKey(key)) {
84 components.put(key, component);
85 }
86 }
87 }
88 }
89
90 private void addToArchive(final Archiver archiver) throws IOException {
91 if (components != null) {
92 final File f = Files.createTempFile("maven-assembly-plugin", "tmp").toFile();
93 f.deleteOnExit();
94
95 try (Writer fileWriter = new XmlStreamWriter(Files.newOutputStream(f.toPath()))) {
96 final Xpp3Dom dom = new Xpp3Dom("component-set");
97 final Xpp3Dom componentDom = new Xpp3Dom("components");
98 dom.addChild(componentDom);
99
100 for (final Xpp3Dom component : components.values()) {
101 componentDom.addChild(component);
102 }
103
104 Xpp3DomWriter.write(fileWriter, dom);
105 }
106
107 excludeOverride = true;
108
109 archiver.addFile(f, COMPONENTS_XML_PATH);
110
111 excludeOverride = false;
112 }
113 }
114
115 @Override
116 public void finalizeArchiveCreation(final Archiver archiver) {
117
118
119
120
121
122 for (final ResourceIterator it = archiver.getResources(); it.hasNext(); ) {
123 it.next();
124 }
125
126 try {
127 addToArchive(archiver);
128 } catch (final IOException e) {
129 throw new ArchiverException("Error finalizing component-set for archive. Reason: " + e.getMessage(), e);
130 }
131 }
132
133 @Override
134 public List<String> getVirtualFiles() {
135 if ((components != null) && !components.isEmpty()) {
136 return Collections.singletonList(COMPONENTS_XML_PATH);
137 }
138
139 return null;
140 }
141
142 @Override
143 public boolean isSelected(final FileInfo fileInfo) throws IOException {
144 if (fileInfo.isFile()) {
145 if (excludeOverride) {
146 return true;
147 }
148
149 String entry = fileInfo.getName().replace('\\', '/');
150
151 if (entry.startsWith("/")) {
152 entry = entry.substring(1);
153 }
154
155 if (ComponentsXmlArchiverFileFilter.COMPONENTS_XML_PATH.equals(entry)) {
156 try (Reader reader = new BufferedReader(new XmlStreamReader(fileInfo.getContents()))) {
157 addComponentsXml(reader);
158 } catch (final XmlPullParserException e) {
159 final IOException error =
160 new IOException("Error finalizing component-set for archive. Reason: " + e.getMessage(), e);
161
162 throw error;
163 }
164 return false;
165 } else {
166 return true;
167 }
168 } else {
169 return true;
170 }
171 }
172
173 @Override
174 public void finalizeArchiveExtraction(final UnArchiver unarchiver) {}
175 }