You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@tomee.apache.org by db...@apache.org on 2021/04/25 07:59:00 UTC

[tomee-jakarta] branch master updated (4f04f07 -> 9350edb)

This is an automated email from the ASF dual-hosted git repository.

dblevins pushed a change to branch master
in repository https://gitbox.apache.org/repos/asf/tomee-jakarta.git.


    from 4f04f07  Upgrade BatchEE to 0.6
     new 192eb5c  CXF ProviderFactory as-is, no modification
     new 485ee2b  TOMEE-3730 Add JSONP and JSONB Providers JAX-RS Client
     new 9350edb  Merge branch 'master' of github.com:apache/tomee-jakarta

The 3 revisions listed above as "new" are entirely new to this
repository and will be described in separate emails.  The revisions
listed as "add" were already present in the repository and have only
been added to this reference.


Summary of changes:
 .../apache/cxf/jaxrs/provider/ProviderFactory.java | 1498 ++++++++++++++++++++
 1 file changed, 1498 insertions(+)
 create mode 100644 transform/src/patch/java/org/apache/cxf/jaxrs/provider/ProviderFactory.java

[tomee-jakarta] 01/03: CXF ProviderFactory as-is, no modification

Posted by db...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

dblevins pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/tomee-jakarta.git

commit 192eb5cb5f13148bce804cba98e453542634986c
Author: David Blevins <da...@gmail.com>
AuthorDate: Sat Apr 24 23:38:54 2021 -0700

    CXF ProviderFactory as-is, no modification
---
 .../apache/cxf/jaxrs/provider/ProviderFactory.java | 1492 ++++++++++++++++++++
 1 file changed, 1492 insertions(+)

diff --git a/transform/src/patch/java/org/apache/cxf/jaxrs/provider/ProviderFactory.java b/transform/src/patch/java/org/apache/cxf/jaxrs/provider/ProviderFactory.java
new file mode 100644
index 0000000..673243d
--- /dev/null
+++ b/transform/src/patch/java/org/apache/cxf/jaxrs/provider/ProviderFactory.java
@@ -0,0 +1,1492 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.cxf.jaxrs.provider;
+
+import java.lang.annotation.Annotation;
+import java.lang.reflect.Constructor;
+import java.lang.reflect.Method;
+import java.lang.reflect.ParameterizedType;
+import java.lang.reflect.Type;
+import java.lang.reflect.TypeVariable;
+import java.lang.reflect.WildcardType;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.Comparator;
+import java.util.HashSet;
+import java.util.LinkedHashMap;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import java.util.TreeMap;
+import java.util.logging.Logger;
+
+import javax.ws.rs.Produces;
+import javax.ws.rs.core.Application;
+import javax.ws.rs.core.Configuration;
+import javax.ws.rs.core.MediaType;
+import javax.ws.rs.core.MultivaluedMap;
+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.ReaderInterceptor;
+import javax.ws.rs.ext.WriterInterceptor;
+
+import org.apache.cxf.Bus;
+import org.apache.cxf.common.classloader.ClassLoaderUtils;
+import org.apache.cxf.common.logging.LogUtils;
+import org.apache.cxf.common.util.ClassHelper;
+import org.apache.cxf.common.util.PropertyUtils;
+import org.apache.cxf.endpoint.Endpoint;
+import org.apache.cxf.helpers.CastUtils;
+import org.apache.cxf.jaxrs.ext.ContextProvider;
+import org.apache.cxf.jaxrs.impl.MetadataMap;
+import org.apache.cxf.jaxrs.impl.ReaderInterceptorMBR;
+import org.apache.cxf.jaxrs.impl.WriterInterceptorMBW;
+import org.apache.cxf.jaxrs.impl.tl.ThreadLocalProxy;
+import org.apache.cxf.jaxrs.model.AbstractResourceInfo;
+import org.apache.cxf.jaxrs.model.ApplicationInfo;
+import org.apache.cxf.jaxrs.model.ClassResourceInfo;
+import org.apache.cxf.jaxrs.model.FilterProviderInfo;
+import org.apache.cxf.jaxrs.model.ProviderInfo;
+import org.apache.cxf.jaxrs.utils.AnnotationUtils;
+import org.apache.cxf.jaxrs.utils.InjectionUtils;
+import org.apache.cxf.jaxrs.utils.JAXRSUtils;
+import org.apache.cxf.jaxrs.utils.ResourceUtils;
+import org.apache.cxf.message.Message;
+import org.apache.cxf.message.MessageUtils;
+
+public abstract class ProviderFactory {
+    public static final String DEFAULT_FILTER_NAME_BINDING = "org.apache.cxf.filter.binding";
+    public static final String PROVIDER_SELECTION_PROPERTY_CHANGED = "provider.selection.property.changed";
+    public static final String ACTIVE_JAXRS_PROVIDER_KEY = "active.jaxrs.provider";
+
+    protected static final String SERVER_FACTORY_NAME = "org.apache.cxf.jaxrs.provider.ServerProviderFactory";
+    protected static final String CLIENT_FACTORY_NAME = "org.apache.cxf.jaxrs.client.ClientProviderFactory";
+    protected static final String IGNORE_TYPE_VARIABLES = "org.apache.cxf.jaxrs.providers.ignore.typevars";
+
+    private static final Logger LOG = LogUtils.getL7dLogger(ProviderFactory.class);
+
+    private static final String JAXB_PROVIDER_NAME = "org.apache.cxf.jaxrs.provider.JAXBElementProvider";
+    private static final String JSON_PROVIDER_NAME = "org.apache.cxf.jaxrs.provider.json.JSONProvider";
+    private static final String BUS_PROVIDERS_ALL = "org.apache.cxf.jaxrs.bus.providers";
+    private static final String PROVIDER_CACHE_ALLOWED = "org.apache.cxf.jaxrs.provider.cache.allowed";
+    private static final String PROVIDER_CACHE_CHECK_ALL = "org.apache.cxf.jaxrs.provider.cache.checkAllCandidates";
+
+
+    static class LazyProviderClass {
+        // class to Lazily call the ClassLoaderUtil.loadClass, but do it once
+        // and cache the result.  Then use the class to create instances as needed.
+        // This avoids calling loadClass every time a factory is initialized as
+        // calling loadClass is super expensive, particularly if the class
+        // cannot be found and particularly in osgi where the search is very complex.
+        // This would record that the class is not found and prevent future
+        // searches.
+        final String className;
+        volatile boolean initialized;
+        Class<?> cls;
+
+        LazyProviderClass(String cn) {
+            className = cn;
+        }
+
+        synchronized void loadClass() {
+            if (!initialized) {
+                try {
+                    cls = ClassLoaderUtils.loadClass(className, ProviderFactory.class);
+                } catch (final Throwable ex) {
+                    LOG.fine(className + " not available, skipping");
+                }
+                initialized = true;
+            }
+        }
+
+        public Object tryCreateInstance(Bus bus) {
+            if (!initialized) {
+                loadClass();
+            }
+            if (cls != null) {
+                try {
+                    for (Constructor<?> c : cls.getConstructors()) {
+                        if (c.getParameterTypes().length == 1 && c.getParameterTypes()[0] == Bus.class) {
+                            return c.newInstance(bus);
+                        }
+                    }
+                    return cls.newInstance();
+                } catch (Throwable ex) {
+                    String message = "Problem with creating the provider " + className;
+                    if (ex.getMessage() != null) {
+                        message += ": " + ex.getMessage();
+                    } else {
+                        message += ", exception class : " + ex.getClass().getName();
+                    }
+                    LOG.fine(message);
+                }
+            }
+            return null;
+        }
+    };
+
+    private static final LazyProviderClass DATA_SOURCE_PROVIDER_CLASS =
+        new LazyProviderClass("org.apache.cxf.jaxrs.provider.DataSourceProvider");
+    private static final LazyProviderClass JAXB_PROVIDER_CLASS =
+        new LazyProviderClass(JAXB_PROVIDER_NAME);
+    private static final LazyProviderClass JAXB_ELEMENT_PROVIDER_CLASS =
+        new LazyProviderClass("org.apache.cxf.jaxrs.provider.JAXBElementTypedProvider");
+    private static final LazyProviderClass MULTIPART_PROVIDER_CLASS =
+        new LazyProviderClass("org.apache.cxf.jaxrs.provider.MultipartProvider");
+
+    protected Map<NameKey, ProviderInfo<ReaderInterceptor>> readerInterceptors =
+        new NameKeyMap<>(true);
+    protected Map<NameKey, ProviderInfo<WriterInterceptor>> writerInterceptors =
+        new NameKeyMap<>(true);
+
+    private List<ProviderInfo<MessageBodyReader<?>>> messageReaders =
+        new ArrayList<>();
+    private List<ProviderInfo<MessageBodyWriter<?>>> messageWriters =
+        new ArrayList<>();
+    private List<ProviderInfo<ContextResolver<?>>> contextResolvers =
+        new ArrayList<>();
+    private List<ProviderInfo<ContextProvider<?>>> contextProviders =
+        new ArrayList<>();
+
+    private List<ProviderInfo<ParamConverterProvider>> paramConverters =
+        new ArrayList<>(1);
+    private boolean paramConverterContextsAvailable;
+    // List of injected providers
+    private Collection<ProviderInfo<?>> injectedProviders =
+        new HashSet<>();
+
+    private Bus bus;
+
+    private Comparator<?> providerComparator;
+
+    private ProviderCache providerCache;
+
+
+    protected ProviderFactory(Bus bus) {
+        this.bus = bus;
+        providerCache = initCache(bus);
+    }
+
+    public Bus getBus() {
+        return bus;
+    }
+    protected static ProviderCache initCache(Bus theBus) {
+        Object allowProp = theBus.getProperty(PROVIDER_CACHE_ALLOWED);
+        boolean allowed = allowProp == null || PropertyUtils.isTrue(allowProp);
+        if (!allowed) {
+            return null;
+        }
+        boolean checkAll = PropertyUtils.isTrue(theBus.getProperty(PROVIDER_CACHE_CHECK_ALL));
+        return new ProviderCache(checkAll);
+    }
+    protected static void initFactory(ProviderFactory factory) {
+        // ensure to not load providers not available in a module environment if not needed
+        factory.setProviders(false,
+                             false,
+                     new BinaryDataProvider<Object>(),
+                     new SourceProvider<Object>(),
+                     DATA_SOURCE_PROVIDER_CLASS.tryCreateInstance(factory.getBus()),
+                     new FormEncodingProvider<Object>(),
+                     new StringTextProvider(),
+                     new PrimitiveTextProvider<Object>(),
+                     JAXB_PROVIDER_CLASS.tryCreateInstance(factory.getBus()),
+                     JAXB_ELEMENT_PROVIDER_CLASS.tryCreateInstance(factory.getBus()),
+                     MULTIPART_PROVIDER_CLASS.tryCreateInstance(factory.getBus()));
+        Object prop = factory.getBus().getProperty("skip.default.json.provider.registration");
+        if (!PropertyUtils.isTrue(prop)) {
+            factory.setProviders(false, false, createProvider(JSON_PROVIDER_NAME, factory.getBus()));
+        }
+    }
+
+    protected static Object createProvider(String className, Bus bus) {
+
+        try {
+            Class<?> cls = ClassLoaderUtils.loadClass(className, ProviderFactory.class);
+            for (Constructor<?> c : cls.getConstructors()) {
+                if (c.getParameterTypes().length == 1 && c.getParameterTypes()[0] == Bus.class) {
+                    return c.newInstance(bus);
+                }
+            }
+            return cls.newInstance();
+        } catch (Throwable ex) {
+            String message = "Problem with creating the default provider " + className;
+            if (ex.getMessage() != null) {
+                message += ": " + ex.getMessage();
+            } else {
+                message += ", exception class : " + ex.getClass().getName();
+            }
+            LOG.fine(message);
+        }
+        return null;
+    }
+
+    public abstract Configuration getConfiguration(Message message);
+
+    public <T> ContextResolver<T> createContextResolver(Type contextType,
+                                                        Message m) {
+        boolean isRequestor = MessageUtils.isRequestor(m);
+        Message requestMessage = isRequestor ? m.getExchange().getOutMessage()
+                                             : m.getExchange().getInMessage();
+
+        Message responseMessage = isRequestor ? m.getExchange().getInMessage()
+                                              : m.getExchange().getOutMessage();
+        final Object ctProperty;
+        if (responseMessage != null) {
+            ctProperty = responseMessage.get(Message.CONTENT_TYPE);
+        } else {
+            ctProperty = requestMessage.get(Message.CONTENT_TYPE);
+        }
+        MediaType mt = ctProperty != null ? JAXRSUtils.toMediaType(ctProperty.toString())
+            : MediaType.WILDCARD_TYPE;
+        return createContextResolver(contextType, m, mt);
+
+    }
+
+    @SuppressWarnings("unchecked")
+    public <T> ContextResolver<T> createContextResolver(Type contextType,
+                                                        Message m,
+                                                        MediaType type) {
+        Class<?> contextCls = InjectionUtils.getActualType(contextType);
+        if (contextCls == null) {
+            return null;
+        }
+        List<ContextResolver<T>> candidates = new LinkedList<>();
+        for (ProviderInfo<ContextResolver<?>> cr : contextResolvers) {
+            Type[] types = cr.getProvider().getClass().getGenericInterfaces();
+            for (Type t : types) {
+                if (t instanceof ParameterizedType) {
+                    ParameterizedType pt = (ParameterizedType)t;
+                    Type[] args = pt.getActualTypeArguments();
+                    if (args.length > 0) {
+                        Class<?> argCls = InjectionUtils.getActualType(args[0]);
+
+                        if (argCls != null && argCls.isAssignableFrom(contextCls)) {
+                            List<MediaType> mTypes = JAXRSUtils.getProduceTypes(
+                                 cr.getProvider().getClass().getAnnotation(Produces.class));
+                            if (JAXRSUtils.doMimeTypesIntersect(mTypes, type)) {
+                                injectContextValues(cr, m);
+                                candidates.add((ContextResolver<T>)cr.getProvider());
+                            }
+                        }
+                    }
+                }
+            }
+        }
+        if (candidates.isEmpty()) {
+            return null;
+        } else if (candidates.size() == 1) {
+            return candidates.get(0);
+        } else {
+            Collections.sort(candidates, new PriorityBasedClassComparator());
+            return new ContextResolverProxy<T>(candidates);
+        }
+
+    }
+
+    @SuppressWarnings("unchecked")
+    public <T> ContextProvider<T> createContextProvider(Type contextType,
+                                                        Message m) {
+        Class<?> contextCls = InjectionUtils.getActualType(contextType);
+        if (contextCls == null) {
+            return null;
+        }
+        for (ProviderInfo<ContextProvider<?>> cr : contextProviders) {
+            Type[] types = cr.getProvider().getClass().getGenericInterfaces();
+            for (Type t : types) {
+                if (t instanceof ParameterizedType) {
+                    ParameterizedType pt = (ParameterizedType)t;
+                    Type[] args = pt.getActualTypeArguments();
+                    if (args.length > 0) {
+                        Class<?> argCls = InjectionUtils.getActualType(args[0]);
+
+                        if (argCls != null && argCls.isAssignableFrom(contextCls)) {
+                            return (ContextProvider<T>)cr.getProvider();
+                        }
+                    }
+                }
+            }
+        }
+        return null;
+    }
+
+    public <T> ParamConverter<T> createParameterHandler(Class<T> paramType,
+                                                        Type genericType,
+                                                        Annotation[] anns,
+                                                        Message m) {
+
+        anns = anns != null ? anns : new Annotation[]{};
+        for (ProviderInfo<ParamConverterProvider> pi : paramConverters) {
+            injectContextValues(pi, m);
+            ParamConverter<T> converter = pi.getProvider().getConverter(paramType, genericType, anns);
+            if (converter != null) {
+                return converter;
+            }
+            pi.clearThreadLocalProxies();
+        }
+        return null;
+    }
+
+    protected <T> boolean handleMapper(ProviderInfo<T> em,
+                                       Class<?> expectedType,
+                                       Message m,
+                                       Class<?> providerClass,
+                                       boolean injectContext) {
+        return handleMapper(em, expectedType, m, providerClass, null, injectContext);
+    }
+
+    protected <T> boolean handleMapper(ProviderInfo<T> em,
+                                       Class<?> expectedType,
+                                       Message m,
+                                       Class<?> providerClass,
+                                       Class<?> commonBaseClass,
+                                       boolean injectContext) {
+
+        Class<?> mapperClass = ClassHelper.getRealClass(bus, em.getProvider());
+        Type[] types;
+        if (m != null && MessageUtils.getContextualBoolean(m, IGNORE_TYPE_VARIABLES)) {
+            types = new Type[]{mapperClass};
+        } else {
+            types = getGenericInterfaces(mapperClass, expectedType, commonBaseClass);
+        }
+        for (Type t : types) {
+            if (t instanceof ParameterizedType) {
+                ParameterizedType pt = (ParameterizedType)t;
+                Type[] args = pt.getActualTypeArguments();
+                for (Type arg : args) {
+                    if (arg instanceof TypeVariable) {
+                        TypeVariable<?> var = (TypeVariable<?>) arg;
+                        Type[] bounds = var.getBounds();
+                        boolean isResolved = false;
+                        for (Type bound : bounds) {
+                            Class<?> cls = InjectionUtils.getRawType(bound);
+                            if (cls != null && (cls == Object.class || cls.isAssignableFrom(expectedType))) {
+                                isResolved = true;
+                                break;
+                            }
+                        }
+                        if (!isResolved) {
+                            return false;
+                        }
+                        if (injectContext) {
+                            injectContextValues(em, m);
+                        }
+                        return true;
+                    }
+                    Class<?> actualClass = InjectionUtils.getRawType(arg);
+                    if (actualClass == null) {
+                        continue;
+                    }
+                    if (expectedType.isArray() && !actualClass.isArray()) {
+                        expectedType = expectedType.getComponentType();
+                    }
+                    if (actualClass.isAssignableFrom(expectedType) || actualClass == Object.class) {
+                        if (injectContext) {
+                            injectContextValues(em, m);
+                        }
+                        return true;
+                    }
+                }
+            } else if (t instanceof Class && providerClass.isAssignableFrom((Class<?>)t)) {
+                if (injectContext) {
+                    injectContextValues(em, m);
+                }
+                return true;
+            }
+        }
+        return false;
+    }
+
+
+    public <T> List<ReaderInterceptor> createMessageBodyReaderInterceptor(Class<T> bodyType,
+                                                            Type parameterType,
+                                                            Annotation[] parameterAnnotations,
+                                                            MediaType mediaType,
+                                                            Message m,
+                                                            boolean checkMbrNow,
+                                                            Set<String> names) {
+        MessageBodyReader<T> mr = !checkMbrNow ? null : createMessageBodyReader(bodyType,
+                                                      parameterType,
+                                                      parameterAnnotations,
+                                                      mediaType,
+                                                      m);
+        int size = readerInterceptors.size();
+        if (mr != null || size > 0) {
+            ReaderInterceptor mbrReader = new ReaderInterceptorMBR(mr, getResponseMessage(m));
+
+            final List<ReaderInterceptor> interceptors;
+            if (size > 0) {
+                interceptors = new ArrayList<>(size + 1);
+                List<ProviderInfo<ReaderInterceptor>> readers =
+                    getBoundFilters(readerInterceptors, names);
+                for (ProviderInfo<ReaderInterceptor> p : readers) {
+                    injectContextValues(p, m);
+                    interceptors.add(p.getProvider());
+                }
+                interceptors.add(mbrReader);
+            } else {
+                interceptors = Collections.singletonList(mbrReader);
+            }
+
+            return interceptors;
+        }
+        return null;
+    }
+
+    public <T> List<WriterInterceptor> createMessageBodyWriterInterceptor(Class<T> bodyType,
+                                                                          Type parameterType,
+                                                                          Annotation[] parameterAnnotations,
+                                                                          MediaType mediaType,
+                                                                          Message m,
+                                                                          Set<String> names) {
+        MessageBodyWriter<T> mw = createMessageBodyWriter(bodyType,
+                                                      parameterType,
+                                                      parameterAnnotations,
+                                                      mediaType,
+                                                      m);
+        int size = writerInterceptors.size();
+        if (mw != null || size > 0) {
+
+            @SuppressWarnings({
+                "unchecked", "rawtypes"
+            })
+            WriterInterceptor mbwWriter = new WriterInterceptorMBW((MessageBodyWriter)mw, m);
+
+            final List<WriterInterceptor> interceptors;
+            if (size > 0) {
+                interceptors = new ArrayList<>(size + 1);
+                List<ProviderInfo<WriterInterceptor>> writers =
+                    getBoundFilters(writerInterceptors, names);
+                for (ProviderInfo<WriterInterceptor> p : writers) {
+                    injectContextValues(p, m);
+                    interceptors.add(p.getProvider());
+                }
+                interceptors.add(mbwWriter);
+            } else {
+                interceptors = Collections.singletonList(mbwWriter);
+            }
+
+            return interceptors;
+        }
+        return null;
+    }
+
+
+
+    @SuppressWarnings("unchecked")
+    public <T> MessageBodyReader<T> createMessageBodyReader(Class<T> type,
+                                                            Type genericType,
+                                                            Annotation[] annotations,
+                                                            MediaType mediaType,
+                                                            Message m) {
+        // Step1: check the cache
+
+        if (providerCache != null) {
+            for (ProviderInfo<MessageBodyReader<?>> ep : providerCache.getReaders(type, mediaType)) {
+                if (isReadable(ep, type, genericType, annotations, mediaType, m)) {
+                    return (MessageBodyReader<T>)ep.getProvider();
+                }
+            }
+        }
+
+        boolean checkAll = providerCache != null && providerCache.isCheckAllCandidates();
+        List<ProviderInfo<MessageBodyReader<?>>> allCandidates =
+            checkAll ? new LinkedList<ProviderInfo<MessageBodyReader<?>>>() : null;
+
+        MessageBodyReader<T> selectedReader = null;
+        for (ProviderInfo<MessageBodyReader<?>> ep : messageReaders) {
+            if (matchesReaderMediaTypes(ep, mediaType)
+                && handleMapper(ep, type, m, MessageBodyReader.class, false)) {
+                // This writer matches Media Type and Class
+                if (checkAll) {
+                    allCandidates.add(ep);
+                } else if (providerCache != null && providerCache.getReaders(type, mediaType).isEmpty()) {
+                    providerCache.putReaders(type, mediaType, Collections.singletonList(ep));
+                }
+                if (selectedReader == null
+                    && isReadable(ep, type, genericType, annotations, mediaType, m)) {
+                    // This writer is a selected candidate
+                    selectedReader = (MessageBodyReader<T>)ep.getProvider();
+                    if (!checkAll) {
+                        return selectedReader;
+                    }
+                }
+
+            }
+        }
+        if (checkAll) {
+            providerCache.putReaders(type, mediaType, allCandidates);
+        }
+        return selectedReader;
+    }
+
+    @SuppressWarnings("unchecked")
+    public <T> MessageBodyWriter<T> createMessageBodyWriter(Class<T> type,
+                                                            Type genericType,
+                                                            Annotation[] annotations,
+                                                            MediaType mediaType,
+                                                            Message m) {
+
+        // Step1: check the cache.
+        if (providerCache != null) {
+            for (ProviderInfo<MessageBodyWriter<?>> ep : providerCache.getWriters(type, mediaType)) {
+                if (isWriteable(ep, type, genericType, annotations, mediaType, m)) {
+                    return (MessageBodyWriter<T>)ep.getProvider();
+                }
+            }
+        }
+
+        // Step2: check all the registered writers
+
+        // The cache, if enabled, may have been configured to keep the top candidate only
+        boolean checkAll = providerCache != null && providerCache.isCheckAllCandidates();
+        List<ProviderInfo<MessageBodyWriter<?>>> allCandidates =
+            checkAll ? new LinkedList<ProviderInfo<MessageBodyWriter<?>>>() : null;
+
+        MessageBodyWriter<T> selectedWriter = null;
+        for (ProviderInfo<MessageBodyWriter<?>> ep : messageWriters) {
+            if (matchesWriterMediaTypes(ep, mediaType)
+                && handleMapper(ep, type, m, MessageBodyWriter.class, false)) {
+                // This writer matches Media Type and Class
+                if (checkAll) {
+                    allCandidates.add(ep);
+                } else if (providerCache != null && providerCache.getWriters(type, mediaType).isEmpty()) {
+                    providerCache.putWriters(type, mediaType, Collections.singletonList(ep));
+                }
+                if (selectedWriter == null
+                    && isWriteable(ep, type, genericType, annotations, mediaType, m)) {
+                    // This writer is a selected candidate
+                    selectedWriter = (MessageBodyWriter<T>)ep.getProvider();
+                    if (!checkAll) {
+                        return selectedWriter;
+                    }
+                }
+
+            }
+        }
+        if (checkAll) {
+            providerCache.putWriters(type, mediaType, allCandidates);
+        }
+        return selectedWriter;
+
+    }
+
+    protected void setBusProviders() {
+        List<Object> extensions = new LinkedList<>();
+        addBusExtension(extensions,
+                        MessageBodyReader.class,
+                        MessageBodyWriter.class,
+                        ExceptionMapper.class);
+        if (!extensions.isEmpty()) {
+            setProviders(true, true, extensions.toArray());
+        }
+    }
+
+
+    private void addBusExtension(List<Object> extensions, Class<?>... extClasses) {
+        for (Class<?> extClass : extClasses) {
+            Object ext = bus.getProperty(extClass.getName());
+            if (extClass.isInstance(ext)) {
+                extensions.add(ext);
+            }
+        }
+        Object allProp = bus.getProperty(BUS_PROVIDERS_ALL);
+        if (allProp instanceof List) {
+            @SuppressWarnings("unchecked")
+            List<Object> all = (List<Object>)allProp;
+            extensions.addAll(all);
+        }
+    }
+
+    protected abstract void setProviders(boolean custom, boolean busGlobal, Object... providers);
+
+    @SuppressWarnings("unchecked")
+    protected void setCommonProviders(List<ProviderInfo<? extends Object>> theProviders) {
+        List<ProviderInfo<ReaderInterceptor>> readInts =
+            new LinkedList<>();
+        List<ProviderInfo<WriterInterceptor>> writeInts =
+            new LinkedList<>();
+        for (ProviderInfo<? extends Object> provider : theProviders) {
+            Class<?> providerCls = ClassHelper.getRealClass(bus, provider.getProvider());
+
+            if (filterContractSupported(provider, providerCls, MessageBodyReader.class)) {
+                addProviderToList(messageReaders, provider);
+            }
+
+            if (filterContractSupported(provider, providerCls, MessageBodyWriter.class)) {
+                addProviderToList(messageWriters, provider);
+            }
+
+            if (filterContractSupported(provider, providerCls, ContextResolver.class)) {
+                addProviderToList(contextResolvers, provider);
+            }
+
+            if (ContextProvider.class.isAssignableFrom(providerCls)) {
+                addProviderToList(contextProviders, provider);
+            }
+
+            if (filterContractSupported(provider, providerCls, ReaderInterceptor.class)) {
+                readInts.add((ProviderInfo<ReaderInterceptor>)provider);
+            }
+
+            if (filterContractSupported(provider, providerCls, WriterInterceptor.class)) {
+                writeInts.add((ProviderInfo<WriterInterceptor>)provider);
+            }
+
+            if (filterContractSupported(provider, providerCls, ParamConverterProvider.class)) {
+                paramConverters.add((ProviderInfo<ParamConverterProvider>)provider);
+            }
+        }
+        sortReaders();
+        sortWriters();
+        sortContextResolvers();
+
+        mapInterceptorFilters(readerInterceptors, readInts, ReaderInterceptor.class, true);
+        mapInterceptorFilters(writerInterceptors, writeInts, WriterInterceptor.class, true);
+
+        injectContextProxies(messageReaders, messageWriters, contextResolvers, paramConverters,
+            readerInterceptors.values(), writerInterceptors.values());
+        checkParamConverterContexts();
+    }
+
+    private void checkParamConverterContexts() {
+        for (ProviderInfo<ParamConverterProvider> pi : paramConverters) {
+            if (pi.contextsAvailable()) {
+                paramConverterContextsAvailable = true;
+            }
+        }
+
+    }
+    public boolean isParamConverterContextsAvailable() {
+        return paramConverterContextsAvailable;
+    }
+
+
+
+    protected void injectContextValues(ProviderInfo<?> pi, Message m) {
+        if (m != null) {
+            InjectionUtils.injectContexts(pi.getProvider(), pi, m);
+        }
+    }
+
+    protected void addProviderToList(List<?> list, ProviderInfo<?> provider) {
+        List<ProviderInfo<?>> list2 = CastUtils.cast(list);
+        for (ProviderInfo<?> pi : list2) {
+            if (pi.getProvider() == provider.getProvider()) {
+                return;
+            }
+        }
+        list2.add(provider);
+    }
+
+    protected void injectContextProxies(Collection<?> ... providerLists) {
+        for (Collection<?> list : providerLists) {
+            Collection<ProviderInfo<?>> l2 = CastUtils.cast(list);
+            for (ProviderInfo<?> pi : l2) {
+                injectContextProxiesIntoProvider(pi);
+            }
+        }
+    }
+
+    protected void injectContextProxiesIntoProvider(ProviderInfo<?> pi) {
+        injectContextProxiesIntoProvider(pi, null);
+    }
+
+    void injectContextProxiesIntoProvider(ProviderInfo<?> pi, Application app) {
+        if (pi.contextsAvailable()) {
+            InjectionUtils.injectContextProxiesAndApplication(pi, pi.getProvider(), app, this);
+            injectedProviders.add(pi);
+        }
+    }
+
+    /*
+     * sorts the available providers according to the media types they declare
+     * support for. Sorting of media types follows the general rule: x/y < * x < *,
+     * i.e. a provider that explicitly lists a media types is sorted before a
+     * provider that lists *. Quality parameter values are also used such that
+     * x/y;q=1.0 < x/y;q=0.7.
+     */
+    private void sortReaders() {
+        if (!customComparatorAvailable(MessageBodyReader.class)) {
+            messageReaders.sort(new MessageBodyReaderComparator());
+        } else {
+            doCustomSort(messageReaders);
+        }
+    }
+    private <T> void sortWriters() {
+        if (!customComparatorAvailable(MessageBodyWriter.class)) {
+            messageWriters.sort(new MessageBodyWriterComparator());
+        } else {
+            doCustomSort(messageWriters);
+        }
+    }
+
+    private boolean customComparatorAvailable(Class<?> providerClass) {
+        if (providerComparator != null) {
+            Type type = ((ParameterizedType)providerComparator.getClass()
+                .getGenericInterfaces()[0]).getActualTypeArguments()[0];
+            if (type instanceof ParameterizedType) {
+                ParameterizedType pt = (ParameterizedType)type;
+                if (pt.getRawType() == ProviderInfo.class) {
+                    Type type2 = pt.getActualTypeArguments()[0];
+                    if (type2 == providerClass
+                        || type2 instanceof WildcardType
+                        || type2 instanceof ParameterizedType
+                           && ((ParameterizedType)type2).getRawType() == providerClass) {
+                        return true;
+                    }
+                }
+            } else if (type == Object.class) {
+                return true;
+            }
+        }
+        return false;
+    }
+
+    @SuppressWarnings("unchecked")
+    private <T> void doCustomSort(List<?> listOfProviders) {
+        Comparator<?> theProviderComparator = providerComparator;
+        Type type = ((ParameterizedType)providerComparator.getClass()
+            .getGenericInterfaces()[0]).getActualTypeArguments()[0];
+        if (type == Object.class) {
+            theProviderComparator =
+                new ProviderInfoClassComparator((Comparator<Object>)theProviderComparator);
+        }
+        List<T> theProviders = (List<T>)listOfProviders;
+        Comparator<? super T> theComparator = (Comparator<? super T>)theProviderComparator;
+        theProviders.sort(theComparator);
+    }
+
+    private void sortContextResolvers() {
+        contextResolvers.sort(new ContextResolverComparator());
+    }
+
+
+
+
+
+    private <T> boolean matchesReaderMediaTypes(ProviderInfo<MessageBodyReader<?>> pi,
+                                                MediaType mediaType) {
+        MessageBodyReader<?> ep = pi.getProvider();
+        List<MediaType> supportedMediaTypes = JAXRSUtils.getProviderConsumeTypes(ep);
+
+        return JAXRSUtils.doMimeTypesIntersect(Collections.singletonList(mediaType), supportedMediaTypes);
+    }
+
+    private boolean isReadable(ProviderInfo<MessageBodyReader<?>> pi,
+                               Class<?> type,
+                               Type genericType,
+                               Annotation[] annotations,
+                               MediaType mediaType,
+                               Message m) {
+        MessageBodyReader<?> ep = pi.getProvider();
+        if (m.get(ACTIVE_JAXRS_PROVIDER_KEY) != ep) {
+            injectContextValues(pi, m);
+        }
+        return ep.isReadable(type, genericType, annotations, mediaType);
+    }
+
+    private <T> boolean matchesWriterMediaTypes(ProviderInfo<MessageBodyWriter<?>> pi,
+                                                MediaType mediaType) {
+        MessageBodyWriter<?> ep = pi.getProvider();
+        List<MediaType> supportedMediaTypes = JAXRSUtils.getProviderProduceTypes(ep);
+
+        return JAXRSUtils.doMimeTypesIntersect(Collections.singletonList(mediaType), supportedMediaTypes);
+    }
+
+    private boolean isWriteable(ProviderInfo<MessageBodyWriter<?>> pi,
+                               Class<?> type,
+                               Type genericType,
+                               Annotation[] annotations,
+                               MediaType mediaType,
+                               Message m) {
+        MessageBodyWriter<?> ep = pi.getProvider();
+        if (m.get(ACTIVE_JAXRS_PROVIDER_KEY) != ep) {
+            injectContextValues(pi, m);
+        }
+        return ep.isWriteable(type, genericType, annotations, mediaType);
+    }
+
+    List<ProviderInfo<MessageBodyReader<?>>> getMessageReaders() {
+        return Collections.unmodifiableList(messageReaders);
+    }
+
+    List<ProviderInfo<MessageBodyWriter<?>>> getMessageWriters() {
+        return Collections.unmodifiableList(messageWriters);
+    }
+
+    public List<ProviderInfo<ContextResolver<?>>> getContextResolvers() {
+        return Collections.unmodifiableList(contextResolvers);
+    }
+
+
+    public void registerUserProvider(Object provider) {
+        setUserProviders(Collections.singletonList(provider));
+    }
+    /**
+     * Use for injection of entityProviders
+     * @param userProviders the userProviders to set
+     */
+    public void setUserProviders(List<?> userProviders) {
+        setProviders(true, false, userProviders.toArray());
+    }
+
+    private static class MessageBodyReaderComparator
+        implements Comparator<ProviderInfo<MessageBodyReader<?>>> {
+
+        public int compare(ProviderInfo<MessageBodyReader<?>> p1,
+                           ProviderInfo<MessageBodyReader<?>> p2) {
+            MessageBodyReader<?> e1 = p1.getProvider();
+            MessageBodyReader<?> e2 = p2.getProvider();
+
+            List<MediaType> types1 = JAXRSUtils.getProviderConsumeTypes(e1);
+            types1 = JAXRSUtils.sortMediaTypes(types1, null);
+            List<MediaType> types2 = JAXRSUtils.getProviderConsumeTypes(e2);
+            types2 = JAXRSUtils.sortMediaTypes(types2, null);
+
+            int result = JAXRSUtils.compareSortedMediaTypes(types1, types2, null);
+            if (result != 0) {
+                return result;
+            }
+            result = compareClasses(e1, e2);
+            if (result != 0) {
+                return result;
+            }
+            result = compareCustomStatus(p1, p2);
+            if (result != 0) {
+                return result;
+            }
+            return comparePriorityStatus(p1.getProvider().getClass(), p2.getProvider().getClass());
+        }
+    }
+
+    private static class MessageBodyWriterComparator
+        implements Comparator<ProviderInfo<MessageBodyWriter<?>>> {
+
+        public int compare(ProviderInfo<MessageBodyWriter<?>> p1,
+                           ProviderInfo<MessageBodyWriter<?>> p2) {
+            MessageBodyWriter<?> e1 = p1.getProvider();
+            MessageBodyWriter<?> e2 = p2.getProvider();
+
+            int result = compareClasses(e1, e2);
+            if (result != 0) {
+                return result;
+            }
+            List<MediaType> types1 =
+                JAXRSUtils.sortMediaTypes(JAXRSUtils.getProviderProduceTypes(e1), JAXRSUtils.MEDIA_TYPE_QS_PARAM);
+            List<MediaType> types2 =
+                JAXRSUtils.sortMediaTypes(JAXRSUtils.getProviderProduceTypes(e2), JAXRSUtils.MEDIA_TYPE_QS_PARAM);
+
+            result = JAXRSUtils.compareSortedMediaTypes(types1, types2, JAXRSUtils.MEDIA_TYPE_QS_PARAM);
+            if (result != 0) {
+                return result;
+            }
+            result = compareCustomStatus(p1, p2);
+            if (result != 0) {
+                return result;
+            }
+
+            return comparePriorityStatus(p1.getProvider().getClass(), p2.getProvider().getClass());
+        }
+    }
+
+    protected static int compareCustomStatus(ProviderInfo<?> p1, ProviderInfo<?> p2) {
+        boolean custom1 = p1.isCustom();
+        int result = Boolean.compare(p2.isCustom(), custom1);
+        if (result == 0 && custom1) {
+            result = Boolean.compare(p1.isBusGlobal(), p2.isBusGlobal());
+        }
+        return result;
+    }
+
+    static int comparePriorityStatus(Class<?> cl1, Class<?> cl2) {
+        return Integer.compare(AnnotationUtils.getBindingPriority(cl1), AnnotationUtils.getBindingPriority(cl2));
+    }
+
+    private static class ContextResolverComparator
+        implements Comparator<ProviderInfo<ContextResolver<?>>> {
+
+        public int compare(ProviderInfo<ContextResolver<?>> p1,
+                           ProviderInfo<ContextResolver<?>> p2) {
+            ContextResolver<?> e1 = p1.getProvider();
+            ContextResolver<?> e2 = p2.getProvider();
+
+            List<MediaType> types1 =
+                JAXRSUtils.sortMediaTypes(JAXRSUtils.getProduceTypes(
+                     e1.getClass().getAnnotation(Produces.class)), JAXRSUtils.MEDIA_TYPE_QS_PARAM);
+            List<MediaType> types2 =
+                JAXRSUtils.sortMediaTypes(JAXRSUtils.getProduceTypes(
+                     e2.getClass().getAnnotation(Produces.class)), JAXRSUtils.MEDIA_TYPE_QS_PARAM);
+
+            return JAXRSUtils.compareSortedMediaTypes(types1, types2, JAXRSUtils.MEDIA_TYPE_QS_PARAM);
+        }
+    }
+
+    public void clearThreadLocalProxies() {
+        clearProxies(injectedProviders);
+    }
+
+    void clearProxies(Collection<?> ...lists) {
+        for (Collection<?> list : lists) {
+            Collection<ProviderInfo<?>> l2 = CastUtils.cast(list);
+            for (ProviderInfo<?> pi : l2) {
+                pi.clearThreadLocalProxies();
+            }
+        }
+    }
+
+    public void clearProviders() {
+        messageReaders.clear();
+        messageWriters.clear();
+        contextResolvers.clear();
+        contextProviders.clear();
+        readerInterceptors.clear();
+        writerInterceptors.clear();
+        paramConverters.clear();
+    }
+
+    public void setBus(Bus bus) {
+        if (bus == null) {
+            return;
+        }
+        for (ProviderInfo<MessageBodyReader<?>> r : messageReaders) {
+            injectProviderProperty(r.getProvider(), "setBus", Bus.class, bus);
+        }
+    }
+
+    private boolean injectProviderProperty(Object provider, String mName, Class<?> pClass,
+                                        Object pValue) {
+        try {
+            Method m = provider.getClass().getMethod(mName, new Class[]{pClass});
+            m.invoke(provider, new Object[]{pValue});
+            return true;
+        } catch (Exception ex) {
+            // ignore
+        }
+        return false;
+    }
+
+    public void setSchemaLocations(List<String> schemas) {
+        for (ProviderInfo<MessageBodyReader<?>> r : messageReaders) {
+            injectProviderProperty(r.getProvider(), "setSchemaLocations", List.class, schemas);
+        }
+    }
+
+    protected static <T> List<ProviderInfo<T>> getBoundFilters(Map<NameKey, ProviderInfo<T>> boundFilters,
+                                                                          Set<String> names) {
+        if (boundFilters.isEmpty()) {
+            return Collections.emptyList();
+        }
+        names = names == null ? Collections.<String>emptySet() : names;
+
+        MultivaluedMap<ProviderInfo<T>, String> map =
+            new MetadataMap<>();
+        for (Map.Entry<NameKey, ProviderInfo<T>> entry : boundFilters.entrySet()) {
+            String entryName = entry.getKey().getName();
+            ProviderInfo<T> provider = entry.getValue();
+            if (entryName.equals(DEFAULT_FILTER_NAME_BINDING)) {
+                map.put(provider, Collections.<String>emptyList());
+            } else {
+                if (provider instanceof FilterProviderInfo) {
+                    FilterProviderInfo<?> fpi = (FilterProviderInfo<?>)provider;
+                    if (fpi.isDynamic() && !names.containsAll(fpi.getNameBindings())) {
+                        continue;
+                    }
+                }
+                map.add(provider, entryName);
+            }
+        }
+        List<ProviderInfo<T>> list = new LinkedList<>();
+        for (Map.Entry<ProviderInfo<T>, List<String>> entry : map.entrySet()) {
+            List<String> values = entry.getValue();
+            if (names.containsAll(values)) {
+                ProviderInfo<T> provider = entry.getKey();
+                list.add(provider);
+            }
+        }
+        return list;
+    }
+
+    public void initProviders(List<ClassResourceInfo> cris) {
+        Set<Object> set = getReadersWriters();
+        for (Object o : set) {
+            Object provider = ((ProviderInfo<?>)o).getProvider();
+            if (provider instanceof AbstractConfigurableProvider) {
+                ((AbstractConfigurableProvider)provider).init(cris);
+            }
+        }
+    }
+
+    Set<Object> getReadersWriters() {
+        Set<Object> set = new HashSet<>();
+        set.addAll(messageReaders);
+        set.addAll(messageWriters);
+        return set;
+    }
+
+    public static class ClassComparator implements
+        Comparator<Object> {
+        private Class<?> expectedCls;
+        public ClassComparator() {
+        }
+        public ClassComparator(Class<?> expectedCls) {
+            this.expectedCls = expectedCls;
+        }
+
+        public int compare(Object em1, Object em2) {
+            return compareClasses(expectedCls, em1, em2);
+        }
+    }
+
+    public static class ProviderInfoClassComparator implements Comparator<ProviderInfo<?>> {
+        private Comparator<Object> comp;
+        private boolean defaultComp;
+        public ProviderInfoClassComparator(Class<?> expectedCls) {
+            this.comp = new ClassComparator(expectedCls);
+            this.defaultComp = true;
+        }
+        public ProviderInfoClassComparator(Comparator<Object> comp) {
+            this.comp = comp;
+        }
+        public int compare(ProviderInfo<?> p1, ProviderInfo<?> p2) {
+            int result = comp.compare(p1.getProvider(), p2.getProvider());
+            if (result == 0 && defaultComp) {
+                result = compareCustomStatus(p1, p2);
+            }
+            return result;
+        }
+    }
+
+    static class PriorityBasedClassComparator extends ClassComparator {
+        PriorityBasedClassComparator() {
+            super();
+        }
+
+        PriorityBasedClassComparator(Class<?> expectedCls) {
+            super(expectedCls);
+        }
+
+        @Override
+        public int compare(Object em1, Object em2) {
+            int result = super.compare(em1, em2);
+            if (result == 0) {
+                result = comparePriorityStatus(em1.getClass(), em2.getClass());
+            }
+            return result;
+        }
+    }
+
+    public static ProviderFactory getInstance(Message m) {
+        Endpoint e = m.getExchange().getEndpoint();
+
+        Message outM = m.getExchange().getOutMessage();
+        boolean isClient = outM != null && MessageUtils.isRequestor(outM);
+        String name = isClient ? CLIENT_FACTORY_NAME : SERVER_FACTORY_NAME;
+
+        return (ProviderFactory)e.get(name);
+    }
+    protected static int compareClasses(Object o1, Object o2) {
+        return compareClasses(null, o1, o2);
+    }
+    protected static int compareClasses(Class<?> expectedCls, Object o1, Object o2) {
+        Class<?> cl1 = ClassHelper.getRealClass(o1);
+        Class<?> cl2 = ClassHelper.getRealClass(o2);
+        Type[] types1 = getGenericInterfaces(cl1, expectedCls);
+        Type[] types2 = getGenericInterfaces(cl2, expectedCls);
+        if (types1.length == 0 && types2.length == 0) {
+            return 0;
+        } else if (types1.length == 0 && types2.length > 0) {
+            return 1;
+        } else if (types1.length > 0 && types2.length == 0) {
+            return -1;
+        }
+
+        Class<?> realClass1 = InjectionUtils.getActualType(types1[0]);
+        Class<?> realClass2 = InjectionUtils.getActualType(types2[0]);
+        if (realClass1 == realClass2) {
+            return 0;
+        }
+        if (realClass1.isAssignableFrom(realClass2)) {
+            // subclass should go first
+            return 1;
+        }
+        return -1;
+    }
+
+    private static Type[] getGenericInterfaces(Class<?> cls, Class<?> expectedClass) {
+        return getGenericInterfaces(cls, expectedClass, Object.class);
+    }
+    private static Type[] getGenericInterfaces(Class<?> cls, Class<?> expectedClass,
+                                               Class<?> commonBaseCls) {
+        if (Object.class == cls) {
+            return new Type[]{};
+        }
+        if (expectedClass != null) {
+            Type genericSuperType = cls.getGenericSuperclass();
+            if (genericSuperType instanceof ParameterizedType) {
+                Class<?> actualType = InjectionUtils.getActualType(genericSuperType);
+                if (actualType != null && actualType.isAssignableFrom(expectedClass)) {
+                    return new Type[]{genericSuperType};
+                } else if (commonBaseCls != null && commonBaseCls != Object.class
+                           && commonBaseCls.isAssignableFrom(expectedClass)
+                           && commonBaseCls.isAssignableFrom(actualType)
+                           || expectedClass.isAssignableFrom(actualType)) {
+                    return new Type[]{};
+                }
+            }
+        }
+        Type[] types = cls.getGenericInterfaces();
+        if (types.length > 0) {
+            return types;
+        }
+        return getGenericInterfaces(cls.getSuperclass(), expectedClass, commonBaseCls);
+    }
+
+    protected static class AbstractPriorityComparator {
+
+        private boolean ascending;
+
+        protected AbstractPriorityComparator(boolean ascending) {
+            this.ascending = ascending;
+        }
+
+        protected int compare(Integer b1Value, Integer b2Value) {
+            int result = b1Value.compareTo(b2Value);
+            return ascending ? result : result * -1;
+        }
+
+    }
+
+    protected static class BindingPriorityComparator extends AbstractPriorityComparator
+        implements Comparator<ProviderInfo<?>> {
+        private Class<?> providerCls;
+
+        public BindingPriorityComparator(Class<?> providerCls, boolean ascending) {
+            super(ascending);
+            this.providerCls = providerCls;
+        }
+
+        public int compare(ProviderInfo<?> p1, ProviderInfo<?> p2) {
+            return compare(getFilterPriority(p1, providerCls),
+                           getFilterPriority(p2, providerCls));
+        }
+
+    }
+
+    static class ContextResolverProxy<T> implements ContextResolver<T> {
+        private List<ContextResolver<T>> candidates;
+        ContextResolverProxy(List<ContextResolver<T>> candidates) {
+            this.candidates = candidates;
+        }
+        public T getContext(Class<?> cls) {
+            for (ContextResolver<T> resolver : candidates) {
+                T context = resolver.getContext(cls);
+                if (context != null) {
+                    return context;
+                }
+            }
+            return null;
+        }
+
+        public List<ContextResolver<T>> getResolvers() {
+            return candidates;
+        }
+    }
+
+    public static ProviderInfo<? extends Object> createProviderFromConstructor(Constructor<?> c,
+                                                                 Map<Class<?>, Object> values,
+                                                                 Bus theBus,
+                                                                 boolean checkContexts,
+                                                                 boolean custom) {
+
+
+        Map<Class<?>, Map<Class<?>, ThreadLocalProxy<?>>> proxiesMap =
+            CastUtils.cast((Map<?, ?>)theBus.getProperty(AbstractResourceInfo.CONSTRUCTOR_PROXY_MAP));
+        Map<Class<?>, ThreadLocalProxy<?>> existingProxies = null;
+        if (proxiesMap != null) {
+            existingProxies = proxiesMap.get(c.getDeclaringClass());
+        }
+        Class<?>[] paramTypes = c.getParameterTypes();
+        Object[] cArgs = ResourceUtils.createConstructorArguments(c, null, false, values);
+        if (existingProxies != null && existingProxies.size() <= paramTypes.length) {
+            for (int i = 0; i < paramTypes.length; i++) {
+                if (cArgs[i] instanceof ThreadLocalProxy) {
+                    cArgs[i] = existingProxies.get(paramTypes[i]);
+                }
+            }
+        }
+        final Object instance;
+        try {
+            instance = c.newInstance(cArgs);
+        } catch (Throwable ex) {
+            throw new RuntimeException("Resource or provider class " + c.getDeclaringClass().getName()
+                                       + " can not be instantiated", ex);
+        }
+        Map<Class<?>, ThreadLocalProxy<?>> proxies =
+            new LinkedHashMap<>();
+        for (int i = 0; i < paramTypes.length; i++) {
+            if (cArgs[i] instanceof ThreadLocalProxy) {
+                @SuppressWarnings("unchecked")
+                ThreadLocalProxy<Object> proxy = (ThreadLocalProxy<Object>)cArgs[i];
+                proxies.put(paramTypes[i], proxy);
+            }
+        }
+        boolean isApplication = Application.class.isAssignableFrom(c.getDeclaringClass());
+        if (isApplication) {
+            return new ApplicationInfo((Application)instance, proxies, theBus);
+        }
+        return new ProviderInfo<Object>(instance, proxies, theBus, checkContexts, custom);
+    }
+
+    private Message getResponseMessage(Message message) {
+        Message responseMessage = message.getExchange().getInMessage();
+        if (responseMessage == null) {
+            responseMessage = message.getExchange().getInFaultMessage();
+        }
+
+        return responseMessage;
+    }
+
+    protected static class NameKey {
+        private String name;
+        private Integer priority;
+        private Class<?> providerCls;
+        private ProviderInfo<?> providerInfo;
+
+        public NameKey(String name,
+                       int priority,
+                       Class<?> providerCls) {
+
+            this(name, priority, providerCls, null);
+        }
+
+        public NameKey(String name,
+                       int priority,
+                       Class<?> providerCls,
+                       ProviderInfo<?> provider) {
+
+            this.name = name;
+            this.priority = priority;
+            this.providerCls = providerCls;
+            this.providerInfo = provider;
+        }
+
+        public String getName() {
+            return name;
+        }
+
+        public Integer getPriority() {
+            return priority;
+        }
+
+        public ProviderInfo<?> getProviderInfo() {
+            return providerInfo;
+        }
+
+        public boolean equals(Object o) {
+            if (!(o instanceof NameKey)) {
+                return false;
+            }
+            NameKey other = (NameKey)o;
+            return name.equals(other.name) && priority.equals(other.priority)
+                && providerCls == other.providerCls;
+        }
+
+        public int hashCode() {
+            return super.hashCode();
+        }
+
+        public String toString() {
+            return name + ":" + priority;
+        }
+    }
+
+    protected static <T> void mapInterceptorFilters(Map<NameKey, ProviderInfo<T>> map,
+                                                    List<ProviderInfo<T>> filters,
+                                                    Class<?> providerCls,
+                                                    boolean ascending) {
+
+        for (ProviderInfo<T> p : filters) {
+            Set<String> names = getFilterNameBindings(p);
+
+            int priority = getFilterPriority(p, providerCls);
+
+            for (String name : names) {
+                map.put(new NameKey(name, priority, p.getClass(), p), p);
+            }
+        }
+
+    }
+
+    protected static Set<String> getFilterNameBindings(ProviderInfo<?> p) {
+        if (p instanceof FilterProviderInfo) {
+            return ((FilterProviderInfo<?>)p).getNameBindings();
+        } else {
+            return getFilterNameBindings(p.getBus(), p.getProvider());
+        }
+
+    }
+    protected static Set<String> getFilterNameBindings(Bus bus, Object provider) {
+        Set<String> names = AnnotationUtils.getInstanceNameBindings(bus, provider);
+        if (names.isEmpty()) {
+            names = Collections.singleton(DEFAULT_FILTER_NAME_BINDING);
+        }
+        return names;
+    }
+
+    protected static int getFilterPriority(ProviderInfo<?> p, Class<?> providerCls) {
+        return p instanceof FilterProviderInfo ? ((FilterProviderInfo<?>)p).getPriority(providerCls)
+            : AnnotationUtils.getBindingPriority(p.getProvider().getClass());
+    }
+
+    protected static class NameKeyComparator extends AbstractPriorityComparator
+        implements Comparator<NameKey> {
+
+        private final Comparator<ProviderInfo<?>> comparator;
+
+        public NameKeyComparator(boolean ascending) {
+            this(null, ascending);
+        }
+
+        public NameKeyComparator(
+            Comparator<ProviderInfo<?>> comparator, boolean ascending) {
+
+            super(ascending);
+            this.comparator = comparator;
+        }
+
+        @Override
+        public int compare(NameKey key1, NameKey key2) {
+            int result = compare(key1.getPriority(), key2.getPriority());
+            if (result != 0) {
+                return result;
+            }
+
+            if (comparator != null) {
+                result = comparator.compare(
+                    key1.getProviderInfo(), key2.getProviderInfo());
+
+                if (result != 0) {
+                    return result;
+                }
+            }
+
+            return compare(key1.hashCode(), key2.hashCode());
+        }
+    }
+
+    protected static class NameKeyMap<T> extends TreeMap<NameKey, T> {
+        private static final long serialVersionUID = -4352258671270502204L;
+
+        public NameKeyMap(
+            Comparator<ProviderInfo<?>> comparator, boolean ascending) {
+
+            super(new NameKeyComparator(comparator, ascending));
+        }
+
+        public NameKeyMap(boolean ascending) {
+            super(new NameKeyComparator(ascending));
+        }
+    }
+
+    protected static boolean filterContractSupported(ProviderInfo<?> provider,
+                                                     Class<?> providerCls,
+                                                     Class<?> contract) {
+        boolean result = false;
+        if (contract.isAssignableFrom(providerCls)) {
+            Set<Class<?>> actualContracts = null;
+            if (provider instanceof FilterProviderInfo) {
+                actualContracts = ((FilterProviderInfo<?>)provider).getSupportedContracts();
+            }
+            if (actualContracts != null) {
+                result = actualContracts.contains(contract);
+            } else {
+                result = true;
+            }
+        }
+        return result;
+    }
+
+    protected List<ProviderInfo<? extends Object>> prepareProviders(boolean custom,
+                                                                    boolean busGlobal,
+                                                                    Object[] providers,
+                                                                    ProviderInfo<Application> application) {
+        List<ProviderInfo<? extends Object>> theProviders =
+            new ArrayList<>(providers.length);
+        for (Object o : providers) {
+            if (o == null) {
+                continue;
+            }
+            Object provider = o;
+            if (provider.getClass() == Class.class) {
+                provider = ResourceUtils.createProviderInstance((Class<?>)provider);
+            }
+            if (provider instanceof Constructor) {
+                Map<Class<?>, Object> values = CastUtils.cast(application == null ? null
+                    : Collections.singletonMap(Application.class, application.getProvider()));
+                theProviders.add(
+                    createProviderFromConstructor((Constructor<?>)provider, values, getBus(), true, custom));
+            } else if (provider instanceof ProviderInfo) {
+                theProviders.add((ProviderInfo<?>)provider);
+            } else {
+                ProviderInfo<Object> theProvider = new ProviderInfo<>(provider, getBus(), custom);
+                theProvider.setBusGlobal(busGlobal);
+                theProviders.add(theProvider);
+            }
+        }
+        return theProviders;
+    }
+
+    public MessageBodyWriter<?> getDefaultJaxbWriter() {
+        for (ProviderInfo<MessageBodyWriter<?>> pi : this.messageWriters) {
+            Class<?> cls = pi.getProvider().getClass();
+            if (cls.getName().equals(JAXB_PROVIDER_NAME)) {
+                return pi.getProvider();
+            }
+        }
+        return null;
+    }
+
+    @SuppressWarnings("unchecked")
+    public void setProviderComparator(Comparator<?> providerComparator) {
+        this.providerComparator = providerComparator;
+
+        sortReaders();
+        sortWriters();
+
+        NameKeyMap<ProviderInfo<ReaderInterceptor>> sortedReaderInterceptors =
+            new NameKeyMap<>(
+                (Comparator<ProviderInfo<?>>) providerComparator, true);
+        sortedReaderInterceptors.putAll(readerInterceptors);
+        NameKeyMap<ProviderInfo<WriterInterceptor>> sortedWriterInterceptors =
+            new NameKeyMap<>(
+                (Comparator<ProviderInfo<?>>) providerComparator, true);
+        sortedWriterInterceptors.putAll(writerInterceptors);
+
+        readerInterceptors = sortedReaderInterceptors;
+        writerInterceptors = sortedWriterInterceptors;
+    }
+
+}

[tomee-jakarta] 03/03: Merge branch 'master' of github.com:apache/tomee-jakarta

Posted by db...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

dblevins pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/tomee-jakarta.git

commit 9350edb14d52988b17d8a365b4c0b55e45b17e0c
Merge: 485ee2b 4f04f07
Author: David Blevins <da...@gmail.com>
AuthorDate: Sun Apr 25 00:58:45 2021 -0700

    Merge branch 'master' of github.com:apache/tomee-jakarta

 pom.xml                                 |  3 ++-
 tomee/tomee-microprofile-webapp/pom.xml | 20 ++++++++++++++++++--
 tomee/tomee-plume-webapp/pom.xml        | 20 ++++++++++++++++++--
 tomee/tomee-plus-webapp/pom.xml         | 20 ++++++++++++++++++--
 tomee/tomee-webprofile-webapp/pom.xml   | 20 ++++++++++++++++++--
 5 files changed, 74 insertions(+), 9 deletions(-)

[tomee-jakarta] 02/03: TOMEE-3730 Add JSONP and JSONB Providers JAX-RS Client

Posted by db...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

dblevins pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/tomee-jakarta.git

commit 485ee2ba6bba2960cf12d6c18e6480fd0e948bfe
Author: David Blevins <da...@gmail.com>
AuthorDate: Sun Apr 25 00:55:54 2021 -0700

    TOMEE-3730 Add JSONP and JSONB Providers JAX-RS Client
---
 .../patch/java/org/apache/cxf/jaxrs/provider/ProviderFactory.java   | 6 ++++++
 1 file changed, 6 insertions(+)

diff --git a/transform/src/patch/java/org/apache/cxf/jaxrs/provider/ProviderFactory.java b/transform/src/patch/java/org/apache/cxf/jaxrs/provider/ProviderFactory.java
index 673243d..ffd8083 100644
--- a/transform/src/patch/java/org/apache/cxf/jaxrs/provider/ProviderFactory.java
+++ b/transform/src/patch/java/org/apache/cxf/jaxrs/provider/ProviderFactory.java
@@ -154,6 +154,10 @@ public abstract class ProviderFactory {
         new LazyProviderClass(JAXB_PROVIDER_NAME);
     private static final LazyProviderClass JAXB_ELEMENT_PROVIDER_CLASS =
         new LazyProviderClass("org.apache.cxf.jaxrs.provider.JAXBElementTypedProvider");
+    private static final LazyProviderClass JSONB_PROVIDER_CLASS =
+        new LazyProviderClass("org.apache.openejb.server.cxf.rs.johnzon.TomEEJsonbProvider");
+    private static final LazyProviderClass JSONP_PROVIDER_CLASS =
+        new LazyProviderClass("org.apache.openejb.server.cxf.rs.johnzon.TomEEJsonpProvider");
     private static final LazyProviderClass MULTIPART_PROVIDER_CLASS =
         new LazyProviderClass("org.apache.cxf.jaxrs.provider.MultipartProvider");
 
@@ -214,6 +218,8 @@ public abstract class ProviderFactory {
                      new PrimitiveTextProvider<Object>(),
                      JAXB_PROVIDER_CLASS.tryCreateInstance(factory.getBus()),
                      JAXB_ELEMENT_PROVIDER_CLASS.tryCreateInstance(factory.getBus()),
+                     JSONP_PROVIDER_CLASS.tryCreateInstance(factory.getBus()),
+                     JSONB_PROVIDER_CLASS.tryCreateInstance(factory.getBus()),
                      MULTIPART_PROVIDER_CLASS.tryCreateInstance(factory.getBus()));
         Object prop = factory.getBus().getProperty("skip.default.json.provider.registration");
         if (!PropertyUtils.isTrue(prop)) {