You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@cxf.apache.org by se...@apache.org on 2013/05/03 22:30:47 UTC
svn commit: r1478963 - in /cxf/trunk:
rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/impl/
rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/interceptor/
rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/provider/
rt/frontend/jaxrs/src/main...
Author: sergeyb
Date: Fri May 3 20:30:47 2013
New Revision: 1478963
URL: http://svn.apache.org/r1478963
Log:
[CXF-5000] Uodating the way reader and writer interceptors are selected
Modified:
cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/impl/ResponseImpl.java
cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/interceptor/JAXRSOutInterceptor.java
cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/provider/ProviderFactory.java
cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/provider/ServerProviderFactory.java
cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/utils/JAXRSUtils.java
cxf/trunk/rt/frontend/jaxrs/src/test/java/org/apache/cxf/jaxrs/utils/JAXRSUtilsTest.java
cxf/trunk/rt/rs/client/src/main/java/org/apache/cxf/jaxrs/client/AbstractClient.java
cxf/trunk/rt/rs/client/src/main/java/org/apache/cxf/jaxrs/client/ClientProviderFactory.java
cxf/trunk/systests/jaxrs/src/test/java/org/apache/cxf/systest/jaxrs/BookServer20.java
cxf/trunk/systests/jaxrs/src/test/java/org/apache/cxf/systest/jaxrs/BookStore.java
cxf/trunk/systests/jaxrs/src/test/java/org/apache/cxf/systest/jaxrs/JAXRS20ClientServerBookTest.java
Modified: cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/impl/ResponseImpl.java
URL: http://svn.apache.org/viewvc/cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/impl/ResponseImpl.java?rev=1478963&r1=1478962&r2=1478963&view=diff
==============================================================================
--- cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/impl/ResponseImpl.java (original)
+++ cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/impl/ResponseImpl.java Fri May 3 20:30:47 2013
@@ -315,7 +315,8 @@ public final class ResponseImpl extends
List<ReaderInterceptor> readers = ProviderFactory.getInstance(responseMessage)
.createMessageBodyReaderInterceptor(cls, t, anns, mediaType,
- responseMessage.getExchange().getOutMessage());
+ responseMessage.getExchange().getOutMessage(),
+ null);
if (readers != null) {
try {
responseMessage.put(Message.PROTOCOL_HEADERS, this.getMetadata());
Modified: cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/interceptor/JAXRSOutInterceptor.java
URL: http://svn.apache.org/viewvc/cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/interceptor/JAXRSOutInterceptor.java?rev=1478963&r1=1478962&r2=1478963&view=diff
==============================================================================
--- cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/interceptor/JAXRSOutInterceptor.java (original)
+++ cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/interceptor/JAXRSOutInterceptor.java Fri May 3 20:30:47 2013
@@ -245,7 +245,8 @@ public class JAXRSOutInterceptor extends
annotations = ((ResponseImpl)response).getEntityAnnotations();
List<WriterInterceptor> writers = providerFactory
- .createMessageBodyWriterInterceptor(targetType, genericType, annotations, responseMediaType, message);
+ .createMessageBodyWriterInterceptor(targetType, genericType, annotations, responseMediaType, message,
+ ori == null ? null : ori.getNameBindings());
OutputStream outOriginal = message.getContent(OutputStream.class);
if (writers == null || writers.isEmpty()) {
Modified: cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/provider/ProviderFactory.java
URL: http://svn.apache.org/viewvc/cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/provider/ProviderFactory.java?rev=1478963&r1=1478962&r2=1478963&view=diff
==============================================================================
--- cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/provider/ProviderFactory.java (original)
+++ cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/provider/ProviderFactory.java Fri May 3 20:30:47 2013
@@ -31,6 +31,7 @@ import java.util.Collections;
import java.util.Comparator;
import java.util.HashMap;
import java.util.HashSet;
+import java.util.LinkedHashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
@@ -41,6 +42,7 @@ import javax.ws.rs.Produces;
import javax.ws.rs.core.Application;
import javax.ws.rs.core.HttpHeaders;
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;
@@ -58,6 +60,7 @@ 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.HttpHeadersImpl;
+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;
@@ -82,10 +85,10 @@ public abstract class ProviderFactory {
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";
- protected List<ProviderInfo<ReaderInterceptor>> readerInterceptors =
- new ArrayList<ProviderInfo<ReaderInterceptor>>(1);
- protected List<ProviderInfo<WriterInterceptor>> writerInterceptors =
- new ArrayList<ProviderInfo<WriterInterceptor>>(1);
+ protected Map<NameKey, ProviderInfo<ReaderInterceptor>> readerInterceptors =
+ new LinkedHashMap<NameKey, ProviderInfo<ReaderInterceptor>>();
+ protected Map<NameKey, ProviderInfo<WriterInterceptor>> writerInterceptors =
+ new LinkedHashMap<NameKey, ProviderInfo<WriterInterceptor>>();
private List<ProviderInfo<MessageBodyReader<?>>> messageReaders =
new ArrayList<ProviderInfo<MessageBodyReader<?>>>();
@@ -317,7 +320,8 @@ public abstract class ProviderFactory {
Type parameterType,
Annotation[] parameterAnnotations,
MediaType mediaType,
- Message m) {
+ Message m,
+ List<String> names) {
MessageBodyReader<T> mr = createMessageBodyReader(bodyType,
parameterType,
parameterAnnotations,
@@ -330,7 +334,9 @@ public abstract class ProviderFactory {
List<ReaderInterceptor> interceptors = null;
if (size > 0) {
interceptors = new ArrayList<ReaderInterceptor>(size + 1);
- for (ProviderInfo<ReaderInterceptor> p : readerInterceptors) {
+ List<ProviderInfo<ReaderInterceptor>> readers =
+ getPostMatchContainerFilters(readerInterceptors, names);
+ for (ProviderInfo<ReaderInterceptor> p : readers) {
InjectionUtils.injectContexts(p.getProvider(), p, m);
interceptors.add(p.getProvider());
}
@@ -349,7 +355,8 @@ public abstract class ProviderFactory {
Type parameterType,
Annotation[] parameterAnnotations,
MediaType mediaType,
- Message m) {
+ Message m,
+ List<String> names) {
MessageBodyWriter<T> mw = createMessageBodyWriter(bodyType,
parameterType,
parameterAnnotations,
@@ -366,7 +373,9 @@ public abstract class ProviderFactory {
List<WriterInterceptor> interceptors = null;
if (size > 0) {
interceptors = new ArrayList<WriterInterceptor>(size + 1);
- for (ProviderInfo<WriterInterceptor> p : writerInterceptors) {
+ List<ProviderInfo<WriterInterceptor>> writers =
+ getPostMatchContainerFilters(writerInterceptors, names);
+ for (ProviderInfo<WriterInterceptor> p : writers) {
InjectionUtils.injectContexts(p.getProvider(), p, m);
interceptors.add(p.getProvider());
}
@@ -462,28 +471,16 @@ public abstract class ProviderFactory {
}
}
- //CHECKSTYLE:OFF
+ protected abstract void setProviders(Object... providers);
+
@SuppressWarnings("unchecked")
- protected void setProviders(Object... providers) {
-
- for (Object o : providers) {
- if (o == null) {
- continue;
- }
-
- ProviderInfo<? extends Object> provider = null;
- Class<?> providerCls = null;
- Object realObject = null;
- if (o instanceof ProviderInfo) {
- provider = (ProviderInfo<? extends Object>)o;
- providerCls = provider.getProvider().getClass();
- realObject = provider;
- } else {
- providerCls = ClassHelper.getRealClass(o);
- provider = new ProviderInfo<Object>(o, getBus());
- realObject = o;
- }
-
+ protected void setCommonProviders(List<ProviderInfo<? extends Object>> theProviders) {
+ List<ProviderInfo<ReaderInterceptor>> readInts =
+ new LinkedList<ProviderInfo<ReaderInterceptor>>();
+ List<ProviderInfo<WriterInterceptor>> writeInts =
+ new LinkedList<ProviderInfo<WriterInterceptor>>();
+ for (ProviderInfo<? extends Object> provider : theProviders) {
+ Class<?> providerCls = ClassHelper.getRealClass(provider.getProvider());
if (MessageBodyReader.class.isAssignableFrom(providerCls)) {
messageReaders.add((ProviderInfo<MessageBodyReader<?>>)provider);
@@ -502,16 +499,16 @@ public abstract class ProviderFactory {
}
if (ReaderInterceptor.class.isAssignableFrom(providerCls)) {
- readerInterceptors.add((ProviderInfo<ReaderInterceptor>)provider);
+ readInts.add((ProviderInfo<ReaderInterceptor>)provider);
}
if (WriterInterceptor.class.isAssignableFrom(providerCls)) {
- writerInterceptors.add((ProviderInfo<WriterInterceptor>)provider);
+ writeInts.add((ProviderInfo<WriterInterceptor>)provider);
}
if (ParamConverterProvider.class.isAssignableFrom(providerCls)) {
//TODO: review the possibility of ParamConverterProvider needing to have Contexts injected
- Object converter = realObject == provider ? provider.getProvider() : realObject;
+ Object converter = provider.getProvider();
newParamConverter = (ParamConverterProvider)converter;
}
}
@@ -519,13 +516,12 @@ public abstract class ProviderFactory {
sortWriters();
sortContextResolvers();
- Collections.sort(readerInterceptors, new BindingPriorityComparator(true));
- Collections.sort(writerInterceptors, new BindingPriorityComparator(false));
+ mapContainerFilters(readerInterceptors, readInts, true);
+ mapContainerFilters(writerInterceptors, writeInts, true);
injectContextProxies(messageReaders, messageWriters, contextResolvers,
- readerInterceptors, writerInterceptors);
+ readerInterceptors.values(), writerInterceptors.values());
}
- //CHECKSTYLE:ON
protected void injectContextValues(ProviderInfo<?> pi, Message m) {
if (m != null) {
@@ -808,6 +804,8 @@ public abstract class ProviderFactory {
messageWriters.clear();
contextResolvers.clear();
contextProviders.clear();
+ readerInterceptors.clear();
+ writerInterceptors.clear();
}
public void setBus(Bus bus) {
@@ -846,6 +844,35 @@ public abstract class ProviderFactory {
}
}
+ protected static <T> List<ProviderInfo<T>> getPostMatchContainerFilters(Map<NameKey, ProviderInfo<T>> boundFilters,
+ List<String> names) {
+ if (boundFilters.isEmpty()) {
+ return Collections.emptyList();
+ }
+ names = names == null ? Collections.<String>emptyList() : names;
+
+ MultivaluedMap<ProviderInfo<T>, String> map =
+ new MetadataMap<ProviderInfo<T>, String>();
+ for (Map.Entry<NameKey, ProviderInfo<T>> entry : boundFilters.entrySet()) {
+ String entryName = entry.getKey().getName();
+ if (entryName.equals(DEFAULT_FILTER_NAME_BINDING)) {
+ ProviderInfo<T> provider = entry.getValue();
+ map.put(provider, Collections.<String>emptyList());
+ } else {
+ map.add(entry.getValue(), entryName);
+ }
+ }
+ List<ProviderInfo<T>> list = new LinkedList<ProviderInfo<T>>();
+ 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) {
@@ -972,7 +999,7 @@ public abstract class ProviderFactory {
}
}
- protected ProviderInfo<Object> createProviderFromConstructor(Constructor<?> c,
+ protected ProviderInfo<? extends Object> createProviderFromConstructor(Constructor<?> c,
Map<Class<?>, Object> values) {
Object[] cArgs = ResourceUtils.createConstructorArguments(c, null, false, values);
Object instance = null;
@@ -994,4 +1021,80 @@ public abstract class ProviderFactory {
}
return new ProviderInfo<Object>(instance, proxies, getBus());
}
+
+ protected static class NameKey {
+ private String name;
+ private int bindingPriority;
+ public NameKey(String name, int priority) {
+ this.name = name;
+ this.bindingPriority = priority;
+ }
+
+ public String getName() {
+ return name;
+ }
+
+ public int getPriority() {
+ return bindingPriority;
+ }
+ }
+
+ protected static <T> void mapContainerFilters(Map<NameKey, ProviderInfo<T>> map,
+ List<ProviderInfo<T>> postMatchFilters,
+ boolean ascending) {
+
+ Collections.sort(postMatchFilters, new PostMatchFilterComparator(ascending));
+ for (ProviderInfo<T> p : postMatchFilters) {
+ List<String> names = AnnotationUtils.getNameBindings(
+ p.getProvider().getClass().getAnnotations());
+ names = names.isEmpty() ? Collections.singletonList(DEFAULT_FILTER_NAME_BINDING) : names;
+ for (String name : names) {
+ map.put(new NameKey(name, AnnotationUtils.getBindingPriority(p.getProvider().getClass())),
+ p);
+ }
+ }
+
+ }
+
+ protected static class PostMatchFilterComparator extends BindingPriorityComparator {
+ public PostMatchFilterComparator(boolean ascending) {
+ super(ascending);
+ }
+
+ @Override
+ public int compare(ProviderInfo<?> p1, ProviderInfo<?> p2) {
+ int result = super.compare(p1, p2);
+ if (result == 0) {
+ Integer namesSize1 =
+ AnnotationUtils.getNameBindings(p1.getProvider().getClass().getAnnotations()).size();
+ Integer namesSize2 =
+ AnnotationUtils.getNameBindings(p2.getProvider().getClass().getAnnotations()).size();
+
+ // if we have two filters with the same binding priority,
+ // then put a filter with more name bindings upfront
+ // (this effectively puts name bound filters before global ones)
+ result = namesSize1.compareTo(namesSize2) * -1;
+ }
+ return result;
+ }
+ }
+
+ protected List<ProviderInfo<? extends Object>> prepareProviders(Object[] providers,
+ ProviderInfo<Application> application) {
+ List<ProviderInfo<? extends Object>> theProviders =
+ new ArrayList<ProviderInfo<? extends Object>>(providers.length);
+ for (Object o : providers) {
+ if (o == null) {
+ continue;
+ }
+ if (o instanceof Constructor) {
+ Map<Class<?>, Object> values = CastUtils.cast(application == null ? null
+ : Collections.singletonMap(Application.class, application.getProvider()));
+ theProviders.add(createProviderFromConstructor((Constructor<?>)o, values));
+ } else {
+ theProviders.add(new ProviderInfo<Object>(o, getBus()));
+ }
+ }
+ return theProviders;
+ }
}
Modified: cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/provider/ServerProviderFactory.java
URL: http://svn.apache.org/viewvc/cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/provider/ServerProviderFactory.java?rev=1478963&r1=1478962&r2=1478963&view=diff
==============================================================================
--- cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/provider/ServerProviderFactory.java (original)
+++ cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/provider/ServerProviderFactory.java Fri May 3 20:30:47 2013
@@ -18,7 +18,6 @@
*/
package org.apache.cxf.jaxrs.provider;
-import java.lang.reflect.Constructor;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
@@ -41,7 +40,6 @@ import javax.ws.rs.core.Application;
import javax.ws.rs.core.Configuration;
import javax.ws.rs.core.Feature;
import javax.ws.rs.core.FeatureContext;
-import javax.ws.rs.core.MultivaluedMap;
import javax.ws.rs.ext.ExceptionMapper;
import javax.ws.rs.ext.ReaderInterceptor;
import javax.ws.rs.ext.WriterInterceptor;
@@ -50,8 +48,6 @@ import org.apache.cxf.Bus;
import org.apache.cxf.BusFactory;
import org.apache.cxf.common.util.ClassHelper;
import org.apache.cxf.endpoint.Endpoint;
-import org.apache.cxf.helpers.CastUtils;
-import org.apache.cxf.jaxrs.impl.MetadataMap;
import org.apache.cxf.jaxrs.impl.RequestPreprocessor;
import org.apache.cxf.jaxrs.impl.ResourceInfoImpl;
import org.apache.cxf.jaxrs.impl.WebApplicationExceptionMapper;
@@ -159,35 +155,6 @@ public final class ServerProviderFactory
names);
}
- private static <T> List<ProviderInfo<T>> getPostMatchContainerFilters(Map<NameKey, ProviderInfo<T>> boundFilters,
- List<String> names) {
- if (boundFilters.isEmpty()) {
- return Collections.emptyList();
- }
- names = names == null ? Collections.<String>emptyList() : names;
-
- MultivaluedMap<ProviderInfo<T>, String> map =
- new MetadataMap<ProviderInfo<T>, String>();
- for (Map.Entry<NameKey, ProviderInfo<T>> entry : boundFilters.entrySet()) {
- String entryName = entry.getKey().getName();
- if (entryName.equals(DEFAULT_FILTER_NAME_BINDING)) {
- ProviderInfo<T> provider = entry.getValue();
- map.put(provider, Collections.<String>emptyList());
- } else {
- map.add(entry.getValue(), entryName);
- }
- }
- List<ProviderInfo<T>> list = new LinkedList<ProviderInfo<T>>();
- 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 addBeanParamInfo(BeanParamInfo bpi) {
beanParams.put(bpi.getResourceClass(), bpi);
}
@@ -221,7 +188,6 @@ public final class ServerProviderFactory
return (ExceptionMapper<T>) candidates.get(0);
}
- //CHECKSTYLE:OFF
@SuppressWarnings("unchecked")
@Override
protected void setProviders(Object... providers) {
@@ -230,25 +196,11 @@ public final class ServerProviderFactory
List<ProviderInfo<ContainerResponseFilter>> postMatchResponseFilters =
new LinkedList<ProviderInfo<ContainerResponseFilter>>();
- for (Object o : providers) {
- if (o == null) {
- continue;
- }
- ProviderInfo<? extends Object> provider = null;
- Class<?> providerCls = null;
- Object realObject = null;
- if (o instanceof Constructor) {
- Map<Class<?>, Object> values = CastUtils.cast(application == null ? null
- : Collections.singletonMap(Application.class, application.getProvider()));
- provider = createProviderFromConstructor((Constructor<?>)o, values);
- providerCls = provider.getProvider().getClass();
- realObject = provider;
- } else {
- providerCls = ClassHelper.getRealClass(o);
- provider = new ProviderInfo<Object>(o, getBus());
- realObject = o;
- }
- super.setProviders(realObject);
+ List<ProviderInfo<? extends Object>> theProviders =
+ prepareProviders((Object[])providers, application);
+ super.setCommonProviders(theProviders);
+ for (ProviderInfo<? extends Object> provider : theProviders) {
+ Class<?> providerCls = ClassHelper.getRealClass(provider.getProvider());
if (ContainerRequestFilter.class.isAssignableFrom(providerCls)) {
addContainerRequestFilter(postMatchRequestFilters,
@@ -261,7 +213,7 @@ public final class ServerProviderFactory
if (DynamicFeature.class.isAssignableFrom(providerCls)) {
//TODO: review the possibility of DynamicFeatures needing to have Contexts injected
- Object feature = realObject == provider ? provider.getProvider() : realObject;
+ Object feature = provider.getProvider();
dynamicFeatures.add((DynamicFeature)feature);
}
@@ -276,13 +228,10 @@ public final class ServerProviderFactory
mapContainerFilters(postMatchContainerRequestFilters, postMatchRequestFilters, true);
mapContainerFilters(postMatchContainerResponseFilters, postMatchResponseFilters, false);
- injectContextProxies(
- exceptionMappers,
+ injectContextProxies(exceptionMappers,
postMatchContainerRequestFilters.values(), preMatchContainerRequestFilters,
- postMatchContainerResponseFilters.values(),
- readerInterceptors, writerInterceptors);
+ postMatchContainerResponseFilters.values());
}
-//CHECKSTYLE:ON
@Override
protected void injectContextProxiesIntoProvider(ProviderInfo<?> pi) {
@@ -380,62 +329,7 @@ public final class ServerProviderFactory
return AnnotationUtils.getClassAnnotation(filterCls, PreMatching.class) != null;
}
- private static <T> void mapContainerFilters(Map<NameKey, ProviderInfo<T>> map,
- List<ProviderInfo<T>> postMatchFilters,
- boolean ascending) {
-
- Collections.sort(postMatchFilters, new PostMatchFilterComparator(ascending));
- for (ProviderInfo<T> p : postMatchFilters) {
- List<String> names = AnnotationUtils.getNameBindings(
- p.getProvider().getClass().getAnnotations());
- names = names.isEmpty() ? Collections.singletonList(DEFAULT_FILTER_NAME_BINDING) : names;
- for (String name : names) {
- map.put(new NameKey(name, AnnotationUtils.getBindingPriority(p.getProvider().getClass())),
- p);
- }
- }
-
- }
-
- private static class PostMatchFilterComparator extends BindingPriorityComparator {
- public PostMatchFilterComparator(boolean ascending) {
- super(ascending);
- }
-
- @Override
- public int compare(ProviderInfo<?> p1, ProviderInfo<?> p2) {
- int result = super.compare(p1, p2);
- if (result == 0) {
- Integer namesSize1 =
- AnnotationUtils.getNameBindings(p1.getProvider().getClass().getAnnotations()).size();
- Integer namesSize2 =
- AnnotationUtils.getNameBindings(p2.getProvider().getClass().getAnnotations()).size();
-
- // if we have two filters with the same binding priority,
- // then put a filter with more name bindings upfront
- // (this effectively puts name bound filters before global ones)
- result = namesSize1.compareTo(namesSize2) * -1;
- }
- return result;
- }
- }
- private static class NameKey {
- private String name;
- private int bindingPriority;
- public NameKey(String name, int priority) {
- this.name = name;
- this.bindingPriority = priority;
- }
-
- public String getName() {
- return name;
- }
-
- public int getPriority() {
- return bindingPriority;
- }
- }
private class MethodConfigurable implements FeatureContext, Configuration {
@@ -530,10 +424,14 @@ public final class ServerProviderFactory
setIsNeeded = true;
}
if (contract == ReaderInterceptor.class && provider instanceof ReaderInterceptor) {
- addToInterceptors(readerInterceptors, provider, bindingPriority, true);
+ readerInterceptors =
+ addToPostMatching(readerInterceptors, provider, bindingPriority, true);
+ setIsNeeded = true;
}
if (contract == WriterInterceptor.class && provider instanceof WriterInterceptor) {
- addToInterceptors(writerInterceptors, provider, bindingPriority, false);
+ writerInterceptors =
+ addToPostMatching(writerInterceptors, provider, bindingPriority, false);
+ setIsNeeded = true;
}
}
Modified: cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/utils/JAXRSUtils.java
URL: http://svn.apache.org/viewvc/cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/utils/JAXRSUtils.java?rev=1478963&r1=1478962&r2=1478963&view=diff
==============================================================================
--- cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/utils/JAXRSUtils.java (original)
+++ cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/utils/JAXRSUtils.java Fri May 3 20:30:47 2013
@@ -831,7 +831,7 @@ public final class JAXRSUtils {
parameterAnns,
is,
toMediaType(contentType),
- ori.getConsumeTypes(),
+ ori,
message);
} else if (parameter.getType() == ParameterType.CONTEXT) {
return createContextValue(message, parameterType, parameterClass);
@@ -1260,10 +1260,10 @@ public final class JAXRSUtils {
Annotation[] parameterAnnotations,
InputStream is,
MediaType contentType,
- List<MediaType> consumeTypes,
+ OperationResourceInfo ori,
Message m) throws IOException, WebApplicationException {
- List<MediaType> types = JAXRSUtils.intersectMimeTypes(consumeTypes, contentType);
+ List<MediaType> types = JAXRSUtils.intersectMimeTypes(ori.getConsumeTypes(), contentType);
final ProviderFactory pf = ServerProviderFactory.getInstance(m);
for (MediaType type : types) {
@@ -1272,7 +1272,8 @@ public final class JAXRSUtils {
parameterType,
parameterAnnotations,
type,
- m);
+ m,
+ ori.getNameBindings());
if (readers != null) {
try {
return readFromMessageBodyReader(readers,
Modified: cxf/trunk/rt/frontend/jaxrs/src/test/java/org/apache/cxf/jaxrs/utils/JAXRSUtilsTest.java
URL: http://svn.apache.org/viewvc/cxf/trunk/rt/frontend/jaxrs/src/test/java/org/apache/cxf/jaxrs/utils/JAXRSUtilsTest.java?rev=1478963&r1=1478962&r2=1478963&view=diff
==============================================================================
--- cxf/trunk/rt/frontend/jaxrs/src/test/java/org/apache/cxf/jaxrs/utils/JAXRSUtilsTest.java (original)
+++ cxf/trunk/rt/frontend/jaxrs/src/test/java/org/apache/cxf/jaxrs/utils/JAXRSUtilsTest.java Fri May 3 20:30:47 2013
@@ -1488,7 +1488,8 @@ public class JAXRSUtilsTest extends Asse
}
});
- List<Object> params = JAXRSUtils.processParameters(new OperationResourceInfo(m, null),
+ List<Object> params = JAXRSUtils.processParameters(new OperationResourceInfo(m,
+ new ClassResourceInfo(Customer.class)),
new MetadataMap<String, String>(), messageImpl);
assertEquals("3 params should've been identified", 3, params.size());
Modified: cxf/trunk/rt/rs/client/src/main/java/org/apache/cxf/jaxrs/client/AbstractClient.java
URL: http://svn.apache.org/viewvc/cxf/trunk/rt/rs/client/src/main/java/org/apache/cxf/jaxrs/client/AbstractClient.java?rev=1478963&r1=1478962&r2=1478963&view=diff
==============================================================================
--- cxf/trunk/rt/rs/client/src/main/java/org/apache/cxf/jaxrs/client/AbstractClient.java (original)
+++ cxf/trunk/rt/rs/client/src/main/java/org/apache/cxf/jaxrs/client/AbstractClient.java Fri May 3 20:30:47 2013
@@ -424,7 +424,7 @@ public abstract class AbstractClient imp
MediaType contentType = JAXRSUtils.toMediaType(headers.getFirst("Content-Type").toString());
List<WriterInterceptor> writers = ClientProviderFactory.getInstance(outMessage)
- .createMessageBodyWriterInterceptor(theClass, type, anns, contentType, outMessage);
+ .createMessageBodyWriterInterceptor(theClass, type, anns, contentType, outMessage, null);
if (writers != null) {
try {
JAXRSUtils.writeMessageBody(writers,
@@ -495,7 +495,7 @@ public abstract class AbstractClient imp
List<ReaderInterceptor> readers
= ClientProviderFactory.getInstance(outMessage).createMessageBodyReaderInterceptor(
- cls, type, anns, contentType, outMessage);
+ cls, type, anns, contentType, outMessage, null);
if (readers != null) {
try {
responseMessage.put(Message.PROTOCOL_HEADERS, r.getMetadata());
Modified: cxf/trunk/rt/rs/client/src/main/java/org/apache/cxf/jaxrs/client/ClientProviderFactory.java
URL: http://svn.apache.org/viewvc/cxf/trunk/rt/rs/client/src/main/java/org/apache/cxf/jaxrs/client/ClientProviderFactory.java?rev=1478963&r1=1478962&r2=1478963&view=diff
==============================================================================
--- cxf/trunk/rt/rs/client/src/main/java/org/apache/cxf/jaxrs/client/ClientProviderFactory.java (original)
+++ cxf/trunk/rt/rs/client/src/main/java/org/apache/cxf/jaxrs/client/ClientProviderFactory.java Fri May 3 20:30:47 2013
@@ -80,38 +80,31 @@ public final class ClientProviderFactory
}
- //CHECKSTYLE:OFF
+ @SuppressWarnings("unchecked")
@Override
protected void setProviders(Object... providers) {
- super.setProviders(providers);
- for (Object o : providers) {
- if (o == null) {
- continue;
- }
- Class<?> oClass = ClassHelper.getRealClass(o);
- if (ClientRequestFilter.class.isAssignableFrom(oClass)) {
- clientRequestFilters.add(
- new ProviderInfo<ClientRequestFilter>((ClientRequestFilter)o, getBus()));
+ List<ProviderInfo<? extends Object>> theProviders =
+ prepareProviders((Object[])providers, null);
+ super.setCommonProviders(theProviders);
+ for (ProviderInfo<? extends Object> provider : theProviders) {
+ Class<?> providerCls = ClassHelper.getRealClass(provider.getProvider());
+ if (ClientRequestFilter.class.isAssignableFrom(providerCls)) {
+ clientRequestFilters.add((ProviderInfo<ClientRequestFilter>)provider);
}
- if (ClientResponseFilter.class.isAssignableFrom(oClass)) {
- clientResponseFilters.add(
- new ProviderInfo<ClientResponseFilter>((ClientResponseFilter)o, getBus()));
+ if (ClientResponseFilter.class.isAssignableFrom(providerCls)) {
+ clientResponseFilters.add((ProviderInfo<ClientResponseFilter>)provider);
}
- if (ResponseExceptionMapper.class.isAssignableFrom(oClass)) {
- responseExceptionMappers.add(
- new ProviderInfo<ResponseExceptionMapper<?>>((ResponseExceptionMapper<?>)o, getBus()));
+ if (ResponseExceptionMapper.class.isAssignableFrom(providerCls)) {
+ responseExceptionMappers.add((ProviderInfo<ResponseExceptionMapper<?>>)provider);
}
-
-
}
Collections.sort(clientRequestFilters, new BindingPriorityComparator(true));
Collections.sort(clientResponseFilters, new BindingPriorityComparator(false));
injectContextProxies(responseExceptionMappers, clientRequestFilters, clientResponseFilters);
}
-//CHECKSTYLE:ON
@SuppressWarnings("unchecked")
public <T extends Throwable> ResponseExceptionMapper<T> createResponseExceptionMapper(
Modified: cxf/trunk/systests/jaxrs/src/test/java/org/apache/cxf/systest/jaxrs/BookServer20.java
URL: http://svn.apache.org/viewvc/cxf/trunk/systests/jaxrs/src/test/java/org/apache/cxf/systest/jaxrs/BookServer20.java?rev=1478963&r1=1478962&r2=1478963&view=diff
==============================================================================
--- cxf/trunk/systests/jaxrs/src/test/java/org/apache/cxf/systest/jaxrs/BookServer20.java (original)
+++ cxf/trunk/systests/jaxrs/src/test/java/org/apache/cxf/systest/jaxrs/BookServer20.java Fri May 3 20:30:47 2013
@@ -79,6 +79,7 @@ public class BookServer20 extends Abstra
providers.add(new PostMatchContainerResponseFilter());
providers.add(new PostMatchContainerResponseFilter3());
providers.add(new PostMatchContainerResponseFilter2());
+ providers.add(new CustomReaderBoundInterceptor());
providers.add(new CustomReaderInterceptor());
providers.add(new CustomWriterInterceptor());
providers.add(new CustomDynamicFeature());
@@ -325,6 +326,13 @@ public class BookServer20 extends Abstra
@Target({ ElementType.TYPE, ElementType.METHOD })
@Retention(value = RetentionPolicy.RUNTIME)
@NameBinding
+ public @interface CustomHeaderAddedAsync {
+
+ }
+
+ @Target({ ElementType.TYPE, ElementType.METHOD })
+ @Retention(value = RetentionPolicy.RUNTIME)
+ @NameBinding
public @interface PostMatchMode {
}
@@ -336,6 +344,7 @@ public class BookServer20 extends Abstra
}
+ @Priority(1)
public static class CustomReaderInterceptor implements ReaderInterceptor {
@Context
private ResourceInfo ri;
@@ -351,6 +360,31 @@ public class BookServer20 extends Abstra
}
+ @Priority(2)
+ @CustomHeaderAddedAsync
+ public static class CustomReaderBoundInterceptor implements ReaderInterceptor {
+ @Context
+ private ResourceInfo ri;
+ @Context
+ private UriInfo ui;
+ @Override
+ public Object aroundReadFrom(ReaderInterceptorContext context) throws IOException,
+ WebApplicationException {
+ if (ri.getResourceClass() == BookStore.class) {
+ String serverRead = context.getHeaders().getFirst("ServerReaderInterceptor");
+ if (serverRead == null || !serverRead.equals("serverRead")) {
+ throw new RuntimeException();
+ }
+ if (ui.getPath().endsWith("/async")) {
+ context.getHeaders().putSingle("ServerReaderInterceptor", "serverReadAsync");
+ }
+ }
+ return context.proceed();
+
+ }
+
+ }
+
public static class CustomWriterInterceptor implements WriterInterceptor {
@Override
Modified: cxf/trunk/systests/jaxrs/src/test/java/org/apache/cxf/systest/jaxrs/BookStore.java
URL: http://svn.apache.org/viewvc/cxf/trunk/systests/jaxrs/src/test/java/org/apache/cxf/systest/jaxrs/BookStore.java?rev=1478963&r1=1478962&r2=1478963&view=diff
==============================================================================
--- cxf/trunk/systests/jaxrs/src/test/java/org/apache/cxf/systest/jaxrs/BookStore.java (original)
+++ cxf/trunk/systests/jaxrs/src/test/java/org/apache/cxf/systest/jaxrs/BookStore.java Fri May 3 20:30:47 2013
@@ -89,6 +89,7 @@ import org.apache.cxf.jaxrs.ext.xml.XSIS
import org.apache.cxf.jaxrs.impl.ResourceContextImpl;
import org.apache.cxf.phase.PhaseInterceptorChain;
import org.apache.cxf.systest.jaxrs.BookServer20.CustomHeaderAdded;
+import org.apache.cxf.systest.jaxrs.BookServer20.CustomHeaderAddedAsync;
import org.apache.cxf.systest.jaxrs.BookServer20.PostMatchMode;
@Path("/bookstore")
@@ -556,6 +557,21 @@ public class BookStore {
return builder.build();
}
+ @POST
+ @Path("/bookheaders/simple/async")
+ @PostMatchMode
+ @CustomHeaderAdded
+ @CustomHeaderAddedAsync
+ public Response echoBookByHeaderSimpleAsync(Book book,
+ @HeaderParam("BOOK") String headerBook,
+ @HeaderParam("Simple") String headerSimple,
+ @HeaderParam("ServerReaderInterceptor") String serverInterceptorHeader,
+ @HeaderParam("ClientWriterInterceptor") String clientInterceptorHeader)
+ throws Exception {
+
+ return echoBookByHeaderSimple(book, headerBook, headerSimple, serverInterceptorHeader, clientInterceptorHeader);
+ }
+
private ResponseBuilder getBookByHeaderSimpleBuilder(@HeaderParam("BOOK") String headerBook,
@HeaderParam("Simple") String headerSimple) throws Exception {
Modified: cxf/trunk/systests/jaxrs/src/test/java/org/apache/cxf/systest/jaxrs/JAXRS20ClientServerBookTest.java
URL: http://svn.apache.org/viewvc/cxf/trunk/systests/jaxrs/src/test/java/org/apache/cxf/systest/jaxrs/JAXRS20ClientServerBookTest.java?rev=1478963&r1=1478962&r2=1478963&view=diff
==============================================================================
--- cxf/trunk/systests/jaxrs/src/test/java/org/apache/cxf/systest/jaxrs/JAXRS20ClientServerBookTest.java (original)
+++ cxf/trunk/systests/jaxrs/src/test/java/org/apache/cxf/systest/jaxrs/JAXRS20ClientServerBookTest.java Fri May 3 20:30:47 2013
@@ -377,7 +377,7 @@ public class JAXRS20ClientServerBookTest
Book book = future.get();
assertSame(book, holder.value);
assertEquals(124L, book.getId());
- validatePostResponse(wc);
+ validatePostResponse(wc, true);
}
private void doTestGetBookAsyncResponse(String address, boolean asyncInvoker)
@@ -413,10 +413,11 @@ public class JAXRS20ClientServerBookTest
assertEquals("http://localhost/redirect", response.getHeaderString(HttpHeaders.LOCATION));
}
- private void validatePostResponse(WebClient wc) {
+ private void validatePostResponse(WebClient wc, boolean async) {
validateResponse(wc);
Response response = wc.getResponse();
- assertEquals("serverRead", response.getHeaderString("ServerReaderInterceptor"));
+ assertEquals(!async ? "serverRead" : "serverReadAsync",
+ response.getHeaderString("ServerReaderInterceptor"));
assertEquals("clientWrite", response.getHeaderString("ClientWriterInterceptor"));
assertEquals("clientRead", response.getHeaderString("ClientReaderInterceptor"));
}
@@ -442,7 +443,7 @@ public class JAXRS20ClientServerBookTest
WebClient wc = createWebClientPost(address);
Book book = wc.post(new Book("Book", 126L), Book.class);
assertEquals(124L, book.getId());
- validatePostResponse(wc);
+ validatePostResponse(wc, false);
}
@Test
@@ -463,16 +464,16 @@ public class JAXRS20ClientServerBookTest
@Test
public void testPostBookAsync() throws Exception {
- String address = "http://localhost:" + PORT + "/bookstore/bookheaders/simple";
+ String address = "http://localhost:" + PORT + "/bookstore/bookheaders/simple/async";
WebClient wc = createWebClientPost(address);
Future<Book> future = wc.async().post(Entity.xml(new Book("Book", 126L)), Book.class);
assertEquals(124L, future.get().getId());
- validatePostResponse(wc);
+ validatePostResponse(wc, true);
}
@Test
public void testPostBookAsyncHandler() throws Exception {
- String address = "http://localhost:" + PORT + "/bookstore/bookheaders/simple";
+ String address = "http://localhost:" + PORT + "/bookstore/bookheaders/simple/async";
doTestPostBookAsyncHandler(address);
}