Please wait. This can take some minutes ...
Many resources are needed to download a project. Please understand that we have to compensate our server costs. Thank you in advance.
Project price only 1 $
You can buy this project and download/modify it how often you want.
org.jboss.resteasy.reactive.common.jaxrs.ConfigurationImpl Maven / Gradle / Ivy
package org.jboss.resteasy.reactive.common.jaxrs;
import java.lang.reflect.Type;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import jakarta.annotation.Priority;
import jakarta.ws.rs.ConstrainedTo;
import jakarta.ws.rs.Consumes;
import jakarta.ws.rs.Priorities;
import jakarta.ws.rs.Produces;
import jakarta.ws.rs.RuntimeType;
import jakarta.ws.rs.client.ClientRequestFilter;
import jakarta.ws.rs.client.ClientResponseFilter;
import jakarta.ws.rs.client.RxInvokerProvider;
import jakarta.ws.rs.core.Configuration;
import jakarta.ws.rs.core.Feature;
import jakarta.ws.rs.core.FeatureContext;
import jakarta.ws.rs.core.MediaType;
import jakarta.ws.rs.core.MultivaluedMap;
import jakarta.ws.rs.ext.ContextResolver;
import jakarta.ws.rs.ext.MessageBodyReader;
import jakarta.ws.rs.ext.MessageBodyWriter;
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.model.ResourceReader;
import org.jboss.resteasy.reactive.common.model.ResourceWriter;
import org.jboss.resteasy.reactive.common.util.MultivaluedTreeMap;
import org.jboss.resteasy.reactive.common.util.QuarkusMultivaluedHashMap;
import org.jboss.resteasy.reactive.common.util.types.Types;
public class ConfigurationImpl implements Configuration {
public static final List WILDCARD_LIST = Collections.singletonList(MediaType.WILDCARD_TYPE);
public static final List WILDCARD_STRING_LIST = Collections.singletonList(MediaType.WILDCARD);
private final RuntimeType runtimeType;
private final Map properties;
private final Map, Object> allInstances;
private final List enabledFeatures;
private final Map, Map, Integer>> contracts;
private final MultivaluedMap requestFilters;
private final MultivaluedMap responseFilters;
private final MultivaluedMap writerInterceptors;
private final MultivaluedMap readerInterceptors;
private final MultivaluedMap, ResourceWriter> resourceWriters;
private final MultivaluedMap, ResourceReader> resourceReaders;
private final MultivaluedMap, RxInvokerProvider>> rxInvokerProviders;
private final Map, MultivaluedMap>> contextResolvers;
public ConfigurationImpl(RuntimeType runtimeType) {
this.runtimeType = runtimeType;
this.properties = new HashMap<>();
this.allInstances = new HashMap<>();
this.enabledFeatures = new ArrayList<>();
this.contracts = new HashMap<>();
this.requestFilters = new MultivaluedTreeMap<>();
this.responseFilters = new MultivaluedTreeMap<>(Collections.reverseOrder());
this.readerInterceptors = new MultivaluedTreeMap<>();
this.writerInterceptors = new MultivaluedTreeMap<>(Collections.reverseOrder());
this.resourceReaders = new QuarkusMultivaluedHashMap<>();
this.resourceWriters = new QuarkusMultivaluedHashMap<>();
this.rxInvokerProviders = new QuarkusMultivaluedHashMap<>();
this.contextResolvers = new HashMap<>();
}
public ConfigurationImpl(Configuration configuration) {
this.runtimeType = configuration.getRuntimeType();
this.properties = new HashMap<>(configuration.getProperties());
if (configuration instanceof ConfigurationImpl) {
// we want to preserve all the registration metadata
ConfigurationImpl configurationImpl = (ConfigurationImpl) configuration;
this.enabledFeatures = new ArrayList<>(configurationImpl.enabledFeatures);
this.contracts = new HashMap<>(configurationImpl.contracts);
this.allInstances = new HashMap<>(configurationImpl.allInstances);
this.requestFilters = new MultivaluedTreeMap<>();
this.requestFilters.putAll(configurationImpl.requestFilters);
// Spec 6.6 makes client/server response filters reversed
this.responseFilters = new MultivaluedTreeMap<>(Collections.reverseOrder());
this.responseFilters.putAll(configurationImpl.responseFilters);
this.readerInterceptors = new MultivaluedTreeMap<>();
this.readerInterceptors.putAll(configurationImpl.readerInterceptors);
this.writerInterceptors = new MultivaluedTreeMap<>();
this.writerInterceptors.putAll(configurationImpl.writerInterceptors);
this.resourceReaders = new QuarkusMultivaluedHashMap<>();
this.resourceReaders.putAll(configurationImpl.resourceReaders);
this.resourceWriters = new QuarkusMultivaluedHashMap<>();
this.resourceWriters.putAll(configurationImpl.resourceWriters);
this.rxInvokerProviders = new QuarkusMultivaluedHashMap<>();
this.rxInvokerProviders.putAll(configurationImpl.rxInvokerProviders);
this.contextResolvers = new HashMap<>();
this.contextResolvers.putAll(configurationImpl.contextResolvers);
} else {
this.allInstances = new HashMap<>();
this.enabledFeatures = new ArrayList<>();
this.contracts = new HashMap<>();
this.requestFilters = new MultivaluedTreeMap<>();
// Spec 6.6 makes client/server response filters reversed
this.responseFilters = new MultivaluedTreeMap<>(
Collections.reverseOrder());
this.readerInterceptors = new MultivaluedTreeMap<>();
this.writerInterceptors = new MultivaluedTreeMap<>();
this.resourceReaders = new QuarkusMultivaluedHashMap<>();
this.resourceWriters = new QuarkusMultivaluedHashMap<>();
this.rxInvokerProviders = new QuarkusMultivaluedHashMap<>();
this.contextResolvers = new HashMap<>();
// this is the best we can do - we don't have any of the metadata associated with the registration
for (Object i : configuration.getInstances()) {
register(i);
}
}
}
@Override
public RuntimeType getRuntimeType() {
return runtimeType;
}
@Override
public Map getProperties() {
return Collections.unmodifiableMap(properties);
}
@Override
public Object getProperty(String name) {
return properties.get(name);
}
@Override
public Collection getPropertyNames() {
return properties.keySet();
}
@Override
public boolean isEnabled(Feature feature) {
return enabledFeatures.contains(feature);
}
@Override
public boolean isEnabled(Class extends Feature> featureClass) {
for (Feature enabledFeature : enabledFeatures) {
if (enabledFeature.getClass().equals(featureClass)) {
return true;
}
}
return false;
}
@Override
public boolean isRegistered(Object component) {
return allInstances.get(component.getClass()) == component;
}
@Override
public boolean isRegistered(Class> componentClass) {
return allInstances.containsKey(componentClass);
}
@Override
public Map, Integer> getContracts(Class> componentClass) {
Map, Integer> componentContracts = contracts.get(componentClass);
if (componentContracts == null) {
return Collections.emptyMap();
}
return componentContracts;
}
@Override
public Set> getClasses() {
return new HashSet<>(allInstances.keySet());
}
@Override
public Set getInstances() {
return new HashSet<>(allInstances.values());
}
public void addEnabledFeature(Feature feature) {
enabledFeatures.add(feature);
}
public String toString(Object value) {
// FIXME: this is weird
return value.toString();
}
public void property(String name, Object value) {
properties.put(name, value);
}
public void register(Class> componentClass) {
try {
register(componentClass.getDeclaredConstructor().newInstance());
} catch (Exception e) {
throw new RuntimeException(e);
}
}
public void register(Class> componentClass, int priority) {
try {
register(componentClass.getDeclaredConstructor().newInstance(), priority);
} catch (Exception e) {
throw new RuntimeException(e);
}
}
public void register(Class> componentClass, Class>... contracts) {
try {
register(componentClass.getDeclaredConstructor().newInstance(), contracts);
} catch (Exception e) {
throw new RuntimeException(e);
}
}
public void register(Object component) {
register(component, (Integer) null);
}
private void register(Object component, Integer priority) {
if (allInstances.containsKey(component.getClass())) {
return;
}
boolean added = false;
List> contractableClasses = new ArrayList<>();
if (component instanceof Feature) {
contractableClasses.add(Feature.class);
Feature thisFeature = (Feature) component;
added = true;
if (thisFeature.configure(new ConfigFeatureContext())) {
enabledFeatures.add(thisFeature);
}
}
if (component instanceof ClientRequestFilter) {
contractableClasses.add(ClientRequestFilter.class);
added = true;
int effectivePriority = priority != null ? priority : determinePriority(component);
requestFilters.add(effectivePriority, (ClientRequestFilter) component);
}
if (component instanceof ClientResponseFilter) {
contractableClasses.add(ClientRequestFilter.class);
added = true;
int effectivePriority = priority != null ? priority : determinePriority(component);
responseFilters.add(effectivePriority, (ClientResponseFilter) component);
}
if (component instanceof WriterInterceptor) {
contractableClasses.add(WriterInterceptor.class);
added = true;
int effectivePriority = priority != null ? priority : determinePriority(component);
writerInterceptors.add(effectivePriority, (WriterInterceptor) component);
}
if (component instanceof ReaderInterceptor) {
contractableClasses.add(ReaderInterceptor.class);
added = true;
int effectivePriority = priority != null ? priority : determinePriority(component);
readerInterceptors.add(effectivePriority, (ReaderInterceptor) component);
}
if (component instanceof MessageBodyReader) {
contractableClasses.add(MessageBodyReader.class);
added = true;
Class> componentClass = component.getClass();
ConstrainedTo constrainedTo = componentClass.getAnnotation(ConstrainedTo.class);
if ((constrainedTo == null) || (constrainedTo.value() == runtimeType)) {
ResourceReader resourceReader = new ResourceReader();
resourceReader.setFactory(new UnmanagedBeanFactory(component));
Consumes consumes = componentClass.getAnnotation(Consumes.class);
resourceReader
.setMediaTypeStrings(
consumes != null ? Arrays.asList(consumes.value()) : WILDCARD_STRING_LIST);
if (priority != null) {
resourceReader.setPriority(priority);
}
Type[] args = Types.findParameterizedTypes(componentClass, MessageBodyReader.class);
resourceReaders.add(args != null && args.length == 1 ? Types.getRawType(args[0]) : Object.class,
resourceReader);
}
}
if (component instanceof MessageBodyWriter) {
contractableClasses.add(MessageBodyWriter.class);
added = true;
Class> componentClass = component.getClass();
ConstrainedTo constrainedTo = componentClass.getAnnotation(ConstrainedTo.class);
if ((constrainedTo == null) || (constrainedTo.value() == runtimeType)) {
ResourceWriter resourceWriter = new ResourceWriter();
resourceWriter.setFactory(new UnmanagedBeanFactory(component));
Produces produces = componentClass.getAnnotation(Produces.class);
resourceWriter
.setMediaTypeStrings(
produces != null ? Arrays.asList(produces.value()) : WILDCARD_STRING_LIST);
if (priority != null) {
resourceWriter.setPriority(priority);
}
Type[] args = Types.findParameterizedTypes(componentClass, MessageBodyWriter.class);
resourceWriters.add(args != null && args.length == 1 ? Types.getRawType(args[0]) : Object.class,
resourceWriter);
}
}
if (component instanceof RxInvokerProvider) {
added = true;
Class> componentClass = component.getClass();
Type[] args = Types.findParameterizedTypes(componentClass, RxInvokerProvider.class);
rxInvokerProviders.add(args != null && args.length == 1 ? Types.getRawType(args[0]) : Object.class,
(RxInvokerProvider>) component);
}
if (component instanceof ContextResolver) {
added = true;
Class> componentClass = component.getClass();
Type[] args = Types.findParameterizedTypes(componentClass, ContextResolver.class);
Class> key = args != null && args.length == 1 ? Types.getRawType(args[0]) : Object.class;
int effectivePriority = priority != null ? priority : determinePriority(component);
contextResolvers.computeIfAbsent(key, k -> new MultivaluedTreeMap<>())
.add(effectivePriority, (ContextResolver>) component);
}
if (added) {
allInstances.put(component.getClass(), component);
Map, Integer> contracts = new HashMap<>();
for (Class> contractableClass : contractableClasses) {
contracts.put(contractableClass, priority);
}
this.contracts.put(component.getClass(), contracts);
}
}
public void register(Object component, Class>[] contracts) {
if (contracts == null || contracts.length == 0) {
return;
}
Map, Integer> priorities = new HashMap<>();
for (Class> i : contracts) {
priorities.put(i, determinePriority(i));
}
register(component, priorities);
}
public void register(Class> componentClass, Map, Integer> contracts) {
try {
register(componentClass.getDeclaredConstructor().newInstance(), contracts);
} catch (Exception e) {
throw new RuntimeException(e);
}
}
public void register(Object component, Map, Integer> componentContracts) {
if (componentContracts == null || componentContracts.isEmpty()) {
return;
}
Class> componentClass = component.getClass();
if (allInstances.containsKey(componentClass)) {
return;
}
boolean added = false;
Integer priority = componentContracts.get(Feature.class);
if (component instanceof Feature && priority != null) {
Feature thisFeature = (Feature) component;
added = true;
if (thisFeature.configure(new ConfigFeatureContext())) {
enabledFeatures.add(priority, (Feature) component);
}
}
priority = componentContracts.get(ClientRequestFilter.class);
if (component instanceof ClientRequestFilter && priority != null) {
added = true;
requestFilters.add(priority, (ClientRequestFilter) component);
}
priority = componentContracts.get(ClientResponseFilter.class);
if (component instanceof ClientResponseFilter && priority != null) {
added = true;
responseFilters.add(priority, (ClientResponseFilter) component);
}
priority = componentContracts.get(WriterInterceptor.class);
if (component instanceof WriterInterceptor && priority != null) {
added = true;
writerInterceptors.add(priority, (WriterInterceptor) component);
}
priority = componentContracts.get(ReaderInterceptor.class);
if (component instanceof ReaderInterceptor && priority != null) {
added = true;
readerInterceptors.add(priority, (ReaderInterceptor) component);
}
priority = componentContracts.get(MessageBodyReader.class);
if (component instanceof MessageBodyReader && priority != null) {
added = true;
ConstrainedTo constrainedTo = componentClass.getAnnotation(ConstrainedTo.class);
if ((constrainedTo == null) || (constrainedTo.value() == runtimeType)) {
ResourceReader resourceReader = new ResourceReader();
resourceReader.setFactory(new UnmanagedBeanFactory(component));
Consumes consumes = componentClass.getAnnotation(Consumes.class);
resourceReader
.setMediaTypeStrings(
consumes != null ? Arrays.asList(consumes.value()) : WILDCARD_STRING_LIST);
Type[] args = Types.findParameterizedTypes(componentClass, MessageBodyReader.class);
resourceReaders.add(args != null && args.length == 1 ? Types.getRawType(args[0]) : Object.class,
resourceReader);
}
}
priority = componentContracts.get(MessageBodyWriter.class);
if (component instanceof MessageBodyWriter && priority != null) {
added = true;
ConstrainedTo constrainedTo = componentClass.getAnnotation(ConstrainedTo.class);
if ((constrainedTo == null) || (constrainedTo.value() == runtimeType)) {
ResourceWriter resourceWriter = new ResourceWriter();
resourceWriter.setFactory(new UnmanagedBeanFactory(component));
Produces produces = componentClass.getAnnotation(Produces.class);
resourceWriter
.setMediaTypeStrings(
produces != null ? Arrays.asList(produces.value()) : WILDCARD_STRING_LIST);
Type[] args = Types.findParameterizedTypes(componentClass, MessageBodyWriter.class);
resourceWriters.add(args != null && args.length == 1 ? Types.getRawType(args[0]) : Object.class,
resourceWriter);
}
}
if (component instanceof ContextResolver) {
added = true;
Type[] args = Types.findParameterizedTypes(componentClass, ContextResolver.class);
Class> key = args != null && args.length == 1 ? Types.getRawType(args[0]) : Object.class;
int effectivePriority = priority != null ? priority : determinePriority(component);
contextResolvers.computeIfAbsent(key, k -> new MultivaluedTreeMap<>())
.add(effectivePriority, (ContextResolver>) component);
}
if (added) {
allInstances.put(componentClass, component);
contracts.put(componentClass, componentContracts);
}
}
/*
* Add some custom methods that allow registering MessageBodyReader and MessageBodyWriter classes with all the necessary
* information
*/
public void registerMessageBodyReader(MessageBodyReader> reader, Class> handledType, List consumes,
RuntimeType runtimeType, boolean builtin, Integer priority) {
if (isRegistered(reader)) {
return;
}
ResourceReader resourceReader = new ResourceReader();
resourceReader.setFactory(new UnmanagedBeanFactory<>(reader));
resourceReader.setMediaTypeStrings(consumes);
resourceReader.setBuiltin(builtin);
resourceReader.setPriority(priority);
resourceReader.setConstraint(runtimeType);
resourceReaders.add(handledType, resourceReader);
allInstances.put(reader.getClass(), reader);
}
public void registerMessageBodyWriter(MessageBodyWriter> messageBodyWriter, Class> handledType, List consumes,
RuntimeType runtimeType, boolean builtin, Integer priority) {
if (isRegistered(messageBodyWriter)) {
return;
}
ResourceWriter resourceWriter = new ResourceWriter();
resourceWriter.setFactory(new UnmanagedBeanFactory<>(messageBodyWriter));
resourceWriter.setMediaTypeStrings(consumes);
resourceWriter.setBuiltin(builtin);
resourceWriter.setPriority(priority);
resourceWriter.setConstraint(runtimeType);
resourceWriters.add(handledType, resourceWriter);
allInstances.put(messageBodyWriter.getClass(), messageBodyWriter);
}
public void register(Object component, int priority) {
register(component, Integer.valueOf(priority));
}
public List getRequestFilters() {
if (requestFilters.isEmpty()) {
return Collections.emptyList();
}
List result = new ArrayList<>(requestFilters.size() * 2);
for (List requestFilters : requestFilters.values()) {
result.addAll(requestFilters);
}
return result;
}
public List getResponseFilters() {
if (responseFilters.isEmpty()) {
return Collections.emptyList();
}
List result = new ArrayList<>(responseFilters.size() * 2);
for (List responseFilters : responseFilters.values()) {
result.addAll(responseFilters);
}
return result;
}
public List getWriterInterceptors() {
if (writerInterceptors.isEmpty()) {
return Collections.emptyList();
}
List result = new ArrayList<>(writerInterceptors.size() * 2);
for (List writerInterceptors : writerInterceptors.values()) {
result.addAll(writerInterceptors);
}
return result;
}
public List getReaderInterceptors() {
if (readerInterceptors.isEmpty()) {
return Collections.emptyList();
}
List result = new ArrayList<>(readerInterceptors.size() * 2);
for (List readerInterceptors : readerInterceptors.values()) {
result.addAll(readerInterceptors);
}
return result;
}
public RxInvokerProvider> getRxInvokerProvider(Class> wantedClass) {
List> candidates = rxInvokerProviders.get(wantedClass);
if (candidates == null) {
return null;
}
for (RxInvokerProvider> invokerProvider : candidates) {
if (invokerProvider.isProviderFor(wantedClass))
return invokerProvider;
}
return null;
}
public ContextResolver getContextResolver(Class wantedClass) {
MultivaluedMap> candidates = contextResolvers.get(wantedClass);
if (candidates == null) {
return null;
}
for (List> contextResolvers : candidates.values()) {
if (!contextResolvers.isEmpty()) {
return (ContextResolver) contextResolvers.get(0);
}
}
return null;
}
public T getFromContext(Class wantedClass) {
MultivaluedMap> candidates = contextResolvers.get(wantedClass);
if (candidates == null) {
return null;
}
for (List> contextResolvers : candidates.values()) {
for (ContextResolver> contextResolver : contextResolvers) {
Object instance = contextResolver.getContext(wantedClass);
if (instance != null) {
return (T) instance;
}
}
}
return null;
}
// TODO: we could generate some kind of index at build time in order to obtain these values without using the annotation
private int determinePriority(Object object) {
return determinePriority(object.getClass());
}
private int determinePriority(Class> object) {
Priority priority = object.getDeclaredAnnotation(Priority.class);
if (priority == null) {
return Priorities.USER;
}
return priority.value();
}
public MultivaluedMap, ResourceReader> getResourceReaders() {
return resourceReaders;
}
public MultivaluedMap, ResourceWriter> getResourceWriters() {
return resourceWriters;
}
private class ConfigFeatureContext implements FeatureContext {
@Override
public Configuration getConfiguration() {
return ConfigurationImpl.this;
}
@Override
public FeatureContext property(String name, Object value) {
ConfigurationImpl.this.property(name, value);
return this;
}
@Override
public FeatureContext register(Class> componentClass) {
ConfigurationImpl.this.register(componentClass);
return this;
}
@Override
public FeatureContext register(Class> componentClass, int priority) {
ConfigurationImpl.this.register(componentClass, priority);
return this;
}
@Override
public FeatureContext register(Class> componentClass, Class>... contracts) {
ConfigurationImpl.this.register(componentClass, contracts);
return this;
}
@Override
public FeatureContext register(Class> componentClass, Map, Integer> contracts) {
ConfigurationImpl.this.register(componentClass, contracts);
return this;
}
@Override
public FeatureContext register(Object component) {
ConfigurationImpl.this.register(component);
return this;
}
@Override
public FeatureContext register(Object component, int priority) {
ConfigurationImpl.this.register(component, priority);
return this;
}
@Override
public FeatureContext register(Object component, Class>... contracts) {
ConfigurationImpl.this.register(component, contracts);
return this;
}
@Override
public FeatureContext register(Object component, Map, Integer> contracts) {
ConfigurationImpl.this.register(component, contracts);
return this;
}
}
}