All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.jboss.resteasy.plugins.providers.jaxb.AbstractJAXBContextFinder Maven / Gradle / Ivy

There is a newer version: 7.0.0.Alpha4
Show newest version
package org.jboss.resteasy.plugins.providers.jaxb;

import java.lang.annotation.Annotation;
import java.security.AccessController;
import java.security.PrivilegedActionException;
import java.security.PrivilegedExceptionAction;
import java.util.Collections;
import java.util.HashSet;
import java.util.Set;

import jakarta.ws.rs.core.Context;
import jakarta.ws.rs.core.MediaType;
import jakarta.ws.rs.ext.ContextResolver;
import jakarta.ws.rs.ext.Providers;
import jakarta.xml.bind.JAXBContext;
import jakarta.xml.bind.JAXBException;
import jakarta.xml.bind.annotation.XmlRegistry;
import jakarta.xml.bind.annotation.XmlType;

/**
 * @author Bill Burke
 * @version $Revision: 1 $
 */
public abstract class AbstractJAXBContextFinder implements JAXBContextFinder {
    protected static final String OBJECT_FACTORY_NAME = ".ObjectFactory";
    @Context
    protected Providers providers;

    public static class CacheKey {
        private Class[] classes;
        private int hashCode;

        public CacheKey(final Class[] classes) {
            this.classes = classes;
            for (Class clazz : classes)
                hashCode += clazz.hashCode();
        }

        @Override
        public boolean equals(Object o) {
            if (this == o)
                return true;
            if (o == null || getClass() != o.getClass())
                return false;

            CacheKey cacheKey = (CacheKey) o;

            if (hashCode != cacheKey.hashCode)
                return false;
            if (classes.length != cacheKey.classes.length)
                return false;

            for (Class clazz : classes) {
                boolean found = false;
                for (Class compare : cacheKey.classes) {
                    if (compare.equals(clazz)) {
                        found = true;
                        break;
                    }
                }
                if (!found)
                    return false;
            }
            return true;
        }

        @Override
        public int hashCode() {
            return hashCode;
        }
    }

    public JAXBContext findProvidedJAXBContext(Class type, MediaType mediaType)
            throws JAXBException {
        JAXBContext jaxb = null;
        ContextResolver resolver = providers.getContextResolver(JAXBContext.class, mediaType);
        if (resolver != null) {
            jaxb = resolver.getContext(type);
            if (jaxb != null)
                return jaxb;
        }
        return jaxb;
    }

    public static String getPackageName(Class type) {
        String packageName;
        int packageSeparator = type.getName().lastIndexOf('.');
        if (packageSeparator != -1) {
            packageName = type.getName().substring(0, packageSeparator);
        } else {
            packageName = type.getName();
        }
        return packageName;
    }

    public static Class findDefaultObjectFactoryClass(Class type) {
        XmlType typeAnnotation = type.getAnnotation(XmlType.class);
        if (typeAnnotation == null)
            return null;
        if (!typeAnnotation.factoryClass().equals(XmlType.DEFAULT.class))
            return null;
        final StringBuilder b = new StringBuilder(getPackageName(type));
        b.append(OBJECT_FACTORY_NAME);
        Class factoryClass;
        try {
            if (System.getSecurityManager() == null) {
                factoryClass = Thread.currentThread().getContextClassLoader().loadClass(b.toString());
            } else {
                factoryClass = AccessController.doPrivileged(new PrivilegedExceptionAction>() {
                    @Override
                    public Class run() throws ClassNotFoundException {
                        return Thread.currentThread().getContextClassLoader().loadClass(b.toString());
                    }
                });
            }
        } catch (PrivilegedActionException | ClassNotFoundException e) {
            return null;
        }
        if (factoryClass.isAnnotationPresent(XmlRegistry.class))
            return factoryClass;
        return null;
    }

    protected abstract JAXBContext createContextObject(Annotation[] parameterAnnotations, Class... classes)
            throws JAXBException;

    protected abstract JAXBContext createContextObject(Annotation[] parameterAnnotations, String contextPath)
            throws JAXBException;

    public JAXBContext createXmlTypeContext(Annotation[] parameterAnnotations, Class... classes) throws JAXBException {

        HashSet packages = new HashSet();
        for (Class type : classes) {
            packages.add(type.getPackage().getName());
        }
        boolean first = true;
        StringBuilder contextPath = new StringBuilder();
        for (String pkg : packages) {
            if (first)
                first = false;
            else
                contextPath.append(':');
            contextPath.append(pkg);
        }
        return createContextObject(parameterAnnotations, contextPath.toString());
    }

    @Override
    public JAXBContext createContext(Annotation[] parameterAnnotations, Class... classes) throws JAXBException {
        Set> classes1 = Collections.emptySet();
        if (classes != null && classes.length != 0) {
            classes1 = new HashSet>();
            for (Class type : classes) {
                if (type == null)
                    continue;
                classes1.add(type);
                Class factory = findDefaultObjectFactoryClass(type);
                if (factory != null)
                    classes1.add(factory);
            }
        }
        Class[] classArray = classes1.toArray(new Class[classes1.size()]);
        return createContextObject(parameterAnnotations, classArray);
    }

    public JAXBContextFinder getContext(Class type) {
        return this;
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy