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 2008/08/31 15:02:23 UTC

svn commit: r690690 - in /activemq/camel/trunk/components/camel-flatpack: ./ src/main/java/org/apache/camel/component/flatpack/ src/test/java/org/apache/camel/component/flatpack/

Author: davsclaus
Date: Sun Aug 31 06:02:22 2008
New Revision: 690690

URL: http://svn.apache.org/viewvc?rev=690690&view=rev
Log:
CAMEL-831, CAMEL-616: Added flatpack writer to camel-flatpack for the dataformat. Improved the dataformat with the marshal operation as well.

Added:
    activemq/camel/trunk/components/camel-flatpack/src/test/java/org/apache/camel/component/flatpack/FlatpackDelimitedDataFormatTest.java   (with props)
    activemq/camel/trunk/components/camel-flatpack/src/test/java/org/apache/camel/component/flatpack/FlatpackFixedLengthDataFormatTest.java
    activemq/camel/trunk/components/camel-flatpack/src/test/java/org/apache/camel/component/flatpack/FlatpackFixedLengthWithHeaderAndTrailerDataFormatTest.java
Modified:
    activemq/camel/trunk/components/camel-flatpack/pom.xml
    activemq/camel/trunk/components/camel-flatpack/src/main/java/org/apache/camel/component/flatpack/FlatpackDataFormat.java

Modified: activemq/camel/trunk/components/camel-flatpack/pom.xml
URL: http://svn.apache.org/viewvc/activemq/camel/trunk/components/camel-flatpack/pom.xml?rev=690690&r1=690689&r2=690690&view=diff
==============================================================================
--- activemq/camel/trunk/components/camel-flatpack/pom.xml (original)
+++ activemq/camel/trunk/components/camel-flatpack/pom.xml Sun Aug 31 06:02:22 2008
@@ -75,6 +75,12 @@
       <artifactId>camel-hamcrest</artifactId>
       <scope>test</scope>
     </dependency>
+      <dependency>
+        <groupId>org.apache.camel</groupId>
+        <artifactId>camel-core</artifactId>
+        <scope>test</scope>
+        <type>test-jar</type>
+      </dependency>
     <dependency>
       <groupId>org.springframework</groupId>
       <artifactId>spring-test</artifactId>

Modified: activemq/camel/trunk/components/camel-flatpack/src/main/java/org/apache/camel/component/flatpack/FlatpackDataFormat.java
URL: http://svn.apache.org/viewvc/activemq/camel/trunk/components/camel-flatpack/src/main/java/org/apache/camel/component/flatpack/FlatpackDataFormat.java?rev=690690&r1=690689&r2=690690&view=diff
==============================================================================
--- activemq/camel/trunk/components/camel-flatpack/src/main/java/org/apache/camel/component/flatpack/FlatpackDataFormat.java (original)
+++ activemq/camel/trunk/components/camel-flatpack/src/main/java/org/apache/camel/component/flatpack/FlatpackDataFormat.java Sun Aug 31 06:02:22 2008
@@ -16,39 +16,78 @@
  */
 package org.apache.camel.component.flatpack;
 
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.InputStreamReader;
-import java.io.OutputStream;
-import java.io.Reader;
-
 import net.sf.flatpack.DataSet;
 import net.sf.flatpack.DefaultParserFactory;
 import net.sf.flatpack.Parser;
 import net.sf.flatpack.ParserFactory;
+import net.sf.flatpack.writer.DelimiterWriterFactory;
+import net.sf.flatpack.writer.FixedWriterFactory;
+import net.sf.flatpack.writer.Writer;
 import org.apache.camel.Exchange;
 import org.apache.camel.spi.DataFormat;
 import org.apache.camel.util.ObjectHelper;
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.jdom.JDOMException;
 import org.springframework.core.io.Resource;
 
+import java.io.*;
+import java.util.List;
+import java.util.Map;
+
 /**
+ * Flatpack DataFormat.
+ * <p/>
+ * This data format supports two operations:
+ * <ul>
+ * <li>marshal = from <tt>List&lt;Map&lt;String, Object&gt;&gt;</tt> to <tt>OutputStream</tt> (convertable to String)</li>
+ * <li>unmarshal = from <tt>InputStream</tt> (such as a File) to {@link DataSetList}.
+ * </ul>
+ *
  * @version $Revision$
  */
 public class FlatpackDataFormat implements DataFormat {
+    private static final transient Log LOG = LogFactory.getLog(FlatpackDataFormat.class);
+    private ParserFactory parserFactory = DefaultParserFactory.getInstance();
     private char delimiter = ',';
     private char textQualifier = '"';
     private boolean ignoreFirstRecord = true;
     private Resource definition;
     private boolean fixed;
-    private ParserFactory parserFactory = DefaultParserFactory.getInstance();
 
     public void marshal(Exchange exchange, Object graph, OutputStream stream) throws Exception {
-        // TODO
-        throw new UnsupportedOperationException("marshal() not implemented yet!");
+        ObjectHelper.notNull(graph, "The object to marshal must be provided");
+
+        List<Map<String, Object>> data = (List<Map<String, Object>>) graph;
+        if (data.isEmpty()) {
+            LOG.warn("No data to marshal as the list is empty");
+            return;
+        }
+        Map<String, Object> firstRow = data.get(0);
+
+        Writer writer = createWriter(exchange, firstRow, stream);
+        try {
+            boolean first = true;
+            writer.printHeader();
+            for (Map<String, Object> row : data) {
+                if (ignoreFirstRecord && first) {
+                    // skip first row
+                    first = false;
+                    continue;
+                }
+                for (String key : row.keySet()) {
+                    writer.addRecordEntry(key, row.get(key));
+                }
+                writer.nextRecord();
+            }
+            writer.printFooter();
+        } finally {
+            writer.flush();
+            writer.close();
+        }
     }
 
     public Object unmarshal(Exchange exchange, InputStream stream) throws Exception {
-        // TODO should we just grab a Reader from the body?
         InputStreamReader reader = new InputStreamReader(stream);
         Parser parser = createParser(exchange, reader);
         DataSet dataSet = parser.parse();
@@ -124,4 +163,27 @@
         }
     }
 
+    private Writer createWriter(Exchange exchange, Map<String, Object> firstRow, OutputStream stream) throws JDOMException, IOException {
+        if (isFixed()) {
+            Resource resource = getDefinition();
+            ObjectHelper.notNull(resource, "resource property");
+            FixedWriterFactory factory = new FixedWriterFactory(new InputStreamReader(resource.getInputStream()));
+            return factory.createWriter(new OutputStreamWriter(stream));
+        } else {
+            Resource resource = getDefinition();
+            if (resource == null) {
+                DelimiterWriterFactory factory = new DelimiterWriterFactory(delimiter, textQualifier);
+                // add coulmns from the keys in the data map as the columns must be known
+                for (String key : firstRow.keySet()) {
+                    factory.addColumnTitle(key);
+                }
+                return factory.createWriter(new OutputStreamWriter(stream));
+            } else {
+                DelimiterWriterFactory factory = new DelimiterWriterFactory(new InputStreamReader(resource.getInputStream()), delimiter, textQualifier);
+                return factory.createWriter(new OutputStreamWriter(stream));
+            }
+        }
+    }
+
+
 }

Added: activemq/camel/trunk/components/camel-flatpack/src/test/java/org/apache/camel/component/flatpack/FlatpackDelimitedDataFormatTest.java
URL: http://svn.apache.org/viewvc/activemq/camel/trunk/components/camel-flatpack/src/test/java/org/apache/camel/component/flatpack/FlatpackDelimitedDataFormatTest.java?rev=690690&view=auto
==============================================================================
--- activemq/camel/trunk/components/camel-flatpack/src/test/java/org/apache/camel/component/flatpack/FlatpackDelimitedDataFormatTest.java (added)
+++ activemq/camel/trunk/components/camel-flatpack/src/test/java/org/apache/camel/component/flatpack/FlatpackDelimitedDataFormatTest.java Sun Aug 31 06:02:22 2008
@@ -0,0 +1,119 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.camel.component.flatpack;
+
+import org.apache.camel.ContextTestSupport;
+import org.apache.camel.builder.RouteBuilder;
+import org.apache.camel.component.mock.MockEndpoint;
+import org.apache.camel.converter.IOConverter;
+import org.springframework.core.io.ClassPathResource;
+
+import java.io.File;
+import java.util.Map;
+import java.util.List;
+import java.util.ArrayList;
+import java.util.LinkedHashMap;
+
+/**
+ * Unit test for delimited DataFormat.
+ */
+public class FlatpackDelimitedDataFormatTest extends ContextTestSupport {
+
+    public void testUnmarshal() throws Exception {
+        MockEndpoint mock = getMockEndpoint("mock:unmarshal");
+        // by default we get on big message
+        mock.expectedMessageCount(1);
+        mock.message(0).body().isInstanceOf(DataSetList.class);
+
+        String data = IOConverter.toString(new File("src/test/data/delim/INVENTORY-CommaDelimitedWithQualifier.txt").getAbsoluteFile());
+
+        template.sendBody("direct:unmarshal", data);
+        assertMockEndpointsSatisifed();
+
+        DataSetList list = mock.getExchanges().get(0).getIn().getBody(DataSetList.class);
+        assertEquals(4, list.size());
+        Map row = (Map) list.get(0);
+        assertEquals("SOME VALVE", row.get("ITEM_DESC"));
+    }
+
+    public void testMarshalWithDefinition() throws Exception {
+        MockEndpoint mock = getMockEndpoint("mock:marshal");
+        // by default we get on big message
+        mock.expectedMessageCount(1);
+
+        List<Map<String, Object>> data = new ArrayList<Map<String, Object>>();
+        Map<String, Object> row = new LinkedHashMap<String, Object>();
+        row.put("ITEM_DESC", "SOME VALVE");
+        row.put("IN_STOCK", "2");
+        row.put("PRICE", "5.00");
+        row.put("LAST_RECV_DT", "20050101");
+        data.add(row);
+
+        Map<String, Object> row2 = new LinkedHashMap<String, Object>();
+        row2.put("ITEM_DESC", "AN ENGINE");
+        row2.put("IN_STOCK", "100");
+        row2.put("PRICE", "1000.00");
+        row2.put("LAST_RECV_DT", "20040601");
+        data.add(row2);
+
+        template.sendBody("direct:marshal", data);
+        assertMockEndpointsSatisifed();
+    }
+
+    public void testMarshalNoDefinition() throws Exception {
+        MockEndpoint mock = getMockEndpoint("mock:marshal2");
+        // by default we get on big message
+        mock.expectedMessageCount(1);
+
+        List<Map<String, Object>> data = new ArrayList<Map<String, Object>>();
+        Map<String, Object> row = new LinkedHashMap<String, Object>();
+        row.put("ITEM_DESC", "SOME VALVE");
+        row.put("IN_STOCK", "2");
+        row.put("PRICE", "5.00");
+        row.put("LAST_RECV_DT", "20050101");
+        data.add(row);
+
+        Map<String, Object> row2 = new LinkedHashMap<String, Object>();
+        row2.put("ITEM_DESC", "AN ENGINE");
+        row2.put("IN_STOCK", "100");
+        row2.put("PRICE", "1000.00");
+        row2.put("LAST_RECV_DT", "20040601");
+        data.add(row2);
+
+        template.sendBody("direct:marshal2", data);
+        assertMockEndpointsSatisifed();
+    }
+
+    @Override
+    protected RouteBuilder createRouteBuilder() throws Exception {
+        return new RouteBuilder() {
+            public void configure() throws Exception {
+                FlatpackDataFormat df = new FlatpackDataFormat();
+                df.setDefinition(new ClassPathResource("INVENTORY-Delimited.pzmap.xml"));
+
+                from("direct:unmarshal").unmarshal(df).to("mock:unmarshal");
+
+                // with the definition
+                from("direct:marshal").marshal(df).convertBodyTo(String.class).to("mock:marshal");
+
+                // without the definition (will auto add column names from the recieved data)
+                FlatpackDataFormat df2 = new FlatpackDataFormat();
+                from("direct:marshal2").marshal(df2).convertBodyTo(String.class).to("mock:marshal2");
+            }
+        };
+    }
+}

Propchange: activemq/camel/trunk/components/camel-flatpack/src/test/java/org/apache/camel/component/flatpack/FlatpackDelimitedDataFormatTest.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: activemq/camel/trunk/components/camel-flatpack/src/test/java/org/apache/camel/component/flatpack/FlatpackDelimitedDataFormatTest.java
------------------------------------------------------------------------------
    svn:keywords = Rev Date

Added: activemq/camel/trunk/components/camel-flatpack/src/test/java/org/apache/camel/component/flatpack/FlatpackFixedLengthDataFormatTest.java
URL: http://svn.apache.org/viewvc/activemq/camel/trunk/components/camel-flatpack/src/test/java/org/apache/camel/component/flatpack/FlatpackFixedLengthDataFormatTest.java?rev=690690&view=auto
==============================================================================
--- activemq/camel/trunk/components/camel-flatpack/src/test/java/org/apache/camel/component/flatpack/FlatpackFixedLengthDataFormatTest.java (added)
+++ activemq/camel/trunk/components/camel-flatpack/src/test/java/org/apache/camel/component/flatpack/FlatpackFixedLengthDataFormatTest.java Sun Aug 31 06:02:22 2008
@@ -0,0 +1,91 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.camel.component.flatpack;
+
+import org.apache.camel.ContextTestSupport;
+import org.apache.camel.builder.RouteBuilder;
+import org.apache.camel.component.mock.MockEndpoint;
+import org.apache.camel.converter.IOConverter;
+import org.springframework.core.io.ClassPathResource;
+
+import java.io.File;
+import java.util.ArrayList;
+import java.util.LinkedHashMap;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * Unit test for fixed length DataFormat.
+ */
+public class FlatpackFixedLengthDataFormatTest extends ContextTestSupport {
+
+    public void testUnmarshal() throws Exception {
+        MockEndpoint mock = getMockEndpoint("mock:unmarshal");
+        // by default we get on big message
+        mock.expectedMessageCount(1);
+        mock.message(0).body().isInstanceOf(DataSetList.class);
+
+        String data = IOConverter.toString(new File("src/test/data/fixed/PEOPLE-FixedLength.txt").getAbsoluteFile());
+
+        template.sendBody("direct:unmarshal", data);
+        assertMockEndpointsSatisifed();
+
+        DataSetList list = mock.getExchanges().get(0).getIn().getBody(DataSetList.class);
+        assertEquals(4, list.size());
+        Map row = (Map) list.get(0);
+        assertEquals("JOHN", row.get("FIRSTNAME"));
+    }
+
+    public void testMarshalWithDefinition() throws Exception {
+        MockEndpoint mock = getMockEndpoint("mock:marshal");
+        // by default we get on big message
+        mock.expectedMessageCount(1);
+
+        List<Map<String, Object>> data = new ArrayList<Map<String, Object>>();
+        Map<String, Object> row = new LinkedHashMap<String, Object>();
+        row.put("FIRSTNAME", "JOHN");
+        row.put("LASTNAME", "DOE");
+        row.put("ADDRESS", "1234 CIRCLE CT");
+        row.put("CITY", "ELYRIA");
+        row.put("STATE", "OH");
+        row.put("ZIP", "44035");
+        data.add(row);
+
+        template.sendBody("direct:marshal", data);
+        assertMockEndpointsSatisifed();
+
+        String s = mock.getExchanges().get(0).getIn().getBody(String.class);
+        assertTrue(s.startsWith("JOHN                               DOE"));
+    }
+
+    @Override
+    protected RouteBuilder createRouteBuilder() throws Exception {
+        return new RouteBuilder() {
+            public void configure() throws Exception {
+                FlatpackDataFormat df = new FlatpackDataFormat();
+                df.setDefinition(new ClassPathResource("PEOPLE-FixedLength.pzmap.xml"));
+                df.setFixed(true);
+                df.setIgnoreFirstRecord(false);
+
+                from("direct:unmarshal").unmarshal(df).to("mock:unmarshal");
+
+                // with the definition
+                from("direct:marshal").marshal(df).convertBodyTo(String.class).to("mock:marshal");
+            }
+        };
+    }
+}
\ No newline at end of file

Added: activemq/camel/trunk/components/camel-flatpack/src/test/java/org/apache/camel/component/flatpack/FlatpackFixedLengthWithHeaderAndTrailerDataFormatTest.java
URL: http://svn.apache.org/viewvc/activemq/camel/trunk/components/camel-flatpack/src/test/java/org/apache/camel/component/flatpack/FlatpackFixedLengthWithHeaderAndTrailerDataFormatTest.java?rev=690690&view=auto
==============================================================================
--- activemq/camel/trunk/components/camel-flatpack/src/test/java/org/apache/camel/component/flatpack/FlatpackFixedLengthWithHeaderAndTrailerDataFormatTest.java (added)
+++ activemq/camel/trunk/components/camel-flatpack/src/test/java/org/apache/camel/component/flatpack/FlatpackFixedLengthWithHeaderAndTrailerDataFormatTest.java Sun Aug 31 06:02:22 2008
@@ -0,0 +1,81 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.camel.component.flatpack;
+
+import org.apache.camel.ContextTestSupport;
+import org.apache.camel.builder.RouteBuilder;
+import org.apache.camel.component.mock.MockEndpoint;
+import org.apache.camel.converter.IOConverter;
+import org.springframework.core.io.ClassPathResource;
+
+import java.io.File;
+import java.util.Map;
+
+/**
+ * Unit test for fixed length DataFormat.
+ */
+public class FlatpackFixedLengthWithHeaderAndTrailerDataFormatTest extends ContextTestSupport {
+
+    public void testUnmarshal() throws Exception {
+        MockEndpoint mock = getMockEndpoint("mock:unmarshal");
+        // by default we get on big message
+        mock.expectedMessageCount(1);
+        mock.message(0).body().isInstanceOf(DataSetList.class);
+
+        String data = IOConverter.toString(new File("src/test/data/headerandtrailer/PEOPLE-HeaderAndTrailer.txt").getAbsoluteFile());
+
+        template.sendBody("direct:unmarshal", data);
+        assertMockEndpointsSatisifed();
+
+        DataSetList list = mock.getExchanges().get(0).getIn().getBody(DataSetList.class);
+        assertEquals(6, list.size());
+
+        // assert header
+        Map header = (Map) list.get(0);
+        assertEquals("HBT", header.get("INDICATOR"));
+        assertEquals("20080817", header.get("DATE"));
+
+        // assert data
+        Map row = (Map) list.get(1);
+        assertEquals("JOHN", row.get("FIRSTNAME"));
+
+        // assert trailer
+        Map trailer = (Map) list.get(5);
+        assertEquals("FBT", trailer.get("INDICATOR"));
+        assertEquals("SUCCESS", trailer.get("STATUS"));
+    }
+
+    public void testMarshalWithDefinition() throws Exception {
+        // TODO: header and trailer not supported for FlatpackWriter
+    }
+
+    @Override
+    protected RouteBuilder createRouteBuilder() throws Exception {
+        return new RouteBuilder() {
+            public void configure() throws Exception {
+                FlatpackDataFormat df = new FlatpackDataFormat();
+                df.setDefinition(new ClassPathResource("PEOPLE-HeaderAndTrailer.pzmap.xml"));
+                df.setFixed(true);
+
+                from("direct:unmarshal").unmarshal(df).to("mock:unmarshal");
+
+                // with the definition
+                from("direct:marshal").marshal(df).convertBodyTo(String.class).to("mock:marshal");
+            }
+        };
+    }
+}
\ No newline at end of file