Author: scheu
Date: Mon May  3 19:46:00 2010
New Revision: 940586

URL: http://svn.apache.org/viewvc?rev=940586&view=rev
Log:
AXIS2-4701
Contributor:Rich Scheuerle
Support JAXB enums that lack certain annotations or generated methods...also 
added unit tests of new code.

Added:
    
axis/axis2/java/core/trunk/modules/jaxws/src/org/apache/axis2/jaxws/utility/XmlEnumUtils.java
    
axis/axis2/java/core/trunk/modules/jaxws/test/org/apache/axis2/jaxws/misc/EnumSample.java
    
axis/axis2/java/core/trunk/modules/jaxws/test/org/apache/axis2/jaxws/misc/EnumSample2.java
    
axis/axis2/java/core/trunk/modules/jaxws/test/org/apache/axis2/jaxws/misc/EnumSample3.java
    
axis/axis2/java/core/trunk/modules/jaxws/test/org/apache/axis2/jaxws/misc/XmlEnumUtilsTest.java
Modified:
    
axis/axis2/java/core/trunk/modules/jaxws/src/org/apache/axis2/datasource/jaxb/JAXBDSContext.java

Modified: 
axis/axis2/java/core/trunk/modules/jaxws/src/org/apache/axis2/datasource/jaxb/JAXBDSContext.java
URL: 
http://svn.apache.org/viewvc/axis/axis2/java/core/trunk/modules/jaxws/src/org/apache/axis2/datasource/jaxb/JAXBDSContext.java?rev=940586&r1=940585&r2=940586&view=diff
==============================================================================
--- 
axis/axis2/java/core/trunk/modules/jaxws/src/org/apache/axis2/datasource/jaxb/JAXBDSContext.java
 (original)
+++ 
axis/axis2/java/core/trunk/modules/jaxws/src/org/apache/axis2/datasource/jaxb/JAXBDSContext.java
 Mon May  3 19:46:00 2010
@@ -30,6 +30,7 @@ import org.apache.axis2.jaxws.message.ut
 import org.apache.axis2.jaxws.spi.Constants;
 import org.apache.axis2.jaxws.utility.JavaUtils;
 import org.apache.axis2.jaxws.utility.XMLRootElementUtil;
+import org.apache.axis2.jaxws.utility.XmlEnumUtils;
 import org.apache.axis2.description.Parameter;
 import org.apache.commons.logging.Log;
 import org.apache.commons.logging.LogFactory;
@@ -603,12 +604,10 @@ public class JAXBDSContext {
                                         + " as Enum");
                             }
 
-                            JAXBElement<String> enumValue = 
u.unmarshal(reader, String.class);
+                            JAXBElement<String> enumValue = 
u.unmarshal(reader, XmlEnumUtils.getConversionType(type));
 
                             if (enumValue != null) {
-                                Method m =
-                                        type.getMethod("fromValue", new 
Class[] { String.class });
-                                jaxb = m.invoke(null, new Object[] { 
enumValue.getValue() });
+                                jaxb = XmlEnumUtils.fromValue(type, 
enumValue.getValue());
                             } else {
                                 jaxb = null;
                             }

Added: 
axis/axis2/java/core/trunk/modules/jaxws/src/org/apache/axis2/jaxws/utility/XmlEnumUtils.java
URL: 
http://svn.apache.org/viewvc/axis/axis2/java/core/trunk/modules/jaxws/src/org/apache/axis2/jaxws/utility/XmlEnumUtils.java?rev=940586&view=auto
==============================================================================
--- 
axis/axis2/java/core/trunk/modules/jaxws/src/org/apache/axis2/jaxws/utility/XmlEnumUtils.java
 (added)
+++ 
axis/axis2/java/core/trunk/modules/jaxws/src/org/apache/axis2/jaxws/utility/XmlEnumUtils.java
 Mon May  3 19:46:00 2010
@@ -0,0 +1,222 @@
+/*
+ * 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.axis2.jaxws.utility;
+
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
+import java.security.PrivilegedAction;
+import java.security.PrivilegedActionException;
+import java.security.PrivilegedExceptionAction;
+
+import javax.xml.bind.annotation.XmlEnum;
+
+import org.apache.axis2.java.security.AccessController;
+import org.apache.axis2.jaxws.ExceptionFactory;
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+
+/**
+ * Utility methods for JAXB Enum classes
+ */
+public class XmlEnumUtils {
+    private static final Log log = LogFactory.getLog(XmlEnumUtils.class);
+    /**
+     * Static Utility classes have private construcors
+     */
+    private XmlEnumUtils() {}
+    
+    /**
+     * @param e Class of enum 
+     * @return a base type that can be used for constructing the enum
+     */
+    public static Class getConversionType(final Class e) {
+        Class cls = null;
+        if (log.isDebugEnabled()) {
+            log.debug("getConversionType for " + e);
+        }
+        try {
+            cls = (Class)     
+                AccessController.doPrivileged(new PrivilegedAction() {
+                    public Object run() {
+                        // Look for forName method that is generated by JAXB.
+                        Method m = fromValueMethod(e, String.class);
+                        if (m != null) {
+                            return String.class;
+                        }
+                        
+                        // If we cannot find forName(String) then look for 
@XmlEnum value
+                        // and then look for a forName with the indicated base 
type
+                        if (log.isDebugEnabled()) {
+                            log.debug("try looking for @XmlEnum ");
+                        }
+                        XmlEnum xmlEnum = (XmlEnum)
+                            e.getAnnotation(XmlEnum.class);
+                        if (xmlEnum != null) {
+                            Class argClass = xmlEnum.value();
+                            m = fromValueMethod(e, argClass);
+                            if (m !=null) {
+                                return argClass;
+                            }
+                            Class primitiveClass = getPrimitiveClass(argClass);
+                            if (primitiveClass != null) {
+                                m = fromValueMethod(e, primitiveClass);
+                                if (m != null) {
+                                    return argClass;
+                                }
+                            }
+                        }
+                        
+                        // If still not found look for valueOf(String) method
+                        if (log.isDebugEnabled()) {
+                            log.debug("try looking for valueOf method ");
+                        }
+                        m = valueOfMethod(e);
+                        if (m != null) {
+                            return String.class;
+                        }
+                       
+                        throw ExceptionFactory.makeWebServiceException(new 
IllegalArgumentException());
+                    }});
+        } finally {
+            if (log.isDebugEnabled()) {
+                log.debug("getConversionType is" + cls);
+            }
+        }    
+        return cls;
+    }
+    
+    /**
+     * @param e enumeration class
+     * @param convObject Object of conversion type
+     * @return Object of enum
+     */
+    public static Object fromValue(final Class e, final Object convObject) {
+        Object enumValue = null;
+        if (log.isDebugEnabled()) {
+            log.debug("fromValue for " + 
JavaUtils.getObjectIdentity(convObject));
+        }
+        try {
+            enumValue =      
+                AccessController.doPrivileged(new PrivilegedExceptionAction() {
+                    public Object run() throws InvocationTargetException, 
IllegalAccessException {
+                        Method m = getConversionMethod(e);
+                        return m.invoke(null, new Object[] { convObject });
+                    }});
+        } catch (PrivilegedActionException pae) {
+            throw ExceptionFactory.makeWebServiceException(pae.getException());
+        } finally {
+            if (log.isDebugEnabled()) {
+                log.debug("getEnumValue is" + 
JavaUtils.getObjectIdentity(enumValue));
+            }
+        }
+        return enumValue;
+    }
+    
+    private static Method getConversionMethod(Class cls) {
+        // Look for forName method that is generated by JAXB.
+        Method m = fromValueMethod(cls, String.class);
+        if (m != null) {
+            return m;
+        }
+        
+        // If cannot find forName(String) then look for @XmlEnum value
+        if (log.isDebugEnabled()) {
+            log.debug("try looking for @XmlEnum ");
+        }
+        XmlEnum xmlEnum = (XmlEnum)
+            cls.getAnnotation(XmlEnum.class);
+        if (xmlEnum != null) {
+            Class argClass = xmlEnum.value();
+            m = fromValueMethod(cls, argClass);
+            if (m !=null) {
+                return m;
+            }
+            Class primitiveClass = getPrimitiveClass(argClass);
+            if (primitiveClass != null) {
+                m = fromValueMethod(cls, primitiveClass);
+                if (m != null) {
+                    return m;
+                }
+            }
+        }
+        
+        // Look for valueOf(String) method
+        if (log.isDebugEnabled()) {
+            log.debug("try looking for valueOf method ");
+        }
+        m = valueOfMethod(cls);
+        if (m != null) {
+            return m;
+        }
+        
+        throw new IllegalArgumentException();
+    }
+    /**
+     * @param cls
+     * @param argClass
+     * @return Method of fromValue with argClass
+     */
+    private static Method fromValueMethod(Class cls, Class argClass) {
+        try {
+            return cls.getMethod("fromValue", new Class[] { argClass });
+        } catch (Throwable t) {
+            return null;
+        }
+    }
+    
+    /**
+     * @param cls
+     * @param argClass
+     * @return Method of valueOf with argClass
+     */
+    private static Method valueOfMethod(Class cls) {
+        try {
+            return cls.getMethod("valueOf", new Class[] { String.class });
+        } catch (Throwable t) {
+            return null;
+        }
+    }
+    
+    /*
+     * @param cls possible wrapper class
+     * @return primitive class if this is a wrapper class
+     */
+    private static Class getPrimitiveClass(Class cls) {
+        if (Integer.class.equals(cls)) {
+            return int.class;
+        } else if (Short.class.equals(cls)) {
+            return short.class;
+        } else if (Boolean.class.equals(cls)) {
+            return boolean.class;
+        } else if (Byte.class.equals(cls)) {
+            return byte.class;
+        } else if (Long.class.equals(cls)) {
+            return long.class;
+        } else if (Double.class.equals(cls)) {
+            return double.class;
+        } else if (Float.class.equals(cls)) {
+            return float.class;
+        } else if (Character.class.equals(cls)) {
+            return char.class;
+        }
+
+        return null;
+    }
+    
+}

Added: 
axis/axis2/java/core/trunk/modules/jaxws/test/org/apache/axis2/jaxws/misc/EnumSample.java
URL: 
http://svn.apache.org/viewvc/axis/axis2/java/core/trunk/modules/jaxws/test/org/apache/axis2/jaxws/misc/EnumSample.java?rev=940586&view=auto
==============================================================================
--- 
axis/axis2/java/core/trunk/modules/jaxws/test/org/apache/axis2/jaxws/misc/EnumSample.java
 (added)
+++ 
axis/axis2/java/core/trunk/modules/jaxws/test/org/apache/axis2/jaxws/misc/EnumSample.java
 Mon May  3 19:46:00 2010
@@ -0,0 +1,33 @@
+/*
+ * 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.axis2.jaxws.misc;
+
+import javax.xml.bind.annotation.XmlType;
+
+/**
+ * Sample Enum
+ */
+...@xmltype(name="SampleEnum", namespace="urn://misc.jaxws.axis2.apache.org")
+public enum EnumSample {
+    DATA_A, DATA_B, DATA_C
+}
\ No newline at end of file

Added: 
axis/axis2/java/core/trunk/modules/jaxws/test/org/apache/axis2/jaxws/misc/EnumSample2.java
URL: 
http://svn.apache.org/viewvc/axis/axis2/java/core/trunk/modules/jaxws/test/org/apache/axis2/jaxws/misc/EnumSample2.java?rev=940586&view=auto
==============================================================================
--- 
axis/axis2/java/core/trunk/modules/jaxws/test/org/apache/axis2/jaxws/misc/EnumSample2.java
 (added)
+++ 
axis/axis2/java/core/trunk/modules/jaxws/test/org/apache/axis2/jaxws/misc/EnumSample2.java
 Mon May  3 19:46:00 2010
@@ -0,0 +1,35 @@
+/*
+ * 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.axis2.jaxws.misc;
+
+import javax.xml.bind.annotation.XmlEnum;
+import javax.xml.bind.annotation.XmlType;
+
+/**
+ * Sample Enum
+ */
+...@xmlenum(value=java.lang.String.class)
+...@xmltype(name="SampleEnum", namespace="urn://misc.jaxws.axis2.apache.org")
+public enum EnumSample2 {
+    DATA_A2, DATA_B2, DATA_C2
+}
\ No newline at end of file

Added: 
axis/axis2/java/core/trunk/modules/jaxws/test/org/apache/axis2/jaxws/misc/EnumSample3.java
URL: 
http://svn.apache.org/viewvc/axis/axis2/java/core/trunk/modules/jaxws/test/org/apache/axis2/jaxws/misc/EnumSample3.java?rev=940586&view=auto
==============================================================================
--- 
axis/axis2/java/core/trunk/modules/jaxws/test/org/apache/axis2/jaxws/misc/EnumSample3.java
 (added)
+++ 
axis/axis2/java/core/trunk/modules/jaxws/test/org/apache/axis2/jaxws/misc/EnumSample3.java
 Mon May  3 19:46:00 2010
@@ -0,0 +1,51 @@
+/*
+ * 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.axis2.jaxws.misc;
+
+import javax.xml.bind.annotation.XmlEnum;
+import javax.xml.bind.annotation.XmlType;
+
+/**
+ * Sample Enum
+ */
+...@xmlenum(value=java.lang.Integer.class)
+...@xmltype(name="SampleEnum", namespace="urn://misc.jaxws.axis2.apache.org")
+public enum EnumSample3 {
+    DATA_A3(10), DATA_B3(20), DATA_C3(30);
+    final private Integer value;
+    EnumSample3(int data) {
+        value = data;
+    }
+    public int value() { return value; }
+    public static EnumSample3 fromValue(int value) {
+        if (value == 10) {
+            return DATA_A3;
+        } else if (value == 20) {
+            return DATA_B3;
+        } else if (value == 30) {
+            return DATA_C3;
+        }
+        return null;
+    }
+                
+}
\ No newline at end of file

Added: 
axis/axis2/java/core/trunk/modules/jaxws/test/org/apache/axis2/jaxws/misc/XmlEnumUtilsTest.java
URL: 
http://svn.apache.org/viewvc/axis/axis2/java/core/trunk/modules/jaxws/test/org/apache/axis2/jaxws/misc/XmlEnumUtilsTest.java?rev=940586&view=auto
==============================================================================
--- 
axis/axis2/java/core/trunk/modules/jaxws/test/org/apache/axis2/jaxws/misc/XmlEnumUtilsTest.java
 (added)
+++ 
axis/axis2/java/core/trunk/modules/jaxws/test/org/apache/axis2/jaxws/misc/XmlEnumUtilsTest.java
 Mon May  3 19:46:00 2010
@@ -0,0 +1,57 @@
+/*
+ * 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.axis2.jaxws.misc;
+
+import junit.framework.TestCase;
+import org.apache.axis2.jaxws.utility.XmlEnumUtils;
+
+/**
+ * Tests Namespace to Package Algorithm
+ */
+public class XmlEnumUtilsTest extends TestCase {
+
+    public void test01() throws Exception {
+        Class cls = XmlEnumUtils.getConversionType(EnumSample.class);
+        assertTrue(String.class.equals(cls));
+        
+        Object value = XmlEnumUtils.fromValue(EnumSample.class, "DATA_C");
+        assertTrue(EnumSample.DATA_C == value);
+    }
+    
+    public void test02() throws Exception {
+        Class cls = XmlEnumUtils.getConversionType(EnumSample2.class);
+        assertTrue(String.class.equals(cls));
+        
+        
+        Object value = XmlEnumUtils.fromValue(EnumSample2.class,"DATA_C2");
+        assertTrue(EnumSample2.DATA_C2 == value);
+    }
+    
+    public void test03() throws Exception {
+        Class cls = XmlEnumUtils.getConversionType(EnumSample3.class);
+        assertTrue(Integer.class.equals(cls));
+       
+        Object value = XmlEnumUtils.fromValue(EnumSample3.class,30);
+        assertTrue(EnumSample3.DATA_C3 == value);
+    }
+}


Reply via email to