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 {