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

davsclaus pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/camel.git


The following commit(s) were added to refs/heads/main by this push:
     new 69a3865f7b0 CAMEL-14631: camel-core - Add support for custom enum 
converterts that are converted via a specialed converter method that are not 
using string based enum constant values. Thanks to Ralf Claussnitzer for 
reporting and unit tests.
69a3865f7b0 is described below

commit 69a3865f7b09dccf52aed28dad7af9318c7d8850
Author: Claus Ibsen <claus.ib...@gmail.com>
AuthorDate: Tue Jun 7 14:41:22 2022 +0200

    CAMEL-14631: camel-core - Add support for custom enum converterts that are 
converted via a specialed converter method that are not using string based enum 
constant values. Thanks to Ralf Claussnitzer for reporting and unit tests.
---
 .../camel/impl/converter/EnumTypeConverter.java    | 25 +++++++-
 .../camel/converter/BasicEnumConverterTest.java    | 56 +++++++++++++++++
 .../converter/CustomEnumTypeConverterTest.java     | 73 ++++++++++++++++++++++
 .../java/org/apache/camel/util/ObjectHelper.java   | 25 ++++++++
 4 files changed, 177 insertions(+), 2 deletions(-)

diff --git 
a/core/camel-base/src/main/java/org/apache/camel/impl/converter/EnumTypeConverter.java
 
b/core/camel-base/src/main/java/org/apache/camel/impl/converter/EnumTypeConverter.java
index f047908f310..3fa3adf57c7 100644
--- 
a/core/camel-base/src/main/java/org/apache/camel/impl/converter/EnumTypeConverter.java
+++ 
b/core/camel-base/src/main/java/org/apache/camel/impl/converter/EnumTypeConverter.java
@@ -17,7 +17,10 @@
 package org.apache.camel.impl.converter;
 
 import org.apache.camel.Exchange;
+import org.apache.camel.TypeConverter;
+import org.apache.camel.spi.TypeConverterRegistry;
 import org.apache.camel.support.TypeConverterSupport;
+import org.apache.camel.util.ObjectHelper;
 import org.apache.camel.util.StringHelper;
 
 /**
@@ -27,12 +30,30 @@ public class EnumTypeConverter extends TypeConverterSupport 
{
 
     @Override
     public <T> T convertTo(Class<T> type, Exchange exchange, Object value) {
-        return EnumTypeConverter.doConvertTo(type, exchange, value);
+        return doConvertTo(type, exchange, value);
     }
 
     @SuppressWarnings("unchecked")
-    public static <T> T doConvertTo(Class<T> type, Exchange exchange, Object 
value) {
+    private <T> T doConvertTo(Class<T> type, Exchange exchange, Object value) {
         if (type.isEnum()) {
+            // is there a direct enum type converter
+            TypeConverterRegistry tcr = exchange != null ? 
exchange.getContext().getTypeConverterRegistry() : null;
+            if (tcr != null) {
+                Class<?> fromType = value.getClass();
+                TypeConverter tc = tcr.lookup(type, value.getClass());
+                if (tc == null) {
+                    // no direct converter but the enum may be a 
wrapper/primitive variant so try to lookup again
+                    Class<?> primitiveType = 
ObjectHelper.convertWrapperTypeToPrimitiveType(fromType);
+                    if (fromType != primitiveType) {
+                        tc = tcr.lookup(type, primitiveType);
+                    }
+                }
+                if (tc != null) {
+                    return tc.convertTo(type, exchange, value);
+                }
+            }
+
+            // convert to enum via its string based enum constant
             String text = value.toString();
             Class<Enum<?>> enumClass = (Class<Enum<?>>) type;
 
diff --git 
a/core/camel-core/src/test/java/org/apache/camel/converter/BasicEnumConverterTest.java
 
b/core/camel-core/src/test/java/org/apache/camel/converter/BasicEnumConverterTest.java
new file mode 100644
index 00000000000..0b688ecf540
--- /dev/null
+++ 
b/core/camel-core/src/test/java/org/apache/camel/converter/BasicEnumConverterTest.java
@@ -0,0 +1,56 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.camel.converter;
+
+import org.apache.camel.impl.converter.EnumTypeConverter;
+import org.junit.jupiter.api.Test;
+
+import static org.junit.jupiter.api.Assertions.assertEquals;
+
+public class BasicEnumConverterTest {
+
+    private final EnumTypeConverter converter = new EnumTypeConverter();
+
+    @Test
+    public void testConvertFromString() {
+        StatusCodeEnum code = converter.convertTo(StatusCodeEnum.class, "OK");
+        assertEquals(code, StatusCodeEnum.OK, "String should be converted to 
corresponding Enum value");
+    }
+
+    @Test
+    public void testConvertFromStringCaseInsensitive() {
+        StatusCodeEnum code = converter.convertTo(StatusCodeEnum.class, "ok");
+        assertEquals(StatusCodeEnum.OK, code, "Lower case string should be 
converted to corresponding Enum value");
+    }
+
+    @Test
+    public void testConvertFromCamelCasedString() {
+        StatusCodeEnum code = converter.convertTo(StatusCodeEnum.class, 
"NotFound");
+        assertEquals(StatusCodeEnum.NOT_FOUND, code, "Camel cased string 
should be converted to corresponding Enum value");
+    }
+
+    @Test
+    public void testConvertFromDashedString() {
+        StatusCodeEnum code = converter.convertTo(StatusCodeEnum.class, 
"not-found");
+        assertEquals(StatusCodeEnum.NOT_FOUND, code, "Dashed string should be 
converted to corresponding Enum value");
+    }
+
+    private enum StatusCodeEnum {
+        OK,
+        NOT_FOUND;
+    }
+}
diff --git 
a/core/camel-core/src/test/java/org/apache/camel/converter/CustomEnumTypeConverterTest.java
 
b/core/camel-core/src/test/java/org/apache/camel/converter/CustomEnumTypeConverterTest.java
new file mode 100644
index 00000000000..e99f29af54d
--- /dev/null
+++ 
b/core/camel-core/src/test/java/org/apache/camel/converter/CustomEnumTypeConverterTest.java
@@ -0,0 +1,73 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.camel.converter;
+
+import org.apache.camel.ContextTestSupport;
+import org.apache.camel.Converter;
+import org.apache.camel.Exchange;
+import org.apache.camel.TypeConverters;
+import org.apache.camel.support.DefaultExchange;
+import org.junit.jupiter.api.Test;
+
+import static org.junit.jupiter.api.Assertions.assertEquals;
+
+public class CustomEnumTypeConverterTest extends ContextTestSupport {
+
+    @Test
+    public void testCustomEnumTypeConverterGetsCalled() {
+        CustomEnumTypeConverter customEnumTypeConverter = new 
CustomEnumTypeConverter();
+
+        
context.getTypeConverterRegistry().addTypeConverters(customEnumTypeConverter);
+
+        Exchange exchange = new DefaultExchange(context);
+
+        StatusCodeEnum result = 
context.getTypeConverter().convertTo(StatusCodeEnum.class, exchange, 200);
+        assertEquals(StatusCodeEnum.OK, result);
+
+        result = context.getTypeConverter().convertTo(StatusCodeEnum.class, 
exchange, 404);
+        assertEquals(StatusCodeEnum.NOT_FOUND, result);
+    }
+
+    public static class CustomEnumTypeConverter implements TypeConverters {
+        @Converter
+        public StatusCodeEnum toStatusCodeEnum(int i) {
+            return StatusCodeEnum.fromCode(i);
+        }
+    }
+
+    public enum StatusCodeEnum {
+        OK(200),
+        NOT_FOUND(404);
+
+        private final int statusCode;
+
+        StatusCodeEnum(int statusCode) {
+            this.statusCode = statusCode;
+        }
+
+        static StatusCodeEnum fromCode(int statusCode) {
+            switch (statusCode) {
+                case 200:
+                    return OK;
+                case 404:
+                    return NOT_FOUND;
+                default:
+                    throw new IllegalArgumentException();
+            }
+        }
+    }
+}
diff --git 
a/core/camel-util/src/main/java/org/apache/camel/util/ObjectHelper.java 
b/core/camel-util/src/main/java/org/apache/camel/util/ObjectHelper.java
index 261addc0bc2..e63f77cede1 100644
--- a/core/camel-util/src/main/java/org/apache/camel/util/ObjectHelper.java
+++ b/core/camel-util/src/main/java/org/apache/camel/util/ObjectHelper.java
@@ -979,6 +979,31 @@ public final class ObjectHelper {
         return rc;
     }
 
+    /**
+     * Converts wrapper type like {@link Integer} to its primitive type, i.e. 
int.
+     */
+    public static Class<?> convertWrapperTypeToPrimitiveType(Class<?> type) {
+        Class<?> rc = type;
+        if (type == Integer.class) {
+            rc = int.class;
+        } else if (type == Long.class) {
+            rc = long.class;
+        } else if (type == Double.class) {
+            rc = double.class;
+        } else if (type == Float.class) {
+            rc = float.class;
+        } else if (type == Short.class) {
+            rc = short.class;
+        } else if (type == Byte.class) {
+            rc = byte.class;
+        } else if (type == Boolean.class) {
+            rc = boolean.class;
+        } else if (type == Character.class) {
+            rc = char.class;
+        }
+        return rc;
+    }
+
     /**
      * Helper method to return the default character set name
      */

Reply via email to