Please wait. This can take some minutes ...
Many resources are needed to download a project. Please understand that we have to compensate our server costs. Thank you in advance.
Project price only 1 $
You can buy this project and download/modify it how often you want.
org.jboss.resteasy.spi.ResteasyProviderFactory Maven / Gradle / Ivy
package org.jboss.resteasy.spi;
import org.jboss.resteasy.core.InjectorFactoryImpl;
import org.jboss.resteasy.core.MediaTypeMap;
import org.jboss.resteasy.core.interception.jaxrs.ClientRequestFilterRegistry;
import org.jboss.resteasy.core.interception.jaxrs.ClientResponseFilterRegistry;
import org.jboss.resteasy.core.interception.jaxrs.ContainerRequestFilterRegistry;
import org.jboss.resteasy.core.interception.jaxrs.ContainerResponseFilterRegistry;
import org.jboss.resteasy.core.interception.jaxrs.ReaderInterceptorRegistry;
import org.jboss.resteasy.core.interception.jaxrs.WriterInterceptorRegistry;
import org.jboss.resteasy.plugins.delegates.CacheControlDelegate;
import org.jboss.resteasy.plugins.delegates.CookieHeaderDelegate;
import org.jboss.resteasy.plugins.delegates.DateDelegate;
import org.jboss.resteasy.plugins.delegates.EntityTagDelegate;
import org.jboss.resteasy.plugins.delegates.LinkDelegate;
import org.jboss.resteasy.plugins.delegates.LinkHeaderDelegate;
import org.jboss.resteasy.plugins.delegates.LocaleDelegate;
import org.jboss.resteasy.plugins.delegates.MediaTypeHeaderDelegate;
import org.jboss.resteasy.plugins.delegates.NewCookieHeaderDelegate;
import org.jboss.resteasy.plugins.delegates.UriHeaderDelegate;
import org.jboss.resteasy.plugins.providers.RegisterBuiltin;
import org.jboss.resteasy.resteasy_jaxrs.i18n.LogMessages;
import org.jboss.resteasy.resteasy_jaxrs.i18n.Messages;
import org.jboss.resteasy.specimpl.LinkBuilderImpl;
import org.jboss.resteasy.specimpl.ResponseBuilderImpl;
import org.jboss.resteasy.specimpl.ResteasyUriBuilder;
import org.jboss.resteasy.specimpl.VariantListBuilderImpl;
import org.jboss.resteasy.spi.metadata.ResourceBuilder;
import org.jboss.resteasy.spi.metadata.ResourceClassProcessor;
import org.jboss.resteasy.tracing.RESTEasyTracingLogger;
import org.jboss.resteasy.util.FeatureContextDelegate;
import org.jboss.resteasy.util.PickConstructor;
import org.jboss.resteasy.util.ThreadLocalStack;
import org.jboss.resteasy.util.Types;
import javax.annotation.Priority;
import javax.ws.rs.ConstrainedTo;
import javax.ws.rs.Consumes;
import javax.ws.rs.Priorities;
import javax.ws.rs.Produces;
import javax.ws.rs.RuntimeType;
import javax.ws.rs.client.ClientRequestFilter;
import javax.ws.rs.client.ClientResponseFilter;
import javax.ws.rs.client.RxInvoker;
import javax.ws.rs.client.RxInvokerProvider;
import javax.ws.rs.container.ContainerRequestFilter;
import javax.ws.rs.container.ContainerResponseFilter;
import javax.ws.rs.container.DynamicFeature;
import javax.ws.rs.core.*;
import javax.ws.rs.core.Link;
import javax.ws.rs.ext.ContextResolver;
import javax.ws.rs.ext.ExceptionMapper;
import javax.ws.rs.ext.MessageBodyReader;
import javax.ws.rs.ext.MessageBodyWriter;
import javax.ws.rs.ext.ParamConverter;
import javax.ws.rs.ext.ParamConverterProvider;
import javax.ws.rs.ext.Providers;
import javax.ws.rs.ext.ReaderInterceptor;
import javax.ws.rs.ext.RuntimeDelegate;
import javax.ws.rs.ext.WriterInterceptor;
import java.lang.annotation.Annotation;
import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Modifier;
import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
import java.net.URI;
import java.util.*;
import java.util.Map.Entry;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.CopyOnWriteArraySet;
/**
* @author Bill Burke
* @version $Revision: 1 $
*/
@SuppressWarnings("unchecked")
public class ResteasyProviderFactory extends RuntimeDelegate implements Providers, HeaderValueProcessor, Configurable, Configuration
{
/**
* Allow us to sort message body implementations that are more specific for their types
* i.e. MessageBodyWriter<Object> is less specific than MessageBodyWriter<String>.
*
* This helps out a lot when the desired media type is a wildcard and to weed out all the possible
* default mappings.
*/
private static class SortedKey implements Comparable>, MediaTypeMap.Typed
{
private final T obj;
private final boolean isBuiltin;
private final Class> template;
private final int priority;
protected SortedKey(Class> intf, T reader, Class> readerClass, int priority, boolean isBuiltin)
{
this.obj = reader;
// check the super class for the generic type 1st
Class> t = Types.getTemplateParameterOfInterface(readerClass, intf);
template = (t != null) ? t : Object.class;
this.priority = priority;
this.isBuiltin = isBuiltin;
}
protected SortedKey(Class> intf, T reader, Class> readerClass, boolean isBuiltin)
{
this(intf, reader, readerClass, Priorities.USER, isBuiltin);
}
protected SortedKey(Class> intf, T reader, Class> readerClass)
{
this(intf, reader, readerClass, Priorities.USER, false);
}
public int compareTo(SortedKey tMessageBodyKey)
{
// Sort user provider before builtins
if (this == tMessageBodyKey) return 0;
if (isBuiltin == tMessageBodyKey.isBuiltin)
{
if (this.priority < tMessageBodyKey.priority)
{
return -1;
}
if (this.priority == tMessageBodyKey.priority)
{
return 0;
}
if (this.priority > tMessageBodyKey.priority)
{
return 1;
}
}
if (isBuiltin) return 1;
else return -1;
}
public Class> getType()
{
return template;
}
public T getObj() {
return obj;
}
}
private static class ExtSortedKey extends SortedKey
{
protected ExtSortedKey(Class> intf, T reader, Class> readerClass, int priority, boolean isBuiltin)
{
super(intf, reader, readerClass, priority, isBuiltin);
}
protected ExtSortedKey(Class> intf, T reader, Class> readerClass, boolean isBuiltin)
{
super(intf, reader, readerClass, isBuiltin);
}
protected ExtSortedKey(Class> intf, T reader, Class> readerClass)
{
super(intf, reader, readerClass);
}
@Override
public int compareTo(SortedKey tMessageBodyKey)
{
int c = super.compareTo(tMessageBodyKey);
if (c != 0)
{
return c;
}
if (this.getObj() == tMessageBodyKey.getObj())
{
return 0;
}
return -1;
}
}
private static final ThreadLocalStack, Object>> contextualData = new ThreadLocalStack, Object>>();
private static final int maxForwards = 20;
private static volatile ResteasyProviderFactory instance;
private static boolean registerBuiltinByDefault = true;
private MediaTypeMap> serverMessageBodyReaders;
private MediaTypeMap> serverMessageBodyWriters;
private MediaTypeMap> clientMessageBodyReaders;
private MediaTypeMap> clientMessageBodyWriters;
private Map, SortedKey> sortedExceptionMappers;
private Map, ExceptionMapper> exceptionMappers;
private Map, AsyncResponseProvider> asyncResponseProviders;
private Map, AsyncClientResponseProvider> asyncClientResponseProviders;
private Map, AsyncStreamProvider> asyncStreamProviders;
private Map, MediaTypeMap>> contextResolvers;
private Map contextInjectors;
private Map asyncContextInjectors;
private Set> sortedParamConverterProviders;
private Map, Class extends StringParameterUnmarshaller>> stringParameterUnmarshallers;
protected Map, Map, Integer>> classContracts;
private Map, HeaderDelegate> headerDelegates;
private ReaderInterceptorRegistry serverReaderInterceptorRegistry;
private WriterInterceptorRegistry serverWriterInterceptorRegistry;
private ContainerRequestFilterRegistry containerRequestFilterRegistry;
private ContainerResponseFilterRegistry containerResponseFilterRegistry;
private ClientRequestFilterRegistry clientRequestFilterRegistry;
private ClientResponseFilterRegistry clientResponseFilters;
private ReaderInterceptorRegistry clientReaderInterceptorRegistry;
private WriterInterceptorRegistry clientWriterInterceptorRegistry;
private boolean builtinsRegistered = false;
private boolean registerBuiltins = true;
private InjectorFactory injectorFactory;
private ResteasyProviderFactory parent;
private Set serverDynamicFeatures;
private Set clientDynamicFeatures;
private Map properties;
private Map, Class extends RxInvokerProvider>>> reactiveClasses;
private ResourceBuilder resourceBuilder;
protected Set enabledFeatures;
protected Set> providerClasses;
protected Set providerInstances;
public ResteasyProviderFactory()
{
// NOTE!!! It is important to put all initialization into initialize() as ThreadLocalResteasyProviderFactory
// subclasses and delegates to this class.
initialize();
}
/**
* Copies a specific component registry when a new
* provider is added. Otherwise delegates to the parent.
*
* @param parent provider factory
*/
public ResteasyProviderFactory(ResteasyProviderFactory parent)
{
this(parent, false);
}
/**
* If local is true, copies components needed by client configuration,
* so that parent is not referenced.
* @param parent provider factory
* @param local local
*/
public ResteasyProviderFactory(ResteasyProviderFactory parent, boolean local)
{
this.parent = parent;
providerClasses = new CopyOnWriteArraySet>();
providerInstances = new CopyOnWriteArraySet();
properties = new ConcurrentHashMap();
properties.putAll(parent.getProperties());
enabledFeatures = new CopyOnWriteArraySet();
reactiveClasses = new ConcurrentHashMap, Class extends RxInvokerProvider>>>();
if (local)
{
classContracts = new ConcurrentHashMap, Map, Integer>>();
if (parent != null)
{
providerClasses.addAll(parent.providerClasses);
providerInstances.addAll(parent.providerInstances);
classContracts.putAll(parent.classContracts);
properties.putAll(parent.properties);
enabledFeatures.addAll(parent.enabledFeatures);
reactiveClasses.putAll(parent.reactiveClasses);
}
}
resourceBuilder = new ResourceBuilder();
}
protected void initialize()
{
serverDynamicFeatures = new CopyOnWriteArraySet();
clientDynamicFeatures = new CopyOnWriteArraySet();
enabledFeatures = new CopyOnWriteArraySet();
properties = new ConcurrentHashMap();
providerClasses = new CopyOnWriteArraySet>();
providerInstances = new CopyOnWriteArraySet();
classContracts = new ConcurrentHashMap, Map, Integer>>();
serverMessageBodyReaders = new MediaTypeMap>();
serverMessageBodyWriters = new MediaTypeMap>();
clientMessageBodyReaders = new MediaTypeMap>();
clientMessageBodyWriters = new MediaTypeMap>();
sortedExceptionMappers = new ConcurrentHashMap, SortedKey>();
asyncResponseProviders = new ConcurrentHashMap, AsyncResponseProvider>();
asyncClientResponseProviders = new ConcurrentHashMap, AsyncClientResponseProvider>();
asyncStreamProviders = new ConcurrentHashMap, AsyncStreamProvider>();
contextResolvers = new ConcurrentHashMap, MediaTypeMap>>();
contextInjectors = new ConcurrentHashMap();
asyncContextInjectors = new ConcurrentHashMap();
sortedParamConverterProviders = Collections.synchronizedSortedSet(new TreeSet>());
stringParameterUnmarshallers = new ConcurrentHashMap, Class extends StringParameterUnmarshaller>>();
reactiveClasses = new ConcurrentHashMap, Class extends RxInvokerProvider>>>();
headerDelegates = new ConcurrentHashMap, HeaderDelegate>();
resourceBuilder = new ResourceBuilder();
initializeRegistriesAndFilters();
builtinsRegistered = false;
registerBuiltins = true;
injectorFactory = new InjectorFactoryImpl();
addHeaderDelegate(MediaType.class, new MediaTypeHeaderDelegate());
addHeaderDelegate(NewCookie.class, new NewCookieHeaderDelegate());
addHeaderDelegate(Cookie.class, new CookieHeaderDelegate());
addHeaderDelegate(URI.class, new UriHeaderDelegate());
addHeaderDelegate(EntityTag.class, new EntityTagDelegate());
addHeaderDelegate(CacheControl.class, new CacheControlDelegate());
addHeaderDelegate(Locale.class, new LocaleDelegate());
addHeaderDelegate(LinkHeader.class, new LinkHeaderDelegate());
addHeaderDelegate(javax.ws.rs.core.Link.class, new LinkDelegate());
addHeaderDelegate(Date.class, new DateDelegate());
}
private void initializeRegistriesAndFilters()
{
serverReaderInterceptorRegistry = new ReaderInterceptorRegistry(this);
serverWriterInterceptorRegistry = new WriterInterceptorRegistry(this);
containerRequestFilterRegistry = new ContainerRequestFilterRegistry(this);
containerResponseFilterRegistry = new ContainerResponseFilterRegistry(this);
clientRequestFilterRegistry = new ClientRequestFilterRegistry(this);
clientResponseFilters = new ClientResponseFilterRegistry(this);
clientReaderInterceptorRegistry = new ReaderInterceptorRegistry(this);
clientWriterInterceptorRegistry = new WriterInterceptorRegistry(this);
}
public Set getServerDynamicFeatures()
{
if (serverDynamicFeatures == null && parent != null) return parent.getServerDynamicFeatures();
return serverDynamicFeatures;
}
public Set getClientDynamicFeatures()
{
if (clientDynamicFeatures == null && parent != null) return parent.getClientDynamicFeatures();
return clientDynamicFeatures;
}
private MediaTypeMap> getServerMessageBodyReaders()
{
if (serverMessageBodyReaders == null && parent != null) return parent.getServerMessageBodyReaders();
return serverMessageBodyReaders;
}
private MediaTypeMap> getServerMessageBodyWriters()
{
if (serverMessageBodyWriters == null && parent != null) return parent.getServerMessageBodyWriters();
return serverMessageBodyWriters;
}
private MediaTypeMap> getClientMessageBodyReaders()
{
if (clientMessageBodyReaders == null && parent != null) return parent.getClientMessageBodyReaders();
return clientMessageBodyReaders;
}
private MediaTypeMap> getClientMessageBodyWriters()
{
if (clientMessageBodyWriters == null && parent != null) return parent.getClientMessageBodyWriters();
return clientMessageBodyWriters;
}
public Map, ExceptionMapper> getExceptionMappers()
{
if (exceptionMappers != null)
{
return exceptionMappers;
}
Map, ExceptionMapper> map = new ConcurrentHashMap, ExceptionMapper>();
for (Entry, SortedKey> entry : getSortedExceptionMappers().entrySet())
{
map.put(entry.getKey(), entry.getValue().getObj());
}
exceptionMappers = map;
return map;
}
private Map, SortedKey> getSortedExceptionMappers()
{
if (sortedExceptionMappers == null && parent != null) return parent.getSortedExceptionMappers();
return sortedExceptionMappers;
}
public Map, AsyncResponseProvider> getAsyncResponseProviders()
{
if (asyncResponseProviders == null && parent != null) return parent.getAsyncResponseProviders();
return asyncResponseProviders;
}
public Map, AsyncClientResponseProvider> getAsyncClientResponseProviders()
{
if (asyncClientResponseProviders == null && parent != null) return parent.getAsyncClientResponseProviders();
return asyncClientResponseProviders;
}
public Map, AsyncStreamProvider> getAsyncStreamProviders()
{
if (asyncStreamProviders == null && parent != null) return parent.getAsyncStreamProviders();
return asyncStreamProviders;
}
public Map getContextInjectors()
{
if (contextInjectors == null && parent != null) return parent.getContextInjectors();
return contextInjectors;
}
public Map getAsyncContextInjectors()
{
if (asyncContextInjectors == null && parent != null) return parent.getAsyncContextInjectors();
return asyncContextInjectors;
}
private Map, MediaTypeMap>> getContextResolvers()
{
if (contextResolvers == null && parent != null) return parent.getContextResolvers();
return contextResolvers;
}
private Set> getSortedParamConverterProviders()
{
if (sortedParamConverterProviders == null && parent != null) return parent.getSortedParamConverterProviders();
return sortedParamConverterProviders;
}
private Map, Class extends StringParameterUnmarshaller>> getStringParameterUnmarshallers()
{
if (stringParameterUnmarshallers == null && parent != null) return parent.getStringParameterUnmarshallers();
return stringParameterUnmarshallers;
}
/**
* Gets provide classes.
*
* @return set of provider classes
*/
public Set> getProviderClasses()
{
if (providerClasses == null && parent != null) return parent.getProviderClasses();
Set> set = new HashSet>();
if (parent != null) set.addAll(parent.getProviderClasses());
set.addAll(providerClasses);
return set;
}
/**
* Gets provider instances.
*
* @return set of provider instances
*/
public Set getProviderInstances()
{
if (providerInstances == null && parent != null) return parent.getProviderInstances();
Set set = new HashSet();
if (parent != null) set.addAll(parent.getProviderInstances());
set.addAll(providerInstances);
return set;
}
private Map, Map, Integer>> getClassContracts()
{
if (classContracts != null) return classContracts;
Map, Map, Integer>> map = new ConcurrentHashMap, Map, Integer>>();
if (parent != null)
{
for (Map.Entry, Map, Integer>> entry : parent.getClassContracts().entrySet())
{
Map, Integer> mapEntry = new HashMap, Integer>();
mapEntry.putAll(entry.getValue());
map.put(entry.getKey(), mapEntry);
}
}
classContracts = map;
return classContracts;
}
public static void pushContext(Class type, T data)
{
getContextDataMap().put(type, data);
}
public static void pushContextDataMap(Map, Object> map)
{
contextualData.push(map);
}
public static Map, Object> getContextDataMap()
{
return getContextDataMap(true);
}
public static T getContextData(Class type)
{
return (T) getContextDataMap().get(type);
}
public boolean hasAsyncContextData(Type genericType) {
return getAsyncContextInjectors().containsKey(Types.boxPrimitives(genericType));
}
public T getContextData(Class rawType, Type genericType, Annotation[] annotations, boolean unwrapAsync)
{
T ret = (T) getContextDataMap().get(rawType);
if(ret != null)
return ret;
ContextInjector contextInjector = getContextInjectors().get(genericType);
boolean async = false;
if(contextInjector == null && unwrapAsync)
{
contextInjector = getAsyncContextInjectors().get(Types.boxPrimitives(genericType));
async = true;
}
if(contextInjector != null)
{
ret = (T) contextInjector.resolve(rawType, genericType, annotations);
if(async && ret != null)
{
Type wrappedType = Types.getActualTypeArgumentsOfAnInterface(contextInjector.getClass(), ContextInjector.class)[0];
Class> rawWrappedType = Types.getRawType(wrappedType);
AsyncResponseProvider converter = getAsyncResponseProvider(rawWrappedType);
// OK this is plain lying
ret = (T) converter.toCompletionStage(ret);
}
}
return ret;
}
public static T popContextData(Class type)
{
return (T) getContextDataMap().remove(type);
}
public static void clearContextData()
{
contextualData.clear();
}
private static Map, Object> getContextDataMap(boolean create)
{
Map, Object> map = contextualData.get();
if (map == null)
{
contextualData.setLast(map = new HashMap, Object>());
}
return map;
}
public static Map, Object> addContextDataLevel()
{
if (getContextDataLevelCount() == maxForwards)
{
throw new BadRequestException(Messages.MESSAGES.excededMaximumForwards(getContextData(UriInfo.class).getPath()));
}
Map, Object> map = new HashMap, Object>();
contextualData.push(map);
return map;
}
public static int getContextDataLevelCount()
{
return contextualData.size();
}
public static void removeContextDataLevel()
{
contextualData.pop();
}
/**
* Will not initialize singleton if not set.
*
* @return provider factory singleton
*/
public static ResteasyProviderFactory peekInstance()
{
return instance;
}
public synchronized static void clearInstanceIfEqual(ResteasyProviderFactory factory)
{
if (instance == factory)
{
instance = null;
RuntimeDelegate.setInstance(null);
}
}
public synchronized static void setInstance(ResteasyProviderFactory factory)
{
synchronized (RD_LOCK)
{
instance = factory;
}
RuntimeDelegate.setInstance(factory);
}
final static Object RD_LOCK = new Object();
/**
* Initializes ResteasyProviderFactory singleton if not set.
*
* @return singleton provider factory
*/
public static ResteasyProviderFactory getInstance()
{
ResteasyProviderFactory result = instance;
if (result == null)
{ // First check (no locking)
synchronized (RD_LOCK)
{
result = instance;
if (result == null)
{ // Second check (with locking)
RuntimeDelegate runtimeDelegate = RuntimeDelegate.getInstance();
if (runtimeDelegate instanceof ResteasyProviderFactory)
{
instance = result = (ResteasyProviderFactory) runtimeDelegate;
}
else
{
instance = result = new ResteasyProviderFactory();
}
if (registerBuiltinByDefault) RegisterBuiltin.register(instance);
}
}
}
return instance;
}
public static ResteasyProviderFactory newInstance()
{
return new ResteasyProviderFactory();
}
public static void setRegisterBuiltinByDefault(boolean registerBuiltinByDefault)
{
ResteasyProviderFactory.registerBuiltinByDefault = registerBuiltinByDefault;
}
public boolean isRegisterBuiltins()
{
return registerBuiltins;
}
public void setRegisterBuiltins(boolean registerBuiltins)
{
this.registerBuiltins = registerBuiltins;
}
public InjectorFactory getInjectorFactory()
{
if (injectorFactory == null && parent != null) return parent.getInjectorFactory();
return injectorFactory;
}
public void setInjectorFactory(InjectorFactory injectorFactory)
{
this.injectorFactory = injectorFactory;
}
public ReaderInterceptorRegistry getServerReaderInterceptorRegistry()
{
if (serverReaderInterceptorRegistry == null && parent != null) return parent.getServerReaderInterceptorRegistry();
return serverReaderInterceptorRegistry;
}
public WriterInterceptorRegistry getServerWriterInterceptorRegistry()
{
if (serverWriterInterceptorRegistry == null && parent != null) return parent.getServerWriterInterceptorRegistry();
return serverWriterInterceptorRegistry;
}
public ContainerRequestFilterRegistry getContainerRequestFilterRegistry()
{
if (containerRequestFilterRegistry == null && parent != null) return parent.getContainerRequestFilterRegistry();
return containerRequestFilterRegistry;
}
public ContainerResponseFilterRegistry getContainerResponseFilterRegistry()
{
if (containerResponseFilterRegistry == null && parent != null) return parent.getContainerResponseFilterRegistry();
return containerResponseFilterRegistry;
}
public ReaderInterceptorRegistry getClientReaderInterceptorRegistry()
{
if (clientReaderInterceptorRegistry == null && parent != null) return parent.getClientReaderInterceptorRegistry();
return clientReaderInterceptorRegistry;
}
public WriterInterceptorRegistry getClientWriterInterceptorRegistry()
{
if (clientWriterInterceptorRegistry == null && parent != null) return parent.getClientWriterInterceptorRegistry();
return clientWriterInterceptorRegistry;
}
public ClientRequestFilterRegistry getClientRequestFilterRegistry()
{
if (clientRequestFilterRegistry == null && parent != null) return parent.getClientRequestFilterRegistry();
return clientRequestFilterRegistry;
}
public ClientResponseFilterRegistry getClientResponseFilters()
{
if (clientResponseFilters == null && parent != null) return parent.getClientResponseFilters();
return clientResponseFilters;
}
public boolean isBuiltinsRegistered()
{
return builtinsRegistered;
}
public void setBuiltinsRegistered(boolean builtinsRegistered)
{
this.builtinsRegistered = builtinsRegistered;
}
public UriBuilder createUriBuilder()
{
return new ResteasyUriBuilder();
}
public Response.ResponseBuilder createResponseBuilder()
{
return new ResponseBuilderImpl();
}
public Variant.VariantListBuilder createVariantListBuilder()
{
return new VariantListBuilderImpl();
}
public HeaderDelegate createHeaderDelegate(Class tClass)
{
if (tClass == null) throw new IllegalArgumentException(Messages.MESSAGES.tClassParameterNull());
if (headerDelegates == null && parent != null) return parent.createHeaderDelegate(tClass);
Class> clazz = tClass;
while (clazz != null)
{
HeaderDelegate delegate = headerDelegates.get(clazz);
if (delegate != null)
{
return delegate;
}
delegate = createHeaderDelegateFromInterfaces(clazz.getInterfaces());
if (delegate != null)
{
return delegate;
}
clazz = clazz.getSuperclass();
}
return createHeaderDelegateFromInterfaces(tClass.getInterfaces());
}
private HeaderDelegate createHeaderDelegateFromInterfaces(Class>[] interfaces)
{
HeaderDelegate delegate = null;
for (int i = 0; i < interfaces.length; i++)
{
delegate = headerDelegates.get(interfaces[i]);
if (delegate != null)
{
return delegate;
}
delegate = createHeaderDelegateFromInterfaces(interfaces[i].getInterfaces());
if (delegate != null)
{
return delegate;
}
}
return null;
}
private Map, HeaderDelegate> getHeaderDelegates()
{
if (headerDelegates == null && parent != null) return parent.getHeaderDelegates();
return headerDelegates;
}
public void addHeaderDelegate(Class clazz, HeaderDelegate header)
{
if (headerDelegates == null)
{
headerDelegates = new ConcurrentHashMap, HeaderDelegate>();
headerDelegates.putAll(parent.getHeaderDelegates());
}
headerDelegates.put(clazz, header);
}
/**
* Specify the provider class. This is there jsut in case the provider instance is a proxy. Proxies tend
* to lose generic type information.
*
* @param provider message reader
* @param providerClass provider class
* @param priority priority
* @param isBuiltin built-in
*/
private void addMessageBodyReader(MessageBodyReader provider, Class> providerClass, int priority, boolean isBuiltin)
{
SortedKey key = new SortedKey(MessageBodyReader.class, provider, providerClass, priority, isBuiltin);
injectProperties(providerClass, provider);
Consumes consumeMime = provider.getClass().getAnnotation(Consumes.class);
RuntimeType type = null;
ConstrainedTo constrainedTo = providerClass.getAnnotation(ConstrainedTo.class);
if (constrainedTo != null) type = constrainedTo.value();
if ((type == null || type == RuntimeType.CLIENT) && clientMessageBodyReaders == null)
{
clientMessageBodyReaders = parent.getClientMessageBodyReaders().clone();
}
if ((type == null || type == RuntimeType.SERVER) && serverMessageBodyReaders == null)
{
serverMessageBodyReaders = parent.getServerMessageBodyReaders().clone();
}
if (consumeMime != null)
{
for (String consume : consumeMime.value())
{
if (type == null) {
clientMessageBodyReaders.add(MediaType.valueOf(consume), key);
serverMessageBodyReaders.add(MediaType.valueOf(consume), key);
} else if (type == RuntimeType.CLIENT) {
clientMessageBodyReaders.add(MediaType.valueOf(consume), key);
} else {
serverMessageBodyReaders.add(MediaType.valueOf(consume), key);
}
}
}
else
{
if (type == null) {
clientMessageBodyReaders.add(new MediaType("*", "*"), key);
serverMessageBodyReaders.add(new MediaType("*", "*"), key);
} else if (type == RuntimeType.CLIENT) {
clientMessageBodyReaders.add(new MediaType("*", "*"), key);
} else {
serverMessageBodyReaders.add(new MediaType("*", "*"), key);
}
}
}
/**
* Specify the provider class. This is there jsut in case the provider instance is a proxy. Proxies tend
* to lose generic type information
*
* @param provider message reader
* @param providerClass provider class
* @param priority priority
* @param isBuiltin built-in
*/
private void addMessageBodyWriter(MessageBodyWriter provider, Class> providerClass, int priority, boolean isBuiltin)
{
injectProperties(providerClass, provider);
Produces consumeMime = provider.getClass().getAnnotation(Produces.class);
SortedKey key = new SortedKey(MessageBodyWriter.class, provider, providerClass, priority, isBuiltin);
RuntimeType type = null;
ConstrainedTo constrainedTo = providerClass.getAnnotation(ConstrainedTo.class);
if (constrainedTo != null) type = constrainedTo.value();
if ((type == null || type == RuntimeType.CLIENT) && clientMessageBodyWriters == null)
{
clientMessageBodyWriters = parent.getClientMessageBodyWriters().clone();
}
if ((type == null || type == RuntimeType.SERVER) && serverMessageBodyWriters == null)
{
serverMessageBodyWriters = parent.getServerMessageBodyWriters().clone();
}
if (consumeMime != null)
{
for (String consume : consumeMime.value())
{
//logger.info(">>> Adding provider: " + provider.getClass().getName() + " with mime type of: " + mime);
if (type == null) {
clientMessageBodyWriters.add(MediaType.valueOf(consume), key);
serverMessageBodyWriters.add(MediaType.valueOf(consume), key);
} else if (type == RuntimeType.CLIENT) {
clientMessageBodyWriters.add(MediaType.valueOf(consume), key);
} else {
serverMessageBodyWriters.add(MediaType.valueOf(consume), key);
}
}
}
else
{
//logger.info(">>> Adding provider: " + provider.getClass().getName() + " with mime type of: default */*");
if (type == null) {
clientMessageBodyWriters.add(new MediaType("*", "*"), key);
serverMessageBodyWriters.add(new MediaType("*", "*"), key);
} else if (type == RuntimeType.CLIENT) {
clientMessageBodyWriters.add(new MediaType("*", "*"), key);
} else {
serverMessageBodyWriters.add(new MediaType("*", "*"), key);
}
}
}
@Deprecated
public MessageBodyReader getServerMessageBodyReader(Class type, Type genericType, Annotation[] annotations, MediaType mediaType)
{
MediaTypeMap> availableReaders = getServerMessageBodyReaders();
return resolveMessageBodyReader(type, genericType, annotations, mediaType, availableReaders);
}
public MessageBodyReader getServerMessageBodyReader(Class type, Type genericType, Annotation[] annotations, MediaType mediaType, RESTEasyTracingLogger tracingLogger)
{
MediaTypeMap> availableReaders = getServerMessageBodyReaders();
return resolveMessageBodyReader(type, genericType, annotations, mediaType, availableReaders, tracingLogger);
}
/**
* Always returns server MBRs.
*
* @param type the class of the object that is to be read.
* @param genericType the type of object to be produced. E.g. if the
* message body is to be converted into a method parameter, this will be
* the formal type of the method parameter as returned by
* {@code Class.getGenericParameterTypes}.
* @param annotations an array of the annotations on the declaration of the
* artifact that will be initialized with the produced instance. E.g. if
* the message body is to be converted into a method parameter, this will
* be the annotations on that parameter returned by
* {@code Class.getParameterAnnotations}.
* @param mediaType the media type of the data that will be read.
* @param type
* @return message reader
*/
public MessageBodyReader getMessageBodyReader(Class type, Type genericType, Annotation[] annotations, MediaType mediaType)
{
MediaTypeMap> availableReaders = getServerMessageBodyReaders();
MessageBodyReader reader = resolveMessageBodyReader(type, genericType, annotations, mediaType, availableReaders);
if (reader!=null)
LogMessages.LOGGER.debugf("MessageBodyReader: %s", reader.getClass().getName());
return reader;
}
public MessageBodyReader getClientMessageBodyReader(Class type, Type genericType, Annotation[] annotations, MediaType mediaType)
{
MediaTypeMap> availableReaders = getClientMessageBodyReaders();
return resolveMessageBodyReader(type, genericType, annotations, mediaType, availableReaders);
}
@Deprecated
private MessageBodyReader resolveMessageBodyReader(Class type, Type genericType, Annotation[] annotations, MediaType mediaType, MediaTypeMap> availableReaders)
{
List> readers = availableReaders.getPossible(mediaType, type);
//logger.info("******** getMessageBodyReader *******");
for (SortedKey reader : readers)
{
//logger.info(" matching reader: " + reader.getClass().getName());
if (reader.obj.isReadable(type, genericType, annotations, mediaType))
{
LogMessages.LOGGER.debugf("MessageBodyReader: %s", reader.getClass().getName());
return (MessageBodyReader) reader.obj;
}
}
return null;
}
protected MessageBodyReader resolveMessageBodyReader(Class type,
Type genericType,
Annotation[] annotations,
MediaType mediaType,
MediaTypeMap> availableReaders,
RESTEasyTracingLogger tracingLogger) {
List> readers = availableReaders.getPossible(mediaType, type);
if (tracingLogger.isLogEnabled("MBR_FIND")) {
tracingLogger.log("MBR_FIND",
type.getName(),
(genericType instanceof Class ? ((Class) genericType).getName() : genericType),
mediaType,
java.util.Arrays.toString(annotations));
}
MessageBodyReader result = null;
Iterator> iterator = readers.iterator();
while (iterator.hasNext()) {
final SortedKey reader = iterator.next();
if (reader.obj.isReadable(type, genericType, annotations, mediaType)) {
LogMessages.LOGGER.debugf("MessageBodyReader: %s", reader.getClass().getName());
result = (MessageBodyReader) reader.obj;
tracingLogger.log("MBR_SELECTED", reader);
break;
}
tracingLogger.log("MBR_NOT_READABLE", result);
}
if (tracingLogger.isLogEnabled("MBR_SKIPPED")) {
while (iterator.hasNext()) {
final SortedKey reader = iterator.next();
tracingLogger.log("MBR_SKIPPED", reader.obj);
}
}
return result;
}
private void addExceptionMapper(ExceptionMapper provider, Class providerClass, boolean isBuiltin)
{
// Check for weld proxy.
if (providerClass.isSynthetic())
{
providerClass = providerClass.getSuperclass();
}
Type exceptionType = Types.getActualTypeArgumentsOfAnInterface(providerClass, ExceptionMapper.class)[0];
injectProperties(providerClass, provider);
Class> exceptionClass = Types.getRawType(exceptionType);
if (!Throwable.class.isAssignableFrom(exceptionClass))
{
throw new RuntimeException(Messages.MESSAGES.incorrectTypeParameterExceptionMapper());
}
if (sortedExceptionMappers == null)
{
sortedExceptionMappers = new ConcurrentHashMap, SortedKey>();
sortedExceptionMappers.putAll(parent.getSortedExceptionMappers());
}
int priority = getPriority(null, null, ExceptionMapper.class, providerClass);
SortedKey candidateExceptionMapper = new SortedKey<>(null, provider, providerClass, priority, isBuiltin);
SortedKey registeredExceptionMapper;
if ((registeredExceptionMapper = sortedExceptionMappers.get(exceptionClass)) != null
&& (candidateExceptionMapper.compareTo(registeredExceptionMapper) > 0)) {
return;
}
sortedExceptionMappers.put(exceptionClass, candidateExceptionMapper);
exceptionMappers = null;
}
private void addAsyncResponseProvider(AsyncResponseProvider provider, Class providerClass)
{
Type asyncType = Types.getActualTypeArgumentsOfAnInterface(providerClass, AsyncResponseProvider.class)[0];
injectProperties(provider.getClass(), provider);
Class> asyncClass = Types.getRawType(asyncType);
if (asyncResponseProviders == null)
{
asyncResponseProviders = new ConcurrentHashMap, AsyncResponseProvider>();
asyncResponseProviders.putAll(parent.getAsyncResponseProviders());
}
asyncResponseProviders.put(asyncClass, provider);
}
private void addAsyncClientResponseProvider(AsyncClientResponseProvider provider, Class providerClass)
{
Type asyncType = Types.getActualTypeArgumentsOfAnInterface(providerClass, AsyncClientResponseProvider.class)[0];
injectProperties(provider.getClass(), provider);
Class> asyncClass = Types.getRawType(asyncType);
if (asyncClientResponseProviders == null)
{
asyncClientResponseProviders = new ConcurrentHashMap, AsyncClientResponseProvider>();
asyncClientResponseProviders.putAll(parent.getAsyncClientResponseProviders());
}
asyncClientResponseProviders.put(asyncClass, provider);
}
private void addAsyncStreamProvider(AsyncStreamProvider provider, Class providerClass)
{
Type asyncType = Types.getActualTypeArgumentsOfAnInterface(providerClass, AsyncStreamProvider.class)[0];
injectProperties(provider.getClass(), provider);
Class> asyncClass = Types.getRawType(asyncType);
if (asyncStreamProviders == null)
{
asyncStreamProviders = new ConcurrentHashMap, AsyncStreamProvider>();
asyncStreamProviders.putAll(parent.getAsyncStreamProviders());
}
asyncStreamProviders.put(asyncClass, provider);
}
private void addContextInjector(ContextInjector provider, Class providerClass)
{
Type[] typeArgs = Types.getActualTypeArgumentsOfAnInterface(providerClass, ContextInjector.class);
injectProperties(provider.getClass(), provider);
if (contextInjectors == null)
{
contextInjectors = new ConcurrentHashMap();
contextInjectors.putAll(parent.getContextInjectors());
}
contextInjectors.put(typeArgs[0], provider);
if(!Objects.equals(typeArgs[0], typeArgs[1]))
{
if (asyncContextInjectors == null)
{
asyncContextInjectors = new ConcurrentHashMap();
asyncContextInjectors.putAll(parent.getAsyncContextInjectors());
}
asyncContextInjectors.put(typeArgs[1], provider);
}
}
private void addContextResolver(ContextResolver provider, Class providerClass, boolean builtin)
{
// RESTEASY-1725
if (providerClass.getName().contains("$$Lambda$")) {
throw new RuntimeException(Messages.MESSAGES.registeringContextResolverAsLambda());
}
Type typeParameter = Types.getActualTypeArgumentsOfAnInterface(providerClass, ContextResolver.class)[0];
injectProperties(providerClass, provider);
Class> parameterClass = Types.getRawType(typeParameter);
if (contextResolvers == null)
{
contextResolvers = new ConcurrentHashMap, MediaTypeMap>>();
for (Map.Entry, MediaTypeMap>> entry : parent.getContextResolvers().entrySet())
{
contextResolvers.put(entry.getKey(), entry.getValue().clone());
}
}
MediaTypeMap> resolvers = contextResolvers.get(parameterClass);
if (resolvers == null)
{
resolvers = new MediaTypeMap>();
contextResolvers.put(parameterClass, resolvers);
}
Produces produces = provider.getClass().getAnnotation(Produces.class);
int priority = this.getPriority(null, null, ContextResolver.class, providerClass);
SortedKey key = new SortedKey(ContextResolver.class, provider, providerClass, priority, builtin);
if (produces != null)
{
for (String produce : produces.value())
{
MediaType mime = MediaType.valueOf(produce);
resolvers.add(mime, key);
}
}
else
{
resolvers.add(new MediaType("*", "*"), key);
}
}
private void addStringParameterUnmarshaller(Class extends StringParameterUnmarshaller> provider)
{
if (stringParameterUnmarshallers == null)
{
stringParameterUnmarshallers = new ConcurrentHashMap, Class extends StringParameterUnmarshaller>>();
stringParameterUnmarshallers.putAll(parent.getStringParameterUnmarshallers());
}
Type[] intfs = provider.getGenericInterfaces();
for (Type type : intfs)
{
if (type instanceof ParameterizedType)
{
ParameterizedType pt = (ParameterizedType) type;
if (pt.getRawType().equals(StringParameterUnmarshaller.class))
{
Class> aClass = Types.getRawType(pt.getActualTypeArguments()[0]);
stringParameterUnmarshallers.put(aClass, provider);
}
}
}
}
public List getContextResolvers(final Class> clazz, MediaType type)
{
MediaTypeMap> resolvers = getContextResolvers().get(clazz);
if (resolvers == null) return null;
List rtn = new ArrayList();
List> list = resolvers.getPossible(type);
if (type.isWildcardType())
{
// do it upside down if it is a wildcard type: Note: this is to pass the stupid TCK which prefers that
// a wildcard type match up with other wildcard types
// for (int i = list.size() - 1; i >= 0; i--)
// {
// rtn.add(list.get(i).obj);
// }
// Fix for RESTEASY-1609.
// This is related to the fix in RESTEASY-1471, prior to which user ContextResolvers appeared
// to be built-in. The original loop may have been in response to that bug, so the reversal
// may not be necessary. In any case, this code will do the reversal but put user ContextResolvers
// at the beginning of the list.
for (int i = list.size() - 1; i >= 0; i--)
{
if (!list.get(i).isBuiltin)
{
rtn.add(list.get(i).obj);
}
}
for (int i = list.size() - 1; i >= 0; i--)
{
if (list.get(i).isBuiltin)
{
rtn.add(list.get(i).obj);
}
}
}
else
{
for (SortedKey resolver : list)
{
rtn.add(resolver.obj);
}
}
return rtn;
}
public ParamConverter getParamConverter(Class clazz, Type genericType, Annotation[] annotations)
{
for (SortedKey provider : getSortedParamConverterProviders())
{
ParamConverter converter = provider.getObj().getConverter(clazz, genericType, annotations);
if (converter != null) return converter;
}
return null;
}
public StringParameterUnmarshaller createStringParameterUnmarshaller(Class clazz)
{
if (getStringParameterUnmarshallers().size() == 0) return null;
Class extends StringParameterUnmarshaller> un = getStringParameterUnmarshallers().get(clazz);
if (un == null) return null;
StringParameterUnmarshaller provider = injectedInstance(un);
return provider;
}
public void registerProvider(Class provider)
{
registerProvider(provider, false);
}
/**
* Convert an object to a string. First try StringConverter then, object.ToString()
*
* @param object object
* @param clazz class
* @param genericType generic type
* @param annotations array of annotation
* @return string representation
*/
public String toString(Object object, Class clazz, Type genericType, Annotation[] annotations)
{
if (object instanceof String)
return (String) object;
ParamConverter paramConverter = getParamConverter(clazz, genericType, annotations);
if (paramConverter != null)
{
return paramConverter.toString(object);
}
return object.toString();
}
@Override
public String toHeaderString(Object object)
{
if (object == null) return "";
if (object instanceof String) return (String) object;
Class> aClass = object.getClass();
ParamConverter paramConverter = getParamConverter(aClass, null, null);
if (paramConverter != null)
{
return paramConverter.toString(object);
}
HeaderDelegate delegate = getHeaderDelegate(aClass);
if (delegate != null)
return delegate.toString(object);
else
return object.toString();
}
/**
* Checks to see if RuntimeDelegate is a ResteasyProviderFactory
* If it is, then use that, otherwise use this.
*
* @param aClass class of the header
* @return header delegate
*/
public HeaderDelegate getHeaderDelegate(Class> aClass)
{
HeaderDelegate delegate = null;
// Stupid idiotic TCK calls RuntimeDelegate.setInstance()
if (RuntimeDelegate.getInstance() instanceof ResteasyProviderFactory)
{
delegate = createHeaderDelegate(aClass);
}
else
{
delegate = RuntimeDelegate.getInstance().createHeaderDelegate(aClass);
}
return delegate;
}
/**
* Register a @Provider class. Can be a MessageBodyReader/Writer or ExceptionMapper.
*
* @param provider provider class
* @param isBuiltin built-in
*/
public void registerProvider(Class provider, boolean isBuiltin)
{
registerProvider(provider, null, isBuiltin, null);
}
protected static boolean isA(Class target, Class type, Map, Integer> contracts)
{
if (!type.isAssignableFrom(target)) return false;
if (contracts == null || contracts.size() == 0) return true;
for (Class> contract : contracts.keySet())
{
if (contract.equals(type)) return true;
}
return false;
}
protected static boolean isA(Object target, Class type, Map, Integer> contracts)
{
return isA(target.getClass(), type, contracts);
}
private static int getPriority(Integer override, Map, Integer> contracts, Class type, Class> component)
{
if (override != null) return override;
if (contracts != null)
{
Integer p = contracts.get(type);
if (p != null) return p;
}
// Check for weld proxy.
component = component.isSynthetic() ? component.getSuperclass() : component;
Priority priority = component.getAnnotation(Priority.class);
if (priority == null) return Priorities.USER;
return priority.value();
}
public void registerProvider(Class provider, Integer priorityOverride, boolean isBuiltin, Map, Integer> contracts)
{
if (getClasses().contains(provider))
{
LogMessages.LOGGER.providerClassAlreadyRegistered(provider.getName());
return;
}
for (Object registered : getInstances())
{
if (registered.getClass() == provider)
{
LogMessages.LOGGER.providerClassAlreadyRegistered(provider.getName());
return;
}
}
Map, Integer> newContracts = new HashMap, Integer>();
processProviderContracts(provider, priorityOverride, isBuiltin, contracts, newContracts);
providerClasses.add(provider);
getClassContracts().put(provider, newContracts);
}
protected void processProviderContracts(Class provider, Integer priorityOverride, boolean isBuiltin,
Map, Integer> contracts, Map, Integer> newContracts)
{
if (isA(provider, ParamConverterProvider.class, contracts))
{
ParamConverterProvider paramConverterProvider = (ParamConverterProvider) injectedInstance(provider);
injectProperties(provider);
if (sortedParamConverterProviders == null)
{
sortedParamConverterProviders = Collections.synchronizedSortedSet(new TreeSet<>(parent.getSortedParamConverterProviders()));
}
int priority = getPriority(priorityOverride, contracts, ParamConverterProvider.class, provider);
sortedParamConverterProviders.add(new ExtSortedKey<>(null, paramConverterProvider, provider, priority, isBuiltin));
newContracts.put(ParamConverterProvider.class, priority);
}
if (isA(provider, MessageBodyReader.class, contracts))
{
try
{
int priority = getPriority(priorityOverride, contracts, MessageBodyReader.class, provider);
addMessageBodyReader(createProviderInstance((Class extends MessageBodyReader>)provider), provider, priority, isBuiltin);
newContracts.put(MessageBodyReader.class, priority);
}
catch (Exception e)
{
throw new RuntimeException(Messages.MESSAGES.unableToInstantiateMessageBodyReader(), e);
}
}
if (isA(provider, MessageBodyWriter.class, contracts))
{
try
{
int priority = getPriority(priorityOverride, contracts, MessageBodyWriter.class, provider);
addMessageBodyWriter(createProviderInstance((Class extends MessageBodyWriter>)provider), provider, priority, isBuiltin);
newContracts.put(MessageBodyWriter.class, priority);
}
catch (Exception e)
{
throw new RuntimeException(Messages.MESSAGES.unableToInstantiateMessageBodyWriter(), e);
}
}
if (isA(provider, ExceptionMapper.class, contracts))
{
try
{
addExceptionMapper(createProviderInstance((Class extends ExceptionMapper>) provider), provider, isBuiltin);
newContracts.put(ExceptionMapper.class, getPriority(priorityOverride, contracts, ExceptionMapper.class, provider));
}
catch (Exception e)
{
throw new RuntimeException(Messages.MESSAGES.unableToInstantiateExceptionMapper(), e);
}
}
if (isA(provider, AsyncResponseProvider.class, contracts))
{
try
{
addAsyncResponseProvider(createProviderInstance((Class extends AsyncResponseProvider>) provider), provider);
newContracts.put(AsyncResponseProvider.class, getPriority(priorityOverride, contracts, AsyncResponseProvider.class, provider));
}
catch (Exception e)
{
throw new RuntimeException(Messages.MESSAGES.unableToInstantiateAsyncResponseProvider(), e);
}
}
if (isA(provider, AsyncClientResponseProvider.class, contracts))
{
try
{
addAsyncClientResponseProvider(createProviderInstance((Class extends AsyncClientResponseProvider>) provider), provider);
newContracts.put(AsyncClientResponseProvider.class, getPriority(priorityOverride, contracts, AsyncClientResponseProvider.class, provider));
}
catch (Exception e)
{
throw new RuntimeException(Messages.MESSAGES.unableToInstantiateAsyncClientResponseProvider(), e);
}
}
if (isA(provider, AsyncStreamProvider.class, contracts))
{
try
{
addAsyncStreamProvider(createProviderInstance((Class extends AsyncStreamProvider>)provider), provider);
newContracts.put(AsyncStreamProvider.class, getPriority(priorityOverride, contracts, AsyncStreamProvider.class, provider));
}
catch (Exception e)
{
throw new RuntimeException(Messages.MESSAGES.unableToInstantiateAsyncStreamProvider(), e);
}
}
if (isA(provider, ClientRequestFilter.class, contracts))
{
if (clientRequestFilterRegistry == null)
{
clientRequestFilterRegistry = parent.getClientRequestFilterRegistry().clone(this);
}
int priority = getPriority(priorityOverride, contracts, ClientRequestFilter.class, provider);
clientRequestFilterRegistry.registerClass(provider, priority);
newContracts.put(ClientRequestFilter.class, priority);
}
if (isA(provider, ClientResponseFilter.class, contracts))
{
if (clientResponseFilters == null)
{
clientResponseFilters = parent.getClientResponseFilters().clone(this);
}
int priority = getPriority(priorityOverride, contracts, ClientResponseFilter.class, provider);
clientResponseFilters.registerClass(provider, priority);
newContracts.put(ClientResponseFilter.class, priority);
}
if (isA(provider, ContainerRequestFilter.class, contracts))
{
if (containerRequestFilterRegistry == null)
{
containerRequestFilterRegistry = parent.getContainerRequestFilterRegistry().clone(this);
}
int priority = getPriority(priorityOverride, contracts, ContainerRequestFilter.class, provider);
containerRequestFilterRegistry.registerClass(provider, priority);
newContracts.put(ContainerRequestFilter.class, priority);
}
if (isA(provider, ContainerResponseFilter.class, contracts))
{
if (containerResponseFilterRegistry == null)
{
containerResponseFilterRegistry = parent.getContainerResponseFilterRegistry().clone(this);
}
int priority = getPriority(priorityOverride, contracts, ContainerResponseFilter.class, provider);
containerResponseFilterRegistry.registerClass(provider, priority);
newContracts.put(ContainerResponseFilter.class, priority);
}
if (isA(provider, ReaderInterceptor.class, contracts))
{
ConstrainedTo constrainedTo = (ConstrainedTo) provider.getAnnotation(ConstrainedTo.class);
int priority = getPriority(priorityOverride, contracts, ReaderInterceptor.class, provider);
if (constrainedTo != null && constrainedTo.value() == RuntimeType.SERVER)
{
if (serverReaderInterceptorRegistry == null)
{
serverReaderInterceptorRegistry = parent.getServerReaderInterceptorRegistry().clone(this);
}
serverReaderInterceptorRegistry.registerClass(provider, priority);
}
if (constrainedTo != null && constrainedTo.value() == RuntimeType.CLIENT)
{
if (clientReaderInterceptorRegistry == null)
{
clientReaderInterceptorRegistry = parent.getClientReaderInterceptorRegistry().clone(this);
}
clientReaderInterceptorRegistry.registerClass(provider, priority);
}
if (constrainedTo == null)
{
if (serverReaderInterceptorRegistry == null)
{
serverReaderInterceptorRegistry = parent.getServerReaderInterceptorRegistry().clone(this);
}
serverReaderInterceptorRegistry.registerClass(provider, priority);
if (clientReaderInterceptorRegistry == null)
{
clientReaderInterceptorRegistry = parent.getClientReaderInterceptorRegistry().clone(this);
}
clientReaderInterceptorRegistry.registerClass(provider, priority);
}
newContracts.put(ReaderInterceptor.class, priority);
}
if (isA(provider, WriterInterceptor.class, contracts))
{
ConstrainedTo constrainedTo = (ConstrainedTo) provider.getAnnotation(ConstrainedTo.class);
int priority = getPriority(priorityOverride, contracts, WriterInterceptor.class, provider);
if (constrainedTo != null && constrainedTo.value() == RuntimeType.SERVER)
{
if (serverWriterInterceptorRegistry == null)
{
serverWriterInterceptorRegistry = parent.getServerWriterInterceptorRegistry().clone(this);
}
serverWriterInterceptorRegistry.registerClass(provider, priority);
}
if (constrainedTo != null && constrainedTo.value() == RuntimeType.CLIENT)
{
if (clientWriterInterceptorRegistry == null)
{
clientWriterInterceptorRegistry = parent.getClientWriterInterceptorRegistry().clone(this);
}
clientWriterInterceptorRegistry.registerClass(provider, priority);
}
if (constrainedTo == null)
{
if (serverWriterInterceptorRegistry == null)
{
serverWriterInterceptorRegistry = parent.getServerWriterInterceptorRegistry().clone(this);
}
serverWriterInterceptorRegistry.registerClass(provider, priority);
if (clientWriterInterceptorRegistry == null)
{
clientWriterInterceptorRegistry = parent.getClientWriterInterceptorRegistry().clone(this);
}
clientWriterInterceptorRegistry.registerClass(provider, priority);
}
newContracts.put(WriterInterceptor.class, priority);
}
if (isA(provider, ContextResolver.class, contracts))
{
try
{
addContextResolver(createProviderInstance((Class extends ContextResolver>)provider), provider, isBuiltin);
int priority = getPriority(priorityOverride, contracts, ContextResolver.class, provider);
newContracts.put(ContextResolver.class, priority);
}
catch (Exception e)
{
throw new RuntimeException(Messages.MESSAGES.unableToInstantiateContextResolver(), e);
}
}
if (isA(provider, ContextInjector.class, contracts))
{
try
{
addContextInjector(createProviderInstance((Class extends ContextInjector>) provider), provider);
int priority = getPriority(priorityOverride, contracts, ContextInjector.class, provider);
newContracts.put(ContextInjector.class, priority);
}
catch (Exception e)
{
throw new RuntimeException(Messages.MESSAGES.unableToInstantiateContextInjector(), e);
}
}
if (isA(provider, StringParameterUnmarshaller.class, contracts))
{
addStringParameterUnmarshaller(provider);
int priority = getPriority(priorityOverride, contracts, StringParameterUnmarshaller.class, provider);
newContracts.put(StringParameterUnmarshaller.class, priority);
}
if (isA(provider, InjectorFactory.class, contracts))
{
try
{
this.injectorFactory = (InjectorFactory) provider.newInstance();
newContracts.put(InjectorFactory.class, 0);
}
catch (Exception e)
{
throw new RuntimeException(e);
}
}
if (isA(provider, DynamicFeature.class, contracts))
{
ConstrainedTo constrainedTo = (ConstrainedTo) provider.getAnnotation(ConstrainedTo.class);
int priority = getPriority(priorityOverride, contracts, DynamicFeature.class, provider);
if (constrainedTo != null && constrainedTo.value() == RuntimeType.SERVER)
{
if (serverDynamicFeatures == null)
{
serverDynamicFeatures = new CopyOnWriteArraySet(parent.getServerDynamicFeatures());
}
serverDynamicFeatures.add((DynamicFeature) injectedInstance(provider));
}
if (constrainedTo != null && constrainedTo.value() == RuntimeType.CLIENT)
{
if (clientDynamicFeatures == null)
{
clientDynamicFeatures = new CopyOnWriteArraySet(parent.getClientDynamicFeatures());
}
clientDynamicFeatures.add((DynamicFeature) injectedInstance(provider));
}
if (constrainedTo == null)
{
if (serverDynamicFeatures == null)
{
serverDynamicFeatures = new CopyOnWriteArraySet(parent.getServerDynamicFeatures());
}
serverDynamicFeatures.add((DynamicFeature) injectedInstance(provider));
if (clientDynamicFeatures == null)
{
clientDynamicFeatures = new CopyOnWriteArraySet(parent.getClientDynamicFeatures());
}
clientDynamicFeatures.add((DynamicFeature) injectedInstance(provider));
}
newContracts.put(DynamicFeature.class, priority);
}
if (isA(provider, Feature.class, contracts))
{
ConstrainedTo constrainedTo = (ConstrainedTo) provider.getAnnotation(ConstrainedTo.class);
int priority = getPriority(priorityOverride, contracts, Feature.class, provider);
Feature feature = injectedInstance((Class extends Feature>) provider);
if (constrainedTo == null || constrainedTo.value() == getRuntimeType()) {
if (feature.configure(new FeatureContextDelegate(this)))
{
enabledFeatures.add(feature);
}
}
newContracts.put(Feature.class, priority);
}
if (isA(provider, RxInvokerProvider.class, contracts))
{
int priority = getPriority(priorityOverride, contracts, RxInvokerProvider.class, provider);
newContracts.put(RxInvokerProvider.class, priority);
Class> clazz = Types.getTemplateParameterOfInterface(provider, RxInvokerProvider.class);
clazz = Types.getTemplateParameterOfInterface(clazz, RxInvoker.class);
if (clazz != null)
{
reactiveClasses.put(clazz, provider);
}
}
if (isA(provider, ResourceClassProcessor.class, contracts))
{
int priority = getPriority(priorityOverride, contracts, ResourceClassProcessor.class, provider);
addResourceClassProcessor(provider, priority);
newContracts.put(ResourceClassProcessor.class, priority);
}
}
/**
* Register a @Provider object. Can be a MessageBodyReader/Writer or ExceptionMapper.
*
* @param provider provider instance
*/
public void registerProviderInstance(Object provider)
{
registerProviderInstance(provider, null, null, false);
}
public void registerProviderInstance(Object provider, Map, Integer> contracts, Integer priorityOverride, boolean builtIn)
{
for (Object registered : getInstances())
{
if (registered == provider)
{
LogMessages.LOGGER.providerInstanceAlreadyRegistered(provider.getClass().getName());
return;
}
}
if (getClasses().contains(provider.getClass()))
{
LogMessages.LOGGER.providerClassAlreadyRegistered(provider.getClass().getName());
return;
}
Map, Integer> newContracts = new HashMap, Integer>();
processProviderInstanceContracts(provider, contracts, priorityOverride, builtIn, newContracts);
providerInstances.add(provider);
getClassContracts().put(provider.getClass(), newContracts);
}
protected void processProviderInstanceContracts(Object provider, Map, Integer> contracts,
Integer priorityOverride, boolean builtIn, Map, Integer> newContracts)
{
if (isA(provider, ParamConverterProvider.class, contracts))
{
injectProperties(provider);
if (sortedParamConverterProviders == null)
{
sortedParamConverterProviders = Collections.synchronizedSortedSet(new TreeSet<>(parent.getSortedParamConverterProviders()));
}
int priority = getPriority(priorityOverride, contracts, ParamConverterProvider.class, provider.getClass());
sortedParamConverterProviders.add(new ExtSortedKey<>(null, (ParamConverterProvider) provider, provider.getClass(), priority, builtIn));
newContracts.put(ParamConverterProvider.class, priority);
}
if (isA(provider, MessageBodyReader.class, contracts))
{
try
{
int priority = getPriority(priorityOverride, contracts, MessageBodyReader.class, provider.getClass());
addMessageBodyReader((MessageBodyReader) provider, provider.getClass(), priority, builtIn);
newContracts.put(MessageBodyReader.class, priority);
}
catch (Exception e)
{
throw new RuntimeException(Messages.MESSAGES.unableToInstantiateMessageBodyReader(), e);
}
}
if (isA(provider, MessageBodyWriter.class, contracts))
{
try
{
int priority = getPriority(priorityOverride, contracts, MessageBodyWriter.class, provider.getClass());
addMessageBodyWriter((MessageBodyWriter) provider, provider.getClass(), priority, builtIn);
newContracts.put(MessageBodyWriter.class, priority);
}
catch (Exception e)
{
throw new RuntimeException(Messages.MESSAGES.unableToInstantiateMessageBodyWriter(), e);
}
}
if (isA(provider, ExceptionMapper.class, contracts))
{
try
{
addExceptionMapper((ExceptionMapper) provider, provider.getClass(), builtIn);
int priority = getPriority(priorityOverride, contracts, ExceptionMapper.class, provider.getClass());
newContracts.put(ExceptionMapper.class, priority);
}
catch (Exception e)
{
throw new RuntimeException(Messages.MESSAGES.unableToInstantiateExceptionMapper(), e);
}
}
if (isA(provider, AsyncResponseProvider.class, contracts))
{
try
{
addAsyncResponseProvider((AsyncResponseProvider) provider, provider.getClass());
int priority = getPriority(priorityOverride, contracts, AsyncResponseProvider.class, provider.getClass());
newContracts.put(AsyncResponseProvider.class, priority);
}
catch (Exception e)
{
throw new RuntimeException(Messages.MESSAGES.unableToInstantiateAsyncResponseProvider(), e);
}
}
if (isA(provider, AsyncClientResponseProvider.class, contracts))
{
try
{
addAsyncClientResponseProvider((AsyncClientResponseProvider) provider, provider.getClass());
int priority = getPriority(priorityOverride, contracts, AsyncClientResponseProvider.class, provider.getClass());
newContracts.put(AsyncClientResponseProvider.class, priority);
}
catch (Exception e)
{
throw new RuntimeException(Messages.MESSAGES.unableToInstantiateAsyncClientResponseProvider(), e);
}
}
if (isA(provider, AsyncStreamProvider.class, contracts))
{
try
{
addAsyncStreamProvider((AsyncStreamProvider) provider, provider.getClass());
int priority = getPriority(priorityOverride, contracts, AsyncStreamProvider.class, provider.getClass());
newContracts.put(AsyncStreamProvider.class, priority);
}
catch (Exception e)
{
throw new RuntimeException(Messages.MESSAGES.unableToInstantiateAsyncStreamProvider(), e);
}
}
if (isA(provider, ContextResolver.class, contracts))
{
try
{
addContextResolver((ContextResolver) provider, provider.getClass(), false);
int priority = getPriority(priorityOverride, contracts, ContextResolver.class, provider.getClass());
newContracts.put(ContextResolver.class, priority);
}
catch (Exception e)
{
throw new RuntimeException(Messages.MESSAGES.unableToInstantiateContextResolver(), e);
}
}
if (isA(provider, ContextInjector.class, contracts))
{
try
{
addContextInjector((ContextInjector)provider, provider.getClass());
int priority = getPriority(priorityOverride, contracts, ContextInjector.class, provider.getClass());
newContracts.put(ContextInjector.class, priority);
}
catch (Exception e)
{
throw new RuntimeException(Messages.MESSAGES.unableToInstantiateContextInjector(), e);
}
}
if (isA(provider, ClientRequestFilter.class, contracts))
{
if (clientRequestFilterRegistry == null)
{
clientRequestFilterRegistry = parent.getClientRequestFilterRegistry().clone(this);
}
int priority = getPriority(priorityOverride, contracts, ClientRequestFilter.class, provider.getClass());
clientRequestFilterRegistry.registerSingleton((ClientRequestFilter) provider, priority);
newContracts.put(ClientRequestFilter.class, priority);
}
if (isA(provider, ClientResponseFilter.class, contracts))
{
if (clientResponseFilters == null)
{
clientResponseFilters = parent.getClientResponseFilters().clone(this);
}
int priority = getPriority(priorityOverride, contracts, ClientResponseFilter.class, provider.getClass());
clientResponseFilters.registerSingleton((ClientResponseFilter) provider, priority);
newContracts.put(ClientResponseFilter.class, priority);
}
if (isA(provider, ContainerRequestFilter.class, contracts))
{
if (containerRequestFilterRegistry == null)
{
containerRequestFilterRegistry = parent.getContainerRequestFilterRegistry().clone(this);
}
int priority = getPriority(priorityOverride, contracts, ContainerRequestFilter.class, provider.getClass());
containerRequestFilterRegistry.registerSingleton((ContainerRequestFilter) provider, priority);
newContracts.put(ContainerRequestFilter.class, priority);
}
if (isA(provider, ContainerResponseFilter.class, contracts))
{
if (containerResponseFilterRegistry == null)
{
containerResponseFilterRegistry = parent.getContainerResponseFilterRegistry().clone(this);
}
int priority = getPriority(priorityOverride, contracts, ContainerResponseFilter.class, provider.getClass());
containerResponseFilterRegistry.registerSingleton((ContainerResponseFilter) provider, priority);
newContracts.put(ContainerResponseFilter.class, priority);
}
if (isA(provider, ReaderInterceptor.class, contracts))
{
ConstrainedTo constrainedTo = (ConstrainedTo) provider.getClass().getAnnotation(ConstrainedTo.class);
int priority = getPriority(priorityOverride, contracts, ReaderInterceptor.class, provider.getClass());
if (constrainedTo != null && constrainedTo.value() == RuntimeType.SERVER)
{
if (serverReaderInterceptorRegistry == null)
{
serverReaderInterceptorRegistry = parent.getServerReaderInterceptorRegistry().clone(this);
}
serverReaderInterceptorRegistry.registerSingleton((ReaderInterceptor) provider, priority);
}
if (constrainedTo != null && constrainedTo.value() == RuntimeType.CLIENT)
{
if (clientReaderInterceptorRegistry == null)
{
clientReaderInterceptorRegistry = parent.getClientReaderInterceptorRegistry().clone(this);
}
clientReaderInterceptorRegistry.registerSingleton((ReaderInterceptor) provider, priority);
}
if (constrainedTo == null)
{
if (serverReaderInterceptorRegistry == null)
{
serverReaderInterceptorRegistry = parent.getServerReaderInterceptorRegistry().clone(this);
}
serverReaderInterceptorRegistry.registerSingleton((ReaderInterceptor) provider, priority);
if (clientReaderInterceptorRegistry == null)
{
clientReaderInterceptorRegistry = parent.getClientReaderInterceptorRegistry().clone(this);
}
clientReaderInterceptorRegistry.registerSingleton((ReaderInterceptor) provider, priority);
}
newContracts.put(ReaderInterceptor.class, priority);
}
if (isA(provider, WriterInterceptor.class, contracts))
{
ConstrainedTo constrainedTo = (ConstrainedTo) provider.getClass().getAnnotation(ConstrainedTo.class);
int priority = getPriority(priorityOverride, contracts, WriterInterceptor.class, provider.getClass());
if (constrainedTo != null && constrainedTo.value() == RuntimeType.SERVER)
{
if (serverWriterInterceptorRegistry == null)
{
serverWriterInterceptorRegistry = parent.getServerWriterInterceptorRegistry().clone(this);
}
serverWriterInterceptorRegistry.registerSingleton((WriterInterceptor) provider, priority);
}
if (constrainedTo != null && constrainedTo.value() == RuntimeType.CLIENT)
{
if (clientWriterInterceptorRegistry == null)
{
clientWriterInterceptorRegistry = parent.getClientWriterInterceptorRegistry().clone(this);
}
clientWriterInterceptorRegistry.registerSingleton((WriterInterceptor) provider, priority);
}
if (constrainedTo == null)
{
if (serverWriterInterceptorRegistry == null)
{
serverWriterInterceptorRegistry = parent.getServerWriterInterceptorRegistry().clone(this);
}
serverWriterInterceptorRegistry.registerSingleton((WriterInterceptor) provider, priority);
if (clientWriterInterceptorRegistry == null)
{
clientWriterInterceptorRegistry = parent.getClientWriterInterceptorRegistry().clone(this);
}
clientWriterInterceptorRegistry.registerSingleton((WriterInterceptor) provider, priority);
}
newContracts.put(WriterInterceptor.class, priority);
}
if (isA(provider, InjectorFactory.class, contracts))
{
this.injectorFactory = (InjectorFactory) provider;
newContracts.put(InjectorFactory.class, 0);
}
if (isA(provider, DynamicFeature.class, contracts))
{
ConstrainedTo constrainedTo = (ConstrainedTo) provider.getClass().getAnnotation(ConstrainedTo.class);
int priority = getPriority(priorityOverride, contracts, DynamicFeature.class, provider.getClass());
if (constrainedTo != null && constrainedTo.value() == RuntimeType.SERVER)
{
if (serverDynamicFeatures == null)
{
serverDynamicFeatures = new CopyOnWriteArraySet(parent.getServerDynamicFeatures());
}
serverDynamicFeatures.add((DynamicFeature) provider);
}
if (constrainedTo != null && constrainedTo.value() == RuntimeType.CLIENT)
{
if (clientDynamicFeatures == null)
{
clientDynamicFeatures = new CopyOnWriteArraySet(parent.getClientDynamicFeatures());
}
clientDynamicFeatures.add((DynamicFeature) provider);
}
if (constrainedTo == null)
{
if (serverDynamicFeatures == null)
{
serverDynamicFeatures = new CopyOnWriteArraySet(parent.getServerDynamicFeatures());
}
serverDynamicFeatures.add((DynamicFeature) provider);
if (clientDynamicFeatures == null)
{
clientDynamicFeatures = new CopyOnWriteArraySet(parent.getClientDynamicFeatures());
}
clientDynamicFeatures.add((DynamicFeature) provider);
}
newContracts.put(DynamicFeature.class, priority);
}
if (isA(provider, Feature.class, contracts))
{
Feature feature = (Feature) provider;
injectProperties(provider.getClass(), provider);
ConstrainedTo constrainedTo = (ConstrainedTo) provider.getClass().getAnnotation(ConstrainedTo.class);
if (constrainedTo == null || constrainedTo.value() == getRuntimeType()) {
if (feature.configure(new FeatureContextDelegate(this)))
{
enabledFeatures.add(feature);
}
}
int priority = getPriority(priorityOverride, contracts, Feature.class, provider.getClass());
newContracts.put(Feature.class, priority);
}
if (isA(provider, ResourceClassProcessor.class, contracts))
{
int priority = getPriority(priorityOverride, contracts, ResourceClassProcessor.class, provider.getClass());
addResourceClassProcessor((ResourceClassProcessor) provider, priority);
newContracts.put(ResourceClassProcessor.class, priority);
}
}
@Override
public ExceptionMapper getExceptionMapper(Class type)
{
Class exceptionType = type;
SortedKey mapper = null;
while (mapper == null)
{
if (exceptionType == null) break;
mapper = getSortedExceptionMappers().get(exceptionType);
if (mapper == null) exceptionType = exceptionType.getSuperclass();
}
return mapper != null ? mapper.getObj() : null;
}
// @Override
public AsyncResponseProvider getAsyncResponseProvider(Class type)
{
Class asyncType = type;
AsyncResponseProvider mapper = null;
while (mapper == null)
{
if (asyncType == null) break;
mapper = getAsyncResponseProviders().get(asyncType);
if (mapper == null) asyncType = asyncType.getSuperclass();
}
return mapper;
}
public AsyncClientResponseProvider getAsyncClientResponseProvider(Class type)
{
Class asyncType = type;
AsyncClientResponseProvider mapper = null;
while (mapper == null)
{
if (asyncType == null) break;
mapper = getAsyncClientResponseProviders().get(asyncType);
if (mapper == null) asyncType = asyncType.getSuperclass();
}
return mapper;
}
// @Override
public AsyncStreamProvider getAsyncStreamProvider(Class type)
{
Class asyncType = type;
AsyncStreamProvider mapper = null;
while (mapper == null)
{
if (asyncType == null) break;
mapper = getAsyncStreamProviders().get(asyncType);
if (mapper == null) asyncType = asyncType.getSuperclass();
}
return mapper;
}
public MediaType getConcreteMediaTypeFromMessageBodyWriters(Class type, Type genericType, Annotation[] annotations, MediaType mediaType)
{
List> writers = getServerMessageBodyWriters().getPossible(mediaType, type);
for (SortedKey writer : writers)
{
if (writer.obj.isWriteable(type, genericType, annotations, mediaType))
{
MessageBodyWriter mbw = writer.obj;
Class writerType = Types.getTemplateParameterOfInterface(mbw.getClass(), MessageBodyWriter.class);
if (writerType == null || writerType.equals(Object.class) || !writerType.isAssignableFrom(type)) continue;
Produces produces = mbw.getClass().getAnnotation(Produces.class);
if (produces == null) continue;
for (String produce : produces.value())
{
MediaType mt = MediaType.valueOf(produce);
if (mt.isWildcardType() || mt.isWildcardSubtype()) continue;
return mt;
}
}
}
return null;
}
public Map, Class>> getPossibleMessageBodyWritersMap(Class type, Type genericType, Annotation[] annotations, MediaType accept)
{
Map, Class>> map = new HashMap, Class>>();
List> writers = getServerMessageBodyWriters().getPossible(accept, type);
for (SortedKey writer : writers)
{
if (writer.obj.isWriteable(type, genericType, annotations, accept))
{
Class> mbwc = writer.obj.getClass();
if (!mbwc.isInterface() && mbwc.getSuperclass() != null && !mbwc.getSuperclass().equals(Object.class) && mbwc.isSynthetic()) {
mbwc = mbwc.getSuperclass();
}
Class writerType = Types.getTemplateParameterOfInterface(mbwc, MessageBodyWriter.class);
if (writerType == null || !writerType.isAssignableFrom(type)) continue;
map.put(writer.obj, writerType);
}
}
return map;
}
// use the tracingLogger enabled version please
@Deprecated
public MessageBodyWriter getServerMessageBodyWriter(Class type, Type genericType, Annotation[] annotations, MediaType mediaType)
{
MediaTypeMap> availableWriters = getServerMessageBodyWriters();
return resolveMessageBodyWriter(type, genericType, annotations, mediaType, availableWriters);
}
public MessageBodyWriter getServerMessageBodyWriter(Class type, Type genericType, Annotation[] annotations, MediaType mediaType, RESTEasyTracingLogger tracingLogger) {
MediaTypeMap> availableWriters = getServerMessageBodyWriters();
return resolveMessageBodyWriter(type, genericType, annotations, mediaType, availableWriters, tracingLogger);
}
/**
* Always gets server MBW.
*
* @param type the class of the object that is to be written.
* @param genericType the type of object to be written. E.g. if the
* message body is to be produced from a field, this will be
* the declared type of the field as returned by {@code Field.getGenericType}.
* @param annotations an array of the annotations on the declaration of the
* artifact that will be written. E.g. if the
* message body is to be produced from a field, this will be
* the annotations on that field returned by
* {@code Field.getDeclaredAnnotations}.
* @param mediaType the media type of the data that will be written.
* @param