View Javadoc
1   /*
2    * Copyright 2013 the original author or authors.
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  
17  package com.orangesignal.csv.handlers;
18  
19  import java.io.IOException;
20  import java.text.Format;
21  import java.util.ArrayList;
22  import java.util.List;
23  import java.util.Map;
24  
25  import com.orangesignal.csv.CsvReader;
26  import com.orangesignal.csv.CsvWriter;
27  import com.orangesignal.csv.bean.CsvColumnPositionMappingBeanTemplate;
28  import com.orangesignal.csv.filters.CsvValueFilter;
29  import com.orangesignal.csv.io.CsvColumnPositionMappingBeanReader;
30  import com.orangesignal.csv.io.CsvColumnPositionMappingBeanWriter;
31  
32  /**
33   * 区切り文字形式データの項目位置を基準として Java プログラム要素のリストと区切り文字形式データアクセスを行うハンドラを提供します。
34   * 
35   * @author Koji Sugisawa
36   * @see com.orangesignal.csv.manager.CsvColumnPositionMappingBeanManager
37   */
38  public class ColumnPositionMappingBeanListHandler<T> extends AbstractBeanListHandler<T, CsvColumnPositionMappingBeanTemplate<T>, ColumnPositionMappingBeanListHandler<T>> {
39  
40  	/**
41  	 * 区切り文字形式データの列見出し (ヘッダ) 行を出力するかどうかを保持します。
42  	 * 
43  	 * @since 2.1
44  	 */
45  	private boolean header = true;
46  
47  	// ------------------------------------------------------------------------
48  
49  	/**
50  	 * コンストラクタです。
51  	 * 
52  	 * @param type Java プログラム要素の型
53  	 * @throws IllegalArgumentException {@code type} が {@code null} の場合
54  	 */
55  	public ColumnPositionMappingBeanListHandler(final Class<T> type) {
56  		super(CsvColumnPositionMappingBeanTemplate.newInstance(type));
57  	}
58  
59  	// ------------------------------------------------------------------------
60  
61  	/**
62  	 * 指定された Java プログラム要素のフィールド名を現在の最後の項目位置としてマップへ追加します。
63  	 * 
64  	 * @param field Java プログラム要素のフィールド名
65  	 * @return このオブジェクトへの参照
66  	 */
67  	public ColumnPositionMappingBeanListHandler<T> addColumn(final String field) {
68  		return addColumn(field, null);
69  	}
70  
71  	/**
72  	 * 指定された Java プログラム要素のフィールド名を現在の最後の項目位置としてマップへ追加します。
73  	 * 
74  	 * @param field Java プログラム要素のフィールド名
75  	 * @param format フィールドを処理するフォーマットオブジェクト (オプション)
76  	 * @return このオブジェクトへの参照
77  	 * @since 1.2
78  	 */
79  	public ColumnPositionMappingBeanListHandler<T> addColumn(final String field, final Format format) {
80  		template.column(field, format);
81  		return this;
82  	}
83  
84  	/**
85  	 * 指定された項目位置と Java プログラム要素のフィールド名をマップへ追加します。
86  	 * 
87  	 * @param position 項目位置
88  	 * @param field Java プログラム要素のフィールド名
89  	 * @return このオブジェクトへの参照
90  	 */
91  	public ColumnPositionMappingBeanListHandler<T> addColumn(final int position, final String field) {
92  		return addColumn(position, field, null);
93  	}
94  
95  	/**
96  	 * 指定された項目位置と Java プログラム要素のフィールド名をマップへ追加します。
97  	 * 
98  	 * @param position 項目名
99  	 * @param field Java プログラム要素のフィールド名
100 	 * @param format フィールドを処理するフォーマットオブジェクト (オプション)
101 	 * @return このオブジェクトへの参照
102 	 * @since 1.2
103 	 */
104 	public ColumnPositionMappingBeanListHandler<T> addColumn(final int position, final String field, final Format format) {
105 		template.column(position, field, format);
106 		return this;
107 	}
108 
109 	/**
110 	 * 項目位置と Java プログラム要素のフィールド名のマップを設定します。
111 	 * 
112 	 * @param columnMapping 項目位置と Java プログラム要素のフィールド名のマップ
113 	 * @throws IllegalArgumentException {@code columnMapping} が {@code null} の場合
114 	 * @since 1.2.4
115 	 */
116 	public void setColumnMapping(final Map<Integer, String> columnMapping) {
117 		template.setColumnMapping(columnMapping);
118 	}
119 
120 	/**
121 	 * 項目位置と Java プログラム要素のフィールド名のマップを設定します。
122 	 * 
123 	 * @param columnMapping 項目位置と Java プログラム要素のフィールド名のマップ
124 	 * @return このオブジェクトへの参照
125 	 * @throws IllegalArgumentException {@code columnMapping} が {@code null} の場合
126 	 */
127 	public ColumnPositionMappingBeanListHandler<T> columnMapping(final Map<Integer, String> columnMapping) {
128 		setColumnMapping(columnMapping);
129 		return this;
130 	}
131 
132 	/**
133 	 * 区切り文字形式データフィルタを設定します。
134 	 * 
135 	 * @param filter 区切り文字形式データフィルタ
136 	 * @return このオブジェクトへの参照
137 	 * @since 1.2.3
138 	 */
139 	public ColumnPositionMappingBeanListHandler<T> filter(final CsvValueFilter filter) {
140 		template.filter(filter);
141 		return this;
142 	}
143 
144 	/**
145 	 * 区切り文字形式データの列見出し (ヘッダ) 行を出力するかどうかを設定します。
146 	 * 
147 	 * @param header 区切り文字形式データの列見出し (ヘッダ) 行を出力するかどうか
148 	 * @return このオブジェクトへの参照
149 	 * @since 2.1
150 	 */
151 	public ColumnPositionMappingBeanListHandler<T> header(final boolean header) {
152 		this.header = header;
153 		return this;
154 	}
155 
156 	// ------------------------------------------------------------------------
157 
158 	@Override
159 	public List<T> load(final CsvReader reader, final boolean ignoreScalar) throws IOException {
160 		@SuppressWarnings("resource")
161 		final CsvColumnPositionMappingBeanReader<T> r = new CsvColumnPositionMappingBeanReader<T>(reader, template);
162 
163 		// データ部を処理します。
164 		final List<T> results = new ArrayList<T>();
165 		final boolean order = ignoreScalar || orders != null && !orders.isEmpty();
166 		int offset = 0;
167 
168 		List<String> values;
169 		while ((values = r.readValues()) != null && (order || limit <= 0 || results.size() < limit)) {
170 			if (beanFilter == null && !order && offset < this.offset) {
171 				offset++;
172 				continue;
173 			}
174 			final T bean = r.toBean(values);
175 			if (beanFilter != null) {
176 				if (!beanFilter.accept(bean)) {
177 					continue;
178 				}
179 				if (!order && offset < this.offset) {
180 					offset++;
181 					continue;
182 				}
183 			}
184 			results.add(bean);
185 		}
186 
187 		if (ignoreScalar || !order) {
188 			return results;
189 		}
190 		return processScalar(results);
191 	}
192 
193 	@Override
194 	public void save(final List<T> list, final CsvWriter writer) throws IOException {
195 		@SuppressWarnings("resource")
196 		final CsvColumnPositionMappingBeanWriter<T> w = new CsvColumnPositionMappingBeanWriter<T>(writer, template, header);
197 
198 		// データ部を処理します。
199 		for (final T bean : list) {
200 			// 要素が null の場合は null 出力します。
201 			if (bean == null) {
202 				w.write(null);
203 				continue;
204 			} else if (beanFilter != null && !beanFilter.accept(bean)) {
205 				continue;
206 			}
207 
208 			w.write(bean);
209 		}
210 	}
211 
212 }