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/07/31 23:42:45 UTC
svn commit: r1509043 - in /cxf/trunk:
rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/
rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/model/
rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/provider/
rt/frontend/jaxrs/src/main/java/org/a...
Author: sergeyb
Date: Wed Jul 31 21:42:45 2013
New Revision: 1509043
URL: http://svn.apache.org/r1509043
Log:
[CXF-5135] Related refactoring to get various provider registration options supported
Added:
cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/model/FilterProviderInfo.java (with props)
Modified:
cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/JAXRSServerFactoryBean.java
cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/model/ClassResourceInfo.java
cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/model/OperationResourceInfo.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/AnnotationUtils.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/model/ClassResourceInfoTest.java
cxf/trunk/systests/jaxrs/src/test/java/org/apache/cxf/systest/jaxrs/BookServer20.java
Modified: cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/JAXRSServerFactoryBean.java
URL: http://svn.apache.org/viewvc/cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/JAXRSServerFactoryBean.java?rev=1509043&r1=1509042&r2=1509043&view=diff
==============================================================================
--- cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/JAXRSServerFactoryBean.java (original)
+++ cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/JAXRSServerFactoryBean.java Wed Jul 31 21:42:45 2013
@@ -22,7 +22,7 @@ import java.io.IOException;
import java.util.Arrays;
import java.util.Collections;
import java.util.HashMap;
-import java.util.LinkedList;
+import java.util.LinkedHashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
@@ -101,9 +101,9 @@ public class JAXRSServerFactoryBean exte
*/
public void setApplication(Application app) {
appProvider = new ProviderInfo<Application>(app, getBus());
- List<String> appNameBindings = AnnotationUtils.getNameBindings(app.getClass().getAnnotations());
+ Set<String> appNameBindings = AnnotationUtils.getNameBindings(app.getClass().getAnnotations());
for (ClassResourceInfo cri : getServiceFactory().getClassResourceInfo()) {
- List<String> clsNameBindings = new LinkedList<String>(appNameBindings);
+ Set<String> clsNameBindings = new LinkedHashSet<String>(appNameBindings);
clsNameBindings.addAll(AnnotationUtils.getNameBindings(cri.getServiceClass().getAnnotations()));
cri.setNameBindings(clsNameBindings);
}
Modified: cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/model/ClassResourceInfo.java
URL: http://svn.apache.org/viewvc/cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/model/ClassResourceInfo.java?rev=1509043&r1=1509042&r2=1509043&view=diff
==============================================================================
--- cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/model/ClassResourceInfo.java (original)
+++ cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/model/ClassResourceInfo.java Wed Jul 31 21:42:45 2013
@@ -53,7 +53,7 @@ public class ClassResourceInfo extends B
private boolean createdFromModel;
private String consumesTypes;
private String producesTypes;
- private List<String> nameBindings = Collections.emptyList();
+ private Set<String> nameBindings = Collections.emptySet();
private ClassResourceInfo parent;
private Set<String> injectedSubInstances = new HashSet<String>();
public ClassResourceInfo(ClassResourceInfo cri) {
@@ -188,7 +188,7 @@ public class ClassResourceInfo extends B
return Collections.unmodifiableCollection(subResources.values());
}
- public List<String> getNameBindings() {
+ public Set<String> getNameBindings() {
if (parent == null) {
return nameBindings;
} else {
@@ -196,7 +196,7 @@ public class ClassResourceInfo extends B
}
}
- public void setNameBindings(List<String> names) {
+ public void setNameBindings(Set<String> names) {
nameBindings = names;
}
Added: cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/model/FilterProviderInfo.java
URL: http://svn.apache.org/viewvc/cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/model/FilterProviderInfo.java?rev=1509043&view=auto
==============================================================================
--- cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/model/FilterProviderInfo.java (added)
+++ cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/model/FilterProviderInfo.java Wed Jul 31 21:42:45 2013
@@ -0,0 +1,57 @@
+/**
+ * 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.model;
+
+import java.util.Collections;
+import java.util.List;
+import java.util.Set;
+
+import org.apache.cxf.Bus;
+
+public class FilterProviderInfo<T> extends ProviderInfo<T> {
+
+ private Set<String> nameBinding;
+ private int priority;
+ private List<Class<?>> supportedContracts;
+
+ public FilterProviderInfo(T provider,
+ Bus bus,
+ String nameBinding,
+ int priority,
+ List<Class<?>> supportedContracts) {
+ super(provider, bus);
+ this.nameBinding = Collections.singleton(nameBinding);
+ this.priority = priority;
+ this.supportedContracts = supportedContracts;
+ }
+
+ public Set<String> getNameBinding() {
+ return nameBinding;
+ }
+
+ public int getPriority() {
+ return priority;
+ }
+
+ public List<Class<?>> getSupportedContracts() {
+ return supportedContracts;
+ }
+
+}
Propchange: cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/model/FilterProviderInfo.java
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/model/FilterProviderInfo.java
------------------------------------------------------------------------------
svn:keywords = Rev Date
Modified: cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/model/OperationResourceInfo.java
URL: http://svn.apache.org/viewvc/cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/model/OperationResourceInfo.java?rev=1509043&r1=1509042&r2=1509043&view=diff
==============================================================================
--- cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/model/OperationResourceInfo.java (original)
+++ cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/model/OperationResourceInfo.java Wed Jul 31 21:42:45 2013
@@ -20,9 +20,9 @@
package org.apache.cxf.jaxrs.model;
import java.lang.reflect.Method;
-import java.util.ArrayList;
-import java.util.LinkedList;
+import java.util.LinkedHashSet;
import java.util.List;
+import java.util.Set;
import javax.ws.rs.Consumes;
import javax.ws.rs.DefaultValue;
@@ -47,7 +47,7 @@ public class OperationResourceInfo {
private String defaultParamValue;
private List<Parameter> parameters;
private boolean oneway;
- private List<String> nameBindings = new LinkedList<String>();
+ private Set<String> nameBindings = new LinkedHashSet<String>();
public OperationResourceInfo(Method mInvoke, ClassResourceInfo cri) {
this(mInvoke, mInvoke, cri);
@@ -106,13 +106,12 @@ public class OperationResourceInfo {
nameBindings.addAll(names);
}
- public List<String> getNameBindings() {
- List<String> criNames = classResourceInfo.getNameBindings();
+ public Set<String> getNameBindings() {
+ Set<String> criNames = classResourceInfo.getNameBindings();
if (criNames.isEmpty()) {
return nameBindings;
} else {
- List<String> all = new ArrayList<String>(criNames.size() + nameBindings.size());
- all.addAll(criNames);
+ Set<String> all = new LinkedHashSet<String>(criNames);
all.addAll(nameBindings);
return all;
}
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=1509043&r1=1509042&r2=1509043&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 Wed Jul 31 21:42:45 2013
@@ -31,11 +31,11 @@ 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;
import java.util.Set;
+import java.util.TreeMap;
import java.util.logging.Logger;
import javax.ws.rs.Produces;
@@ -65,6 +65,7 @@ import org.apache.cxf.jaxrs.impl.ReaderI
import org.apache.cxf.jaxrs.impl.WriterInterceptorMBW;
import org.apache.cxf.jaxrs.impl.tl.ThreadLocalProxy;
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;
@@ -87,9 +88,9 @@ public abstract class ProviderFactory {
private static final String BUS_PROVIDERS_ALL = "org.apache.cxf.jaxrs.bus.providers";
protected Map<NameKey, ProviderInfo<ReaderInterceptor>> readerInterceptors =
- new LinkedHashMap<NameKey, ProviderInfo<ReaderInterceptor>>();
+ new NameKeyMap<ProviderInfo<ReaderInterceptor>>(true);
protected Map<NameKey, ProviderInfo<WriterInterceptor>> writerInterceptors =
- new LinkedHashMap<NameKey, ProviderInfo<WriterInterceptor>>();
+ new NameKeyMap<ProviderInfo<WriterInterceptor>>(true);
private List<ProviderInfo<MessageBodyReader<?>>> messageReaders =
new ArrayList<ProviderInfo<MessageBodyReader<?>>>();
@@ -333,7 +334,7 @@ public abstract class ProviderFactory {
Annotation[] parameterAnnotations,
MediaType mediaType,
Message m,
- List<String> names) {
+ Set<String> names) {
MessageBodyReader<T> mr = createMessageBodyReader(bodyType,
parameterType,
parameterAnnotations,
@@ -368,7 +369,7 @@ public abstract class ProviderFactory {
Annotation[] parameterAnnotations,
MediaType mediaType,
Message m,
- List<String> names) {
+ Set<String> names) {
MessageBodyWriter<T> mw = createMessageBodyWriter(bodyType,
parameterType,
parameterAnnotations,
@@ -510,11 +511,11 @@ public abstract class ProviderFactory {
contextProviders.add((ProviderInfo<ContextProvider<?>>)provider);
}
- if (ReaderInterceptor.class.isAssignableFrom(providerCls)) {
+ if (filterContractSupported(provider, providerCls, ReaderInterceptor.class)) {
readInts.add((ProviderInfo<ReaderInterceptor>)provider);
}
- if (WriterInterceptor.class.isAssignableFrom(providerCls)) {
+ if (filterContractSupported(provider, providerCls, WriterInterceptor.class)) {
writeInts.add((ProviderInfo<WriterInterceptor>)provider);
}
@@ -531,8 +532,8 @@ public abstract class ProviderFactory {
sortWriters();
sortContextResolvers();
- mapContainerFilters(readerInterceptors, readInts, true);
- mapContainerFilters(writerInterceptors, writeInts, true);
+ mapInterceptorFilters(readerInterceptors, readInts, true);
+ mapInterceptorFilters(writerInterceptors, writeInts, true);
injectContextProxies(messageReaders, messageWriters, contextResolvers,
readerInterceptors.values(), writerInterceptors.values());
@@ -860,11 +861,11 @@ public abstract class ProviderFactory {
}
protected static <T> List<ProviderInfo<T>> getPostMatchContainerFilters(Map<NameKey, ProviderInfo<T>> boundFilters,
- List<String> names) {
+ Set<String> names) {
if (boundFilters.isEmpty()) {
return Collections.emptyList();
}
- names = names == null ? Collections.<String>emptyList() : names;
+ names = names == null ? Collections.<String>emptySet() : names;
MultivaluedMap<ProviderInfo<T>, String> map =
new MetadataMap<ProviderInfo<T>, String>();
@@ -977,32 +978,32 @@ public abstract class ProviderFactory {
return getGenericInterfaces(cls.getSuperclass(), expectedClass);
}
- protected static class BindingPriorityComparator extends AbstactBindingPriorityComparator {
- public BindingPriorityComparator(boolean ascending) {
- super(ascending);
- }
- }
-
- private abstract static class AbstactBindingPriorityComparator implements
- Comparator<ProviderInfo<?>> {
+ protected static class AbstractPriorityComparator {
private boolean ascending;
- protected AbstactBindingPriorityComparator(boolean ascending) {
+ protected AbstractPriorityComparator(boolean ascending) {
this.ascending = ascending;
}
- public int compare(ProviderInfo<?> p1, ProviderInfo<?> p2) {
- Integer b1Value = getBindingPriorityValue(p1);
- Integer b2Value = getBindingPriorityValue(p2);
-
+ protected int compare(Integer b1Value, Integer b2Value) {
int result = b1Value.compareTo(b2Value);
return ascending ? result : result * -1;
}
- private int getBindingPriorityValue(ProviderInfo<?> p) {
- return AnnotationUtils.getBindingPriority(p.getProvider().getClass());
+ }
+
+ protected static class BindingPriorityComparator extends AbstractPriorityComparator
+ implements Comparator<ProviderInfo<?>> {
+
+ public BindingPriorityComparator(boolean ascending) {
+ super(ascending);
+ }
+
+ public int compare(ProviderInfo<?> p1, ProviderInfo<?> p2) {
+ return compare(getFilterPriority(p1), getFilterPriority(p2));
}
+
}
static class ContextResolverProxy<T> implements ContextResolver<T> {
@@ -1050,7 +1051,7 @@ public abstract class ProviderFactory {
protected static class NameKey {
private String name;
- private int bindingPriority;
+ private Integer bindingPriority;
public NameKey(String name, int priority) {
this.name = name;
this.bindingPriority = priority;
@@ -1060,49 +1061,92 @@ public abstract class ProviderFactory {
return name;
}
- public int getPriority() {
+ public Integer getPriority() {
return bindingPriority;
}
+
+ public String toString() {
+ return name + ":" + 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;
+ protected static <T> void mapInterceptorFilters(Map<NameKey, ProviderInfo<T>> map,
+ List<ProviderInfo<T>> filters,
+ boolean ascending) {
+
+ for (ProviderInfo<T> p : filters) {
+ Set<String> names = getFilterNameBindings(p);
+
+ int priority = getFilterPriority(p);
+
for (String name : names) {
- map.put(new NameKey(name, AnnotationUtils.getBindingPriority(p.getProvider().getClass())),
- p);
+ map.put(new NameKey(name, priority), p);
}
}
}
- protected static class PostMatchFilterComparator extends BindingPriorityComparator {
- public PostMatchFilterComparator(boolean ascending) {
+ protected static Set<String> getFilterNameBindings(ProviderInfo<?> p) {
+ Set<String> names = null;
+ if (p instanceof FilterProviderInfo) {
+ names = ((FilterProviderInfo<?>)p).getNameBinding();
+ }
+ if (names == null) {
+ names = AnnotationUtils.getNameBindings(p.getProvider().getClass().getAnnotations());
+ }
+ if (names.isEmpty()) {
+ names = Collections.singleton(DEFAULT_FILTER_NAME_BINDING);
+ }
+ return names;
+ }
+
+ protected static int getFilterPriority(ProviderInfo<?> p) {
+ return p instanceof FilterProviderInfo ? ((FilterProviderInfo<?>)p).getPriority()
+ : AnnotationUtils.getBindingPriority(p.getProvider().getClass());
+ }
+
+ protected static class NameKeyComparator extends AbstractPriorityComparator
+ implements Comparator<NameKey> {
+
+ public NameKeyComparator(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;
+ public int compare(NameKey key1, NameKey key2) {
+ int result = compare(key1.getPriority(), key2.getPriority());
+ 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(boolean ascending) {
+ super(new NameKeyComparator(ascending));
+ }
+ }
+
+ protected static boolean filterContractSupported(ProviderInfo<?> provider,
+ Class<?> providerCls,
+ Class<?> contract) {
+ boolean result = false;
+ if (contract.isAssignableFrom(providerCls)) {
+ List<Class<?>> actualContracts = null;
+ if (provider instanceof FilterProviderInfo) {
+ actualContracts = ((FilterProviderInfo<?>)provider).getSupportedContracts();
+ }
+ if (actualContracts != null) {
+ result = actualContracts.contains(contract);
+ } else {
+ result = true;
}
- return result;
}
+ return result;
}
protected List<ProviderInfo<? extends Object>> prepareProviders(Object[] providers,
@@ -1117,7 +1161,9 @@ public abstract class ProviderFactory {
Map<Class<?>, Object> values = CastUtils.cast(application == null ? null
: Collections.singletonMap(Application.class, application.getProvider()));
theProviders.add(createProviderFromConstructor((Constructor<?>)o, values));
- } else {
+ } else if (o instanceof ProviderInfo) {
+ theProviders.add((ProviderInfo<?>)o);
+ } else {
theProviders.add(new ProviderInfo<Object>(o, getBus()));
}
}
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=1509043&r1=1509042&r2=1509043&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 Wed Jul 31 21:42:45 2013
@@ -19,11 +19,11 @@
package org.apache.cxf.jaxrs.provider;
import java.util.ArrayList;
+import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
-import java.util.Iterator;
-import java.util.LinkedHashMap;
+import java.util.HashSet;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
@@ -53,6 +53,7 @@ import org.apache.cxf.jaxrs.impl.Resourc
import org.apache.cxf.jaxrs.impl.WebApplicationExceptionMapper;
import org.apache.cxf.jaxrs.model.BeanParamInfo;
import org.apache.cxf.jaxrs.model.ClassResourceInfo;
+import org.apache.cxf.jaxrs.model.FilterProviderInfo;
import org.apache.cxf.jaxrs.model.OperationResourceInfo;
import org.apache.cxf.jaxrs.model.ProviderInfo;
import org.apache.cxf.jaxrs.utils.AnnotationUtils;
@@ -61,11 +62,12 @@ import org.apache.cxf.message.Message;
public final class ServerProviderFactory extends ProviderFactory {
private static final String SHARED_SERVER_FACTORY = "jaxrs.shared.server.factory";
- private static final Class<?>[] SERVER_FILTER_INTERCEPTOR_CLASSES =
- new Class<?>[] {ContainerRequestFilter.class,
- ContainerResponseFilter.class,
- ReaderInterceptor.class,
- WriterInterceptor.class};
+ private static final Set<Class<?>> SERVER_FILTER_INTERCEPTOR_CLASSES =
+ new HashSet<Class<?>>(Arrays.<Class<?>>asList(ContainerRequestFilter.class,
+ ContainerResponseFilter.class,
+ ReaderInterceptor.class,
+ WriterInterceptor.class));
+
private static final String WADL_PROVIDER_NAME = "org.apache.cxf.jaxrs.model.wadl.WadlGenerator";
private List<ProviderInfo<ExceptionMapper<?>>> exceptionMappers =
new ArrayList<ProviderInfo<ExceptionMapper<?>>>(1);
@@ -73,9 +75,9 @@ public final class ServerProviderFactory
private List<ProviderInfo<ContainerRequestFilter>> preMatchContainerRequestFilters =
new ArrayList<ProviderInfo<ContainerRequestFilter>>(1);
private Map<NameKey, ProviderInfo<ContainerRequestFilter>> postMatchContainerRequestFilters =
- new LinkedHashMap<NameKey, ProviderInfo<ContainerRequestFilter>>();
+ new NameKeyMap<ProviderInfo<ContainerRequestFilter>>(true);
private Map<NameKey, ProviderInfo<ContainerResponseFilter>> postMatchContainerResponseFilters =
- new LinkedHashMap<NameKey, ProviderInfo<ContainerResponseFilter>>();
+ new NameKeyMap<ProviderInfo<ContainerResponseFilter>>(false);
private RequestPreprocessor requestPreprocessor;
private ProviderInfo<Application> application;
private List<DynamicFeature> dynamicFeatures = new LinkedList<DynamicFeature>();
@@ -135,7 +137,7 @@ public final class ServerProviderFactory
return getContainerRequestFilters(preMatchContainerRequestFilters, true);
}
- public List<ProviderInfo<ContainerRequestFilter>> getPostMatchContainerRequestFilters(List<String> names) {
+ public List<ProviderInfo<ContainerRequestFilter>> getPostMatchContainerRequestFilters(Set<String> names) {
return getPostMatchContainerFilters(postMatchContainerRequestFilters, names);
}
@@ -162,7 +164,7 @@ public final class ServerProviderFactory
}
}
- public List<ProviderInfo<ContainerResponseFilter>> getContainerResponseFilters(List<String> names) {
+ public List<ProviderInfo<ContainerResponseFilter>> getContainerResponseFilters(Set<String> names) {
return getPostMatchContainerFilters(postMatchContainerResponseFilters,
names);
}
@@ -200,6 +202,7 @@ public final class ServerProviderFactory
return (ExceptionMapper<T>) candidates.get(0);
}
+
@SuppressWarnings("unchecked")
@Override
protected void setProviders(Object... providers) {
@@ -213,13 +216,13 @@ public final class ServerProviderFactory
super.setCommonProviders(theProviders);
for (ProviderInfo<? extends Object> provider : theProviders) {
Class<?> providerCls = ClassHelper.getRealClass(provider.getProvider());
-
- if (ContainerRequestFilter.class.isAssignableFrom(providerCls)) {
+
+ if (filterContractSupported(provider, providerCls, ContainerRequestFilter.class)) {
addContainerRequestFilter(postMatchRequestFilters,
(ProviderInfo<ContainerRequestFilter>)provider);
}
- if (ContainerResponseFilter.class.isAssignableFrom(providerCls)) {
+ if (filterContractSupported(provider, providerCls, ContainerResponseFilter.class)) {
postMatchResponseFilters.add((ProviderInfo<ContainerResponseFilter>)provider);
}
@@ -237,8 +240,8 @@ public final class ServerProviderFactory
}
Collections.sort(preMatchContainerRequestFilters, new BindingPriorityComparator(true));
- mapContainerFilters(postMatchContainerRequestFilters, postMatchRequestFilters, true);
- mapContainerFilters(postMatchContainerResponseFilters, postMatchResponseFilters, false);
+ mapInterceptorFilters(postMatchContainerRequestFilters, postMatchRequestFilters, true);
+ mapInterceptorFilters(postMatchContainerResponseFilters, postMatchResponseFilters, false);
injectContextProxies(exceptionMappers,
postMatchContainerRequestFilters.values(), preMatchContainerRequestFilters,
@@ -358,7 +361,6 @@ public final class ServerProviderFactory
private Configurable<FeatureContext> configImpl;
private OperationResourceInfo ori;
private String nameBinding;
- private boolean bindingSet;
public MethodFeatureContextImpl(OperationResourceInfo ori) {
this.ori = ori;
@@ -420,130 +422,37 @@ public final class ServerProviderFactory
return configImpl.register(object, map);
}
- FeatureContext doRegister(Object provider, int bindingPriority, Class<?>... contracts) {
+ FeatureContext doRegister(Object provider, int priority, Class<?>... contracts) {
if (provider instanceof Feature) {
((Feature)provider).configure(this);
return this;
}
- boolean setIsNeeded = false;
+ List<Class<?>> actualContracts = new LinkedList<Class<?>>();
+
for (Class<?> contract : contracts) {
- if (contract == ContainerRequestFilter.class && provider instanceof ContainerRequestFilter) {
- if (isPrematching(provider.getClass())) {
- addToInterceptors(preMatchContainerRequestFilters, provider, bindingPriority, true);
- } else {
- postMatchContainerRequestFilters =
- addToPostMatching(postMatchContainerRequestFilters, provider, bindingPriority, true);
- setIsNeeded = true;
- }
- }
- if (contract == ContainerResponseFilter.class && provider instanceof ContainerResponseFilter) {
- postMatchContainerResponseFilters =
- addToPostMatching(postMatchContainerResponseFilters, provider, bindingPriority, false);
- setIsNeeded = true;
- }
- if (contract == ReaderInterceptor.class && provider instanceof ReaderInterceptor) {
- readerInterceptors =
- addToPostMatching(readerInterceptors, provider, bindingPriority, true);
- setIsNeeded = true;
- }
- if (contract == WriterInterceptor.class && provider instanceof WriterInterceptor) {
- writerInterceptors =
- addToPostMatching(writerInterceptors, provider, bindingPriority, false);
- setIsNeeded = true;
+ if (SERVER_FILTER_INTERCEPTOR_CLASSES.contains(contract)
+ && contract.isAssignableFrom(provider.getClass())) {
+ actualContracts.add(contract);
}
}
-
- if (setIsNeeded && !bindingSet) {
+ if (!actualContracts.isEmpty()) {
+ registerUserProvider(new FilterProviderInfo<Object>(provider,
+ getBus(),
+ nameBinding,
+ priority,
+ actualContracts));
ori.addNameBindings(Collections.singletonList(nameBinding));
- bindingSet = true;
}
-
return this;
}
- @SuppressWarnings("unchecked")
- private <T> void addToInterceptors(List<ProviderInfo<T>> providers, Object provider,
- int priority, boolean asc) {
- int size = providers.size();
- if (size > 0) {
- for (int i = 0; i < size; i++) {
- int providerPriority = AnnotationUtils.getBindingPriority(
- providers.get(i).getProvider().getClass());
- if (asc) {
- if (priority < providerPriority || i + 1 == size) {
- int index = priority < providerPriority ? i : i + 1;
- providers.add(index, (ProviderInfo<T>)newProvider(provider));
- break;
- }
- } else if (priority > providerPriority || i + 1 == size) {
- int index = priority > providerPriority ? i : i + 1;
- providers.add(index, (ProviderInfo<T>)newProvider(provider));
- break;
- }
- }
- } else {
- providers.add((ProviderInfo<T>)newProvider(provider));
- }
- }
-
- private <T> ProviderInfo<T> newProvider(T provider) {
- ProviderInfo<T> newProvider = new ProviderInfo<T>(provider, getBus());
- injectContextProxiesIntoProvider(newProvider);
- return newProvider;
- }
-
- @SuppressWarnings("unchecked")
- private <T> Map<NameKey, ProviderInfo<T>> addToPostMatching(
- Map<NameKey, ProviderInfo<T>> map, Object provider, int priority, boolean asc) {
- Map<NameKey, ProviderInfo<T>> newMap = new LinkedHashMap<NameKey, ProviderInfo<T>>();
-
- Iterator<Map.Entry<NameKey, ProviderInfo<T>>> it = map.entrySet().iterator();
- if (it.hasNext()) {
- boolean added = false;
- while (it.hasNext()) {
- Map.Entry<NameKey, ProviderInfo<T>> entry = it.next();
- int providerPriority = entry.getKey().getPriority();
- // this surely can be collapsed further
- if (!added && asc && (priority < providerPriority || !it.hasNext())) {
- addNewProvider(newMap, entry, provider, priority, providerPriority >= priority);
- added = true;
- } else if (!added && !asc && (priority > providerPriority || !it.hasNext())) {
- addNewProvider(newMap, entry, provider, priority, priority > providerPriority);
- added = true;
- } else {
- newMap.put(entry.getKey(), entry.getValue());
- }
- }
- } else {
- newMap.put(new NameKey(nameBinding, priority), (ProviderInfo<T>)newProvider(provider));
- }
- return newMap;
-
-
- }
-
- @SuppressWarnings("unchecked")
- private <T> void addNewProvider(Map<NameKey, ProviderInfo<T>> newMap,
- Map.Entry<NameKey, ProviderInfo<T>> entry,
- Object provider,
- int priority,
- boolean first) {
- if (first) {
- newMap.put(new NameKey(nameBinding, priority), (ProviderInfo<T>)newProvider(provider));
- newMap.put(entry.getKey(), entry.getValue());
- } else {
- newMap.put(entry.getKey(), entry.getValue());
- newMap.put(new NameKey(nameBinding, priority), (ProviderInfo<T>)newProvider(provider));
- }
- }
-
-
}
+
private static class MethodFeatureContextConfigurable extends ConfigurableImpl<FeatureContext> {
protected MethodFeatureContextConfigurable(MethodFeatureContextImpl mc) {
- super(mc, RuntimeType.SERVER, SERVER_FILTER_INTERCEPTOR_CLASSES);
+ super(mc, RuntimeType.SERVER, SERVER_FILTER_INTERCEPTOR_CLASSES.toArray(new Class<?>[]{}));
}
@Override
protected FeatureContext doRegister(Object provider, int bindingPriority, Class<?>... contracts) {
Modified: cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/utils/AnnotationUtils.java
URL: http://svn.apache.org/viewvc/cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/utils/AnnotationUtils.java?rev=1509043&r1=1509042&r2=1509043&view=diff
==============================================================================
--- cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/utils/AnnotationUtils.java (original)
+++ cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/utils/AnnotationUtils.java Wed Jul 31 21:42:45 2013
@@ -23,8 +23,7 @@ import java.lang.annotation.Annotation;
import java.lang.reflect.Method;
import java.util.Collections;
import java.util.HashSet;
-import java.util.LinkedList;
-import java.util.List;
+import java.util.LinkedHashSet;
import java.util.ResourceBundle;
import java.util.Set;
import java.util.logging.Logger;
@@ -134,11 +133,11 @@ public final class AnnotationUtils {
Priority b = getClassAnnotation(providerCls, Priority.class);
return b == null ? Priorities.USER : b.value();
}
- public static List<String> getNameBindings(Annotation[] targetAnns) {
+ public static Set<String> getNameBindings(Annotation[] targetAnns) {
if (targetAnns.length == 0) {
- return Collections.emptyList();
+ return Collections.emptySet();
}
- List<String> names = new LinkedList<String>();
+ Set<String> names = new LinkedHashSet<String>();
for (Annotation a : targetAnns) {
NameBinding nb = a.annotationType().getAnnotation(NameBinding.class);
if (nb != null) {
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=1509043&r1=1509042&r2=1509043&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 Wed Jul 31 21:42:45 2013
@@ -1693,7 +1693,7 @@ public final class JAXRSUtils {
public static boolean runContainerRequestFilters(ServerProviderFactory pf,
Message m,
boolean preMatch,
- List<String> names,
+ Set<String> names,
boolean sub) {
List<ProviderInfo<ContainerRequestFilter>> containerFilters = preMatch
? pf.getPreMatchContainerRequestFilters() : pf.getPostMatchContainerRequestFilters(names);
Modified: cxf/trunk/rt/frontend/jaxrs/src/test/java/org/apache/cxf/jaxrs/model/ClassResourceInfoTest.java
URL: http://svn.apache.org/viewvc/cxf/trunk/rt/frontend/jaxrs/src/test/java/org/apache/cxf/jaxrs/model/ClassResourceInfoTest.java?rev=1509043&r1=1509042&r2=1509043&view=diff
==============================================================================
--- cxf/trunk/rt/frontend/jaxrs/src/test/java/org/apache/cxf/jaxrs/model/ClassResourceInfoTest.java (original)
+++ cxf/trunk/rt/frontend/jaxrs/src/test/java/org/apache/cxf/jaxrs/model/ClassResourceInfoTest.java Wed Jul 31 21:42:45 2013
@@ -224,8 +224,8 @@ public class ClassResourceInfoTest exten
Application app = new TestApplication();
JAXRSServerFactoryBean bean = ResourceUtils.createApplication(app, true, true);
ClassResourceInfo cri = bean.getServiceFactory().getClassResourceInfo().get(0);
- List<String> names = cri.getNameBindings();
- assertEquals(Collections.singletonList(CustomNameBinding.class.getName()), names);
+ Set<String> names = cri.getNameBindings();
+ assertEquals(Collections.singleton(CustomNameBinding.class.getName()), names);
}
@Target({ ElementType.TYPE, ElementType.METHOD })
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=1509043&r1=1509042&r2=1509043&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 Wed Jul 31 21:42:45 2013
@@ -30,7 +30,9 @@ import java.lang.annotation.Target;
import java.lang.reflect.Type;
import java.net.URI;
import java.util.ArrayList;
+import java.util.HashMap;
import java.util.List;
+import java.util.Map;
import javax.annotation.Priority;
import javax.servlet.http.HttpServletRequest;
@@ -302,8 +304,8 @@ public class BookServer20 extends Abstra
}
- @Priority(2)
- public static class PostMatchDynamicContainerResponseFilter implements ContainerResponseFilter {
+ public static class PostMatchDynamicContainerResponseFilter
+ implements ContainerRequestFilter, ContainerResponseFilter {
@Override
public void filter(ContainerRequestContext requestContext,
@@ -314,6 +316,12 @@ public class BookServer20 extends Abstra
responseContext.getHeaders().add("DynamicResponse", "Dynamic");
}
+
+ @Override
+ public void filter(ContainerRequestContext requestContext) throws IOException {
+ throw new RuntimeException();
+
+ }
}
@@ -407,7 +415,10 @@ public class BookServer20 extends Abstra
public void configure(ResourceInfo resourceInfo, FeatureContext configurable) {
configurable.register(new PreMatchDynamicContainerRequestFilter());
- configurable.register(new PostMatchDynamicContainerResponseFilter());
+ Map<Class<?>, Integer> contracts = new HashMap<Class<?>, Integer>();
+ contracts.put(ContainerResponseFilter.class, 2);
+ configurable.register(new PostMatchDynamicContainerResponseFilter(),
+ contracts);
}
}