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

Reply via email to