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