This is an automated email from the ASF dual-hosted git repository.

rmannibucau pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/johnzon.git


The following commit(s) were added to refs/heads/master by this push:
     new ecdc643  JOHNZON-287 JOHNZON-288 JOHNZON-289 add supportPrivateAccess 
for jsonbcreator in jsonbaccessmode + cleanup CDI property support
ecdc643 is described below

commit ecdc643014446ef35be2782224f450360d23ed74
Author: Romain Manni-Bucau <rmannibu...@gmail.com>
AuthorDate: Wed Oct 9 14:45:57 2019 +0200

    JOHNZON-287 JOHNZON-288 JOHNZON-289 add supportPrivateAccess for 
jsonbcreator in jsonbaccessmode + cleanup CDI property support
---
 .../org/apache/johnzon/jsonb/JohnzonBuilder.java   | 28 ++++++++++++-----
 .../org/apache/johnzon/jsonb/JsonbAccessMode.java  | 36 +++++++++++++++++-----
 .../johnzon/jsonb/ConstructorVisibilityTest.java   | 24 +++++++++++++++
 src/site/markdown/index.md                         |  9 ++++++
 4 files changed, 81 insertions(+), 16 deletions(-)

diff --git 
a/johnzon-jsonb/src/main/java/org/apache/johnzon/jsonb/JohnzonBuilder.java 
b/johnzon-jsonb/src/main/java/org/apache/johnzon/jsonb/JohnzonBuilder.java
index f5bb7ea..d33f229 100644
--- a/johnzon-jsonb/src/main/java/org/apache/johnzon/jsonb/JohnzonBuilder.java
+++ b/johnzon-jsonb/src/main/java/org/apache/johnzon/jsonb/JohnzonBuilder.java
@@ -141,6 +141,8 @@ public class JohnzonBuilder implements JsonbBuilder {
             config = new JsonbConfig();
         }
 
+        final Boolean skipCdi = shouldSkipCdi();
+
         // todo: global spec toggle to disable all these ones at once?
         builder.setUseBigDecimalForObjectNumbers(
                 
config.getProperty("johnzon.use-big-decimal-for-object").map(this::toBool).orElse(true));
@@ -222,7 +224,7 @@ public class JohnzonBuilder implements JsonbBuilder {
                 }
             }
             throw new IllegalArgumentException("Unsupported factory: " + val);
-        }).orElseGet(this::findFactory);
+        }).orElseGet(() -> findFactory(skipCdi));
 
         final AccessMode accessMode = config.getProperty("johnzon.accessMode")
                 .map(this::toAccessMode)
@@ -235,9 +237,12 @@ public class JohnzonBuilder implements JsonbBuilder {
                                 .map(this::toAccessMode)
                                 .orElseGet(() -> new 
FieldAndMethodAccessMode(true, true, false, true)),
                         
config.getProperty("johnzon.failOnMissingCreatorValues")
-                              .map(it -> String.class.isInstance(it) ? 
Boolean.parseBoolean(it.toString()) : Boolean.class.cast(it))
+                              .map(this::toBool)
                               .orElse(true) /*spec 1.0 requirement*/,
-                        isNillable));
+                        isNillable,
+                        config.getProperty("johnzon.supportsPrivateAccess")
+                                .map(this::toBool)
+                                .orElse(false)));
         builder.setAccessMode(accessMode);
 
         // user adapters
@@ -285,7 +290,9 @@ public class JohnzonBuilder implements JsonbBuilder {
             }
         });
 
-        getBeanManager(); // force detection
+        if (!skipCdi) {
+            getBeanManager(); // force detection
+        }
 
         final Types types = new Types();
         builder.setReadAttributeBeforeWrite(
@@ -340,7 +347,7 @@ public class JohnzonBuilder implements JsonbBuilder {
             });
         });
 
-        final boolean useCdi = cdiIntegration != null && 
cdiIntegration.isCanWrite() && 
config.getProperty("johnzon.cdi.activated").map(Boolean.class::cast).orElse(Boolean.TRUE);
+        final boolean useCdi = cdiIntegration != null && 
cdiIntegration.isCanWrite() && !skipCdi;
         if (Closeable.class.isInstance(accessMode)) {
             builder.addCloseable(Closeable.class.cast(accessMode));
         }
@@ -408,9 +415,8 @@ public class JohnzonBuilder implements JsonbBuilder {
         return beanManager;
     }
 
-    private JohnzonAdapterFactory findFactory() {
-        if (getBeanManager() == NO_BM || config.getProperty("johnzon.skip-cdi")
-                .map(s -> 
"true".equalsIgnoreCase(String.valueOf(s))).orElse(false)) {
+    private JohnzonAdapterFactory findFactory(final boolean skipCdi) {
+        if (skipCdi || getBeanManager() == NO_BM) {
             return new SimpleJohnzonAdapterFactory();
         }
         try { // don't trigger CDI is not there
@@ -420,6 +426,12 @@ public class JohnzonBuilder implements JsonbBuilder {
         }
     }
 
+    private Boolean shouldSkipCdi() {
+        return config.getProperty("johnzon.skip-cdi")
+                .map(s -> "true".equalsIgnoreCase(String.valueOf(s)))
+                .orElseGet(() -> 
!config.getProperty("johnzon.cdi.activated").map(Boolean.class::cast).orElse(Boolean.TRUE));
+    }
+
     private ClassLoader tccl() {
         return 
ofNullable(Thread.currentThread().getContextClassLoader()).orElseGet(ClassLoader::getSystemClassLoader);
     }
diff --git 
a/johnzon-jsonb/src/main/java/org/apache/johnzon/jsonb/JsonbAccessMode.java 
b/johnzon-jsonb/src/main/java/org/apache/johnzon/jsonb/JsonbAccessMode.java
index 4d19dff..c778724 100644
--- a/johnzon-jsonb/src/main/java/org/apache/johnzon/jsonb/JsonbAccessMode.java
+++ b/johnzon-jsonb/src/main/java/org/apache/johnzon/jsonb/JsonbAccessMode.java
@@ -146,6 +146,7 @@ public class JsonbAccessMode implements AccessMode, 
Closeable {
     private boolean failOnMissingCreatorValues;
     private final Types types = new Types();
     private final boolean globalIsNillable;
+    private final boolean supportsPrivateAccess;
 
     // CHECKSTYLE:OFF
     public JsonbAccessMode(final PropertyNamingStrategy 
propertyNamingStrategy, final String orderValue,
@@ -155,7 +156,8 @@ public class JsonbAccessMode implements AccessMode, 
Closeable {
                            final Supplier<JsonParserFactory> parserFactory,
                            final AccessMode delegate,
                            final boolean failOnMissingCreatorValues,
-                           final boolean globalIsNillable) {
+                           final boolean globalIsNillable,
+                           final boolean supportsPrivateAccess) {
         // CHECKSTYLE:ON
         this.globalIsNillable = globalIsNillable;
         this.naming = propertyNamingStrategy;
@@ -169,6 +171,7 @@ public class JsonbAccessMode implements AccessMode, 
Closeable {
         this.jsonProvider = jsonProvider;
         this.parserFactory = parserFactory;
         this.failOnMissingCreatorValues = failOnMissingCreatorValues;
+        this.supportsPrivateAccess = supportsPrivateAccess;
     }
 
     @Override
@@ -182,22 +185,29 @@ public class JsonbAccessMode implements AccessMode, 
Closeable {
         Constructor<?> constructor = null;
         Method factory = null;
         boolean invalidConstructorForDeserialization = false;
-        for (final Constructor<?> c : clazz.getConstructors()) {
+        for (final Constructor<?> c : supportsPrivateAccess ? 
clazz.getDeclaredConstructors() : clazz.getConstructors()) {
             if (c.isAnnotationPresent(JsonbCreator.class)) {
                 if (constructor != null) {
                     throw new JsonbException("Only one constructor or method 
can have @JsonbCreator");
                 }
+                if (!c.isAccessible()) {
+                    c.setAccessible(true);
+                }
                 constructor = c;
             }
         }
-        for (final Method m : clazz.getMethods()) {
+        for (final Method m : 
findPotentialFactoryMethods(clazz).collect(toList())) {
             final int modifiers = m.getModifiers();
-            if (Modifier.isPublic(modifiers) && 
m.isAnnotationPresent(JsonbCreator.class)) {
-                if (constructor != null || factory != null) {
-                    throw new JsonbException("Only one constructor or method 
can have @JsonbCreator");
-                }
-                factory = m;
+            if ((!supportsPrivateAccess && !Modifier.isPublic(modifiers)) || 
!m.isAnnotationPresent(JsonbCreator.class)) {
+                continue;
             }
+            if (constructor != null || factory != null) {
+                throw new JsonbException("Only one constructor or method can 
have @JsonbCreator");
+            }
+            if (!m.isAccessible()) {
+                m.setAccessible(true);
+            }
+            factory = m;
         }
         if (constructor == null && factory == null) {
             invalidConstructorForDeserialization = 
Stream.of(clazz.getDeclaredConstructors())
@@ -280,6 +290,16 @@ public class JsonbAccessMode implements AccessMode, 
Closeable {
         return methodFactory(clazz, finalFactory, factoryValidator, types, 
params, converters, itemConverters, objectConverters);
     }
 
+    private Stream<Method> findPotentialFactoryMethods(final Class<?> clazz) {
+        return (!supportsPrivateAccess ?
+                Stream.of(clazz.getMethods()) :
+                Stream.concat(
+                        Stream.of(clazz.getDeclaredMethods()),
+                        clazz.getSuperclass() == null || clazz.getSuperclass() 
== Object.class || clazz.getSuperclass() == clazz ?
+                                Stream.empty() :
+                                findPotentialFactoryMethods(clazz)));
+    }
+
     private Factory methodFactory(final Class<?> clazz, final Method 
finalFactory,
                                   final Consumer<Object[]> factoryValidator, 
final Type[] types,
                                   final String[] params, final Adapter<?, ?>[] 
converters,
diff --git 
a/johnzon-jsonb/src/test/java/org/apache/johnzon/jsonb/ConstructorVisibilityTest.java
 
b/johnzon-jsonb/src/test/java/org/apache/johnzon/jsonb/ConstructorVisibilityTest.java
index 0b0949c..bb69ad0 100644
--- 
a/johnzon-jsonb/src/test/java/org/apache/johnzon/jsonb/ConstructorVisibilityTest.java
+++ 
b/johnzon-jsonb/src/test/java/org/apache/johnzon/jsonb/ConstructorVisibilityTest.java
@@ -18,7 +18,14 @@
  */
 package org.apache.johnzon.jsonb;
 
+import static org.junit.Assert.assertEquals;
+
+import javax.json.bind.Jsonb;
+import javax.json.bind.JsonbBuilder;
+import javax.json.bind.JsonbConfig;
 import javax.json.bind.JsonbException;
+import javax.json.bind.annotation.JsonbCreator;
+import javax.json.bind.annotation.JsonbProperty;
 
 import org.apache.johnzon.jsonb.test.JsonbRule;
 import org.junit.Rule;
@@ -33,6 +40,14 @@ public class ConstructorVisibilityTest {
         jsonb.fromJson("{}", PackageCons.class);
     }
 
+    @Test
+    public void instantiablePackageConstructor() throws Exception {
+        try (final Jsonb jsonb = JsonbBuilder.create(new JsonbConfig()
+                .setProperty("johnzon.supportsPrivateAccess", "true"))) {
+            assertEquals("ok", jsonb.fromJson("{\"foo\":\"ok\"}", 
InstantiablePackageCons.class).value);
+        }
+    }
+
     public static class PackageCons {
         public String value;
 
@@ -40,4 +55,13 @@ public class ConstructorVisibilityTest {
             // no-op
         }
     }
+
+    public static class InstantiablePackageCons {
+        public String value;
+
+        @JsonbCreator
+        InstantiablePackageCons(@JsonbProperty("foo") final String foo) {
+            this.value = foo;
+        }
+    }
 }
diff --git a/src/site/markdown/index.md b/src/site/markdown/index.md
index 764c722..3f30aaa 100644
--- a/src/site/markdown/index.md
+++ b/src/site/markdown/index.md
@@ -314,6 +314,15 @@ JsonbConfig specific properties:
 * johnzon.support-enum-container-deserialization: prevent EnumMap/EnumSet 
instantiation, true by default.
 * johnzon.attributeOrder: Comparator instance to sort properties by name.
 * johnzon.deduplicateObjects: should instances be deduplicated.
+* johnzon.supportsPrivateAccess: should private constructors/methods with 
`@JsonbCreator` be used too.
+* johnzon.fail-on-unknown-properties: should unmapped properties fail the 
mapping. Similar to `jsonb.fail-on-unknown-properties`.
+* johnzon.readAttributeBeforeWrite: should collection be read before being 
written, it enables to have an "append" mode.
+* johnzon.autoAdjustBuffer: should internal read buffers be autoadjusted to 
stay fixed.
+* johnzon.serialize-value-filter: enable to set a filter to not serialize some 
values.
+* johnzon.cdi.activated: should cdi support be active.
+* johnzon.accessMode: custom access mode, note that it can disable some JSON-B 
feature (annotations support).
+* johnzon.accessModeDelegate: delegate access mode used by JsonbAccessModel. 
Enables to enrich default access mode.
+* johnzon.failOnMissingCreatorValues: should the mapping fail when a 
`@JsonbCreator` misses some values.
 
 TIP: more in JohnzonBuilder class.
 

Reply via email to