1
2
3
4
5 package org.apache.maven.cli.internal.extension.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.cli.internal.extension.model.CoreExtensions;
28 import org.apache.maven.cli.internal.extension.model.CoreExtension;
29 import org.codehaus.stax2.util.StreamWriterDelegate;
30
31 import static javax.xml.XMLConstants.W3C_XML_SCHEMA_INSTANCE_NS_URI;
32
33 @Generated
34 public class CoreExtensionsStaxWriter {
35
36
37
38
39
40
41
42
43 private static final String NAMESPACE = "http://maven.apache.org/EXTENSIONS/1.2.0";
44
45
46
47
48 private static final String SCHEMA_LOCATION = "http://maven.apache.org/xsd/core-extensions-1.2.0.xsd";
49
50
51
52
53 private String namespace = NAMESPACE;
54
55
56
57
58 private String schemaLocation = SCHEMA_LOCATION;
59
60
61
62
63 private String fileComment = null;
64
65
66
67
68
69
70
71
72
73
74 public void setNamespace(String namespace) {
75 this.namespace = Objects.requireNonNull(namespace);
76 }
77
78
79
80
81
82
83 public void setSchemaLocation(String schemaLocation) {
84 this.schemaLocation = Objects.requireNonNull(schemaLocation);
85 }
86
87
88
89
90
91
92 public void setFileComment(String fileComment) {
93 this.fileComment = fileComment;
94 }
95
96
97
98
99
100
101
102
103 public void write(Writer writer, CoreExtensions coreExtensions) throws IOException, XMLStreamException {
104 XMLOutputFactory factory = new com.ctc.wstx.stax.WstxOutputFactory();
105 factory.setProperty(XMLOutputFactory.IS_REPAIRING_NAMESPACES, false);
106 factory.setProperty(com.ctc.wstx.api.WstxOutputProperties.P_USE_DOUBLE_QUOTES_IN_XML_DECL, true);
107 factory.setProperty(com.ctc.wstx.api.WstxOutputProperties.P_ADD_SPACE_AFTER_EMPTY_ELEM, true);
108 XMLStreamWriter serializer = new IndentingXMLStreamWriter(factory.createXMLStreamWriter(writer));
109 serializer.writeStartDocument(coreExtensions.getModelEncoding(), null);
110 writeCoreExtensions("extensions", coreExtensions, serializer);
111 serializer.writeEndDocument();
112 }
113
114
115
116
117
118
119
120
121 public void write(OutputStream stream, CoreExtensions coreExtensions) throws IOException, XMLStreamException {
122 XMLOutputFactory factory = new com.ctc.wstx.stax.WstxOutputFactory();
123 factory.setProperty(XMLOutputFactory.IS_REPAIRING_NAMESPACES, false);
124 factory.setProperty(com.ctc.wstx.api.WstxOutputProperties.P_USE_DOUBLE_QUOTES_IN_XML_DECL, true);
125 factory.setProperty(com.ctc.wstx.api.WstxOutputProperties.P_ADD_SPACE_AFTER_EMPTY_ELEM, true);
126 XMLStreamWriter serializer = new IndentingXMLStreamWriter(factory.createXMLStreamWriter(stream, coreExtensions.getModelEncoding()));
127 serializer.writeStartDocument(coreExtensions.getModelEncoding(), null);
128 writeCoreExtensions("extensions", coreExtensions, serializer);
129 serializer.writeEndDocument();
130 }
131
132 private void writeCoreExtensions(String tagName, CoreExtensions coreExtensions, XMLStreamWriter serializer)
133 throws IOException, XMLStreamException {
134 if (coreExtensions != null) {
135 if (this.fileComment != null) {
136 serializer.writeCharacters("\n");
137 serializer.writeComment(this.fileComment);
138 serializer.writeCharacters("\n");
139 }
140 serializer.writeStartElement("", tagName, namespace);
141 serializer.writeNamespace("", namespace);
142 serializer.writeNamespace("xsi", W3C_XML_SCHEMA_INSTANCE_NS_URI);
143 serializer.writeAttribute(W3C_XML_SCHEMA_INSTANCE_NS_URI, "schemaLocation", namespace + " " + schemaLocation);
144 writeList("extensions", true, coreExtensions.getExtensions(), serializer,
145 t -> writeCoreExtension("extension", t, serializer));
146 serializer.writeEndElement();
147 }
148 }
149
150 private void writeCoreExtension(String tagName, CoreExtension coreExtension, XMLStreamWriter serializer)
151 throws IOException, XMLStreamException {
152 if (coreExtension != null) {
153 serializer.writeStartElement(namespace, tagName);
154 writeTag("groupId", null, coreExtension.getGroupId(), serializer);
155 writeTag("artifactId", null, coreExtension.getArtifactId(), serializer);
156 writeTag("version", null, coreExtension.getVersion(), serializer);
157 writeTag("classLoadingStrategy", "self-first", coreExtension.getClassLoadingStrategy(), serializer);
158 writeDom(coreExtension.getConfiguration(), serializer);
159 serializer.writeEndElement();
160 }
161 }
162
163 @FunctionalInterface
164 private interface ElementWriter<T> {
165 public void write(T t) throws IOException, XMLStreamException;
166 }
167
168 private <T> void writeList(String tagName, List<T> list, XMLStreamWriter serializer, ElementWriter<T> writer) throws IOException, XMLStreamException {
169 writeList(tagName, false, list, serializer, writer);
170 }
171
172 private <T> void writeList(String tagName, boolean flat, List<T> list, XMLStreamWriter serializer, ElementWriter<T> writer) throws IOException, XMLStreamException {
173 if (list != null && !list.isEmpty()) {
174 if (!flat) {
175 serializer.writeStartElement(namespace, tagName);
176 }
177 int index = 0;
178 for (T t : list) {
179 writer.write(t);
180 }
181 if (!flat) {
182 serializer.writeEndElement();
183 }
184 }
185 }
186
187 private <T> void writeProperties(String tagName, Map<String, String> props, XMLStreamWriter serializer) throws IOException, XMLStreamException {
188 if (props != null && !props.isEmpty()) {
189 serializer.writeStartElement(namespace, tagName);
190 for (Map.Entry<String, String> entry : props.entrySet()) {
191 String key = entry.getKey();
192 writeTag(key, null, entry.getValue(), serializer);
193 }
194 serializer.writeEndElement();
195 }
196 }
197
198 private void writeDom(XmlNode dom, XMLStreamWriter serializer) throws IOException, XMLStreamException {
199 if (dom != null) {
200 serializer.writeStartElement(namespace, dom.getName());
201 for (Map.Entry<String, String> attr : dom.getAttributes().entrySet()) {
202 if (attr.getKey().startsWith("xml:")) {
203 serializer.writeAttribute("http://www.w3.org/XML/1998/namespace",
204 attr.getKey().substring(4), attr.getValue());
205 } else {
206 serializer.writeAttribute(attr.getKey(), attr.getValue());
207 }
208 }
209 for (XmlNode child : dom.getChildren()) {
210 writeDom(child, serializer);
211 }
212 String value = dom.getValue();
213 if (value != null) {
214 serializer.writeCharacters(value);
215 }
216 serializer.writeEndElement();
217 }
218 }
219
220 private void writeTag(String tagName, String defaultValue, String value, XMLStreamWriter serializer) throws IOException, XMLStreamException {
221 if (value != null && !Objects.equals(defaultValue, value)) {
222 serializer.writeStartElement(namespace, tagName);
223 serializer.writeCharacters(value);
224 serializer.writeEndElement();
225 }
226 }
227
228 private void writeAttr(String attrName, String value, XMLStreamWriter serializer) throws IOException, XMLStreamException {
229 if (value != null) {
230 serializer.writeAttribute(attrName, value);
231 }
232 }
233
234 static class IndentingXMLStreamWriter extends StreamWriterDelegate {
235
236 int depth = 0;
237 boolean hasChildren = false;
238
239 public IndentingXMLStreamWriter(XMLStreamWriter parent) {
240 super(parent);
241 }
242
243 @Override
244 public void writeEmptyElement(String localName) throws XMLStreamException {
245 indent();
246 super.writeEmptyElement(localName);
247 hasChildren = true;
248 }
249
250 @Override
251 public void writeEmptyElement(String namespaceURI, String localName) throws XMLStreamException {
252 indent();
253 super.writeEmptyElement(namespaceURI, localName);
254 hasChildren = true;
255 }
256
257 @Override
258 public void writeEmptyElement(String prefix, String localName, String namespaceURI) throws XMLStreamException {
259 indent();
260 super.writeEmptyElement(prefix, localName, namespaceURI);
261 hasChildren = true;
262 }
263
264 @Override
265 public void writeStartElement(String localName) throws XMLStreamException {
266 indent();
267 super.writeStartElement(localName);
268 depth++;
269 hasChildren = false;
270 }
271
272 @Override
273 public void writeStartElement(String namespaceURI, String localName) throws XMLStreamException {
274 indent();
275 super.writeStartElement(namespaceURI, localName);
276 depth++;
277 hasChildren = false;
278 }
279
280 @Override
281 public void writeStartElement(String prefix, String localName, String namespaceURI) throws XMLStreamException {
282 indent();
283 super.writeStartElement(prefix, localName, namespaceURI);
284 depth++;
285 hasChildren = false;
286 }
287
288 @Override
289 public void writeEndElement() throws XMLStreamException {
290 depth--;
291 if (hasChildren) {
292 indent();
293 }
294 super.writeEndElement();
295 hasChildren = true;
296 }
297
298 private void indent() throws XMLStreamException {
299 super.writeCharacters("\n");
300 for (int i = 0; i < depth; i++) {
301 super.writeCharacters(" ");
302 }
303 }
304 }
305 }