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 <[email protected]>
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.