package com.fasterxml.jackson.dataformat.xml.util;
import java.io.IOException;
import java.math.BigDecimal;
import java.math.BigInteger;
import java.util.Arrays;
import javax.xml.stream.XMLStreamException;
import org.codehaus.stax2.XMLStreamWriter2;
import com.fasterxml.jackson.core.*;
import com.fasterxml.jackson.core.util.Instantiatable;
import com.fasterxml.jackson.dataformat.xml.XmlPrettyPrinter;
import com.fasterxml.jackson.dataformat.xml.ser.ToXmlGenerator;
public class DefaultXmlPrettyPrinter
implements XmlPrettyPrinter, Instantiatable<DefaultXmlPrettyPrinter>,
java.io.Serializable
{
private static final long serialVersionUID = 1L;
public interface Indenter
{
public void writeIndentation(JsonGenerator g, int level) throws IOException;
public void writeIndentation(XMLStreamWriter2 sw, int level) throws XMLStreamException;
public boolean isInline();
}
protected Indenter _arrayIndenter = new FixedSpaceIndenter();
protected Indenter _objectIndenter = new Lf2SpacesIndenter();
protected boolean _spacesInObjectEntries = true;
protected transient int _nesting = 0;
protected transient boolean _justHadStartElement;
public DefaultXmlPrettyPrinter() { }
protected DefaultXmlPrettyPrinter(DefaultXmlPrettyPrinter base)
{
_arrayIndenter = base._arrayIndenter;
_objectIndenter = base._objectIndenter;
_spacesInObjectEntries = base._spacesInObjectEntries;
_nesting = base._nesting;
}
public void indentArraysWith(Indenter i)
{
_arrayIndenter = (i == null) ? new NopIndenter() : i;
}
public void indentObjectsWith(Indenter i)
{
_objectIndenter = (i == null) ? new NopIndenter() : i;
}
public void spacesInObjectEntries(boolean b) { _spacesInObjectEntries = b; }
@Override
public DefaultXmlPrettyPrinter createInstance() {
return new DefaultXmlPrettyPrinter(this);
}
@Override
public void writeRootValueSeparator(JsonGenerator gen) throws IOException {
gen.writeRaw('\n');
}
@Override
public void beforeArrayValues(JsonGenerator gen) throws IOException {
}
@Override
public void writeStartArray(JsonGenerator gen) throws IOException {
}
@Override
public void writeArrayValueSeparator(JsonGenerator gen) throws IOException {
}
@Override
public void writeEndArray(JsonGenerator gen, int nrOfValues) throws IOException {
}
@Override
public void beforeObjectEntries(JsonGenerator gen)
throws IOException, JsonGenerationException
{
}
@Override
public void writeStartObject(JsonGenerator gen) throws IOException
{
if (!_objectIndenter.isInline()) {
if (_nesting > 0) {
_objectIndenter.writeIndentation(gen, _nesting);
}
++_nesting;
}
_justHadStartElement = true;
((ToXmlGenerator) gen)._handleStartObject();
}
@Override
public void writeObjectEntrySeparator(JsonGenerator gen) throws IOException {
}
@Override
public void writeObjectFieldValueSeparator(JsonGenerator gen) throws IOException {
}
@Override
public void writeEndObject(JsonGenerator gen, int nrOfEntries) throws IOException
{
if (!_objectIndenter.isInline()) {
--_nesting;
}
if (_justHadStartElement) {
_justHadStartElement = false;
} else {
_objectIndenter.writeIndentation(gen, _nesting);
}
((ToXmlGenerator) gen)._handleEndObject();
}
@Override
public void writeStartElement(XMLStreamWriter2 sw,
String nsURI, String localName) throws XMLStreamException
{
if (!_objectIndenter.isInline()) {
if (_justHadStartElement) {
_justHadStartElement = false;
}
_objectIndenter.writeIndentation(sw, _nesting);
++_nesting;
}
sw.writeStartElement(nsURI, localName);
_justHadStartElement = true;
}
@Override
public void writeEndElement(XMLStreamWriter2 sw, int nrOfEntries) throws XMLStreamException
{
if (!_objectIndenter.isInline()) {
--_nesting;
}
if (_justHadStartElement) {
_justHadStartElement = false;
} else {
_objectIndenter.writeIndentation(sw, _nesting);
}
sw.writeEndElement();
}
@Override
public void writeLeafElement(XMLStreamWriter2 sw,
String nsURI, String localName, String text, boolean isCData)
throws XMLStreamException
{
if (!_objectIndenter.isInline()) {
_objectIndenter.writeIndentation(sw, _nesting);
}
sw.writeStartElement(nsURI, localName);
if(isCData) {
sw.writeCData(text);
} else {
sw.writeCharacters(text);
}
sw.writeEndElement();
_justHadStartElement = false;
}
@Override
public void writeLeafElement(XMLStreamWriter2 sw,
String nsURI, String localName,
char[] buffer, int offset, int len, boolean isCData)
throws XMLStreamException
{
if (!_objectIndenter.isInline()) {
_objectIndenter.writeIndentation(sw, _nesting);
}
sw.writeStartElement(nsURI, localName);
if(isCData) {
sw.writeCData(buffer, offset, len);
} else {
sw.writeCharacters(buffer, offset, len);
}
sw.writeEndElement();
_justHadStartElement = false;
}
@Override
public void writeLeafElement(XMLStreamWriter2 sw,
String nsURI, String localName, boolean value)
throws XMLStreamException
{
if (!_objectIndenter.isInline()) {
_objectIndenter.writeIndentation(sw, _nesting);
}
sw.writeStartElement(nsURI, localName);
sw.writeBoolean(value);
sw.writeEndElement();
_justHadStartElement = false;
}
@Override
public void writeLeafElement(XMLStreamWriter2 sw,
String nsURI, String localName, int value)
throws XMLStreamException
{
if (!_objectIndenter.isInline()) {
_objectIndenter.writeIndentation(sw, _nesting);
}
sw.writeStartElement(nsURI, localName);
sw.writeInt(value);
sw.writeEndElement();
_justHadStartElement = false;
}
@Override
public void writeLeafElement(XMLStreamWriter2 sw,
String nsURI, String localName, long value)
throws XMLStreamException
{
if (!_objectIndenter.isInline()) {
_objectIndenter.writeIndentation(sw, _nesting);
}
sw.writeStartElement(nsURI, localName);
sw.writeLong(value);
sw.writeEndElement();
_justHadStartElement = false;
}
@Override
public void writeLeafElement(XMLStreamWriter2 sw,
String nsURI, String localName, double value)
throws XMLStreamException
{
if (!_objectIndenter.isInline()) {
_objectIndenter.writeIndentation(sw, _nesting);
}
sw.writeStartElement(nsURI, localName);
sw.writeDouble(value);
sw.writeEndElement();
_justHadStartElement = false;
}
@Override
public void writeLeafElement(XMLStreamWriter2 sw,
String nsURI, String localName, float value)
throws XMLStreamException
{
if (!_objectIndenter.isInline()) {
_objectIndenter.writeIndentation(sw, _nesting);
}
sw.writeStartElement(nsURI, localName);
sw.writeFloat(value);
sw.writeEndElement();
_justHadStartElement = false;
}
@Override
public void writeLeafElement(XMLStreamWriter2 sw,
String nsURI, String localName, BigInteger value)
throws XMLStreamException
{
if (!_objectIndenter.isInline()) {
_objectIndenter.writeIndentation(sw, _nesting);
}
sw.writeStartElement(nsURI, localName);
sw.writeInteger(value);
sw.writeEndElement();
_justHadStartElement = false;
}
@Override
public void writeLeafElement(XMLStreamWriter2 sw,
String nsURI, String localName, BigDecimal value)
throws XMLStreamException
{
if (!_objectIndenter.isInline()) {
_objectIndenter.writeIndentation(sw, _nesting);
}
sw.writeStartElement(nsURI, localName);
sw.writeDecimal(value);
sw.writeEndElement();
_justHadStartElement = false;
}
@Override
public void writeLeafElement(XMLStreamWriter2 sw,
String nsURI, String localName,
byte[] data, int offset, int len)
throws XMLStreamException
{
if (!_objectIndenter.isInline()) {
_objectIndenter.writeIndentation(sw, _nesting);
}
sw.writeStartElement(nsURI, localName);
sw.writeBinary(data, offset, len);
sw.writeEndElement();
_justHadStartElement = false;
}
@Override
public void writeLeafNullElement(XMLStreamWriter2 sw,
String nsURI, String localName)
throws XMLStreamException
{
if (!_objectIndenter.isInline()) {
_objectIndenter.writeIndentation(sw, _nesting);
}
sw.writeEmptyElement(nsURI, localName);
_justHadStartElement = false;
}
@Override
public void writePrologLinefeed(XMLStreamWriter2 sw) throws XMLStreamException
{
sw.writeRaw(Lf2SpacesIndenter.SYSTEM_LINE_SEPARATOR);
}
protected static class NopIndenter
implements Indenter, java.io.Serializable
{
private static final long serialVersionUID = 1L;
public NopIndenter() { }
@Override public void writeIndentation(JsonGenerator jg, int level) { }
@Override public boolean isInline() { return true; }
@Override public void writeIndentation(XMLStreamWriter2 sw, int level) { }
}
protected static class FixedSpaceIndenter
implements Indenter, java.io.Serializable
{
private static final long serialVersionUID = 1L;
public FixedSpaceIndenter() { }
@Override
public void writeIndentation(XMLStreamWriter2 sw, int level)
throws XMLStreamException
{
sw.writeRaw(" ");
}
@Override
public void writeIndentation(JsonGenerator g, int level) throws IOException
{
g.writeRaw(' ');
}
@Override
public boolean isInline() { return true; }
}
protected static class Lf2SpacesIndenter
implements Indenter, java.io.Serializable
{
private static final long serialVersionUID = 1L;
final static String SYSTEM_LINE_SEPARATOR;
static {
String lf = null;
try {
lf = System.getProperty("line.separator");
} catch (Throwable t) { }
SYSTEM_LINE_SEPARATOR = (lf == null) ? "\n" : lf;
}
final static int SPACE_COUNT = 64;
final static char[] SPACES = new char[SPACE_COUNT];
static {
Arrays.fill(SPACES, ' ');
}
public Lf2SpacesIndenter() { }
@Override
public boolean isInline() { return false; }
@Override
public void writeIndentation(XMLStreamWriter2 sw, int level) throws XMLStreamException
{
sw.writeRaw(SYSTEM_LINE_SEPARATOR);
level += level;
while (level > SPACE_COUNT) {
sw.writeRaw(SPACES, 0, SPACE_COUNT);
level -= SPACES.length;
}
sw.writeRaw(SPACES, 0, level);
}
@Override
public void writeIndentation(JsonGenerator jg, int level) throws IOException
{
jg.writeRaw(SYSTEM_LINE_SEPARATOR);
level += level;
while (level > SPACE_COUNT) {
jg.writeRaw(SPACES, 0, SPACE_COUNT);
level -= SPACES.length;
}
jg.writeRaw(SPACES, 0, level);
}
}
}