Enabled usage of supertype adapters and serializers declared explicitly to allow "Immutables" to be usable.

Signed-off-by: Roman Grigoriadi <roman.grigoriadi@oracle.com>
diff --git a/src/main/java/org/eclipse/yasson/internal/AnnotationIntrospector.java b/src/main/java/org/eclipse/yasson/internal/AnnotationIntrospector.java
index bc363b4..1b9a226 100644
--- a/src/main/java/org/eclipse/yasson/internal/AnnotationIntrospector.java
+++ b/src/main/java/org/eclipse/yasson/internal/AnnotationIntrospector.java
@@ -226,7 +226,7 @@
         final Class<? extends JsonbAdapter> adapterClass = adapterAnnotation.value();
         final AdapterBinding adapterBinding = jsonbContext.getComponentMatcher().introspectAdapterBinding(adapterClass, null);
 
-        if (expectedClass.isPresent() && !(ReflectionUtils.getRawType(adapterBinding.getBindingType()).equals(expectedClass.get()))) {
+        if (expectedClass.isPresent() && !(ReflectionUtils.getRawType(adapterBinding.getBindingType()).isAssignableFrom(expectedClass.get()))) {
             throw new JsonbException(Messages.getMessage(MessageKeys.ADAPTER_INCOMPATIBLE, adapterBinding.getBindingType(), expectedClass.get()));
         }
         return adapterBinding;
diff --git a/src/main/java/org/eclipse/yasson/internal/ComponentMatcher.java b/src/main/java/org/eclipse/yasson/internal/ComponentMatcher.java
index 9b07327..1a25469 100644
--- a/src/main/java/org/eclipse/yasson/internal/ComponentMatcher.java
+++ b/src/main/java/org/eclipse/yasson/internal/ComponentMatcher.java
@@ -197,16 +197,18 @@
         if (componentBindingType.equals(runtimeType)) {
             return true;
         }
+
+        if (componentBindingType instanceof Class && runtimeType instanceof Class) {
+            return ((Class<?>) componentBindingType).isAssignableFrom((Class) runtimeType);
+        }
+
         //don't try to runtime generic scan if not needed
         if (!jsonbContext.genericComponentsPresent()) {
             return false;
         }
-        if (componentBindingType instanceof Class && runtimeType instanceof Class) {
-            //for polymorphic adapters
-            return ((Class<?>) componentBindingType).isAssignableFrom((Class) runtimeType);
-        }
+
         return runtimeType instanceof ParameterizedType && componentBindingType instanceof ParameterizedType &&
-                ReflectionUtils.getRawType(runtimeType) == ReflectionUtils.getRawType(componentBindingType) &&
+                ReflectionUtils.getRawType(componentBindingType).isAssignableFrom(ReflectionUtils.getRawType(runtimeType)) &&
                 matchTypeArguments((ParameterizedType) runtimeType, (ParameterizedType) componentBindingType);
     }
 
diff --git a/src/test/java/org/eclipse/yasson/adapters/AdaptersTest.java b/src/test/java/org/eclipse/yasson/adapters/AdaptersTest.java
index f8ab20a..c2fc5ad 100644
--- a/src/test/java/org/eclipse/yasson/adapters/AdaptersTest.java
+++ b/src/test/java/org/eclipse/yasson/adapters/AdaptersTest.java
@@ -1,5 +1,5 @@
 /*******************************************************************************
- * Copyright (c) 2016 Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2016, 2018 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 v1.0 and Eclipse Distribution License v. 1.0
  * which accompanies this distribution.
@@ -15,7 +15,17 @@
 
 
 import org.eclipse.yasson.TestTypeToken;
-import org.eclipse.yasson.adapters.model.*;
+import org.eclipse.yasson.adapters.model.AdaptedPojo;
+import org.eclipse.yasson.adapters.model.Author;
+import org.eclipse.yasson.adapters.model.Box;
+import org.eclipse.yasson.adapters.model.BoxToCrateCompatibleGenericsAdapter;
+import org.eclipse.yasson.adapters.model.BoxToCratePropagatedIntegerStringAdapter;
+import org.eclipse.yasson.adapters.model.Crate;
+import org.eclipse.yasson.adapters.model.GenericBox;
+import org.eclipse.yasson.adapters.model.IntegerListToStringAdapter;
+import org.eclipse.yasson.adapters.model.JsonObjectPojo;
+import org.eclipse.yasson.adapters.model.SupertypeAdapterPojo;
+import org.eclipse.yasson.adapters.model.UUIDContainer;
 import org.junit.Assert;
 import org.junit.Test;
 
@@ -24,7 +34,12 @@
 import javax.json.bind.JsonbConfig;
 import javax.json.bind.adapter.JsonbAdapter;
 import java.math.BigDecimal;
-import java.util.*;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.UUID;
 
 import static org.junit.Assert.assertEquals;
 
@@ -435,4 +450,16 @@
         Assert.assertEquals(uuid, uuidContainer.getUuidClsBased());
         Assert.assertEquals(uuid, uuidContainer.getUuidIfcBased());
     }
+
+    @Test
+    public void testSupertypeAdapter() {
+        jsonb = JsonbBuilder.create();
+        SupertypeAdapterPojo pojo = new SupertypeAdapterPojo();
+        pojo.setNumberInteger(10);
+        pojo.setSerializableInteger(11);
+        Assert.assertEquals("{\"numberInteger\":\"11\",\"serializableInteger\":12}", jsonb.toJson(pojo));
+        pojo = jsonb.fromJson("{\"numberInteger\":\"11\",\"serializableInteger\":12}", SupertypeAdapterPojo.class);
+        Assert.assertEquals(Integer.valueOf(10), pojo.getNumberInteger());
+        Assert.assertEquals(Integer.valueOf(11), pojo.getSerializableInteger());
+    }
 }
diff --git a/src/test/java/org/eclipse/yasson/adapters/model/NumberAdapter.java b/src/test/java/org/eclipse/yasson/adapters/model/NumberAdapter.java
new file mode 100644
index 0000000..205ef59
--- /dev/null
+++ b/src/test/java/org/eclipse/yasson/adapters/model/NumberAdapter.java
@@ -0,0 +1,25 @@
+/*******************************************************************************
+ * Copyright (c) 2018 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 v1.0 and Eclipse Distribution License v. 1.0
+ * which accompanies this distribution.
+ * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
+ * and the Eclipse Distribution License is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ *
+ ******************************************************************************/
+package org.eclipse.yasson.adapters.model;
+
+import javax.json.bind.adapter.JsonbAdapter;
+
+public class NumberAdapter implements JsonbAdapter<Number, String> {
+    @Override
+    public String adaptToJson(Number obj) throws Exception {
+        return Integer.valueOf(((Integer)obj) + 1).toString();
+    }
+
+    @Override
+    public Number adaptFromJson(String obj) throws Exception {
+        return Integer.parseInt(obj) - 1;
+    }
+}
diff --git a/src/test/java/org/eclipse/yasson/adapters/model/SerializableAdapter.java b/src/test/java/org/eclipse/yasson/adapters/model/SerializableAdapter.java
new file mode 100644
index 0000000..59bdfac
--- /dev/null
+++ b/src/test/java/org/eclipse/yasson/adapters/model/SerializableAdapter.java
@@ -0,0 +1,26 @@
+/*******************************************************************************
+ * Copyright (c) 2018 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 v1.0 and Eclipse Distribution License v. 1.0
+ * which accompanies this distribution.
+ * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
+ * and the Eclipse Distribution License is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ *
+ ******************************************************************************/
+package org.eclipse.yasson.adapters.model;
+
+import javax.json.bind.adapter.JsonbAdapter;
+import java.io.Serializable;
+
+public class SerializableAdapter implements JsonbAdapter<Serializable, Integer> {
+    @Override
+    public Integer adaptToJson(Serializable obj) throws Exception {
+        return Integer.valueOf(obj.toString()) + 1;
+    }
+
+    @Override
+    public Serializable adaptFromJson(Integer obj) throws Exception {
+        return obj - 1;
+    }
+}
diff --git a/src/test/java/org/eclipse/yasson/adapters/model/SupertypeAdapterPojo.java b/src/test/java/org/eclipse/yasson/adapters/model/SupertypeAdapterPojo.java
new file mode 100644
index 0000000..c7ef3f8
--- /dev/null
+++ b/src/test/java/org/eclipse/yasson/adapters/model/SupertypeAdapterPojo.java
@@ -0,0 +1,38 @@
+/*******************************************************************************
+ * Copyright (c) 2018 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 v1.0 and Eclipse Distribution License v. 1.0
+ * which accompanies this distribution.
+ * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
+ * and the Eclipse Distribution License is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ *
+ ******************************************************************************/
+package org.eclipse.yasson.adapters.model;
+
+import javax.json.bind.annotation.JsonbTypeAdapter;
+
+public class SupertypeAdapterPojo {
+
+    @JsonbTypeAdapter(NumberAdapter.class)
+    private Integer numberInteger;
+
+    @JsonbTypeAdapter(SerializableAdapter.class)
+    private Integer serializableInteger;
+
+    public Integer getNumberInteger() {
+        return numberInteger;
+    }
+
+    public void setNumberInteger(Integer numberInteger) {
+        this.numberInteger = numberInteger;
+    }
+
+    public Integer getSerializableInteger() {
+        return serializableInteger;
+    }
+
+    public void setSerializableInteger(Integer serializableInteger) {
+        this.serializableInteger = serializableInteger;
+    }
+}
diff --git a/src/test/java/org/eclipse/yasson/serializers/SerializersTest.java b/src/test/java/org/eclipse/yasson/serializers/SerializersTest.java
index f470943..41823c9 100644
--- a/src/test/java/org/eclipse/yasson/serializers/SerializersTest.java
+++ b/src/test/java/org/eclipse/yasson/serializers/SerializersTest.java
@@ -13,7 +13,25 @@
 
 package org.eclipse.yasson.serializers;
 
-import org.eclipse.yasson.serializers.model.*;
+import org.eclipse.yasson.serializers.model.AnnotatedWithSerializerType;
+import org.eclipse.yasson.serializers.model.Author;
+import org.eclipse.yasson.serializers.model.Box;
+import org.eclipse.yasson.serializers.model.BoxWithAnnotations;
+import org.eclipse.yasson.serializers.model.Crate;
+import org.eclipse.yasson.serializers.model.CrateDeserializer;
+import org.eclipse.yasson.serializers.model.CrateDeserializerWithConversion;
+import org.eclipse.yasson.serializers.model.CrateInner;
+import org.eclipse.yasson.serializers.model.CrateJsonObjectDeserializer;
+import org.eclipse.yasson.serializers.model.CrateSerializer;
+import org.eclipse.yasson.serializers.model.CrateSerializerWithConversion;
+import org.eclipse.yasson.serializers.model.NumberDeserializer;
+import org.eclipse.yasson.serializers.model.NumberSerializer;
+import org.eclipse.yasson.serializers.model.RecursiveDeserializer;
+import org.eclipse.yasson.serializers.model.RecursiveSerializer;
+import org.eclipse.yasson.serializers.model.SimpleAnnotatedSerializedArrayContainer;
+import org.eclipse.yasson.serializers.model.SimpleContainer;
+import org.eclipse.yasson.serializers.model.StringWrapper;
+import org.eclipse.yasson.serializers.model.SupertypeSerializerPojo;
 import org.junit.Assert;
 import org.junit.Test;
 
@@ -282,6 +300,21 @@
         Assert.assertEquals("Connor", result.getLastName());
     }
 
+    @Test
+    public void testSupertypeSerializer() {
+        Jsonb jsonb = JsonbBuilder.create(
+                new JsonbConfig().withSerializers(new NumberSerializer())
+                        .withDeserializers(new NumberDeserializer()));
+        SupertypeSerializerPojo pojo = new SupertypeSerializerPojo();
+        pojo.setNumberInteger(10);
+        pojo.setAnotherNumberInteger(11);
+        Assert.assertEquals("{\"anotherNumberInteger\":\"12\",\"numberInteger\":\"11\"}", jsonb.toJson(pojo));
+
+        pojo = jsonb.fromJson("{\"anotherNumberInteger\":\"12\",\"numberInteger\":\"11\"}", SupertypeSerializerPojo.class);
+        Assert.assertEquals(Integer.valueOf(10), pojo.getNumberInteger());
+        Assert.assertEquals(Integer.valueOf(11), pojo.getAnotherNumberInteger());
+    }
+
     private Box createPojoWithDates() {
         Date date = getExpectedDate();
         Box box = createPojo();
diff --git a/src/test/java/org/eclipse/yasson/serializers/model/NumberDeserializer.java b/src/test/java/org/eclipse/yasson/serializers/model/NumberDeserializer.java
new file mode 100644
index 0000000..0db5d9d
--- /dev/null
+++ b/src/test/java/org/eclipse/yasson/serializers/model/NumberDeserializer.java
@@ -0,0 +1,22 @@
+/*******************************************************************************
+ * Copyright (c) 2018 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 v1.0 and Eclipse Distribution License v. 1.0
+ * which accompanies this distribution.
+ * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
+ * and the Eclipse Distribution License is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ ******************************************************************************/
+package org.eclipse.yasson.serializers.model;
+
+import javax.json.bind.serializer.DeserializationContext;
+import javax.json.bind.serializer.JsonbDeserializer;
+import javax.json.stream.JsonParser;
+import java.lang.reflect.Type;
+
+public class NumberDeserializer implements JsonbDeserializer<Number> {
+    @Override
+    public Number deserialize(JsonParser parser, DeserializationContext ctx, Type rtType) {
+        return Integer.valueOf(parser.getString()) - 1;
+    }
+}
diff --git a/src/test/java/org/eclipse/yasson/serializers/model/NumberSerializer.java b/src/test/java/org/eclipse/yasson/serializers/model/NumberSerializer.java
new file mode 100644
index 0000000..3e49bda
--- /dev/null
+++ b/src/test/java/org/eclipse/yasson/serializers/model/NumberSerializer.java
@@ -0,0 +1,21 @@
+/*******************************************************************************
+ * Copyright (c) 2018 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 v1.0 and Eclipse Distribution License v. 1.0
+ * which accompanies this distribution.
+ * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
+ * and the Eclipse Distribution License is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ ******************************************************************************/
+package org.eclipse.yasson.serializers.model;
+
+import javax.json.bind.serializer.JsonbSerializer;
+import javax.json.bind.serializer.SerializationContext;
+import javax.json.stream.JsonGenerator;
+
+public class NumberSerializer implements JsonbSerializer<Number> {
+    @Override
+    public void serialize(Number obj, JsonGenerator generator, SerializationContext ctx) {
+        generator.write(Integer.valueOf(obj.intValue() + 1).toString());
+    }
+}
diff --git a/src/test/java/org/eclipse/yasson/serializers/model/SupertypeSerializerPojo.java b/src/test/java/org/eclipse/yasson/serializers/model/SupertypeSerializerPojo.java
new file mode 100644
index 0000000..ad8b943
--- /dev/null
+++ b/src/test/java/org/eclipse/yasson/serializers/model/SupertypeSerializerPojo.java
@@ -0,0 +1,40 @@
+/*******************************************************************************
+ * Copyright (c) 2018 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 v1.0 and Eclipse Distribution License v. 1.0
+ * which accompanies this distribution.
+ * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
+ * and the Eclipse Distribution License is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ ******************************************************************************/
+package org.eclipse.yasson.serializers.model;
+
+import javax.json.bind.annotation.JsonbTypeDeserializer;
+import javax.json.bind.annotation.JsonbTypeSerializer;
+
+public class SupertypeSerializerPojo {
+
+
+    @JsonbTypeSerializer(NumberSerializer.class)
+    @JsonbTypeDeserializer(NumberDeserializer.class)
+    private Integer numberInteger;
+
+    //Serializers bound with JsonbConfig for this one.
+    private Integer anotherNumberInteger;
+
+    public Integer getNumberInteger() {
+        return numberInteger;
+    }
+
+    public void setNumberInteger(Integer numberInteger) {
+        this.numberInteger = numberInteger;
+    }
+
+    public Integer getAnotherNumberInteger() {
+        return anotherNumberInteger;
+    }
+
+    public void setAnotherNumberInteger(Integer anotherNumberInteger) {
+        this.anotherNumberInteger = anotherNumberInteger;
+    }
+}