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);
+ }
+}