View Javadoc
1   /*
2    * Copyright 2007 Kasper B. Graversen
3    * 
4    * Licensed under the Apache License, Version 2.0 (the "License");
5    * you may not use this file except in compliance with the License.
6    * You may obtain a copy of the License at
7    * 
8    *     http://www.apache.org/licenses/LICENSE-2.0
9    * 
10   * Unless required by applicable law or agreed to in writing, software
11   * distributed under the License is distributed on an "AS IS" BASIS,
12   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13   * See the License for the specific language governing permissions and
14   * limitations under the License.
15   */
16  package org.supercsv.io;
17  
18  import java.io.IOException;
19  import java.io.Writer;
20  import java.lang.reflect.Method;
21  import java.util.ArrayList;
22  import java.util.List;
23  
24  import org.supercsv.cellprocessor.ift.CellProcessor;
25  import org.supercsv.exception.SuperCsvReflectionException;
26  import org.supercsv.prefs.CsvPreference;
27  import org.supercsv.util.MethodCache;
28  import org.supercsv.util.Util;
29  
30  /**
31   * CsvBeanWriter writes a CSV file by mapping each field on the bean to a column in the CSV file (using the supplied
32   * name mapping).
33   * 
34   * @author Kasper B. Graversen
35   * @author James Bassett
36   */
37  public class CsvBeanWriter extends AbstractCsvWriter implements ICsvBeanWriter {
38  	
39  	// temporary storage of bean values
40  	private final List<Object> beanValues = new ArrayList<Object>();
41  	
42  	// temporary storage of processed columns to be written
43  	private final List<Object> processedColumns = new ArrayList<Object>();
44  	
45  	// cache of methods for mapping from fields to columns
46  	private final MethodCache cache = new MethodCache();
47  	
48  	/**
49  	 * Constructs a new <tt>CsvBeanWriter</tt> with the supplied Writer and CSV preferences. Note that the
50  	 * <tt>writer</tt> will be wrapped in a <tt>BufferedWriter</tt> before accessed.
51  	 * 
52  	 * @param writer
53  	 *            the writer
54  	 * @param preference
55  	 *            the CSV preferences
56  	 * @throws NullPointerException
57  	 *             if writer or preference are null
58  	 */
59  	public CsvBeanWriter(final Writer writer, final CsvPreference preference) {
60  		super(writer, preference);
61  	}
62  	
63  	/**
64  	 * Extracts the bean values, using the supplied name mapping array.
65  	 * 
66  	 * @param source
67  	 *            the bean
68  	 * @param nameMapping
69  	 *            the name mapping
70  	 * @throws NullPointerException
71  	 *             if source or nameMapping are null
72  	 * @throws SuperCsvReflectionException
73  	 *             if there was a reflection exception extracting the bean value
74  	 */
75  	private void extractBeanValues(final Object source, final String[] nameMapping) {
76  		
77  		if( source == null ) {
78  			throw new NullPointerException("the bean to write should not be null");
79  		} else if( nameMapping == null ) {
80  			throw new NullPointerException(
81  				"the nameMapping array can't be null as it's used to map from fields to columns");
82  		}
83  		
84  		beanValues.clear();
85  		
86  		for( int i = 0; i < nameMapping.length; i++ ) {
87  			
88  			final String fieldName = nameMapping[i];
89  			
90  			if( fieldName == null ) {
91  				beanValues.add(null); // assume they always want a blank column
92  				
93  			} else {
94  				Method getMethod = cache.getGetMethod(source, fieldName);
95  				try {
96  					beanValues.add(getMethod.invoke(source));
97  				}
98  				catch(final Exception e) {
99  					throw new SuperCsvReflectionException(String.format("error extracting bean value for field %s",
100 						fieldName), e);
101 				}
102 			}
103 			
104 		}
105 		
106 	}
107 	
108 	/**
109 	 * {@inheritDoc}
110 	 */
111 	public void write(final Object source, final String... nameMapping) throws IOException {
112 		
113 		// update the current row/line numbers
114 		super.incrementRowAndLineNo();
115 		
116 		// extract the bean values
117 		extractBeanValues(source, nameMapping);
118 		
119 		// write the list
120 		super.writeRow(beanValues);
121 	}
122 	
123 	/**
124 	 * {@inheritDoc}
125 	 */
126 	public void write(final Object source, final String[] nameMapping, final CellProcessor[] processors)
127 		throws IOException {
128 		
129 		// update the current row/line numbers
130 		super.incrementRowAndLineNo();
131 		
132 		// extract the bean values
133 		extractBeanValues(source, nameMapping);
134 		
135 		// execute the processors for each column
136 		Util.executeCellProcessors(processedColumns, beanValues, processors, getLineNumber(), getRowNumber());
137 		
138 		// write the list
139 		super.writeRow(processedColumns);
140 	}
141 }