View Javadoc
1   // =================== DO NOT EDIT THIS FILE ====================
2   //  Generated by Modello Velocity from writer-stax.vm
3   //  template, any modifications will be overwritten.
4   // ==============================================================
5   package org.apache.maven.artifact.repository.metadata.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.artifact.repository.metadata.v4.Metadata;
28  import org.apache.maven.artifact.repository.metadata.v4.Versioning;
29  import org.apache.maven.artifact.repository.metadata.v4.Snapshot;
30  import org.apache.maven.artifact.repository.metadata.v4.SnapshotVersion;
31  import org.apache.maven.artifact.repository.metadata.v4.Plugin;
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 MetadataStaxWriter {
38  
39        //--------------------------/
40       //- Class/Member Variables -/
41      //--------------------------/
42  
43      /**
44       * Default namespace.
45       */
46      private static final String NAMESPACE = "http://maven.apache.org/METADATA/1.1.0";
47  
48      /**
49       * Default schemaLocation.
50       */
51      private static final String SCHEMA_LOCATION = "https://maven.apache.org/xsd/repository-metadata-1.1.0.xsd";
52  
53      /**
54       * Field namespace.
55       */
56      private String namespace = NAMESPACE;
57  
58      /**
59       * Field schemaLocation.
60       */
61      private String schemaLocation = SCHEMA_LOCATION;
62  
63      /**
64       * Field fileComment.
65       */
66      private String fileComment = null;
67  
68        //-----------/
69       //- Methods -/
70      //-----------/
71  
72      /**
73       * Method setNamespace.
74       *
75       * @param namespace the namespace to use.
76       */
77      public void setNamespace(String namespace) {
78          this.namespace = Objects.requireNonNull(namespace);
79      } //-- void setNamespace(String)
80  
81      /**
82       * Method setSchemaLocation.
83       *
84       * @param schemaLocation the schema location to use.
85       */
86      public void setSchemaLocation(String schemaLocation) {
87          this.schemaLocation = Objects.requireNonNull(schemaLocation);
88          } //-- void setSchemaLocation(String)
89  
90      /**
91       * Method setFileComment.
92       *
93       * @param fileComment a fileComment object.
94       */
95      public void setFileComment(String fileComment) {
96          this.fileComment = fileComment;
97      } //-- void setFileComment(String)
98  
99      /**
100      * Method write.
101      *
102      * @param writer a writer object
103      * @param metadata a Metadata object
104      * @throws IOException IOException if any
105      */
106     public void write(Writer writer, Metadata metadata) 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(metadata.getModelEncoding(), null);
113         writeMetadata("metadata", metadata, serializer);
114         serializer.writeEndDocument();
115     } //-- void write(Writer, Metadata)
116 
117     /**
118      * Method write.
119      *
120      * @param stream a stream object
121      * @param metadata a Metadata object
122      * @throws IOException IOException if any
123      */
124     public void write(OutputStream stream, Metadata metadata) 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, metadata.getModelEncoding()));
130         serializer.writeStartDocument(metadata.getModelEncoding(), null);
131         writeMetadata("metadata", metadata, serializer);
132         serializer.writeEndDocument();
133     } //-- void write(OutputStream, Metadata)
134 
135     private void writeMetadata(String tagName, Metadata metadata, XMLStreamWriter serializer)
136         throws IOException, XMLStreamException {
137         if (metadata != 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             writeAttr("modelVersion", metadata.getModelVersion(), serializer);
148             writeTag("groupId", null, metadata.getGroupId(), serializer);
149             writeTag("artifactId", null, metadata.getArtifactId(), serializer);
150             writeVersioning("versioning", metadata.getVersioning(), serializer);
151             writeTag("version", null, metadata.getVersion(), serializer);
152             writeList("plugins", false, metadata.getPlugins(), serializer,
153                     t -> writePlugin("plugin", t, serializer));
154             serializer.writeEndElement();
155         }
156     }
157 
158     private void writeVersioning(String tagName, Versioning versioning, XMLStreamWriter serializer)
159         throws IOException, XMLStreamException {
160         if (versioning != null) {
161             serializer.writeStartElement(namespace, tagName);
162             writeTag("latest", null, versioning.getLatest(), serializer);
163             writeTag("release", null, versioning.getRelease(), serializer);
164             writeList("versions", versioning.getVersions(), serializer,
165                     t -> writeTag("version", null, t, serializer));
166             writeTag("lastUpdated", null, versioning.getLastUpdated(), serializer);
167             writeSnapshot("snapshot", versioning.getSnapshot(), serializer);
168             writeList("snapshotVersions", false, versioning.getSnapshotVersions(), serializer,
169                     t -> writeSnapshotVersion("snapshotVersion", t, serializer));
170             serializer.writeEndElement();
171         }
172     }
173 
174     private void writeSnapshot(String tagName, Snapshot snapshot, XMLStreamWriter serializer)
175         throws IOException, XMLStreamException {
176         if (snapshot != null) {
177             serializer.writeStartElement(namespace, tagName);
178             writeTag("timestamp", null, snapshot.getTimestamp(), serializer);
179             writeTag("buildNumber", "0", Integer.toString(snapshot.getBuildNumber()), serializer);
180             writeTag("localCopy", "false", snapshot.isLocalCopy() ? "true" : null, serializer);
181             serializer.writeEndElement();
182         }
183     }
184 
185     private void writeSnapshotVersion(String tagName, SnapshotVersion snapshotVersion, XMLStreamWriter serializer)
186         throws IOException, XMLStreamException {
187         if (snapshotVersion != null) {
188             serializer.writeStartElement(namespace, tagName);
189             writeTag("classifier", null, snapshotVersion.getClassifier(), serializer);
190             writeTag("extension", null, snapshotVersion.getExtension(), serializer);
191             writeTag("value", null, snapshotVersion.getVersion(), serializer);
192             writeTag("updated", null, snapshotVersion.getUpdated(), serializer);
193             serializer.writeEndElement();
194         }
195     }
196 
197     private void writePlugin(String tagName, Plugin plugin, XMLStreamWriter serializer)
198         throws IOException, XMLStreamException {
199         if (plugin != null) {
200             serializer.writeStartElement(namespace, tagName);
201             writeTag("name", null, plugin.getName(), serializer);
202             writeTag("prefix", null, plugin.getPrefix(), serializer);
203             writeTag("artifactId", null, plugin.getArtifactId(), serializer);
204             serializer.writeEndElement();
205         }
206     }
207 
208     @FunctionalInterface
209     private interface ElementWriter<T> {
210         public void write(T t) throws IOException, XMLStreamException;
211     }
212 
213     private <T> void writeList(String tagName, List<T> list, XMLStreamWriter serializer, ElementWriter<T> writer) throws IOException, XMLStreamException {
214         writeList(tagName, false, list, serializer, writer);
215     }
216 
217     private <T> void writeList(String tagName, boolean flat, List<T> list, XMLStreamWriter serializer, ElementWriter<T> writer) throws IOException, XMLStreamException {
218         if (list != null && !list.isEmpty()) {
219             if (!flat) {
220                 serializer.writeStartElement(namespace, tagName);
221             }
222             int index = 0;
223             for (T t : list) {
224                 writer.write(t);
225             }
226             if (!flat) {
227                 serializer.writeEndElement();
228             }
229         }
230     }
231 
232     private <T> void writeProperties(String tagName, Map<String, String> props, XMLStreamWriter serializer) throws IOException, XMLStreamException {
233         if (props != null && !props.isEmpty()) {
234             serializer.writeStartElement(namespace, tagName);
235             for (Map.Entry<String, String> entry : props.entrySet()) {
236                 String key = entry.getKey();
237                 writeTag(key, null, entry.getValue(), serializer);
238             }
239             serializer.writeEndElement();
240         }
241     }
242 
243     private void writeDom(XmlNode dom, XMLStreamWriter serializer) throws IOException, XMLStreamException {
244         if (dom != null) {
245             serializer.writeStartElement(namespace, dom.getName());
246             for (Map.Entry<String, String> attr : dom.getAttributes().entrySet()) {
247                 if (attr.getKey().startsWith("xml:")) {
248                     serializer.writeAttribute("http://www.w3.org/XML/1998/namespace",
249                     attr.getKey().substring(4), attr.getValue());
250                 } else {
251                     serializer.writeAttribute(attr.getKey(), attr.getValue());
252                 }
253             }
254             for (XmlNode child : dom.getChildren()) {
255                 writeDom(child, serializer);
256             }
257             String value = dom.getValue();
258             if (value != null) {
259                 serializer.writeCharacters(value);
260             }
261             serializer.writeEndElement();
262         }
263     }
264 
265     private void writeTag(String tagName, String defaultValue, String value, XMLStreamWriter serializer) throws IOException, XMLStreamException {
266         if (value != null && !Objects.equals(defaultValue, value)) {
267             serializer.writeStartElement(namespace, tagName);
268             serializer.writeCharacters(value);
269             serializer.writeEndElement();
270         }
271     }
272 
273     private void writeAttr(String attrName, String value, XMLStreamWriter serializer) throws IOException, XMLStreamException {
274         if (value != null) {
275             serializer.writeAttribute(attrName, value);
276         }
277     }
278 
279     static class IndentingXMLStreamWriter extends StreamWriterDelegate {
280 
281         int depth = 0;
282         boolean hasChildren = false;
283 
284         public IndentingXMLStreamWriter(XMLStreamWriter parent) {
285             super(parent);
286         }
287 
288         @Override
289         public void writeEmptyElement(String localName) throws XMLStreamException {
290             indent();
291             super.writeEmptyElement(localName);
292             hasChildren = true;
293         }
294 
295         @Override
296         public void writeEmptyElement(String namespaceURI, String localName) throws XMLStreamException {
297             indent();
298             super.writeEmptyElement(namespaceURI, localName);
299             hasChildren = true;
300         }
301 
302         @Override
303         public void writeEmptyElement(String prefix, String localName, String namespaceURI) throws XMLStreamException {
304             indent();
305             super.writeEmptyElement(prefix, localName, namespaceURI);
306             hasChildren = true;
307         }
308 
309         @Override
310         public void writeStartElement(String localName) throws XMLStreamException {
311             indent();
312             super.writeStartElement(localName);
313             depth++;
314             hasChildren = false;
315         }
316 
317         @Override
318         public void writeStartElement(String namespaceURI, String localName) throws XMLStreamException {
319             indent();
320             super.writeStartElement(namespaceURI, localName);
321             depth++;
322             hasChildren = false;
323         }
324 
325         @Override
326         public void writeStartElement(String prefix, String localName, String namespaceURI) throws XMLStreamException {
327             indent();
328             super.writeStartElement(prefix, localName, namespaceURI);
329             depth++;
330             hasChildren = false;
331         }
332 
333         @Override
334         public void writeEndElement() throws XMLStreamException {
335             depth--;
336             if (hasChildren) {
337                 indent();
338             }
339             super.writeEndElement();
340             hasChildren = true;
341         }
342 
343         private void indent() throws XMLStreamException {
344             super.writeCharacters("\n");
345             for (int i = 0; i < depth; i++) {
346                 super.writeCharacters("  ");
347             }
348         }
349     }
350 }