1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27 package gov.nist.secauto.metaschema.core.model.xml;
28
29 import org.codehaus.stax2.XMLStreamWriter2;
30 import org.codehaus.stax2.util.StreamWriter2Delegate;
31
32 import java.util.HashMap;
33 import java.util.Map;
34 import java.util.Objects;
35
36 import javax.xml.stream.XMLStreamException;
37
38 public class IndentingXmlStreamWriter2
39 extends StreamWriter2Delegate {
40 private String indentText = DEFAULT_INDENT_TEXT;
41 private String lineEndText = DEFAULT_LINE_END_TEXT;
42 private int depth;
43 private final Map<Integer, Boolean> depthWithChildMap = new HashMap<>();
44 private static final String DEFAULT_INDENT_TEXT = " ";
45 private static final String DEFAULT_LINE_END_TEXT = "\n";
46
47 public IndentingXmlStreamWriter2(XMLStreamWriter2 parent) {
48 super(parent);
49 }
50
51 protected String getIndentText() {
52 return indentText;
53 }
54
55 protected void setIndentText(String indentText) {
56 Objects.requireNonNull(indentText, "indentText");
57 this.indentText = indentText;
58 }
59
60 protected String getLineEndText() {
61 return lineEndText;
62 }
63
64 protected void setLineEndText(String lineEndText) {
65 Objects.requireNonNull(lineEndText, "lineEndText");
66 this.lineEndText = lineEndText;
67 }
68
69 protected void handleStartElement() throws XMLStreamException {
70
71 if (depth > 0) {
72 depthWithChildMap.put(depth - 1, true);
73 }
74
75 depthWithChildMap.put(depth, false);
76
77 getParent().writeCharacters(getLineEndText());
78 getParent().writeCharacters(getIndentText().repeat(depth));
79 depth++;
80 }
81
82 @Override
83 public void writeStartElement(String localName) throws XMLStreamException {
84 handleStartElement();
85 super.writeStartElement(localName);
86 }
87
88 @Override
89 public void writeStartElement(String namespaceURI, String localName) throws XMLStreamException {
90 handleStartElement();
91 super.writeStartElement(namespaceURI, localName);
92 }
93
94 @Override
95 public void writeStartElement(String prefix,
96 String localName,
97 String namespaceURI) throws XMLStreamException {
98 handleStartElement();
99 super.writeStartElement(prefix, localName, namespaceURI);
100 }
101
102 protected void handleEndElement() throws XMLStreamException {
103 depth--;
104 if (depthWithChildMap.get(depth)) {
105 getParent().writeCharacters(getLineEndText());
106 getParent().writeCharacters(getIndentText().repeat(depth));
107 }
108 }
109
110 @Override
111 public void writeEndElement() throws XMLStreamException {
112 handleEndElement();
113 super.writeEndElement();
114 }
115
116 @Override
117 public void writeFullEndElement() throws XMLStreamException {
118 handleEndElement();
119 super.writeFullEndElement();
120 }
121
122 protected void handleEmptyElement() throws XMLStreamException {
123
124 if (depth > 0) {
125 depthWithChildMap.put(depth - 1, true);
126 }
127
128 getParent().writeCharacters(getLineEndText());
129 getParent().writeCharacters(getIndentText().repeat(depth));
130 }
131
132 @Override
133 public void writeEmptyElement(String localName) throws XMLStreamException {
134 handleEmptyElement();
135 super.writeEmptyElement(localName);
136 }
137
138 @Override
139 public void writeEmptyElement(String namespaceURI, String localName) throws XMLStreamException {
140 handleEmptyElement();
141 super.writeEmptyElement(namespaceURI, localName);
142 }
143
144 @Override
145 public void writeEmptyElement(String prefix, String localName, String namespaceURI) throws XMLStreamException {
146 handleEmptyElement();
147 super.writeEmptyElement(prefix, localName, namespaceURI);
148 }
149 }