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 = XmlStreamWriter.builder()
96 .setOutputStream(Files.newOutputStream(f.toPath()))
97 .get()) {
98 final Xpp3Dom dom = new Xpp3Dom("component-set");
99 final Xpp3Dom componentDom = new Xpp3Dom("components");
100 dom.addChild(componentDom);
101
102 for (final Xpp3Dom component : components.values()) {
103 componentDom.addChild(component);
104 }
105
106 Xpp3DomWriter.write(fileWriter, dom);
107 }
108
109 excludeOverride = true;
110
111 archiver.addFile(f, COMPONENTS_XML_PATH);
112
113 excludeOverride = false;
114 }
115 }
116
117 @Override
118 public void finalizeArchiveCreation(final Archiver archiver) {
119
120
121
122
123
124 for (final ResourceIterator it = archiver.getResources(); it.hasNext(); ) {
125 it.next();
126 }
127
128 try {
129 addToArchive(archiver);
130 } catch (final IOException e) {
131 throw new ArchiverException("Error finalizing component-set for archive. Reason: " + e.getMessage(), e);
132 }
133 }
134
135 @Override
136 public List<String> getVirtualFiles() {
137 if ((components != null) && !components.isEmpty()) {
138 return Collections.singletonList(COMPONENTS_XML_PATH);
139 }
140
141 return null;
142 }
143
144 @Override
145 public boolean isSelected(final FileInfo fileInfo) throws IOException {
146 if (fileInfo.isFile()) {
147 if (excludeOverride) {
148 return true;
149 }
150
151 String entry = fileInfo.getName().replace('\\', '/');
152
153 if (entry.startsWith("/")) {
154 entry = entry.substring(1);
155 }
156
157 if (ComponentsXmlArchiverFileFilter.COMPONENTS_XML_PATH.equals(entry)) {
158 try (Reader reader = new BufferedReader(XmlStreamReader.builder()
159 .setInputStream(fileInfo.getContents())
160 .get())) {
161 addComponentsXml(reader);
162 } catch (final XmlPullParserException e) {
163 throw new IOException("Error finalizing component-set for archive. Reason: " + e.getMessage(), e);
164 }
165 return false;
166 } else {
167 return true;
168 }
169 } else {
170 return true;
171 }
172 }
173
174 @Override
175 public void finalizeArchiveExtraction(final UnArchiver unarchiver) {}
176 }