Skip to content

Commit 2a07652

Browse files
committed
Fix #232
1 parent a018ddf commit 2a07652

File tree

7 files changed

+57
-16
lines changed

7 files changed

+57
-16
lines changed

release-notes/VERSION-2.x

+2
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,8 @@ Modules:
2424
#231: (yaml) Typed object with anchor throws Already had POJO for id (note: actual
2525
fix in `jackson-annotations`)
2626
(reported by almson@github)
27+
#232: (yaml) Typed object throws "Missing type id" when annotated with @JsonIdentityInfo
28+
(reported by almson@github)
2729
#233: (yaml) Support decoding Binary, Octal and Hex numbers as integers
2830
- Add configurability of "YAML version generator is to follow" via "YAMLFactory.builder()"
2931
- SnakeYAML 1.26 -> 1.27

yaml/src/main/java/com/fasterxml/jackson/dataformat/yaml/YAMLParser.java

+30-6
Original file line numberDiff line numberDiff line change
@@ -110,6 +110,15 @@ private Feature(boolean defaultState) {
110110
*/
111111
protected Event _lastEvent;
112112

113+
/**
114+
* To keep track of tags ("type ids"), need to either get tags for all
115+
* events, or, keep tag of relevant event that might have it: this is
116+
* different from {@code _lastEvent} in some cases.
117+
*
118+
* @since 2.12
119+
*/
120+
protected Event _lastTagEvent;
121+
113122
/**
114123
* We need to keep track of text values.
115124
*/
@@ -139,7 +148,7 @@ private Feature(boolean defaultState) {
139148
* structured types, value whose first token current token is.
140149
*/
141150
protected String _currentAnchor;
142-
151+
143152
/*
144153
/**********************************************************************
145154
/* Life-cycle
@@ -387,6 +396,7 @@ public JsonToken nextToken() throws IOException
387396
// is null ok? Assume it is, for now, consider to be same as end-of-doc
388397
if (evt == null) {
389398
_currentAnchor = null;
399+
_lastTagEvent = null;
390400
return (_currToken = null);
391401
}
392402
_lastEvent = evt;
@@ -397,6 +407,7 @@ public JsonToken nextToken() throws IOException
397407
if (_currToken != JsonToken.FIELD_NAME) {
398408
if (!evt.is(Event.ID.Scalar)) {
399409
_currentAnchor = null;
410+
_lastTagEvent = null;
400411
// end is fine
401412
if (evt.is(Event.ID.MappingEnd)) {
402413
if (!_parsingContext.inObject()) { // sanity check is optional, but let's do it for now
@@ -407,6 +418,7 @@ public JsonToken nextToken() throws IOException
407418
}
408419
_reportError("Expected a field name (Scalar value in YAML), got this instead: "+evt);
409420
}
421+
410422
// 20-Feb-2019, tatu: [dataformats-text#123] Looks like YAML exposes Anchor for Object at point
411423
// where we return START_OBJECT (which makes sense), but, alas, Jackson expects that at point
412424
// after first FIELD_NAME. So we will need to defer clearing of the anchor slightly,
@@ -415,9 +427,15 @@ public JsonToken nextToken() throws IOException
415427
// test case given.
416428
final ScalarEvent scalar = (ScalarEvent) evt;
417429
final String newAnchor = scalar.getAnchor();
418-
if ((newAnchor != null) || (_currToken != JsonToken.START_OBJECT)) {
430+
final boolean firstEntry = (_currToken == JsonToken.START_OBJECT);
431+
if ((newAnchor != null) || !firstEntry) {
419432
_currentAnchor = scalar.getAnchor();
420433
}
434+
// 23-Nov-2020, tatu: [dataformats-text#232] shows case where ref to type id
435+
// needs to be similarly deferred...
436+
if (!firstEntry) {
437+
_lastTagEvent = evt;
438+
}
421439
final String name = scalar.getValue();
422440
_currentFieldName = name;
423441
_parsingContext.setCurrentName(name);
@@ -429,6 +447,7 @@ public JsonToken nextToken() throws IOException
429447

430448
// Ugh. Why not expose id, to be able to Switch?
431449
_currentAnchor = null;
450+
_lastTagEvent = evt;
432451

433452
// scalar values are probably the commonest:
434453
if (evt.is(Event.ID.Scalar)) {
@@ -1000,11 +1019,16 @@ public String getObjectId() throws IOException
10001019
public String getTypeId() throws IOException
10011020
{
10021021
String tag;
1003-
if (_lastEvent instanceof CollectionStartEvent) {
1004-
tag = ((CollectionStartEvent) _lastEvent).getTag();
1005-
} else if (_lastEvent instanceof ScalarEvent) {
1006-
tag = ((ScalarEvent) _lastEvent).getTag();
1022+
1023+
if (_lastTagEvent instanceof CollectionStartEvent) {
1024+
tag = ((CollectionStartEvent) _lastTagEvent).getTag();
1025+
//System.err.println("getTypeId() at "+currentToken()+", last was collection ("+_lastTagEvent.getClass().getSimpleName()+") -> "+tag);
1026+
} else if (_lastTagEvent instanceof ScalarEvent) {
1027+
tag = ((ScalarEvent) _lastTagEvent).getTag();
1028+
//System.err.println("getTypeId() at "+currentToken()+", last was scalar -> "+tag+", scalar == "+_lastEvent);
1029+
10071030
} else {
1031+
//System.err.println("getTypeId(), something else, curr token: "+currentToken());
10081032
return null;
10091033
}
10101034
if (tag != null) {

yaml/src/main/java/com/fasterxml/jackson/dataformat/yaml/snakeyaml/error/MarkedYAMLException.java

+2-1
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,8 @@
55
/**
66
* Replacement for formerly shaded exception type from SnakeYAML; included
77
* in 2.8 solely for backwards compatibility: new code that relies on Jackson 2.8
8-
* and alter should NOT use this type but only base type {@link YAMLException}.
8+
* and after should NOT use this type but only base type
9+
* {@link com.fasterxml.jackson.dataformat.yaml.JacksonYAMLParseException}.
910
*
1011
* @deprecated Since 2.8
1112
*/

yaml/src/test/java/com/fasterxml/jackson/dataformat/yaml/failing/PolymorphicWithObjectId25Test.java

+1-1
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,7 @@ public void testPolymorphicAndObjectId25() throws Exception
4646
+"type: \"node\"\n"
4747
+"next:\n"
4848
+" &id2 name: \"second\"\n"
49-
+" next: *id1"
49+
+" next: *id1\n"
5050
;
5151

5252
NodeWithStringId node = MAPPER.readValue(yml, NodeWithStringId.class);

yaml/src/test/java/com/fasterxml/jackson/dataformat/yaml/misc/ObjectAndTypeId231Test.java

+9-3
Original file line numberDiff line numberDiff line change
@@ -33,15 +33,21 @@ public void testTypeAndObjectId231() throws Exception
3333
{
3434
String yaml = "list:\n" +
3535
" - !Derived &id1\n" +
36-
" a: foo";
36+
" a: foo\n"+
37+
" - !Derived &id2\n" +
38+
" a: bar\n"+
39+
"";
3740
Container container = MAPPER.readValue(yaml, Container.class);
3841
assertNotNull(container);
3942
assertNotNull(container.list);
40-
assertEquals(1, container.list.size());
43+
assertEquals(2, container.list.size());
4144

4245
Base item = container.list.get(0);
4346
assertEquals(Derived.class, item.getClass());
44-
4547
assertEquals("foo", ((Derived) item).a);
48+
49+
item = container.list.get(1);
50+
assertEquals(Derived.class, item.getClass());
51+
assertEquals("bar", ((Derived) item).a);
4652
}
4753
}

yaml/src/test/java/com/fasterxml/jackson/dataformat/yaml/failing/ObjectAndTypeId232Test.java renamed to yaml/src/test/java/com/fasterxml/jackson/dataformat/yaml/misc/ObjectAndTypeId232Test.java

+13-4
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
package com.fasterxml.jackson.dataformat.yaml.failing;
1+
package com.fasterxml.jackson.dataformat.yaml.misc;
22

33
import java.util.List;
44

@@ -19,7 +19,7 @@ static class Container232 {
1919
@JsonProperty
2020
List<Base232> list;
2121
}
22-
22+
2323
@JsonTypeInfo(use = Id.NAME)
2424
@JsonSubTypes({@JsonSubTypes.Type(name="Derived", value=Derived232.class)})
2525
@JsonIdentityInfo(generator = ObjectIdGenerators.StringIdGenerator.class)
@@ -43,12 +43,21 @@ public void testTypedYAML232() throws Exception
4343
{
4444
String yaml = "list:\n" +
4545
" - !Derived\n" +
46-
" a: foo";
46+
" a: foo\n"+
47+
" - !Derived\n" +
48+
" a: bar\n"+
49+
"";
4750
Container232 container = MAPPER.readValue(yaml, Container232.class);
4851
assertNotNull(container);
4952
assertNotNull(container.list);
50-
assertEquals(1, container.list.size());
53+
assertEquals(2, container.list.size());
54+
5155
assertNotNull(container.list.get(0));
5256
assertEquals(Derived232.class, container.list.get(0).getClass());
57+
assertEquals("foo", ((Derived232) container.list.get(0)).a);
58+
59+
assertNotNull(container.list.get(1));
60+
assertEquals(Derived232.class, container.list.get(1).getClass());
61+
assertEquals("bar", ((Derived232) container.list.get(1)).a);
5362
}
5463
}

yaml/src/test/java/com/fasterxml/jackson/dataformat/yaml/type/PolymorphicIdTest.java

-1
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,6 @@
55
import com.fasterxml.jackson.annotation.*;
66
import com.fasterxml.jackson.databind.*;
77
import com.fasterxml.jackson.dataformat.yaml.ModuleTestBase;
8-
import com.fasterxml.jackson.dataformat.yaml.YAMLFactory;
98

109
public class PolymorphicIdTest extends ModuleTestBase
1110
{

0 commit comments

Comments
 (0)