package org.jboss.resteasy.core.providerfactory;
import org.jboss.resteasy.core.MediaTypeMap;
import org.jboss.resteasy.core.interception.jaxrs.ReaderInterceptorRegistryImpl;
import org.jboss.resteasy.core.interception.jaxrs.WriterInterceptorRegistryImpl;
import org.jboss.resteasy.resteasy_jaxrs.i18n.Messages;
import org.jboss.resteasy.spi.interception.JaxrsInterceptorRegistry;
import javax.ws.rs.Consumes;
import javax.ws.rs.Produces;
import javax.ws.rs.container.DynamicFeature;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.ext.MessageBodyReader;
import javax.ws.rs.ext.MessageBodyWriter;
import javax.ws.rs.ext.ReaderInterceptor;
import javax.ws.rs.ext.WriterInterceptor;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;
@SuppressWarnings({"rawtypes", "unchecked"})
public class CommonProviders {
protected ResteasyProviderFactoryImpl rpf;
protected boolean lockSnapshots;
protected boolean attachedMessageBodyReaders;
protected volatile MediaTypeMap<SortedKey<MessageBodyReader>> messageBodyReaders;
protected boolean attachedMessageBodyWriters;
protected volatile MediaTypeMap<SortedKey<MessageBodyWriter>> messageBodyWriters;
protected boolean attachedReaderInterceptors;
protected volatile JaxrsInterceptorRegistry<ReaderInterceptor> readerInterceptorRegistry;
protected boolean attachedWriterInterceptors;
protected volatile JaxrsInterceptorRegistry<WriterInterceptor> writerInterceptorRegistry;
protected boolean attachedFeatures;
protected volatile Set<DynamicFeature> dynamicFeatures;
CommonProviders() {
}
public CommonProviders(final ResteasyProviderFactoryImpl rpf)
{
this.rpf = rpf;
}
public CommonProviders(final ResteasyProviderFactoryImpl rpf, final CommonProviders parent)
{
this(rpf);
this.lockSnapshots = true;
if (parent.messageBodyReaders != null) {
this.messageBodyReaders = parent.messageBodyReaders;
attachedMessageBodyReaders = true;
}
if (parent.messageBodyWriters != null) {
this.messageBodyWriters = parent.messageBodyWriters;
attachedMessageBodyWriters = true;
}
if (parent.readerInterceptorRegistry != null) {
this.readerInterceptorRegistry = parent.readerInterceptorRegistry;
attachedReaderInterceptors = true;
}
if (parent.writerInterceptorRegistry != null) {
this.writerInterceptorRegistry = parent.writerInterceptorRegistry;
attachedWriterInterceptors = true;
}
if (parent.dynamicFeatures != null) {
this.dynamicFeatures = parent.dynamicFeatures;
attachedFeatures = true;
}
}
protected void processProviderContracts(Class provider, Integer priorityOverride, boolean isBuiltin,
Map<Class<?>, Integer> contracts, Map<Class<?>, Integer> newContracts)
{
if (Utils.isA(provider, MessageBodyReader.class, contracts))
{
try
{
int priority = Utils.getPriority(priorityOverride, contracts, MessageBodyReader.class, provider);
addMessageBodyReader(Utils.createProviderInstance(rpf, (Class<? extends MessageBodyReader>) provider), provider,
priority, isBuiltin);
newContracts.put(MessageBodyReader.class, priority);
}
catch (Exception e)
{
throw new RuntimeException(Messages.MESSAGES.unableToInstantiateMessageBodyReader(), e);
}
}
if (Utils.isA(provider, MessageBodyWriter.class, contracts))
{
try
{
int priority = Utils.getPriority(priorityOverride, contracts, MessageBodyWriter.class, provider);
addMessageBodyWriter(Utils.createProviderInstance(rpf, (Class<? extends MessageBodyWriter>) provider), provider,
priority, isBuiltin);
newContracts.put(MessageBodyWriter.class, priority);
}
catch (Exception e)
{
throw new RuntimeException(Messages.MESSAGES.unableToInstantiateMessageBodyWriter(), e);
}
}
if (Utils.isA(provider, ReaderInterceptor.class, contracts))
{
int priority = Utils.getPriority(priorityOverride, contracts, ReaderInterceptor.class, provider);
addReaderInterceptor(provider, priority);
newContracts.put(ReaderInterceptor.class, priority);
}
if (Utils.isA(provider, WriterInterceptor.class, contracts))
{
int priority = Utils.getPriority(priorityOverride, contracts, WriterInterceptor.class, provider);
addWriterInterceptor(provider, priority);
newContracts.put(WriterInterceptor.class, priority);
}
if (Utils.isA(provider, DynamicFeature.class, contracts))
{
int priority = Utils.getPriority(priorityOverride, contracts, DynamicFeature.class, provider);
addDynamicFeature(provider);
newContracts.put(DynamicFeature.class, priority);
}
}
protected void processProviderInstanceContracts(Object provider, Map<Class<?>, Integer> contracts,
Integer priorityOverride, boolean builtIn, Map<Class<?>, Integer> newContracts)
{
if (Utils.isA(provider, MessageBodyReader.class, contracts))
{
try
{
int priority = Utils.getPriority(priorityOverride, contracts, MessageBodyReader.class, provider.getClass());
addMessageBodyReader((MessageBodyReader) provider, provider.getClass(), priority, builtIn);
newContracts.put(MessageBodyReader.class, priority);
}
catch (Exception e)
{
throw new RuntimeException(Messages.MESSAGES.unableToInstantiateMessageBodyReader(), e);
}
}
if (Utils.isA(provider, MessageBodyWriter.class, contracts))
{
try
{
int priority = Utils.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 (Utils.isA(provider, ReaderInterceptor.class, contracts))
{
int priority = Utils.getPriority(priorityOverride, contracts, ReaderInterceptor.class, provider.getClass());
JaxrsInterceptorRegistry<ReaderInterceptor> registry = getReaderInterceptorRegistryForWrite();
registry.registerSingleton((ReaderInterceptor) provider, priority);
attachedReaderInterceptors = false;
readerInterceptorRegistry = registry;
newContracts.put(ReaderInterceptor.class, priority);
}
if (Utils.isA(provider, WriterInterceptor.class, contracts))
{
int priority = Utils.getPriority(priorityOverride, contracts, WriterInterceptor.class, provider.getClass());
JaxrsInterceptorRegistry<WriterInterceptor> registry = getWriterInterceptorRegistryForWrite();
registry.registerSingleton((WriterInterceptor) provider, priority);
attachedWriterInterceptors = false;
writerInterceptorRegistry = registry;
newContracts.put(WriterInterceptor.class, priority);
}
if (Utils.isA(provider, DynamicFeature.class, contracts))
{
int priority = Utils.getPriority(priorityOverride, contracts, DynamicFeature.class, provider.getClass());
Set<DynamicFeature> registry = getDynamicFeaturesForWrite();
registry.add((DynamicFeature) provider);
attachedFeatures = false;
dynamicFeatures = registry;
newContracts.put(DynamicFeature.class, priority);
}
}
protected void addMessageBodyReader(MessageBodyReader provider, Class<?> providerClass, int priority,
boolean isBuiltin)
{
SortedKey<MessageBodyReader> key = new SortedKey<MessageBodyReader>(MessageBodyReader.class, provider,
providerClass, priority, isBuiltin);
Utils.injectProperties(rpf, providerClass, provider);
Consumes consumeMime = provider.getClass().getAnnotation(Consumes.class);
MediaTypeMap<SortedKey<MessageBodyReader>> registry = getMessageBodyReadersForWrite();
if (consumeMime != null)
{
for (String consume : consumeMime.value())
{
registry.add(consume, key);
}
}
else
{
registry.addWildcard(key);
}
attachedMessageBodyReaders = false;
messageBodyReaders = registry;
}
protected void addMessageBodyWriter(MessageBodyWriter provider, Class<?> providerClass, int priority,
boolean isBuiltin)
{
Utils.injectProperties(rpf, providerClass, provider);
Produces consumeMime = provider.getClass().getAnnotation(Produces.class);
SortedKey<MessageBodyWriter> key = new SortedKey<MessageBodyWriter>(MessageBodyWriter.class, provider,
providerClass, priority, isBuiltin);
MediaTypeMap<SortedKey<MessageBodyWriter>> registry = getMessageBodyWritersForWrite();
if (consumeMime != null)
{
for (String consume : consumeMime.value())
{
registry.add(consume, key);
}
}
else
{
registry.add(MediaType.WILDCARD, key);
}
attachedMessageBodyWriters = false;
messageBodyWriters = registry;
}
protected MediaTypeMap<SortedKey<MessageBodyReader>> getMessageBodyReadersForWrite() {
if (messageBodyReaders == null) {
return new MediaTypeMap<>();
} else if (lockSnapshots || attachedMessageBodyReaders) {
return new MediaTypeMap<>(messageBodyReaders);
}
return messageBodyReaders;
}
protected MediaTypeMap<SortedKey<MessageBodyWriter>> getMessageBodyWritersForWrite() {
if (messageBodyWriters == null) {
return new MediaTypeMap<>();
} else if (lockSnapshots || attachedMessageBodyWriters) {
return new MediaTypeMap<>(messageBodyWriters);
}
return messageBodyWriters;
}
protected JaxrsInterceptorRegistry<ReaderInterceptor> getReaderInterceptorRegistryForWrite() {
if (readerInterceptorRegistry == null) {
return new ReaderInterceptorRegistryImpl(rpf);
} else if (lockSnapshots || attachedReaderInterceptors) {
return readerInterceptorRegistry.clone(rpf);
}
return readerInterceptorRegistry;
}
protected JaxrsInterceptorRegistry<WriterInterceptor> getWriterInterceptorRegistryForWrite() {
if (writerInterceptorRegistry == null) {
return new WriterInterceptorRegistryImpl(rpf);
} else if (lockSnapshots || attachedWriterInterceptors) {
return writerInterceptorRegistry.clone(rpf);
}
return writerInterceptorRegistry;
}
protected Set<DynamicFeature> getDynamicFeaturesForWrite() {
if (dynamicFeatures == null) {
return new HashSet<>();
} else if (lockSnapshots || attachedFeatures) {
return new HashSet<>(dynamicFeatures);
}
return dynamicFeatures;
}
public MediaTypeMap<SortedKey<MessageBodyReader>> getMessageBodyReaders() {
return messageBodyReaders;
}
public MediaTypeMap<SortedKey<MessageBodyWriter>> getMessageBodyWriters() {
return messageBodyWriters;
}
public JaxrsInterceptorRegistry<ReaderInterceptor> getReaderInterceptorRegistry() {
return readerInterceptorRegistry;
}
public JaxrsInterceptorRegistry<WriterInterceptor> getWriterInterceptorRegistry() {
return writerInterceptorRegistry;
}
public Set<DynamicFeature> getDynamicFeatures() {
return dynamicFeatures;
}
public void lockSnapshots() {
this.lockSnapshots = true;
if (messageBodyReaders != null) {
messageBodyReaders.lockSnapshots();
}
if (messageBodyWriters != null) {
messageBodyWriters.lockSnapshots();
}
}
public void addDynamicFeature(Class provider) {
Set<DynamicFeature> registry = getDynamicFeaturesForWrite();
registry.add((DynamicFeature) rpf.injectedInstance(provider));
attachedFeatures = false;
dynamicFeatures = registry;
}
public void addWriterInterceptor(Class provider, int priority) {
JaxrsInterceptorRegistry<WriterInterceptor> registry = getWriterInterceptorRegistryForWrite();
registry.registerClass(provider, priority);
attachedWriterInterceptors = false;
writerInterceptorRegistry = registry;
}
public void addReaderInterceptor(Class provider, int priority) {
JaxrsInterceptorRegistry<ReaderInterceptor> registry = getReaderInterceptorRegistryForWrite();
registry.registerClass(provider, priority);
attachedReaderInterceptors = false;
readerInterceptorRegistry = registry;
}
public void addWildcardMBR(SortedKey<MessageBodyReader> mbr) {
MediaTypeMap<SortedKey<MessageBodyReader>> registry = getMessageBodyReadersForWrite();
registry.addWildcard(mbr);
attachedMessageBodyReaders = false;
messageBodyReaders = registry;
}
public void addSubtypeWildMBR(MediaType mediaType, SortedKey<MessageBodyReader> mbr) {
MediaTypeMap<SortedKey<MessageBodyReader>> registry = getMessageBodyReadersForWrite();
registry.addWildSubtype(mediaType, mbr);
attachedMessageBodyReaders = false;
messageBodyReaders = registry;
}
public void addRegularMBR(MediaType mediaType, SortedKey<MessageBodyReader> mbr) {
MediaTypeMap<SortedKey<MessageBodyReader>> registry = getMessageBodyReadersForWrite();
registry.addRegular(mediaType, mbr);
attachedMessageBodyReaders = false;
messageBodyReaders = registry;
}
public void addCompositeWildcardMBR(MediaType mediaType, SortedKey<MessageBodyReader> mbr, String baseSubtype) {
MediaTypeMap<SortedKey<MessageBodyReader>> registry = getMessageBodyReadersForWrite();
registry.addCompositeWild(mediaType, mbr, baseSubtype);
attachedMessageBodyReaders = false;
messageBodyReaders = registry;
}
public void addWildcardCompositeMBR(MediaType mediaType, SortedKey<MessageBodyReader> mbr, String baseSubtype) {
MediaTypeMap<SortedKey<MessageBodyReader>> registry = getMessageBodyReadersForWrite();
registry.addWildComposite(mediaType, mbr, baseSubtype);
attachedMessageBodyReaders = false;
messageBodyReaders = registry;
}
public void addWildcardMBW(SortedKey<MessageBodyWriter> mbw) {
MediaTypeMap<SortedKey<MessageBodyWriter>> registry = getMessageBodyWritersForWrite();
registry.addWildcard(mbw);
attachedMessageBodyWriters = false;
messageBodyWriters = registry;
}
public void addRegularMBW(MediaType mediaType, SortedKey<MessageBodyWriter> mbw) {
MediaTypeMap<SortedKey<MessageBodyWriter>> registry = getMessageBodyWritersForWrite();
registry.addRegular(mediaType, mbw);
attachedMessageBodyWriters = false;
messageBodyWriters = registry;
}
public void addSubtypeWildMBW(MediaType mediaType, SortedKey<MessageBodyWriter> mbw) {
MediaTypeMap<SortedKey<MessageBodyWriter>> registry = getMessageBodyWritersForWrite();
registry.addWildSubtype(mediaType, mbw);
attachedMessageBodyWriters = false;
messageBodyWriters = registry;
}
public void addCompositeWildcardMBW(MediaType mediaType, SortedKey<MessageBodyWriter> mbw, String baseSubtype) {
MediaTypeMap<SortedKey<MessageBodyWriter>> registry = getMessageBodyWritersForWrite();
registry.addCompositeWild(mediaType, mbw, baseSubtype);
attachedMessageBodyWriters = false;
messageBodyWriters = registry;
}
public void addWildcardCompositeMBW(MediaType mediaType, SortedKey<MessageBodyWriter> mbw, String baseSubtype) {
MediaTypeMap<SortedKey<MessageBodyWriter>> registry = getMessageBodyWritersForWrite();
registry.addWildComposite(mediaType, mbw, baseSubtype);
attachedMessageBodyWriters = false;
messageBodyWriters = registry;
}
}