diff --git a/src/main/java/com/fasterxml/jackson/core/Separators.java b/src/main/java/com/fasterxml/jackson/core/Separators.java new file mode 100644 index 0000000000..c0ad6a938e --- /dev/null +++ b/src/main/java/com/fasterxml/jackson/core/Separators.java @@ -0,0 +1,43 @@ +package com.fasterxml.jackson.core; + +import java.io.Serializable; + +public class Separators implements Serializable { + + private static final long serialVersionUID = 1; + + private char objectFieldValueSeparator = ':'; + private char objectEntrySeparator = ','; + private char arrayValueSeparator = ','; + + public static Separators createDefaultInstance() { + return new Separators(); + } + + public Separators withObjectFieldValueSeparator(char objectFieldValueSeparator) { + this.objectFieldValueSeparator = objectFieldValueSeparator; + return this; + } + + public Separators withObjectEntrySeparator(char objectEntrySeparator) { + this.objectEntrySeparator = objectEntrySeparator; + return this; + } + + public Separators withArrayValueSeparator(char arrayValueSeparator) { + this.arrayValueSeparator = arrayValueSeparator; + return this; + } + + public char getObjectFieldValueSeparator() { + return objectFieldValueSeparator; + } + + public char getObjectEntrySeparator() { + return objectEntrySeparator; + } + + public char getArrayValueSeparator() { + return arrayValueSeparator; + } +} diff --git a/src/main/java/com/fasterxml/jackson/core/util/DefaultPrettyPrinter.java b/src/main/java/com/fasterxml/jackson/core/util/DefaultPrettyPrinter.java index e80159d034..846790f61c 100644 --- a/src/main/java/com/fasterxml/jackson/core/util/DefaultPrettyPrinter.java +++ b/src/main/java/com/fasterxml/jackson/core/util/DefaultPrettyPrinter.java @@ -26,7 +26,7 @@ public class DefaultPrettyPrinter * @since 2.1 */ public final static SerializedString DEFAULT_ROOT_VALUE_SEPARATOR = new SerializedString(" "); - + /** * Interface that defines objects that can produce indentation used * to separate object entries and array values. Indentation in this @@ -43,7 +43,7 @@ public interface Indenter */ boolean isInline(); } - + // // // Config, indentation /** @@ -63,7 +63,7 @@ public interface Indenter * String printed between root-level values, if any. */ protected final SerializableString _rootSeparator; - + // // // Config, other white space configuration /** @@ -81,6 +81,10 @@ public interface Indenter */ protected transient int _nesting; + protected Separators _separators = Separators.createDefaultInstance(); + + private String _objectFieldValueSeparatorWithSpaces = " " + _separators.getObjectFieldValueSeparator() + " "; + /* /********************************************************** /* Life-cycle (construct, configure) @@ -129,6 +133,8 @@ public DefaultPrettyPrinter(DefaultPrettyPrinter base, _objectIndenter = base._objectIndenter; _spacesInObjectEntries = base._spacesInObjectEntries; _nesting = base._nesting; + _separators = base._separators; + _objectFieldValueSeparatorWithSpaces = " " + base._separators.getObjectFieldValueSeparator() + " "; _rootSeparator = rootSeparator; } @@ -148,7 +154,7 @@ public DefaultPrettyPrinter withRootSeparator(SerializableString rootSeparator) public DefaultPrettyPrinter withRootSeparator(String rootSeparator) { return withRootSeparator((rootSeparator == null) ? null : new SerializedString(rootSeparator)); } - + public void indentArraysWith(Indenter i) { _arrayIndenter = (i == null) ? NopIndenter.instance : i; } @@ -210,7 +216,7 @@ public DefaultPrettyPrinter withSpacesInObjectEntries() { * that does not use spaces inside object entries; if 'this' instance already * does this, it is returned; if not, a new instance will be constructed * and returned. - * + * * @since 2.3 */ public DefaultPrettyPrinter withoutSpacesInObjectEntries() { @@ -226,13 +232,19 @@ protected DefaultPrettyPrinter _withSpaces(boolean state) pp._spacesInObjectEntries = state; return pp; } - + + public DefaultPrettyPrinter withCustomSeparators(Separators separators) { + this._separators = separators; + this._objectFieldValueSeparatorWithSpaces = " " + separators.getObjectFieldValueSeparator() + " "; + return this; + } + /* /********************************************************** /* Instantiatable impl /********************************************************** */ - + @Override public DefaultPrettyPrinter createInstance() { return new DefaultPrettyPrinter(this); @@ -280,9 +292,9 @@ public void beforeObjectEntries(JsonGenerator g) throws IOException public void writeObjectFieldValueSeparator(JsonGenerator g) throws IOException { if (_spacesInObjectEntries) { - g.writeRaw(" : "); + g.writeRaw(_objectFieldValueSeparatorWithSpaces); } else { - g.writeRaw(':'); + g.writeRaw(_separators.getObjectFieldValueSeparator()); } } @@ -298,7 +310,7 @@ public void writeObjectFieldValueSeparator(JsonGenerator g) throws IOException @Override public void writeObjectEntrySeparator(JsonGenerator g) throws IOException { - g.writeRaw(','); + g.writeRaw(_separators.getObjectEntrySeparator()); _objectIndenter.writeIndentation(g, _nesting); } @@ -340,24 +352,24 @@ public void beforeArrayValues(JsonGenerator g) throws IOException { * (white-space) decoration. */ @Override - public void writeArrayValueSeparator(JsonGenerator gen) throws IOException + public void writeArrayValueSeparator(JsonGenerator g) throws IOException { - gen.writeRaw(','); - _arrayIndenter.writeIndentation(gen, _nesting); + g.writeRaw(_separators.getArrayValueSeparator()); + _arrayIndenter.writeIndentation(g, _nesting); } @Override - public void writeEndArray(JsonGenerator gen, int nrOfValues) throws IOException + public void writeEndArray(JsonGenerator g, int nrOfValues) throws IOException { if (!_arrayIndenter.isInline()) { --_nesting; } if (nrOfValues > 0) { - _arrayIndenter.writeIndentation(gen, _nesting); + _arrayIndenter.writeIndentation(g, _nesting); } else { - gen.writeRaw(' '); + g.writeRaw(' '); } - gen.writeRaw(']'); + g.writeRaw(']'); } /* diff --git a/src/main/java/com/fasterxml/jackson/core/util/MinimalPrettyPrinter.java b/src/main/java/com/fasterxml/jackson/core/util/MinimalPrettyPrinter.java index 92b7dc2265..bf0ca20dc8 100644 --- a/src/main/java/com/fasterxml/jackson/core/util/MinimalPrettyPrinter.java +++ b/src/main/java/com/fasterxml/jackson/core/util/MinimalPrettyPrinter.java @@ -4,6 +4,7 @@ import com.fasterxml.jackson.core.JsonGenerator; import com.fasterxml.jackson.core.PrettyPrinter; +import com.fasterxml.jackson.core.Separators; /** * {@link PrettyPrinter} implementation that adds no indentation, @@ -34,6 +35,8 @@ public class MinimalPrettyPrinter protected String _rootValueSeparator = DEFAULT_ROOT_VALUE_SEPARATOR; + protected Separators _separators = Separators.createDefaultInstance(); + /* /********************************************************** /* Life-cycle, construction, configuration @@ -47,7 +50,10 @@ public MinimalPrettyPrinter() { public MinimalPrettyPrinter(String rootValueSeparator) { _rootValueSeparator = rootValueSeparator; } - + public MinimalPrettyPrinter withCustomSeparators(Separators separators) { + this._separators = separators; + return this; + } public void setRootValueSeparator(String sep) { _rootValueSeparator = sep; } @@ -62,7 +68,7 @@ public void setRootValueSeparator(String sep) { public void writeRootValueSeparator(JsonGenerator g) throws IOException { if (_rootValueSeparator != null) { - g.writeRaw(_rootValueSeparator); + g.writeRaw(_rootValueSeparator); } } @@ -88,7 +94,7 @@ public void beforeObjectEntries(JsonGenerator g) throws IOException @Override public void writeObjectFieldValueSeparator(JsonGenerator g) throws IOException { - g.writeRaw(':'); + g.writeRaw(_separators.getObjectFieldValueSeparator()); } /** @@ -101,7 +107,7 @@ public void writeObjectFieldValueSeparator(JsonGenerator g) throws IOException @Override public void writeObjectEntrySeparator(JsonGenerator g) throws IOException { - g.writeRaw(','); + g.writeRaw(_separators.getObjectEntrySeparator()); } @Override @@ -132,7 +138,7 @@ public void beforeArrayValues(JsonGenerator g) throws IOException @Override public void writeArrayValueSeparator(JsonGenerator g) throws IOException { - g.writeRaw(','); + g.writeRaw(_separators.getArrayValueSeparator()); } @Override diff --git a/src/test/java/com/fasterxml/jackson/core/main/TestPrettyPrinter.java b/src/test/java/com/fasterxml/jackson/core/main/TestPrettyPrinter.java index c31d0d51f6..fcdd39bceb 100644 --- a/src/test/java/com/fasterxml/jackson/core/main/TestPrettyPrinter.java +++ b/src/test/java/com/fasterxml/jackson/core/main/TestPrettyPrinter.java @@ -1,6 +1,7 @@ package com.fasterxml.jackson.core.main; import com.fasterxml.jackson.core.*; +import com.fasterxml.jackson.core.util.DefaultIndenter; import com.fasterxml.jackson.core.util.DefaultPrettyPrinter; import com.fasterxml.jackson.core.util.MinimalPrettyPrinter; @@ -153,7 +154,56 @@ public void testCustomRootSeparatorWithFactory() throws Exception gen.close(); assertEquals("13##false##null", sw.toString()); } - + + public void testCustomSeparatorsWithMinimal() throws Exception + { + StringWriter sw = new StringWriter(); + JsonGenerator gen = new JsonFactory().createGenerator(sw); + gen.setPrettyPrinter(new MinimalPrettyPrinter().withCustomSeparators(Separators.createDefaultInstance() + .withObjectFieldValueSeparator('=') + .withObjectEntrySeparator(';') + .withArrayValueSeparator('|'))); + + _writeTestDocument(gen); + + assertEquals("[3|\"abc\"|[true]|{\"f\"=null;\"f2\"=null}]", sw.toString()); + } + + public void testCustomSeparatorsWithPP() throws Exception + { + StringWriter sw = new StringWriter(); + JsonGenerator gen = new JsonFactory().createGenerator(sw); + gen.setPrettyPrinter(new DefaultPrettyPrinter().withCustomSeparators(Separators.createDefaultInstance() + .withObjectFieldValueSeparator('=') + .withObjectEntrySeparator(';') + .withArrayValueSeparator('|'))); + + _writeTestDocument(gen); + + assertEquals("[ 3| \"abc\"| [ true ]| {" + DefaultIndenter.SYS_LF + + " \"f\" = null;" + DefaultIndenter.SYS_LF + + " \"f2\" = null" + DefaultIndenter.SYS_LF + + "} ]", sw.toString()); + } + + public void testCustomSeparatorsWithPPWithoutSpaces() throws Exception + { + StringWriter sw = new StringWriter(); + JsonGenerator gen = new JsonFactory().createGenerator(sw); + gen.setPrettyPrinter(new DefaultPrettyPrinter().withCustomSeparators(Separators.createDefaultInstance() + .withObjectFieldValueSeparator('=') + .withObjectEntrySeparator(';') + .withArrayValueSeparator('|')) + .withoutSpacesInObjectEntries()); + + _writeTestDocument(gen); + + assertEquals("[ 3| \"abc\"| [ true ]| {" + DefaultIndenter.SYS_LF + + " \"f\"=null;" + DefaultIndenter.SYS_LF + + " \"f2\"=null" + DefaultIndenter.SYS_LF + + "} ]", sw.toString()); + } + /* /********************************************************** /* Helper methods @@ -161,24 +211,8 @@ public void testCustomRootSeparatorWithFactory() throws Exception */ private String _verifyPrettyPrinter(JsonGenerator gen, StringWriter sw) throws Exception - { - gen.writeStartArray(); - gen.writeNumber(3); - gen.writeString("abc"); - - gen.writeStartArray(); - gen.writeBoolean(true); - gen.writeEndArray(); - - gen.writeStartObject(); - gen.writeFieldName("f"); - gen.writeNull(); - gen.writeFieldName("f2"); - gen.writeNull(); - gen.writeEndObject(); - - gen.writeEndArray(); - gen.close(); + { + _writeTestDocument(gen); String docStr = sw.toString(); JsonParser jp = createParserUsingReader(docStr); @@ -210,6 +244,26 @@ private String _verifyPrettyPrinter(JsonGenerator gen, StringWriter sw) throws E return docStr; } + private void _writeTestDocument(JsonGenerator gen) throws IOException { + gen.writeStartArray(); + gen.writeNumber(3); + gen.writeString("abc"); + + gen.writeStartArray(); + gen.writeBoolean(true); + gen.writeEndArray(); + + gen.writeStartObject(); + gen.writeFieldName("f"); + gen.writeNull(); + gen.writeFieldName("f2"); + gen.writeNull(); + gen.writeEndObject(); + + gen.writeEndArray(); + gen.close(); + } + protected String _generateRoot(JsonFactory jf, PrettyPrinter pp) throws IOException { StringWriter sw = new StringWriter();