/*
* Copyright 2011, 2012 Odysseus Software GmbH
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.synapse.commons.staxon.core.xml.util;
import javax.xml.stream.XMLEventFactory;
import javax.xml.stream.XMLEventWriter;
import javax.xml.stream.XMLStreamException;
import javax.xml.stream.XMLStreamWriter;
import javax.xml.stream.events.Characters;
import org.apache.synapse.commons.staxon.core.event.SimpleXMLEventFactory;
/**
* Package-private helper used by {@link PrettyXMLStreamWriter} and {@link PrettyXMLEventWriter}
* to handle pretty printing state and insert indentation and newline characters events.
*/
class PrettyXMLWhitespaceHandler {
static final XMLEventFactory EVENT_FACTORY = new SimpleXMLEventFactory();
/**
* Whitespace writer.
*/
private static abstract class WhitespaceWriter {
abstract void add(Characters event) throws XMLStreamException;
}
private static final int MAX_DEPTH = 64;
private final Characters newline;
private final Characters[] indent;
private final WhitespaceWriter writer;
private int depth = 0;
private boolean text = false;
private boolean leaf = false;
/**
* Create whitespace handler for an {@link XMLStreamWriter}.
*
* @param writer stream writer
* @param indentation line indentation
* @param newline line separator
*/
PrettyXMLWhitespaceHandler(final XMLStreamWriter writer, String indentation, String newline) {
this(indentation, newline, new WhitespaceWriter() {
@Override
public void add(Characters event) throws XMLStreamException {
writer.writeCharacters(event.getData());
}
});
}
/**
* Create whitespace handler for an {@link XMLEventWriter}.
*
* @param writer event writer
* @param indentation line indentation
* @param newline line separator
*/
PrettyXMLWhitespaceHandler(final XMLEventWriter writer, String indentation, String newline) {
this(indentation, newline, new WhitespaceWriter() {
@Override
public void add(Characters event) throws XMLStreamException {
writer.add(event);
}
});
}
private PrettyXMLWhitespaceHandler(String indentation, String newline, WhitespaceWriter writer) {
this.newline = EVENT_FACTORY.createSpace(newline);
this.indent = new Characters[MAX_DEPTH];
this.writer = writer;
/*
* initialize indentation whitespace events
*/
StringBuilder builder = new StringBuilder();
for (int i = 0; i < indent.length; i++) {
indent[i] = EVENT_FACTORY.createSpace(builder.toString());
builder.append(indentation);
}
}
private void preStructure() throws XMLStreamException {
if (text) {
text = false;
} else if (depth > 0) {
writer.add(newline);
writer.add(indent[depth]);
}
}
private void postComment_PI() throws XMLStreamException {
leaf = false;
if (depth == 0) {
writer.add(newline);
}
}
void preStartDocument() throws XMLStreamException {
preStructure();
}
void postStartDocument() throws XMLStreamException {
postComment_PI();
}
void preComment() throws XMLStreamException {
preStructure();
}
void postComment() throws XMLStreamException {
postComment_PI();
}
void preProcessingInstruction() throws XMLStreamException {
preStructure();
}
void postProcessingInstruction() throws XMLStreamException {
postComment_PI();
}
void preStartElement() throws XMLStreamException {
preStructure();
}
void postStartElement() throws XMLStreamException {
depth++;
leaf = true;
}
void preEndElement() throws XMLStreamException {
depth--;
if (text) {
text = false;
} else if (!leaf) {
writer.add(newline);
if (depth > 0) {
writer.add(indent[depth]);
}
}
}
void postEndElement() throws XMLStreamException {
leaf = false;
if (depth == 0) {
writer.add(newline);
}
}
void preEmptyELement() throws XMLStreamException {
preStructure();
}
void postEmptyELement() throws XMLStreamException {
leaf = false;
}
void preCharacters() {
text = true;
}
void postCharacters() {
}
}