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.io;
18  
19  import java.io.Closeable;
20  import java.io.IOException;
21  import java.util.List;
22  import java.util.SortedMap;
23  import java.util.TreeMap;
24  
25  import com.orangesignal.csv.CsvReader;
26  import com.orangesignal.csv.filters.CsvValueFilter;
27  
28  /**
29   * 項目位置と項目値のマップで区切り文字形式データアクセスを行う区切り文字形式入力ストリームを提供します。
30   * 
31   * @author Koji Sugisawa
32   * @since 1.4.0
33   */
34  public class CsvColumnPositionMapReader implements Closeable {
35  
36  	/**
37  	 * 区切り文字形式入力ストリームを保持します。
38  	 */
39  	private CsvReader reader;
40  
41  	/**
42  	 * 区切り文字形式データフィルタを保持します。
43  	 */
44  	private CsvValueFilter filter;
45  
46  	// ------------------------------------------------------------------------
47  	// コンストラクタ
48  
49  	/**
50  	 * 指定された区切り文字形式入力ストリームを使用して、このクラスを構築するコンストラクタです。
51  	 * 
52  	 * @param reader 区切り文字形式入力ストリーム
53  	 * @throws IllegalArgumentException {@code reader} が {@code null} の場合。
54  	 */
55  	public CsvColumnPositionMapReader(final CsvReader reader) {
56  		if (reader == null) {
57  			throw new IllegalArgumentException("CsvReader must not be null");
58  		}
59  		this.reader = reader;
60  	}
61  
62  	// ------------------------------------------------------------------------
63  	// プライベート メソッド
64  
65  	/**
66  	 * Checks to make sure that the stream has not been closed
67  	 */
68  	private void ensureOpen() throws IOException {
69  		if (reader == null) {
70  			throw new IOException("CsvReader closed");
71  		}
72  	}
73  
74  	// ------------------------------------------------------------------------
75  	// オーバーライド メソッド
76  
77  	@Override
78  	public void close() throws IOException {
79  		synchronized (this) {
80  			ensureOpen();
81  			reader.close();
82  			reader = null;
83  		}
84  	}
85  
86  	// ------------------------------------------------------------------------
87  	// パブリック メソッド
88  
89  	/**
90  	 * 論理行を読込み項目名と項目値のマップとして返します。
91  	 *
92  	 * @return 項目名と項目値のマップ。ストリームの終わりに達した場合は {@code null}
93  	 * @throws IOException 入出力エラーが発生した場合
94  	 */
95  	public SortedMap<Integer, String> read() throws IOException {
96  		synchronized (this) {
97  			ensureOpen();
98  
99  			final List<String> values = nextValues();
100 			if (values == null) {
101 				return null;
102 			}
103 			return convert(values);
104 		}
105 	}
106 
107 	/**
108 	 * 論理行を読込み CSV トークンの値をリストとして返します。
109 	 * 
110 	 * @return CSV トークンの値をリスト。ストリームの終わりに達している場合は {@code null}
111 	 * @throws IOException 入出力エラーが発生した場合
112 	 */
113 	public List<String> readValues() throws IOException {
114 		synchronized (this) {
115 			ensureOpen();
116 			return nextValues();
117 		}
118 	}
119 
120 	/**
121 	 * 指定された CSV トークンの値をリストを項目名と項目値のマップへ変換して返します。
122 	 * 
123 	 * @param values CSV トークンの値をリスト
124 	 * @return 変換された項目名と項目値のマップ
125 	 * @throws IOException 入出力エラーが発生した場合
126 	 */
127 	public SortedMap<Integer, String> toMap(final List<String> values) throws IOException {
128 		synchronized (this) {
129 			ensureOpen();
130 			return convert(values);
131 		}
132 	}
133 
134 	private List<String> nextValues() throws IOException {
135 		List<String> values;
136 		while ((values = reader.readValues()) != null) {
137 			if (filter != null && !filter.accept(values)) {
138 				continue;
139 			}
140 			return values;
141 		}
142 		return null;
143 	}
144 
145 	private SortedMap<Integer, String> convert(final List<String> values) {
146 		final SortedMap<Integer, String> map = new TreeMap<Integer, String>();
147 		final int len = values.size();
148 		for (int pos = 0; pos < len; pos++) {
149 			map.put(pos, values.get(pos));
150 		}
151 		return map;
152 	}
153 
154 	// ------------------------------------------------------------------------
155 	// セッター / ゲッター
156 
157 	/**
158 	 * 区切り文字形式データフィルタを返します。
159 	 * 
160 	 * @return 区切り文字形式データフィルタ。または {@code null}
161 	 */
162 	public CsvValueFilter getFilter() {
163 		return filter;
164 	}
165 
166 	/**
167 	 * 区切り文字形式データフィルタを設定します。
168 	 * 
169 	 * @param filter 区切り文字形式データフィルタ
170 	 */
171 	public void setFilter(final CsvValueFilter filter) {
172 		synchronized (this) {
173 			this.filter = filter;
174 		}
175 	}
176 
177 }