camel-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From davscl...@apache.org
Subject git commit: CAMEL-5359: Fixed camel-castor to be able to load mapping from XML file. Also fixed thread safety issues of marshaller. Thanks to Joshua Ecklund for patch. And also thanks to jacob vandergoot for working with this.
Date Fri, 10 May 2013 12:49:28 GMT
Updated Branches:
  refs/heads/master 513065a58 -> e63b8beb8


CAMEL-5359: Fixed camel-castor to be able to load mapping from XML file. Also fixed thread
safety issues of marshaller. Thanks to Joshua Ecklund for patch. And also thanks to jacob
vandergoot for working with this.


Project: http://git-wip-us.apache.org/repos/asf/camel/repo
Commit: http://git-wip-us.apache.org/repos/asf/camel/commit/e63b8beb
Tree: http://git-wip-us.apache.org/repos/asf/camel/tree/e63b8beb
Diff: http://git-wip-us.apache.org/repos/asf/camel/diff/e63b8beb

Branch: refs/heads/master
Commit: e63b8beb8ce54988dc0e082ac1cb9f91966bfdc6
Parents: 513065a
Author: Claus Ibsen <davsclaus@apache.org>
Authored: Fri May 10 14:49:17 2013 +0200
Committer: Claus Ibsen <davsclaus@apache.org>
Committed: Fri May 10 14:49:17 2013 +0200

----------------------------------------------------------------------
 .../castor/AbstractCastorDataFormat.java           |  110 ++++++++-------
 .../castor/MarshalWithMappingDomainObjectTest.java |    7 +-
 .../castor/SpringMarshalDomainObjectTest.java      |   30 ++++
 .../apache/camel/dataformat/castor/Student.java    |   39 +++++-
 components/camel-castor/src/test/resources/map.xml |   72 ++++++----
 .../castor/SpringMarshalDomainObjectTest.xml       |    9 +-
 6 files changed, 177 insertions(+), 90 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/camel/blob/e63b8beb/components/camel-castor/src/main/java/org/apache/camel/dataformat/castor/AbstractCastorDataFormat.java
----------------------------------------------------------------------
diff --git a/components/camel-castor/src/main/java/org/apache/camel/dataformat/castor/AbstractCastorDataFormat.java
b/components/camel-castor/src/main/java/org/apache/camel/dataformat/castor/AbstractCastorDataFormat.java
index 85fc3d1..24cbcf2 100644
--- a/components/camel-castor/src/main/java/org/apache/camel/dataformat/castor/AbstractCastorDataFormat.java
+++ b/components/camel-castor/src/main/java/org/apache/camel/dataformat/castor/AbstractCastorDataFormat.java
@@ -23,9 +23,12 @@ import java.io.OutputStreamWriter;
 import java.io.Reader;
 import java.io.Writer;
 
+import org.apache.camel.CamelContext;
+import org.apache.camel.CamelContextAware;
 import org.apache.camel.Exchange;
 import org.apache.camel.spi.ClassResolver;
 import org.apache.camel.spi.DataFormat;
+import org.apache.camel.support.ServiceSupport;
 import org.apache.camel.util.ObjectHelper;
 import org.exolab.castor.mapping.Mapping;
 import org.exolab.castor.xml.Marshaller;
@@ -37,25 +40,21 @@ import org.exolab.castor.xml.XMLContext;
  * href="http://camel.apache.org/data-format.html">data format</a> ({@link DataFormat})
  * interface which leverage the Castor library for XML marshaling and
  * unmarshaling
- *
- * @version 
  */
-public abstract class AbstractCastorDataFormat implements DataFormat {
+public abstract class AbstractCastorDataFormat extends ServiceSupport implements DataFormat,
CamelContextAware {
 
     /**
      * The default encoding used for stream access.
      */
     public static final String DEFAULT_ENCODING = "UTF-8";
 
+    private CamelContext camelContext;
     private String encoding = DEFAULT_ENCODING;
     private String mappingFile;
     private String[] classNames;
     private String[] packages;
     private boolean validation;
-
     private volatile XMLContext xmlContext;
-    private volatile Marshaller marshaller;
-    private volatile Unmarshaller unmarshaller;
 
     public AbstractCastorDataFormat() {
     }
@@ -66,57 +65,63 @@ public abstract class AbstractCastorDataFormat implements DataFormat {
 
     public void marshal(Exchange exchange, Object body, OutputStream outputStream) throws
Exception {
         Writer writer = new OutputStreamWriter(outputStream, encoding);
-        Marshaller.marshal(body, writer);
+
+        Marshaller marshaller = createMarshaller(exchange);
+        marshaller.setWriter(writer);
+        marshaller.marshal(body);
     }
 
     public Object unmarshal(Exchange exchange, InputStream inputStream) throws Exception
{
         Reader reader = new InputStreamReader(inputStream, encoding);
-        return getUnmarshaller(exchange).unmarshal(reader);
+        return createUnmarshaller(exchange).unmarshal(reader);
     }
 
-    public XMLContext getXmlContext(ClassResolver resolver, ClassLoader contextClassLoader)
throws Exception {
-        if (xmlContext == null) {
-            xmlContext = new XMLContext();
-
-            if (ObjectHelper.isNotEmpty(getMappingFile())) {
-                Mapping xmlMap;
-                if (contextClassLoader != null) {
-                    xmlMap = new Mapping(contextClassLoader);
-                } else {
-                    xmlMap = new Mapping();
-                }
-                xmlMap.loadMapping(resolver.loadResourceAsURL(getMappingFile()));
-                xmlContext.addMapping(xmlMap);
-            }
+    protected XMLContext createXMLContext(ClassResolver resolver, ClassLoader contextClassLoader)
throws Exception {
+        XMLContext xmlContext = new XMLContext();
 
-            if (getPackages() != null) {
-                xmlContext.addPackages(getPackages());
-            }
-            if (getClassNames() != null) {
-                for (String name : getClassNames()) {
-                    Class<?> clazz = resolver.resolveClass(name);
-                    xmlContext.addClass(clazz);
-                }
+        if (ObjectHelper.isNotEmpty(getMappingFile())) {
+            Mapping xmlMap;
+            if (contextClassLoader != null) {
+                xmlMap = new Mapping(contextClassLoader);
+            } else {
+                xmlMap = new Mapping();
             }
+            xmlMap.loadMapping(resolver.loadResourceAsURL(getMappingFile()));
+            xmlContext.addMapping(xmlMap);
         }
 
+        if (getPackages() != null) {
+            xmlContext.addPackages(getPackages());
+        }
+        if (getClassNames() != null) {
+            for (String name : getClassNames()) {
+                Class<?> clazz = resolver.resolveClass(name);
+                xmlContext.addClass(clazz);
+            }
+        }
         return xmlContext;
     }
 
-    public Unmarshaller getUnmarshaller(Exchange exchange) throws Exception {
-        if (this.unmarshaller == null) {
-            this.unmarshaller = getXmlContext(exchange.getContext().getClassResolver(), exchange.getContext().getApplicationContextClassLoader()).createUnmarshaller();
-            this.unmarshaller.setValidation(isValidation());
-        }
-        return this.unmarshaller;
+    public CamelContext getCamelContext() {
+        return camelContext;
     }
 
-    public Marshaller getMarshaller(Exchange exchange) throws Exception {
-        if (this.marshaller == null) {
-            this.marshaller = getXmlContext(exchange.getContext().getClassResolver(), exchange.getContext().getApplicationContextClassLoader()).createMarshaller();
-            this.marshaller.setValidation(isValidation());
-        }
-        return this.marshaller;
+    public void setCamelContext(CamelContext camelContext) {
+        this.camelContext = camelContext;
+    }
+
+    public Unmarshaller createUnmarshaller(Exchange exchange) throws Exception {
+        // need to create new marshaller as we may have concurrent processing
+        Unmarshaller answer = xmlContext.createUnmarshaller();
+        answer.setValidation(isValidation());
+        return answer;
+    }
+
+    public Marshaller createMarshaller(Exchange exchange) throws Exception {
+        // need to create new marshaller as we may have concurrent processing
+        Marshaller answer = xmlContext.createMarshaller();
+        answer.setValidation(isValidation());
+        return answer;
     }
 
     public void setXmlContext(XMLContext xmlContext) {
@@ -131,14 +136,6 @@ public abstract class AbstractCastorDataFormat implements DataFormat
{
         this.mappingFile = mappingFile;
     }
 
-    public void setMarshaller(Marshaller marshaller) {
-        this.marshaller = marshaller;
-    }
-
-    public void setUnmarshaller(Unmarshaller unmarshaller) {
-        this.unmarshaller = unmarshaller;
-    }
-
     public String[] getClassNames() {
         return classNames;
     }
@@ -170,4 +167,17 @@ public abstract class AbstractCastorDataFormat implements DataFormat
{
     public void setValidation(boolean validation) {
         this.validation = validation;
     }
+
+    @Override
+    protected void doStart() throws Exception {
+        if (xmlContext == null) {
+            xmlContext = createXMLContext(getCamelContext().getClassResolver(), getCamelContext().getApplicationContextClassLoader());
+        }
+    }
+
+    @Override
+    protected void doStop() throws Exception {
+        // noop
+    }
+
 }
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/camel/blob/e63b8beb/components/camel-castor/src/test/java/org/apache/camel/dataformat/castor/MarshalWithMappingDomainObjectTest.java
----------------------------------------------------------------------
diff --git a/components/camel-castor/src/test/java/org/apache/camel/dataformat/castor/MarshalWithMappingDomainObjectTest.java
b/components/camel-castor/src/test/java/org/apache/camel/dataformat/castor/MarshalWithMappingDomainObjectTest.java
index 459c33b..f390734 100644
--- a/components/camel-castor/src/test/java/org/apache/camel/dataformat/castor/MarshalWithMappingDomainObjectTest.java
+++ b/components/camel-castor/src/test/java/org/apache/camel/dataformat/castor/MarshalWithMappingDomainObjectTest.java
@@ -37,7 +37,7 @@ public class MarshalWithMappingDomainObjectTest extends CamelTestSupport
{
         mock.expectedMessageCount(1);
 
         Student student = new Student();
-        student.setStuName("Dilshan");
+        student.setStuLastName("Dilshan");
         student.setStuAge(25);
         template.sendBody("direct:marshal", student);
 
@@ -54,11 +54,12 @@ public class MarshalWithMappingDomainObjectTest extends CamelTestSupport
{
         MockEndpoint mock = getMockEndpoint("mock:unmarshal");
         mock.expectedMessageCount(1);
 
-        String xml = "<student><name>Sagara Gunathunga</name><age>27</age></student>";
+        String xml = "<student><firstname>Sagara</firstname><lastname>Gunathunga</lastname><age>27</age></student>";
         template.sendBody("direct:unmarshal", xml);
 
         Student student = new Student();
-        student.setStuName("Sagara Gunathunga");
+        student.setStuLastName("Gunathunga");
+        student.setStuFirstName("Sagara");
         student.setStuAge(27);
 
         mock.assertIsSatisfied();

http://git-wip-us.apache.org/repos/asf/camel/blob/e63b8beb/components/camel-castor/src/test/java/org/apache/camel/dataformat/castor/SpringMarshalDomainObjectTest.java
----------------------------------------------------------------------
diff --git a/components/camel-castor/src/test/java/org/apache/camel/dataformat/castor/SpringMarshalDomainObjectTest.java
b/components/camel-castor/src/test/java/org/apache/camel/dataformat/castor/SpringMarshalDomainObjectTest.java
index d4df6c2..9629b96 100644
--- a/components/camel-castor/src/test/java/org/apache/camel/dataformat/castor/SpringMarshalDomainObjectTest.java
+++ b/components/camel-castor/src/test/java/org/apache/camel/dataformat/castor/SpringMarshalDomainObjectTest.java
@@ -45,6 +45,36 @@ public class SpringMarshalDomainObjectTest extends CamelSpringTestSupport
{
     }
 
     @Test
+    public void testMappingOfDomainObject() throws Exception {
+        // some platform cannot test using Castor as it uses a SUN dependent Xerces
+        if (isJavaVendor("IBM")) {
+            return;
+        }
+
+        MockEndpoint mock = getMockEndpoint("mock:result");
+        mock.expectedMessageCount(2);
+
+        Student expectedStudent = new Student();
+        expectedStudent.setStuFirstName("John");
+        expectedStudent.setStuLastName("Doe");
+        expectedStudent.setStuAge(21);
+
+        String expectedString = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<student><firstname>John</firstname><lastname>Doe</lastname><age>21</age></student>";
+
+        template.sendBody("direct:unmarshal", expectedString);
+        template.sendBody("direct:marshal", expectedStudent);
+
+        mock.assertIsSatisfied();
+        Student actualStudent = mock.getExchanges().get(0).getIn().getBody(Student.class);
+        String actualString = mock.getExchanges().get(1).getIn().getBody(String.class);
+
+        // compare objects
+        assertEquals("The expected student does not match the unmarshal XML student.", expectedStudent,
actualStudent);
+        // compare XML
+        assertEquals("The expected XML does not match the marshal student XML.", expectedString,
actualString);
+    }
+
+    @Test
     public void testMarshalDomainObjectTwice() throws Exception {
         // some platform cannot test using Castor as it uses a SUN dependent Xerces
         if (isJavaVendor("IBM")) {

http://git-wip-us.apache.org/repos/asf/camel/blob/e63b8beb/components/camel-castor/src/test/java/org/apache/camel/dataformat/castor/Student.java
----------------------------------------------------------------------
diff --git a/components/camel-castor/src/test/java/org/apache/camel/dataformat/castor/Student.java
b/components/camel-castor/src/test/java/org/apache/camel/dataformat/castor/Student.java
index 6c4710e..994079a 100644
--- a/components/camel-castor/src/test/java/org/apache/camel/dataformat/castor/Student.java
+++ b/components/camel-castor/src/test/java/org/apache/camel/dataformat/castor/Student.java
@@ -17,7 +17,8 @@
 package org.apache.camel.dataformat.castor;
 
 public class Student {
-    private String stuName;
+    private String stuFirstName;
+    private String stuLastName;
     private Integer stuAge;
 
     public Integer getStuAge() {
@@ -28,17 +29,43 @@ public class Student {
         this.stuAge = stuAge;
     }
 
-    public String getStuName() {
-        return stuName;
+    public String getStuFirstName() {
+        return stuFirstName;
     }
 
-    public void setStuName(String stuName) {
-        this.stuName = stuName;
+    public void setStuFirstName(String stuFirstName) {
+        this.stuFirstName = stuFirstName;
+    }
+
+    public String getStuLastName() {
+        return stuLastName;
+    }
+
+    public void setStuLastName(String stuLastName) {
+        this.stuLastName = stuLastName;
     }
 
     @Override
     public String toString() {
-        return "Name : " + getStuName();
+        return "Name : " + getStuLastName()
+                + ", " + getStuFirstName()
+                + " [" + stuAge + "]";
     }
 
+    @Override
+    public boolean equals(Object obj) {
+        try {
+            Student student = (Student) obj;
+            return stuLastName.equals(student.stuLastName)
+                    && stuFirstName.equals(student.stuFirstName)
+                    && stuAge.equals(student.stuAge);
+        } catch (ClassCastException e) {
+            return false;
+        }
+    }
+
+    @Override
+    public int hashCode() {
+        return 0;
+    }
 }

http://git-wip-us.apache.org/repos/asf/camel/blob/e63b8beb/components/camel-castor/src/test/resources/map.xml
----------------------------------------------------------------------
diff --git a/components/camel-castor/src/test/resources/map.xml b/components/camel-castor/src/test/resources/map.xml
index 27540ca..45244e0 100644
--- a/components/camel-castor/src/test/resources/map.xml
+++ b/components/camel-castor/src/test/resources/map.xml
@@ -15,33 +15,45 @@
     limitations under the License.
 -->
 <mapping>
-  <class name="org.apache.camel.dataformat.castor.Student" auto-complete="false">
-    <description>Default mapping </description>
-    <map-to xml="student"/>
-    <field name="stuName" 
-    	   type="string" 
-    	   required="false"                          
-           direct="false"
-           transient="false"                       
-           get-method="getStuName"
-           set-method="setStuName">
-           
-          <bind-xml name="name" 
-          			node="element"/>
-           <sql name="name" type="char"/>
-    </field>
-    
-    <field name="stuAge" 
-    	   type="integer" 
-    	   required="false"
-           direct="false" 
-           transient="false"  
-           get-method="getStuAge"
-           set-method="setStuAge">
-           
-      <bind-xml name="age" 
-                node="element"/>
-      <sql name="name" type="numeric"/>
-    </field>
-  </class>
-  </mapping>
\ No newline at end of file
+    <class name="org.apache.camel.dataformat.castor.Student" auto-complete="false">
+        <description>Default mapping</description>
+        <map-to xml="student"/>
+        <field name="stuFirstName"
+               type="string"
+               required="false"
+               direct="false"
+               transient="false"
+               get-method="getStuFirstName"
+               set-method="setStuFirstName">
+
+            <bind-xml name="firstname"
+                      node="element"/>
+            <sql name="name" type="char"/>
+        </field>
+        <field name="stuLastName"
+               type="string"
+               required="false"
+               direct="false"
+               transient="false"
+               get-method="getStuLastName"
+               set-method="setStuLastName">
+
+            <bind-xml name="lastname"
+                      node="element"/>
+            <sql name="name" type="char"/>
+        </field>
+
+        <field name="stuAge"
+               type="integer"
+               required="false"
+               direct="false"
+               transient="false"
+               get-method="getStuAge"
+               set-method="setStuAge">
+
+            <bind-xml name="age"
+                      node="element"/>
+            <sql name="name" type="numeric"/>
+        </field>
+    </class>
+</mapping>
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/camel/blob/e63b8beb/components/camel-castor/src/test/resources/org/apache/camel/dataformat/castor/SpringMarshalDomainObjectTest.xml
----------------------------------------------------------------------
diff --git a/components/camel-castor/src/test/resources/org/apache/camel/dataformat/castor/SpringMarshalDomainObjectTest.xml
b/components/camel-castor/src/test/resources/org/apache/camel/dataformat/castor/SpringMarshalDomainObjectTest.xml
index d078947..28e6f30 100644
--- a/components/camel-castor/src/test/resources/org/apache/camel/dataformat/castor/SpringMarshalDomainObjectTest.xml
+++ b/components/camel-castor/src/test/resources/org/apache/camel/dataformat/castor/SpringMarshalDomainObjectTest.xml
@@ -25,7 +25,7 @@
     <camelContext id="camel" xmlns="http://camel.apache.org/schema/spring">       

        
         <dataFormats>
-            <castor id="castor"/>
+            <castor id="castor" mappingFile="map.xml"/>
         </dataFormats>
 
         <route>
@@ -37,6 +37,13 @@
         <route>
             <from uri="direct:marshal"/>
             <marshal ref="castor"/>
+            <to uri="mock:result"/>	
+        </route>
+        
+        <route>
+            <from uri="direct:unmarshal"/>
+            <unmarshal ref="castor"/>
+            <to uri="mock:result"/>	
         </route>
 
     </camelContext>   


Mime
View raw message