Skip to content

Commit 3d059ab

Browse files
committed
Add IndentingXmlStreamWriter class
1 parent 4f354ff commit 3d059ab

3 files changed

Lines changed: 238 additions & 236 deletions

File tree

Lines changed: 238 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,238 @@
1+
/*
2+
* Copyright 2016-2025 Pavel Castornii.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
package com.techsenger.toolkit.core.xml;
18+
19+
import javax.xml.namespace.NamespaceContext;
20+
import javax.xml.stream.XMLStreamException;
21+
import javax.xml.stream.XMLStreamWriter;
22+
23+
/**
24+
* Decorator over {@link XMLStreamWriter} that adds pretty-print indentation.
25+
*
26+
* <p>Standard StAX API has no built-in support for indentation — output is compact by default. This class wraps any
27+
* {@link XMLStreamWriter} and inserts newlines and indentation before each element, making the resulting XML
28+
* human-readable.
29+
*
30+
* <p>All methods delegate to the underlying writer; only element-related methods
31+
* ({@code writeStartElement}, {@code writeEndElement}, {@code writeEmptyElement}) are intercepted to inject whitespace.
32+
*
33+
* <p>Example usage:
34+
* <pre>{@code
35+
* XMLStreamWriter raw = XMLOutputFactory.newInstance()
36+
* .createXMLStreamWriter(Files.newOutputStream(path), "UTF-8");
37+
*
38+
* XMLStreamWriter xml = new IndentingXMLStreamWriter(raw);
39+
*
40+
* xml.writeStartElement(...);
41+
* ...
42+
* xml.writeEndDocument();
43+
* xml.flush();
44+
* }</pre>
45+
*
46+
* @author Pavel Castornii
47+
*/
48+
public class IndentingXmlStreamWriter implements XMLStreamWriter, AutoCloseable {
49+
50+
private final XMLStreamWriter delegate;
51+
private final String indent;
52+
private int depth = 0;
53+
54+
public IndentingXmlStreamWriter(XMLStreamWriter delegate) {
55+
this(delegate, " ");
56+
}
57+
58+
public IndentingXmlStreamWriter(XMLStreamWriter delegate, String indent) {
59+
this.delegate = delegate;
60+
this.indent = indent;
61+
}
62+
63+
@Override
64+
public void writeStartElement(String localName) throws XMLStreamException {
65+
writeIndent();
66+
delegate.writeStartElement(localName);
67+
depth++;
68+
}
69+
70+
@Override
71+
public void writeStartElement(String namespaceURI, String localName) throws XMLStreamException {
72+
writeIndent();
73+
delegate.writeStartElement(namespaceURI, localName);
74+
depth++;
75+
}
76+
77+
@Override
78+
public void writeStartElement(String prefix, String localName, String namespaceURI) throws XMLStreamException {
79+
writeIndent();
80+
delegate.writeStartElement(prefix, localName, namespaceURI);
81+
depth++;
82+
}
83+
84+
@Override
85+
public void writeEndElement() throws XMLStreamException {
86+
depth--;
87+
writeIndent();
88+
delegate.writeEndElement();
89+
}
90+
91+
@Override
92+
public void writeEmptyElement(String localName) throws XMLStreamException {
93+
writeIndent();
94+
delegate.writeEmptyElement(localName);
95+
}
96+
97+
@Override
98+
public void writeEmptyElement(String namespaceURI, String localName) throws XMLStreamException {
99+
writeIndent();
100+
delegate.writeEmptyElement(namespaceURI, localName);
101+
}
102+
103+
@Override
104+
public void writeEmptyElement(String prefix, String localName, String namespaceURI) throws XMLStreamException {
105+
writeIndent();
106+
delegate.writeEmptyElement(prefix, localName, namespaceURI);
107+
}
108+
109+
@Override
110+
public void writeStartDocument() throws XMLStreamException {
111+
delegate.writeStartDocument();
112+
}
113+
114+
@Override
115+
public void writeStartDocument(String version) throws XMLStreamException {
116+
delegate.writeStartDocument(version);
117+
}
118+
119+
@Override
120+
public void writeStartDocument(String encoding, String version) throws XMLStreamException {
121+
delegate.writeStartDocument(encoding, version);
122+
}
123+
124+
@Override
125+
public void writeEndDocument() throws XMLStreamException {
126+
delegate.writeEndDocument();
127+
}
128+
129+
@Override
130+
public void writeAttribute(String localName, String value) throws XMLStreamException {
131+
delegate.writeAttribute(localName, value);
132+
}
133+
134+
@Override
135+
public void writeAttribute(String namespaceURI, String localName, String value) throws XMLStreamException {
136+
delegate.writeAttribute(namespaceURI, localName, value);
137+
}
138+
139+
@Override
140+
public void writeAttribute(String prefix, String namespaceURI, String localName, String value)
141+
throws XMLStreamException {
142+
delegate.writeAttribute(prefix, namespaceURI, localName, value);
143+
}
144+
145+
@Override
146+
public void writeCharacters(String text) throws XMLStreamException {
147+
delegate.writeCharacters(text);
148+
}
149+
150+
@Override
151+
public void writeCharacters(char[] text, int start, int len) throws XMLStreamException {
152+
delegate.writeCharacters(text, start, len);
153+
}
154+
155+
@Override
156+
public void writeCData(String data) throws XMLStreamException {
157+
delegate.writeCData(data);
158+
}
159+
160+
@Override
161+
public void writeComment(String data) throws XMLStreamException {
162+
delegate.writeComment(data);
163+
}
164+
165+
@Override
166+
public void writeNamespace(String prefix, String namespaceURI) throws XMLStreamException {
167+
delegate.writeNamespace(prefix, namespaceURI);
168+
}
169+
170+
@Override
171+
public void writeDefaultNamespace(String namespaceURI) throws XMLStreamException {
172+
delegate.writeDefaultNamespace(namespaceURI);
173+
}
174+
175+
@Override
176+
public void writeProcessingInstruction(String target) throws XMLStreamException {
177+
delegate.writeProcessingInstruction(target);
178+
}
179+
180+
@Override
181+
public void writeProcessingInstruction(String target, String data) throws XMLStreamException {
182+
delegate.writeProcessingInstruction(target, data);
183+
}
184+
185+
@Override
186+
public void writeEntityRef(String name) throws XMLStreamException {
187+
delegate.writeEntityRef(name);
188+
}
189+
190+
@Override
191+
public void writeDTD(String dtd) throws XMLStreamException {
192+
delegate.writeDTD(dtd);
193+
}
194+
195+
@Override
196+
public void flush() throws XMLStreamException {
197+
delegate.flush();
198+
}
199+
200+
@Override
201+
public void close() throws XMLStreamException {
202+
delegate.close();
203+
}
204+
205+
@Override
206+
public String getPrefix(String uri) throws XMLStreamException {
207+
return delegate.getPrefix(uri);
208+
}
209+
210+
@Override
211+
public void setPrefix(String prefix, String uri) throws XMLStreamException {
212+
delegate.setPrefix(prefix, uri);
213+
}
214+
215+
@Override
216+
public void setDefaultNamespace(String uri) throws XMLStreamException {
217+
delegate.setDefaultNamespace(uri);
218+
}
219+
220+
@Override
221+
public void setNamespaceContext(NamespaceContext context) throws XMLStreamException {
222+
delegate.setNamespaceContext(context);
223+
}
224+
225+
@Override
226+
public NamespaceContext getNamespaceContext() {
227+
return delegate.getNamespaceContext();
228+
}
229+
230+
@Override
231+
public Object getProperty(String name) {
232+
return delegate.getProperty(name);
233+
}
234+
235+
private void writeIndent() throws XMLStreamException {
236+
delegate.writeCharacters("\n" + indent.repeat(depth));
237+
}
238+
}

toolkit-core/src/main/java/com/techsenger/toolkit/core/xml/StaxWriterHelper.java

Lines changed: 0 additions & 133 deletions
This file was deleted.

0 commit comments

Comments
 (0)