001 /*
002 * Java Genetic Algorithm Library (jenetics-7.0.0).
003 * Copyright (c) 2007-2022 Franz Wilhelmstötter
004 *
005 * Licensed under the Apache License, Version 2.0 (the "License");
006 * you may not use this file except in compliance with the License.
007 * You may obtain a copy of the License at
008 *
009 * http://www.apache.org/licenses/LICENSE-2.0
010 *
011 * Unless required by applicable law or agreed to in writing, software
012 * distributed under the License is distributed on an "AS IS" BASIS,
013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014 * See the License for the specific language governing permissions and
015 * limitations under the License.
016 *
017 * Author:
018 * Franz Wilhelmstötter (franz.wilhelmstoetter@gmail.com)
019 */
020 package io.jenetics.xml.stream;
021
022 import java.util.Deque;
023 import java.util.LinkedList;
024
025 import javax.xml.stream.XMLStreamException;
026 import javax.xml.stream.XMLStreamWriter;
027
028 /**
029 * {@link XMLStreamWriter} proxy for writing XML indentations.
030 *
031 * @author <a href="mailto:franz.wilhelmstoetter@gmail.com">Franz Wilhelmstötter</a>
032 * @version 3.9
033 * @since 3.9
034 */
035 final class IndentingXMLWriter extends XMLWriterProxy {
036
037 private enum State {
038 SEEN_NOTHING,
039 SEEN_ELEMENT,
040 SEEN_DATA
041 }
042
043 private static final String NEW_LINE = System.lineSeparator();
044
045 private final String _indent;
046
047 private State _state;
048 private final Deque<State> _states = new LinkedList<>();
049 private int _depth;
050
051 IndentingXMLWriter(final XMLStreamWriter writer, final String indent) {
052 super(writer);
053 _state = State.SEEN_NOTHING;
054 _indent = indent;
055 _depth = 0;
056 }
057
058 private void onStartElement() throws XMLStreamException {
059 _states.push(State.SEEN_ELEMENT);
060 _state = State.SEEN_NOTHING;
061 if (_depth > 0) {
062 super.writeCharacters(NEW_LINE);
063 }
064
065 doIndent();
066 ++_depth;
067 }
068
069 private void onEndElement() throws XMLStreamException {
070 --_depth;
071 if (_state == State.SEEN_ELEMENT) {
072 super.writeCharacters(NEW_LINE);
073 doIndent();
074 }
075
076 _state = _states.pop();
077 }
078
079 private void onEmptyElement() throws XMLStreamException {
080 _state = State.SEEN_ELEMENT;
081 if(_depth > 0) {
082 super.writeCharacters(NEW_LINE);
083 }
084
085 doIndent();
086 }
087
088 private void doIndent() throws XMLStreamException {
089 if (_depth > 0) {
090 for(int i = 0; i < _depth; ++i) {
091 super.writeCharacters(_indent);
092 }
093 }
094
095 }
096
097 @Override
098 public void writeStartDocument() throws XMLStreamException {
099 super.writeStartDocument();
100 super.writeCharacters(NEW_LINE);
101 }
102
103 @Override
104 public void writeStartDocument(final String version)
105 throws XMLStreamException
106 {
107 super.writeStartDocument(version);
108 super.writeCharacters(NEW_LINE);
109 }
110
111 @Override
112 public void writeStartDocument(final String encoding, final String version)
113 throws XMLStreamException
114 {
115 super.writeStartDocument(encoding, version);
116 super.writeCharacters(NEW_LINE);
117 }
118
119 @Override
120 public void writeStartElement(final String localName)
121 throws XMLStreamException
122 {
123 onStartElement();
124 super.writeStartElement(localName);
125 }
126
127 @Override
128 public void writeStartElement(
129 final String namespaceURI,
130 final String localName
131 )
132 throws XMLStreamException
133 {
134 onStartElement();
135 super.writeStartElement(namespaceURI, localName);
136 }
137
138 @Override
139 public void writeStartElement(
140 final String prefix,
141 final String localName,
142 final String namespaceURI
143 )
144 throws XMLStreamException
145 {
146 onStartElement();
147 super.writeStartElement(prefix, localName, namespaceURI);
148 }
149
150 @Override
151 public void writeEmptyElement(
152 final String namespaceURI,
153 final String localName
154 )
155 throws XMLStreamException
156 {
157 onEmptyElement();
158 super.writeEmptyElement(namespaceURI, localName);
159 }
160
161 @Override
162 public void writeEmptyElement(
163 final String prefix,
164 final String localName,
165 final String namespaceURI
166 )
167 throws XMLStreamException
168 {
169 onEmptyElement();
170 super.writeEmptyElement(prefix, localName, namespaceURI);
171 }
172
173 @Override
174 public void writeEmptyElement(final String localName)
175 throws XMLStreamException
176 {
177 onEmptyElement();
178 super.writeEmptyElement(localName);
179 }
180
181 @Override
182 public void writeEndElement() throws XMLStreamException {
183 onEndElement();
184 super.writeEndElement();
185 }
186
187 @Override
188 public void writeCharacters(final String text) throws XMLStreamException {
189 _state = State.SEEN_DATA;
190 super.writeCharacters(text);
191 }
192
193 @Override
194 public void writeCharacters(
195 final char[] text,
196 final int start,
197 final int len
198 )
199 throws XMLStreamException
200 {
201 _state = State.SEEN_DATA;
202 super.writeCharacters(text, start, len);
203 }
204
205 @Override
206 public void writeCData(final String data) throws XMLStreamException {
207 _state = State.SEEN_DATA;
208 super.writeCData(data);
209 }
210 }
|