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

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

commit de6398935587f57e88300fd434a9335a7a195f46
Author: Jean-Louis Monteiro <[email protected]>
AuthorDate: Thu Apr 22 13:58:09 2021 +0200

    Fix some enum conversion with the EL Processor
---
 .../tomee/security/TomEEELInvocationHandler.java   | 58 +++++++++++++++++++++-
 .../security/TomEEELInvocationHandlerTest.java     |  6 ++-
 2 files changed, 62 insertions(+), 2 deletions(-)

diff --git 
a/tomee/tomee-security/src/main/java/org/apache/tomee/security/TomEEELInvocationHandler.java
 
b/tomee/tomee-security/src/main/java/org/apache/tomee/security/TomEEELInvocationHandler.java
index 1faddd3..3393788 100644
--- 
a/tomee/tomee-security/src/main/java/org/apache/tomee/security/TomEEELInvocationHandler.java
+++ 
b/tomee/tomee-security/src/main/java/org/apache/tomee/security/TomEEELInvocationHandler.java
@@ -19,6 +19,7 @@ package org.apache.tomee.security;
 import javax.el.ELProcessor;
 import javax.enterprise.inject.spi.BeanManager;
 import java.lang.annotation.Annotation;
+import java.lang.reflect.Array;
 import java.lang.reflect.InvocationHandler;
 import java.lang.reflect.InvocationTargetException;
 import java.lang.reflect.Method;
@@ -70,7 +71,62 @@ public class TomEEELInvocationHandler implements 
InvocationHandler {
         // expression maybe #{expression} instead of ${expression}
         // the ELProcessor anyways wraps it with ${}
         final String sanitizedExpression = 
expression.replaceAll("^[#$]\\{(.+)}$", "$1");
-        return processor.getValue(sanitizedExpression, expectedType);
+
+        // ELProcessor does not do a good job with enums, so try to be a bit 
better (not sure)
+        // otherwise, let the EL processor do its best to convert into the 
expected value
+        if (!isEnumOrArrayOfEnums(expectedType)) {
+            return processor.getValue(sanitizedExpression, expectedType);
+        }
+
+        final Object value = processor.getValue(sanitizedExpression, 
Object.class);
+
+        // Convert single enum name to single enum
+        if (expectedType.isEnum()  && value instanceof String) {
+            // yeah could use Enum.valueOf ....
+            return of(expectedType, value);
+        }
+
+        // Convert single enum name to enum array (multiple enum values not 
supported)
+        if (expectedType.isArray()  && value instanceof String) {
+            final Class<?> enumType = expectedType.getComponentType();
+
+            if (enumType.isEnum()) { // just in case
+                final Enum<?> enumConstant = (Enum<?>) of(enumType, value);
+                final Enum<?>[] outcomeArray = (Enum<?>[]) 
Array.newInstance(enumType, 1);
+                outcomeArray[0] = enumConstant;
+
+                return outcomeArray;
+            }
+
+            // else not sure what else we can do but let the Object go
+
+        }
+
+        return value;
+    }
+
+    private boolean isEnumOrArrayOfEnums(final Class type) {
+        if (type.isEnum()) {
+            return true;
+        }
+
+        if (type.isArray()) {
+            final Class componentType = type.getComponentType();
+            return componentType.isEnum();
+        }
+
+        return false;
+    }
+
+    private <T /*extends Enum<T>*/> T of(final Class<T> type, final Object 
name) {
+        try {
+            return (T) type.getDeclaredMethod("valueOf", 
String.class).invoke(null, name);
+
+        } catch (final Exception e) {
+            // this will most likely result in a conversion error, but at 
least we know
+            // it won't be swallowed
+            return (T) name;
+        }
     }
 
     public static <T extends Annotation> T of(final Class<T> annotationClass, 
final T annotation, final BeanManager beanManager) {
diff --git 
a/tomee/tomee-security/src/test/java/org/apache/tomee/security/TomEEELInvocationHandlerTest.java
 
b/tomee/tomee-security/src/test/java/org/apache/tomee/security/TomEEELInvocationHandlerTest.java
index 3516527..80db047 100644
--- 
a/tomee/tomee-security/src/test/java/org/apache/tomee/security/TomEEELInvocationHandlerTest.java
+++ 
b/tomee/tomee-security/src/test/java/org/apache/tomee/security/TomEEELInvocationHandlerTest.java
@@ -25,6 +25,7 @@ import javax.enterprise.inject.Vetoed;
 import javax.enterprise.inject.spi.BeanManager;
 import javax.enterprise.inject.spi.CDI;
 import javax.security.enterprise.identitystore.DatabaseIdentityStoreDefinition;
+import javax.security.enterprise.identitystore.IdentityStore;
 import javax.security.enterprise.identitystore.PasswordHash;
 import java.lang.reflect.InvocationHandler;
 import java.util.Map;
@@ -46,6 +47,7 @@ public class TomEEELInvocationHandlerTest extends 
AbstractTomEESecurityTest {
         Assert.assertEquals(90, proxiedAnnotation.priority());
 
         Assert.assertEquals("90", proxiedAnnotation.priorityExpression());
+        Assert.assertArrayEquals(new IdentityStore.ValidationType[] 
{IdentityStore.ValidationType.VALIDATE}, proxiedAnnotation.useFor());
 
     }
 
@@ -58,7 +60,9 @@ public class TomEEELInvocationHandlerTest extends 
AbstractTomEESecurityTest {
                                      callerQuery = "select password from 
caller where name = ?",
                                      groupsQuery = "select group_name from 
caller_groups where caller_name = ?",
                                      hashAlgorithm = 
CleartextPasswordHash.class,
-                                     priority = 30, priorityExpression = "90")
+                                     priority = 30,
+                                     priorityExpression = "90",
+                                     useForExpression = "#{'VALIDATE'}")
     public static class Color {
     }
 

Reply via email to