org.jboss.resteasy.reactive.server.jaxrs.FeatureContextImpl Maven / Gradle / Ivy
package org.jboss.resteasy.reactive.server.jaxrs;
import java.lang.annotation.Annotation;
import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;
import java.util.function.Function;
import jakarta.annotation.Priority;
import jakarta.ws.rs.NameBinding;
import jakarta.ws.rs.container.ContainerRequestFilter;
import jakarta.ws.rs.container.ContainerResponseFilter;
import jakarta.ws.rs.container.PreMatching;
import jakarta.ws.rs.core.Configuration;
import jakarta.ws.rs.core.FeatureContext;
import jakarta.ws.rs.ext.ExceptionMapper;
import jakarta.ws.rs.ext.ReaderInterceptor;
import jakarta.ws.rs.ext.WriterInterceptor;
import org.jboss.resteasy.reactive.common.core.UnmanagedBeanFactory;
import org.jboss.resteasy.reactive.common.jaxrs.ConfigurationImpl;
import org.jboss.resteasy.reactive.common.model.InterceptorContainer;
import org.jboss.resteasy.reactive.common.model.PreMatchInterceptorContainer;
import org.jboss.resteasy.reactive.common.model.ResourceExceptionMapper;
import org.jboss.resteasy.reactive.common.model.ResourceInterceptor;
import org.jboss.resteasy.reactive.common.model.ResourceInterceptors;
import org.jboss.resteasy.reactive.common.model.SettableResourceInterceptor;
import org.jboss.resteasy.reactive.server.core.RuntimeExceptionMapper;
import org.jboss.resteasy.reactive.spi.BeanFactory;
public class FeatureContextImpl implements FeatureContext {
protected final ResourceInterceptors interceptors;
private final RuntimeExceptionMapper exceptionMapping;
private final Function, BeanFactory>> beanFactoryCreator;
private final ConfigurationImpl configuration;
private boolean filtersNeedSorting = false;
public FeatureContextImpl(ResourceInterceptors interceptors, RuntimeExceptionMapper exceptionMapping,
ConfigurationImpl configuration, Function, BeanFactory>> beanFactoryCreator) {
this.interceptors = interceptors;
this.exceptionMapping = exceptionMapping;
this.configuration = configuration;
this.beanFactoryCreator = beanFactoryCreator;
}
@Override
public Configuration getConfiguration() {
return configuration;
}
@Override
public FeatureContext property(String name, Object value) {
configuration.property(name, value);
return this;
}
@Override
public FeatureContext register(Class> componentClass) {
doRegister(componentClass, null, null);
return this;
}
@Override
public FeatureContext register(Class> componentClass, int priority) {
doRegister(componentClass, null, priority);
return this;
}
@Override
public FeatureContext register(Class> componentClass, Class>... contracts) {
throw new UnsupportedOperationException();
}
@Override
public FeatureContext register(Class> componentClass, Map, Integer> contracts) {
throw new UnsupportedOperationException();
}
@Override
public FeatureContext register(Object component) {
doRegister(component.getClass(), new UnmanagedBeanFactory<>(component), null);
return this;
}
@Override
public FeatureContext register(Object component, int priority) {
doRegister(component.getClass(), new UnmanagedBeanFactory<>(component), priority);
return this;
}
@Override
public FeatureContext register(Object component, Class>... contracts) {
throw new UnsupportedOperationException();
}
@Override
public FeatureContext register(Object component, Map, Integer> contracts) {
throw new UnsupportedOperationException();
}
@SuppressWarnings({ "rawtypes", "unchecked" })
private void doRegister(Class> componentClass, BeanFactory> beanFactory, Integer priority) {
if (!isAllowed(componentClass)) {
//TODO: log a warning
return;
}
if (ExceptionMapper.class.isAssignableFrom(componentClass)) {
Type[] genericInterfaces = componentClass.getGenericInterfaces();
for (Type type : genericInterfaces) {
// TODO: use proper generic handling
if (type instanceof ParameterizedType) {
ParameterizedType parameterizedType = (ParameterizedType) type;
if (parameterizedType.getRawType().equals(ExceptionMapper.class)) {
Type exceptionType = parameterizedType.getActualTypeArguments()[0];
if (exceptionType instanceof Class) {
Class exceptionClass = (Class) exceptionType;
ResourceExceptionMapper resourceExceptionMapper = new ResourceExceptionMapper();
resourceExceptionMapper.setFactory(getFactory(componentClass, beanFactory));
exceptionMapping.addExceptionMapper(exceptionClass, resourceExceptionMapper);
break;
}
}
}
}
}
if (isFilter(componentClass)) {
registerFilters(componentClass, beanFactory, priority);
filtersNeedSorting = true;
}
if (isInterceptor(componentClass)) {
registerInterceptors(componentClass, beanFactory, priority);
filtersNeedSorting = true;
}
//TODO: log warning if nothing was done
}
protected boolean isFilter(Class> componentClass) {
return ContainerRequestFilter.class.isAssignableFrom(componentClass)
|| ContainerResponseFilter.class.isAssignableFrom(componentClass);
}
protected void registerFilters(Class> componentClass, BeanFactory> beanFactory, Integer priority) {
boolean isRequest = ContainerRequestFilter.class.isAssignableFrom(componentClass);
boolean isResponse = ContainerResponseFilter.class.isAssignableFrom(componentClass);
if (isRequest) {
register(componentClass, beanFactory, priority, interceptors.getContainerRequestFilters());
}
if (isResponse) {
register(componentClass, beanFactory, priority, interceptors.getContainerResponseFilters());
}
}
protected boolean isInterceptor(Class> componentClass) {
return ReaderInterceptor.class.isAssignableFrom(componentClass)
|| WriterInterceptor.class.isAssignableFrom(componentClass);
}
protected void registerInterceptors(Class> componentClass, BeanFactory> beanFactory, Integer priority) {
boolean isReader = ReaderInterceptor.class.isAssignableFrom(componentClass);
boolean isWriter = WriterInterceptor.class.isAssignableFrom(componentClass);
if (isReader) {
register(componentClass, beanFactory, priority, interceptors.getReaderInterceptors());
}
if (isWriter) {
register(componentClass, beanFactory, priority, interceptors.getWriterInterceptors());
}
}
private void register(Class> componentClass, BeanFactory> beanFactory, Integer priority,
InterceptorContainer interceptorContainer) {
ResourceInterceptor interceptor = interceptorContainer.create();
Set nameBindings = setCommonFilterProperties(componentClass, beanFactory, priority,
interceptor);
if (interceptorContainer instanceof PreMatchInterceptorContainer
&& componentClass.isAnnotationPresent(PreMatching.class)) {
((PreMatchInterceptorContainer) interceptorContainer).addPreMatchInterceptor(interceptor);
} else if (nameBindings.isEmpty()) {
interceptorContainer.addGlobalRequestInterceptor(interceptor);
} else {
interceptorContainer.addNameRequestInterceptor(interceptor);
}
}
protected boolean isAllowed(Class> componentClass) {
return true;
}
@SuppressWarnings({ "rawtypes", "unchecked" })
private Set setCommonFilterProperties(Class> componentClass, BeanFactory> beanFactory, Integer priority,
SettableResourceInterceptor interceptor) {
interceptor.setFactory(getFactory(componentClass, beanFactory));
setFilterPriority(componentClass, priority, interceptor);
Set nameBindings = new HashSet<>();
Annotation[] annotations = componentClass.getDeclaredAnnotations();
for (Annotation annotation : annotations) {
if (annotation.annotationType().isAnnotation()) {
if (annotation.annotationType().isAnnotationPresent(NameBinding.class)) {
nameBindings.add(annotation.annotationType().getName());
}
}
}
if (!nameBindings.isEmpty()) {
interceptor.setNameBindingNames(nameBindings);
}
return nameBindings;
}
protected void setFilterPriority(Class> componentClass, Integer priority, SettableResourceInterceptor interceptor) {
if (priority == null) {
if (componentClass.isAnnotationPresent(Priority.class)) {
interceptor.setPriority(componentClass.getDeclaredAnnotation(Priority.class).value());
}
} else {
interceptor.setPriority(priority);
}
}
@SuppressWarnings({ "rawtypes", "unchecked" })
protected BeanFactory getFactory(Class> componentClass, BeanFactory explicitValue) {
if (explicitValue != null) {
return explicitValue;
}
return beanFactoryCreator.apply(componentClass);
}
public boolean isFiltersNeedSorting() {
return filtersNeedSorting;
}
}
© 2015 - 2024 Weber Informatics LLC | Privacy Policy