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 */