Author: sergeyb
Date: Tue Apr 12 14:23:20 2011
New Revision: 1091428

URL: http://svn.apache.org/viewvc?rev=1091428&view=rev
Log:
[JAX-RS] Some more enhancements to the way adapters are applied to JAX-RS params

Modified:
    
cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/provider/AbstractJAXBProvider.java
    
cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/utils/InjectionUtils.java
    
cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/utils/JAXBUtils.java
    cxf/trunk/rt/frontend/jaxrs/src/test/java/org/apache/cxf/jaxrs/Customer.java
    
cxf/trunk/rt/frontend/jaxrs/src/test/java/org/apache/cxf/jaxrs/utils/JAXRSUtilsTest.java

Modified: 
cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/provider/AbstractJAXBProvider.java
URL: 
http://svn.apache.org/viewvc/cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/provider/AbstractJAXBProvider.java?rev=1091428&r1=1091427&r2=1091428&view=diff
==============================================================================
--- 
cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/provider/AbstractJAXBProvider.java
 (original)
+++ 
cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/provider/AbstractJAXBProvider.java
 Tue Apr 12 14:23:20 2011
@@ -503,16 +503,7 @@ public abstract class AbstractJAXBProvid
             theType = type;
         }
         XmlJavaTypeAdapter adapter = getAdapter(theType, anns);
-        if (adapter != null) {
-            if (adapter.type() != XmlJavaTypeAdapter.DEFAULT.class) {
-                theType = adapter.type();
-            } else {
-                Type[] types = 
InjectionUtils.getActualTypes(adapter.value().getGenericSuperclass());
-                if (types != null && types.length == 2) {
-                    theType = InjectionUtils.getActualType(types[0]);
-                }
-            }
-        }
+        theType = 
org.apache.cxf.jaxrs.utils.JAXBUtils.getTypeFromAdapter(adapter, theType, 
false);
         
         return theType;
     }

Modified: 
cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/utils/InjectionUtils.java
URL: 
http://svn.apache.org/viewvc/cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/utils/InjectionUtils.java?rev=1091428&r1=1091427&r2=1091428&view=diff
==============================================================================
--- 
cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/utils/InjectionUtils.java
 (original)
+++ 
cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/utils/InjectionUtils.java
 Tue Apr 12 14:23:20 2011
@@ -305,34 +305,42 @@ public final class InjectionUtils {
                 throw new WebApplicationException(nfe, 
Response.Status.BAD_REQUEST);
             }
         }
+        
+        boolean adapterHasToBeUsed = false;
+        Class<?> valueType = JAXBUtils.getValueTypeFromAdapter(pClass, pClass, 
paramAnns);
+        if (valueType != pClass) {
+            pClass = valueType;
+            adapterHasToBeUsed = true;
+        }
+        
+        Object result = null;
         // check constructors accepting a single String value
         try {
             Constructor<?> c = pClass.getConstructor(new 
Class<?>[]{String.class});
-            return c.newInstance(new Object[]{value});
+            result = c.newInstance(new Object[]{value});
         } catch (NoSuchMethodException ex) {
             // try valueOf
         } catch (WebApplicationException ex) {
             throw ex;
         } catch (Exception ex) {
-            Object result = createFromParameterHandler(value, pClass, message);
-            if (result != null) {
-                return result;
+            result = createFromParameterHandler(value, pClass, message);
+            if (result == null) {
+                LOG.severe(new 
org.apache.cxf.common.i18n.Message("CLASS_CONSTRUCTOR_FAILURE", 
+                                                                   BUNDLE, 
+                                                                   
pClass.getName()).toString());
+                throw new WebApplicationException(ex, 
HttpUtils.getParameterFailureStatus(pType));
             }
-            LOG.severe(new 
org.apache.cxf.common.i18n.Message("CLASS_CONSTRUCTOR_FAILURE", 
-                                                               BUNDLE, 
-                                                               
pClass.getName()).toString());
-            throw new WebApplicationException(ex, 
HttpUtils.getParameterFailureStatus(pType));
         }
-        
-        Object result = null;
-        // check for valueOf(String) static methods
-        String[] methodNames = pClass.isEnum() 
-            ? new String[] {"fromString", "fromValue", "valueOf"} 
-            : new String[] {"valueOf", "fromString"};
-        for (String mName : methodNames) {   
-            result = evaluateFactoryMethod(value, pClass, pType, mName);
-            if (result != null) {
-                break;
+        if (result == null) {
+            // check for valueOf(String) static methods
+            String[] methodNames = pClass.isEnum() 
+                ? new String[] {"fromString", "fromValue", "valueOf"} 
+                : new String[] {"valueOf", "fromString"};
+            for (String mName : methodNames) {   
+                result = evaluateFactoryMethod(value, pClass, pType, mName);
+                if (result != null) {
+                    break;
+                }
             }
         }
         
@@ -340,12 +348,12 @@ public final class InjectionUtils {
             result = createFromParameterHandler(value, pClass, message);
         }
         
-        if (result == null) {
+        if (result != null && adapterHasToBeUsed) {
             // as the last resort, try XmlJavaTypeAdapters
             try {
-                result = JAXBUtils.convertWithAdapter(value, paramAnns);
+                result = JAXBUtils.convertWithAdapter(result, paramAnns);
             } catch (Throwable ex) {
-                // ignore - may be to do with JAXB classes not being available 
+                result = null; 
             }
         }
         

Modified: 
cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/utils/JAXBUtils.java
URL: 
http://svn.apache.org/viewvc/cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/utils/JAXBUtils.java?rev=1091428&r1=1091427&r2=1091428&view=diff
==============================================================================
--- 
cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/utils/JAXBUtils.java
 (original)
+++ 
cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/utils/JAXBUtils.java
 Tue Apr 12 14:23:20 2011
@@ -19,6 +19,7 @@
 package org.apache.cxf.jaxrs.utils;
 
 import java.lang.annotation.Annotation;
+import java.lang.reflect.Type;
 
 import javax.xml.bind.annotation.adapters.XmlAdapter;
 import javax.xml.bind.annotation.adapters.XmlJavaTypeAdapter;
@@ -28,13 +29,45 @@ public final class JAXBUtils {
         
     }
     
-    public static Object convertWithAdapter(String value, Annotation[] anns) 
throws Exception {
-        
-        return useAdapter(value,
+    public static Object convertWithAdapter(Object obj, 
+                                            Annotation[] anns) {
+        return useAdapter(obj, 
                           AnnotationUtils.getAnnotation(anns, 
XmlJavaTypeAdapter.class),
-                          false,
-                          null);
-            
+                          false, 
+                          obj);
+    }
+    
+    public static Class<?> getValueTypeFromAdapter(Class<?> expectedBoundType,
+                                                   Class<?> defaultClass,
+                                                   Annotation[] anns) {
+        try {
+            XmlJavaTypeAdapter adapter = AnnotationUtils.getAnnotation(anns, 
XmlJavaTypeAdapter.class);
+            if (adapter != null) {
+                Class<?> boundType = JAXBUtils.getTypeFromAdapter(adapter, 
null, true);
+                if (boundType != null && 
boundType.isAssignableFrom(expectedBoundType)) {
+                    return JAXBUtils.getTypeFromAdapter(adapter, null, false);
+                }
+            }
+        } catch (Throwable ex) {
+            // ignore
+        }
+        return defaultClass; 
+    }
+    
+    public static Class<?> getTypeFromAdapter(XmlJavaTypeAdapter adapter, 
Class<?> theType,
+                                              boolean boundType) {
+        if (adapter != null) {
+            if (adapter.type() != XmlJavaTypeAdapter.DEFAULT.class) {
+                theType = adapter.type();
+            } else {
+                Type[] types = 
InjectionUtils.getActualTypes(adapter.value().getGenericSuperclass());
+                if (types != null && types.length == 2) {
+                    int index = boundType ? 1 : 0;
+                    theType = InjectionUtils.getActualType(types[index]);
+                }
+            }
+        }
+        return theType;
     }
     
     public static Object useAdapter(Object obj, 

Modified: 
cxf/trunk/rt/frontend/jaxrs/src/test/java/org/apache/cxf/jaxrs/Customer.java
URL: 
http://svn.apache.org/viewvc/cxf/trunk/rt/frontend/jaxrs/src/test/java/org/apache/cxf/jaxrs/Customer.java?rev=1091428&r1=1091427&r2=1091428&view=diff
==============================================================================
--- 
cxf/trunk/rt/frontend/jaxrs/src/test/java/org/apache/cxf/jaxrs/Customer.java 
(original)
+++ 
cxf/trunk/rt/frontend/jaxrs/src/test/java/org/apache/cxf/jaxrs/Customer.java 
Tue Apr 12 14:23:20 2011
@@ -180,6 +180,12 @@ public class Customer extends AbstractCu
         
     }
     
+    public void testXmlAdapter2(@QueryParam("a") 
+                               @XmlJavaTypeAdapter(CustomerBeanAdapter2.class) 
+                               CustomerBean cb) {
+        
+    }
+    
     public void testPathBean(@PathParam("") CustomerBean cb) {
         
     }
@@ -437,4 +443,36 @@ public class Customer extends AbstractCu
         }
         
     }
+    
+    public static final class ABean {
+        private String value;
+        private ABean(String value) {
+            this.value = value;
+        }
+        
+        public String getValue() {
+            return value;
+        }
+        
+        public static ABean fromString(String value) {
+            return new ABean(value);
+        }
+    }
+    
+    public static class CustomerBeanAdapter2 extends XmlAdapter<ABean, 
CustomerBean> {
+
+        @Override
+        public CustomerBean unmarshal(ABean value) throws Exception {
+            CustomerBean bean = new CustomerBean();
+            bean.setA(value.getValue());
+            return bean;
+        }
+
+        @Override
+        public ABean marshal(CustomerBean v) throws Exception {
+            // TODO Auto-generated method stub
+            return null;
+        }
+        
+    }
 };

Modified: 
cxf/trunk/rt/frontend/jaxrs/src/test/java/org/apache/cxf/jaxrs/utils/JAXRSUtilsTest.java
URL: 
http://svn.apache.org/viewvc/cxf/trunk/rt/frontend/jaxrs/src/test/java/org/apache/cxf/jaxrs/utils/JAXRSUtilsTest.java?rev=1091428&r1=1091427&r2=1091428&view=diff
==============================================================================
--- 
cxf/trunk/rt/frontend/jaxrs/src/test/java/org/apache/cxf/jaxrs/utils/JAXRSUtilsTest.java
 (original)
+++ 
cxf/trunk/rt/frontend/jaxrs/src/test/java/org/apache/cxf/jaxrs/utils/JAXRSUtilsTest.java
 Tue Apr 12 14:23:20 2011
@@ -868,6 +868,21 @@ public class JAXRSUtilsTest extends Asse
         assertEquals("aValue", bean.getA());
     }
     
+    @Test
+    public void testXmlAdapterBean2() throws Exception {
+        Class[] argType = {Customer.CustomerBean.class};
+        Method m = Customer.class.getMethod("testXmlAdapter2", argType);
+        Message messageImpl = createMessage();
+        messageImpl.put(Message.QUERY_STRING, "a=aValue");
+
+        List<Object> params = JAXRSUtils.processParameters(new 
OperationResourceInfo(m, null), 
+                                                           null, messageImpl);
+        assertEquals(1, params.size());
+        
+        Customer.CustomerBean bean = (Customer.CustomerBean)params.get(0);
+        assertEquals("aValue", bean.getA());
+    }
+    
     
     @Test
     public void testPathParametersBean() throws Exception {


Reply via email to