You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@commons.apache.org by gg...@apache.org on 2019/10/24 19:25:11 UTC

[commons-beanutils] branch master updated: [BEANUTILS-346] New converter for Enum (#16)

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

ggregory pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/commons-beanutils.git


The following commit(s) were added to refs/heads/master by this push:
     new 55dcbaa  [BEANUTILS-346] New converter for Enum (#16)
55dcbaa is described below

commit 55dcbaa944b8f677c45831c6198e8c1c75bbf7f1
Author: Melloware <me...@gmail.com>
AuthorDate: Thu Oct 24 15:25:02 2019 -0400

    [BEANUTILS-346] New converter for Enum (#16)
    
    * [BEANUTILS-346] New converter for Enum
    
    * [BEANUTILS-346] New converter for Enum
    
    * [BEANUTILS-346] Code review comments.
    
    * [BEANUTILS-346] Code review comments.
---
 src/changes/changes.xml                            |   3 +
 .../commons/beanutils2/ConvertUtilsBean.java       |   7 +-
 .../beanutils2/converters/EnumConverter.java       |  93 +++++++++++++++++
 .../converters/EnumConverterTestCase.java          | 114 +++++++++++++++++++++
 4 files changed, 216 insertions(+), 1 deletion(-)

diff --git a/src/changes/changes.xml b/src/changes/changes.xml
index d841b8a..80876c2 100644
--- a/src/changes/changes.xml
+++ b/src/changes/changes.xml
@@ -30,6 +30,9 @@
   <body>
 
     <release version="2.0.0" date="2018-MM-DD" description="Update to Java 8.">
+      <action issue="BEANUTILS-346" dev="melloware" type="update" due-to="Melloware">
+        New converter for Enum.
+      </action>
       <action issue="BEANUTILS-402" dev="melloware" type="update" due-to="Melloware">
         Double-Checked Locking anti pattern in WeakFastHashMap.
       </action>
diff --git a/src/main/java/org/apache/commons/beanutils2/ConvertUtilsBean.java b/src/main/java/org/apache/commons/beanutils2/ConvertUtilsBean.java
index cd9d36b..43ec1bf 100644
--- a/src/main/java/org/apache/commons/beanutils2/ConvertUtilsBean.java
+++ b/src/main/java/org/apache/commons/beanutils2/ConvertUtilsBean.java
@@ -55,6 +55,7 @@ import org.apache.commons.beanutils2.converters.ClassConverter;
 import org.apache.commons.beanutils2.converters.ConverterFacade;
 import org.apache.commons.beanutils2.converters.DateConverter;
 import org.apache.commons.beanutils2.converters.DoubleConverter;
+import org.apache.commons.beanutils2.converters.EnumConverter;
 import org.apache.commons.beanutils2.converters.DurationConverter;
 import org.apache.commons.beanutils2.converters.FileConverter;
 import org.apache.commons.beanutils2.converters.FloatConverter;
@@ -105,6 +106,7 @@ import org.apache.commons.logging.LogFactory;
  * <li>long and java.lang.Long (default to zero)</li>
  * <li>short and java.lang.Short (default to zero)</li>
  * <li>java.lang.String (default to null)</li>
+ * <li>java.lang.Enum (default to null)</li>
  * <li>java.io.File (no default value)</li>
  * <li>java.nio.file.Path (no default value)</li>
  * <li>java.net.URL (no default value)</li>
@@ -489,6 +491,7 @@ public class ConvertUtilsBean {
      * This method registers the following converters:
      * <ul>
      *     <li><code>Class.class</code> - {@link ClassConverter}</li>
+     *     <li><code>Enum.class</code> - {@link EnumConverter}</li>
      *     <li><code>java.util.Date.class</code> - {@link DateConverter}</li>
      *     <li><code>java.util.Calendar.class</code> - {@link CalendarConverter}</li>
      *     <li><code>File.class</code> - {@link FileConverter}</li>
@@ -518,8 +521,9 @@ public class ConvertUtilsBean {
      * <code>false</code> if a default value should be used.
      */
     private void registerOther(final boolean throwException) {
-    	// @formatter:off
+    	  // @formatter:off
         register(Class.class,          throwException ? new ClassConverter()          : new ClassConverter(null));
+        register(Enum.class,           throwException ? new EnumConverter()           : new EnumConverter(null));
         register(java.util.Date.class, throwException ? new DateConverter()           : new DateConverter(null));
         register(Calendar.class,       throwException ? new CalendarConverter()       : new CalendarConverter(null));
         register(File.class,           throwException ? new FileConverter()           : new FileConverter(null));
@@ -585,6 +589,7 @@ public class ConvertUtilsBean {
 
         // Other
         registerArrayConverter(Class.class,          new ClassConverter(),         throwException, defaultArraySize);
+        registerArrayConverter(Enum.class,           new EnumConverter(),          throwException, defaultArraySize);
         registerArrayConverter(java.util.Date.class, new DateConverter(),          throwException, defaultArraySize);
         registerArrayConverter(Calendar.class,       new DateConverter(),          throwException, defaultArraySize);
         registerArrayConverter(File.class,           new FileConverter(),          throwException, defaultArraySize);
diff --git a/src/main/java/org/apache/commons/beanutils2/converters/EnumConverter.java b/src/main/java/org/apache/commons/beanutils2/converters/EnumConverter.java
new file mode 100644
index 0000000..2fe8d77
--- /dev/null
+++ b/src/main/java/org/apache/commons/beanutils2/converters/EnumConverter.java
@@ -0,0 +1,93 @@
+/*
+ * 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.commons.beanutils2.converters;
+
+
+/**
+ * {@link org.apache.commons.beanutils2.Converter} implementation that handles conversion
+ * to and from <b>java.lang.Enum</b> objects.
+ * <p>
+ * Can be configured to either return a <i>default value</i> or throw a
+ * {@code ConversionException} if a conversion error occurs.
+ * </p>
+ *
+ * @since 2.0
+ * @see java.lang.Enum
+ */
+public final class EnumConverter extends AbstractConverter {
+
+    /**
+     * Construct a <b>java.lang.Enum</b> <i>Converter</i> that throws
+     * a {@code ConversionException} if an error occurs.
+     */
+    public EnumConverter() {
+        super();
+    }
+
+    /**
+     * Construct a <b>java.lang.Enum</b> <i>Converter</i> that returns
+     * a default value if an error occurs.
+     *
+     * @param defaultValue The default value to be returned
+     * if the value to be converted is missing or an error
+     * occurs converting the value.
+     */
+    public EnumConverter(final Object defaultValue) {
+        super(defaultValue);
+    }
+
+    /**
+     * Return the default type this {@code Converter} handles.
+     *
+     * @return The default type this {@code Converter} handles.
+     * @since 2.0
+     */
+    @Override
+    protected Class<?> getDefaultType() {
+        return Enum.class;
+    }
+
+    /**
+     * <p>Convert a java.lang.Enum or object into a String.</p>
+     *
+     * @param <T> Target type of the conversion.
+     * @param type Data type to which this value should be converted.
+     * @param value The input value to be converted.
+     * @return The converted value.
+     * @throws Throwable if an error occurs converting to the specified type
+     * @since 2.0
+     */
+    @SuppressWarnings({ "rawtypes" })
+    @Override
+    protected <T> T  convertToType(final Class<T> type, final Object value) throws Throwable {
+        if (Enum.class.isAssignableFrom(type)) {
+            final String enumValue = String.valueOf(value);
+            final T[] constants = type.getEnumConstants();
+            if (constants == null) {
+                throw conversionException(type, value);
+            }
+            for (final T candidate : constants) {
+                if (((Enum)candidate).name().equalsIgnoreCase(enumValue)) {
+                    return candidate;
+                }
+            }
+        }
+
+        throw conversionException(type, value);
+    }
+
+}
diff --git a/src/test/java/org/apache/commons/beanutils2/converters/EnumConverterTestCase.java b/src/test/java/org/apache/commons/beanutils2/converters/EnumConverterTestCase.java
new file mode 100644
index 0000000..3a100b9
--- /dev/null
+++ b/src/test/java/org/apache/commons/beanutils2/converters/EnumConverterTestCase.java
@@ -0,0 +1,114 @@
+/*
+ * 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.commons.beanutils2.converters;
+
+
+
+import org.apache.commons.beanutils2.ConversionException;
+import org.apache.commons.beanutils2.Converter;
+
+import junit.framework.TestCase;
+import junit.framework.TestSuite;
+
+
+/**
+ * Test Case for the EnumConverter class.
+ *
+ */
+public class EnumConverterTestCase extends TestCase {
+
+    public static TestSuite suite() {
+        return new TestSuite(EnumConverterTestCase.class);
+    }
+
+    private Converter converter = null;
+
+    public EnumConverterTestCase(final String name) {
+        super(name);
+    }
+
+    protected Class<?> getExpectedType() {
+        return Enum.class;
+    }
+
+    protected Converter makeConverter() {
+        return new EnumConverter();
+    }
+
+    @Override
+    public void setUp() throws Exception {
+        converter = makeConverter();
+    }
+
+    @Override
+    public void tearDown() throws Exception {
+        converter = null;
+    }
+
+    public void testSimpleConversion() throws Exception {
+        final String[] message= {
+            "from String",
+            "from String",
+            "from String",
+            "from String",
+            "from String",
+            "from String",
+            "from String",
+            "from String",
+        };
+
+        final Object[] input = {
+        	"DELIVERED",
+        	"ORDERED",
+        	"READY"
+        };
+
+        final PizzaStatus[] expected = {
+        	PizzaStatus.DELIVERED,
+        	PizzaStatus.ORDERED,
+        	PizzaStatus.READY
+        };
+
+        for(int i=0;i<expected.length;i++) {
+            assertEquals(message[i] + " to Enum",expected[i],converter.convert(PizzaStatus.class,input[i]));
+        }
+
+        for(int i=0;i<expected.length;i++) {
+            assertEquals(input[i] + " to String", input[i], converter.convert(String.class, expected[i]));
+        }
+    }
+
+    /**
+     * Tests a conversion to an unsupported type.
+     */
+    public void testUnsupportedType() {
+        try {
+            converter.convert(Integer.class, "http://www.apache.org");
+            fail("Unsupported type could be converted!");
+        } catch (final ConversionException cex) {
+            // expected result
+        }
+    }
+
+    public enum PizzaStatus {
+        ORDERED,
+        READY,
+        DELIVERED;
+    }
+}
+