/* * 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() { } }