package org.jboss.resteasy.core.providerfactory;
import org.jboss.resteasy.core.InjectorFactoryImpl;
import org.jboss.resteasy.core.MediaTypeMap;
import org.jboss.resteasy.core.ResteasyContext;
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.spi.AsyncClientResponseProvider;
import org.jboss.resteasy.spi.AsyncResponseProvider;
import org.jboss.resteasy.spi.AsyncStreamProvider;
import org.jboss.resteasy.spi.ConstructorInjector;
import org.jboss.resteasy.spi.ContextInjector;
import org.jboss.resteasy.spi.Dispatcher;
import org.jboss.resteasy.spi.HeaderValueProcessor;
import org.jboss.resteasy.spi.HttpRequest;
import org.jboss.resteasy.spi.HttpResponse;
import org.jboss.resteasy.spi.InjectorFactory;
import org.jboss.resteasy.spi.LinkHeader;
import org.jboss.resteasy.spi.PropertyInjector;
import org.jboss.resteasy.spi.ResteasyProviderFactory;
import org.jboss.resteasy.spi.StringParameterUnmarshaller;
import org.jboss.resteasy.spi.interception.JaxrsInterceptorRegistry;
import org.jboss.resteasy.spi.metadata.ResourceBuilder;
import org.jboss.resteasy.spi.metadata.ResourceClassProcessor;
import org.jboss.resteasy.spi.statistics.StatisticsController;
import org.jboss.resteasy.spi.util.PickConstructor;
import org.jboss.resteasy.spi.util.Types;
import org.jboss.resteasy.statistics.StatisticsControllerImpl;
import org.jboss.resteasy.tracing.RESTEasyTracingLogger;
import org.jboss.resteasy.util.FeatureContextDelegate;
import org.jboss.resteasy.util.snapshot.SnapshotMap;
import org.jboss.resteasy.util.snapshot.SnapshotSet;
import javax.ws.rs.ConstrainedTo;
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.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.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.Iterator;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Objects;
import java.util.Set;
import java.util.TreeSet;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.CompletionStage;
import java.util.concurrent.ConcurrentHashMap;
@SuppressWarnings({"unchecked", "rawtypes"})
public class ResteasyProviderFactoryImpl extends ResteasyProviderFactory implements Providers, HeaderValueProcessor, Configurable<ResteasyProviderFactory>, Configuration
{
protected ClientHelper clientHelper;
protected ServerHelper serverHelper;
protected SnapshotSet<Class<?>> providerClasses;
protected SnapshotSet<Object> providerInstances;
protected SnapshotMap<Class<?>, Map<Class<?>, Integer>> classContracts;
protected SnapshotMap<String, Object> properties;
protected SnapshotMap<Class<?>, HeaderDelegate> ;
protected SnapshotMap<Type, ContextInjector> contextInjectors;
protected SnapshotMap<Type, ContextInjector> asyncContextInjectors;
protected SnapshotMap<Class<?>, Class<? extends StringParameterUnmarshaller>> stringParameterUnmarshallers;
protected SnapshotSet<Feature> enabledFeatures;
protected boolean attachedContextResolvers;
protected Map<Class<?>, MediaTypeMap<SortedKey<ContextResolver>>> contextResolvers;
protected boolean attachedParamConverterProviders;
protected Set<ExtSortedKey<ParamConverterProvider>> sortedParamConverterProviders;
protected Set<Class<?>> = ConcurrentHashMap.newKeySet();
protected boolean builtinsRegistered = false;
protected boolean registerBuiltins = true;
protected InjectorFactory injectorFactory;
protected ResourceBuilder resourceBuilder;
protected boolean initialized = false;
protected boolean lockSnapshots;
protected StatisticsControllerImpl statisticsController = new StatisticsControllerImpl();
public ResteasyProviderFactoryImpl()
{
initialize();
}
public ResteasyProviderFactoryImpl(final RuntimeType runtimeType)
{
if (runtimeType != RuntimeType.CLIENT) throw new IllegalStateException();
this.clientHelper = new ClientHelper(this);
this.serverHelper = NOOPServerHelper.SINGLETON;
initializeCommon(null, true, false);
lockSnapshots();
}
public ResteasyProviderFactoryImpl(final RuntimeType runtimeType, final ResteasyProviderFactory parent)
{
if (runtimeType == RuntimeType.CLIENT) {
ResteasyProviderFactoryImpl impl = (ResteasyProviderFactoryImpl) parent;
this.clientHelper = new ClientHelper(this, impl.clientHelper);
this.serverHelper = NOOPServerHelper.SINGLETON;
this.lockSnapshots = true;
initializeCommon(impl, true, false);
lockSnapshots();
} else {
ResteasyProviderFactoryImpl parentImpl = (ResteasyProviderFactoryImpl)parent;
clientHelper = NOOPClientHelper.SINGLETON;
serverHelper = new ServerHelper(this, parentImpl.serverHelper);
initializeCommon(parentImpl, false, true);
}
}
protected void registerBuiltin()
{
RegisterBuiltin.register(this);
}
protected void initializeCommon(ResteasyProviderFactoryImpl parent, boolean lockSnapshots, boolean snapFirst)
{
properties = parent == null ? new SnapshotMap<>(lockSnapshots) : new SnapshotMap<>(parent.properties, true, lockSnapshots, snapFirst);
providerClasses = parent == null ? new SnapshotSet<>(lockSnapshots) : new SnapshotSet<>(parent.providerClasses, true, lockSnapshots, snapFirst);
providerInstances = parent == null ? new SnapshotSet<>(lockSnapshots) : new SnapshotSet<>(parent.providerInstances, true, lockSnapshots, snapFirst);
classContracts = parent == null ? new SnapshotMap<>(lockSnapshots) : new SnapshotMap<>(parent.classContracts, true, lockSnapshots, snapFirst);
enabledFeatures = parent == null ? new SnapshotSet<>(lockSnapshots) : new SnapshotSet<>(parent.enabledFeatures, true, lockSnapshots, snapFirst);
if (parent != null) {
if (snapFirst) {
attachedParamConverterProviders = true;
sortedParamConverterProviders = parent.sortedParamConverterProviders;
attachedContextResolvers = true;
contextResolvers = parent.contextResolvers;
} else {
contextResolvers = new ConcurrentHashMap<>();
for (Entry<Class<?>, MediaTypeMap<SortedKey<ContextResolver>>> entry : parent.contextResolvers.entrySet())
{
contextResolvers.put(entry.getKey(), new MediaTypeMap<>(entry.getValue()));
}
sortedParamConverterProviders = Collections.synchronizedSortedSet(new TreeSet<>(parent.sortedParamConverterProviders));
}
} else {
contextResolvers = new ConcurrentHashMap<>();
sortedParamConverterProviders = Collections.synchronizedSortedSet(new TreeSet<>());
}
resourceBuilder = new ResourceBuilder();
headerDelegates = parent == null ? new SnapshotMap<>(lockSnapshots) : new SnapshotMap<>(parent.getHeaderDelegates(), true, lockSnapshots, snapFirst);
if (parent == null) {
addHeaderDelegateIfAbsent(MediaType.class, MediaTypeHeaderDelegate.INSTANCE);
addHeaderDelegateIfAbsent(NewCookie.class, NewCookieHeaderDelegate.INSTANCE);
addHeaderDelegateIfAbsent(Cookie.class, CookieHeaderDelegate.INSTANCE);
addHeaderDelegateIfAbsent(URI.class, UriHeaderDelegate.INSTANCE);
addHeaderDelegateIfAbsent(EntityTag.class, EntityTagDelegate.INSTANCE);
addHeaderDelegateIfAbsent(CacheControl.class, CacheControlDelegate.INSTANCE);
addHeaderDelegateIfAbsent(Locale.class, LocaleDelegate.INSTANCE);
addHeaderDelegateIfAbsent(LinkHeader.class, LinkHeaderDelegate.INSTANCE);
addHeaderDelegateIfAbsent(javax.ws.rs.core.Link.class, LinkDelegate.INSTANCE);
addHeaderDelegateIfAbsent(Date.class, DateDelegate.INSTANCE);
}
builtinsRegistered = false;
registerBuiltins = true;
stringParameterUnmarshallers = parent == null ? new SnapshotMap<>(lockSnapshots) : new SnapshotMap<>(parent.stringParameterUnmarshallers, true, lockSnapshots, snapFirst);
contextInjectors = parent == null ? new SnapshotMap<>(lockSnapshots) : new SnapshotMap<>(parent.contextInjectors, true, lockSnapshots, snapFirst);
asyncContextInjectors = parent == null ? new SnapshotMap<>(lockSnapshots) : new SnapshotMap<>(parent.asyncContextInjectors, true, lockSnapshots, snapFirst);
injectorFactory = parent == null ? InjectorFactoryImpl.INSTANCE : parent.getInjectorFactory();
initialized = true;
}
private void copyResolversIfNeeded() {
if (!attachedContextResolvers) return;
Map<Class<?>, MediaTypeMap<SortedKey<ContextResolver>>> newResolvers = new ConcurrentHashMap<>();
for (Entry<Class<?>, MediaTypeMap<SortedKey<ContextResolver>>> entry : contextResolvers.entrySet())
{
newResolvers.put(entry.getKey(), new MediaTypeMap<>(entry.getValue()));
}
contextResolvers = newResolvers;
attachedContextResolvers = false;
}
protected void initialize()
{
initializeCommon(null, false, false);
clientHelper = new ClientHelper(this);
serverHelper = new ServerHelper(this);
}
public void lockSnapshots() {
lockSnapshots = true;
if (providerClasses != null) providerClasses.lockSnapshots();
if (providerInstances != null) providerInstances.lockSnapshots();
if (classContracts != null) classContracts.lockSnapshots();
if (properties != null) properties.lockSnapshots();
if (headerDelegates != null) headerDelegates.lockSnapshots();
if (contextInjectors != null) contextInjectors.lockSnapshots();
if (asyncContextInjectors != null) asyncContextInjectors.lockSnapshots();
if (stringParameterUnmarshallers != null) stringParameterUnmarshallers.lockSnapshots();
if (enabledFeatures != null) enabledFeatures.lockSnapshots();
clientHelper.lockSnapshots();
serverHelper.lockSnapshots();
}
public Set<DynamicFeature> getServerDynamicFeatures()
{
return serverHelper.getDynamicFeatures();
}
public Set<DynamicFeature> getClientDynamicFeatures()
{
return clientHelper.getDynamicFeatures();
}
protected MediaTypeMap<SortedKey<MessageBodyReader>> getServerMessageBodyReaders()
{
return serverHelper.getMessageBodyReaders();
}
protected MediaTypeMap<SortedKey<MessageBodyWriter>> getServerMessageBodyWriters()
{
return serverHelper.getMessageBodyWriters();
}
protected MediaTypeMap<SortedKey<MessageBodyReader>> getClientMessageBodyReaders()
{
return clientHelper.getMessageBodyReaders();
}
protected MediaTypeMap<SortedKey<MessageBodyWriter>> getClientMessageBodyWriters()
{
return clientHelper.getMessageBodyWriters();
}
private Map<Class<?>, SortedKey<ExceptionMapper>> getSortedExceptionMappers()
{
return serverHelper.getExceptionMappers();
}
public Map<Class<?>, AsyncResponseProvider> getAsyncResponseProviders()
{
return serverHelper.getAsyncResponseProviders();
}
public Map<Class<?>, AsyncStreamProvider> getAsyncStreamProviders()
{
return serverHelper.getAsyncStreamProviders();
}
public Map<Class<?>, AsyncClientResponseProvider> getAsyncClientResponseProviders()
{
return clientHelper.getAsyncClientResponseProviders();
}
public Map<Type, ContextInjector> getContextInjectors()
{
return contextInjectors;
}
public Map<Type, ContextInjector> getAsyncContextInjectors()
{
return asyncContextInjectors;
}
protected Map<Class<?>, MediaTypeMap<SortedKey<ContextResolver>>> getContextResolvers()
{
return contextResolvers;
}
protected Set<ExtSortedKey<ParamConverterProvider>> getSortedParamConverterProviders()
{
return sortedParamConverterProviders;
}
protected Map<Class<?>, Class<? extends StringParameterUnmarshaller>> getStringParameterUnmarshallers()
{
return stringParameterUnmarshallers;
}
public Set<Class<?>> getProviderClasses()
{
return Collections.unmodifiableSet(providerClasses);
}
public Set<Object> getProviderInstances()
{
return Collections.unmodifiableSet(providerInstances);
}
public Map<Class<?>, Map<Class<?>, Integer>> getClassContracts()
{
return classContracts;
}
public <T> T getContextData(Class<T> rawType, Type genericType, Annotation[] annotations, boolean unwrapAsync)
{
T ret = (T) ResteasyContext.getContextDataMap().get(rawType);
if (ret != null)
return ret;
ContextInjector contextInjector = getContextInjectors().get(genericType);
boolean async = false;
if (contextInjector == null && unwrapAsync)
{
contextInjector = getAsyncContextInjectors().get(Types.boxPrimitives(genericType));
async = true;
}
if (contextInjector != null)
{
ret = (T) contextInjector.resolve(rawType, genericType, annotations);
if (async && ret != null)
{
Type wrappedType = Types.getActualTypeArgumentsOfAnInterface(contextInjector.getClass(),
ContextInjector.class)[0];
Class<?> rawWrappedType = Types.getRawType(wrappedType);
AsyncResponseProvider converter = getAsyncResponseProvider(rawWrappedType);
ret = (T) converter.toCompletionStage(ret);
}
}
return ret;
}
public boolean isRegisterBuiltins()
{
return registerBuiltins;
}
public void setRegisterBuiltins(boolean registerBuiltins)
{
this.registerBuiltins = registerBuiltins;
}
public InjectorFactory getInjectorFactory()
{
return injectorFactory;
}
public void setInjectorFactory(InjectorFactory injectorFactory)
{
this.injectorFactory = injectorFactory;
}
public JaxrsInterceptorRegistry<ReaderInterceptor> getServerReaderInterceptorRegistry()
{
return serverHelper.getReaderInterceptorRegistry();
}
public JaxrsInterceptorRegistry<WriterInterceptor> getServerWriterInterceptorRegistry()
{
return serverHelper.getWriterInterceptorRegistry();
}
public JaxrsInterceptorRegistry<ContainerRequestFilter> getContainerRequestFilterRegistry()
{
return serverHelper.getRequestFilters();
}
public JaxrsInterceptorRegistry<ContainerResponseFilter> getContainerResponseFilterRegistry()
{
return serverHelper.getResponseFilters();
}
public JaxrsInterceptorRegistry<ReaderInterceptor> getClientReaderInterceptorRegistry()
{
return clientHelper.getReaderInterceptorRegistry();
}
public JaxrsInterceptorRegistry<WriterInterceptor> getClientWriterInterceptorRegistry()
{
return clientHelper.getWriterInterceptorRegistry();
}
public JaxrsInterceptorRegistry<ClientRequestFilter> getClientRequestFilterRegistry()
{
return clientHelper.getRequestFilters();
}
public JaxrsInterceptorRegistry<ClientResponseFilter> getClientResponseFilters()
{
return clientHelper.getResponseFilters();
}
public boolean isBuiltinsRegistered()
{
return builtinsRegistered;
}
public void setBuiltinsRegistered(boolean builtinsRegistered)
{
this.builtinsRegistered = builtinsRegistered;
}
public UriBuilder createUriBuilder()
{
return Utils.createUriBuilder();
}
public Response.ResponseBuilder createResponseBuilder()
{
return Utils.createResponseBuilder();
}
public Variant.VariantListBuilder createVariantListBuilder()
{
return Utils.createVariantListBuilder();
}
public <T> HeaderDelegate<T> (Class<T> tClass)
{
if (tClass == null)
throw new IllegalArgumentException(Messages.MESSAGES.tClassParameterNull());
return Utils.createHeaderDelegate(headerDelegates, alreadyEstablishedNullHeaderDelegate, tClass);
}
protected Map<Class<?>, HeaderDelegate> ()
{
return headerDelegates;
}
public void (Class clazz, HeaderDelegate header)
{
headerDelegates.put(clazz, header);
}
protected void (Class clazz, HeaderDelegate header)
{
if (!headerDelegates.containsKey(clazz))
{
addHeaderDelegate(clazz, header);
}
}
@Deprecated
public <T> MessageBodyReader<T> getServerMessageBodyReader(Class<T> type, Type genericType, Annotation[] annotations,
MediaType mediaType)
{
MediaTypeMap<SortedKey<MessageBodyReader>> availableReaders = getServerMessageBodyReaders();
return resolveMessageBodyReader(type, genericType, annotations, mediaType, availableReaders);
}
public <T> MessageBodyReader<T> getServerMessageBodyReader(Class<T> type, Type genericType, Annotation[] annotations,
MediaType mediaType, RESTEasyTracingLogger tracingLogger)
{
MediaTypeMap<SortedKey<MessageBodyReader>> availableReaders = getServerMessageBodyReaders();
return resolveMessageBodyReader(type, genericType, annotations, mediaType, availableReaders, tracingLogger);
}
public <T> MessageBodyReader<T> getMessageBodyReader(Class<T> type, Type genericType, Annotation[] annotations,
MediaType mediaType)
{
MediaTypeMap<SortedKey<MessageBodyReader>> availableReaders = getServerMessageBodyReaders();
MessageBodyReader<T> reader = resolveMessageBodyReader(type, genericType, annotations, mediaType,
availableReaders);
if (reader != null)
LogMessages.LOGGER.debugf("MessageBodyReader: %s", reader.getClass().getName());
return reader;
}
public <T> MessageBodyReader<T> getClientMessageBodyReader(Class<T> type, Type genericType, Annotation[] annotations,
MediaType mediaType)
{
MediaTypeMap<SortedKey<MessageBodyReader>> availableReaders = getClientMessageBodyReaders();
if (availableReaders == null) return null;
return resolveMessageBodyReader(type, genericType, annotations, mediaType, availableReaders);
}
@Deprecated
private <T> MessageBodyReader<T> resolveMessageBodyReader(Class<T> type, Type genericType, Annotation[] annotations,
MediaType mediaType, MediaTypeMap<SortedKey<MessageBodyReader>> availableReaders)
{
if (availableReaders == null) return null;
List<SortedKey<MessageBodyReader>> readers = availableReaders.getPossible(mediaType, type);
for (SortedKey<MessageBodyReader> reader : readers)
{
if (reader.getObj().isReadable(type, genericType, annotations, mediaType))
{
LogMessages.LOGGER.debugf("MessageBodyReader: %s", reader.getClass().getName());
return (MessageBodyReader<T>) reader.getObj();
}
}
return null;
}
private <T> MessageBodyReader<T> resolveMessageBodyReader(Class<T> type, Type genericType,
Annotation[] annotations, MediaType mediaType, MediaTypeMap<SortedKey<MessageBodyReader>> availableReaders,
RESTEasyTracingLogger tracingLogger)
{
if (availableReaders == null) return null;
List<SortedKey<MessageBodyReader>> readers = availableReaders.getPossible(mediaType, type);
if (tracingLogger.isLogEnabled("MBR_FIND"))
{
tracingLogger.log("MBR_FIND", type.getName(),
(genericType instanceof Class ? ((Class) genericType).getName() : genericType), mediaType,
java.util.Arrays.toString(annotations));
}
MessageBodyReader<T> result = null;
Iterator<SortedKey<MessageBodyReader>> iterator = readers.iterator();
while (iterator.hasNext())
{
final SortedKey<MessageBodyReader> reader = iterator.next();
if (reader.getObj().isReadable(type, genericType, annotations, mediaType))
{
LogMessages.LOGGER.debugf("MessageBodyReader: %s", reader.getClass().getName());
result = (MessageBodyReader<T>) reader.getObj();
tracingLogger.log("MBR_SELECTED", reader);
break;
}
tracingLogger.log("MBR_NOT_READABLE", result);
}
if (tracingLogger.isLogEnabled("MBR_SKIPPED"))
{
while (iterator.hasNext())
{
final SortedKey<MessageBodyReader> reader = iterator.next();
tracingLogger.log("MBR_SKIPPED", reader.getObj());
}
}
return result;
}
private void addContextInjector(ContextInjector provider, Class providerClass)
{
Type[] typeArgs = Types.getActualTypeArgumentsOfAnInterface(providerClass, ContextInjector.class);
Utils.injectProperties(this, provider.getClass(), provider);
contextInjectors.put(typeArgs[0], provider);
if (!Objects.equals(typeArgs[0], typeArgs[1]))
{
asyncContextInjectors.put(typeArgs[1], provider);
}
}
private void addContextResolver(ContextResolver provider, int priority, Class providerClass, boolean builtin)
{
if (providerClass.getName().contains("$$Lambda$"))
{
throw new RuntimeException(Messages.MESSAGES.registeringContextResolverAsLambda());
}
copyResolversIfNeeded();
Type typeParameter = Types.getActualTypeArgumentsOfAnInterface(providerClass, ContextResolver.class)[0];
Utils.injectProperties(this, providerClass, provider);
Class<?> parameterClass = Types.getRawType(typeParameter);
MediaTypeMap<SortedKey<ContextResolver>> resolvers = contextResolvers.get(parameterClass);
if (resolvers == null)
{
resolvers = new MediaTypeMap<SortedKey<ContextResolver>>();
contextResolvers.put(parameterClass, resolvers);
}
Produces produces = provider.getClass().getAnnotation(Produces.class);
SortedKey<ContextResolver> key = new SortedKey<ContextResolver>(ContextResolver.class, provider, providerClass, priority, builtin);
if (produces != null)
{
for (String produce : produces.value())
{
resolvers.add(produce, key);
}
}
else
{
resolvers.add(MediaType.WILDCARD, key);
}
}
public void addStringParameterUnmarshaller(Class<? extends StringParameterUnmarshaller> provider)
{
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<ContextResolver> getContextResolvers(final Class<?> clazz, MediaType type)
{
if (getContextResolvers() == null) return null;
MediaTypeMap<SortedKey<ContextResolver>> resolvers = getContextResolvers().get(clazz);
if (resolvers == null)
return null;
List<ContextResolver> rtn = new ArrayList<ContextResolver>();
List<SortedKey<ContextResolver>> list = resolvers.getPossible(type);
list.forEach(resolver -> rtn.add(resolver.getObj()));
return rtn;
}
public ParamConverter getParamConverter(Class clazz, Type genericType, Annotation[] annotations)
{
try
{
ResteasyContext.pushContext(ResteasyProviderFactory.class, this);
for (SortedKey<ParamConverterProvider> provider : getSortedParamConverterProviders())
{
ParamConverter converter = provider.getObj().getConverter(clazz, genericType, annotations);
if (converter != null) return converter;
}
return null;
}
finally
{
ResteasyContext.popContextData(ResteasyProviderFactory.class);
}
}
public <T> StringParameterUnmarshaller<T> createStringParameterUnmarshaller(Class<T> clazz)
{
if (getStringParameterUnmarshallers() == null || getStringParameterUnmarshallers().isEmpty())
return null;
Class<? extends StringParameterUnmarshaller> un = getStringParameterUnmarshallers().get(clazz);
if (un == null)
return null;
StringParameterUnmarshaller<T> provider = injectedInstance(un);
return provider;
}
public void registerProvider(Class provider)
{
registerProvider(provider, false);
}
public String toString(Object object, Class clazz, Type genericType, Annotation[] annotations)
{
if (object instanceof String)
return (String) object;
ParamConverter paramConverter = getParamConverter(clazz, genericType, annotations);
if (paramConverter != null)
{
return paramConverter.toString(object);
}
return object.toString();
}
@Override
public String (Object object)
{
if (object == null)
return "";
if (object instanceof String)
return (String) object;
Class<?> aClass = object.getClass();
ParamConverter paramConverter = getParamConverter(aClass, null, null);
if (paramConverter != null)
{
return paramConverter.toString(object);
}
HeaderDelegate delegate = getHeaderDelegate(aClass);
if (delegate != null)
return delegate.toString(object);
else
return object.toString();
}
public HeaderDelegate (Class<?> aClass)
{
HeaderDelegate delegate = null;
if (RuntimeDelegate.getInstance() instanceof ResteasyProviderFactory)
{
delegate = createHeaderDelegate(aClass);
}
else
{
delegate = RuntimeDelegate.getInstance().createHeaderDelegate(aClass);
}
return delegate;
}
public void registerProvider(Class provider, boolean isBuiltin)
{
registerProvider(provider, null, isBuiltin, null);
}
public void registerProvider(Class provider, Integer priorityOverride, boolean isBuiltin,
Map<Class<?>, Integer> contracts)
{
Map<Class<?>, Map<Class<?>, Integer>> classContracts = getClassContracts();
if (classContracts.containsKey(provider))
{
LogMessages.LOGGER.providerClassAlreadyRegistered(provider.getName());
return;
}
final Map<Class<?>, Integer> newContracts = new HashMap<>();
processProviderContracts(provider, priorityOverride, isBuiltin, contracts, newContracts);
providerClasses.add(provider);
classContracts.put(provider, newContracts);
}
public Set<Class<?>> getMutableProviderClasses() {
return providerClasses;
}
private void processProviderContracts(Class provider, Integer priorityOverride, boolean isBuiltin,
Map<Class<?>, Integer> contracts, Map<Class<?>, Integer> newContracts)
{
clientHelper.processProviderContracts(provider, priorityOverride, isBuiltin, contracts, newContracts);
serverHelper.processProviderContracts(provider, priorityOverride, isBuiltin, contracts, newContracts);
if (Utils.isA(provider, ParamConverterProvider.class, contracts))
{
int priority = Utils.getPriority(priorityOverride, contracts, ParamConverterProvider.class, provider);
addParameterConverterProvider(provider, isBuiltin, priority);
newContracts.put(ParamConverterProvider.class, priority);
}
if (Utils.isA(provider, ContextResolver.class, contracts))
{
try
{
int priority = Utils.getPriority(priorityOverride, contracts, ContextResolver.class, provider);
addContextResolver(provider, isBuiltin, priority);
newContracts.put(ContextResolver.class, priority);
}
catch (Exception e)
{
throw new RuntimeException(Messages.MESSAGES.unableToInstantiateContextResolver(), e);
}
}
if (Utils.isA(provider, ContextInjector.class, contracts))
{
try
{
addContextInjector(provider);
int priority = Utils.getPriority(priorityOverride, contracts, ContextInjector.class, provider);
newContracts.put(ContextInjector.class, priority);
}
catch (Exception e)
{
throw new RuntimeException(Messages.MESSAGES.unableToInstantiateContextInjector(), e);
}
}
if (Utils.isA(provider, StringParameterUnmarshaller.class, contracts))
{
addStringParameterUnmarshaller(provider);
int priority = Utils.getPriority(priorityOverride, contracts, StringParameterUnmarshaller.class, provider);
newContracts.put(StringParameterUnmarshaller.class, priority);
}
if (Utils.isA(provider, InjectorFactory.class, contracts))
{
try
{
addInjectorFactory(provider);
newContracts.put(InjectorFactory.class, 0);
}
catch (Exception e)
{
throw new RuntimeException(e);
}
}
if (Utils.isA(provider, Feature.class, contracts))
{
ConstrainedTo constrainedTo = (ConstrainedTo) provider.getAnnotation(ConstrainedTo.class);
int priority = Utils.getPriority(priorityOverride, contracts, Feature.class, provider);
if (constrainedTo == null || constrainedTo.value() == getRuntimeType())
{
addFeature(provider);
}
newContracts.put(Feature.class, priority);
}
if (Utils.isA(provider, ResourceClassProcessor.class, contracts))
{
int priority = Utils.getPriority(priorityOverride, contracts, ResourceClassProcessor.class, provider);
addResourceClassProcessor(provider, priority);
newContracts.put(ResourceClassProcessor.class, priority);
}
if (Utils.isA(provider, HeaderDelegate.class, contracts))
{
addHeaderDelegate(provider);
}
}
public void (Class provider) {
Type[] headerTypes = Types.getActualTypeArgumentsOfAnInterface(provider, HeaderDelegate.class);
if (headerTypes.length == 0)
{
LogMessages.LOGGER.cannotRegisterheaderDelegate(provider);
}
else
{
Class<?> headerClass = Types.getRawType(headerTypes[0]);
addHeaderDelegate(provider, headerClass);
}
}
public ClientHelper getClientHelper() {
return clientHelper;
}
public ServerHelper getServerHelper() {
return serverHelper;
}
public void (Class<? extends HeaderDelegate> provider, Class<?> headerClass) {
HeaderDelegate<?> delegate = createProviderInstance(provider);
addHeaderDelegate(headerClass, delegate);
}
public void addFeature(Class<? extends Feature> provider) {
Feature feature = injectedInstance(provider);
if (feature.configure(new FeatureContextDelegate(this)))
{
enabledFeatures.add(feature);
}
}
public void addInjectorFactory(Class provider) throws InstantiationException, IllegalAccessException {
this.injectorFactory = (InjectorFactory) provider.newInstance();
}
public void addContextInjector(Class provider) {
addContextInjector(createProviderInstance((Class<? extends ContextInjector>) provider), provider);
}
public void addContextResolver(Class provider, boolean isBuiltin, int priority) {
addContextResolver(createProviderInstance((Class<? extends ContextResolver>)provider), priority, provider, isBuiltin);
}
public void addParameterConverterProvider(Class provider, boolean isBuiltin, int priority) {
ParamConverterProvider paramConverterProvider = (ParamConverterProvider) injectedInstance(provider);
injectProperties(provider);
copyParamConvertsIfNeeded();
sortedParamConverterProviders
.add(new ExtSortedKey<>(null, paramConverterProvider, provider, priority, isBuiltin));
}
private void copyParamConvertsIfNeeded() {
if (attachedParamConverterProviders) {
sortedParamConverterProviders = Collections.synchronizedSortedSet(new TreeSet<>(sortedParamConverterProviders));
attachedParamConverterProviders = false;
}
}
public void registerProviderInstance(Object provider)
{
registerProviderInstance(provider, null, null, false);
}
public void registerProviderInstance(Object provider, Map<Class<?>, Integer> contracts, Integer priorityOverride,
boolean builtIn)
{
Class<?> providerClass = provider.getClass();
Map<Class<?>, Map<Class<?>, Integer>> classContracts = getClassContracts();
if (classContracts.containsKey(providerClass))
{
LogMessages.LOGGER.providerInstanceAlreadyRegistered(providerClass.getName());
return;
}
Map<Class<?>, Integer> newContracts = new HashMap<>();
processProviderInstanceContracts(provider, contracts, priorityOverride, builtIn, newContracts);
providerInstances.add(provider);
classContracts.put(providerClass, newContracts);
}
private void processProviderInstanceContracts(Object provider, Map<Class<?>, Integer> contracts,
Integer priorityOverride, boolean builtIn, Map<Class<?>, Integer> newContracts)
{
clientHelper.processProviderInstanceContracts(provider, contracts, priorityOverride, builtIn, newContracts);
serverHelper.processProviderInstanceContracts(provider, contracts, priorityOverride, builtIn, newContracts);
if (Utils.isA(provider, ParamConverterProvider.class, contracts))
{
injectProperties(provider);
int priority = Utils.getPriority(priorityOverride, contracts, ParamConverterProvider.class, provider.getClass());
copyParamConvertsIfNeeded();
sortedParamConverterProviders.add(
new ExtSortedKey<>(null, (ParamConverterProvider) provider, provider.getClass(), priority, builtIn));
newContracts.put(ParamConverterProvider.class, priority);
}
if (Utils.isA(provider, ContextResolver.class, contracts))
{
try
{
int priority = Utils.getPriority(priorityOverride, contracts, ContextResolver.class, provider.getClass());
addContextResolver((ContextResolver) provider, priority, provider.getClass(), false);
newContracts.put(ContextResolver.class, priority);
}
catch (Exception e)
{
throw new RuntimeException(Messages.MESSAGES.unableToInstantiateContextResolver(), e);
}
}
if (Utils.isA(provider, ContextInjector.class, contracts))
{
try
{
addContextInjector((ContextInjector) provider, provider.getClass());
int priority = Utils.getPriority(priorityOverride, contracts, ContextInjector.class, provider.getClass());
newContracts.put(ContextInjector.class, priority);
}
catch (Exception e)
{
throw new RuntimeException(Messages.MESSAGES.unableToInstantiateContextInjector(), e);
}
}
if (Utils.isA(provider, InjectorFactory.class, contracts))
{
this.injectorFactory = (InjectorFactory) provider;
newContracts.put(InjectorFactory.class, 0);
}
if (Utils.isA(provider, Feature.class, contracts))
{
Feature feature = (Feature) provider;
Utils.injectProperties(this, 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 = Utils.getPriority(priorityOverride, contracts, Feature.class, provider.getClass());
newContracts.put(Feature.class, priority);
}
if (Utils.isA(provider, ResourceClassProcessor.class, contracts))
{
int priority = Utils.getPriority(priorityOverride, contracts, ResourceClassProcessor.class, provider.getClass());
addResourceClassProcessor((ResourceClassProcessor) provider, priority);
newContracts.put(ResourceClassProcessor.class, priority);
}
if (Utils.isA(provider, HeaderDelegate.class, contracts))
{
Type[] headerTypes = Types.getActualTypeArgumentsOfAnInterface(provider.getClass(), HeaderDelegate.class);
if (headerTypes.length == 0)
{
LogMessages.LOGGER.cannotRegisterheaderDelegate(provider.getClass());
}
else
{
Class<?> headerClass = Types.getRawType(headerTypes[0]);
addHeaderDelegate(headerClass, (HeaderDelegate) provider);
}
}
}
@Override
public <T extends Throwable> ExceptionMapper<T> getExceptionMapper(Class<T> type)
{
Class exceptionType = type;
SortedKey<ExceptionMapper> mapper = null;
Map<Class<?>, SortedKey<ExceptionMapper>> mappers = getSortedExceptionMappers();
if (mappers == null) {
return null;
}
while (mapper == null)
{
if (exceptionType == null)
break;
mapper = mappers.get(exceptionType);
if (mapper == null)
exceptionType = exceptionType.getSuperclass();
}
return mapper != null ? mapper.getObj() : null;
}
public <T extends Throwable> ExceptionMapper<T> getExceptionMapperForClass(Class<T> type)
{
Map<Class<?>, SortedKey<ExceptionMapper>> mappers = getSortedExceptionMappers();
if (mappers == null) return null;
SortedKey<ExceptionMapper> mapper = mappers.get(type);
return mapper != null ? mapper.getObj() : null;
}
public <T> AsyncResponseProvider<T> getAsyncResponseProvider(Class<T> type)
{
Class asyncType = type;
AsyncResponseProvider<T> mapper = null;
while (mapper == null)
{
if (asyncType == null)
break;
Map<Class<?>, AsyncResponseProvider> asyncResponseProviders = getAsyncResponseProviders();
if (asyncResponseProviders != null) mapper = asyncResponseProviders.get(asyncType);
if (mapper == null)
asyncType = asyncType.getSuperclass();
}
return mapper;
}
public <T> AsyncClientResponseProvider<T> getAsyncClientResponseProvider(Class<T> type)
{
Class asyncType = type;
AsyncClientResponseProvider<T> mapper = null;
while (mapper == null)
{
if (asyncType == null)
break;
Map<Class<?>, AsyncClientResponseProvider> asyncClientResponseProviders = getAsyncClientResponseProviders();
if (asyncClientResponseProviders != null) mapper = asyncClientResponseProviders.get(asyncType);
if (mapper == null)
asyncType = asyncType.getSuperclass();
}
return mapper;
}
public <T> AsyncStreamProvider<T> getAsyncStreamProvider(Class<T> type)
{
Class asyncType = type;
AsyncStreamProvider<T> mapper = null;
while (mapper == null)
{
if (asyncType == null)
break;
Map<Class<?>, AsyncStreamProvider> asyncStreamProviders = getAsyncStreamProviders();
if (asyncStreamProviders != null) mapper = asyncStreamProviders.get(asyncType);
if (mapper == null)
asyncType = asyncType.getSuperclass();
}
return mapper;
}
public MediaType getConcreteMediaTypeFromMessageBodyWriters(Class<?> type, Type genericType,
Annotation[] annotations, MediaType mediaType)
{
List<SortedKey<MessageBodyWriter>> writers = getServerMessageBodyWriters().getPossible(mediaType, type);
for (SortedKey<MessageBodyWriter> writer : writers)
{
if (writer.getObj().isWriteable(type, genericType, annotations, mediaType))
{
MessageBodyWriter mbw = writer.getObj();
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<MessageBodyWriter<?>, Class<?>> getPossibleMessageBodyWritersMap(Class type, Type genericType,
Annotation[] annotations, MediaType accept)
{
Map<MessageBodyWriter<?>, Class<?>> map = new HashMap<MessageBodyWriter<?>, Class<?>>();
MediaTypeMap<SortedKey<MessageBodyWriter>> serverMessageBodyWriters = getServerMessageBodyWriters();
if (serverMessageBodyWriters == null) return map;
List<SortedKey<MessageBodyWriter>> writers = serverMessageBodyWriters.getPossible(accept, type);
for (SortedKey<MessageBodyWriter> writer : writers)
{
if (writer.getObj().isWriteable(type, genericType, annotations, accept))
{
Class<?> mbwc = writer.getObj().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.getObj(), writerType);
}
}
return map;
}
@Deprecated
public <T> MessageBodyWriter<T> getServerMessageBodyWriter(Class<T> type, Type genericType, Annotation[] annotations,
MediaType mediaType)
{
MediaTypeMap<SortedKey<MessageBodyWriter>> availableWriters = getServerMessageBodyWriters();
return resolveMessageBodyWriter(type, genericType, annotations, mediaType, availableWriters);
}
public <T> MessageBodyWriter<T> getServerMessageBodyWriter(Class<T> type, Type genericType, Annotation[] annotations,
MediaType mediaType, RESTEasyTracingLogger tracingLogger)
{
MediaTypeMap<SortedKey<MessageBodyWriter>> availableWriters = getServerMessageBodyWriters();
return resolveMessageBodyWriter(type, genericType, annotations, mediaType, availableWriters, tracingLogger);
}
public <T> MessageBodyWriter<T> getMessageBodyWriter(Class<T> type, Type genericType, Annotation[] annotations,
MediaType mediaType)
{
MediaTypeMap<SortedKey<MessageBodyWriter>> availableWriters = getServerMessageBodyWriters();
MessageBodyWriter<T> writer = resolveMessageBodyWriter(type, genericType, annotations, mediaType,
availableWriters);
if (writer != null)
LogMessages.LOGGER.debugf("MessageBodyWriter: %s", writer.getClass().getName());
return writer;
}
public <T> MessageBodyWriter<T> getClientMessageBodyWriter(Class<T> type, Type genericType, Annotation[] annotations,
MediaType mediaType)
{
MediaTypeMap<SortedKey<MessageBodyWriter>> availableWriters = getClientMessageBodyWriters();
return resolveMessageBodyWriter(type, genericType, annotations, mediaType, availableWriters);
}
@Deprecated
private <T> MessageBodyWriter<T> resolveMessageBodyWriter(Class<T> type, Type genericType, Annotation[] annotations,
MediaType mediaType, MediaTypeMap<SortedKey<MessageBodyWriter>> availableWriters)
{
if (availableWriters == null) return null;
List<SortedKey<MessageBodyWriter>> writers = availableWriters.getPossible(mediaType, type);
for (SortedKey<MessageBodyWriter> writer : writers)
{
if (writer.getObj().isWriteable(type, genericType, annotations, mediaType))
{
LogMessages.LOGGER.debugf("MessageBodyWriter: %s", writer.getClass().getName());
return (MessageBodyWriter<T>) writer.getObj();
}
}
return null;
}
private <T> MessageBodyWriter<T> resolveMessageBodyWriter(Class<T> type, Type genericType,
Annotation[] annotations, MediaType mediaType, MediaTypeMap<SortedKey<MessageBodyWriter>> availableWriters,
RESTEasyTracingLogger tracingLogger)
{
if (availableWriters == null) return null;
List<SortedKey<MessageBodyWriter>> writers = availableWriters.getPossible(mediaType, type);
if (tracingLogger.isLogEnabled("MBW_FIND"))
{
tracingLogger.log("MBW_FIND", type.getName(),
(genericType instanceof Class ? ((Class) genericType).getName() : genericType), mediaType,
java.util.Arrays.toString(annotations));
}
MessageBodyWriter<T> result = null;
Iterator<SortedKey<MessageBodyWriter>> iterator = writers.iterator();
while (iterator.hasNext())
{
final SortedKey<MessageBodyWriter> writer = iterator.next();
if (writer.getObj().isWriteable(type, genericType, annotations, mediaType))
{
LogMessages.LOGGER.debugf("MessageBodyWriter: %s", writer.getClass().getName());
result = (MessageBodyWriter<T>) writer.getObj();
tracingLogger.log("MBW_SELECTED", result);
break;
}
tracingLogger.log("MBW_NOT_WRITEABLE", result);
}
if (tracingLogger.isLogEnabled("MBW_SKIPPED"))
{
while (iterator.hasNext())
{
final SortedKey<MessageBodyWriter> writer = iterator.next();
tracingLogger.log("MBW_SKIPPED", writer.getObj());
}
}
return result;
}
public <T> T createEndpoint(Application applicationConfig, Class<T> endpointType)
throws IllegalArgumentException, UnsupportedOperationException
{
if (applicationConfig == null)
throw new IllegalArgumentException(Messages.MESSAGES.applicationParamNull());
throw new UnsupportedOperationException();
}
public <T> ContextResolver<T> getContextResolver(Class<T> contextType, MediaType mediaType)
{
final List<ContextResolver> resolvers = getContextResolvers(contextType, mediaType);
if (resolvers == null)
return null;
if (resolvers.size() == 1)
return resolvers.get(0);
return new ContextResolver<T>()
{
public T getContext(Class type)
{
for (ContextResolver resolver : resolvers)
{
Object rtn = resolver.getContext(type);
if (rtn != null)
return (T) rtn;
}
return null;
}
};
}
public <T> T createProviderInstance(Class<? extends T> clazz)
{
return Utils.createProviderInstance(this, clazz);
}
public <T> T injectedInstance(Class<? extends T> clazz)
{
Constructor<?> constructor = PickConstructor.pickSingletonConstructor(clazz);
ConstructorInjector constructorInjector = getInjectorFactory().createConstructor(constructor, this);
Object obj = constructorInjector.construct(false);
PropertyInjector propertyInjector = getInjectorFactory().createPropertyInjector(clazz, this);
if (obj instanceof CompletionStage) {
CompletionStage<Object> stage = (CompletionStage<Object>)obj;
return (T)stage.thenCompose(target -> {
CompletionStage<Void> propertyStage = propertyInjector.inject(target, false);
if (propertyStage != null) {
return propertyStage
.thenApply(v -> target);
} else {
return CompletableFuture.completedFuture(target);
}
}).toCompletableFuture().getNow(null);
}
CompletionStage<Void> propertyStage = propertyInjector.inject(obj, false);
if (propertyStage == null) return (T)obj;
return (T) propertyStage.thenApply(v -> obj).toCompletableFuture().getNow(null);
}
public <T> T injectedInstance(Class<? extends T> clazz, HttpRequest request, HttpResponse response)
{
Constructor<?> constructor = PickConstructor.pickSingletonConstructor(clazz);
Object obj = null;
if (constructor == null)
{
throw new IllegalArgumentException(Messages.MESSAGES.unableToFindPublicConstructorForClass(clazz.getName()));
}
else
{
ConstructorInjector constructorInjector = getInjectorFactory().createConstructor(constructor, this);
obj = constructorInjector.construct(request, response, false);
if (obj instanceof CompletionStage) {
obj = ((CompletionStage<Object>)obj).toCompletableFuture().getNow(null);
}
}
PropertyInjector propertyInjector = getInjectorFactory().createPropertyInjector(clazz, this);
CompletionStage<Void> propertyStage = propertyInjector.inject(request, response, obj, false);
if (propertyStage != null) propertyStage.toCompletableFuture().getNow(null);
return (T) obj;
}
public Map<String, Object> getMutableProperties()
{
return properties;
}
@Override
public Map<String, Object> getProperties()
{
return Collections.unmodifiableMap(properties);
}
@Override
public Object getProperty(String name)
{
return properties.get(name);
}
public ResteasyProviderFactory setProperties(Map<String, Object> properties)
{
this.properties = new SnapshotMap<>(properties, false, lockSnapshots, false);
return this;
}
@Override
public ResteasyProviderFactory property(String name, Object value)
{
if (value == null)
properties.remove(name);
else
properties.put(name, value);
return this;
}
public Collection<Feature> getEnabledFeatures()
{
return Collections.unmodifiableSet(enabledFeatures);
}
@Override
public ResteasyProviderFactory register(Class<?> providerClass)
{
registerProvider(providerClass);
return this;
}
@Override
public ResteasyProviderFactory register(Object provider)
{
registerProviderInstance(provider);
return this;
}
@Override
public ResteasyProviderFactory register(Class<?> componentClass, int priority)
{
registerProvider(componentClass, priority, false, null);
return this;
}
@Override
public ResteasyProviderFactory register(Class<?> componentClass, Class<?>... contracts)
{
if (contracts == null || contracts.length == 0)
{
LogMessages.LOGGER.attemptingToRegisterEmptyContracts(componentClass.getName());
return this;
}
Map<Class<?>, Integer> cons = new HashMap<Class<?>, Integer>();
for (Class<?> contract : contracts)
{
if (!contract.isAssignableFrom(componentClass))
{
LogMessages.LOGGER.attemptingToRegisterUnassignableContract(componentClass.getName());
return this;
}
cons.put(contract, Priorities.USER);
}
registerProvider(componentClass, null, false, cons);
return this;
}
@Override
public ResteasyProviderFactory register(Object component, int priority)
{
registerProviderInstance(component, null, priority, false);
return this;
}
@Override
public ResteasyProviderFactory register(Object component, Class<?>... contracts)
{
if (contracts == null || contracts.length == 0)
{
LogMessages.LOGGER.attemptingToRegisterEmptyContracts(component.getClass().getName());
return this;
}
Map<Class<?>, Integer> cons = new HashMap<Class<?>, Integer>();
for (Class<?> contract : contracts)
{
if (!contract.isAssignableFrom(component.getClass()))
{
LogMessages.LOGGER.attemptingToRegisterUnassignableContract(component.getClass().getName());
return this;
}
cons.put(contract, Priorities.USER);
}
registerProviderInstance(component, cons, null, false);
return this;
}
@Override
public ResteasyProviderFactory register(Class<?> componentClass, Map<Class<?>, Integer> contracts)
{
for (Class<?> contract : contracts.keySet())
{
if (!contract.isAssignableFrom(componentClass))
{
LogMessages.LOGGER.attemptingToRegisterUnassignableContract(componentClass.getName());
return this;
}
}
registerProvider(componentClass, null, false, contracts);
return this;
}
@Override
public ResteasyProviderFactory register(Object component, Map<Class<?>, Integer> contracts)
{
for (Class<?> contract : contracts.keySet())
{
if (!contract.isAssignableFrom(component.getClass()))
{
LogMessages.LOGGER.attemptingToRegisterUnassignableContract(component.getClass().getName());
return this;
}
}
registerProviderInstance(component, contracts, null, false);
return this;
}
@Override
public Configuration getConfiguration()
{
return this;
}
@Override
public RuntimeType getRuntimeType()
{
return RuntimeType.SERVER;
}
@Override
public Collection<String> getPropertyNames()
{
return getProperties().keySet();
}
@Override
public boolean isEnabled(Feature feature)
{
return getEnabledFeatures().contains(feature);
}
@Override
public boolean isEnabled(Class<? extends Feature> featureClass)
{
Collection<Feature> enabled = getEnabledFeatures();
if (enabled == null)
return false;
for (Feature feature : enabled)
{
if (featureClass.equals(feature.getClass()))
{
return true;
}
}
return false;
}
@Override
public boolean isRegistered(Object component)
{
return getProviderInstances().contains(component);
}
@Override
public boolean isRegistered(Class<?> componentClass)
{
return getClassContracts().containsKey(componentClass);
}
@Override
public Map<Class<?>, Integer> getContracts(Class<?> componentClass)
{
Map<Class<?>, Integer> classIntegerMap = classContracts.get(componentClass);
if (classIntegerMap == null)
return Collections.emptyMap();
return classIntegerMap;
}
@Override
public Set<Class<?>> getClasses()
{
Set<Class<?>> providerClasses = getProviderClasses();
return (providerClasses == null || providerClasses.isEmpty())
? Collections.emptySet()
: Collections.unmodifiableSet(providerClasses);
}
@Override
public Set<Object> getInstances()
{
Set<Object> providerInstances = getProviderInstances();
return (providerInstances == null || providerInstances.isEmpty())
? Collections.emptySet()
: Collections.unmodifiableSet(providerInstances);
}
@Override
public Link.Builder createLinkBuilder()
{
return Utils.createLinkBuilder();
}
public <I extends RxInvoker> RxInvokerProvider<I> getRxInvokerProvider(Class<I> clazz)
{
for (Entry<Class<?>, Map<Class<?>, Integer>> entry : classContracts.entrySet())
{
if (entry.getValue().containsKey(RxInvokerProvider.class))
{
RxInvokerProvider<?> rip = (RxInvokerProvider<?>) createProviderInstance(entry.getKey());
if (rip.isProviderFor(clazz))
{
return (RxInvokerProvider<I>) rip;
}
}
}
return null;
}
public RxInvokerProvider<?> getRxInvokerProviderFromReactiveClass(Class<?> clazz)
{
return clientHelper.getRxInvokerProviderFromReactiveClass(clazz);
}
public boolean isReactive(Class<?> clazz)
{
return clientHelper.isReactive(clazz);
}
public void addResourceClassProcessor(Class<ResourceClassProcessor> processorClass, int priority)
{
ResourceClassProcessor processor = createProviderInstance(processorClass);
addResourceClassProcessor(processor, priority);
}
private void addResourceClassProcessor(ResourceClassProcessor processor, int priority)
{
resourceBuilder.registerResourceClassProcessor(processor, priority);
}
public ResourceBuilder getResourceBuilder()
{
return resourceBuilder;
}
public <T> T getContextData(Class<T> type)
{
return ResteasyContext.getContextData(type);
}
public void initializeClientProviders(ResteasyProviderFactory factory)
{
clientHelper.initializeClientProviders(factory);
}
public void injectProperties(Object obj)
{
Utils.injectProperties(this, obj);
}
public void injectProperties(Object obj, HttpRequest request, HttpResponse response)
{
Utils.injectProperties(this, obj, request, response);
}
public StatisticsController getStatisticsController() {
return statisticsController;
}
@Override
protected boolean isOnServer() {
return ResteasyContext.searchContextData(Dispatcher.class) != null;
}
}