Fixed #589 (by adding skipObject() and skipArray() methods) (#590)
Fix issue #589 (implement skipObject() and skipArray() methods)
diff --git a/src/main/java/org/eclipse/yasson/internal/deserializer/ObjectDeserializer.java b/src/main/java/org/eclipse/yasson/internal/deserializer/ObjectDeserializer.java
index acd62ed..fa7d914 100644
--- a/src/main/java/org/eclipse/yasson/internal/deserializer/ObjectDeserializer.java
+++ b/src/main/java/org/eclipse/yasson/internal/deserializer/ObjectDeserializer.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2021, 2022 Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2021, 2023 Oracle and/or its affiliates. All rights reserved.
*
* This program and the accompanying materials are made available under the
* terms of the Eclipse Public License v. 2.0 which is available at
diff --git a/src/main/java/org/eclipse/yasson/internal/jsonstructure/JsonStructureToParserAdapter.java b/src/main/java/org/eclipse/yasson/internal/jsonstructure/JsonStructureToParserAdapter.java
index 94d3782..dfa9d64 100644
--- a/src/main/java/org/eclipse/yasson/internal/jsonstructure/JsonStructureToParserAdapter.java
+++ b/src/main/java/org/eclipse/yasson/internal/jsonstructure/JsonStructureToParserAdapter.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2019, 2022 Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2019, 2023 Oracle and/or its affiliates. All rights reserved.
*
* This program and the accompanying materials are made available under the
* terms of the Eclipse Public License v. 2.0 which is available at
@@ -25,6 +25,9 @@
import jakarta.json.stream.JsonLocation;
import jakarta.json.stream.JsonParser;
+import org.eclipse.yasson.internal.properties.MessageKeys;
+import org.eclipse.yasson.internal.properties.Messages;
+
/**
* Adapter for {@link JsonParser}, that reads a {@link JsonStructure} content tree instead of JSON text.
*
@@ -66,9 +69,9 @@
JsonStructureIterator current = iterators.peek();
Event next = current.next();
if (next == Event.START_OBJECT) {
- iterators.push(new JsonObjectIterator((JsonObject) iterators.peek().getValue()));
+ iterators.push(new JsonObjectIterator((JsonObject) current.getValue()));
} else if (next == Event.START_ARRAY) {
- iterators.push(new JsonArrayIterator((JsonArray) iterators.peek().getValue()));
+ iterators.push(new JsonArrayIterator((JsonArray) current.getValue()));
} else if (next == Event.END_OBJECT || next == Event.END_ARRAY) {
iterators.pop();
}
@@ -102,8 +105,14 @@
@Override
public JsonObject getObject() {
-// ((JsonObjectIterator) iterators.peek()).jsonObject
- return iterators.peek().getValue().asJsonObject();
+ JsonStructureIterator current = iterators.peek();
+ if (current instanceof JsonObjectIterator) {
+ //Remove child iterator as getObject() method contract says
+ iterators.pop();
+ return current.getValue().asJsonObject();
+ } else {
+ throw new JsonbException(Messages.getMessage(MessageKeys.INTERNAL_ERROR, "Outside of object context"));
+ }
}
private JsonNumber getJsonNumberValue() {
@@ -121,6 +130,26 @@
}
@Override
+ public void skipArray() {
+ if (!iterators.isEmpty()) {
+ JsonStructureIterator current = iterators.peek();
+ if (current instanceof JsonArrayIterator) {
+ iterators.pop();
+ }
+ }
+ }
+
+ @Override
+ public void skipObject() {
+ if (!iterators.isEmpty()) {
+ JsonStructureIterator current = iterators.peek();
+ if (current instanceof JsonObjectIterator) {
+ iterators.pop();
+ }
+ }
+ }
+
+ @Override
public void close() {
//noop
}
diff --git a/src/main/java/org/eclipse/yasson/internal/model/JsonbAnnotatedElement.java b/src/main/java/org/eclipse/yasson/internal/model/JsonbAnnotatedElement.java
index 774be03..b93abe9 100644
--- a/src/main/java/org/eclipse/yasson/internal/model/JsonbAnnotatedElement.java
+++ b/src/main/java/org/eclipse/yasson/internal/model/JsonbAnnotatedElement.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2016, 2022 Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2016, 2023 Oracle and/or its affiliates. All rights reserved.
*
* This program and the accompanying materials are made available under the
* terms of the Eclipse Public License v. 2.0 which is available at
@@ -100,7 +100,7 @@
// }
// annotations.put(annotation.annotationType(), new AnnotationWrapper(annotation, inherited));
annotations.computeIfAbsent(annotation.annotationType(), aClass -> new LinkedList<>())
- .add(new AnnotationWrapper(annotation, inherited, definedType));
+ .add(new AnnotationWrapper<Annotation>(annotation, inherited, definedType));
}
public void putAnnotationWrapper(AnnotationWrapper<?> annotationWrapper) {
diff --git a/src/test/java/org/eclipse/yasson/customization/polymorphism/NestedPolymorphismTest.java b/src/test/java/org/eclipse/yasson/customization/polymorphism/NestedPolymorphismTest.java
new file mode 100644
index 0000000..fe1c4dd
--- /dev/null
+++ b/src/test/java/org/eclipse/yasson/customization/polymorphism/NestedPolymorphismTest.java
@@ -0,0 +1,123 @@
+/*
+ * Copyright (c) 2021, 2023 Oracle and/or its affiliates. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0,
+ * or the Eclipse Distribution License v. 1.0 which is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ *
+ * SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
+ */
+
+package org.eclipse.yasson.customization.polymorphism;
+
+import jakarta.json.bind.annotation.JsonbSubtype;
+import jakarta.json.bind.annotation.JsonbTypeInfo;
+
+import org.eclipse.yasson.Jsonbs;
+import org.junit.jupiter.api.Test;
+
+import static org.eclipse.yasson.Jsonbs.defaultJsonb;
+import static org.hamcrest.CoreMatchers.instanceOf;
+import static org.hamcrest.MatcherAssert.assertThat;
+import static org.junit.jupiter.api.Assertions.assertDoesNotThrow;
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertNotNull;
+
+/**
+ * Tests for verification of proper polymorphism handling based on annotation.
+ */
+public class NestedPolymorphismTest {
+
+ /**
+ * 1st test for: https://github.com/eclipse-ee4j/yasson/issues/589
+ * <p>(deserialization of nested polymorphic and unmapped properties)
+ */
+ @Test
+ public void testNestedUnmappedProperty() {
+ String json = "{\"inner\":{\"id\":123,\"@type\":\"derivationA\","
+ + "\"unmapped\":{\"x\":9,\"y\":[9,8,7]},\"name\":\"abc\"}}";
+ Outer obj = assertDoesNotThrow(() -> defaultJsonb.fromJson(json, Outer.class));
+ assertEquals(123L, obj.inner.id);
+ assertEquals("abc", obj.inner.name);
+ }
+
+ // a base class
+ @JsonbTypeInfo(key = "@type", value =
+ @JsonbSubtype(type = InnerBase.class, alias = "derivationA"))
+ public static class InnerBase {
+ public Long id;
+ public String name;
+ }
+
+ // derivation of the base class
+ public class Derivation extends InnerBase {}
+
+ // an arbitrary 'outer' root element
+ public static class Outer {
+ public InnerBase inner;
+ }
+
+ /**
+ * 2nd test for: https://github.com/eclipse-ee4j/yasson/issues/589
+ * <p>(deserialization of multiple nested polymorphic properties)
+ */
+ @Test
+ public void testNestedDeserialization() {
+ String json = "{\"@type\":\"Pets\",\"pet1\":{\"@type\":\"Cat\",\"name\":\"kitty\"}"
+ + ",\"pet2\":{\"@type\":\"Dog\",\"name\":\"puppy\"}}";
+ final Animals animals = Jsonbs.defaultJsonb.fromJson(json, Animals.class);
+ assertThat(animals, instanceOf(Pets.class));
+ assertNotNull(((Pets) animals).pet1, "Empty 'pet1' property");
+ assertEquals("kitty", ((Cat) ((Pets) animals).pet1).name, "First pet has invalid name");
+ assertNotNull(((Pets) animals).pet2, "Empty 'pet2' property");
+ assertThat("Invalid pet nr 2", ((Pets) animals).pet2, instanceOf(Dog.class));
+ }
+
+ @JsonbTypeInfo(key = "@type", value = {
+ @JsonbSubtype(alias = "Dog", type = Dog.class),
+ @JsonbSubtype(alias = "Cat", type = Cat.class)
+ })
+ public interface Pet {
+ public String getType();
+ }
+
+ public static class Dog implements Pet {
+
+ public String name;
+
+ @Override
+ public String getType() {
+ return "Dog";
+ }
+ }
+
+ public static class Cat implements Pet {
+
+ public String name;
+
+ @Override
+ public String getType() {
+ return "Cat";
+ }
+ }
+
+ @JsonbTypeInfo(key = "@type", value = {
+ @JsonbSubtype(alias = "Pets", type = Pets.class),
+ @JsonbSubtype(alias = "Fishes", type = Fishes.class)
+ })
+ public interface Animals {
+
+ }
+
+ public static class Pets implements Animals {
+ public Pet pet1;
+ public Pet pet2;
+ }
+
+ public static class Fishes implements Animals {
+
+ }
+
+}
diff --git a/src/test/java/org/eclipse/yasson/internal/serializer/ObjectDeserializerTest.java b/src/test/java/org/eclipse/yasson/internal/serializer/ObjectDeserializerTest.java
index ad2f0d0..3c41581 100644
--- a/src/test/java/org/eclipse/yasson/internal/serializer/ObjectDeserializerTest.java
+++ b/src/test/java/org/eclipse/yasson/internal/serializer/ObjectDeserializerTest.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2019, 2020 Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2019, 2023 Oracle and/or its affiliates. All rights reserved.
*
* This program and the accompanying materials are made available under the
* terms of the Eclipse Public License v. 2.0 which is available at
@@ -22,9 +22,9 @@
@Test
public void testGetInstanceExceptionShouldContainClassNameOnMissingConstructor() {
- assertThrows(JsonbException.class,
- () -> defaultJsonb.fromJson("{\"key\":\"value\"}", DummyDeserializationClass.class),
- DummyDeserializationClass.class::getName);
+ assertThrows(JsonbException.class,
+ () -> defaultJsonb.fromJson("{\"key\":\"value\"}", DummyDeserializationClass.class),
+ DummyDeserializationClass.class::getName);
}
public static class DummyDeserializationClass {