1
2
3
4
5 package org.apache.maven.plugin.descriptor.io;
6
7 import java.io.IOException;
8 import java.io.InputStream;
9 import java.io.OutputStream;
10 import java.io.Reader;
11 import java.io.Writer;
12 import java.text.DateFormat;
13 import java.util.ArrayList;
14 import java.util.Date;
15 import java.util.HashSet;
16 import java.util.List;
17 import java.util.Map;
18 import java.util.Objects;
19 import java.util.Properties;
20 import java.util.Set;
21 import javax.xml.stream.XMLOutputFactory;
22 import javax.xml.stream.XMLStreamException;
23 import javax.xml.stream.XMLStreamWriter;
24 import org.apache.maven.api.annotations.Generated;
25 import org.apache.maven.api.xml.XmlNode;
26 import org.apache.maven.internal.xml.XmlNodeBuilder;
27 import org.apache.maven.api.plugin.descriptor.PluginDescriptor;
28 import org.apache.maven.api.plugin.descriptor.MojoDescriptor;
29 import org.apache.maven.api.plugin.descriptor.Parameter;
30 import org.apache.maven.api.plugin.descriptor.Requirement;
31 import org.apache.maven.api.plugin.descriptor.Dependency;
32 import org.codehaus.stax2.util.StreamWriterDelegate;
33
34 import static javax.xml.XMLConstants.W3C_XML_SCHEMA_INSTANCE_NS_URI;
35
36 @Generated
37 public class PluginDescriptorStaxWriter {
38
39
40
41
42
43
44
45
46 private static final String NAMESPACE = "http://maven.apache.org/PLUGIN/2.0.0";
47
48
49
50
51 private static final String SCHEMA_LOCATION = "https://maven.apache.org/xsd/plugin-2.0.0.xsd";
52
53
54
55
56 private String namespace = NAMESPACE;
57
58
59
60
61 private String schemaLocation = SCHEMA_LOCATION;
62
63
64
65
66 private String fileComment = null;
67
68
69
70
71
72
73
74
75
76
77 public void setNamespace(String namespace) {
78 this.namespace = Objects.requireNonNull(namespace);
79 }
80
81
82
83
84
85
86 public void setSchemaLocation(String schemaLocation) {
87 this.schemaLocation = Objects.requireNonNull(schemaLocation);
88 }
89
90
91
92
93
94
95 public void setFileComment(String fileComment) {
96 this.fileComment = fileComment;
97 }
98
99
100
101
102
103
104
105
106 public void write(Writer writer, PluginDescriptor pluginDescriptor) throws IOException, XMLStreamException {
107 XMLOutputFactory factory = new com.ctc.wstx.stax.WstxOutputFactory();
108 factory.setProperty(XMLOutputFactory.IS_REPAIRING_NAMESPACES, false);
109 factory.setProperty(com.ctc.wstx.api.WstxOutputProperties.P_USE_DOUBLE_QUOTES_IN_XML_DECL, true);
110 factory.setProperty(com.ctc.wstx.api.WstxOutputProperties.P_ADD_SPACE_AFTER_EMPTY_ELEM, true);
111 XMLStreamWriter serializer = new IndentingXMLStreamWriter(factory.createXMLStreamWriter(writer));
112 serializer.writeStartDocument(pluginDescriptor.getModelEncoding(), null);
113 writePluginDescriptor("plugin", pluginDescriptor, serializer);
114 serializer.writeEndDocument();
115 }
116
117
118
119
120
121
122
123
124 public void write(OutputStream stream, PluginDescriptor pluginDescriptor) throws IOException, XMLStreamException {
125 XMLOutputFactory factory = new com.ctc.wstx.stax.WstxOutputFactory();
126 factory.setProperty(XMLOutputFactory.IS_REPAIRING_NAMESPACES, false);
127 factory.setProperty(com.ctc.wstx.api.WstxOutputProperties.P_USE_DOUBLE_QUOTES_IN_XML_DECL, true);
128 factory.setProperty(com.ctc.wstx.api.WstxOutputProperties.P_ADD_SPACE_AFTER_EMPTY_ELEM, true);
129 XMLStreamWriter serializer = new IndentingXMLStreamWriter(factory.createXMLStreamWriter(stream, pluginDescriptor.getModelEncoding()));
130 serializer.writeStartDocument(pluginDescriptor.getModelEncoding(), null);
131 writePluginDescriptor("plugin", pluginDescriptor, serializer);
132 serializer.writeEndDocument();
133 }
134
135 private void writePluginDescriptor(String tagName, PluginDescriptor pluginDescriptor, XMLStreamWriter serializer)
136 throws IOException, XMLStreamException {
137 if (pluginDescriptor != null) {
138 if (this.fileComment != null) {
139 serializer.writeCharacters("\n");
140 serializer.writeComment(this.fileComment);
141 serializer.writeCharacters("\n");
142 }
143 serializer.writeStartElement("", tagName, namespace);
144 serializer.writeNamespace("", namespace);
145 serializer.writeNamespace("xsi", W3C_XML_SCHEMA_INSTANCE_NS_URI);
146 serializer.writeAttribute(W3C_XML_SCHEMA_INSTANCE_NS_URI, "schemaLocation", namespace + " " + schemaLocation);
147 writeTag("name", null, pluginDescriptor.getName(), serializer);
148 writeTag("description", null, pluginDescriptor.getDescription(), serializer);
149 writeTag("groupId", null, pluginDescriptor.getGroupId(), serializer);
150 writeTag("artifactId", null, pluginDescriptor.getArtifactId(), serializer);
151 writeTag("version", null, pluginDescriptor.getVersion(), serializer);
152 writeTag("goalPrefix", null, pluginDescriptor.getGoalPrefix(), serializer);
153 writeTag("isolatedRealm", "false", pluginDescriptor.isIsolatedRealm() ? "true" : null, serializer);
154 writeTag("inheritedByDefault", "true", pluginDescriptor.isInheritedByDefault() ? null : "false", serializer);
155 writeTag("requiredJavaVersion", null, pluginDescriptor.getRequiredJavaVersion(), serializer);
156 writeTag("requiredMavenVersion", null, pluginDescriptor.getRequiredMavenVersion(), serializer);
157 writeList("mojos", false, pluginDescriptor.getMojos(), serializer,
158 t -> writeMojoDescriptor("mojo", t, serializer));
159 serializer.writeEndElement();
160 }
161 }
162
163 private void writeMojoDescriptor(String tagName, MojoDescriptor mojoDescriptor, XMLStreamWriter serializer)
164 throws IOException, XMLStreamException {
165 if (mojoDescriptor != null) {
166 serializer.writeStartElement(namespace, tagName);
167 writeTag("goal", null, mojoDescriptor.getGoal(), serializer);
168 writeTag("description", null, mojoDescriptor.getDescription(), serializer);
169 writeTag("implementation", null, mojoDescriptor.getImplementation(), serializer);
170 writeTag("language", "java", mojoDescriptor.getLanguage(), serializer);
171 writeTag("phase", null, mojoDescriptor.getPhase(), serializer);
172 writeTag("executePhase", null, mojoDescriptor.getExecutePhase(), serializer);
173 writeTag("executeGoal", null, mojoDescriptor.getExecuteGoal(), serializer);
174 writeTag("executeLifecycle", null, mojoDescriptor.getExecuteLifecycle(), serializer);
175 writeTag("dependencyResolution", "runtime", mojoDescriptor.getDependencyResolution(), serializer);
176 writeTag("dependencyCollection", null, mojoDescriptor.getDependencyCollection(), serializer);
177 writeTag("directInvocationOnly", "false", mojoDescriptor.isDirectInvocationOnly() ? "true" : null, serializer);
178 writeTag("projectRequired", "true", mojoDescriptor.isProjectRequired() ? null : "false", serializer);
179 writeTag("onlineRequired", "false", mojoDescriptor.isOnlineRequired() ? "true" : null, serializer);
180 writeTag("aggregator", "false", mojoDescriptor.isAggregator() ? "true" : null, serializer);
181 writeTag("inheritedByDefault", "true", mojoDescriptor.isInheritedByDefault() ? null : "false", serializer);
182 writeTag("since", null, mojoDescriptor.getSince(), serializer);
183 writeTag("deprecated", null, mojoDescriptor.getDeprecated(), serializer);
184 writeTag("configurator", null, mojoDescriptor.getConfigurator(), serializer);
185 writeList("parameters", false, mojoDescriptor.getParameters(), serializer,
186 t -> writeParameter("parameter", t, serializer));
187 serializer.writeEndElement();
188 }
189 }
190
191 private void writeParameter(String tagName, Parameter parameter, XMLStreamWriter serializer)
192 throws IOException, XMLStreamException {
193 if (parameter != null) {
194 serializer.writeStartElement(namespace, tagName);
195 writeTag("name", null, parameter.getName(), serializer);
196 writeTag("alias", null, parameter.getAlias(), serializer);
197 writeTag("type", null, parameter.getType(), serializer);
198 writeTag("required", "false", parameter.isRequired() ? "true" : null, serializer);
199 writeTag("editable", "true", parameter.isEditable() ? null : "false", serializer);
200 writeTag("description", null, parameter.getDescription(), serializer);
201 writeTag("since", null, parameter.getSince(), serializer);
202 writeTag("deprecated", null, parameter.getDeprecated(), serializer);
203 writeTag("expression", null, parameter.getExpression(), serializer);
204 writeTag("defaultValue", null, parameter.getDefaultValue(), serializer);
205 serializer.writeEndElement();
206 }
207 }
208
209 private void writeRequirement(String tagName, Requirement requirement, XMLStreamWriter serializer)
210 throws IOException, XMLStreamException {
211 if (requirement != null) {
212 serializer.writeStartElement(namespace, tagName);
213 writeTag("role", null, requirement.getRole(), serializer);
214 writeTag("role-hint", null, requirement.getRoleHint(), serializer);
215 writeTag("field-name", null, requirement.getFieldName(), serializer);
216 serializer.writeEndElement();
217 }
218 }
219
220 private void writeDependency(String tagName, Dependency dependency, XMLStreamWriter serializer)
221 throws IOException, XMLStreamException {
222 if (dependency != null) {
223 serializer.writeStartElement(namespace, tagName);
224 writeTag("groupId", null, dependency.getGroupId(), serializer);
225 writeTag("artifactId", null, dependency.getArtifactId(), serializer);
226 writeTag("version", null, dependency.getVersion(), serializer);
227 writeTag("type", "jar", dependency.getType(), serializer);
228 serializer.writeEndElement();
229 }
230 }
231
232 @FunctionalInterface
233 private interface ElementWriter<T> {
234 public void write(T t) throws IOException, XMLStreamException;
235 }
236
237 private <T> void writeList(String tagName, List<T> list, XMLStreamWriter serializer, ElementWriter<T> writer) throws IOException, XMLStreamException {
238 writeList(tagName, false, list, serializer, writer);
239 }
240
241 private <T> void writeList(String tagName, boolean flat, List<T> list, XMLStreamWriter serializer, ElementWriter<T> writer) throws IOException, XMLStreamException {
242 if (list != null && !list.isEmpty()) {
243 if (!flat) {
244 serializer.writeStartElement(namespace, tagName);
245 }
246 int index = 0;
247 for (T t : list) {
248 writer.write(t);
249 }
250 if (!flat) {
251 serializer.writeEndElement();
252 }
253 }
254 }
255
256 private <T> void writeProperties(String tagName, Map<String, String> props, XMLStreamWriter serializer) throws IOException, XMLStreamException {
257 if (props != null && !props.isEmpty()) {
258 serializer.writeStartElement(namespace, tagName);
259 for (Map.Entry<String, String> entry : props.entrySet()) {
260 String key = entry.getKey();
261 writeTag(key, null, entry.getValue(), serializer);
262 }
263 serializer.writeEndElement();
264 }
265 }
266
267 private void writeDom(XmlNode dom, XMLStreamWriter serializer) throws IOException, XMLStreamException {
268 if (dom != null) {
269 serializer.writeStartElement(namespace, dom.getName());
270 for (Map.Entry<String, String> attr : dom.getAttributes().entrySet()) {
271 if (attr.getKey().startsWith("xml:")) {
272 serializer.writeAttribute("http://www.w3.org/XML/1998/namespace",
273 attr.getKey().substring(4), attr.getValue());
274 } else {
275 serializer.writeAttribute(attr.getKey(), attr.getValue());
276 }
277 }
278 for (XmlNode child : dom.getChildren()) {
279 writeDom(child, serializer);
280 }
281 String value = dom.getValue();
282 if (value != null) {
283 serializer.writeCharacters(value);
284 }
285 serializer.writeEndElement();
286 }
287 }
288
289 private void writeTag(String tagName, String defaultValue, String value, XMLStreamWriter serializer) throws IOException, XMLStreamException {
290 if (value != null && !Objects.equals(defaultValue, value)) {
291 serializer.writeStartElement(namespace, tagName);
292 serializer.writeCharacters(value);
293 serializer.writeEndElement();
294 }
295 }
296
297 private void writeAttr(String attrName, String value, XMLStreamWriter serializer) throws IOException, XMLStreamException {
298 if (value != null) {
299 serializer.writeAttribute(attrName, value);
300 }
301 }
302
303 static class IndentingXMLStreamWriter extends StreamWriterDelegate {
304
305 int depth = 0;
306 boolean hasChildren = false;
307
308 public IndentingXMLStreamWriter(XMLStreamWriter parent) {
309 super(parent);
310 }
311
312 @Override
313 public void writeEmptyElement(String localName) throws XMLStreamException {
314 indent();
315 super.writeEmptyElement(localName);
316 hasChildren = true;
317 }
318
319 @Override
320 public void writeEmptyElement(String namespaceURI, String localName) throws XMLStreamException {
321 indent();
322 super.writeEmptyElement(namespaceURI, localName);
323 hasChildren = true;
324 }
325
326 @Override
327 public void writeEmptyElement(String prefix, String localName, String namespaceURI) throws XMLStreamException {
328 indent();
329 super.writeEmptyElement(prefix, localName, namespaceURI);
330 hasChildren = true;
331 }
332
333 @Override
334 public void writeStartElement(String localName) throws XMLStreamException {
335 indent();
336 super.writeStartElement(localName);
337 depth++;
338 hasChildren = false;
339 }
340
341 @Override
342 public void writeStartElement(String namespaceURI, String localName) throws XMLStreamException {
343 indent();
344 super.writeStartElement(namespaceURI, localName);
345 depth++;
346 hasChildren = false;
347 }
348
349 @Override
350 public void writeStartElement(String prefix, String localName, String namespaceURI) throws XMLStreamException {
351 indent();
352 super.writeStartElement(prefix, localName, namespaceURI);
353 depth++;
354 hasChildren = false;
355 }
356
357 @Override
358 public void writeEndElement() throws XMLStreamException {
359 depth--;
360 if (hasChildren) {
361 indent();
362 }
363 super.writeEndElement();
364 hasChildren = true;
365 }
366
367 private void indent() throws XMLStreamException {
368 super.writeCharacters("\n");
369 for (int i = 0; i < depth; i++) {
370 super.writeCharacters(" ");
371 }
372 }
373 }
374 }