Skip to content

Commit 625398d

Browse files
Allow disabling native type ids when deserializing for #270 (#271)
1 parent 112ae75 commit 625398d

File tree

3 files changed

+98
-10
lines changed

3 files changed

+98
-10
lines changed

ion/src/main/java/com/fasterxml/jackson/dataformat/ion/IonFactory.java

+7-7
Original file line numberDiff line numberDiff line change
@@ -291,15 +291,15 @@ public int getFormatGeneratorFeatures() {
291291
* @since 2.7
292292
*/
293293
public IonParser createParser(IonReader in) {
294-
return new IonParser(in, _system, _createContext(in, false), getCodec());
294+
return new IonParser(in, _system, _createContext(in, false), getCodec(), _ionParserFeatures);
295295
}
296296

297297
/**
298298
* @since 2.7
299299
*/
300300
public IonParser createParser(IonValue value) {
301301
IonReader in = value.getSystem().newReader(value);
302-
return new IonParser(in, _system, _createContext(in, true), getCodec());
302+
return new IonParser(in, _system, _createContext(in, true), getCodec(), _ionParserFeatures);
303303
}
304304

305305
// NOTE! Suboptimal return type -- but can't change safely before 3.0 as return
@@ -324,7 +324,7 @@ public IonSystem getIonSystem() {
324324
*/
325325
@Deprecated
326326
public IonParser createJsonParser(IonReader in) {
327-
return new IonParser(in, _system, _createContext(in, false), getCodec());
327+
return new IonParser(in, _system, _createContext(in, false), getCodec(), _ionParserFeatures);
328328
}
329329

330330
/**
@@ -333,7 +333,7 @@ public IonParser createJsonParser(IonReader in) {
333333
@Deprecated
334334
public IonParser createJsonParser(IonValue value) {
335335
IonReader in = value.getSystem().newReader(value);
336-
return new IonParser(in, _system, _createContext(in, true), getCodec());
336+
return new IonParser(in, _system, _createContext(in, true), getCodec(), _ionParserFeatures);
337337
}
338338

339339
/**
@@ -355,14 +355,14 @@ protected JsonParser _createParser(InputStream in, IOContext ctxt)
355355
throws IOException
356356
{
357357
IonReader ion = _system.newReader(in);
358-
return new IonParser(ion, _system, ctxt, getCodec());
358+
return new IonParser(ion, _system, ctxt, getCodec(), _ionParserFeatures);
359359
}
360360

361361
@Override
362362
protected JsonParser _createParser(Reader r, IOContext ctxt)
363363
throws IOException
364364
{
365-
return new IonParser(_system.newReader(r), _system, ctxt, getCodec());
365+
return new IonParser(_system.newReader(r), _system, ctxt, getCodec(), _ionParserFeatures);
366366
}
367367

368368
@Override
@@ -376,7 +376,7 @@ protected JsonParser _createParser(char[] data, int offset, int len, IOContext c
376376
protected JsonParser _createParser(byte[] data, int offset, int len, IOContext ctxt)
377377
throws IOException
378378
{
379-
return new IonParser(_system.newReader(data, offset, len), _system, ctxt, getCodec());
379+
return new IonParser(_system.newReader(data, offset, len), _system, ctxt, getCodec(), _ionParserFeatures);
380380
}
381381

382382
@Override

ion/src/main/java/com/fasterxml/jackson/dataformat/ion/IonParser.java

+25-3
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,18 @@ public class IonParser
4040
*/
4141
public enum Feature implements FormatFeature // in 2.12
4242
{
43+
/**
44+
* Whether to expect Ion native Type Id construct for indicating type (true);
45+
* or "generic" type property (false) when deserializing.
46+
*<p>
47+
* Enabled by default for backwards compatibility as that has been the behavior
48+
* of `jackson-dataformat-ion` since 2.9 (first official public version)
49+
*
50+
* @see <a href="https://amzn.github.io/ion-docs/docs/spec.html#annot">The Ion Specification</a>
51+
*
52+
* @since 2.12.3
53+
*/
54+
USE_NATIVE_TYPE_ID(true),
4355
;
4456

4557
final boolean _defaultState;
@@ -113,6 +125,13 @@ private Feature(boolean defaultState) {
113125
*/
114126
protected JsonToken _valueToken;
115127

128+
/**
129+
* Bit flag composed of bits that indicate which
130+
* {@link IonParser.Feature}s
131+
* are enabled.
132+
*/
133+
protected int _formatFeatures;
134+
116135
/*
117136
/*****************************************************************
118137
/* Construction
@@ -133,15 +152,16 @@ public IonParser(IonReader r, IOContext ctxt)
133152
*/
134153
@Deprecated
135154
public IonParser(IonReader r, IOContext ctxt, ObjectCodec codec) {
136-
this(r, IonSystemBuilder.standard().build(), ctxt, codec);
155+
this(r, IonSystemBuilder.standard().build(), ctxt, codec, IonFactory.DEFAULT_ION_PARSER_FEATURE_FLAGS);
137156
}
138157

139-
IonParser(IonReader r, IonSystem system, IOContext ctxt, ObjectCodec codec) {
158+
IonParser(IonReader r, IonSystem system, IOContext ctxt, ObjectCodec codec, int ionParserFeatures) {
140159
this._reader = r;
141160
this._ioContext = ctxt;
142161
this._objectCodec = codec;
143162
this._parsingContext = JsonReadContext.createRootContext(-1, -1, null);
144163
this._system = system;
164+
this._formatFeatures = ionParserFeatures;
145165
}
146166

147167
@Override
@@ -179,7 +199,9 @@ public IonSystem getIonSystem() {
179199

180200
@Override
181201
public boolean canReadTypeId() {
182-
return true; // yes, Ion got 'em
202+
// yes, Ion got 'em
203+
// 31-Mar-2021, manaigrn: but we might want to ignore them as per [dataformats-binary#270]
204+
return Feature.USE_NATIVE_TYPE_ID.enabledIn(_formatFeatures);
183205
}
184206

185207
@Override
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,66 @@
1+
package com.fasterxml.jackson.dataformat.ion.polymorphism;
2+
3+
import java.io.IOException;
4+
5+
import com.fasterxml.jackson.annotation.JsonSubTypes;
6+
import com.fasterxml.jackson.annotation.JsonSubTypes.Type;
7+
import com.fasterxml.jackson.annotation.JsonTypeInfo;
8+
import com.fasterxml.jackson.dataformat.ion.IonObjectMapper;
9+
import com.fasterxml.jackson.dataformat.ion.IonParser.Feature;
10+
import org.junit.Assert;
11+
import org.junit.Test;
12+
13+
import com.amazon.ion.IonValue;
14+
import com.amazon.ion.system.IonSystemBuilder;
15+
16+
public class PolymorphicTypeAnnotationsTest {
17+
private static final String SUBCLASS_TYPE_NAME = "subtype";
18+
19+
@JsonTypeInfo(
20+
use = JsonTypeInfo.Id.NAME,
21+
include = JsonTypeInfo.As.PROPERTY,
22+
property = "base",
23+
visible = true
24+
)
25+
@JsonSubTypes({
26+
@Type(value = Subclass.class, name = SUBCLASS_TYPE_NAME),
27+
})
28+
static public class BaseClass {
29+
}
30+
31+
32+
public static class Subclass extends BaseClass {
33+
public String base;
34+
}
35+
36+
37+
public static class Container {
38+
public BaseClass objectWithType;
39+
}
40+
41+
42+
private static final IonValue CONTAINER_WITH_TYPED_OBJECT = asIonValue(
43+
"{" +
44+
" objectWithType:type::" +
45+
" {" +
46+
" base:\"" + SUBCLASS_TYPE_NAME + "\"," +
47+
" }" +
48+
"}");
49+
50+
@Test
51+
public void testNativeTypeIdsDisabledReadsTypeAnnotationsSuccessfully() throws IOException {
52+
IonObjectMapper mapper = new IonObjectMapper();
53+
mapper.disable(Feature.USE_NATIVE_TYPE_ID);
54+
55+
Container containerWithBaseClass = mapper.readValue(CONTAINER_WITH_TYPED_OBJECT, Container.class);
56+
57+
Assert.assertTrue(containerWithBaseClass.objectWithType instanceof Subclass);
58+
Assert.assertEquals(SUBCLASS_TYPE_NAME, ((Subclass) containerWithBaseClass.objectWithType).base);
59+
}
60+
61+
private static IonValue asIonValue(final String ionStr) {
62+
return IonSystemBuilder.standard()
63+
.build()
64+
.singleValue(ionStr);
65+
}
66+
}

0 commit comments

Comments
 (0)