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 2012/10/31 18:17:08 UTC

svn commit: r1404256 - in /cxf/trunk/rt/frontend/jaxrs/src: main/java/org/apache/cxf/jaxrs/ main/java/org/apache/cxf/jaxrs/client/ main/java/org/apache/cxf/jaxrs/provider/ test/java/org/apache/cxf/jaxrs/client/

Author: sergeyb
Date: Wed Oct 31 17:17:08 2012
New Revision: 1404256

URL: http://svn.apache.org/viewvc?rev=1404256&view=rev
Log:
Support for ParamConverterProvider at the client side

Modified:
    cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/AbstractJAXRSFactoryBean.java
    cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/client/AbstractClient.java
    cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/client/ClientProxyImpl.java
    cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/client/WebClient.java
    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/client/WebClientTest.java

Modified: cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/AbstractJAXRSFactoryBean.java
URL: http://svn.apache.org/viewvc/cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/AbstractJAXRSFactoryBean.java?rev=1404256&r1=1404255&r2=1404256&view=diff
==============================================================================
--- cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/AbstractJAXRSFactoryBean.java (original)
+++ cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/AbstractJAXRSFactoryBean.java Wed Oct 31 17:17:08 2012
@@ -317,7 +317,7 @@ public class AbstractJAXRSFactoryBean ex
     }
     
     protected ProviderFactory setupFactory(Endpoint ep) { 
-        ProviderFactory factory = ProviderFactory.getInstance(getBus()); 
+        ProviderFactory factory = ProviderFactory.createInstance(getBus()); 
         if (entityProviders != null) {
             factory.setUserProviders(entityProviders); 
         }
@@ -329,6 +329,7 @@ public class AbstractJAXRSFactoryBean ex
             factory.setSchemaLocations(schemaLocations);
         }
         ep.put(ProviderFactory.class.getName(), factory);
+        getBus().setProperty(ProviderFactory.class.getName(), factory);
         return factory;
     }
 

Modified: cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/client/AbstractClient.java
URL: http://svn.apache.org/viewvc/cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/client/AbstractClient.java?rev=1404256&r1=1404255&r2=1404256&view=diff
==============================================================================
--- cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/client/AbstractClient.java (original)
+++ cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/client/AbstractClient.java Wed Oct 31 17:17:08 2012
@@ -48,6 +48,7 @@ import javax.ws.rs.core.MultivaluedMap;
 import javax.ws.rs.core.Response;
 import javax.ws.rs.core.Response.ResponseBuilder;
 import javax.ws.rs.core.UriBuilder;
+import javax.ws.rs.ext.ParamConverter;
 import javax.ws.rs.ext.ReaderInterceptor;
 import javax.ws.rs.ext.WriterInterceptor;
 import javax.xml.stream.XMLStreamReader;
@@ -118,10 +119,10 @@ public abstract class AbstractClient imp
             if (values.length > 1) {
                 throw new IllegalArgumentException("Content-Type can have a single value only");
             }
-            type(values[0].toString());
+            type(convertParamValue(values[0]));
         } else {
             for (Object o : values) {
-                possiblyAddHeader(name, o.toString());
+                possiblyAddHeader(name, convertParamValue(o));
             }
         }
         return this;
@@ -611,44 +612,76 @@ public abstract class AbstractClient imp
                                  Exchange exchange, 
                                  Map<String, Object> invContext) throws Throwable;
     
-    // TODO : shall we just do the reflective invocation here ?
-    protected static void addParametersToBuilder(UriBuilder ub, String paramName, Object pValue,
-                                                 ParameterType pt) {
+    
+    protected void addMatrixQueryParamsToBuilder(UriBuilder ub, 
+                                                 String paramName, 
+                                                 ParameterType pt,
+                                                 Object... pValues) {
+        if (pValues == null) {
+            throw new IllegalArgumentException("Null parameters are not supported");
+        }
         if (pt != ParameterType.MATRIX && pt != ParameterType.QUERY) {
             throw new IllegalArgumentException("This method currently deal "
                                                + "with matrix and query parameters only");
         }
         if (!"".equals(paramName)) {
-            
-            if (InjectionUtils.isSupportedCollectionOrArray(pValue.getClass())) {
-                Collection<?> c = pValue.getClass().isArray() 
-                    ? Arrays.asList((Object[]) pValue) : (Collection<?>) pValue;
-                for (Iterator<?> it = c.iterator(); it.hasNext();) {
-                    addToBuilder(ub, paramName, it.next(), pt);
+            for (Object pValue : pValues) {
+                if (InjectionUtils.isSupportedCollectionOrArray(pValue.getClass())) {
+                    Collection<?> c = pValue.getClass().isArray() 
+                        ? Arrays.asList((Object[]) pValue) : (Collection<?>) pValue;
+                    for (Iterator<?> it = c.iterator(); it.hasNext();) {
+                        addMatrixOrQueryToBuilder(ub, paramName, it.next(), pt);
+                    }
+                } else { 
+                    addMatrixOrQueryToBuilder(ub, paramName, pValue, pt); 
                 }
-            } else { 
-                addToBuilder(ub, paramName, pValue, pt); 
-            }
-                
+            }    
                     
         } else {
+            Object pValue = pValues[0];
             MultivaluedMap<String, Object> values = 
                 InjectionUtils.extractValuesFromBean(pValue, "");
             for (Map.Entry<String, List<Object>> entry : values.entrySet()) {
                 for (Object v : entry.getValue()) {
-                    addToBuilder(ub, entry.getKey(), v, pt);
+                    addMatrixOrQueryToBuilder(ub, entry.getKey(), v, pt);
                 }
             }
         }
     }
 
-    private static void addToBuilder(UriBuilder ub, String paramName, Object pValue,
-                                     ParameterType pt) {
+    private void addMatrixOrQueryToBuilder(UriBuilder ub, 
+                                           String paramName, 
+                                           Object pValue,
+                                           ParameterType pt) {
+        Object convertedValue = convertParamValue(pValue);
         if (pt == ParameterType.MATRIX) {
-            ub.matrixParam(paramName, pValue.toString());
+            ub.matrixParam(paramName, convertedValue);
         } else {
-            ub.queryParam(paramName, pValue.toString());
+            ub.queryParam(paramName, convertedValue);
+        }
+    }
+    
+    
+    protected String convertParamValue(Object pValue) {
+        Class<?> pClass = pValue.getClass();
+        if (pClass == String.class || pClass.isPrimitive()) {
+            return pValue.toString();
+        }
+        
+        // A little scope for some optimization exists, particularly,
+        // it is feasible a complex object may need to be repeatedly converted
+        // so we can keep a map of ParamConverter on the bus, that said
+        // it seems an over-optimization at this stage, it's a 5% case;
+        // typical requests have a limited number of simple URI parameters
+        ProviderFactory pf = ProviderFactory.getInstance(cfg.getBus());
+        if (pf != null) {
+            @SuppressWarnings("unchecked")
+            ParamConverter<Object> prov = (ParamConverter<Object>)pf.createParameterHandler(pClass);
+            if (prov != null) {
+                return prov.toString(pValue);
+            }
         }
+        return pValue.toString();
     }
     
     protected static void reportMessageHandlerProblem(String name, Class<?> cls, MediaType ct, 

Modified: cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/client/ClientProxyImpl.java
URL: http://svn.apache.org/viewvc/cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/client/ClientProxyImpl.java?rev=1404256&r1=1404255&r2=1404256&view=diff
==============================================================================
--- cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/client/ClientProxyImpl.java (original)
+++ cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/client/ClientProxyImpl.java Wed Oct 31 17:17:08 2012
@@ -397,7 +397,7 @@ public class ClientProxyImpl extends Abs
         for (String varName : methodVars) {
             Parameter p = paramsMap.remove(varName);
             if (p != null) {
-                list.add(params[p.getIndex()]);
+                list.add(convertParamValue(params[p.getIndex()]));
             }
         }
         
@@ -407,7 +407,7 @@ public class ClientProxyImpl extends Abs
                 for (Iterator<String> it = valuesMap.keySet().iterator(); it.hasNext(); index++) {
                     if (it.next().equals(p.getName()) && index < list.size()) {
                         list.remove(index);
-                        list.add(index, params[p.getIndex()]);
+                        list.add(index, convertParamValue(params[p.getIndex()]));
                         break;
                     }
                 }
@@ -423,23 +423,23 @@ public class ClientProxyImpl extends Abs
         return  map.get(key) == null ? Collections.EMPTY_LIST : map.get(key);
     }
     
-    private static void handleQueries(MultivaluedMap<ParameterType, Parameter> map, 
+    private void handleQueries(MultivaluedMap<ParameterType, Parameter> map, 
                                       Object[] params,
                                       UriBuilder ub) {
         List<Parameter> qs = getParameters(map, ParameterType.QUERY);
         for (Parameter p : qs) {
             if (params[p.getIndex()] != null) {
-                addParametersToBuilder(ub, p.getName(), params[p.getIndex()], ParameterType.QUERY);
+                addMatrixQueryParamsToBuilder(ub, p.getName(), ParameterType.QUERY, params[p.getIndex()]);
             }
         }
     }
     
-    private static void handleMatrixes(MultivaluedMap<ParameterType, Parameter> map, Object[] params,
+    private void handleMatrixes(MultivaluedMap<ParameterType, Parameter> map, Object[] params,
                                 UriBuilder ub) {
         List<Parameter> mx = getParameters(map, ParameterType.MATRIX);
         for (Parameter p : mx) {
             if (params[p.getIndex()] != null) {
-                addParametersToBuilder(ub, p.getName(), params[p.getIndex()], ParameterType.MATRIX);
+                addMatrixQueryParamsToBuilder(ub, p.getName(), ParameterType.MATRIX, params[p.getIndex()]);
             }
         }
     }
@@ -457,10 +457,11 @@ public class ClientProxyImpl extends Abs
                     Collection<?> c = pValue.getClass().isArray() 
                         ? Arrays.asList((Object[]) pValue) : (Collection<?>) pValue;
                     for (Iterator<?> it = c.iterator(); it.hasNext();) {
-                        FormUtils.addPropertyToForm(form, p.getName(), it.next());
+                        FormUtils.addPropertyToForm(form, p.getName(), convertParamValue(it.next()));
                     }
                 } else { 
-                    FormUtils.addPropertyToForm(form, p.getName(), pValue); 
+                    String name = p.getName();
+                    FormUtils.addPropertyToForm(form, name, name.isEmpty() ? pValue : convertParamValue(pValue)); 
                 }
                 
             }
@@ -489,7 +490,7 @@ public class ClientProxyImpl extends Abs
         List<Parameter> hs = getParameters(map, ParameterType.HEADER);
         for (Parameter p : hs) {
             if (params[p.getIndex()] != null) {
-                headers.add(p.getName(), params[p.getIndex()].toString());
+                headers.add(p.getName(), convertParamValue(params[p.getIndex()]));
             }
         }
     }
@@ -505,7 +506,9 @@ public class ClientProxyImpl extends Abs
         List<Parameter> cs = getParameters(map, ParameterType.COOKIE);
         for (Parameter p : cs) {
             if (params[p.getIndex()] != null) {
-                headers.add(HttpHeaders.COOKIE, p.getName() + '=' + params[p.getIndex()].toString());
+                headers.add(HttpHeaders.COOKIE, p.getName() 
+                            + '=' 
+                            + convertParamValue(params[p.getIndex()].toString()));
             }
         }
     }

Modified: cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/client/WebClient.java
URL: http://svn.apache.org/viewvc/cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/client/WebClient.java?rev=1404256&r1=1404255&r2=1404256&view=diff
==============================================================================
--- cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/client/WebClient.java (original)
+++ cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/client/WebClient.java Wed Oct 31 17:17:08 2012
@@ -506,7 +506,7 @@ public class WebClient extends AbstractC
      * @return updated WebClient
      */
     public WebClient path(Object path) {
-        getCurrentBuilder().path(path.toString());
+        getCurrentBuilder().path(convertParamValue(path));
         
         return this;
     }
@@ -530,12 +530,7 @@ public class WebClient extends AbstractC
      * @return updated WebClient
      */
     public WebClient query(String name, Object ...values) {
-        if (!"".equals(name)) {
-            getCurrentBuilder().queryParam(name, values);
-        } else {
-            addParametersToBuilder(getCurrentBuilder(), name, values[0], ParameterType.QUERY);
-        }
-        
+        addMatrixQueryParamsToBuilder(getCurrentBuilder(), name, ParameterType.QUERY, values);
         return this;
     }
     
@@ -546,12 +541,7 @@ public class WebClient extends AbstractC
      * @return updated WebClient
      */
     public WebClient matrix(String name, Object ...values) {
-        if (!"".equals(name)) {
-            getCurrentBuilder().matrixParam(name, values);
-        } else {
-            addParametersToBuilder(getCurrentBuilder(), name, values[0], ParameterType.MATRIX);
-        }
-        
+        addMatrixQueryParamsToBuilder(getCurrentBuilder(), name, ParameterType.MATRIX, values);
         return this;
     }
     

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=1404256&r1=1404255&r2=1404256&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 Oct 31 17:17:08 2012
@@ -220,10 +220,14 @@ public final class ProviderFactory {
         return new ProviderFactory(BusFactory.getThreadDefaultBus());
     }
     
-    public static ProviderFactory getInstance(Bus bus) {
+    public static ProviderFactory createInstance(Bus bus) {
         return new ProviderFactory(bus);
     }
     
+    public static ProviderFactory getInstance(Bus bus) {
+        return (ProviderFactory)bus.getProperty(ProviderFactory.class.getName());
+    }
+    
     public static ProviderFactory getInstance(Message m) {
         Endpoint e = m.getExchange().get(Endpoint.class);
         return (ProviderFactory)e.get(ProviderFactory.class.getName());

Modified: cxf/trunk/rt/frontend/jaxrs/src/test/java/org/apache/cxf/jaxrs/client/WebClientTest.java
URL: http://svn.apache.org/viewvc/cxf/trunk/rt/frontend/jaxrs/src/test/java/org/apache/cxf/jaxrs/client/WebClientTest.java?rev=1404256&r1=1404255&r2=1404256&view=diff
==============================================================================
--- cxf/trunk/rt/frontend/jaxrs/src/test/java/org/apache/cxf/jaxrs/client/WebClientTest.java (original)
+++ cxf/trunk/rt/frontend/jaxrs/src/test/java/org/apache/cxf/jaxrs/client/WebClientTest.java Wed Oct 31 17:17:08 2012
@@ -19,7 +19,13 @@
 
 package org.apache.cxf.jaxrs.client;
 
+import java.lang.annotation.Annotation;
+import java.lang.reflect.Type;
 import java.net.URI;
+import java.util.Collections;
+
+import javax.ws.rs.ext.ParamConverter;
+import javax.ws.rs.ext.ParamConverterProvider;
 
 import org.apache.cxf.jaxrs.resources.BookInterface;
 import org.apache.cxf.jaxrs.resources.BookStore;
@@ -248,6 +254,16 @@ public class WebClientTest extends Asser
     }
     
     @Test
+    public void testWebClientPathParamConverter() {
+        WebClient wc = WebClient.create("http://foo",
+                                        Collections.singletonList(new ParamConverterProviderImpl()));
+        wc.path(new ComplexObject());
+        wc.query("param", new ComplexObject());
+        assertEquals("http://foo/complex?param=complex", wc.getCurrentURI().toString());
+        
+    }
+    
+    @Test
     public void testProxyConfiguration() {
         // interface
         BookInterface proxy = JAXRSClientFactory.create("http://foo", BookInterface.class);
@@ -257,4 +273,31 @@ public class WebClientTest extends Asser
         assertNotNull(WebClient.getConfig(proxy2) != null);
     }
     
+    private static class ParamConverterProviderImpl implements ParamConverterProvider {
+        
+        @SuppressWarnings("unchecked")
+        @Override
+        public <T> ParamConverter<T> getConverter(Class<T> rawType, Type genericType, Annotation[] annotations) {
+            return (ParamConverter<T>)new ParamConverterImpl();
+        }
+        
+    }
+    
+    private static class ParamConverterImpl implements ParamConverter<ComplexObject> {
+
+        @Override
+        public ComplexObject fromString(String value) throws IllegalArgumentException {
+            // TODO Auto-generated method stub
+            return null;
+        }
+
+        @Override
+        public String toString(ComplexObject value) throws IllegalArgumentException {
+            return "complex";
+        }
+    }
+    
+    private static class ComplexObject {
+        
+    }
 }