andymc12 closed pull request #321: Check @Priority annotations on providers
when sorting
URL: https://github.com/apache/cxf/pull/321
This is a PR merged from a forked repository.
As GitHub hides the original diff on merge, it is displayed below for
the sake of provenance:
As this is a foreign pull request (from a fork), the diff is supplied
below (as it won't show otherwise due to GitHub magic):
diff --git
a/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/provider/ProviderFactory.java
b/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/provider/ProviderFactory.java
index 9450f8e26e1..efd5a4c73c2 100644
---
a/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/provider/ProviderFactory.java
+++
b/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/provider/ProviderFactory.java
@@ -236,7 +236,7 @@ protected static Object createProvider(String className,
Bus bus) {
} else if (candidates.size() == 1) {
return candidates.get(0);
} else {
- Collections.sort(candidates, new ClassComparator());
+ Collections.sort(candidates, new PriorityBasedClassComparator());
return new ContextResolverProxy<T>(candidates);
}
@@ -808,7 +808,11 @@ public int compare(ProviderInfo<MessageBodyReader<?>> p1,
if (result != 0) {
return result;
}
- return compareCustomStatus(p1, p2);
+ result = compareCustomStatus(p1, p2);
+ if (result != 0) {
+ return result;
+ }
+ return comparePriorityStatus(p1.getProvider().getClass(),
p2.getProvider().getClass());
}
}
@@ -833,7 +837,12 @@ public int compare(ProviderInfo<MessageBodyWriter<?>> p1,
if (result != 0) {
return result;
}
- return compareCustomStatus(p1, p2);
+ result = compareCustomStatus(p1, p2);
+ if (result != 0) {
+ return result;
+ }
+
+ return comparePriorityStatus(p1.getProvider().getClass(),
p2.getProvider().getClass());
}
}
@@ -849,6 +858,12 @@ private static int compareCustomStatus(ProviderInfo<?> p1,
ProviderInfo<?> p2) {
return result;
}
+ private static int comparePriorityStatus(Class<?> cl1, Class<?> cl2) {
+ Integer value1 = AnnotationUtils.getBindingPriority(cl1);
+ Integer value2 = AnnotationUtils.getBindingPriority(cl2);
+ return value1.compareTo(value2);
+ }
+
private static class ContextResolverComparator
implements Comparator<ProviderInfo<ContextResolver<?>>> {
@@ -1003,6 +1018,25 @@ public int compare(ProviderInfo<?> p1, ProviderInfo<?>
p2) {
}
}
+ 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();
diff --git
a/rt/frontend/jaxrs/src/test/java/org/apache/cxf/jaxrs/provider/ProviderFactoryTest.java
b/rt/frontend/jaxrs/src/test/java/org/apache/cxf/jaxrs/provider/ProviderFactoryTest.java
index b4d6b914ac0..3bf35e1194e 100644
---
a/rt/frontend/jaxrs/src/test/java/org/apache/cxf/jaxrs/provider/ProviderFactoryTest.java
+++
b/rt/frontend/jaxrs/src/test/java/org/apache/cxf/jaxrs/provider/ProviderFactoryTest.java
@@ -33,7 +33,9 @@
import javax.activation.DataHandler;
import javax.activation.DataSource;
+import javax.annotation.Priority;
import javax.ws.rs.Consumes;
+import javax.ws.rs.Priorities;
import javax.ws.rs.Produces;
import javax.ws.rs.WebApplicationException;
import javax.ws.rs.core.MediaType;
@@ -820,6 +822,70 @@ public void testSetSchemasFromClasspath() {
assertNotNull("schema can not be read from classpath", s);
}
+ @Test
+ public void testSortByPriority() {
+ ProviderFactory pf = ServerProviderFactory.getInstance();
+ List<Object> providers = new ArrayList<>();
+ BookReaderWriter bookHandler = new BookReaderWriter();
+ providers.add(bookHandler);
+ HighPriorityBookReaderWriter highPriorityBookHandler = new
HighPriorityBookReaderWriter();
+ providers.add(highPriorityBookHandler);
+ pf.setUserProviders(providers);
+ assertSame(highPriorityBookHandler,
+ pf.createMessageBodyReader(Book.class, Book.class, new
Annotation[]{},
+ MediaType.APPLICATION_XML_TYPE,
new MessageImpl()));
+ assertSame(highPriorityBookHandler,
+ pf.createMessageBodyWriter(Book.class, Book.class, new
Annotation[]{},
+ MediaType.APPLICATION_XML_TYPE,
new MessageImpl()));
+ }
+
+ @Test
+ public void testSortByPriorityReversed() {
+ // do the same thing again but add the providers in the reverse order
to ensure add order
+ // isn't responsible for our success so far.
+ ProviderFactory pf = ServerProviderFactory.getInstance();
+ List<Object> providers = new ArrayList<>();
+ HighPriorityBookReaderWriter highPriorityBookHandler = new
HighPriorityBookReaderWriter();
+ providers.add(highPriorityBookHandler);
+ BookReaderWriter bookHandler = new BookReaderWriter();
+ providers.add(bookHandler);
+ pf.setUserProviders(providers);
+ assertSame(highPriorityBookHandler,
+ pf.createMessageBodyReader(Book.class, Book.class, new
Annotation[]{},
+ MediaType.APPLICATION_XML_TYPE,
new MessageImpl()));
+ assertSame(highPriorityBookHandler,
+ pf.createMessageBodyWriter(Book.class, Book.class, new
Annotation[]{},
+ MediaType.APPLICATION_XML_TYPE,
new MessageImpl()));
+ }
+
+ @Test
+ public void testSortContextResolverByPriority() {
+ ProviderFactory pf = ServerProviderFactory.getInstance();
+ List<Object> providers = new ArrayList<>();
+ LowPriorityContextResolver lowResolver = new
LowPriorityContextResolver();
+ providers.add(lowResolver);
+ HighPriorityContextResolver highResolver = new
HighPriorityContextResolver();
+ providers.add(highResolver);
+ pf.setUserProviders(providers);
+ Message m = new MessageImpl();
+ assertEquals(highResolver.getContext(null),
+ pf.createContextResolver(String.class, m,
MediaType.TEXT_PLAIN_TYPE).getContext(null));
+ }
+
+ @Test
+ public void testSortContextResolverByPriorityReversed() {
+ ProviderFactory pf = ServerProviderFactory.getInstance();
+ List<Object> providers = new ArrayList<>();
+ HighPriorityContextResolver highResolver = new
HighPriorityContextResolver();
+ providers.add(highResolver);
+ LowPriorityContextResolver lowResolver = new
LowPriorityContextResolver();
+ providers.add(lowResolver);
+ pf.setUserProviders(providers);
+ Message m = new MessageImpl();
+ assertEquals(highResolver.getContext(null),
+ pf.createContextResolver(String.class, m,
MediaType.TEXT_PLAIN_TYPE).getContext(null));
+ }
+
private static class TestRuntimeExceptionMapper implements
ExceptionMapper<RuntimeException> {
public Response toResponse(RuntimeException exception) {
@@ -828,6 +894,58 @@ public Response toResponse(RuntimeException exception) {
}
+ @Priority(100)
+ private static class LowPriorityContextResolver implements
ContextResolver<String> {
+
+ @Override
+ public String getContext(Class<?> paramClass) {
+ return "low";
+ }
+ }
+
+ @Priority(1)
+ private static class HighPriorityContextResolver implements
ContextResolver<String> {
+
+ @Override
+ public String getContext(Class<?> paramClass) {
+ return "high";
+ }
+ }
+
+ @Priority(Priorities.USER - 10)
+ @Produces("application/xml")
+ @Consumes("application/xml")
+ private static class HighPriorityBookReaderWriter
+ implements MessageBodyReader<Book>, MessageBodyWriter<Book> {
+
+ public boolean isReadable(Class<?> type, Type genericType,
Annotation[] annotations,
+ MediaType mediaType) {
+ return true;
+ }
+
+ public Book readFrom(Class<Book> arg0, Type arg1, Annotation[] arg2,
+ MediaType arg3, MultivaluedMap<String, String>
arg4, InputStream arg5)
+ throws IOException, WebApplicationException {
+ return null;
+ }
+
+ public long getSize(Book t, Class<?> type, Type genericType,
Annotation[] annotations,
+ MediaType mediaType) {
+ return 0;
+ }
+
+ public boolean isWriteable(Class<?> type, Type genericType,
Annotation[] annotations,
+ MediaType mediaType) {
+ return true;
+ }
+
+ public void writeTo(Book arg0, Class<?> arg1, Type arg2, Annotation[]
arg3,
+ MediaType arg4, MultivaluedMap<String, Object>
arg5, OutputStream arg6)
+ throws IOException, WebApplicationException {
+
+ }
+ }
+
@Produces("application/xml")
@Consumes("application/xml")
private static class BookReaderWriter
----------------------------------------------------------------
This is an automated message from the Apache Git Service.
To respond to the message, please log on GitHub and use the
URL above to go to the specific comment.
For queries about this service, please contact Infrastructure at:
[email protected]
With regards,
Apache Git Services