diff --git a/release-notes/CREDITS-2.x b/release-notes/CREDITS-2.x index 400c0cec40..a89312826b 100644 --- a/release-notes/CREDITS-2.x +++ b/release-notes/CREDITS-2.x @@ -456,3 +456,8 @@ Jared Stehler (@jaredstehler) Zhanghao (@zhangOranges) * Contributed #1305: Make helper methods of `WriterBasedJsonGenerator` non-final to allow overriding (2.18.0) + +Eduard Gomoliako (@Gems) + * Contributed #1356: Make `JsonGenerator::writeTypePrefix` method to not write a + `WRAPPER_ARRAY` when `typeIdDef.id == null` + (2.19.0) diff --git a/release-notes/VERSION-2.x b/release-notes/VERSION-2.x index ad4b7179f1..d7062e8df2 100644 --- a/release-notes/VERSION-2.x +++ b/release-notes/VERSION-2.x @@ -17,6 +17,9 @@ a pure JSON library. 2.19.0 (not yet released) #1328: Optimize handling of `JsonPointer.head()` +#1356: Make `JsonGenerator::writeTypePrefix` method to not write a + `WRAPPER_ARRAY` when `typeIdDef.id == null` + (contributed by Eduard G) 2.18.1 (28-Oct-2024) diff --git a/src/main/java/com/fasterxml/jackson/core/JsonGenerator.java b/src/main/java/com/fasterxml/jackson/core/JsonGenerator.java index d71ee9aa04..58437fadda 100644 --- a/src/main/java/com/fasterxml/jackson/core/JsonGenerator.java +++ b/src/main/java/com/fasterxml/jackson/core/JsonGenerator.java @@ -1969,39 +1969,47 @@ public void writeTypeId(Object id) throws IOException { */ public WritableTypeId writeTypePrefix(WritableTypeId typeIdDef) throws IOException { - final boolean hasStartObjectWritten = canWriteTypeId() - // just rely on native type output method (sub-classes likely to override) - ? writeTypePrefixWithTypeId(typeIdDef) - // No native type id; write wrappers - : writeTypePrefixWrapper(typeIdDef); + // First: is this a native type id? If so, just use write method, be done + if (canWriteTypeId()) { + // just rely on native type output method (sub-classes likely to override) + return _writeNativeTypePrefix(typeIdDef); + } + + // No native type id; write wrappers + final boolean wasStartObjectWritten = _writeTypePrefixWrapper(typeIdDef); // and finally possible start marker for value itself: switch (typeIdDef.valueShape) { case START_OBJECT: - if (!hasStartObjectWritten) + if (!wasStartObjectWritten) { writeStartObject(typeIdDef.forValue); + } break; case START_ARRAY: // should we now set the current object? writeStartArray(); break; + default: // otherwise: no start marker } return typeIdDef; } - private boolean writeTypePrefixWithTypeId(WritableTypeId typeIdDef) throws IOException { + // @since 2.19 + protected WritableTypeId _writeNativeTypePrefix(WritableTypeId typeIdDef) throws IOException { typeIdDef.wrapperWritten = false; writeTypeId(typeIdDef.id); - - return false; + return typeIdDef; } /** * Writes a wrapper for the type id; if necessary. + * * @return True if start of an object has been written, False otherwise. + * + * @since 2.19 */ - private boolean writeTypePrefixWrapper(WritableTypeId typeIdDef) throws IOException { + protected boolean _writeTypePrefixWrapper(WritableTypeId typeIdDef) throws IOException { // Normally we only support String type ids (non-String reserved for native type ids) final String id = Objects.toString(typeIdDef.id, null); @@ -2017,7 +2025,6 @@ private boolean writeTypePrefixWrapper(WritableTypeId typeIdDef) throws IOExcept typeIdDef.include = incl = WritableTypeId.Inclusion.WRAPPER_ARRAY; } - typeIdDef.wrapperWritten = true; switch (incl) {