Author: sergeyb
Date: Thu Apr 7 21:46:45 2011
New Revision: 1090035
URL: http://svn.apache.org/viewvc?rev=1090035&view=rev
Log:
[CXF-3415] Opting for a more straightforward approach for making JAXB providers
endpoint-specific
Modified:
cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/provider/ProviderFactory.java
cxf/trunk/rt/frontend/jaxrs/src/test/java/org/apache/cxf/jaxrs/provider/ProviderFactoryTest.java
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=1090035&r1=1090034&r2=1090035&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
Thu Apr 7 21:46:45 2011
@@ -66,10 +66,7 @@ public final class ProviderFactory {
private static final String JSON_PROVIDER_NAME =
"org.apache.cxf.jaxrs.provider.JSONProvider";
static {
- SHARED_FACTORY.setProviders(true,
- createProvider(JAXB_PROVIDER_NAME),
- createProvider(JSON_PROVIDER_NAME),
- new BinaryDataProvider(),
+ SHARED_FACTORY.setProviders(new BinaryDataProvider(),
new SourceProvider(),
new FormEncodingProvider(),
new PrimitiveTextProvider(),
@@ -97,9 +94,34 @@ public final class ProviderFactory {
private RequestPreprocessor requestPreprocessor;
private ProviderInfo<Application> application;
+ private List<ProviderInfo<MessageBodyReader>> jaxbReaders =
+ new ArrayList<ProviderInfo<MessageBodyReader>>();
+ private List<ProviderInfo<MessageBodyWriter>> jaxbWriters =
+ new ArrayList<ProviderInfo<MessageBodyWriter>>();
+
private ProviderFactory() {
+ initJaxbProviders();
}
+ // Not ideal but in the end seems like the simplest option compared
+ // to adding default readers/writers to existing messageReaders/Writers
+ // (due to all sort of conflicts with custom providers) and cloning
+ // at the request time
+ private void initJaxbProviders() {
+ Object jaxbProvider = createProvider(JAXB_PROVIDER_NAME);
+ if (jaxbProvider != null) {
+ jaxbReaders.add(new
ProviderInfo<MessageBodyReader>((MessageBodyReader)jaxbProvider));
+ jaxbWriters.add(new
ProviderInfo<MessageBodyWriter>((MessageBodyWriter)jaxbProvider));
+ }
+ Object jsonProvider = createProvider(JSON_PROVIDER_NAME);
+ if (jsonProvider != null) {
+ jaxbReaders.add(new
ProviderInfo<MessageBodyReader>((MessageBodyReader)jsonProvider));
+ jaxbWriters.add(new
ProviderInfo<MessageBodyWriter>((MessageBodyWriter)jsonProvider));
+ }
+ injectContexts(jaxbReaders, jaxbWriters);
+ }
+
+
private static Object createProvider(String className) {
@@ -273,29 +295,36 @@ public final class ProviderFactory {
- @SuppressWarnings("unchecked")
public <T> MessageBodyReader<T> createMessageBodyReader(Class<T> bodyType,
Type parameterType,
Annotation[]
parameterAnnotations,
MediaType
mediaType,
Message m) {
// Try user provided providers
- MessageBodyReader<T> mr = chooseMessageReader(bodyType,
+ MessageBodyReader<T> mr = chooseMessageReader(messageReaders,
+ bodyType,
parameterType,
parameterAnnotations,
mediaType,
m);
- //If none found try the default ones
- if (mr != null) {
+ if (mr == null) {
+ mr = chooseMessageReader(jaxbReaders,
+ bodyType,
+ parameterType,
+ parameterAnnotations,
+ mediaType,
+ m);
+ }
+
+ if (mr != null || SHARED_FACTORY == this) {
return mr;
}
- mr = SHARED_FACTORY.chooseMessageReader(bodyType,
- parameterType,
- parameterAnnotations,
- mediaType,
- m);
- return (MessageBodyReader)cloneSharedProviderIfNeeded(mr, m);
+ return SHARED_FACTORY.createMessageBodyReader(bodyType,
+ parameterType,
+ parameterAnnotations,
+ mediaType,
+ m);
}
private boolean isJaxbBasedProvider(Object sharedProvider) {
@@ -303,35 +332,6 @@ public final class ProviderFactory {
return JAXB_PROVIDER_NAME.equals(clsName) ||
JSON_PROVIDER_NAME.equals(clsName);
}
- private Object cloneSharedProviderIfNeeded(Object sharedProvider, Message
m) {
- if (sharedProvider != null && isJaxbBasedProvider(sharedProvider)) {
- try {
- synchronized (this) {
- ProviderInfo<?> info = null;
- for (int i = messageReaders.size() - 1; i >= 0; i--) {
- ProviderInfo<?> lastInfo = messageReaders.get(i);
- if (lastInfo.getProvider().getClass().getName().equals(
- sharedProvider.getClass().getName())) {
- info = lastInfo;
- break;
- }
- }
- if (info == null) {
- setProviders(false,
sharedProvider.getClass().newInstance());
- info = messageReaders.get(messageReaders.size() - 1);
- }
- InjectionUtils.injectContextFields(info.getProvider(),
info, m);
- InjectionUtils.injectContextMethods(info.getProvider(),
info, m);
-
- return info.getProvider();
- }
- } catch (Exception ex) {
- // won't happen at this stage
- }
- }
- return sharedProvider;
- }
-
public List<ProviderInfo<RequestHandler>> getRequestHandlers() {
List<ProviderInfo<RequestHandler>> handlers = null;
if (requestHandlers.size() == 0) {
@@ -360,33 +360,41 @@ public final class ProviderFactory {
return Collections.unmodifiableList(responseHandlers);
}
- @SuppressWarnings("unchecked")
public <T> MessageBodyWriter<T> createMessageBodyWriter(Class<T> bodyType,
Type parameterType,
Annotation[]
parameterAnnotations,
MediaType
mediaType,
Message m) {
// Try user provided providers
- MessageBodyWriter<T> mw = chooseMessageWriter(bodyType,
+ MessageBodyWriter<T> mw = chooseMessageWriter(messageWriters,
+ bodyType,
parameterType,
parameterAnnotations,
mediaType,
m);
- //If none found try the default ones
- if (mw != null) {
+ if (mw == null) {
+ mw = chooseMessageWriter(jaxbWriters,
+ bodyType,
+ parameterType,
+ parameterAnnotations,
+ mediaType,
+ m);
+ }
+
+ if (mw != null || SHARED_FACTORY == this) {
return mw;
}
- mw = SHARED_FACTORY.chooseMessageWriter(bodyType,
- parameterType,
- parameterAnnotations,
- mediaType,
- m);
- return (MessageBodyWriter)cloneSharedProviderIfNeeded(mw, m);
+
+ return SHARED_FACTORY.createMessageBodyWriter(bodyType,
+ parameterType,
+ parameterAnnotations,
+ mediaType,
+ m);
}
//CHECKSTYLE:OFF
- private void setProviders(boolean sort, Object... providers) {
+ private void setProviders(Object... providers) {
for (Object o : providers) {
if (o == null) {
@@ -426,10 +434,8 @@ public final class ProviderFactory {
paramHandlers.add(new
ProviderInfo<ParameterHandler>((ParameterHandler)o));
}
}
- if (sort) {
- sortReaders();
- sortWriters();
- }
+ sortReaders();
+ sortWriters();
injectContexts(messageReaders, messageWriters, contextResolvers,
requestHandlers, responseHandlers,
exceptionMappers);
@@ -476,13 +482,14 @@ public final class ProviderFactory {
* @return
*/
@SuppressWarnings("unchecked")
- private <T> MessageBodyReader<T> chooseMessageReader(Class<T> type,
+ private <T> MessageBodyReader<T>
chooseMessageReader(List<ProviderInfo<MessageBodyReader>> readers,
+ Class<T> type,
Type genericType,
Annotation[]
annotations,
MediaType mediaType,
Message m) {
List<MessageBodyReader<T>> candidates = new
LinkedList<MessageBodyReader<T>>();
- for (ProviderInfo<MessageBodyReader> ep : messageReaders) {
+ for (ProviderInfo<MessageBodyReader> ep : readers) {
if (matchesReaderCriterias(ep.getProvider(), type, genericType,
annotations, mediaType)) {
if (this == SHARED_FACTORY) {
if (!isJaxbBasedProvider(ep.getProvider())) {
@@ -532,13 +539,14 @@ public final class ProviderFactory {
* @return
*/
@SuppressWarnings("unchecked")
- private <T> MessageBodyWriter<T> chooseMessageWriter(Class<T> type,
+ private <T> MessageBodyWriter<T>
chooseMessageWriter(List<ProviderInfo<MessageBodyWriter>> writers,
+ Class<T> type,
Type genericType,
Annotation[]
annotations,
MediaType mediaType,
Message m) {
List<MessageBodyWriter<T>> candidates = new
LinkedList<MessageBodyWriter<T>>();
- for (ProviderInfo<MessageBodyWriter> ep : messageWriters) {
+ for (ProviderInfo<MessageBodyWriter> ep : writers) {
if (matchesWriterCriterias(ep.getProvider(), type, genericType,
annotations, mediaType)) {
if (this == SHARED_FACTORY) {
if (!isJaxbBasedProvider(ep.getProvider())) {
@@ -595,7 +603,7 @@ public final class ProviderFactory {
* @param entityProviders the entityProviders to set
*/
public void setUserProviders(List<?> userProviders) {
- setProviders(true, userProviders.toArray());
+ setProviders(userProviders.toArray());
}
private static class MessageBodyReaderComparator
@@ -706,16 +714,9 @@ public final class ProviderFactory {
List.class,
schemas);
}
if (!schemasMethodAvailable) {
- for (ProviderInfo<MessageBodyReader> r :
SHARED_FACTORY.messageReaders) {
- try {
- Method m =
r.getProvider().getClass().getMethod("setSchemas",
- new
Class[]{List.class});
- Object provider = r.getProvider().getClass().newInstance();
- m.invoke(provider, new Object[]{schemas});
- registerUserProvider(provider);
- } catch (Exception ex) {
- // ignore
- }
+ for (ProviderInfo<MessageBodyReader> r : jaxbReaders) {
+ schemasMethodAvailable =
injectProviderProperty(r.getProvider(), "setSchemas",
+ List.class,
schemas);
}
}
}
@@ -736,7 +737,9 @@ public final class ProviderFactory {
Set<Object> getReadersWriters() {
Set<Object> set = new HashSet<Object>();
set.addAll(messageReaders);
+ set.addAll(jaxbReaders);
set.addAll(messageWriters);
+ set.addAll(jaxbWriters);
return set;
}
Modified:
cxf/trunk/rt/frontend/jaxrs/src/test/java/org/apache/cxf/jaxrs/provider/ProviderFactoryTest.java
URL:
http://svn.apache.org/viewvc/cxf/trunk/rt/frontend/jaxrs/src/test/java/org/apache/cxf/jaxrs/provider/ProviderFactoryTest.java?rev=1090035&r1=1090034&r2=1090035&view=diff
==============================================================================
---
cxf/trunk/rt/frontend/jaxrs/src/test/java/org/apache/cxf/jaxrs/provider/ProviderFactoryTest.java
(original)
+++
cxf/trunk/rt/frontend/jaxrs/src/test/java/org/apache/cxf/jaxrs/provider/ProviderFactoryTest.java
Thu Apr 7 21:46:45 2011
@@ -135,33 +135,45 @@ public class ProviderFactoryTest extends
}
@Test
- public void testDefaultJaxbProviderCloned() {
+ public void testDefaultJaxbProvider() throws Exception {
ProviderFactory pf = ProviderFactory.getInstance();
doTestDefaultJaxbProviderCloned(pf, "http://localhost:8080/base/");
checkJaxbProvider(pf);
}
@Test
- public void testDefaultJaxbProviderClonedMultipleThreads() throws
Exception {
+ public void testDefaultJaxbProviderMultipleThreads() throws Exception {
+ for (int i = 0; i < 100; i++) {
+ doTestDefaultJaxbProviderClonedMultipleThreads();
+ }
+ }
+
+
+ public void doTestDefaultJaxbProviderClonedMultipleThreads() throws
Exception {
ProviderFactory pf = ProviderFactory.getInstance();
- ThreadPoolExecutor executor = new ThreadPoolExecutor(5, 5, 0,
TimeUnit.SECONDS,
+ ThreadPoolExecutor executor = new ThreadPoolExecutor(50, 50, 0,
TimeUnit.SECONDS,
new
ArrayBlockingQueue<Runnable>(10));
CountDownLatch startSignal = new CountDownLatch(1);
- CountDownLatch doneSignal = new CountDownLatch(5);
+ CountDownLatch doneSignal = new CountDownLatch(50);
- executor.execute(new TestRunnable(pf, startSignal, doneSignal,
"http://localhost:8080/base/1"));
- executor.execute(new TestRunnable(pf, startSignal, doneSignal,
"http://localhost:8080/base/2"));
- executor.execute(new TestRunnable(pf, startSignal, doneSignal,
"http://localhost:8080/base/3"));
- executor.execute(new TestRunnable(pf, startSignal, doneSignal,
"http://localhost:8080/base/4"));
- executor.execute(new TestRunnable(pf, startSignal, doneSignal,
"http://localhost:8080/base/5"));
+ addThreads(executor, pf, startSignal, doneSignal, 50);
startSignal.countDown();
- doneSignal.await(10, TimeUnit.SECONDS);
+ doneSignal.await(60, TimeUnit.SECONDS);
executor.shutdownNow();
assertEquals("Not all invocations have completed", 0,
doneSignal.getCount());
checkJaxbProvider(pf);
}
+ private void addThreads(ThreadPoolExecutor executor, ProviderFactory pf,
+ CountDownLatch startSignal, CountDownLatch
doneSignal, int count) {
+
+ for (int i = 1; i <= count; i++) {
+ executor.execute(new TestRunnable(pf, startSignal, doneSignal,
+ "http://localhost:8080/base/" +
i));
+ }
+ }
+
private void doTestDefaultJaxbProviderCloned(ProviderFactory pf, String
property) {
Message message = new MessageImpl();
message.put(Message.QUERY_STRING, "uri=" + property);
@@ -179,7 +191,6 @@ public class ProviderFactoryTest extends
assertEquals(1, uriQuery.size());
assertEquals(property, uriQuery.get(0));
-
MessageBodyReader customJaxbReader2 =
pf.createMessageBodyReader((Class<?>)Book.class, null, null,
MediaType.TEXT_XML_TYPE, message);
assertSame(customJaxbReader, customJaxbReader2);
@@ -812,6 +823,7 @@ public class ProviderFactoryTest extends
ProviderFactoryTest.this.doTestDefaultJaxbProviderCloned(pf,
property);
doneSignal.countDown();
} catch (Exception ex) {
+ ex.printStackTrace();
Assert.fail(ex.getMessage());
}