package org.jboss.resteasy.spi.old; import java.lang.reflect.Type; import java.util.List; import java.util.Map; import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.CopyOnWriteArrayList; import javax.ws.rs.Priorities; import javax.ws.rs.client.ClientRequestFilter; import javax.ws.rs.ext.ContextResolver; 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.interception.InterceptorRegistry; import org.jboss.resteasy.core.interception.LegacyPrecedence; 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.JaxrsInterceptorRegistry; import org.jboss.resteasy.core.interception.ReaderInterceptorRegistry; import org.jboss.resteasy.core.interception.WriterInterceptorRegistry; import org.jboss.resteasy.resteasy_jaxrs.i18n.Messages; 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.util.Types; /** * @author <a href="mailto:bill@burkecentral.com">Bill Burke</a> * @version $Revision: 1 $ */ @SuppressWarnings("unchecked") public class ResteasyProviderFactory extends org.jboss.resteasy.spi.ResteasyProviderFactory { protected Map<Class<?>, ClientExceptionMapper> clientExceptionMappers; protected LegacyPrecedence precedence; protected InterceptorRegistry<ClientExecutionInterceptor> clientExecutionInterceptorRegistry; protected List<ClientErrorInterceptor> clientErrorInterceptors; public ResteasyProviderFactory() { super(); } /** * Copies a specific component registry when a new * provider is added. Otherwise delegates to the parent. * * @param parent */ public ResteasyProviderFactory(ResteasyProviderFactory parent) { super(parent, false); } /** * If local is true, copies components needed by client configuration, * so that parent is not referenced. * @param parent * @param local */ public ResteasyProviderFactory(ResteasyProviderFactory parent, boolean local) { super(parent, local); } protected void initialize() { super.initialize(); clientExceptionMappers = new ConcurrentHashMap<Class<?>, ClientExceptionMapper>(); clientExecutionInterceptorRegistry = new InterceptorRegistry<ClientExecutionInterceptor>(ClientExecutionInterceptor.class, this); clientErrorInterceptors = new CopyOnWriteArrayList<ClientErrorInterceptor>(); registerDefaultInterceptorPrecedences(); } protected void initializeRegistriesAndFilters() { precedence = new LegacyPrecedence(); serverReaderInterceptorRegistry = new ReaderInterceptorRegistry(this, precedence); serverWriterInterceptorRegistry = new WriterInterceptorRegistry(this, precedence); containerRequestFilterRegistry = new ContainerRequestFilterRegistry(this, precedence); containerResponseFilterRegistry = new ContainerResponseFilterRegistry(this, precedence); clientRequestFilters = new JaxrsInterceptorRegistry<ClientRequestFilter>(this, ClientRequestFilter.class); clientResponseFilters = new ClientResponseFilterRegistry(this); clientReaderInterceptorRegistry = new ReaderInterceptorRegistry(this, precedence); clientWriterInterceptorRegistry = new WriterInterceptorRegistry(this, precedence); } protected Map<Class<?>, ClientExceptionMapper> getClientExceptionMappers() { if (clientExceptionMappers == null && parent != null && parent instanceof ResteasyProviderFactory) return ((ResteasyProviderFactory)parent).getClientExceptionMappers(); return clientExceptionMappers; } protected LegacyPrecedence getPrecedence() { if (precedence == null && parent != null) return ((ResteasyProviderFactory)parent).getPrecedence(); return precedence; } 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()); } private boolean isParentSameType() { return parent != null && parent instanceof ResteasyProviderFactory; } /** * Append interceptor predence * * @param precedence */ public void appendInterceptorPrecedence(String precedence) { if (this.precedence == null) { this.precedence = ((ResteasyProviderFactory)parent).getPrecedence().clone(); } if (clientExecutionInterceptorRegistry == null) { clientExecutionInterceptorRegistry = ((ResteasyProviderFactory)parent).getClientExecutionInterceptorRegistry().cloneTo(this); } this.precedence.appendPrecedence(precedence); clientExecutionInterceptorRegistry.appendPrecedence(precedence); } /** * @param after put newPrecedence after this * @param newPrecedence */ public void insertInterceptorPrecedenceAfter(String after, String newPrecedence) { if (this.precedence == null) { this.precedence = ((ResteasyProviderFactory)parent).getPrecedence().clone(); } if (clientExecutionInterceptorRegistry == null) { clientExecutionInterceptorRegistry = ((ResteasyProviderFactory)parent).getClientExecutionInterceptorRegistry().cloneTo(this); } this.precedence.insertPrecedenceAfter(after, newPrecedence); getClientExecutionInterceptorRegistry().insertPrecedenceAfter(after, newPrecedence); } /** * @param before put newPrecedence before this * @param newPrecedence */ public void insertInterceptorPrecedenceBefore(String before, String newPrecedence) { if (this.precedence == null) { this.precedence = ((ResteasyProviderFactory)parent).getPrecedence().clone(); } if (clientExecutionInterceptorRegistry == null) { clientExecutionInterceptorRegistry = ((ResteasyProviderFactory)parent).getClientExecutionInterceptorRegistry().cloneTo(this); } this.precedence.insertPrecedenceBefore(before, newPrecedence); getClientExecutionInterceptorRegistry().insertPrecedenceBefore(before, newPrecedence); } public InterceptorRegistry<ClientExecutionInterceptor> getClientExecutionInterceptorRegistry() { if (clientExecutionInterceptorRegistry == null && parent != null) return ((ResteasyProviderFactory)parent).getClientExecutionInterceptorRegistry(); return clientExecutionInterceptorRegistry; } @Override public ReaderInterceptorRegistry getServerReaderInterceptorRegistry() { if (serverReaderInterceptorRegistry == null && parent != null) return ((ResteasyProviderFactory)parent).getServerReaderInterceptorRegistry(); return (ReaderInterceptorRegistry)serverReaderInterceptorRegistry; } @Override public WriterInterceptorRegistry getServerWriterInterceptorRegistry() { if (serverWriterInterceptorRegistry == null && parent != null) return ((ResteasyProviderFactory)parent).getServerWriterInterceptorRegistry(); return (WriterInterceptorRegistry)serverWriterInterceptorRegistry; } @Override public ContainerRequestFilterRegistry getContainerRequestFilterRegistry() { if (containerRequestFilterRegistry == null && parent != null) return ((ResteasyProviderFactory)parent).getContainerRequestFilterRegistry(); return (ContainerRequestFilterRegistry)containerRequestFilterRegistry; } @Override public ContainerResponseFilterRegistry getContainerResponseFilterRegistry() { if (containerResponseFilterRegistry == null && parent != null) return ((ResteasyProviderFactory)parent).getContainerResponseFilterRegistry(); return (ContainerResponseFilterRegistry)containerResponseFilterRegistry; } @Override public ReaderInterceptorRegistry getClientReaderInterceptorRegistry() { if (clientReaderInterceptorRegistry == null && parent != null) return ((ResteasyProviderFactory)parent).getClientReaderInterceptorRegistry(); return (ReaderInterceptorRegistry)clientReaderInterceptorRegistry; } @Override public WriterInterceptorRegistry getClientWriterInterceptorRegistry() { if (clientWriterInterceptorRegistry == null && parent != null) return ((ResteasyProviderFactory)parent).getClientWriterInterceptorRegistry(); return (WriterInterceptorRegistry)clientWriterInterceptorRegistry; } @Override public JaxrsInterceptorRegistry<ClientRequestFilter> getClientRequestFilters() { if (clientRequestFilters == null && parent != null) return ((ResteasyProviderFactory)parent).getClientRequestFilters(); return (JaxrsInterceptorRegistry<ClientRequestFilter>)clientRequestFilters; } @Override public ClientResponseFilterRegistry getClientResponseFilters() { if (clientResponseFilters == null && parent != null) return ((ResteasyProviderFactory)parent).getClientResponseFilters(); return (ClientResponseFilterRegistry)clientResponseFilters; } 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<Class<?>, ClientExceptionMapper>(); clientExceptionMappers.putAll(((ResteasyProviderFactory)parent).getClientExceptionMappers()); } clientExceptionMappers.put(exceptionClass, provider); } /** * Add a {@link ClientErrorInterceptor} to this provider factory instance. * Duplicate handlers are ignored. (For Client Proxy API only) */ public void addClientErrorInterceptor(ClientErrorInterceptor handler) { if (clientErrorInterceptors == null) { clientErrorInterceptors = new CopyOnWriteArrayList<ClientErrorInterceptor>(((ResteasyProviderFactory)parent).getClientErrorInterceptors()); } if (!clientErrorInterceptors.contains(handler)) { clientErrorInterceptors.add(handler); } } /** * Return the list of currently registered {@link ClientErrorInterceptor} instances. */ public List<ClientErrorInterceptor> getClientErrorInterceptors() { if (clientErrorInterceptors == null && parent != null) return ((ResteasyProviderFactory)parent).getClientErrorInterceptors(); return clientErrorInterceptors; } protected void addContextResolver(Class<? extends ContextResolver> resolver, boolean builtin) { ContextResolver writer = createProviderInstance(resolver); addContextResolver(writer, resolver, builtin); } @Override protected void processProviderContracts(Class provider, Integer priorityOverride, boolean isBuiltin, Map<Class<?>, Integer> contracts, Map<Class<?>, Integer> newContracts) { super.processProviderContracts(provider, priorityOverride, isBuiltin, contracts, newContracts); 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, ClientExecutionInterceptor.class, contracts)) { if (clientExecutionInterceptorRegistry == null) { clientExecutionInterceptorRegistry = ((ResteasyProviderFactory)parent).getClientExecutionInterceptorRegistry().cloneTo(this); } clientExecutionInterceptorRegistry.register(provider); newContracts.put(ClientExecutionInterceptor.class, 0); } if (isA(provider, PreProcessInterceptor.class, contracts)) { if (containerRequestFilterRegistry == null) { containerRequestFilterRegistry = ((ResteasyProviderFactory)parent).getContainerRequestFilterRegistry().clone(this); } ((ContainerRequestFilterRegistry)containerRequestFilterRegistry).registerLegacy(provider); newContracts.put(PreProcessInterceptor.class, 0); } if (isA(provider, PostProcessInterceptor.class, contracts)) { if (containerResponseFilterRegistry == null) { containerResponseFilterRegistry = ((ResteasyProviderFactory)parent).getContainerResponseFilterRegistry().clone(this); } ((ContainerResponseFilterRegistry)containerResponseFilterRegistry).registerLegacy(provider); newContracts.put(PostProcessInterceptor.class, 0); } if (isA(provider, MessageBodyWriterInterceptor.class, contracts)) { if (provider.isAnnotationPresent(ServerInterceptor.class)) { if (serverWriterInterceptorRegistry == null) { serverWriterInterceptorRegistry = ((ResteasyProviderFactory)parent).getServerWriterInterceptorRegistry().clone(this); } ((WriterInterceptorRegistry)serverWriterInterceptorRegistry).registerLegacy(provider); } if (provider.isAnnotationPresent(ClientInterceptor.class)) { if (clientWriterInterceptorRegistry == null) { clientWriterInterceptorRegistry = ((ResteasyProviderFactory)parent).getClientWriterInterceptorRegistry().clone(this); } ((WriterInterceptorRegistry)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 = ((ResteasyProviderFactory)parent).getServerReaderInterceptorRegistry().clone(this); } ((ReaderInterceptorRegistry)serverReaderInterceptorRegistry).registerLegacy(provider); } if (provider.isAnnotationPresent(ClientInterceptor.class)) { if (clientReaderInterceptorRegistry == null) { clientReaderInterceptorRegistry = ((ResteasyProviderFactory)parent).getClientReaderInterceptorRegistry().clone(this); } ((ReaderInterceptorRegistry)clientReaderInterceptorRegistry).registerLegacy(provider); } if (!provider.isAnnotationPresent(ServerInterceptor.class) && !provider.isAnnotationPresent(ClientInterceptor.class)) { throw new RuntimeException(Messages.MESSAGES.interceptorClassMustBeAnnotated()); } newContracts.put(MessageBodyReaderInterceptor.class, 0); } } @Override protected void processProviderInstanceContracts(Object provider, Map<Class<?>, Integer> contracts, Integer priorityOverride, boolean builtIn, Map<Class<?>, Integer> newContracts) { super.processProviderInstanceContracts(provider, contracts, priorityOverride, builtIn, newContracts); 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, ClientExecutionInterceptor.class, contracts)) { if (clientExecutionInterceptorRegistry == null) { clientExecutionInterceptorRegistry = ((ResteasyProviderFactory)parent).getClientExecutionInterceptorRegistry().cloneTo(this); } clientExecutionInterceptorRegistry.register((ClientExecutionInterceptor) provider); newContracts.put(ClientExecutionInterceptor.class, 0); } if (isA(provider, PreProcessInterceptor.class, contracts)) { if (containerRequestFilterRegistry == null) { containerRequestFilterRegistry = ((ResteasyProviderFactory)parent).getContainerRequestFilterRegistry().clone(this); } ((ContainerRequestFilterRegistry)containerRequestFilterRegistry).registerLegacy((PreProcessInterceptor) provider); newContracts.put(PreProcessInterceptor.class, 0); } if (isA(provider, PostProcessInterceptor.class, contracts)) { if (containerResponseFilterRegistry == null) { containerResponseFilterRegistry = ((ResteasyProviderFactory)parent).getContainerResponseFilterRegistry().clone(this); } ((ContainerResponseFilterRegistry)containerResponseFilterRegistry).registerLegacy((PostProcessInterceptor) provider); newContracts.put(PostProcessInterceptor.class, 0); } if (isA(provider, MessageBodyWriterInterceptor.class, contracts)) { if (provider.getClass().isAnnotationPresent(ServerInterceptor.class)) { if (serverWriterInterceptorRegistry == null) { serverWriterInterceptorRegistry = ((ResteasyProviderFactory)parent).getServerWriterInterceptorRegistry().clone(this); } ((WriterInterceptorRegistry)serverWriterInterceptorRegistry).registerLegacy((MessageBodyWriterInterceptor) provider); } if (provider.getClass().isAnnotationPresent(ClientInterceptor.class)) { if (clientWriterInterceptorRegistry == null) { clientWriterInterceptorRegistry = ((ResteasyProviderFactory)parent).getClientWriterInterceptorRegistry().clone(this); } ((WriterInterceptorRegistry)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 = ((ResteasyProviderFactory)parent).getServerReaderInterceptorRegistry().clone(this); } ((ReaderInterceptorRegistry)serverReaderInterceptorRegistry).registerLegacy((MessageBodyReaderInterceptor) provider); } if (provider.getClass().isAnnotationPresent(ClientInterceptor.class)) { if (clientReaderInterceptorRegistry == null) { clientReaderInterceptorRegistry = ((ResteasyProviderFactory)parent).getClientReaderInterceptorRegistry().clone(this); } ((ReaderInterceptorRegistry)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); } } public <T extends Throwable> ClientExceptionMapper<T> getClientExceptionMapper(Class<T> type) { return getClientExceptionMappers().get(type); } }