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