View Javadoc
1   /*
2    * Licensed to the Apache Software Foundation (ASF) under one
3    * or more contributor license agreements.  See the NOTICE file
4    * distributed with this work for additional information
5    * regarding copyright ownership.  The ASF licenses this file
6    * to you under the Apache License, Version 2.0 (the
7    * "License"); you may not use this file except in compliance
8    * with the License.  You may obtain a copy of the License at
9    *
10   *   http://www.apache.org/licenses/LICENSE-2.0
11   *
12   * Unless required by applicable law or agreed to in writing,
13   * software distributed under the License is distributed on an
14   * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15   * KIND, either express or implied.  See the License for the
16   * specific language governing permissions and limitations
17   * under the License.
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 }