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.annotations.interception.ClientInterceptor;
import org.jboss.resteasy.annotations.interception.DecoderPrecedence;
import org.jboss.resteasy.annotations.interception.EncoderPrecedence;
import org.jboss.resteasy.annotations.interception.HeaderDecoratorPrecedence;
import org.jboss.resteasy.annotations.interception.RedirectPrecedence;
import org.jboss.resteasy.annotations.interception.SecurityPrecedence;
import org.jboss.resteasy.annotations.interception.ServerInterceptor;
import org.jboss.resteasy.client.core.ClientErrorInterceptor;
import org.jboss.resteasy.client.exception.mapper.ClientExceptionMapper;
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.ClientResponseFilterRegistry;
import org.jboss.resteasy.core.interception.ContainerRequestFilterRegistry;
import org.jboss.resteasy.core.interception.ContainerResponseFilterRegistry;
import org.jboss.resteasy.core.interception.InterceptorRegistry;
import org.jboss.resteasy.core.interception.JaxrsInterceptorRegistry;
import org.jboss.resteasy.core.interception.LegacyPrecedence;
import org.jboss.resteasy.core.interception.ReaderInterceptorRegistry;
import org.jboss.resteasy.core.interception.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.interception.ClientExecutionInterceptor;
import org.jboss.resteasy.spi.interception.MessageBodyReaderInterceptor;
import org.jboss.resteasy.spi.interception.MessageBodyWriterInterceptor;
import org.jboss.resteasy.spi.interception.PostProcessInterceptor;
import org.jboss.resteasy.spi.interception.PreProcessInterceptor;
import org.jboss.resteasy.spi.metadata.ResourceBuilder;
import org.jboss.resteasy.spi.metadata.ResourceClassProcessor;
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 org.jboss.resteasy.spi.statistics.StatisticsController;
import org.jboss.resteasy.statistics.StatisticsControllerImpl;
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.Application;
import javax.ws.rs.core.CacheControl;
import javax.ws.rs.core.Configurable;
import javax.ws.rs.core.Configuration;
import javax.ws.rs.core.Cookie;
import javax.ws.rs.core.EntityTag;
import javax.ws.rs.core.Feature;
import javax.ws.rs.core.Link;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.NewCookie;
import javax.ws.rs.core.Response;
import javax.ws.rs.core.UriBuilder;
import javax.ws.rs.core.UriInfo;
import javax.ws.rs.core.Variant;
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.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.Date;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import java.util.Set;
import java.util.TreeSet;
import java.util.Map.Entry;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.CopyOnWriteArrayList;
import java.util.concurrent.CopyOnWriteArraySet;
import java.util.concurrent.atomic.AtomicReference;
/**
* @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.
*/
protected static class SortedKey implements Comparable>, MediaTypeMap.Typed
{
public Class> readerClass;
public T obj;
public boolean isBuiltin = false;
public Class> template = null;
public int priority = Priorities.USER;
protected SortedKey(final Class> intf, final T reader, final Class> readerClass, final int priority, final boolean isBuiltin)
{
this(intf, reader, readerClass);
this.priority = priority;
this.isBuiltin = isBuiltin;
}
protected SortedKey(final Class> intf, final T reader, final Class> readerClass, final boolean isBuiltin)
{
this(intf, reader, readerClass);
this.isBuiltin = isBuiltin;
}
protected SortedKey(final Class> intf, final T reader, final Class> readerClass)
{
this.readerClass = readerClass;
this.obj = reader;
// check the super class for the generic type 1st
template = Types.getTemplateParameterOfInterface(readerClass, intf);
if (template == null) template = Object.class;
}
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;
}
}
protected static class ExtSortedKey extends SortedKey
{
protected ExtSortedKey(final Class> intf, final T reader, final Class> readerClass, final int priority, final boolean isBuiltin)
{
super(intf, reader, readerClass, priority, isBuiltin);
}
protected ExtSortedKey(final Class> intf, final T reader, final Class> readerClass, final boolean isBuiltin)
{
super(intf, reader, readerClass, isBuiltin);
}
protected ExtSortedKey(final Class> intf, final T reader, final Class> readerClass)
{
super(intf, reader, readerClass);
}
@Override
public int compareTo(SortedKey tMessageBodyKey)
{
int c = super.compareTo(tMessageBodyKey);
if (c != 0)
{
return c;
}
if (this.obj == tMessageBodyKey.obj)
{
return 0;
}
return -1;
}
}
public interface CloseableContext extends AutoCloseable {
@Override
void close();
}
protected static AtomicReference pfr = new AtomicReference();
protected static ThreadLocalStack, Object>> contextualData = new ThreadLocalStack, Object>>();
protected static int maxForwards = 20;
protected static volatile ResteasyProviderFactory instance;
public static boolean registerBuiltinByDefault = true;
protected MediaTypeMap> serverMessageBodyReaders;
protected MediaTypeMap> serverMessageBodyWriters;
protected MediaTypeMap> clientMessageBodyReaders;
protected MediaTypeMap> clientMessageBodyWriters;
protected Map, SortedKey> sortedExceptionMappers;
protected Map, ExceptionMapper> exceptionMappers;
protected Map, ClientExceptionMapper> clientExceptionMappers;
protected Map, AsyncResponseProvider> asyncResponseProviders;
protected Map, AsyncClientResponseProvider> asyncClientResponseProviders;
protected Map, AsyncStreamProvider> asyncStreamProviders;
protected Map, MediaTypeMap>> contextResolvers;
protected Map, StringConverter> stringConverters;
protected Set> sortedParamConverterProviders;
protected List paramConverterProviders;
protected Map, Class extends StringParameterUnmarshaller>> stringParameterUnmarshallers;
protected Map, Map, Integer>> classContracts;
protected Map, HeaderDelegate> headerDelegates;
protected LegacyPrecedence precedence;
protected ReaderInterceptorRegistry serverReaderInterceptorRegistry;
protected WriterInterceptorRegistry serverWriterInterceptorRegistry;
protected ContainerRequestFilterRegistry containerRequestFilterRegistry;
protected ContainerResponseFilterRegistry containerResponseFilterRegistry;
protected ClientRequestFilterRegistry clientRequestFilterRegistry;
@Deprecated // variable is maintained for jaxrs-leagcy code support only
protected JaxrsInterceptorRegistry clientRequestFilters;
protected ClientResponseFilterRegistry clientResponseFilters;
protected ReaderInterceptorRegistry clientReaderInterceptorRegistry;
protected WriterInterceptorRegistry clientWriterInterceptorRegistry;
protected InterceptorRegistry clientExecutionInterceptorRegistry;
protected List clientErrorInterceptors;
protected boolean builtinsRegistered = false;
protected boolean registerBuiltins = true;
protected InjectorFactory injectorFactory;
protected ResteasyProviderFactory parent;
protected Set serverDynamicFeatures;
protected Set clientDynamicFeatures;
protected Set enabledFeatures;
protected Map properties;
protected Set> providerClasses;
protected Set providerInstances;
protected Set> featureClasses;
protected Set featureInstances;
protected Map, Class extends RxInvokerProvider>>> reactiveClasses;
private boolean initialized = false;
protected ResourceBuilder resourceBuilder;
private StatisticsControllerImpl statisticsController = new StatisticsControllerImpl();
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(final 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(final ResteasyProviderFactory parent, final boolean local)
{
if (local || parent == null)
{
// Parent MUST not be referenced after current object is created
this.parent = null;
initialize(parent);
}
else
{
this.parent = parent;
featureClasses = new CopyOnWriteArraySet<>();
featureInstances = new CopyOnWriteArraySet<>();
providerClasses = new CopyOnWriteArraySet<>();
providerInstances = new CopyOnWriteArraySet<>();
properties = new ConcurrentHashMap<>();
properties.putAll(parent.getProperties());
enabledFeatures = new CopyOnWriteArraySet<>();
reactiveClasses = new ConcurrentHashMap<>();
}
}
protected void initialize()
{
initialize(null);
}
protected void initialize(ResteasyProviderFactory parent)
{
serverDynamicFeatures = parent == null ? new CopyOnWriteArraySet<>() : new CopyOnWriteArraySet<>(parent.getServerDynamicFeatures());
clientDynamicFeatures = parent == null ? new CopyOnWriteArraySet<>() : new CopyOnWriteArraySet<>(parent.getClientDynamicFeatures());
enabledFeatures = parent == null ? new CopyOnWriteArraySet<>() : new CopyOnWriteArraySet<>(parent.getEnabledFeatures());
properties = parent == null ? new ConcurrentHashMap<>() : new ConcurrentHashMap<>(parent.getProperties());
featureClasses = parent == null ? new CopyOnWriteArraySet<>() : new CopyOnWriteArraySet<>(parent.getFeatureClasses());
featureInstances = parent == null ? new CopyOnWriteArraySet<>() : new CopyOnWriteArraySet<>(parent.getFeatureInstances());
providerClasses = parent == null ? new CopyOnWriteArraySet<>() : new CopyOnWriteArraySet<>(parent.getProviderClasses());
providerInstances = parent == null ? new CopyOnWriteArraySet<>() : new CopyOnWriteArraySet<>(parent.getProviderInstances());
classContracts = parent == null ? new ConcurrentHashMap<>() : new ConcurrentHashMap<>(parent.getClassContracts());
serverMessageBodyReaders = parent == null ? new MediaTypeMap<>() : new MediaTypeMap(parent.getServerMessageBodyReaders());
serverMessageBodyWriters = parent == null ? new MediaTypeMap<>() : new MediaTypeMap(parent.getServerMessageBodyWriters());
clientMessageBodyReaders = parent == null ? new MediaTypeMap<>() : new MediaTypeMap(parent.getClientMessageBodyReaders());
clientMessageBodyWriters = parent == null ? new MediaTypeMap<>() : new MediaTypeMap(parent.getClientMessageBodyWriters());
sortedExceptionMappers = parent == null ? new ConcurrentHashMap<>() : new ConcurrentHashMap<>(parent.getSortedExceptionMappers());
exceptionMappers = parent == null ? new ConcurrentHashMap<>() : new ConcurrentHashMap<>(parent.getExceptionMappers());
clientExceptionMappers = parent == null ? new ConcurrentHashMap<>() : new ConcurrentHashMap<>(parent.getClientExceptionMappers());
asyncResponseProviders = parent == null ? new ConcurrentHashMap<>() : new ConcurrentHashMap<>(parent.getAsyncResponseProviders());
asyncClientResponseProviders = parent == null ? new ConcurrentHashMap<>() : new ConcurrentHashMap<>(parent.getAsyncClientResponseProviders());
asyncStreamProviders = parent == null ? new ConcurrentHashMap<>() : new ConcurrentHashMap<>(parent.getAsyncStreamProviders());
contextResolvers = new ConcurrentHashMap<>();
if (parent != null)
{
for (Map.Entry, MediaTypeMap>> entry : parent.getContextResolvers()
.entrySet())
{
contextResolvers.put(entry.getKey(), new MediaTypeMap<>(entry.getValue()));
}
}
sortedParamConverterProviders = Collections.synchronizedSortedSet(parent == null ? new TreeSet<>() : new TreeSet<>(parent.getSortedParamConverterProviders()));
stringConverters = parent == null ? new ConcurrentHashMap<>() : new ConcurrentHashMap<>(parent.getStringConverters());
stringParameterUnmarshallers = parent == null ? new ConcurrentHashMap<>() : new ConcurrentHashMap<>(parent.getStringParameterUnmarshallers());
reactiveClasses = parent == null ? new ConcurrentHashMap<>() : new ConcurrentHashMap<>(parent.reactiveClasses);
headerDelegates = parent == null ? new ConcurrentHashMap<>() : new ConcurrentHashMap<>(parent.getHeaderDelegates());
precedence = new LegacyPrecedence();
serverReaderInterceptorRegistry = parent == null ? new ReaderInterceptorRegistry(this, precedence) : parent.getServerReaderInterceptorRegistry().clone(this);
serverWriterInterceptorRegistry = parent == null ? new WriterInterceptorRegistry(this, precedence) : parent.getServerWriterInterceptorRegistry().clone(this);
containerRequestFilterRegistry = parent == null ? new ContainerRequestFilterRegistry(this, precedence) : parent.getContainerRequestFilterRegistry().clone(this);
containerResponseFilterRegistry = parent == null ? new ContainerResponseFilterRegistry(this, precedence) : parent.getContainerResponseFilterRegistry().clone(this);
initializeClientProviders(parent);
clientReaderInterceptorRegistry = parent == null ? new ReaderInterceptorRegistry(this, precedence) : parent.getClientReaderInterceptorRegistry().clone(this);
clientWriterInterceptorRegistry = parent == null ? new WriterInterceptorRegistry(this, precedence) : parent.getClientWriterInterceptorRegistry().clone(this);
clientExecutionInterceptorRegistry = parent == null ? new InterceptorRegistry(ClientExecutionInterceptor.class, this) : parent.getClientExecutionInterceptorRegistry().cloneTo(this);
clientErrorInterceptors = parent == null ? new CopyOnWriteArrayList<>() : new CopyOnWriteArrayList<>(parent.getClientErrorInterceptors());
resourceBuilder = new ResourceBuilder();
builtinsRegistered = false;
registerBuiltins = true;
injectorFactory = parent == null ? new InjectorFactoryImpl() : parent.getInjectorFactory();
registerDefaultInterceptorPrecedences();
addHeaderDelegateIfAbsent(MediaType.class, new MediaTypeHeaderDelegate());
addHeaderDelegateIfAbsent(NewCookie.class, new NewCookieHeaderDelegate());
addHeaderDelegateIfAbsent(Cookie.class, new CookieHeaderDelegate());
addHeaderDelegateIfAbsent(URI.class, new UriHeaderDelegate());
addHeaderDelegateIfAbsent(EntityTag.class, new EntityTagDelegate());
addHeaderDelegateIfAbsent(CacheControl.class, new CacheControlDelegate());
addHeaderDelegateIfAbsent(Locale.class, new LocaleDelegate());
addHeaderDelegateIfAbsent(LinkHeader.class, new LinkHeaderDelegate());
addHeaderDelegateIfAbsent(javax.ws.rs.core.Link.class, new LinkDelegate());
addHeaderDelegateIfAbsent(Date.class, new DateDelegate());
initialized = true;
}
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;
}
protected MediaTypeMap> getServerMessageBodyReaders()
{
if (serverMessageBodyReaders == null && parent != null) return parent.getServerMessageBodyReaders();
return serverMessageBodyReaders;
}
protected MediaTypeMap> getServerMessageBodyWriters()
{
if (serverMessageBodyWriters == null && parent != null) return parent.getServerMessageBodyWriters();
return serverMessageBodyWriters;
}
protected MediaTypeMap> getClientMessageBodyReaders()
{
if (clientMessageBodyReaders == null && parent != null) return parent.getClientMessageBodyReaders();
return clientMessageBodyReaders;
}
protected 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;
}
protected Map, SortedKey> getSortedExceptionMappers()
{
if (sortedExceptionMappers == null && parent != null) return parent.getSortedExceptionMappers();
return sortedExceptionMappers;
}
protected Map, ClientExceptionMapper> getClientExceptionMappers()
{
if (clientExceptionMappers == null && parent != null) return parent.getClientExceptionMappers();
return clientExceptionMappers;
}
public Map, AsyncClientResponseProvider> getAsyncClientResponseProviders()
{
if (asyncClientResponseProviders == null && parent != null) return parent.getAsyncClientResponseProviders();
return asyncClientResponseProviders;
}
public Map, AsyncResponseProvider> getAsyncResponseProviders()
{
if (asyncResponseProviders == null && parent != null) return parent.getAsyncResponseProviders();
return asyncResponseProviders;
}
public Map, AsyncStreamProvider> getAsyncStreamProviders()
{
if (asyncStreamProviders == null && parent != null) return parent.getAsyncStreamProviders();
return asyncStreamProviders;
}
protected void addAsyncClientResponseProvider(Class extends AsyncClientResponseProvider> providerClass)
{
AsyncClientResponseProvider provider = createProviderInstance(providerClass);
addAsyncClientResponseProvider(provider, providerClass);
}
protected void addAsyncClientResponseProvider(AsyncClientResponseProvider provider)
{
addAsyncClientResponseProvider(provider, provider.getClass());
}
protected void addAsyncClientResponseProvider(AsyncClientResponseProvider provider, Class providerClass)
{
Type asyncType = Types.getActualTypeArgumentsOfAnInterface(providerClass, AsyncClientResponseProvider.class)[0];
addAsyncClientResponseProvider(provider, asyncType);
}
protected void addAsyncClientResponseProvider(AsyncClientResponseProvider provider, Type asyncType)
{
injectProperties(provider.getClass(), provider);
Class> asyncClass = Types.getRawType(asyncType);
if (asyncClientResponseProviders == null)
{
asyncClientResponseProviders = new ConcurrentHashMap, AsyncClientResponseProvider>();
asyncClientResponseProviders.putAll(parent.getAsyncClientResponseProviders());
}
asyncClientResponseProviders.put(asyncClass, provider);
}
protected Map, MediaTypeMap>> getContextResolvers()
{
if (contextResolvers == null && parent != null) return parent.getContextResolvers();
return contextResolvers;
}
protected Map, StringConverter> getStringConverters()
{
if (stringConverters == null && parent != null) return parent.getStringConverters();
return stringConverters;
}
public List getParamConverterProviders()
{
if (paramConverterProviders != null)
{
return paramConverterProviders;
}
List list = new CopyOnWriteArrayList();
for (SortedKey key : getSortedParamConverterProviders())
{
list.add(key.getObj());
}
paramConverterProviders = list;
return list;
}
protected Set> getSortedParamConverterProviders()
{
if (sortedParamConverterProviders == null && parent != null) return parent.getSortedParamConverterProviders();
return sortedParamConverterProviders;
}
protected 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 (initialized) {
return providerClasses;
}
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 (initialized) {
return providerInstances;
}
Set set = new HashSet();
if (parent != null) set.addAll(parent.getProviderInstances());
set.addAll(providerInstances);
return set;
}
public 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;
}
protected LegacyPrecedence getPrecedence()
{
if (precedence == null && parent != null) return parent.getPrecedence();
return precedence;
}
public ResteasyProviderFactory getParent()
{
return parent;
}
protected void registerDefaultInterceptorPrecedences(InterceptorRegistry registry)
{
// legacy
registry.appendPrecedence(SecurityPrecedence.PRECEDENCE_STRING);
registry.appendPrecedence(HeaderDecoratorPrecedence.PRECEDENCE_STRING);
registry.appendPrecedence(EncoderPrecedence.PRECEDENCE_STRING);
registry.appendPrecedence(RedirectPrecedence.PRECEDENCE_STRING);
registry.appendPrecedence(DecoderPrecedence.PRECEDENCE_STRING);
}
protected void registerDefaultInterceptorPrecedences()
{
precedence.addPrecedence(SecurityPrecedence.PRECEDENCE_STRING, Priorities.AUTHENTICATION);
precedence.addPrecedence(HeaderDecoratorPrecedence.PRECEDENCE_STRING, Priorities.HEADER_DECORATOR);
precedence.addPrecedence(EncoderPrecedence.PRECEDENCE_STRING, Priorities.ENTITY_CODER);
precedence.addPrecedence(RedirectPrecedence.PRECEDENCE_STRING, Priorities.ENTITY_CODER + 50);
precedence.addPrecedence(DecoderPrecedence.PRECEDENCE_STRING, Priorities.ENTITY_CODER);
registerDefaultInterceptorPrecedences(getClientExecutionInterceptorRegistry());
}
/**
* Append interceptor predence.
*
* @param precedence precedence
*/
@Deprecated
public void appendInterceptorPrecedence(String precedence)
{
if (this.precedence == null)
{
this.precedence = parent.getPrecedence().clone();
}
if (clientExecutionInterceptorRegistry == null)
{
clientExecutionInterceptorRegistry = parent.getClientExecutionInterceptorRegistry().cloneTo(this);
}
this.precedence.appendPrecedence(precedence);
clientExecutionInterceptorRegistry.appendPrecedence(precedence);
}
/**
* @param after put newPrecedence after this
* @param newPrecedence new precedence
*/
@Deprecated
public void insertInterceptorPrecedenceAfter(String after, String newPrecedence)
{
if (this.precedence == null)
{
this.precedence = parent.getPrecedence().clone();
}
if (clientExecutionInterceptorRegistry == null)
{
clientExecutionInterceptorRegistry = parent.getClientExecutionInterceptorRegistry().cloneTo(this);
}
this.precedence.insertPrecedenceAfter(after, newPrecedence);
getClientExecutionInterceptorRegistry().insertPrecedenceAfter(after, newPrecedence);
}
/**
* @param before put newPrecedence before this
* @param newPrecedence new precedence
*/
@Deprecated
public void insertInterceptorPrecedenceBefore(String before, String newPrecedence)
{
if (this.precedence == null)
{
this.precedence = parent.getPrecedence().clone();
}
if (clientExecutionInterceptorRegistry == null)
{
clientExecutionInterceptorRegistry = parent.getClientExecutionInterceptorRegistry().cloneTo(this);
}
this.precedence.insertPrecedenceBefore(before, newPrecedence);
getClientExecutionInterceptorRegistry().insertPrecedenceBefore(before, newPrecedence);
}
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)
{
Map, Object> contextDataMap = getContextDataMap(false);
if (contextDataMap == null) {
return null;
}
return (T) contextDataMap.get(type);
}
public static T popContextData(Class type)
{
return (T) getContextDataMap().remove(type);
}
public static void clearContextData()
{
contextualData.clear();
}
public static Map, Object> getContextDataMap(boolean create)
{
Map, Object> map = contextualData.get();
if (map == null && create)
{
contextualData.setLast(map = new HashMap, Object>());
}
return map;
}
public static CloseableContext addCloseableContextDataLevel()
{
addContextDataLevel();
return () -> removeContextDataLevel();
}
public static CloseableContext addCloseableContextDataLevel(Map,Object> data)
{
pushContextDataMap(data);
return ResteasyProviderFactory::removeContextDataLevel;
}
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 static synchronized void clearInstanceIfEqual(ResteasyProviderFactory factory)
{
if (instance == factory)
{
instance = null;
RuntimeDelegate.setInstance(null);
}
}
public static synchronized void setInstance(ResteasyProviderFactory factory)
{
synchronized (RD_LOCK)
{
instance = factory;
}
RuntimeDelegate.setInstance(factory);
}
static final 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 InterceptorRegistry getClientExecutionInterceptorRegistry()
{
if (clientExecutionInterceptorRegistry == null && parent != null)
return parent.getClientExecutionInterceptorRegistry();
return clientExecutionInterceptorRegistry;
}
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;
}
/**
* This method retained for jaxrs-legacy code. This method is deprecated and is replace
* by method, getClientRequestFilterRegistry().
* @return interceptor registry
*/
@Deprecated
public JaxrsInterceptorRegistry getClientRequestFilters()
{
if (clientRequestFilters == null && parent != null) return parent.getClientRequestFilters();
return clientRequestFilters;
}
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());
}
protected 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;
}
protected Map, HeaderDelegate> getHeaderDelegates()
{
if (headerDelegates == null && parent != null) return parent.getHeaderDelegates();
return headerDelegates;
}
private void addHeaderDelegateIfAbsent(Class clazz, HeaderDelegate header)
{
if (headerDelegates == null || !headerDelegates.containsKey(clazz))
{
addHeaderDelegate(clazz, header);
}
}
public void addHeaderDelegate(Class clazz, HeaderDelegate header)
{
if (headerDelegates == null)
{
headerDelegates = new ConcurrentHashMap, HeaderDelegate>();
headerDelegates.putAll(parent.getHeaderDelegates());
}
headerDelegates.put(clazz, header);
}
protected void addMessageBodyReader(Class extends MessageBodyReader> provider, int priority, boolean isBuiltin)
{
MessageBodyReader reader = createProviderInstance(provider);
addMessageBodyReader(reader, provider, priority, isBuiltin);
}
protected void addMessageBodyReader(MessageBodyReader provider)
{
addMessageBodyReader(provider, Priorities.USER, false);
}
protected void addMessageBodyReader(MessageBodyReader provider, int priority, boolean isBuiltin)
{
addMessageBodyReader(provider, provider.getClass(), priority, isBuiltin);
}
/**
* 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
*/
protected 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)
{
addClientMessageBodyReader(key, consumeMime);
addServerMessageBodyReader(key, consumeMime);
}
else if (type == RuntimeType.CLIENT)
{
addClientMessageBodyReader(key, consumeMime);
}
else
{
addServerMessageBodyReader(key, consumeMime);
}
}
protected void addServerMessageBodyReader(SortedKey key, Consumes consumeMime)
{
if (serverMessageBodyReaders == null)
{
serverMessageBodyReaders = new MediaTypeMap(parent.getServerMessageBodyReaders());
}
if (consumeMime != null)
{
for (String consume : consumeMime.value())
{
MediaType mime = MediaType.valueOf(consume);
serverMessageBodyReaders.add(mime, key);
}
}
else
{
serverMessageBodyReaders.add(new MediaType("*", "*"), key);
}
}
protected void addClientMessageBodyReader(SortedKey key, Consumes consumeMime)
{
if (clientMessageBodyReaders == null)
{
clientMessageBodyReaders = new MediaTypeMap(parent.getClientMessageBodyReaders());
}
if (consumeMime != null)
{
for (String consume : consumeMime.value())
{
MediaType mime = MediaType.valueOf(consume);
clientMessageBodyReaders.add(mime, key);
}
}
else
{
clientMessageBodyReaders.add(new MediaType("*", "*"), key);
}
}
protected void addMessageBodyWriter(Class extends MessageBodyWriter> provider, int priority, boolean isBuiltin)
{
MessageBodyWriter writer = createProviderInstance(provider);
addMessageBodyWriter(writer, provider, priority, isBuiltin);
}
protected void addMessageBodyWriter(MessageBodyWriter provider)
{
addMessageBodyWriter(provider, provider.getClass(), Priorities.USER, false);
}
/**
* 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
*/
protected 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)
{
addClientMessageBodyWriter(consumeMime, key);
addServerMessageBodyWriter(consumeMime, key);
}
else if (type == RuntimeType.CLIENT)
{
addClientMessageBodyWriter(consumeMime, key);
}
else
{
addServerMessageBodyWriter(consumeMime, key);
}
}
protected void addServerMessageBodyWriter(Produces consumeMime, SortedKey key)
{
if (serverMessageBodyWriters == null)
{
serverMessageBodyWriters = new MediaTypeMap(parent.getServerMessageBodyWriters());
}
if (consumeMime != null)
{
for (String consume : consumeMime.value())
{
MediaType mime = MediaType.valueOf(consume);
//logger.info(">>> Adding provider: " + provider.getClass().getName() + " with mime type of: " + mime);
serverMessageBodyWriters.add(mime, key);
}
}
else
{
//logger.info(">>> Adding provider: " + provider.getClass().getName() + " with mime type of: default */*");
serverMessageBodyWriters.add(new MediaType("*", "*"), key);
}
}
protected void addClientMessageBodyWriter(Produces consumeMime, SortedKey key)
{
if (clientMessageBodyWriters == null)
{
clientMessageBodyWriters = new MediaTypeMap(parent.getClientMessageBodyWriters());
}
if (consumeMime != null)
{
for (String consume : consumeMime.value())
{
MediaType mime = MediaType.valueOf(consume);
//logger.info(">>> Adding provider: " + provider.getClass().getName() + " with mime type of: " + mime);
clientMessageBodyWriters.add(mime, key);
}
}
else
{
//logger.info(">>> Adding provider: " + provider.getClass().getName() + " with mime type of: default */*");
clientMessageBodyWriters.add(new MediaType("*", "*"), key);
}
}
public MessageBodyReader getServerMessageBodyReader(Class type, Type genericType, Annotation[] annotations, MediaType mediaType)
{
MediaTypeMap> availableReaders = getServerMessageBodyReaders();
return resolveMessageBodyReader(type, genericType, annotations, mediaType, availableReaders);
}
/**
* 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);
}
protected 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 void addExceptionMapper(Class extends ExceptionMapper> providerClass)
{
addExceptionMapper(providerClass, false);
}
protected void addExceptionMapper(ExceptionMapper provider)
{
addExceptionMapper(provider, false);
}
protected void addExceptionMapper(ExceptionMapper provider, Class providerClass)
{
addExceptionMapper(provider, providerClass, false);
}
protected void addExceptionMapper(ExceptionMapper provider, Type exceptionType)
{
addExceptionMapper(provider, exceptionType, provider.getClass(), false);
}
protected void addExceptionMapper(Class extends ExceptionMapper> providerClass, boolean isBuiltin)
{
ExceptionMapper provider = createProviderInstance(providerClass);
addExceptionMapper(provider, providerClass, isBuiltin);
}
protected void addExceptionMapper(ExceptionMapper provider, boolean isBuiltin)
{
addExceptionMapper(provider, provider.getClass(), isBuiltin);
}
protected 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];
addExceptionMapper(provider, exceptionType, providerClass, isBuiltin);
}
protected void addExceptionMapper(ExceptionMapper provider, Type exceptionType, Class providerClass, boolean isBuiltin)
{
// Check for weld proxy.
if (providerClass.isSynthetic())
{
providerClass = providerClass.getSuperclass();
}
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;
}
public void addClientExceptionMapper(Class extends ClientExceptionMapper>> providerClass)
{
ClientExceptionMapper> provider = createProviderInstance(providerClass);
addClientExceptionMapper(provider, providerClass);
}
public void addClientExceptionMapper(ClientExceptionMapper> provider)
{
addClientExceptionMapper(provider, provider.getClass());
}
public void addClientExceptionMapper(ClientExceptionMapper> provider, Class> providerClass)
{
Type exceptionType = Types.getActualTypeArgumentsOfAnInterface(providerClass, ClientExceptionMapper.class)[0];
addClientExceptionMapper(provider, exceptionType);
}
public void addClientExceptionMapper(ClientExceptionMapper> provider, Type exceptionType)
{
injectProperties(provider.getClass());
Class> exceptionClass = Types.getRawType(exceptionType);
if (!Throwable.class.isAssignableFrom(exceptionClass))
{
throw new RuntimeException(Messages.MESSAGES.incorrectTypeParameterClientExceptionMapper());
}
if (clientExceptionMappers == null)
{
clientExceptionMappers = new ConcurrentHashMap, ClientExceptionMapper>();
clientExceptionMappers.putAll(parent.getClientExceptionMappers());
}
clientExceptionMappers.put(exceptionClass, provider);
}
/**
* Add a {@link ClientErrorInterceptor} to this provider factory instance.
* Duplicate handlers are ignored. (For Client Proxy API only)
* @param handler ClientErrorInterceptor handler
*/
public void addClientErrorInterceptor(ClientErrorInterceptor handler)
{
if (clientErrorInterceptors == null)
{
clientErrorInterceptors = new CopyOnWriteArrayList(parent.getClientErrorInterceptors());
}
if (!clientErrorInterceptors.contains(handler))
{
clientErrorInterceptors.add(handler);
}
}
/**
* Return the list of currently registered {@link ClientErrorInterceptor} instances.
*
* @return List of {@link ClientErrorInterceptor} instances
*/
public List getClientErrorInterceptors()
{
if (clientErrorInterceptors == null && parent != null) return parent.getClientErrorInterceptors();
return clientErrorInterceptors;
}
protected void addAsyncResponseProvider(Class extends AsyncResponseProvider> providerClass)
{
AsyncResponseProvider provider = createProviderInstance(providerClass);
addAsyncResponseProvider(provider, providerClass);
}
protected void addAsyncResponseProvider(AsyncResponseProvider provider)
{
addAsyncResponseProvider(provider, provider.getClass());
}
protected void addAsyncResponseProvider(AsyncResponseProvider provider, Class providerClass)
{
Type asyncType = Types.getActualTypeArgumentsOfAnInterface(providerClass, AsyncResponseProvider.class)[0];
addAsyncResponseProvider(provider, asyncType);
}
protected void addAsyncResponseProvider(AsyncResponseProvider provider, Type asyncType)
{
injectProperties(provider.getClass(), provider);
Class> asyncClass = Types.getRawType(asyncType);
if (asyncResponseProviders == null)
{
asyncResponseProviders = new ConcurrentHashMap, AsyncResponseProvider>();
asyncResponseProviders.putAll(parent.getAsyncResponseProviders());
}
asyncResponseProviders.put(asyncClass, provider);
}
protected void addAsyncStreamProvider(Class extends AsyncStreamProvider> providerClass)
{
AsyncStreamProvider provider = createProviderInstance(providerClass);
addAsyncStreamProvider(provider, providerClass);
}
protected void addAsyncStreamProvider(AsyncStreamProvider provider)
{
addAsyncStreamProvider(provider, provider.getClass());
}
protected void addAsyncStreamProvider(AsyncStreamProvider provider, Class providerClass)
{
Type asyncType = Types.getActualTypeArgumentsOfAnInterface(providerClass, AsyncStreamProvider.class)[0];
addAsyncStreamProvider(provider, asyncType);
}
protected void addAsyncStreamProvider(AsyncStreamProvider provider, Type asyncType)
{
injectProperties(provider.getClass(), provider);
Class> asyncClass = Types.getRawType(asyncType);
if (asyncStreamProviders == null)
{
asyncStreamProviders = new ConcurrentHashMap, AsyncStreamProvider>();
asyncStreamProviders.putAll(parent.getAsyncStreamProviders());
}
asyncStreamProviders.put(asyncClass, provider);
}
protected void addContextResolver(Class extends ContextResolver> resolver, int priority, boolean builtin)
{
ContextResolver writer = createProviderInstance(resolver);
addContextResolver(writer, priority, resolver, builtin);
}
protected void addContextResolver(ContextResolver provider, int priority)
{
addContextResolver(provider, priority, false);
}
protected void addContextResolver(ContextResolver provider, int priority, boolean builtin)
{
addContextResolver(provider, priority, provider.getClass(), builtin);
}
protected void addContextResolver(ContextResolver provider, int priority, Class providerClass, boolean builtin)
{
// RESTEASY-1725
if (providerClass.getName().contains("$$Lambda$"))
{
throw new RuntimeException(Messages.MESSAGES.registeringContextResolverAsLambda());
}
Type parameter = Types.getActualTypeArgumentsOfAnInterface(providerClass, ContextResolver.class)[0];
addContextResolver(provider, priority, parameter, providerClass, builtin);
}
protected void addContextResolver(ContextResolver provider, int priority, Type typeParameter, Class providerClass,
boolean builtin)
{
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(), new MediaTypeMap<>(entry.getValue()));
}
}
MediaTypeMap> resolvers = contextResolvers.get(parameterClass);
if (resolvers == null)
{
resolvers = new MediaTypeMap>();
contextResolvers.put(parameterClass, resolvers);
}
Produces produces = provider.getClass().getAnnotation(Produces.class);
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);
}
}
////////////////////////////////////////////////////////////////////////////
// Restoring five addContextResolver() methods previously replaced by versions with priority parameter.
// See RESTEASY-2231
protected void addContextResolver(Class extends ContextResolver> resolver, boolean builtin)
{
ContextResolver writer = createProviderInstance(resolver);
addContextResolver(writer, resolver, builtin);
}
protected void addContextResolver(ContextResolver provider)
{
addContextResolver(provider, false);
}
protected void addContextResolver(ContextResolver provider, boolean builtin)
{
addContextResolver(provider, provider.getClass(), builtin);
}
protected void addContextResolver(ContextResolver provider, Class providerClass, boolean builtin)
{
// RESTEASY-1725
if (providerClass.getName().contains("$$Lambda$")) {
throw new RuntimeException(Messages.MESSAGES.registeringContextResolverAsLambda());
}
Type parameter = Types.getActualTypeArgumentsOfAnInterface(providerClass, ContextResolver.class)[0];
addContextResolver(provider, parameter, providerClass, builtin);
}
protected void addContextResolver(ContextResolver provider, Type typeParameter, Class providerClass, boolean builtin)
{
int priority = getPriority(null, null, ContextResolver.class, providerClass);
addContextResolver(provider, priority, typeParameter, providerClass, builtin);
}
////////////////////////////////////////////////////////////////////////////
protected void addStringConverter(Class extends StringConverter> resolver)
{
StringConverter writer = createProviderInstance(resolver);
addStringConverter(writer, resolver);
}
protected void addStringConverter(StringConverter provider)
{
addStringConverter(provider, provider.getClass());
}
protected void addStringConverter(StringConverter provider, Class providerClass)
{
Type parameter = Types.getActualTypeArgumentsOfAnInterface(providerClass, StringConverter.class)[0];
addStringConverter(provider, parameter);
}
protected void addStringConverter(StringConverter provider, Type typeParameter)
{
injectProperties(provider.getClass(), provider);
Class> parameterClass = Types.getRawType(typeParameter);
if (stringConverters == null)
{
stringConverters = new ConcurrentHashMap, StringConverter>();
stringConverters.putAll(parent.getStringConverters());
}
stringConverters.put(parameterClass, provider);
}
public 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);
list.forEach(resolver -> 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 StringConverter getStringConverter(Class> clazz)
{
if (getStringConverters().size() == 0) return null;
return getStringConverters().get(clazz);
}
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);
}
StringConverter converter = getStringConverter(object
.getClass());
if (converter != null)
return converter.toString(object);
else
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);
}
StringConverter converter = getStringConverter(aClass);
if (converter != null)
return converter.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);
}
public static boolean isA(Class target, Class type, Set> contracts)
{
if (!type.isAssignableFrom(target)) return false;
if (contracts == null || contracts.size() == 0) return true;
for (Class> contract : contracts)
{
if (contract.equals(type)) return true;
}
return false;
}
public static boolean isA(Object target, Class type, Set> contracts)
{
return isA(target.getClass(), type, contracts);
}
protected boolean isA(Class target, Class type, Map, Integer> contracts)
{
return isA(target, type, contracts == null ? null : contracts.keySet());
}
protected boolean isA(Object target, Class type, Map, Integer> contracts)
{
return isA(target.getClass(), type, contracts);
}
protected int getPriority(Integer override, Map, Integer> contracts, Class type, Class> component)
{
if (override != null && override != -1) 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)
{
Map, Map, Integer>> classContracts = getClassContracts();
if (classContracts.containsKey(provider))
{
LogMessages.LOGGER.providerClassAlreadyRegistered(provider.getName());
return;
}
Map, Integer> newContracts = new HashMap, Integer>();
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));
paramConverterProviders = null;
newContracts.put(ParamConverterProvider.class, priority);
}
if (isA(provider, MessageBodyReader.class, contracts))
{
try
{
int priority = getPriority(priorityOverride, contracts, MessageBodyReader.class, provider);
addMessageBodyReader(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(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(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, ClientExceptionMapper.class, contracts))
{
try
{
addClientExceptionMapper(provider);
newContracts.put(ClientExceptionMapper.class, getPriority(priorityOverride, contracts, ClientExceptionMapper.class, provider));
}
catch (Exception e)
{
throw new RuntimeException(Messages.MESSAGES.unableToInstantiateClientExceptionMapper(), e);
}
}
if (isA(provider, AsyncResponseProvider.class, contracts))
{
try
{
addAsyncResponseProvider(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(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(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);
{ // code maintained for backward compatibility for jaxrs-legacy code
if (clientRequestFilters == null)
{
clientRequestFilters = parent.getClientRequestFilters().clone(this);
}
clientRequestFilters.registerClass(provider, 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, ClientExecutionInterceptor.class, contracts))
{
if (clientExecutionInterceptorRegistry == null)
{
clientExecutionInterceptorRegistry = parent.getClientExecutionInterceptorRegistry().cloneTo(this);
}
clientExecutionInterceptorRegistry.register(provider);
newContracts.put(ClientExecutionInterceptor.class, 0);
}
if (isA(provider, PreProcessInterceptor.class, contracts))
{
if (containerRequestFilterRegistry == null)
{
containerRequestFilterRegistry = parent.getContainerRequestFilterRegistry().clone(this);
}
containerRequestFilterRegistry.registerLegacy(provider);
newContracts.put(PreProcessInterceptor.class, 0);
}
if (isA(provider, PostProcessInterceptor.class, contracts))
{
if (containerResponseFilterRegistry == null)
{
containerResponseFilterRegistry = parent.getContainerResponseFilterRegistry().clone(this);
}
containerResponseFilterRegistry.registerLegacy(provider);
newContracts.put(PostProcessInterceptor.class, 0);
}
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, MessageBodyWriterInterceptor.class, contracts))
{
if (provider.isAnnotationPresent(ServerInterceptor.class))
{
if (serverWriterInterceptorRegistry == null)
{
serverWriterInterceptorRegistry = parent.getServerWriterInterceptorRegistry().clone(this);
}
serverWriterInterceptorRegistry.registerLegacy(provider);
}
if (provider.isAnnotationPresent(ClientInterceptor.class))
{
if (clientWriterInterceptorRegistry == null)
{
clientWriterInterceptorRegistry = parent.getClientWriterInterceptorRegistry().clone(this);
}
clientWriterInterceptorRegistry.registerLegacy(provider);
}
if (!provider.isAnnotationPresent(ServerInterceptor.class) && !provider.isAnnotationPresent(ClientInterceptor.class))
{
throw new RuntimeException(Messages.MESSAGES.interceptorClassMustBeAnnotated());
}
newContracts.put(MessageBodyWriterInterceptor.class, 0);
}
if (isA(provider, MessageBodyReaderInterceptor.class, contracts))
{
if (provider.isAnnotationPresent(ServerInterceptor.class))
{
if (serverReaderInterceptorRegistry == null)
{
serverReaderInterceptorRegistry = parent.getServerReaderInterceptorRegistry().clone(this);
}
serverReaderInterceptorRegistry.registerLegacy(provider);
}
if (provider.isAnnotationPresent(ClientInterceptor.class))
{
if (clientReaderInterceptorRegistry == null)
{
clientReaderInterceptorRegistry = parent.getClientReaderInterceptorRegistry().clone(this);
}
clientReaderInterceptorRegistry.registerLegacy(provider);
}
if (!provider.isAnnotationPresent(ServerInterceptor.class) && !provider.isAnnotationPresent(ClientInterceptor.class))
{
throw new RuntimeException(Messages.MESSAGES.interceptorClassMustBeAnnotated());
}
newContracts.put(MessageBodyReaderInterceptor.class, 0);
}
if (isA(provider, ContextResolver.class, contracts))
{
try
{
int priority = getPriority(priorityOverride, contracts, ContextResolver.class, provider);
addContextResolver(provider, priority, isBuiltin);
newContracts.put(ContextResolver.class, priority);
}
catch (Exception e)
{
throw new RuntimeException(Messages.MESSAGES.unableToInstantiateContextResolver(), e);
}
}
if (isA(provider, StringConverter.class, contracts))
{
addStringConverter(provider);
int priority = getPriority(priorityOverride, contracts, StringConverter.class, provider);
newContracts.put(StringConverter.class, priority);
}
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);
}
}
featureClasses.add(provider);
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);
}
providerClasses.add(provider);
getClassContracts().put(provider, newContracts);
}
/**
* 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)
{
Class> providerClass = provider.getClass();
if (getClassContracts().containsKey(providerClass))
{
LogMessages.LOGGER.providerInstanceAlreadyRegistered(providerClass.getName());
return;
}
Map, Integer> newContracts = new HashMap, Integer>();
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));
paramConverterProviders = null;
newContracts.put(ParamConverterProvider.class, priority);
}
if (isA(provider, MessageBodyReader.class, contracts))
{
try
{
int priority = getPriority(priorityOverride, contracts, MessageBodyReader.class, provider.getClass());
addMessageBodyReader((MessageBodyReader) provider, 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, 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, ClientExceptionMapper.class, contracts))
{
try
{
addClientExceptionMapper((ClientExceptionMapper) provider);
newContracts.put(ClientExceptionMapper.class, 0);
}
catch (Exception e)
{
throw new RuntimeException(Messages.MESSAGES.unableToInstantiateExceptionMapper(), e);
}
}
if (isA(provider, AsyncResponseProvider.class, contracts))
{
try
{
addAsyncResponseProvider((AsyncResponseProvider) provider);
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);
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);
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
{
int priority = getPriority(priorityOverride, contracts, ContextResolver.class, provider.getClass());
addContextResolver((ContextResolver) provider, priority);
newContracts.put(ContextResolver.class, priority);
}
catch (Exception e)
{
throw new RuntimeException(Messages.MESSAGES.unableToInstantiateContextResolver(), 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);
{ // code maintained for backward compatibility for jaxrs-legacy code
if (clientRequestFilters == null)
{
clientRequestFilters = parent.getClientRequestFilters().clone(this);
}
clientRequestFilters.registerSingleton((ClientRequestFilter) provider, 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, ClientExecutionInterceptor.class, contracts))
{
if (clientExecutionInterceptorRegistry == null)
{
clientExecutionInterceptorRegistry = parent.getClientExecutionInterceptorRegistry().cloneTo(this);
}
clientExecutionInterceptorRegistry.register((ClientExecutionInterceptor) provider);
newContracts.put(ClientExecutionInterceptor.class, 0);
}
if (isA(provider, PreProcessInterceptor.class, contracts))
{
if (containerRequestFilterRegistry == null)
{
containerRequestFilterRegistry = parent.getContainerRequestFilterRegistry().clone(this);
}
containerRequestFilterRegistry.registerLegacy((PreProcessInterceptor) provider);
newContracts.put(PreProcessInterceptor.class, 0);
}
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, PostProcessInterceptor.class, contracts))
{
if (containerResponseFilterRegistry == null)
{
containerResponseFilterRegistry = parent.getContainerResponseFilterRegistry().clone(this);
}
containerResponseFilterRegistry.registerLegacy((PostProcessInterceptor) provider);
newContracts.put(PostProcessInterceptor.class, 0);
}
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, MessageBodyWriterInterceptor.class, contracts))
{
if (provider.getClass().isAnnotationPresent(ServerInterceptor.class))
{
if (serverWriterInterceptorRegistry == null)
{
serverWriterInterceptorRegistry = parent.getServerWriterInterceptorRegistry().clone(this);
}
serverWriterInterceptorRegistry.registerLegacy((MessageBodyWriterInterceptor) provider);
}
if (provider.getClass().isAnnotationPresent(ClientInterceptor.class))
{
if (clientWriterInterceptorRegistry == null)
{
clientWriterInterceptorRegistry = parent.getClientWriterInterceptorRegistry().clone(this);
}
clientWriterInterceptorRegistry.registerLegacy((MessageBodyWriterInterceptor) provider);
}
if (!provider.getClass().isAnnotationPresent(ServerInterceptor.class) && !provider.getClass().isAnnotationPresent(ClientInterceptor.class))
{
throw new RuntimeException(Messages.MESSAGES.interceptorClassMustBeAnnotatedWithClass(provider.getClass()));
}
newContracts.put(MessageBodyWriterInterceptor.class, 0);
}
if (isA(provider, MessageBodyReaderInterceptor.class, contracts))
{
if (provider.getClass().isAnnotationPresent(ServerInterceptor.class))
{
if (serverReaderInterceptorRegistry == null)
{
serverReaderInterceptorRegistry = parent.getServerReaderInterceptorRegistry().clone(this);
}
serverReaderInterceptorRegistry.registerLegacy((MessageBodyReaderInterceptor) provider);
}
if (provider.getClass().isAnnotationPresent(ClientInterceptor.class))
{
if (clientReaderInterceptorRegistry == null)
{
clientReaderInterceptorRegistry = parent.getClientReaderInterceptorRegistry().clone(this);
}
clientReaderInterceptorRegistry.registerLegacy((MessageBodyReaderInterceptor) provider);
}
if (!provider.getClass().isAnnotationPresent(ServerInterceptor.class) && !provider.getClass().isAnnotationPresent(ClientInterceptor.class))
{
throw new RuntimeException(Messages.MESSAGES.interceptorClassMustBeAnnotatedWithClass(provider.getClass()));
}
newContracts.put(MessageBodyReaderInterceptor.class, 0);
}
if (isA(provider, StringConverter.class, contracts))
{
addStringConverter((StringConverter) provider);
newContracts.put(StringConverter.class, 0);
}
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());
featureInstances.add(provider);
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);
}
providerInstances.add(provider);
getClassContracts().put(provider.getClass(), newContracts);
}
@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;
}
public ClientExceptionMapper getClientExceptionMapper(Class type)
{
return getClientExceptionMappers().get(type);
}
// @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;
}
public MessageBodyWriter getServerMessageBodyWriter(Class type, Type genericType, Annotation[] annotations, MediaType mediaType)
{
MediaTypeMap> availableWriters = getServerMessageBodyWriters();
return resolveMessageBodyWriter(type, genericType, annotations, mediaType, availableWriters);
}
/**
* 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 type
* @return message writer
*/
public MessageBodyWriter getMessageBodyWriter(Class type, Type genericType, Annotation[] annotations, MediaType mediaType)
{
MediaTypeMap> availableWriters = getServerMessageBodyWriters();
MessageBodyWriter writer = resolveMessageBodyWriter(type, genericType, annotations, mediaType, availableWriters);
if (writer!=null)
LogMessages.LOGGER.debugf("MessageBodyWriter: %s", writer.getClass().getName());
return writer;
}
public MessageBodyWriter getClientMessageBodyWriter(Class type, Type genericType, Annotation[] annotations, MediaType mediaType)
{
MediaTypeMap> availableWriters = getClientMessageBodyWriters();
return resolveMessageBodyWriter(type, genericType, annotations, mediaType, availableWriters);
}
protected MessageBodyWriter resolveMessageBodyWriter(Class type, Type genericType, Annotation[] annotations, MediaType mediaType, MediaTypeMap> availableWriters)
{
List> writers = availableWriters.getPossible(mediaType, type);
/*
logger.info("******* getMessageBodyWriter(" + type.getName() + ", " + mediaType.toString() + ")****");
for (SortedKey writer : writers)
{
logger.info(" possible writer: " + writer.obj.getClass().getName());
}
*/
for (SortedKey writer : writers)
{
if (writer.obj.isWriteable(type, genericType, annotations, mediaType))
{
LogMessages.LOGGER.debugf("MessageBodyWriter: %s", writer.getClass().getName());
//logger.info(" picking: " + writer.obj.getClass().getName());
return (MessageBodyWriter) writer.obj;
}
}
return null;
}
/**
* This is a spec method that is unsupported. It is an optional method anyways.
*
* @param applicationConfig application
* @param endpointType endpoint type
* @return endpoint
* @throws IllegalArgumentException if applicationConfig is null
* @throws UnsupportedOperationException allways throw since this method is not supported
*/
public T createEndpoint(Application applicationConfig, Class endpointType) throws IllegalArgumentException, UnsupportedOperationException
{
if (applicationConfig == null) throw new IllegalArgumentException(Messages.MESSAGES.applicationParamNull());
throw new UnsupportedOperationException();
}
public ContextResolver getContextResolver(Class contextType, MediaType mediaType)
{
final List resolvers = getContextResolvers(contextType, mediaType);
if (resolvers == null) return null;
if (resolvers.size() == 1) return resolvers.get(0);
return new ContextResolver()
{
public T getContext(Class type)
{
for (ContextResolver resolver : resolvers)
{
Object rtn = resolver.getContext(type);
if (rtn != null) return (T) rtn;
}
return null;
}
};
}
/**
* Create an instance of a class using provider allocation rules of the specification as well as the InjectorFactory
* only does constructor injection.
*
* @param clazz class
* @param type
* @return provider instance of type T
*/
public