1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19 package org.apache.maven.internal.xml;
20
21 import javax.xml.stream.XMLOutputFactory;
22 import javax.xml.stream.XMLStreamException;
23 import javax.xml.stream.XMLStreamWriter;
24
25 import java.io.Writer;
26 import java.util.Map;
27
28 import org.apache.maven.api.xml.XmlNode;
29 import org.codehaus.stax2.util.StreamWriterDelegate;
30
31
32
33
34 public class XmlNodeWriter {
35 public static void write(Writer writer, XmlNode dom) throws XMLStreamException {
36 XMLOutputFactory factory = new com.ctc.wstx.stax.WstxOutputFactory();
37 factory.setProperty(XMLOutputFactory.IS_REPAIRING_NAMESPACES, false);
38 factory.setProperty(com.ctc.wstx.api.WstxOutputProperties.P_USE_DOUBLE_QUOTES_IN_XML_DECL, true);
39 factory.setProperty(com.ctc.wstx.api.WstxOutputProperties.P_ADD_SPACE_AFTER_EMPTY_ELEM, true);
40 XMLStreamWriter serializer = new IndentingXMLStreamWriter(factory.createXMLStreamWriter(writer));
41 write(serializer, dom);
42 serializer.close();
43 }
44
45 public static void write(XMLStreamWriter xmlWriter, XmlNode dom) throws XMLStreamException {
46 xmlWriter.writeStartElement(dom.getPrefix(), dom.getName(), dom.getNamespaceUri());
47 for (Map.Entry<String, String> attr : dom.getAttributes().entrySet()) {
48 xmlWriter.writeAttribute(attr.getKey(), attr.getValue());
49 }
50 for (XmlNode aChildren : dom.getChildren()) {
51 write(xmlWriter, aChildren);
52 }
53 String value = dom.getValue();
54 if (value != null) {
55 xmlWriter.writeCharacters(value);
56 }
57 xmlWriter.writeEndElement();
58 }
59
60 static class IndentingXMLStreamWriter extends StreamWriterDelegate {
61
62 int depth = 0;
63 boolean hasChildren = false;
64 boolean anew = true;
65
66 IndentingXMLStreamWriter(XMLStreamWriter parent) {
67 super(parent);
68 }
69
70 @Override
71 public void writeStartDocument() throws XMLStreamException {
72 super.writeStartDocument();
73 anew = false;
74 }
75
76 @Override
77 public void writeStartDocument(String version) throws XMLStreamException {
78 super.writeStartDocument(version);
79 anew = false;
80 }
81
82 @Override
83 public void writeStartDocument(String encoding, String version) throws XMLStreamException {
84 super.writeStartDocument(encoding, version);
85 anew = false;
86 }
87
88 @Override
89 public void writeEmptyElement(String localName) throws XMLStreamException {
90 indent();
91 super.writeEmptyElement(localName);
92 hasChildren = true;
93 anew = false;
94 }
95
96 @Override
97 public void writeEmptyElement(String namespaceURI, String localName) throws XMLStreamException {
98 indent();
99 super.writeEmptyElement(namespaceURI, localName);
100 hasChildren = true;
101 anew = false;
102 }
103
104 @Override
105 public void writeEmptyElement(String prefix, String localName, String namespaceURI) throws XMLStreamException {
106 indent();
107 super.writeEmptyElement(prefix, localName, namespaceURI);
108 hasChildren = true;
109 anew = false;
110 }
111
112 @Override
113 public void writeStartElement(String localName) throws XMLStreamException {
114 indent();
115 super.writeStartElement(localName);
116 depth++;
117 hasChildren = false;
118 anew = false;
119 }
120
121 @Override
122 public void writeStartElement(String namespaceURI, String localName) throws XMLStreamException {
123 indent();
124 super.writeStartElement(namespaceURI, localName);
125 depth++;
126 hasChildren = false;
127 anew = false;
128 }
129
130 @Override
131 public void writeStartElement(String prefix, String localName, String namespaceURI) throws XMLStreamException {
132 indent();
133 super.writeStartElement(prefix, localName, namespaceURI);
134 depth++;
135 hasChildren = false;
136 anew = false;
137 }
138
139 @Override
140 public void writeEndElement() throws XMLStreamException {
141 depth--;
142 if (hasChildren) {
143 indent();
144 }
145 super.writeEndElement();
146 hasChildren = true;
147 anew = false;
148 }
149
150 private void indent() throws XMLStreamException {
151 if (!anew) {
152 super.writeCharacters("\n");
153 }
154 for (int i = 0; i < depth; i++) {
155 super.writeCharacters(" ");
156 }
157 }
158 }
159 }