You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@johnzon.apache.org by rm...@apache.org on 2019/08/10 10:49:53 UTC
[johnzon] branch master updated: JOHNZON-235 ensure @JsonbCreator
is validated even when the factory is not static
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 2961aa8 JOHNZON-235 ensure @JsonbCreator is validated even when the factory is not static
2961aa8 is described below
commit 2961aa8f73ab4793810b07a4125f3a7daebc31ac
Author: Romain Manni-Bucau <rm...@apache.org>
AuthorDate: Sat Aug 10 12:49:48 2019 +0200
JOHNZON-235 ensure @JsonbCreator is validated even when the factory is not static
---
.../org/apache/johnzon/jsonb/JsonbAccessMode.java | 173 ++++++++++++---------
1 file changed, 100 insertions(+), 73 deletions(-)
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 2a396e3..fcedbc5 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
@@ -173,16 +173,16 @@ public class JsonbAccessMode implements AccessMode, Closeable {
for (final Constructor<?> c : clazz.getConstructors()) {
if (c.isAnnotationPresent(JsonbCreator.class)) {
if (constructor != null) {
- throw new IllegalArgumentException("Only one constructor or method can have @JsonbCreator");
+ throw new JsonbException("Only one constructor or method can have @JsonbCreator");
}
constructor = c;
}
}
for (final Method m : clazz.getMethods()) {
final int modifiers = m.getModifiers();
- if (Modifier.isStatic(modifiers) && Modifier.isPublic(modifiers) && m.isAnnotationPresent(JsonbCreator.class)) {
+ if (Modifier.isPublic(modifiers) && m.isAnnotationPresent(JsonbCreator.class)) {
if (constructor != null || factory != null) {
- throw new IllegalArgumentException("Only one constructor or method can have @JsonbCreator");
+ throw new JsonbException("Only one constructor or method can have @JsonbCreator");
}
factory = m;
}
@@ -254,86 +254,113 @@ public class JsonbAccessMode implements AccessMode, Closeable {
return constructor == null && factory == null ? delegate.findFactory(clazz) : (
constructor != null ?
- new Factory() {
- @Override
- public Object create(final Object[] params) {
- factoryValidator.accept(params);
- try {
- return finalConstructor.newInstance(params);
- } catch (final InstantiationException | IllegalAccessException e) {
- throw new IllegalStateException(e);
- } catch (final InvocationTargetException e) {
- throw new IllegalStateException(e.getCause());
- }
- }
+ constructorFactory(finalConstructor, factoryValidator, types, params, converters, itemConverters, objectConverters) :
+ methodFactory(clazz, finalFactory, factoryValidator, types, params, converters, itemConverters, objectConverters));
+ }
- @Override
- public Type[] getParameterTypes() {
- return types;
- }
+ private Factory methodFactory(final Class<?> clazz, final Method finalFactory,
+ final Consumer<Object[]> factoryValidator, final Type[] types,
+ final String[] params, final Adapter<?, ?>[] converters,
+ final Adapter<?, ?>[] itemConverters, final ObjectConverter.Codec<?>[] objectConverters) {
+ final Object instance = Modifier.isStatic(finalFactory.getModifiers()) ?
+ null : tryToCreateInstance(finalFactory.getDeclaringClass());
+ return new Factory() {
+ @Override
+ public Object create(final Object[] params) {
+ factoryValidator.accept(params);
+ try {
+ final Object invoke = finalFactory.invoke(instance, params);
+ if (!clazz.isInstance(invoke)) {
+ throw new IllegalArgumentException(invoke + " is not a " + clazz.getName());
+ }
+ return invoke;
+ } catch (final IllegalAccessException e) {
+ throw new IllegalStateException(e);
+ } catch (final InvocationTargetException e) {
+ throw new IllegalStateException(e.getCause());
+ }
+ }
- @Override
- public String[] getParameterNames() {
- return params;
- }
+ @Override
+ public Type[] getParameterTypes() {
+ return types;
+ }
- @Override
- public Adapter<?, ?>[] getParameterConverter() {
- return converters;
- }
+ @Override
+ public String[] getParameterNames() {
+ return params;
+ }
- @Override
- public Adapter<?, ?>[] getParameterItemConverter() {
- return itemConverters;
- }
+ @Override
+ public Adapter<?, ?>[] getParameterConverter() {
+ return converters;
+ }
- @Override
- public ObjectConverter.Codec<?>[] getObjectConverter() {
- return objectConverters;
- }
- } :
- new Factory() {
- @Override
- public Object create(final Object[] params) {
- factoryValidator.accept(params);
- try {
- final Object invoke = finalFactory.invoke(null, params);
- if (!clazz.isInstance(invoke)) {
- throw new IllegalArgumentException(invoke + " is not a " + clazz.getName());
- }
- return invoke;
- } catch (final IllegalAccessException e) {
- throw new IllegalStateException(e);
- } catch (final InvocationTargetException e) {
- throw new IllegalStateException(e.getCause());
- }
- }
+ @Override
+ public Adapter<?, ?>[] getParameterItemConverter() {
+ return itemConverters;
+ }
- @Override
- public Type[] getParameterTypes() {
- return types;
- }
+ @Override
+ public ObjectConverter.Codec<?>[] getObjectConverter() {
+ return objectConverters;
+ }
+ };
+ }
- @Override
- public String[] getParameterNames() {
- return params;
- }
+ private Object tryToCreateInstance(final Class<?> declaringClass) {
+ try {
+ final Constructor<?> declaredConstructor = declaringClass.getDeclaredConstructor();
+ if (!declaredConstructor.isAccessible()) {
+ declaredConstructor.setAccessible(true);
+ }
+ return declaredConstructor.newInstance();
+ } catch (final Exception e) {
+ return null;
+ }
+ }
- @Override
- public Adapter<?, ?>[] getParameterConverter() {
- return converters;
- }
+ private Factory constructorFactory(final Constructor<?> finalConstructor, final Consumer<Object[]> factoryValidator,
+ final Type[] types, final String[] params, final Adapter<?, ?>[] converters,
+ final Adapter<?, ?>[] itemConverters, final ObjectConverter.Codec<?>[] objectConverters) {
+ return new Factory() {
+ @Override
+ public Object create(final Object[] params) {
+ factoryValidator.accept(params);
+ try {
+ return finalConstructor.newInstance(params);
+ } catch (final InstantiationException | IllegalAccessException e) {
+ throw new IllegalStateException(e);
+ } catch (final InvocationTargetException e) {
+ throw new IllegalStateException(e.getCause());
+ }
+ }
- @Override
- public Adapter<?, ?>[] getParameterItemConverter() {
- return itemConverters;
- }
+ @Override
+ public Type[] getParameterTypes() {
+ return types;
+ }
- @Override
- public ObjectConverter.Codec<?>[] getObjectConverter() {
- return objectConverters;
- }
- });
+ @Override
+ public String[] getParameterNames() {
+ return params;
+ }
+
+ @Override
+ public Adapter<?, ?>[] getParameterConverter() {
+ return converters;
+ }
+
+ @Override
+ public Adapter<?, ?>[] getParameterItemConverter() {
+ return itemConverters;
+ }
+
+ @Override
+ public ObjectConverter.Codec<?>[] getObjectConverter() {
+ return objectConverters;
+ }
+ };
}
private void validateAnnotations(final Object parameter,