Skip to content

Commit f3cbb35

Browse files
authored
Fixed #589 (by adding skipObject() and skipArray() methods) (#590)
Fix issue #589 (implement skipObject() and skipArray() methods)
1 parent a5b6943 commit f3cbb35

File tree

5 files changed

+164
-12
lines changed

5 files changed

+164
-12
lines changed

src/main/java/org/eclipse/yasson/internal/deserializer/ObjectDeserializer.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright (c) 2021, 2022 Oracle and/or its affiliates. All rights reserved.
2+
* Copyright (c) 2021, 2023 Oracle and/or its affiliates. All rights reserved.
33
*
44
* This program and the accompanying materials are made available under the
55
* terms of the Eclipse Public License v. 2.0 which is available at

src/main/java/org/eclipse/yasson/internal/jsonstructure/JsonStructureToParserAdapter.java

Lines changed: 34 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright (c) 2019, 2022 Oracle and/or its affiliates. All rights reserved.
2+
* Copyright (c) 2019, 2023 Oracle and/or its affiliates. All rights reserved.
33
*
44
* This program and the accompanying materials are made available under the
55
* terms of the Eclipse Public License v. 2.0 which is available at
@@ -25,6 +25,9 @@
2525
import jakarta.json.stream.JsonLocation;
2626
import jakarta.json.stream.JsonParser;
2727

28+
import org.eclipse.yasson.internal.properties.MessageKeys;
29+
import org.eclipse.yasson.internal.properties.Messages;
30+
2831
/**
2932
* Adapter for {@link JsonParser}, that reads a {@link JsonStructure} content tree instead of JSON text.
3033
*
@@ -66,9 +69,9 @@ public Event next() {
6669
JsonStructureIterator current = iterators.peek();
6770
Event next = current.next();
6871
if (next == Event.START_OBJECT) {
69-
iterators.push(new JsonObjectIterator((JsonObject) iterators.peek().getValue()));
72+
iterators.push(new JsonObjectIterator((JsonObject) current.getValue()));
7073
} else if (next == Event.START_ARRAY) {
71-
iterators.push(new JsonArrayIterator((JsonArray) iterators.peek().getValue()));
74+
iterators.push(new JsonArrayIterator((JsonArray) current.getValue()));
7275
} else if (next == Event.END_OBJECT || next == Event.END_ARRAY) {
7376
iterators.pop();
7477
}
@@ -102,8 +105,14 @@ public BigDecimal getBigDecimal() {
102105

103106
@Override
104107
public JsonObject getObject() {
105-
// ((JsonObjectIterator) iterators.peek()).jsonObject
106-
return iterators.peek().getValue().asJsonObject();
108+
JsonStructureIterator current = iterators.peek();
109+
if (current instanceof JsonObjectIterator) {
110+
//Remove child iterator as getObject() method contract says
111+
iterators.pop();
112+
return current.getValue().asJsonObject();
113+
} else {
114+
throw new JsonbException(Messages.getMessage(MessageKeys.INTERNAL_ERROR, "Outside of object context"));
115+
}
107116
}
108117

109118
private JsonNumber getJsonNumberValue() {
@@ -120,6 +129,26 @@ public JsonLocation getLocation() {
120129
throw new JsonbException("Operation not supported");
121130
}
122131

132+
@Override
133+
public void skipArray() {
134+
if (!iterators.isEmpty()) {
135+
JsonStructureIterator current = iterators.peek();
136+
if (current instanceof JsonArrayIterator) {
137+
iterators.pop();
138+
}
139+
}
140+
}
141+
142+
@Override
143+
public void skipObject() {
144+
if (!iterators.isEmpty()) {
145+
JsonStructureIterator current = iterators.peek();
146+
if (current instanceof JsonObjectIterator) {
147+
iterators.pop();
148+
}
149+
}
150+
}
151+
123152
@Override
124153
public void close() {
125154
//noop

src/main/java/org/eclipse/yasson/internal/model/JsonbAnnotatedElement.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright (c) 2016, 2022 Oracle and/or its affiliates. All rights reserved.
2+
* Copyright (c) 2016, 2023 Oracle and/or its affiliates. All rights reserved.
33
*
44
* This program and the accompanying materials are made available under the
55
* terms of the Eclipse Public License v. 2.0 which is available at
@@ -100,7 +100,7 @@ public void putAnnotation(Annotation annotation, boolean inherited, Class<?> def
100100
// }
101101
// annotations.put(annotation.annotationType(), new AnnotationWrapper(annotation, inherited));
102102
annotations.computeIfAbsent(annotation.annotationType(), aClass -> new LinkedList<>())
103-
.add(new AnnotationWrapper(annotation, inherited, definedType));
103+
.add(new AnnotationWrapper<Annotation>(annotation, inherited, definedType));
104104
}
105105

106106
public void putAnnotationWrapper(AnnotationWrapper<?> annotationWrapper) {
Lines changed: 123 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,123 @@
1+
/*
2+
* Copyright (c) 2021, 2023 Oracle and/or its affiliates. All rights reserved.
3+
*
4+
* This program and the accompanying materials are made available under the
5+
* terms of the Eclipse Public License v. 2.0 which is available at
6+
* http://www.eclipse.org/legal/epl-2.0,
7+
* or the Eclipse Distribution License v. 1.0 which is available at
8+
* http://www.eclipse.org/org/documents/edl-v10.php.
9+
*
10+
* SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
11+
*/
12+
13+
package org.eclipse.yasson.customization.polymorphism;
14+
15+
import jakarta.json.bind.annotation.JsonbSubtype;
16+
import jakarta.json.bind.annotation.JsonbTypeInfo;
17+
18+
import org.eclipse.yasson.Jsonbs;
19+
import org.junit.jupiter.api.Test;
20+
21+
import static org.eclipse.yasson.Jsonbs.defaultJsonb;
22+
import static org.hamcrest.CoreMatchers.instanceOf;
23+
import static org.hamcrest.MatcherAssert.assertThat;
24+
import static org.junit.jupiter.api.Assertions.assertDoesNotThrow;
25+
import static org.junit.jupiter.api.Assertions.assertEquals;
26+
import static org.junit.jupiter.api.Assertions.assertNotNull;
27+
28+
/**
29+
* Tests for verification of proper polymorphism handling based on annotation.
30+
*/
31+
public class NestedPolymorphismTest {
32+
33+
/**
34+
* 1st test for: https://github.com/eclipse-ee4j/yasson/issues/589
35+
* <p>(deserialization of nested polymorphic and unmapped properties)
36+
*/
37+
@Test
38+
public void testNestedUnmappedProperty() {
39+
String json = "{\"inner\":{\"id\":123,\"@type\":\"derivationA\","
40+
+ "\"unmapped\":{\"x\":9,\"y\":[9,8,7]},\"name\":\"abc\"}}";
41+
Outer obj = assertDoesNotThrow(() -> defaultJsonb.fromJson(json, Outer.class));
42+
assertEquals(123L, obj.inner.id);
43+
assertEquals("abc", obj.inner.name);
44+
}
45+
46+
// a base class
47+
@JsonbTypeInfo(key = "@type", value =
48+
@JsonbSubtype(type = InnerBase.class, alias = "derivationA"))
49+
public static class InnerBase {
50+
public Long id;
51+
public String name;
52+
}
53+
54+
// derivation of the base class
55+
public class Derivation extends InnerBase {}
56+
57+
// an arbitrary 'outer' root element
58+
public static class Outer {
59+
public InnerBase inner;
60+
}
61+
62+
/**
63+
* 2nd test for: https://github.com/eclipse-ee4j/yasson/issues/589
64+
* <p>(deserialization of multiple nested polymorphic properties)
65+
*/
66+
@Test
67+
public void testNestedDeserialization() {
68+
String json = "{\"@type\":\"Pets\",\"pet1\":{\"@type\":\"Cat\",\"name\":\"kitty\"}"
69+
+ ",\"pet2\":{\"@type\":\"Dog\",\"name\":\"puppy\"}}";
70+
final Animals animals = Jsonbs.defaultJsonb.fromJson(json, Animals.class);
71+
assertThat(animals, instanceOf(Pets.class));
72+
assertNotNull(((Pets) animals).pet1, "Empty 'pet1' property");
73+
assertEquals("kitty", ((Cat) ((Pets) animals).pet1).name, "First pet has invalid name");
74+
assertNotNull(((Pets) animals).pet2, "Empty 'pet2' property");
75+
assertThat("Invalid pet nr 2", ((Pets) animals).pet2, instanceOf(Dog.class));
76+
}
77+
78+
@JsonbTypeInfo(key = "@type", value = {
79+
@JsonbSubtype(alias = "Dog", type = Dog.class),
80+
@JsonbSubtype(alias = "Cat", type = Cat.class)
81+
})
82+
public interface Pet {
83+
public String getType();
84+
}
85+
86+
public static class Dog implements Pet {
87+
88+
public String name;
89+
90+
@Override
91+
public String getType() {
92+
return "Dog";
93+
}
94+
}
95+
96+
public static class Cat implements Pet {
97+
98+
public String name;
99+
100+
@Override
101+
public String getType() {
102+
return "Cat";
103+
}
104+
}
105+
106+
@JsonbTypeInfo(key = "@type", value = {
107+
@JsonbSubtype(alias = "Pets", type = Pets.class),
108+
@JsonbSubtype(alias = "Fishes", type = Fishes.class)
109+
})
110+
public interface Animals {
111+
112+
}
113+
114+
public static class Pets implements Animals {
115+
public Pet pet1;
116+
public Pet pet2;
117+
}
118+
119+
public static class Fishes implements Animals {
120+
121+
}
122+
123+
}

src/test/java/org/eclipse/yasson/internal/serializer/ObjectDeserializerTest.java

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright (c) 2019, 2020 Oracle and/or its affiliates. All rights reserved.
2+
* Copyright (c) 2019, 2023 Oracle and/or its affiliates. All rights reserved.
33
*
44
* This program and the accompanying materials are made available under the
55
* terms of the Eclipse Public License v. 2.0 which is available at
@@ -22,9 +22,9 @@ public class ObjectDeserializerTest {
2222

2323
@Test
2424
public void testGetInstanceExceptionShouldContainClassNameOnMissingConstructor() {
25-
assertThrows(JsonbException.class,
26-
() -> defaultJsonb.fromJson("{\"key\":\"value\"}", DummyDeserializationClass.class),
27-
DummyDeserializationClass.class::getName);
25+
assertThrows(JsonbException.class,
26+
() -> defaultJsonb.fromJson("{\"key\":\"value\"}", DummyDeserializationClass.class),
27+
DummyDeserializationClass.class::getName);
2828
}
2929

3030
public static class DummyDeserializationClass {

0 commit comments

Comments
 (0)