You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@wink.apache.org by el...@apache.org on 2009/07/14 09:29:58 UTC
svn commit: r793805 - in /incubator/wink/trunk/wink-common/src:
main/java/org/apache/wink/common/internal/registry/ProvidersRegistry.java
test/java/org/apache/wink/common/internal/providers/ProvidersContextResolverTest.java
Author: elman
Date: Tue Jul 14 07:29:58 2009
New Revision: 793805
URL: http://svn.apache.org/viewvc?rev=793805&view=rev
Log:
Fixing sort algorithm [WINK-82]
Modified:
incubator/wink/trunk/wink-common/src/main/java/org/apache/wink/common/internal/registry/ProvidersRegistry.java
incubator/wink/trunk/wink-common/src/test/java/org/apache/wink/common/internal/providers/ProvidersContextResolverTest.java
Modified: incubator/wink/trunk/wink-common/src/main/java/org/apache/wink/common/internal/registry/ProvidersRegistry.java
URL: http://svn.apache.org/viewvc/incubator/wink/trunk/wink-common/src/main/java/org/apache/wink/common/internal/registry/ProvidersRegistry.java?rev=793805&r1=793804&r2=793805&view=diff
==============================================================================
--- incubator/wink/trunk/wink-common/src/main/java/org/apache/wink/common/internal/registry/ProvidersRegistry.java (original)
+++ incubator/wink/trunk/wink-common/src/main/java/org/apache/wink/common/internal/registry/ProvidersRegistry.java Tue Jul 14 07:29:58 2009
@@ -32,7 +32,6 @@
import java.util.List;
import java.util.Map;
import java.util.Set;
-import java.util.TreeMap;
import java.util.TreeSet;
import java.util.Map.Entry;
import java.util.concurrent.locks.Lock;
@@ -47,14 +46,14 @@
import javax.ws.rs.ext.MessageBodyReader;
import javax.ws.rs.ext.MessageBodyWriter;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
import org.apache.wink.common.WinkApplication;
import org.apache.wink.common.internal.application.ApplicationValidator;
import org.apache.wink.common.internal.lifecycle.LifecycleManagersRegistry;
import org.apache.wink.common.internal.lifecycle.ObjectFactory;
import org.apache.wink.common.internal.runtime.RuntimeContext;
import org.apache.wink.common.internal.utils.GenericsUtils;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
/**
* Keeps the registry of providers.
@@ -394,7 +393,7 @@
private final Map<MediaType, Set<ObjectFactory<T>>> data =
new LinkedHashMap<MediaType, Set<ObjectFactory<T>>>();
private final Class<?> rawType;
-
+
public MediaTypeMap(Class<?> rawType) {
super();
this.rawType = rawType;
@@ -439,6 +438,7 @@
// from the Providers interface, therefore isCompatible method
// should be used
// the search here is less efficient that the regular search
+ // see https://issues.apache.org/jira/browse/WINK-47
List<ObjectFactory<T>> list = new ArrayList<ObjectFactory<T>>();
@@ -449,29 +449,41 @@
compatibleList.add(entry);
}
}
- // sort list according to n / m > n / * > * / *
- Collections.sort(compatibleList,
- new Comparator<Entry<MediaType, Set<ObjectFactory<T>>>>() {
-
- public int compare(Entry<MediaType, Set<ObjectFactory<T>>> o1,
- Entry<MediaType, Set<ObjectFactory<T>>> o2) {
- MediaType m1 = o1.getKey();
- MediaType m2 = o2.getKey();
- if (m1.getType().equals(MediaType.MEDIA_TYPE_WILDCARD)) {
- if (m2.getType().equals(MediaType.MEDIA_TYPE_WILDCARD)) {
- return 0;
- }
- // m2 > m1
- return -1;
- } else {
- if (!m2.getType().equals(MediaType.MEDIA_TYPE_WILDCARD)) {
- return 0;
- }
- // m1 > m2
- return 1;
- }
- }
- });
+
+ // sorts according to the following algorithm: n / m > n / * > * / * in descending order
+ // see https://issues.apache.org/jira/browse/WINK-82
+ Collections.sort(compatibleList, Collections.reverseOrder(new Comparator<Entry<MediaType, Set<ObjectFactory<T>>>>() {
+
+ public int compare(Entry<MediaType, Set<ObjectFactory<T>>> o1,
+ Entry<MediaType, Set<ObjectFactory<T>>> o2) {
+ MediaType m1 = o1.getKey();
+ MediaType m2 = o2.getKey();
+ int compareTypes = compareTypes(m1.getType(), m2.getType());
+ if (compareTypes == 0) {
+ return compareTypes(m1.getSubtype(), m2.getSubtype());
+ }
+ return compareTypes;
+ }
+
+ private int compareTypes(String type1, String type2) {
+ if (type1.equals(MediaType.MEDIA_TYPE_WILDCARD)) {
+ if (type2.equals(MediaType.MEDIA_TYPE_WILDCARD)) {
+ // both types are wildcards
+ return 0;
+ }
+ // only type2 is concrete
+ // type2 > type1
+ return -1;
+ }
+ if (type2.equals(MediaType.MEDIA_TYPE_WILDCARD)) {
+ // only type1 is concrete
+ return 1;
+ }
+ // both types are concrete
+ return 0;
+ }
+ }));
+
for (Entry<MediaType, Set<ObjectFactory<T>>> entry : compatibleList) {
limitByType(list, entry.getValue(), cls);
}
Modified: incubator/wink/trunk/wink-common/src/test/java/org/apache/wink/common/internal/providers/ProvidersContextResolverTest.java
URL: http://svn.apache.org/viewvc/incubator/wink/trunk/wink-common/src/test/java/org/apache/wink/common/internal/providers/ProvidersContextResolverTest.java?rev=793805&r1=793804&r2=793805&view=diff
==============================================================================
--- incubator/wink/trunk/wink-common/src/test/java/org/apache/wink/common/internal/providers/ProvidersContextResolverTest.java (original)
+++ incubator/wink/trunk/wink-common/src/test/java/org/apache/wink/common/internal/providers/ProvidersContextResolverTest.java Tue Jul 14 07:29:58 2009
@@ -40,6 +40,8 @@
private static final String STRING = "String";
private static final String STRING2 = "String2";
+ private static final String STRING3 = "String3";
+ private static final String STRING4 = "String4";
private static final String ATOM = "Atom";
private static final byte[] BYTE = new byte[0];
private static final Integer _12345 = new Integer(12345);
@@ -55,13 +57,31 @@
}
@Provider
- @Produces( "text/*" )
+ @Produces( {MediaType.TEXT_PLAIN})
public static class StringContextResolver2 implements ContextResolver<String> {
public String getContext(Class<?> type) {
return STRING2;
}
}
+
+ @Provider
+ @Produces( "text/*" )
+ public static class StringContextResolver3 implements ContextResolver<String> {
+
+ public String getContext(Class<?> type) {
+ return STRING3;
+ }
+ }
+
+ @Provider
+ @Produces( "*/*" )
+ public static class StringContextResolver4 implements ContextResolver<String> {
+
+ public String getContext(Class<?> type) {
+ return STRING4;
+ }
+ }
@Provider
@Produces(MediaType.APPLICATION_FORM_URLENCODED)
@@ -118,6 +138,7 @@
private ProvidersRegistry createProvidersRegistryImpl() {
ProvidersRegistry providers =
new ProvidersRegistry(new LifecycleManagersRegistry(), new ApplicationValidator());
+ ;
return providers;
}
@@ -155,12 +176,12 @@
* AtomContextResolver comes before StringContextResolver, therefore it
* should be invoked after
*/
- assertEquals(STRING, providers.getContextResolver(String.class,
+ assertEquals(ATOM, providers.getContextResolver(String.class,
MediaType.WILDCARD_TYPE,
null).getContext(null));
/*
- * AtomContextResolver returnes null, if the parameter is not null,
+ * AtomContextResolver returns null, if the parameter is not null,
* therefore StringContextResolver should be invoked
*/
assertEquals(STRING, providers.getContextResolver(String.class,
@@ -178,7 +199,7 @@
public void testContextResolverWildCards() {
ProvidersRegistry providers = createProvidersRegistryImpl();
assertTrue(providers.addProvider(new MyContextResolver()));
- assertTrue(providers.addProvider(new StringContextResolver2()));
+ assertTrue(providers.addProvider(new StringContextResolver3()));
/*
* Check various wildcard permutations
@@ -199,12 +220,39 @@
assertSame(MYCLASS, providers
.getContextResolver(MyClass.class, new MediaType("*", "x-www-form-urlencoded"), null)
.getContext(MyClass.class));
-
+
// should hit an exact match when search expands out to "text/*"
- assertSame(STRING2, providers.getContextResolver(String.class,
+ assertSame(STRING3, providers.getContextResolver(String.class,
new MediaType("text",
"blarg"),
null).getContext(String.class));
}
+
+ public void testContextResolverSortingAlgorithm() {
+ ProvidersRegistry providers = createProvidersRegistryImpl();
+ // note: the order these are added is important to the test
+ assertTrue(providers.addProvider(new StringContextResolver4()));
+ assertTrue(providers.addProvider(new StringContextResolver3()));
+ assertTrue(providers.addProvider(new StringContextResolver2()));
+
+
+ // StringContextResolver2 takes priority over the others due to the media type in @Produces
+ assertSame(STRING2, providers.getContextResolver(String.class,
+ new MediaType("text",
+ "*"),
+ null).getContext(String.class));
+
+ // StringContextResolver2 takes priority over the others due to the media type in @Produces
+ assertSame(STRING2, providers.getContextResolver(String.class,
+ new MediaType("*",
+ "*"),
+ null).getContext(String.class));
+
+ // StringContextResolver2 takes priority over the others due to the media type in @Produces
+ assertSame(STRING2, providers.getContextResolver(String.class,
+ new MediaType("text",
+ "plain"),
+ null).getContext(String.class));
+ }
}