You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@camel.apache.org by da...@apache.org on 2010/07/09 14:29:49 UTC

svn commit: r962504 - in /camel/trunk/components/camel-xstream/src: main/java/org/apache/camel/dataformat/xstream/AbstractXStreamWrapper.java test/java/org/apache/camel/dataformat/xstream/XStreamConfigurationTest.java

Author: davsclaus
Date: Fri Jul  9 12:29:48 2010
New Revision: 962504

URL: http://svn.apache.org/viewvc?rev=962504&view=rev
Log:
CAMEL-2915: Applied patch with thanks to Mark Proctor.

Modified:
    camel/trunk/components/camel-xstream/src/main/java/org/apache/camel/dataformat/xstream/AbstractXStreamWrapper.java
    camel/trunk/components/camel-xstream/src/test/java/org/apache/camel/dataformat/xstream/XStreamConfigurationTest.java

Modified: camel/trunk/components/camel-xstream/src/main/java/org/apache/camel/dataformat/xstream/AbstractXStreamWrapper.java
URL: http://svn.apache.org/viewvc/camel/trunk/components/camel-xstream/src/main/java/org/apache/camel/dataformat/xstream/AbstractXStreamWrapper.java?rev=962504&r1=962503&r2=962504&view=diff
==============================================================================
--- camel/trunk/components/camel-xstream/src/main/java/org/apache/camel/dataformat/xstream/AbstractXStreamWrapper.java (original)
+++ camel/trunk/components/camel-xstream/src/main/java/org/apache/camel/dataformat/xstream/AbstractXStreamWrapper.java Fri Jul  9 12:29:48 2010
@@ -18,6 +18,8 @@ package org.apache.camel.dataformat.xstr
 
 import java.io.InputStream;
 import java.io.OutputStream;
+import java.lang.reflect.Constructor;
+import java.lang.reflect.Method;
 import java.util.List;
 import java.util.Map;
 import java.util.Map.Entry;
@@ -33,6 +35,7 @@ import org.apache.camel.Exchange;
 import org.apache.camel.converter.jaxp.StaxConverter;
 import org.apache.camel.spi.ClassResolver;
 import org.apache.camel.spi.DataFormat;
+import org.apache.camel.util.ObjectHelper;
 
 /**
  * An abstract class which implement <a href="http://camel.apache.org/data-format.html">data format</a>
@@ -40,7 +43,6 @@ import org.apache.camel.spi.DataFormat;
  *
  * @version $Revision$
  */
-
 public abstract class AbstractXStreamWrapper implements DataFormat {
     
     private XStream xstream;
@@ -86,16 +88,39 @@ public abstract class AbstractXStreamWra
             }
 
             if (this.converters != null) {
-                for (String converter : this.converters) {
-                    xstream.registerConverter(resolver.resolveMandatoryClass(converter, Converter.class).newInstance());
+                for (String name : this.converters) {
+                    Class<Converter> converterClass = resolver.resolveMandatoryClass(name, Converter.class);
+                    Converter converter;
+
+                    Constructor con = null;
+                    try {
+                        con = converterClass.getDeclaredConstructor(new Class[] {XStream.class});
+                    } catch (Exception e) {
+                         //swallow as we null check in a moment.
+                    }
+                    if (con != null) {
+                        converter = (Converter) con.newInstance(xstream);
+                    } else {
+                        converter = converterClass.newInstance();
+                        try { 
+                            Method method = converterClass.getMethod("setXStream", new Class[] {XStream.class});
+                            if (method != null) {
+                                ObjectHelper.invokeMethod(method, converter, xstream);
+                            }
+                        } catch (Throwable e) {
+                            // swallow, as it just means the user never add an XStream setter, which is optional
+                        }
+                    }
+
+                    xstream.registerConverter(converter);
                 }
             }
         } catch (Exception e) {
-            throw new RuntimeException("Unable to build Xstream instance", e);
+            throw new RuntimeException("Unable to build XStream instance", e);
         }
 
         return xstream;
-    }
+    }    
 
     public StaxConverter getStaxConverter() {
         if (staxConverter == null) {

Modified: camel/trunk/components/camel-xstream/src/test/java/org/apache/camel/dataformat/xstream/XStreamConfigurationTest.java
URL: http://svn.apache.org/viewvc/camel/trunk/components/camel-xstream/src/test/java/org/apache/camel/dataformat/xstream/XStreamConfigurationTest.java?rev=962504&r1=962503&r2=962504&view=diff
==============================================================================
--- camel/trunk/components/camel-xstream/src/test/java/org/apache/camel/dataformat/xstream/XStreamConfigurationTest.java (original)
+++ camel/trunk/components/camel-xstream/src/test/java/org/apache/camel/dataformat/xstream/XStreamConfigurationTest.java Fri Jul  9 12:29:48 2010
@@ -21,6 +21,7 @@ import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
 
+import com.thoughtworks.xstream.XStream;
 import com.thoughtworks.xstream.converters.Converter;
 import com.thoughtworks.xstream.converters.MarshallingContext;
 import com.thoughtworks.xstream.converters.UnmarshallingContext;
@@ -38,6 +39,21 @@ import org.junit.Test;
  */
 public class XStreamConfigurationTest extends CamelTestSupport {
 
+    private static volatile boolean constructorInjected;
+    private static volatile boolean methodInjected;
+
+    @Override
+    public void setUp() throws Exception {
+        super.setUp();
+        constructorInjected = false;
+        methodInjected = false;
+    }
+
+    public void testXStreamInjection() {
+        assertTrue(constructorInjected);
+        assertTrue(methodInjected);
+    }
+
     @Test
     public void testCustomMarshalDomainObject() throws Exception {
         MockEndpoint mock = getMockEndpoint("mock:result");
@@ -51,12 +67,11 @@ public class XStreamConfigurationTest ex
         list.add(11.5);
         list.add(97.5);
 
-        String ordereString = "<?xml version='1.0' encoding='UTF-8'?>"
-            + "<purchase-order name=\"Tiger\" price=\"99.95\" amount=\"1.0\"/>";
+        String ordereString = "<?xml version='1.0' encoding='UTF-8'?>" + "<purchase-order name=\"Tiger\" price=\"99.95\" amount=\"1.0\"/>";
         mock.expectedBodiesReceived(new Object[] {ordereString, order});
 
-        template.sendBody("direct:marshal", order);
-        template.sendBody("direct:unmarshal", ordereString);
+        this.template.sendBody("direct:marshal", order);
+        this.template.sendBody("direct:unmarshal", ordereString);
 
         mock.assertIsSatisfied();
     }
@@ -72,14 +87,12 @@ public class XStreamConfigurationTest ex
         list.add(97.5);
         history.setHistory(list);
 
-        String ordereString = "<?xml version='1.0' encoding='UTF-8'?>"
-            + "<org.apache.camel.dataformat.xstream.PurchaseHistory>"
-            + "<double>11.5</double><double>97.5</double>"
-            + "</org.apache.camel.dataformat.xstream.PurchaseHistory>";
+        String ordereString = "<?xml version='1.0' encoding='UTF-8'?>" + "<org.apache.camel.dataformat.xstream.PurchaseHistory>"
+                + "<double>11.5</double><double>97.5</double>" + "</org.apache.camel.dataformat.xstream.PurchaseHistory>";
         mock.expectedBodiesReceived(new Object[] {ordereString, history});
 
-        template.sendBody("direct:marshal", history);
-        template.sendBody("direct:unmarshal", ordereString);
+        this.template.sendBody("direct:marshal", history);
+        this.template.sendBody("direct:unmarshal", ordereString);
 
         mock.assertIsSatisfied();
     }
@@ -100,14 +113,16 @@ public class XStreamConfigurationTest ex
         String ordereString = "{\"purchase-order\":{\"@name\":\"Tiger\",\"@price\":\"99.95\",\"@amount\":\"1.0\"}}";
         mock.expectedBodiesReceived(new Object[] {ordereString, order});
 
-        template.sendBody("direct:marshal-json", order);
-        template.sendBody("direct:unmarshal-json", ordereString);
+        this.template.sendBody("direct:marshal-json", order);
+        this.template.sendBody("direct:unmarshal-json", ordereString);
 
         mock.assertIsSatisfied();
     }
 
+    @Override
     protected RouteBuilder createRouteBuilder() throws Exception {
         return new RouteBuilder() {
+            @Override
             public void configure() throws Exception {
                 XStreamDataFormat xstreamDefinition = new XStreamDataFormat();
                 Map<String, String> aliases = new HashMap<String, String>();
@@ -116,6 +131,9 @@ public class XStreamConfigurationTest ex
 
                 List<String> converters = new ArrayList<String>();
                 converters.add(PurchaseOrderConverter.class.getName());
+                converters.add(CheckMethodInjection.class.getName());
+                converters.add(CheckConstructorInjection.class.getName());
+
                 xstreamDefinition.setConverters(converters);
 
                 Map<String, String[]> implicits = new HashMap<String, String[]>();
@@ -156,9 +174,55 @@ public class XStreamConfigurationTest ex
 
         public void marshal(Object object, HierarchicalStreamWriter writer, MarshallingContext context) {
 
-            writer.addAttribute("name", ((PurchaseOrder)object).getName());
+            writer.addAttribute("name", ((PurchaseOrder) object).getName());
             writer.addAttribute("price", Double.toString(((PurchaseOrder) object).getPrice()));
             writer.addAttribute("amount", Double.toString(((PurchaseOrder) object).getAmount()));
         }
     }
+
+    public static class CheckConstructorInjection implements Converter {
+        public CheckConstructorInjection(XStream xstream) {
+            if (xstream != null) {
+                constructorInjected = true;
+            } else {
+                throw new RuntimeException("XStream should not be null");
+            }
+        }
+
+        public void marshal(Object source, HierarchicalStreamWriter writer, MarshallingContext context) {
+        }
+
+        public Object unmarshal(HierarchicalStreamReader reader, UnmarshallingContext context) {
+            return null;
+        }
+
+        public boolean canConvert(Class type) {
+            return false;
+        }
+    }
+
+    public static class CheckMethodInjection implements Converter {
+        public CheckMethodInjection() {
+
+        }
+
+        public void setXStream(XStream xstream) {
+            if (xstream != null) {
+                methodInjected = true;
+            } else {
+                throw new RuntimeException("XStream should not be null");
+            }
+        }
+
+        public void marshal(Object source, HierarchicalStreamWriter writer, MarshallingContext context) {
+        }
+
+        public Object unmarshal(HierarchicalStreamReader reader, UnmarshallingContext context) {
+            return null;
+        }
+
+        public boolean canConvert(Class type) {
+            return false;
+        }
+    }
 }
\ No newline at end of file