diff --git a/src/main/java/com/fasterxml/jackson/core/JsonFactory.java b/src/main/java/com/fasterxml/jackson/core/JsonFactory.java index a754660b25..f5355c0659 100644 --- a/src/main/java/com/fasterxml/jackson/core/JsonFactory.java +++ b/src/main/java/com/fasterxml/jackson/core/JsonFactory.java @@ -7,6 +7,8 @@ import java.io.*; import java.lang.ref.SoftReference; import java.net.URL; +import java.util.ArrayList; +import java.util.List; import java.util.Objects; import com.fasterxml.jackson.core.format.InputAccessor; @@ -317,6 +319,9 @@ public static int collectDefaults() { */ protected final char _quoteChar; + /** @since 2.16 */ + protected List _generatorDecorators = new ArrayList<>(); + /* /********************************************************** /* Construction @@ -393,6 +398,7 @@ public JsonFactory(JsonFactoryBuilder b) { _rootValueSeparator = b._rootValueSeparator; _maximumNonEscapedChar = b._maximumNonEscapedChar; _quoteChar = b._quoteChar; + _generatorDecorators = new ArrayList<>(b._generatorDecorators); } /** @@ -1892,7 +1898,14 @@ protected JsonGenerator _createGenerator(Writer out, IOContext ctxt) throws IOEx if (rootSep != DEFAULT_ROOT_VALUE_SEPARATOR) { gen.setRootValueSeparator(rootSep); } - return gen; + return _decorate(gen); + } + + private JsonGenerator _decorate(JsonGenerator result) { + for(JsonGeneratorDecorator decorator : _generatorDecorators) { + result = decorator.decorate(this, result); + } + return result; } /** @@ -1925,7 +1938,7 @@ protected JsonGenerator _createUTF8Generator(OutputStream out, IOContext ctxt) t if (rootSep != DEFAULT_ROOT_VALUE_SEPARATOR) { gen.setRootValueSeparator(rootSep); } - return gen; + return _decorate(gen); } protected Writer _createWriter(OutputStream out, JsonEncoding enc, IOContext ctxt) throws IOException diff --git a/src/main/java/com/fasterxml/jackson/core/JsonGeneratorDecorator.java b/src/main/java/com/fasterxml/jackson/core/JsonGeneratorDecorator.java new file mode 100644 index 0000000000..f17093253d --- /dev/null +++ b/src/main/java/com/fasterxml/jackson/core/JsonGeneratorDecorator.java @@ -0,0 +1,13 @@ +package com.fasterxml.jackson.core; + +public interface JsonGeneratorDecorator { + /** + * Allow to decorate {@link JsonGenerator} instances returned by {@link JsonFactory}. + * + * @since 2.16 + * @param factory The factory which was used to build the original generator + * @param generator The generator to decorate. This might already be a decorated instance, not the original. + * @return decorated generator + */ + JsonGenerator decorate(JsonFactory factory, JsonGenerator generator); +} diff --git a/src/main/java/com/fasterxml/jackson/core/TSFBuilder.java b/src/main/java/com/fasterxml/jackson/core/TSFBuilder.java index 757b627efe..e13a000189 100644 --- a/src/main/java/com/fasterxml/jackson/core/TSFBuilder.java +++ b/src/main/java/com/fasterxml/jackson/core/TSFBuilder.java @@ -1,5 +1,8 @@ package com.fasterxml.jackson.core; +import java.util.ArrayList; +import java.util.List; + import com.fasterxml.jackson.core.io.InputDecorator; import com.fasterxml.jackson.core.io.OutputDecorator; import com.fasterxml.jackson.core.json.JsonReadFeature; @@ -84,6 +87,9 @@ public abstract class TSFBuilder _generatorDecorators = new ArrayList<>(); + /* /********************************************************************** /* Construction @@ -284,6 +290,11 @@ public B streamReadConstraints(StreamReadConstraints streamReadConstraints) { // // // Other methods + public B decorateWith(JsonGeneratorDecorator decorator) { + _generatorDecorators.add(decorator); + return _this(); + } + /** * Method for constructing actual {@link TokenStreamFactory} instance, given * configuration.