JOHNZON-290 configuration of jaxrs provider for polymorphic config
diff --git a/johnzon-jaxrs/src/main/java/org/apache/johnzon/jaxrs/ConfigurableJohnzonProvider.java b/johnzon-jaxrs/src/main/java/org/apache/johnzon/jaxrs/ConfigurableJohnzonProvider.java
index 9b853db..edcf545 100644
--- a/johnzon-jaxrs/src/main/java/org/apache/johnzon/jaxrs/ConfigurableJohnzonProvider.java
+++ b/johnzon-jaxrs/src/main/java/org/apache/johnzon/jaxrs/ConfigurableJohnzonProvider.java
@@ -20,6 +20,7 @@
 
 import static java.util.Arrays.asList;
 import static java.util.stream.Collectors.toMap;
+import static java.util.stream.Collectors.toSet;
 
 import java.io.IOException;
 import java.io.InputStream;
@@ -30,8 +31,10 @@
 import java.util.Comparator;
 import java.util.List;
 import java.util.Map;
+import java.util.Set;
 import java.util.concurrent.atomic.AtomicReference;
 import java.util.function.Function;
+import java.util.stream.Stream;
 
 import javax.json.JsonReaderFactory;
 import javax.json.stream.JsonGeneratorFactory;
@@ -134,6 +137,46 @@
         builder.setFailOnUnknownProperties(active);
     }
 
+    public void setPolymorphicSerializationPredicate(final String classes) {
+        final Set<Class<?>> set = asSet(classes);
+        builder.setPolymorphicSerializationPredicate(set::contains);
+    }
+
+    public void setPolymorphicDeserializationPredicate(final String classes) {
+        final Set<Class<?>> set = asSet(classes);
+        builder.setPolymorphicDeserializationPredicate(set::contains);
+    }
+
+    public void setPolymorphicDiscriminatorMapper(final Map<String, String> discriminatorMapper) {
+        final ClassLoader loader = Thread.currentThread().getContextClassLoader();
+        final Map<Class<?>, String> map = discriminatorMapper.entrySet().stream()
+                .collect(toMap(e -> {
+                    try {
+                        return loader.loadClass(e.getKey().trim());
+                    } catch (final ClassNotFoundException ex) {
+                        throw new IllegalArgumentException(ex);
+                    }
+                }, Map.Entry::getValue));
+        builder.setPolymorphicDiscriminatorMapper(map::get);
+    }
+
+    public void setPolymorphicTypeLoader(final Map<String, String> aliasTypeMapping) {
+        final ClassLoader loader = Thread.currentThread().getContextClassLoader();
+        final Map<String, Class<?>> map = aliasTypeMapping.entrySet().stream()
+                .collect(toMap(Map.Entry::getKey, e -> {
+                    try {
+                        return loader.loadClass(e.getValue().trim());
+                    } catch (final ClassNotFoundException ex) {
+                        throw new IllegalArgumentException(ex);
+                    }
+                }));
+        builder.setPolymorphicTypeLoader(map::get);
+    }
+
+    public void setPolymorphicDiscriminator(final String value) {
+        builder.setPolymorphicDiscriminator(value);
+    }
+
     public void setSupportConstructors(final boolean supportConstructors) {
         builder.setSupportConstructors(supportConstructors);
     }
@@ -269,4 +312,16 @@
     public void setAutoAdjustStringBuffers(final boolean autoAdjustStringBuffers) {
         builder.setAutoAdjustStringBuffers(autoAdjustStringBuffers);
     }
+
+    private Set<Class<?>> asSet(final String classes) {
+        final ClassLoader loader = Thread.currentThread().getContextClassLoader();
+        return Stream.of(classes.split(" *, *"))
+                .map(n -> {
+                    try {
+                        return loader.loadClass(n.trim());
+                    } catch (final ClassNotFoundException ex) {
+                        throw new IllegalArgumentException(ex);
+                    }
+                }).collect(toSet());
+    }
 }
diff --git a/johnzon-jsonb/src/main/java/org/apache/johnzon/jaxrs/jsonb/jaxrs/JsonbJaxrsProvider.java b/johnzon-jsonb/src/main/java/org/apache/johnzon/jaxrs/jsonb/jaxrs/JsonbJaxrsProvider.java
index 20d547a..43fbe70 100644
--- a/johnzon-jsonb/src/main/java/org/apache/johnzon/jaxrs/jsonb/jaxrs/JsonbJaxrsProvider.java
+++ b/johnzon-jsonb/src/main/java/org/apache/johnzon/jaxrs/jsonb/jaxrs/JsonbJaxrsProvider.java
@@ -20,6 +20,7 @@
 
 import static java.util.Optional.ofNullable;
 import static java.util.stream.Collectors.toMap;
+import static java.util.stream.Collectors.toSet;
 
 import javax.json.JsonStructure;
 import javax.json.bind.Jsonb;
@@ -47,14 +48,18 @@
 import java.util.Collection;
 import java.util.Map;
 import java.util.Properties;
+import java.util.Set;
 import java.util.function.Function;
 import java.util.logging.Logger;
+import java.util.stream.Stream;
 
 import javax.annotation.Priority;
 import javax.ws.rs.core.Context;
 import javax.ws.rs.ext.ContextResolver;
 import javax.ws.rs.ext.Providers;
 
+import org.apache.johnzon.jsonb.api.experimental.PolymorphicConfig;
+
 // here while we dont compile in java 8 jaxrs module, when migrated we'll merge it with IgnorableTypes hierarchy at least
 @Provider
 @Produces(MediaType.APPLICATION_JSON)
@@ -165,6 +170,74 @@
         customized = true;
     }
 
+
+    public void setPolymorphicSerializationPredicate(final String classes) {
+        final Set<Class<?>> set = asSet(classes);
+        getOrCreatePolymorphicConfig().withSerializationPredicate(set::contains);
+        customized = true;
+    }
+
+    public void setPolymorphicDeserializationPredicate(final String classes) {
+        final Set<Class<?>> set = asSet(classes);
+        getOrCreatePolymorphicConfig().withDeserializationPredicate(set::contains);
+        customized = true;
+    }
+
+    public void setPolymorphicDiscriminatorMapper(final Map<String, String> discriminatorMapper) {
+        final ClassLoader loader = Thread.currentThread().getContextClassLoader();
+        final Map<Class<?>, String> map = discriminatorMapper.entrySet().stream()
+                .collect(toMap(e -> {
+                    try {
+                        return loader.loadClass(e.getKey().trim());
+                    } catch (final ClassNotFoundException ex) {
+                        throw new IllegalArgumentException(ex);
+                    }
+                }, Map.Entry::getValue));
+        getOrCreatePolymorphicConfig().withDiscriminatorMapper(map::get);
+        customized = true;
+    }
+
+    public void setPolymorphicTypeLoader(final Map<String, String> aliasTypeMapping) {
+        final ClassLoader loader = Thread.currentThread().getContextClassLoader();
+        final Map<String, Class<?>> map = aliasTypeMapping.entrySet().stream()
+                .collect(toMap(Map.Entry::getKey, e -> {
+                    try {
+                        return loader.loadClass(e.getValue().trim());
+                    } catch (final ClassNotFoundException ex) {
+                        throw new IllegalArgumentException(ex);
+                    }
+                }));
+        getOrCreatePolymorphicConfig().withTypeLoader(map::get);
+        customized = true;
+    }
+
+    public void setPolymorphicDiscriminator(final String value) {
+        getOrCreatePolymorphicConfig().withDiscriminator(value);
+        customized = true;
+    }
+
+    private PolymorphicConfig getOrCreatePolymorphicConfig() {
+        return config.getProperty(PolymorphicConfig.class.getName())
+                .map(PolymorphicConfig.class::cast)
+                .orElseGet(() -> {
+                    final PolymorphicConfig config = new PolymorphicConfig();
+                    this.config.setProperty(PolymorphicConfig.class.getName(), config);
+                    return config;
+                });
+    }
+
+    private Set<Class<?>> asSet(final String classes) {
+        final ClassLoader loader = Thread.currentThread().getContextClassLoader();
+        return Stream.of(classes.split(" *, *"))
+                .map(n -> {
+                    try {
+                        return loader.loadClass(n.trim());
+                    } catch (final ClassNotFoundException ex) {
+                        throw new IllegalArgumentException(ex);
+                    }
+                }).collect(toSet());
+    }
+
     // actual impl
 
     @Override