cxf-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From serg...@apache.org
Subject svn commit: r1089390 - in /cxf/trunk/rt/frontend/jaxrs/src: main/java/org/apache/cxf/jaxrs/provider/ProviderFactory.java test/java/org/apache/cxf/jaxrs/provider/ProviderFactoryTest.java
Date Wed, 06 Apr 2011 10:37:41 GMT
Author: sergeyb
Date: Wed Apr  6 10:37:41 2011
New Revision: 1089390

URL: http://svn.apache.org/viewvc?rev=1089390&view=rev
Log:
[CXF-3415] Making sure contexts are injected into cloned JAXB providers

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=1089390&r1=1089389&r2=1089390&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 Apr  6 10:37:41 2011
@@ -97,8 +97,6 @@ public final class ProviderFactory {
     private RequestPreprocessor requestPreprocessor;
     private ProviderInfo<Application> application;
     
-    private Set<Object> clonedProviders = new HashSet<Object>();
-    
     private ProviderFactory() {
     }
     
@@ -289,33 +287,46 @@ public final class ProviderFactory {
                                                       m);
         
         //If none found try the default ones
-        if (mr != null ||  this == SHARED_FACTORY) {
+        if (mr != null) {
             return mr;
         }
-        mr = SHARED_FACTORY.createMessageBodyReader(bodyType, parameterType, 
-                                                        parameterAnnotations, mediaType,
m);
-        return (MessageBodyReader)cloneSharedProviderIfNeeded(mr);
-    }
-    
-    private Object cloneSharedProviderIfNeeded(Object sharedProvider) {
-        if (sharedProvider != null) {
-            String clsName = sharedProvider.getClass().getName();
-            if (JAXB_PROVIDER_NAME.equals(clsName) || JSON_PROVIDER_NAME.equals(clsName))
{
-                try {
-                    synchronized (this) {
-                        for (Object cloned : clonedProviders) {
-                            if (cloned.getClass().getName().equals(clsName)) {
-                                return cloned;
-                            }
+        mr = SHARED_FACTORY.chooseMessageReader(bodyType,
+                                                parameterType,
+                                                parameterAnnotations,
+                                                mediaType,
+                                                m);
+        return (MessageBodyReader)cloneSharedProviderIfNeeded(mr, m);
+    }
+    
+    private boolean isJaxbBasedProvider(Object sharedProvider) {
+        String clsName = sharedProvider.getClass().getName();
+        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;
                         }
-                        Object provider = sharedProvider.getClass().newInstance();
-                        clonedProviders.add(provider);
-                        setProviders(false, provider);
-                        return provider;
                     }
-                } catch (Exception ex) {
-                    // won't happen at this stage
+                    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;
@@ -363,12 +374,15 @@ public final class ProviderFactory {
                                                       m);
         
         //If none found try the default ones
-        if (mw != null || this == SHARED_FACTORY) {
+        if (mw != null) {
             return mw;
         }
-        mw = SHARED_FACTORY.createMessageBodyWriter(bodyType, parameterType, 
-                                                        parameterAnnotations, mediaType,
m);
-        return (MessageBodyWriter)cloneSharedProviderIfNeeded(mw);
+        mw = SHARED_FACTORY.chooseMessageWriter(bodyType,
+                                                parameterType,
+                                                parameterAnnotations,
+                                                mediaType,
+                                                m);
+        return (MessageBodyWriter)cloneSharedProviderIfNeeded(mw, m);
     }
     
 //CHECKSTYLE:OFF       
@@ -426,6 +440,9 @@ public final class ProviderFactory {
         for (List<?> list : providerLists) {
             for (Object p : list) {
                 ProviderInfo pi = (ProviderInfo)p;
+                //if (ProviderFactory.SHARED_FACTORY == this && isJaxbBasedProvider(pi.getProvider()))
{
+                //    continue;
+                //}
                 InjectionUtils.injectContextProxies(pi, pi.getProvider());
             }
         }
@@ -468,8 +485,10 @@ public final class ProviderFactory {
         for (ProviderInfo<MessageBodyReader> ep : messageReaders) {
             if (matchesReaderCriterias(ep.getProvider(), type, genericType, annotations,
mediaType)) {
                 if (this == SHARED_FACTORY) {
-                    InjectionUtils.injectContextFields(ep.getProvider(), ep, m);
-                    InjectionUtils.injectContextMethods(ep.getProvider(), ep, m);
+                    if (!isJaxbBasedProvider(ep.getProvider())) {
+                        InjectionUtils.injectContextFields(ep.getProvider(), ep, m);
+                        InjectionUtils.injectContextMethods(ep.getProvider(), ep, m);
+                    }
                     return ep.getProvider();
                 }
                 handleMapper((List)candidates, ep, type, m, MessageBodyReader.class);
@@ -522,8 +541,10 @@ public final class ProviderFactory {
         for (ProviderInfo<MessageBodyWriter> ep : messageWriters) {
             if (matchesWriterCriterias(ep.getProvider(), type, genericType, annotations,
mediaType)) {
                 if (this == SHARED_FACTORY) {
-                    InjectionUtils.injectContextFields(ep.getProvider(), ep, m);
-                    InjectionUtils.injectContextMethods(ep.getProvider(), ep, m);
+                    if (!isJaxbBasedProvider(ep.getProvider())) {
+                        InjectionUtils.injectContextFields(ep.getProvider(), ep, m);
+                        InjectionUtils.injectContextMethods(ep.getProvider(), ep, m);
+                    }
                     return ep.getProvider();
                 }
                 handleMapper((List)candidates, ep, type, m, MessageBodyWriter.class);
@@ -700,9 +721,7 @@ public final class ProviderFactory {
     }
 
     public void initProviders(List<ClassResourceInfo> cris) {
-        Set<Object> set = new HashSet<Object>();
-        set.addAll(messageReaders);
-        set.addAll(messageWriters);
+        Set<Object> set = getReadersWriters();
         for (Object o : set) {
             Object provider = ((ProviderInfo)o).getProvider();
             if (provider instanceof AbstractConfigurableProvider) {
@@ -714,6 +733,13 @@ public final class ProviderFactory {
         }
     }
     
+    Set<Object> getReadersWriters() {
+        Set<Object> set = new HashSet<Object>();
+        set.addAll(messageReaders);
+        set.addAll(messageWriters);
+        return set;
+    }
+    
     private static class ExceptionMapperComparator implements 
         Comparator<ExceptionMapper<? extends Throwable>> {
 

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=1089390&r1=1089389&r2=1089390&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
Wed Apr  6 10:37:41 2011
@@ -29,6 +29,10 @@ import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.Collections;
 import java.util.List;
+import java.util.concurrent.ArrayBlockingQueue;
+import java.util.concurrent.CountDownLatch;
+import java.util.concurrent.ThreadPoolExecutor;
+import java.util.concurrent.TimeUnit;
 
 import javax.ws.rs.Consumes;
 import javax.ws.rs.Produces;
@@ -36,6 +40,7 @@ import javax.ws.rs.WebApplicationExcepti
 import javax.ws.rs.core.MediaType;
 import javax.ws.rs.core.MultivaluedMap;
 import javax.ws.rs.core.Response;
+import javax.ws.rs.core.UriInfo;
 import javax.ws.rs.ext.ContextResolver;
 import javax.ws.rs.ext.ExceptionMapper;
 import javax.ws.rs.ext.MessageBodyReader;
@@ -51,6 +56,7 @@ import org.apache.cxf.helpers.IOUtils;
 import org.apache.cxf.jaxrs.Customer;
 import org.apache.cxf.jaxrs.CustomerParameterHandler;
 import org.apache.cxf.jaxrs.JAXBContextProvider;
+import org.apache.cxf.jaxrs.ext.MessageContext;
 import org.apache.cxf.jaxrs.ext.ParameterHandler;
 import org.apache.cxf.jaxrs.ext.RequestHandler;
 import org.apache.cxf.jaxrs.impl.WebApplicationExceptionMapper;
@@ -67,6 +73,7 @@ import org.easymock.classextension.EasyM
 
 import org.junit.Assert;
 import org.junit.Before;
+import org.junit.Ignore;
 import org.junit.Test;
 
 public class ProviderFactoryTest extends Assert {
@@ -130,24 +137,73 @@ public class ProviderFactoryTest extends
     @Test
     public void testDefaultJaxbProviderCloned() {
         ProviderFactory pf = ProviderFactory.getInstance();
+        doTestDefaultJaxbProviderCloned(pf, "http://localhost:8080/base/");
+        checkJaxbProvider(pf);
+    }
+    
+    @Test
+    public void testDefaultJaxbProviderClonedMultipleThreads() throws Exception {
+        ProviderFactory pf = ProviderFactory.getInstance();
+        ThreadPoolExecutor executor = new ThreadPoolExecutor(5, 5, 0, TimeUnit.SECONDS,
+                                                             new ArrayBlockingQueue<Runnable>(10));
+        CountDownLatch startSignal = new CountDownLatch(1);
+        CountDownLatch doneSignal = new CountDownLatch(5);
+        
+        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"));
+        
+        startSignal.countDown();
+        doneSignal.await(10, TimeUnit.SECONDS);
+        executor.shutdownNow();
+        assertEquals("Not all invocations have completed", 0, doneSignal.getCount());
+        checkJaxbProvider(pf);
+    }
+    
+    private void doTestDefaultJaxbProviderCloned(ProviderFactory pf, String property) {
+        Message message = new MessageImpl();
+        message.put(Message.QUERY_STRING, "uri=" + property);
         MessageBodyReader customJaxbReader = pf.createMessageBodyReader((Class<?>)Book.class,
null, null, 
-                                                              MediaType.TEXT_XML_TYPE, new
MessageImpl());
+                                                              MediaType.TEXT_XML_TYPE, message);
         assertTrue(customJaxbReader instanceof JAXBElementProvider);
         
+        JAXBElementProvider provider = (JAXBElementProvider)customJaxbReader;
+        MessageContext mc = provider.getContext();
+        assertNotNull(mc);
+        UriInfo ui = mc.getUriInfo();
+        MultivaluedMap<String, String> queries = ui.getQueryParameters();
+        assertEquals(1, queries.size());
+        List<String> uriQuery = queries.get("uri");
+        assertEquals(1, uriQuery.size());
+        assertEquals(property, uriQuery.get(0));
+        
+        
         MessageBodyReader customJaxbReader2 = pf.createMessageBodyReader((Class<?>)Book.class,
null, null, 
-                                                              MediaType.TEXT_XML_TYPE, new
MessageImpl());
+                                                              MediaType.TEXT_XML_TYPE, message);
         assertSame(customJaxbReader, customJaxbReader2);
-        
+         
         MessageBodyWriter customJaxbWriter = pf.createMessageBodyWriter((Class<?>)Book.class,
null, null, 
-                                                              MediaType.TEXT_XML_TYPE, new
MessageImpl());
+                                                              MediaType.TEXT_XML_TYPE, message);
         assertSame(customJaxbReader, customJaxbWriter);
         
         MessageBodyReader jaxbReader = ProviderFactory.getSharedInstance().createMessageBodyReader(
-            (Class<?>)Book.class, null, null, MediaType.TEXT_XML_TYPE, new MessageImpl());
+            (Class<?>)Book.class, null, null, MediaType.TEXT_XML_TYPE, message);
         assertTrue(jaxbReader instanceof JAXBElementProvider);
         assertNotSame(jaxbReader, customJaxbReader);
     }
     
+    private void checkJaxbProvider(ProviderFactory pf) {
+        int count = 0;
+        for (Object provider : pf.getReadersWriters()) {
+            if (((ProviderInfo)provider).getProvider() instanceof JAXBElementProvider) {
+                count++;
+            }
+        }
+        assertEquals(1, count);
+    }
+    
     @Test
     public void testCustomJaxbProvider() {
         ProviderFactory pf = ProviderFactory.getInstance();
@@ -731,4 +787,35 @@ public class ProviderFactoryTest extends
         }
         
     }
+    
+    @Ignore
+    private class TestRunnable implements Runnable {
+
+        private CountDownLatch startSignal;
+        private CountDownLatch doneSignal;
+        private ProviderFactory pf;
+        private String property; 
+        public TestRunnable(ProviderFactory pf,
+                            CountDownLatch startSignal,
+                            CountDownLatch doneSignal,
+                            String property) {
+            this.startSignal = startSignal;
+            this.doneSignal = doneSignal;
+            this.pf = pf;
+            this.property = property;
+        }
+        
+        public void run() {
+            
+            try {
+                startSignal.await();
+                ProviderFactoryTest.this.doTestDefaultJaxbProviderCloned(pf, property);
+                doneSignal.countDown();
+            } catch (Exception ex) {
+                Assert.fail(ex.getMessage());
+            } 
+            
+        }
+        
+    }
 }



Mime
View raw message