org.apache.cxf.jaxb.Utils Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of cxf-bundle-minimal Show documentation
Show all versions of cxf-bundle-minimal Show documentation
Apache CXF Minimal Bundle Jar
/**
* 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.cxf.jaxb;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
import java.util.Arrays;
import java.util.Collection;
import java.util.HashSet;
import java.util.Set;
import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlTransient;
import javax.xml.bind.annotation.adapters.XmlAdapter;
import javax.xml.bind.annotation.adapters.XmlJavaTypeAdapter;
import javax.xml.bind.annotation.adapters.XmlJavaTypeAdapters;
/**
* JAXB reflection utilities.
*/
final class Utils {
private Utils() {
}
static XmlAccessType getXmlAccessType(Class> cls) {
XmlAccessorType accessorType = cls.getAnnotation(XmlAccessorType.class);
if (accessorType == null && cls.getPackage() != null) {
accessorType = cls.getPackage().getAnnotation(XmlAccessorType.class);
}
return accessorType != null
? accessorType.value() : XmlAccessType.PUBLIC_MEMBER;
}
static Collection getFields(Class> cls, XmlAccessType accessType) {
return getFieldsInternal(cls, accessType);
}
private static Collection getFieldsInternal(Class> cls, XmlAccessType accessType) {
Set fields = new HashSet();
Class> superClass = cls.getSuperclass();
if (superClass != null && !superClass.equals(Object.class) && !superClass.equals(Throwable.class)) {
// process super class until java.lang.Object or java.lang.Throwable is not reached
fields.addAll(getFieldsInternal(superClass, accessType));
}
// process current class
for (Field field : cls.getDeclaredFields()) {
if (JAXBContextInitializer.isFieldAccepted(field, accessType)) {
fields.add(field);
}
}
return fields;
}
private static Collection getMethods(Class> cls, XmlAccessType accessType, boolean acceptSetters) {
return getMethodsInternal(cls, accessType, acceptSetters);
}
private static Collection getMethodsInternal(Class> cls, XmlAccessType accessType,
boolean acceptSetters) {
Set methods = new HashSet();
Class> superClass = cls.getSuperclass();
if (superClass != null && !superClass.equals(Object.class) && !superClass.equals(Throwable.class)) {
// process super class until java.lang.Object or java.lang.Throwable is not reached
methods.addAll(getMethodsInternal(superClass, accessType, acceptSetters));
}
// process current class
for (Method method : cls.getDeclaredMethods()) {
if (isMethodAccepted(method, accessType, acceptSetters)) {
methods.add(method);
}
}
return methods;
}
static Method getMethod(Class> cls, XmlAccessType accessType, String methodName,
Class>... paramTypes) {
for (Method m : getMethods(cls, accessType, true)) {
if (m.getName().equals(methodName) && Arrays.equals(m.getParameterTypes(), paramTypes)) {
return m;
}
}
return null;
}
static Field getField(Class> cls, XmlAccessType accessType, String fieldName) {
for (final Field f : getFields(cls, accessType)) {
if (f.getName().equals(fieldName)) {
return f;
}
}
return null;
}
static Collection getGetters(Class> cls, XmlAccessType accessType) {
return getMethods(cls, accessType, false);
}
static boolean isMethodAccepted(Method method, XmlAccessType accessType, boolean acceptSetters) {
// ignore bridge, static, @XmlTransient methods plus methods declared in Throwable
if (method.isBridge()
|| Modifier.isStatic(method.getModifiers())
|| method.isAnnotationPresent(XmlTransient.class)
|| method.getDeclaringClass().equals(Throwable.class)
|| "getClass".equals(method.getName())) {
return false;
}
// Allow only public methods if PUBLIC_MEMBER access is requested
if (accessType == XmlAccessType.PUBLIC_MEMBER && !Modifier.isPublic(method.getModifiers())) {
return false;
}
if (isGetter(method)) {
// does nothing
} else if (isSetter(method)) {
if (!acceptSetters) {
return false;
}
} else {
// we accept only getters and setters
return false;
}
// let JAXB annotations decide if NONE or FIELD access is requested
if (accessType == XmlAccessType.NONE || accessType == XmlAccessType.FIELD) {
return JAXBContextInitializer.checkJaxbAnnotation(method.getAnnotations());
}
// method accepted
return true;
}
private static boolean isGetter(Method m) {
if (m.getReturnType() != Void.class && m.getReturnType() != Void.TYPE && m.getParameterTypes().length == 0) {
Method setter = getSetter(m);
if (setter != null) {
return !setter.isAnnotationPresent(XmlTransient.class);
}
if (getterIndex(m.getName()) > -1) {
return true;
}
}
return false;
}
private static Method getSetter(Method m) {
final int index = getterIndex(m.getName());
if (index != -1) {
String setterName = "set" + m.getName().substring(index);
Class> paramTypes = m.getReturnType();
return getDeclaredMethod(m.getDeclaringClass(), setterName, paramTypes);
}
return null;
}
private static boolean isSetter(Method m) {
Class> declaringClass = m.getDeclaringClass();
boolean isVoidReturnType = m.getReturnType() == Void.class || m.getReturnType() == Void.TYPE;
if (isVoidReturnType && m.getParameterTypes().length == 1 && m.getName().startsWith("set")) {
String getterName = "get" + m.getName().substring(3);
Class> setterParamType = m.getParameterTypes()[0];
Method getter = getDeclaredMethod(declaringClass, getterName);
if (getter != null && getter.getReturnType().equals(setterParamType)
&& !getter.isAnnotationPresent(XmlTransient.class)) {
return true;
}
}
return false;
}
private static int getterIndex(String methodName) {
if (methodName.startsWith("is")) {
return 2;
}
if (methodName.startsWith("get")) {
return 3;
}
return -1;
}
private static Method getDeclaredMethod(Class> cls, String methodName, Class>... paramTypes) {
try {
return cls.getDeclaredMethod(methodName, paramTypes);
} catch (Exception e) {
return null;
}
}
static Class> getFieldType(Field f) {
XmlJavaTypeAdapter adapter = getFieldXJTA(f);
if (adapter == null && f.getGenericType() instanceof ParameterizedType) {
return null;
}
Class> adapterType = (Class>)getTypeFromXmlAdapter(adapter);
return adapterType != null ? adapterType : f.getType();
}
static Class> getMethodReturnType(Method m) {
XmlJavaTypeAdapter adapter = getMethodXJTA(m);
// if there is no adapter, yet we have a collection make sure
// we return the Generic type; if there is an annotation let the
// adapter handle what gets populated
if (adapter == null && m.getGenericReturnType() instanceof ParameterizedType) {
return null;
}
Class> adapterType = (Class>)getTypeFromXmlAdapter(adapter);
return adapterType != null ? adapterType : m.getReturnType();
}
@SuppressWarnings({ "rawtypes", "unchecked" })
static Object getFieldValue(Field f, Object target) throws Exception {
XmlJavaTypeAdapter adapterAnnotation = getFieldXJTA(f);
XmlAdapter adapter = getXmlAdapter(adapterAnnotation);
return adapter != null ? adapter.marshal(f.get(target)) : f.get(target);
}
@SuppressWarnings({ "rawtypes", "unchecked" })
static Object getMethodValue(Method m, Object target) throws Exception {
XmlJavaTypeAdapter adapterAnnotation = getMethodXJTA(m);
XmlAdapter adapter = getXmlAdapter(adapterAnnotation);
return adapter != null ? adapter.marshal(m.invoke(target)) : m.invoke(target);
}
@SuppressWarnings({ "rawtypes", "unchecked" })
static void setFieldValue(Field f, Object target, Object value) throws Exception {
XmlJavaTypeAdapter xjta = getFieldXJTA(f);
XmlAdapter adapter = getXmlAdapter(xjta);
f.set(target, adapter != null ? adapter.unmarshal(value) : value);
}
@SuppressWarnings({ "rawtypes", "unchecked" })
static void setMethodValue(Method getter, Method setter, Object target, Object value) throws Exception {
XmlJavaTypeAdapter xjta = getMethodXJTA(getter);
XmlAdapter adapter = getXmlAdapter(xjta);
setter.invoke(target, adapter != null ? adapter.unmarshal(value) : value);
}
@SuppressWarnings("rawtypes")
static XmlAdapter getXmlAdapter(XmlJavaTypeAdapter adapterAnnotation)
throws InstantiationException, IllegalAccessException {
return adapterAnnotation != null ? adapterAnnotation.value().newInstance() : null;
}
static XmlJavaTypeAdapter getFieldXJTA(final Field f) {
XmlJavaTypeAdapter adapter = f.getAnnotation(XmlJavaTypeAdapter.class);
if (adapter == null) {
adapter = f.getType().getAnnotation(XmlJavaTypeAdapter.class);
}
if (adapter == null) {
XmlJavaTypeAdapters adapters = f.getDeclaringClass().getPackage().getAnnotation(XmlJavaTypeAdapters.class);
if (adapters != null) {
for (XmlJavaTypeAdapter candidate : adapters.value()) {
if (candidate != null && candidate.type().equals(f.getType())) {
adapter = candidate;
break;
}
}
}
}
return adapter;
}
static XmlJavaTypeAdapter getMethodXJTA(final Method m) {
XmlJavaTypeAdapter adapter = m.getAnnotation(XmlJavaTypeAdapter.class);
if (adapter == null) {
Method setter = getSetter(m);
if (setter != null) {
adapter = setter.getAnnotation(XmlJavaTypeAdapter.class);
}
}
if (adapter == null) {
adapter = m.getReturnType().getAnnotation(XmlJavaTypeAdapter.class);
}
if (adapter == null) {
XmlJavaTypeAdapters adapters = m.getDeclaringClass().getPackage().getAnnotation(XmlJavaTypeAdapters.class);
if (adapters != null) {
for (XmlJavaTypeAdapter candidate : adapters.value()) {
if (candidate != null && candidate.type().equals(m.getGenericReturnType())) {
adapter = candidate;
break;
}
}
}
}
return adapter;
}
static Type getTypeFromXmlAdapter(XmlJavaTypeAdapter xjta) {
if (xjta != null) {
Class> c2 = xjta.value();
Type sp = c2.getGenericSuperclass();
while (!XmlAdapter.class.equals(c2) && c2 != null) {
sp = c2.getGenericSuperclass();
c2 = c2.getSuperclass();
}
if (sp instanceof ParameterizedType) {
return ((ParameterizedType)sp).getActualTypeArguments()[0];
}
}
return null;
}
}