Repository: incubator-batchee
Updated Branches:
  refs/heads/master 6cb7b3739 -> 711054266


BATCHEE-70 added header support for jsefa


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

Branch: refs/heads/master
Commit: 711054266b945b38477495dc7361199a87f98323
Parents: 6cb7b37
Author: Reinhard Sandtner <[email protected]>
Authored: Wed Dec 2 15:41:15 2015 +0100
Committer: Reinhard Sandtner <[email protected]>
Committed: Wed Dec 2 15:41:15 2015 +0100

----------------------------------------------------------------------
 .../java/org/apache/batchee/jsefa/Header.java   |  39 +++
 .../apache/batchee/jsefa/JSefaCsvMapping.java   | 118 +++++++++
 .../apache/batchee/jsefa/JSefaCsvReader.java    |  29 ++-
 .../apache/batchee/jsefa/JSefaCsvWriter.java    |  57 +++++
 .../batchee/jsefa/JSefaCsvReaderTest.java       |  43 ++++
 .../batchee/jsefa/JSefaCsvWriterHeaderTest.java | 249 +++++++++++++++++++
 .../batchee/jsefa/JSefaCsvWriterTest.java       |  93 +++++++
 .../org/apache/batchee/jsefa/bean/Address.java  |  62 +++++
 .../org/apache/batchee/jsefa/bean/Person.java   |  54 ++++
 .../batchee/jsefa/bean/PersonWithAddress.java   |  42 ++++
 .../batchee/jsefa/bean/RecordWithHeader.java    |  51 ++++
 .../org/apache/batchee/jsefa/util/CsvUtil.java  | 115 +++++++++
 .../java/org/apache/batchee/jsefa/util/IOs.java |  46 +++-
 .../batch-jobs/jsefa-csv-reader-header.xml      |  30 +++
 ...-csv-writer-header-fromFieldsMoreObjects.xml |  29 +++
 ...sefa-csv-writer-header-fromFieldsOneType.xml |  29 +++
 ...-writer-header-fromFieldsWithInheritance.xml |  29 +++
 ...a-csv-writer-header-fromHeaderAnnotation.xml |  29 +++
 .../batch-jobs/jsefa-csv-writer-header.xml      |  29 +++
 .../jsefa-csv-writer-multiOjectTypes.xml        |  28 +++
 .../jsefa-csv-writer-nestedObjects.xml          |  28 +++
 21 files changed, 1215 insertions(+), 14 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-batchee/blob/71105426/extensions/jsefa/src/main/java/org/apache/batchee/jsefa/Header.java
----------------------------------------------------------------------
diff --git 
a/extensions/jsefa/src/main/java/org/apache/batchee/jsefa/Header.java 
b/extensions/jsefa/src/main/java/org/apache/batchee/jsefa/Header.java
new file mode 100644
index 0000000..52bab1d
--- /dev/null
+++ b/extensions/jsefa/src/main/java/org/apache/batchee/jsefa/Header.java
@@ -0,0 +1,39 @@
+/*
+ * 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.batchee.jsefa;
+
+import org.apache.batchee.doc.api.Documentation;
+
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+/**
+ * Annotation to add a custom Header for a {@link 
net.sf.jsefa.csv.annotation.CsvField}.
+ */
+@Target(value = ElementType.FIELD)
+@Retention(value = RetentionPolicy.RUNTIME)
+@Documentation("This annotation is used to specify a custom header for a 
annotated @CsvField.")
+public @interface Header {
+
+
+    /**
+     * @return header for the annotated field
+     */
+    String value();
+}

http://git-wip-us.apache.org/repos/asf/incubator-batchee/blob/71105426/extensions/jsefa/src/main/java/org/apache/batchee/jsefa/JSefaCsvMapping.java
----------------------------------------------------------------------
diff --git 
a/extensions/jsefa/src/main/java/org/apache/batchee/jsefa/JSefaCsvMapping.java 
b/extensions/jsefa/src/main/java/org/apache/batchee/jsefa/JSefaCsvMapping.java
new file mode 100644
index 0000000..e6d6e22
--- /dev/null
+++ 
b/extensions/jsefa/src/main/java/org/apache/batchee/jsefa/JSefaCsvMapping.java
@@ -0,0 +1,118 @@
+/*
+ * 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.batchee.jsefa;
+
+import net.sf.jsefa.csv.annotation.CsvDataType;
+import net.sf.jsefa.csv.annotation.CsvField;
+
+import java.lang.reflect.Field;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.SortedMap;
+import java.util.TreeMap;
+
+public class JSefaCsvMapping {
+
+    /**
+     * storage for CsvHeaders
+     */
+    private final List<String> headers = new ArrayList<String>();
+
+
+    private JSefaCsvMapping(Class<?> type) {
+        calculateHeaders(type);
+    }
+
+
+    public Iterable<String> getHeader() {
+        return headers;
+    }
+
+
+
+    private void calculateHeaders(Class<?> type) {
+
+        SortedMap<Integer, SortedMap<Integer, String>> allHeaders = new 
TreeMap<Integer, SortedMap<Integer, String>>();
+
+        calculateHeaders(type, allHeaders, 0);
+
+        for (SortedMap<Integer, String> headerMap : allHeaders.values()) {
+
+            for (String header : headerMap.values()) {
+                headers.add(header);
+            }
+        }
+    }
+
+    private void calculateHeaders(Class<?> type, SortedMap<Integer, 
SortedMap<Integer, String>> allHeaders, int index) {
+
+        if (type.getSuperclass() != Object.class) {
+            // decrement index for inheritance, because index will be the same
+            // but if we have another object within OR the same positions 
specified in the @CsvField annotation
+            // we override the values
+            calculateHeaders(type.getSuperclass(), allHeaders, index - 1);
+        }
+
+        SortedMap<Integer, String> typeHeaders = new TreeMap<Integer, 
String>();
+
+        for (Field field : type.getDeclaredFields()) {
+
+            CsvField fieldAnnotation = field.getAnnotation(CsvField.class);
+            if (fieldAnnotation == null) {
+                continue;
+            }
+
+            if (field.getType().getAnnotation(CsvDataType.class) != null) {
+                calculateHeaders(field.getType(), allHeaders, 
fieldAnnotation.pos());
+            } else {
+
+                String header = null;
+
+                Header headerAnnotation = field.getAnnotation(Header.class);
+                if (headerAnnotation != null) {
+                    header = headerAnnotation.value();
+                }
+
+                // use field.getName() as default
+                if (header == null || header.isEmpty()) {
+                    header = field.getName();
+                }
+
+                String previousField = typeHeaders.put(fieldAnnotation.pos(), 
header);
+                if (previousField != null) {
+                    throw new IllegalArgumentException(String.format("multiple 
fields for position %d defined! Fields: %s! Type: %s", fieldAnnotation.pos(),
+                                                                               
                                                       previousField + ", " + 
field.getName(),
+                                                                               
                                                       type.getName()));
+                }
+            }
+        }
+
+        allHeaders.put(index, typeHeaders);
+    }
+
+
+    public static List<JSefaCsvMapping> forTypes(Class<?>... types) {
+        List<JSefaCsvMapping> mappings = new 
ArrayList<JSefaCsvMapping>(types.length);
+
+        for (Class<?> type : types) {
+            mappings.add(new JSefaCsvMapping(type));
+        }
+
+        return mappings;
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-batchee/blob/71105426/extensions/jsefa/src/main/java/org/apache/batchee/jsefa/JSefaCsvReader.java
----------------------------------------------------------------------
diff --git 
a/extensions/jsefa/src/main/java/org/apache/batchee/jsefa/JSefaCsvReader.java 
b/extensions/jsefa/src/main/java/org/apache/batchee/jsefa/JSefaCsvReader.java
index 6939571..4068e19 100644
--- 
a/extensions/jsefa/src/main/java/org/apache/batchee/jsefa/JSefaCsvReader.java
+++ 
b/extensions/jsefa/src/main/java/org/apache/batchee/jsefa/JSefaCsvReader.java
@@ -17,7 +17,9 @@
 package org.apache.batchee.jsefa;
 
 import net.sf.jsefa.Deserializer;
+import net.sf.jsefa.common.lowlevel.filter.HeaderAndFooterFilter;
 import net.sf.jsefa.csv.CsvIOFactory;
+import net.sf.jsefa.csv.config.CsvConfiguration;
 import org.apache.batchee.doc.api.Documentation;
 
 import javax.batch.api.BatchProperty;
@@ -80,14 +82,33 @@ public class JSefaCsvReader extends JSefaReader {
     @Documentation("should deliimter be used after last field")
     private String useDelimiterAfterLastField;
 
+    @Inject
+    @BatchProperty
+    @Documentation("should the header be ignored")
+    private Boolean ignoreHeader;
+
+    @Inject
+    @BatchProperty()
+    @Documentation("number of header lines")
+    private Integer headerSize;
+
+
     @Override
     protected Deserializer initDeserializer() throws Exception {
-        return CsvIOFactory.createFactory(
-            JsefaConfigurations.newCsvConfiguration(
+        CsvConfiguration config = JsefaConfigurations.newCsvConfiguration(
                 defaultNoValueString, defaultQuoteMode, fieldDelimiter, 
lineBreak, quoteCharacter,
                 quoteCharacterEscapeMode, useDelimiterAfterLastField, 
validationMode, validationProvider,
                 lineFilter, lowLevelConfiguration, lineFilterLimit, 
objectAccessorProvider,
-                specialRecordDelimiter, simpleTypeProvider, 
typeMappingRegistry),
-            
JsefaConfigurations.createObjectTypes(objectTypes)).createDeserializer();
+                specialRecordDelimiter, simpleTypeProvider, 
typeMappingRegistry);
+
+        if (config.getLineFilter() == null &&
+            Boolean.TRUE.equals(ignoreHeader) &&
+            headerSize != null && headerSize > 0) {
+
+            config.setLineFilter(new HeaderAndFooterFilter(headerSize, false, 
false));
+        }
+
+        return CsvIOFactory.createFactory(config, 
JsefaConfigurations.createObjectTypes(objectTypes))
+                           .createDeserializer();
     }
 }

http://git-wip-us.apache.org/repos/asf/incubator-batchee/blob/71105426/extensions/jsefa/src/main/java/org/apache/batchee/jsefa/JSefaCsvWriter.java
----------------------------------------------------------------------
diff --git 
a/extensions/jsefa/src/main/java/org/apache/batchee/jsefa/JSefaCsvWriter.java 
b/extensions/jsefa/src/main/java/org/apache/batchee/jsefa/JSefaCsvWriter.java
index 502dd5f..9874d9b 100644
--- 
a/extensions/jsefa/src/main/java/org/apache/batchee/jsefa/JSefaCsvWriter.java
+++ 
b/extensions/jsefa/src/main/java/org/apache/batchee/jsefa/JSefaCsvWriter.java
@@ -18,10 +18,13 @@ package org.apache.batchee.jsefa;
 
 import net.sf.jsefa.Serializer;
 import net.sf.jsefa.csv.CsvIOFactory;
+import net.sf.jsefa.csv.CsvSerializer;
+import net.sf.jsefa.csv.lowlevel.config.CsvLowLevelConfiguration;
 import org.apache.batchee.doc.api.Documentation;
 
 import javax.batch.api.BatchProperty;
 import javax.inject.Inject;
+import java.io.Serializable;
 
 @Documentation("Writes a CSV file using JSefa.")
 public class JSefaCsvWriter extends JSefaWriter {
@@ -80,6 +83,17 @@ public class JSefaCsvWriter extends JSefaWriter {
     @Documentation("should deliimter be used after last field")
     private String useDelimiterAfterLastField;
 
+    @Inject
+    @BatchProperty
+    @Documentation("the header for the file")
+    private String header;
+
+    @Inject
+    @BatchProperty
+    @Documentation("Should the header be calculated from @Header or fieldnames 
if @Header is not present on fields annotated with @CsvField. " +
+                   "This property will be ignored if the header property is 
set.")
+    private Boolean writeHeader;
+
     @Override
     protected Serializer createSerializer() throws Exception {
         return CsvIOFactory.createFactory(
@@ -91,4 +105,47 @@ public class JSefaCsvWriter extends JSefaWriter {
             JsefaConfigurations.createObjectTypes(objectTypes))
             .createSerializer();
     }
+
+    @Override
+    public void open(Serializable checkpoint) throws Exception {
+        super.open(checkpoint);
+
+        // write header only on first run
+        if (checkpoint != null) {
+            return;
+        }
+
+        char delimiter;
+        if (fieldDelimiter != null && !fieldDelimiter.isEmpty()) {
+            delimiter = fieldDelimiter.charAt(0);
+        } else {
+            delimiter = 
CsvLowLevelConfiguration.Defaults.DEFAULT_FIELD_DELIMITER;
+        }
+
+        //X TODO align behavoir of DefaultBAtchArtifactFactory and 
CDIBatchArtifactFactory?
+        //X      DefaultBatchArtifactFactory only resolves properties which 
are set, while
+        //X      CDIBatchArtifactFactory resolves every field...
+        if (header == null && writeHeader != null && writeHeader) {
+            Class<?>[] classes = 
JsefaConfigurations.createObjectTypes(objectTypes);
+
+            StringBuilder headerBuilder = new StringBuilder(50);
+            for (JSefaCsvMapping mapping : JSefaCsvMapping.forTypes(classes)) {
+
+                for (String headerPart : mapping.getHeader()) {
+
+                    if (headerBuilder.length() > 0) {
+                        headerBuilder.append(delimiter);
+                    }
+
+                    headerBuilder.append(headerPart);
+                }
+            }
+
+            header = headerBuilder.toString();
+        }
+
+        if (header != null && !header.trim().isEmpty()) {
+            ((CsvSerializer) 
serializer).getLowLevelSerializer().writeLine(header.trim());
+        }
+    }
 }

http://git-wip-us.apache.org/repos/asf/incubator-batchee/blob/71105426/extensions/jsefa/src/test/java/org/apache/batchee/jsefa/JSefaCsvReaderTest.java
----------------------------------------------------------------------
diff --git 
a/extensions/jsefa/src/test/java/org/apache/batchee/jsefa/JSefaCsvReaderTest.java
 
b/extensions/jsefa/src/test/java/org/apache/batchee/jsefa/JSefaCsvReaderTest.java
index bed7596..5d1eede 100644
--- 
a/extensions/jsefa/src/test/java/org/apache/batchee/jsefa/JSefaCsvReaderTest.java
+++ 
b/extensions/jsefa/src/test/java/org/apache/batchee/jsefa/JSefaCsvReaderTest.java
@@ -16,9 +16,14 @@
  */
 package org.apache.batchee.jsefa;
 
+import org.apache.batchee.extras.typed.TypedItemProcessor;
+import org.apache.batchee.jsefa.bean.Address;
+import org.apache.batchee.jsefa.bean.PersonWithAddress;
 import org.apache.batchee.jsefa.bean.Record;
+import org.apache.batchee.jsefa.util.CsvUtil;
 import org.apache.batchee.jsefa.util.IOs;
 import org.apache.batchee.util.Batches;
+import org.testng.Assert;
 import org.testng.annotations.Test;
 
 import javax.batch.api.chunk.ItemProcessor;
@@ -51,6 +56,33 @@ public class JSefaCsvReaderTest {
         }
     }
 
+
+    @Test
+    public void testReadWithHeader() {
+        String path = "target/work/JsefaCsvReaderWithHeader.csv";
+
+        Properties properties = new Properties();
+        properties.setProperty("input", path);
+
+        StringBuilder csvBuilder = new StringBuilder(200);
+        for (int i = 0; i < 10; i++) {
+            csvBuilder.append(IOs.LINE_SEPARATOR)
+                      .append(CsvUtil.toCsv(new PersonWithAddress("firstName_" 
+ i,
+                                                                  "lastName_" 
+ i,
+                                                                  new 
Address("street_" + i,
+                                                                              
"zip_" + i,
+                                                                              
"city_" + i))));
+        }
+
+        IOs.write(path, csvBuilder.toString());
+
+        JobOperator operator = BatchRuntime.getJobOperator();
+        Batches.waitForEnd(operator, operator.start("jsefa-csv-reader-header", 
properties));
+
+        Assert.assertEquals(Storage.ITEMS.size(), 10);
+
+    }
+
     public static class StoreItems implements ItemProcessor {
         public static final List<Record> ITEMS = new ArrayList<Record>(3);
 
@@ -60,4 +92,15 @@ public class JSefaCsvReaderTest {
             return item;
         }
     }
+
+    public static class Storage extends TypedItemProcessor<PersonWithAddress, 
PersonWithAddress> {
+
+        static final List<PersonWithAddress> ITEMS = new 
ArrayList<PersonWithAddress>(10);
+
+        @Override
+        protected PersonWithAddress doProcessItem(PersonWithAddress item) {
+            ITEMS.add(item);
+            return item;
+        }
+    }
 }

http://git-wip-us.apache.org/repos/asf/incubator-batchee/blob/71105426/extensions/jsefa/src/test/java/org/apache/batchee/jsefa/JSefaCsvWriterHeaderTest.java
----------------------------------------------------------------------
diff --git 
a/extensions/jsefa/src/test/java/org/apache/batchee/jsefa/JSefaCsvWriterHeaderTest.java
 
b/extensions/jsefa/src/test/java/org/apache/batchee/jsefa/JSefaCsvWriterHeaderTest.java
new file mode 100644
index 0000000..baaf3d8
--- /dev/null
+++ 
b/extensions/jsefa/src/test/java/org/apache/batchee/jsefa/JSefaCsvWriterHeaderTest.java
@@ -0,0 +1,249 @@
+/*
+ * 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.batchee.jsefa;
+
+import org.apache.batchee.extras.typed.NoStateTypedItemReader;
+import org.apache.batchee.jsefa.bean.Address;
+import org.apache.batchee.jsefa.bean.Person;
+import org.apache.batchee.jsefa.bean.PersonWithAddress;
+import org.apache.batchee.jsefa.bean.Record;
+import org.apache.batchee.jsefa.bean.RecordWithHeader;
+import org.apache.batchee.jsefa.util.CsvUtil;
+import org.apache.batchee.jsefa.util.IOs;
+import org.apache.batchee.util.Batches;
+import org.testng.Assert;
+import org.testng.annotations.Test;
+
+import javax.batch.api.chunk.AbstractItemReader;
+import javax.batch.operations.JobOperator;
+import javax.batch.runtime.BatchRuntime;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Properties;
+
+public class JSefaCsvWriterHeaderTest {
+
+
+    /**
+     * Tests a specified header via xml-file
+     *
+     * {@code <property name="header" value="VALUE1;VALUE2" />}
+     */
+    @Test
+    public void testWriteWithPropertyHeader() {
+
+        startBatchAndAssertResult("target/work/JSefaCsvWriterHeaderTest.csv",
+                                  "jsefa-csv-writer-header",
+                                  "VALUE1;VALUE2",
+                                  RecordReader.STORAGE);
+    }
+
+    @Test
+    public void testWriteHeaderFromFieldsOneType() {
+
+        
startBatchAndAssertResult("target/work/JSefaCsvWriterHeaderFromFieldsOnTypeTest.csv",
+                                  "jsefa-csv-writer-header-fromFieldsOneType",
+                                  "firstName;lastName",
+                                  SimpleOneTypeReader.STORAGE);
+    }
+
+    @Test
+    public void testWriteHeaderFromFieldsWithInheritance() {
+
+        
startBatchAndAssertResult("target/work/JSefaCsvWriterHeaderWithInheritance.csv",
+                                  
"jsefa-csv-writer-header-fromFieldsWithInheritance",
+                                  "firstName;lastName;street;zip;city",
+                                  InheritanceReader.STORAGE);
+    }
+
+    @Test
+    public void testWriteHeaderFromFieldsMoreObjectTypes() {
+
+        
startBatchAndAssertResult("target/work/JSefaCsvWriterHeaderMoreObjects.csv",
+                                  
"jsefa-csv-writer-header-fromFieldsMoreObjects",
+                                  "firstName;lastName;street;zip;city",
+                                  MoreObjectReader.STORAGE);
+    }
+
+    @Test
+    public void testWriteHeaderFromHeaderAnnotation() {
+
+        
startBatchAndAssertResult("target/work/JsefaCsvWriterHeaderFromAnnotation.csv",
+                                  
"jsefa-csv-writer-header-fromHeaderAnnotation",
+                                  "VALUE_HEADER;ANOTHER_VALUE_HEADER",
+                                  HeaderAnnotationReader.STORAGE);
+    }
+
+
+    private void startBatchAndAssertResult(String path,
+                                           String jobName,
+                                           String header,
+                                           List storage) {
+
+        Properties properties = new Properties();
+        properties.setProperty("output", path);
+
+        JobOperator jobOperator = BatchRuntime.getJobOperator();
+        Batches.waitForEnd(jobOperator, jobOperator.start(jobName, 
properties));
+
+        List<String> lines = IOs.getLines(path);
+
+        int expectedSize = header == null ? storage.size() : storage.size() + 
1;
+        Assert.assertEquals(lines.size(), expectedSize);
+
+        for (int i = 0; i < lines.size(); i++) {
+
+            String line = lines.get(i);
+            String expected;
+
+            if (header == null) {
+                expected = CsvUtil.toCsv(storage.get(i));
+            }
+            else if (i == 0) {
+                expected = header;
+            }
+            else {
+                expected = CsvUtil.toCsv(storage.get(i - 1));
+            }
+
+            Assert.assertEquals(line, expected);
+        }
+    }
+
+
+    public static class RecordReader extends NoStateTypedItemReader<Record> {
+
+        static final List<Record> STORAGE = new ArrayList<Record>(5);
+
+
+        private int count;
+
+        @Override
+        protected Record doRead() {
+
+            if (count++ < 5) {
+                Record record = new Record("Entry_" + count + "_Value_");
+
+                STORAGE.add(record);
+                return record;
+            }
+
+            return null;
+        }
+    }
+
+    public static class SimpleOneTypeReader extends AbstractItemReader {
+
+        static final List<Person> STORAGE = new ArrayList<Person>();
+
+
+        private int count;
+
+
+        @Override
+        public Object readItem() throws Exception {
+
+            if (count++ < 10) {
+
+                Person person = new Person("firstName_" + count, "lastName_" + 
count);
+
+                STORAGE.add(person);
+                return person;
+            }
+
+            return null;
+        }
+    }
+
+    public static class InheritanceReader extends AbstractItemReader {
+
+        static final List<PersonWithAddress> STORAGE = new 
ArrayList<PersonWithAddress>();
+
+
+        private int count;
+
+
+        @Override
+        public Object readItem() throws Exception {
+
+            if (count++ < 10) {
+
+                PersonWithAddress person = new PersonWithAddress("firstName_" 
+ count,
+                                                                 "lastName_" + 
count,
+                                                                 new 
Address("street_" + count,
+                                                                             
"zip_" + count,
+                                                                             
"city_" + count));
+
+                STORAGE.add(person);
+                return person;
+            }
+
+            return null;
+        }
+    }
+
+    public static class MoreObjectReader extends AbstractItemReader {
+
+        static final List<Object> STORAGE = new ArrayList<Object>();
+
+
+        private int count;
+
+
+        @Override
+        public Object readItem() throws Exception {
+
+            Object item;
+            if (count++ == 10) {
+                item = null;
+            }
+            else if (count % 2 == 0) {
+                item = new Person("firstName_" + count, "lastName_" + count);
+            }
+            else {
+                item = new Address("street_" + count, "zip_" + count, "city_" 
+ count);
+            }
+
+            if (item != null) {
+                STORAGE.add(item);
+            }
+
+            return item;
+        }
+    }
+
+    public static class HeaderAnnotationReader extends AbstractItemReader {
+
+        static final List<RecordWithHeader> STORAGE = new 
ArrayList<RecordWithHeader>(5);
+
+
+        private int count;
+
+        @Override
+        public Object readItem() throws Exception {
+
+            if (count++ < 5) {
+
+                RecordWithHeader record = new RecordWithHeader(count);
+                STORAGE.add(record);
+                return record;
+            }
+
+            return null;
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-batchee/blob/71105426/extensions/jsefa/src/test/java/org/apache/batchee/jsefa/JSefaCsvWriterTest.java
----------------------------------------------------------------------
diff --git 
a/extensions/jsefa/src/test/java/org/apache/batchee/jsefa/JSefaCsvWriterTest.java
 
b/extensions/jsefa/src/test/java/org/apache/batchee/jsefa/JSefaCsvWriterTest.java
index f8f4ede..d9ab821 100644
--- 
a/extensions/jsefa/src/test/java/org/apache/batchee/jsefa/JSefaCsvWriterTest.java
+++ 
b/extensions/jsefa/src/test/java/org/apache/batchee/jsefa/JSefaCsvWriterTest.java
@@ -16,17 +16,25 @@
  */
 package org.apache.batchee.jsefa;
 
+import org.apache.batchee.jsefa.bean.Address;
+import org.apache.batchee.jsefa.bean.Person;
+import org.apache.batchee.jsefa.bean.PersonWithAddress;
 import org.apache.batchee.jsefa.bean.Record;
+import org.apache.batchee.jsefa.util.CsvUtil;
 import org.apache.batchee.jsefa.util.IOs;
 import org.apache.batchee.util.Batches;
 import org.testng.annotations.Test;
 
+import javax.batch.api.chunk.AbstractItemReader;
 import javax.batch.api.chunk.ItemReader;
 import javax.batch.operations.JobOperator;
 import javax.batch.runtime.BatchRuntime;
 import java.io.Serializable;
+import java.util.ArrayList;
+import java.util.List;
 import java.util.Properties;
 
+import static org.testng.Assert.assertEquals;
 import static org.testng.Assert.assertTrue;
 
 public class JSefaCsvWriterTest {
@@ -45,6 +53,43 @@ public class JSefaCsvWriterTest {
         assertTrue(output.contains("v2_1;v2_2"));
     }
 
+    @Test
+    public void testWriteMultipleObjectTypes() {
+
+        
startBatchAndAssertResult("target/work/JSefaCsvWriterMulitObjectTypes.csv",
+                                  "jsefa-csv-writer-multiOjectTypes",
+                                  new Properties(),
+                                  MultipleObjectTypesReader.STORAGE);
+    }
+
+    @Test
+    public void testWriteNestedObjects() {
+
+        
startBatchAndAssertResult("target/work/JSefaCsvWriterNestedObjects.csv",
+                                  "jsefa-csv-writer-nestedObjects",
+                                  new Properties(),
+                                  NestedObjectReader.STORAGE);
+    }
+
+
+    private void startBatchAndAssertResult(String path,
+                                           String jobName,
+                                           Properties jobProperties,
+                                           List storage) {
+
+        jobProperties.setProperty("output", path);
+
+        JobOperator jobOperator = BatchRuntime.getJobOperator();
+        Batches.waitForEnd(jobOperator, jobOperator.start(jobName, 
jobProperties));
+
+        List<String> batchOutput = IOs.getLines(path);
+        assertEquals(batchOutput.size(), storage.size());
+
+        for (int i = 0; i < batchOutput.size(); i++) {
+            assertEquals(batchOutput.get(i), CsvUtil.toCsv(storage.get(i)));
+        }
+    }
+
     public static class TwoItemsReader implements ItemReader {
         private int count = 0;
 
@@ -71,4 +116,52 @@ public class JSefaCsvWriterTest {
             return null;
         }
     }
+
+    public static class MultipleObjectTypesReader extends AbstractItemReader {
+        static final List<Object> STORAGE = new ArrayList<Object>();
+
+        private int count;
+
+        @Override
+        public Object readItem() throws Exception {
+
+            if (count++ == 10) {
+                return null;
+            }
+
+            Object item;
+            if (count % 2 == 0) {
+                item =  new Person("firstName_" + count, "lastName_" + count);
+            }
+            else {
+                item = new Address("street_" + count, "zip_" + count, "city_" 
+ count);
+            }
+
+            STORAGE.add(item);
+            return item;
+        }
+    }
+
+    public static class NestedObjectReader extends AbstractItemReader {
+        static final List<Person> STORAGE = new ArrayList<Person>(10);
+
+        private int count;
+
+        @Override
+        public Object readItem() throws Exception {
+
+            if (count++ == 10) {
+                return null;
+            }
+
+            PersonWithAddress item = new PersonWithAddress("firstName_" + 
count,
+                                                           "lastName_" + count,
+                                                           new 
Address("street_" + count,
+                                                                     "zip_" + 
count,
+                                                                     "city_" + 
count));
+            STORAGE.add(item);
+
+            return item;
+        }
+    }
 }

http://git-wip-us.apache.org/repos/asf/incubator-batchee/blob/71105426/extensions/jsefa/src/test/java/org/apache/batchee/jsefa/bean/Address.java
----------------------------------------------------------------------
diff --git 
a/extensions/jsefa/src/test/java/org/apache/batchee/jsefa/bean/Address.java 
b/extensions/jsefa/src/test/java/org/apache/batchee/jsefa/bean/Address.java
new file mode 100644
index 0000000..14f332d
--- /dev/null
+++ b/extensions/jsefa/src/test/java/org/apache/batchee/jsefa/bean/Address.java
@@ -0,0 +1,62 @@
+/*
+ * 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.batchee.jsefa.bean;
+
+import net.sf.jsefa.csv.annotation.CsvDataType;
+import net.sf.jsefa.csv.annotation.CsvField;
+
+@CsvDataType(defaultPrefix = "ADDRESS")
+public class Address {
+
+    @CsvField(pos = 1)
+    private String street;
+
+    @CsvField(pos = 2)
+    private String zip;
+
+    @CsvField(pos = 3)
+    private String city;
+
+
+    private Address() {
+        // no-op -> needed for jsefa
+    }
+
+    public Address(String street, String zip, String city) {
+        this.street = street;
+        this.zip = zip;
+        this.city = city;
+    }
+
+
+    public String getStreet() {
+        return street;
+    }
+
+    public String getZip() {
+        return zip;
+    }
+
+    public String getCity() {
+        return city;
+    }
+
+
+    public String toCsvString(String seperator) {
+        return street + seperator + zip + seperator + city;
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-batchee/blob/71105426/extensions/jsefa/src/test/java/org/apache/batchee/jsefa/bean/Person.java
----------------------------------------------------------------------
diff --git 
a/extensions/jsefa/src/test/java/org/apache/batchee/jsefa/bean/Person.java 
b/extensions/jsefa/src/test/java/org/apache/batchee/jsefa/bean/Person.java
new file mode 100644
index 0000000..5b152eb
--- /dev/null
+++ b/extensions/jsefa/src/test/java/org/apache/batchee/jsefa/bean/Person.java
@@ -0,0 +1,54 @@
+/*
+ * 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.batchee.jsefa.bean;
+
+import net.sf.jsefa.csv.annotation.CsvDataType;
+import net.sf.jsefa.csv.annotation.CsvField;
+
+@CsvDataType(defaultPrefix = "PERSON")
+public class Person {
+
+    @CsvField(pos = 1)
+    private String firstName;
+
+    @CsvField(pos = 2)
+    private String lastName;
+
+
+    private Person() {
+        // no-op -> needed for jsefa
+    }
+
+    public Person(String firstName, String lastName) {
+        this.firstName = firstName;
+        this.lastName = lastName;
+    }
+
+
+    public String getFirstName() {
+        return firstName;
+    }
+
+    public String getLastName() {
+        return lastName;
+    }
+
+
+    public String toCsvString(String seperator) {
+        return firstName + seperator + lastName;
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-batchee/blob/71105426/extensions/jsefa/src/test/java/org/apache/batchee/jsefa/bean/PersonWithAddress.java
----------------------------------------------------------------------
diff --git 
a/extensions/jsefa/src/test/java/org/apache/batchee/jsefa/bean/PersonWithAddress.java
 
b/extensions/jsefa/src/test/java/org/apache/batchee/jsefa/bean/PersonWithAddress.java
new file mode 100644
index 0000000..f29d35e
--- /dev/null
+++ 
b/extensions/jsefa/src/test/java/org/apache/batchee/jsefa/bean/PersonWithAddress.java
@@ -0,0 +1,42 @@
+/*
+ * 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.batchee.jsefa.bean;
+
+import net.sf.jsefa.csv.annotation.CsvDataType;
+import net.sf.jsefa.csv.annotation.CsvField;
+
+@CsvDataType
+public class PersonWithAddress extends Person {
+
+    @CsvField(pos = 3)
+    private Address address;
+
+
+    private PersonWithAddress() {
+        this(null, null, null);
+    }
+
+    public PersonWithAddress(String firstName, String lastName, Address 
address) {
+        super(firstName, lastName);
+        this.address = address;
+    }
+
+
+    public Address getAddress() {
+        return address;
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-batchee/blob/71105426/extensions/jsefa/src/test/java/org/apache/batchee/jsefa/bean/RecordWithHeader.java
----------------------------------------------------------------------
diff --git 
a/extensions/jsefa/src/test/java/org/apache/batchee/jsefa/bean/RecordWithHeader.java
 
b/extensions/jsefa/src/test/java/org/apache/batchee/jsefa/bean/RecordWithHeader.java
new file mode 100644
index 0000000..224f8d1
--- /dev/null
+++ 
b/extensions/jsefa/src/test/java/org/apache/batchee/jsefa/bean/RecordWithHeader.java
@@ -0,0 +1,51 @@
+/*
+ * 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.batchee.jsefa.bean;
+
+import net.sf.jsefa.csv.annotation.CsvDataType;
+import net.sf.jsefa.csv.annotation.CsvField;
+import org.apache.batchee.jsefa.Header;
+
+@CsvDataType
+public class RecordWithHeader {
+
+    @Header("VALUE_HEADER")
+    @CsvField(pos = 1)
+    private String value;
+
+    @Header("ANOTHER_VALUE_HEADER")
+    @CsvField(pos = 2)
+    private String anotherValue;
+
+
+    private RecordWithHeader() {
+    }
+
+    public RecordWithHeader(int count) {
+        this.value = "value_" + count;
+        this.anotherValue = "anotherValue_" + count;
+    }
+
+
+    public String getValue() {
+        return value;
+    }
+
+    public String getAnotherValue() {
+        return anotherValue;
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-batchee/blob/71105426/extensions/jsefa/src/test/java/org/apache/batchee/jsefa/util/CsvUtil.java
----------------------------------------------------------------------
diff --git 
a/extensions/jsefa/src/test/java/org/apache/batchee/jsefa/util/CsvUtil.java 
b/extensions/jsefa/src/test/java/org/apache/batchee/jsefa/util/CsvUtil.java
new file mode 100644
index 0000000..5afe1ff
--- /dev/null
+++ b/extensions/jsefa/src/test/java/org/apache/batchee/jsefa/util/CsvUtil.java
@@ -0,0 +1,115 @@
+/*
+ * 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.batchee.jsefa.util;
+
+import net.sf.jsefa.csv.annotation.CsvDataType;
+import net.sf.jsefa.csv.annotation.CsvField;
+import org.testng.Assert;
+
+import java.lang.reflect.Field;
+import java.util.SortedMap;
+import java.util.TreeMap;
+
+public final class CsvUtil {
+
+    private CsvUtil() {
+        // no instantiation
+    }
+
+
+    /**
+     * Converts the given Object annotated with {@link CsvDataType} to a 
csv-{@link String}
+     *
+     * @param object to convert
+     *
+     * @return the csv-{@link String}
+     */
+    public static String toCsv(Object object) {
+        return toCsv(object, false);
+    }
+
+    /**
+     * Converts the given Object annotated with {@link CsvDataType} to a 
csv-{@link String}
+     *
+     * @param object to convert
+     * @param ignorePrefix if {@code true} the {@link 
CsvDataType#defaultPrefix()} will be ignored for conversion
+     *
+     * @return the csv-{@link String}
+     */
+    public static String toCsv(Object object, boolean ignorePrefix) {
+        StringBuilder csvBuilder = new StringBuilder(30);
+
+        Class<?> clazz = object.getClass();
+        CsvDataType dataType = clazz.getAnnotation(CsvDataType.class);
+
+        // dataType can never be null, otherwise it can't be serialized with 
jsefa
+        if (!ignorePrefix && !"".equals(dataType.defaultPrefix())) {
+            csvBuilder.append(dataType.defaultPrefix());
+        }
+
+        for (String value : getValues(object, object.getClass(), new 
TreeMap<Integer, String>()).values()) {
+            if (csvBuilder.length() > 0) {
+                csvBuilder.append(";");
+            }
+
+            csvBuilder.append(value);
+        }
+
+        return csvBuilder.toString();
+
+    }
+
+
+    private static SortedMap<Integer, String> getValues(Object object, 
Class<?> clazz, SortedMap<Integer, String> values) {
+
+        if (clazz.getSuperclass() != Object.class) {
+            values = getValues(object, clazz.getSuperclass(), values);
+        }
+
+        Field[] fields = clazz.getDeclaredFields();
+        for (Field field : fields) {
+            CsvField annotation = field.getAnnotation(CsvField.class);
+            if (annotation == null) {
+                continue;
+            }
+
+            try {
+                field.setAccessible(true);
+                Object value = field.get(object);
+
+                if (value != null) {
+
+                    String valuetoPut;
+                    if (value.getClass().getAnnotation(CsvDataType.class) != 
null) {
+                        valuetoPut = toCsv(value, true);
+                    }
+                    else {
+                        valuetoPut = value.toString();
+                    }
+
+                    values.put(annotation.pos(), valuetoPut);
+                }
+            }
+            catch (IllegalAccessException e) {
+                Assert.fail("Cannot read from field " + field.getName(), e);
+            }
+        }
+
+        return values;
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-batchee/blob/71105426/extensions/jsefa/src/test/java/org/apache/batchee/jsefa/util/IOs.java
----------------------------------------------------------------------
diff --git 
a/extensions/jsefa/src/test/java/org/apache/batchee/jsefa/util/IOs.java 
b/extensions/jsefa/src/test/java/org/apache/batchee/jsefa/util/IOs.java
index b5e7c5a..5e5cd49 100644
--- a/extensions/jsefa/src/test/java/org/apache/batchee/jsefa/util/IOs.java
+++ b/extensions/jsefa/src/test/java/org/apache/batchee/jsefa/util/IOs.java
@@ -21,8 +21,14 @@ import java.io.File;
 import java.io.FileReader;
 import java.io.FileWriter;
 import java.io.IOException;
+import java.util.ArrayList;
+import java.util.List;
 
 public class IOs {
+
+    public static final String LINE_SEPARATOR = 
System.getProperty("line.separator");
+
+
     public static void write(final String path, final String content) {
         final File file = new File(path);
         if (!file.getParentFile().exists() && !file.getParentFile().mkdirs()) {
@@ -40,20 +46,40 @@ public class IOs {
 
     public static String slurp(final String path) {
         final StringBuilder builder = new StringBuilder();
+
+        for (String line : getLines(path)) {
+            builder.append(line).append(LINE_SEPARATOR);
+        }
+
+        return builder.toString();
+    }
+
+    public static List<String> getLines(final String path) {
+        List<String> lines = new ArrayList<String>();
+
+        BufferedReader reader = null;
         try {
-            final BufferedReader reader = new BufferedReader(new 
FileReader(path));
+            reader = new BufferedReader(new FileReader(path));
             String line;
-            do {
-                line = reader.readLine();
-                if (line != null) {
-                    
builder.append(line).append(System.getProperty("line.separator"));
-                }
-            } while (line != null);
-            reader.close();
-        } catch (final Exception e) {
+            while ((line = reader.readLine()) != null) {
+                lines.add(line);
+            }
+        }
+        catch (Exception e) {
             // no-op
         }
-        return builder.toString();
+        finally {
+            if (reader != null) {
+                try {
+                    reader.close();
+                }
+                catch (IOException e) {
+                    // bad luck
+                }
+            }
+        }
+
+        return lines;
     }
 
     private IOs() {

http://git-wip-us.apache.org/repos/asf/incubator-batchee/blob/71105426/extensions/jsefa/src/test/resources/META-INF/batch-jobs/jsefa-csv-reader-header.xml
----------------------------------------------------------------------
diff --git 
a/extensions/jsefa/src/test/resources/META-INF/batch-jobs/jsefa-csv-reader-header.xml
 
b/extensions/jsefa/src/test/resources/META-INF/batch-jobs/jsefa-csv-reader-header.xml
new file mode 100644
index 0000000..069a234
--- /dev/null
+++ 
b/extensions/jsefa/src/test/resources/META-INF/batch-jobs/jsefa-csv-reader-header.xml
@@ -0,0 +1,30 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+  See the NOTICE file distributed with this work for additional information
+  regarding copyright ownership. Licensed 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.
+-->
+<job id="jsefa-csv-reader-header" xmlns="http://xmlns.jcp.org/xml/ns/javaee"; 
version="1.0">
+  <step id="step1">
+    <chunk>
+      <reader ref="jsefaCsvReader">
+        <properties>
+          <property name="file" value="#{jobParameters['input']}"/>
+          <property name="objectTypes" 
value="org.apache.batchee.jsefa.bean.PersonWithAddress"/>
+          <property name="ignoreHeader" value="true" />
+        </properties>
+      </reader>
+      <processor ref="org.apache.batchee.jsefa.JSefaCsvReaderTest$Storage" />
+      <writer ref="noopWriter" />
+    </chunk>
+  </step>
+</job>

http://git-wip-us.apache.org/repos/asf/incubator-batchee/blob/71105426/extensions/jsefa/src/test/resources/META-INF/batch-jobs/jsefa-csv-writer-header-fromFieldsMoreObjects.xml
----------------------------------------------------------------------
diff --git 
a/extensions/jsefa/src/test/resources/META-INF/batch-jobs/jsefa-csv-writer-header-fromFieldsMoreObjects.xml
 
b/extensions/jsefa/src/test/resources/META-INF/batch-jobs/jsefa-csv-writer-header-fromFieldsMoreObjects.xml
new file mode 100644
index 0000000..43462fb
--- /dev/null
+++ 
b/extensions/jsefa/src/test/resources/META-INF/batch-jobs/jsefa-csv-writer-header-fromFieldsMoreObjects.xml
@@ -0,0 +1,29 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+  See the NOTICE file distributed with this work for additional information
+  regarding copyright ownership. Licensed 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.
+-->
+<job id="jsefa-csv-writer-header-fromFieldsMoreObjects" 
xmlns="http://xmlns.jcp.org/xml/ns/javaee"; version="1.0">
+  <step id="step1">
+    <chunk>
+      <reader 
ref="org.apache.batchee.jsefa.JSefaCsvWriterHeaderTest$MoreObjectReader" />
+      <writer ref="jsefaCsvWriter">
+        <properties>
+          <property name="file" value="#{jobParameters['output']}"/>
+          <property name="objectTypes" 
value="org.apache.batchee.jsefa.bean.Person,org.apache.batchee.jsefa.bean.Address"
 />
+          <property name="writeHeader" value="true" />
+        </properties>
+      </writer>
+    </chunk>
+  </step>
+</job>

http://git-wip-us.apache.org/repos/asf/incubator-batchee/blob/71105426/extensions/jsefa/src/test/resources/META-INF/batch-jobs/jsefa-csv-writer-header-fromFieldsOneType.xml
----------------------------------------------------------------------
diff --git 
a/extensions/jsefa/src/test/resources/META-INF/batch-jobs/jsefa-csv-writer-header-fromFieldsOneType.xml
 
b/extensions/jsefa/src/test/resources/META-INF/batch-jobs/jsefa-csv-writer-header-fromFieldsOneType.xml
new file mode 100644
index 0000000..3032c1d
--- /dev/null
+++ 
b/extensions/jsefa/src/test/resources/META-INF/batch-jobs/jsefa-csv-writer-header-fromFieldsOneType.xml
@@ -0,0 +1,29 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+  See the NOTICE file distributed with this work for additional information
+  regarding copyright ownership. Licensed 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.
+-->
+<job id="jsefa-csv-writer-header-fromFieldsOneType" 
xmlns="http://xmlns.jcp.org/xml/ns/javaee"; version="1.0">
+  <step id="step1">
+    <chunk>
+      <reader 
ref="org.apache.batchee.jsefa.JSefaCsvWriterHeaderTest$SimpleOneTypeReader" />
+      <writer ref="jsefaCsvWriter">
+        <properties>
+          <property name="file" value="#{jobParameters['output']}"/>
+          <property name="objectTypes" 
value="org.apache.batchee.jsefa.bean.Person" />
+          <property name="writeHeader" value="true" />
+        </properties>
+      </writer>
+    </chunk>
+  </step>
+</job>

http://git-wip-us.apache.org/repos/asf/incubator-batchee/blob/71105426/extensions/jsefa/src/test/resources/META-INF/batch-jobs/jsefa-csv-writer-header-fromFieldsWithInheritance.xml
----------------------------------------------------------------------
diff --git 
a/extensions/jsefa/src/test/resources/META-INF/batch-jobs/jsefa-csv-writer-header-fromFieldsWithInheritance.xml
 
b/extensions/jsefa/src/test/resources/META-INF/batch-jobs/jsefa-csv-writer-header-fromFieldsWithInheritance.xml
new file mode 100644
index 0000000..1b48844
--- /dev/null
+++ 
b/extensions/jsefa/src/test/resources/META-INF/batch-jobs/jsefa-csv-writer-header-fromFieldsWithInheritance.xml
@@ -0,0 +1,29 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+  See the NOTICE file distributed with this work for additional information
+  regarding copyright ownership. Licensed 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.
+-->
+<job id="jsefa-csv-writer-header-fromFieldsWithInheritance" 
xmlns="http://xmlns.jcp.org/xml/ns/javaee"; version="1.0">
+  <step id="step1">
+    <chunk>
+      <reader 
ref="org.apache.batchee.jsefa.JSefaCsvWriterHeaderTest$InheritanceReader" />
+      <writer ref="jsefaCsvWriter">
+        <properties>
+          <property name="file" value="#{jobParameters['output']}"/>
+          <property name="objectTypes" 
value="org.apache.batchee.jsefa.bean.PersonWithAddress" />
+          <property name="writeHeader" value="true" />
+        </properties>
+      </writer>
+    </chunk>
+  </step>
+</job>

http://git-wip-us.apache.org/repos/asf/incubator-batchee/blob/71105426/extensions/jsefa/src/test/resources/META-INF/batch-jobs/jsefa-csv-writer-header-fromHeaderAnnotation.xml
----------------------------------------------------------------------
diff --git 
a/extensions/jsefa/src/test/resources/META-INF/batch-jobs/jsefa-csv-writer-header-fromHeaderAnnotation.xml
 
b/extensions/jsefa/src/test/resources/META-INF/batch-jobs/jsefa-csv-writer-header-fromHeaderAnnotation.xml
new file mode 100644
index 0000000..49021c8
--- /dev/null
+++ 
b/extensions/jsefa/src/test/resources/META-INF/batch-jobs/jsefa-csv-writer-header-fromHeaderAnnotation.xml
@@ -0,0 +1,29 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+  See the NOTICE file distributed with this work for additional information
+  regarding copyright ownership. Licensed 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.
+-->
+<job id="jsefa-csv-writer-header-fromHeaderAnnotation.xml" 
xmlns="http://xmlns.jcp.org/xml/ns/javaee"; version="1.0">
+  <step id="step1">
+    <chunk>
+      <reader 
ref="org.apache.batchee.jsefa.JSefaCsvWriterHeaderTest$HeaderAnnotationReader" 
/>
+      <writer ref="jsefaCsvWriter">
+        <properties>
+          <property name="file" value="#{jobParameters['output']}"/>
+          <property name="objectTypes" 
value="org.apache.batchee.jsefa.bean.RecordWithHeader" />
+          <property name="writeHeader" value="true" />
+        </properties>
+      </writer>
+    </chunk>
+  </step>
+</job>

http://git-wip-us.apache.org/repos/asf/incubator-batchee/blob/71105426/extensions/jsefa/src/test/resources/META-INF/batch-jobs/jsefa-csv-writer-header.xml
----------------------------------------------------------------------
diff --git 
a/extensions/jsefa/src/test/resources/META-INF/batch-jobs/jsefa-csv-writer-header.xml
 
b/extensions/jsefa/src/test/resources/META-INF/batch-jobs/jsefa-csv-writer-header.xml
new file mode 100644
index 0000000..4d27242
--- /dev/null
+++ 
b/extensions/jsefa/src/test/resources/META-INF/batch-jobs/jsefa-csv-writer-header.xml
@@ -0,0 +1,29 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+  See the NOTICE file distributed with this work for additional information
+  regarding copyright ownership. Licensed 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.
+-->
+<job id="jsefa-csv-writer-header" xmlns="http://xmlns.jcp.org/xml/ns/javaee"; 
version="1.0">
+    <step id="step1">
+        <chunk>
+            <reader 
ref="org.apache.batchee.jsefa.JSefaCsvWriterHeaderTest$RecordReader" />
+            <writer ref="jsefaCsvWriter">
+                <properties>
+                    <property name="file" value="#{jobParameters['output']}"/>
+                    <property name="objectTypes" 
value="org.apache.batchee.jsefa.bean.Record"/>
+                    <property name="header" value="VALUE1;VALUE2" />
+                </properties>
+            </writer>
+        </chunk>
+    </step>
+</job>

http://git-wip-us.apache.org/repos/asf/incubator-batchee/blob/71105426/extensions/jsefa/src/test/resources/META-INF/batch-jobs/jsefa-csv-writer-multiOjectTypes.xml
----------------------------------------------------------------------
diff --git 
a/extensions/jsefa/src/test/resources/META-INF/batch-jobs/jsefa-csv-writer-multiOjectTypes.xml
 
b/extensions/jsefa/src/test/resources/META-INF/batch-jobs/jsefa-csv-writer-multiOjectTypes.xml
new file mode 100644
index 0000000..0ae4545
--- /dev/null
+++ 
b/extensions/jsefa/src/test/resources/META-INF/batch-jobs/jsefa-csv-writer-multiOjectTypes.xml
@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+  See the NOTICE file distributed with this work for additional information
+  regarding copyright ownership. Licensed 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.
+-->
+<job id="jsefa-csv-writer-multiObjectTypes" 
xmlns="http://xmlns.jcp.org/xml/ns/javaee"; version="1.0">
+  <step id="step1">
+    <chunk>
+      <reader 
ref="org.apache.batchee.jsefa.JSefaCsvWriterTest$MultipleObjectTypesReader" />
+      <writer ref="jsefaCsvWriter">
+        <properties>
+          <property name="file" value="#{jobParameters['output']}"/>
+          <property name="objectTypes" 
value="org.apache.batchee.jsefa.bean.Person,org.apache.batchee.jsefa.bean.Address"
 />
+        </properties>
+      </writer>
+    </chunk>
+  </step>
+</job>

http://git-wip-us.apache.org/repos/asf/incubator-batchee/blob/71105426/extensions/jsefa/src/test/resources/META-INF/batch-jobs/jsefa-csv-writer-nestedObjects.xml
----------------------------------------------------------------------
diff --git 
a/extensions/jsefa/src/test/resources/META-INF/batch-jobs/jsefa-csv-writer-nestedObjects.xml
 
b/extensions/jsefa/src/test/resources/META-INF/batch-jobs/jsefa-csv-writer-nestedObjects.xml
new file mode 100644
index 0000000..4efe6a5
--- /dev/null
+++ 
b/extensions/jsefa/src/test/resources/META-INF/batch-jobs/jsefa-csv-writer-nestedObjects.xml
@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+  See the NOTICE file distributed with this work for additional information
+  regarding copyright ownership. Licensed 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.
+-->
+<job id="jsefa-csv-writer-multiObjectTypes" 
xmlns="http://xmlns.jcp.org/xml/ns/javaee"; version="1.0">
+  <step id="step1">
+    <chunk>
+      <reader 
ref="org.apache.batchee.jsefa.JSefaCsvWriterTest$NestedObjectReader" />
+      <writer ref="jsefaCsvWriter">
+        <properties>
+          <property name="file" value="#{jobParameters['output']}"/>
+          <property name="objectTypes" 
value="org.apache.batchee.jsefa.bean.PersonWithAddress" />
+        </properties>
+      </writer>
+    </chunk>
+  </step>
+</job>

Reply via email to