You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@wink.apache.org by bl...@apache.org on 2009/09/18 01:04:32 UTC

svn commit: r816403 - in /incubator/wink/trunk/wink-common/src: main/java/org/apache/wink/common/internal/registry/ValueConvertor.java test/java/org/apache/wink/common/internal/registry/ValueConvertorTest.java

Author: bluk
Date: Thu Sep 17 23:04:31 2009
New Revision: 816403

URL: http://svn.apache.org/viewvc?rev=816403&view=rev
Log:
Add fromString capabilities

Thanks Mike for the contribution.

See [WINK-194]

Added:
    incubator/wink/trunk/wink-common/src/test/java/org/apache/wink/common/internal/registry/ValueConvertorTest.java   (with props)
Modified:
    incubator/wink/trunk/wink-common/src/main/java/org/apache/wink/common/internal/registry/ValueConvertor.java

Modified: incubator/wink/trunk/wink-common/src/main/java/org/apache/wink/common/internal/registry/ValueConvertor.java
URL: http://svn.apache.org/viewvc/incubator/wink/trunk/wink-common/src/main/java/org/apache/wink/common/internal/registry/ValueConvertor.java?rev=816403&r1=816402&r2=816403&view=diff
==============================================================================
--- incubator/wink/trunk/wink-common/src/main/java/org/apache/wink/common/internal/registry/ValueConvertor.java (original)
+++ incubator/wink/trunk/wink-common/src/main/java/org/apache/wink/common/internal/registry/ValueConvertor.java Thu Sep 17 23:04:31 2009
@@ -113,11 +113,45 @@
         } else if (classType.equals(Set.class)) {
             return new SetConvertor(getSingleValueConvertor(GenericsUtils
                 .getGenericParamType(genericType)));
+        } else if (classType.isEnum()) {
+            return getEnumValueConvertor(classType);
         } else {
             return getSingleValueConvertor(classType);
         }
     }
 
+    private static ValueConvertor getEnumValueConvertor(Class<?> classType) {
+        if (classType == null) {
+            return null;
+        }
+
+        // see JAX-RS 1.1 C006:
+        // http://jcp.org/aboutJava/communityprocess/maintenance/jsr311/311ChangeLog.html
+        // precendence for enums is fromString, then valueOf
+        try {
+            Method valueOf = classType.getDeclaredMethod("fromString", String.class);
+            return new FromStringConvertor(valueOf);
+        } catch (SecurityException e) {
+        } catch (NoSuchMethodException e) {
+            try {
+                Method fromString = classType.getDeclaredMethod("valueOf", String.class);
+                return new ValueOfConvertor(fromString);
+            } catch (SecurityException e2) {
+            } catch (NoSuchMethodException e2) {
+            }
+        }
+
+        try {
+            Constructor<?> constructor = classType.getConstructor(String.class);
+            return new ConstructorConvertor(constructor);
+        } catch (SecurityException e) {
+        } catch (NoSuchMethodException e) {
+        }
+
+        throw new IllegalArgumentException("type '" + classType
+            + "' is not a supported resource method parameter");
+    }
+
     private static ValueConvertor getSingleValueConvertor(Class<?> classType) {
         if (classType.equals(String.class)) {
             return new StringConvertor();
@@ -142,6 +176,15 @@
             return new ValueOfConvertor(valueOf);
         } catch (SecurityException e) {
         } catch (NoSuchMethodException e) {
+            // see JAX-RS 1.1 C006:
+            // http://jcp.org/aboutJava/communityprocess/maintenance/jsr311/311ChangeLog.html
+            // fallback to fromString method when no valueOf method exists
+            try {
+                Method fromString = classType.getDeclaredMethod("fromString", String.class);
+                return new FromStringConvertor(fromString);
+            } catch (SecurityException e2) {
+            } catch (NoSuchMethodException e2) {
+            }
         }
 
         try {
@@ -258,6 +301,18 @@
         }
     }
 
+    /**
+     * FromStringConvertor class exists only to make it obvious which method we
+     * picked up from the custom *Param type being converted See
+     * http://jcp.org/aboutJava
+     * /communityprocess/maintenance/jsr311/311ChangeLog.html C006
+     */
+    private static class FromStringConvertor extends ValueOfConvertor {
+        public FromStringConvertor(Method method) {
+            super(method);
+        }
+    }
+
     private static class StringConvertor extends SingleValueConvertor {
 
         @Override

Added: incubator/wink/trunk/wink-common/src/test/java/org/apache/wink/common/internal/registry/ValueConvertorTest.java
URL: http://svn.apache.org/viewvc/incubator/wink/trunk/wink-common/src/test/java/org/apache/wink/common/internal/registry/ValueConvertorTest.java?rev=816403&view=auto
==============================================================================
--- incubator/wink/trunk/wink-common/src/test/java/org/apache/wink/common/internal/registry/ValueConvertorTest.java (added)
+++ incubator/wink/trunk/wink-common/src/test/java/org/apache/wink/common/internal/registry/ValueConvertorTest.java Thu Sep 17 23:04:31 2009
@@ -0,0 +1,117 @@
+/*******************************************************************************
+ * 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.wink.common.internal.registry;
+
+import junit.framework.TestCase;
+
+public class ValueConvertorTest extends TestCase {
+
+    /**
+     * custom type with both valueOf and fromString methods
+     */
+    static class CustomType {
+
+        private String _value = "";
+
+        public CustomType(String value) {
+            _value = value;
+        }
+
+        static CustomType valueOf(String value) {
+            return new CustomType(value + "_valueOf");
+        }
+
+        static CustomType fromString(String value) {
+            return new CustomType(value + "_fromString");
+        }
+
+        public String toString() {
+            return _value;
+        }
+    }
+
+    /**
+     * custom type with fromString method only
+     */
+    static class CustomTypeNoValueOf {
+        private String _value = "";
+
+        public CustomTypeNoValueOf(String value) {
+            _value = value;
+        }
+
+        static CustomTypeNoValueOf fromString(String value) {
+            return new CustomTypeNoValueOf(value + "_fromString");
+        }
+
+        public String toString() {
+            return _value;
+        }
+    }
+
+    /**
+     * enum with implicit valueOf method only
+     */
+    enum MyEnum {
+        SUNDAY, SATURDAY;
+    }
+
+    /**
+     * enum with fromString method only
+     */
+    enum MyEnumWithFromString {
+        SUNDAY, SATURDAY, SUNDAY_fromString, SATURDAY_fromString;
+
+        public static MyEnumWithFromString fromString(String val) {
+            return valueOf(val + "_fromString");
+        }
+    }
+
+    // make sure "valueOf" is favored over "fromString"
+    public void testConvertorPrecedence() throws Exception {
+        ValueConvertor valueOfConvertor =
+            ValueConvertor.createConcreteValueConvertor(CustomType.class, CustomType.class);
+        assertEquals("VALUE_valueOf", valueOfConvertor.convert("VALUE").toString());
+    }
+
+    // make sure fallback to "fromString" if no "valueOf" method is found
+    public void testConvertorPrecedenceNoValueOf() throws Exception {
+        ValueConvertor fromStringConvertor =
+            ValueConvertor.createConcreteValueConvertor(CustomTypeNoValueOf.class,
+                                                        CustomTypeNoValueOf.class);
+        assertEquals("VALUE_fromString", fromStringConvertor.convert("VALUE").toString());
+    }
+
+    // make sure default enum conversion continues to work
+    public void testEnumConvertorDefault() throws Exception {
+        ValueConvertor fromStringConvertor =
+            ValueConvertor.createValueConvertor(MyEnum.class, MyEnum.class);
+        assertEquals(MyEnum.SUNDAY, fromStringConvertor.convert("SUNDAY"));
+    }
+
+    // make sure "fromString" is favored over "valueOf" for enums
+    public void testEnumConvertorPrecedence() throws Exception {
+        ValueConvertor fromStringConvertor =
+            ValueConvertor.createValueConvertor(MyEnumWithFromString.class,
+                                                MyEnumWithFromString.class);
+        assertEquals(MyEnumWithFromString.SUNDAY_fromString, fromStringConvertor.convert("SUNDAY"));
+    }
+
+}

Propchange: incubator/wink/trunk/wink-common/src/test/java/org/apache/wink/common/internal/registry/ValueConvertorTest.java
------------------------------------------------------------------------------
    svn:eol-style = native