/** * 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.jaxrs.utils; import java.io.Closeable; import java.io.IOException; import java.lang.annotation.Annotation; import java.lang.reflect.Type; import javax.xml.bind.Unmarshaller; import javax.xml.bind.annotation.adapters.XmlAdapter; import javax.xml.bind.annotation.adapters.XmlJavaTypeAdapter; public final class JAXBUtils { private JAXBUtils() { } public static void closeUnmarshaller(Unmarshaller u) { if (u instanceof Closeable) { //need to do this to clear the ThreadLocal cache //see https://java.net/jira/browse/JAXB-1000 try { ((Closeable)u).close(); } catch (IOException e) { //ignore } } } public static Object convertWithAdapter(Object obj, Class<?> adapterClass, Annotation[] anns) { return useAdapter(obj, getAdapter(adapterClass, anns), false, obj); } public static Class<?> getValueTypeFromAdapter(Class<?> expectedBoundType, Class<?> defaultClass, Annotation[] anns) { try { XmlJavaTypeAdapter adapter = getAdapter(expectedBoundType, anns); if (adapter != null) { Class<?> boundType = JAXBUtils.getTypeFromAdapter(adapter, null, true); if (boundType != null && boundType.isAssignableFrom(expectedBoundType)) { return JAXBUtils.getTypeFromAdapter(adapter, null, false); } } } catch (Throwable ex) { // ignore } return defaultClass; } public static XmlJavaTypeAdapter getAdapter(Class<?> objectClass, Annotation[] anns) { XmlJavaTypeAdapter typeAdapter = AnnotationUtils.getAnnotation(anns, XmlJavaTypeAdapter.class); if (typeAdapter == null) { typeAdapter = objectClass.getAnnotation(XmlJavaTypeAdapter.class); if (typeAdapter == null) { // lets just try the 1st interface for now Class<?>[] interfaces = objectClass.getInterfaces(); typeAdapter = interfaces.length > 0 ? interfaces[0].getAnnotation(XmlJavaTypeAdapter.class) : null; } } return typeAdapter; } public static Class<?> getTypeFromAdapter(XmlJavaTypeAdapter adapter, Class<?> theType, boolean boundType) { if (adapter != null) { if (adapter.type() != XmlJavaTypeAdapter.DEFAULT.class) { theType = adapter.type(); } else { Type[] types = InjectionUtils.getActualTypes(adapter.value().getGenericSuperclass()); if (types != null && types.length == 2) { int index = boundType ? 1 : 0; theType = InjectionUtils.getActualType(types[index]); } } } return theType; } public static Object useAdapter(Object obj, XmlJavaTypeAdapter typeAdapter, boolean marshal) { return useAdapter(obj, typeAdapter, marshal, obj); } @SuppressWarnings("unchecked") public static Object useAdapter(Object obj, XmlJavaTypeAdapter typeAdapter, boolean marshal, Object defaultValue) { if (typeAdapter != null) { if (InjectionUtils.isSupportedCollectionOrArray(typeAdapter.value().getClass())) { return obj; } try { @SuppressWarnings("rawtypes") XmlAdapter xmlAdapter = typeAdapter.value().newInstance(); if (marshal) { return xmlAdapter.marshal(obj); } else { return xmlAdapter.unmarshal(obj); } } catch (Exception ex) { ex.printStackTrace(); } } return defaultValue; } }