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<Map<String, Object>></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