View Javadoc
1   /*
2    * Copyright 2012 Olivier Godineau
3    * 
4    * Licensed under the Apache License, Version 2.0 (the "License"); you may not
5    * use this file except in compliance with the License. You may obtain a copy of
6    * the License at http://www.apache.org/licenses/LICENSE-2.0
7    * 
8    * Unless required by applicable law or agreed to in writing, software
9    * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
10   * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
11   * License for the specific language governing permissions and limitations under
12   * the License.
13   */
14  package olg.csv.base;
15  import java.io.IOException;
16  import java.util.List;
17  import java.util.NoSuchElementException;
18  
19  /**
20   * Abstract class which embeds sheet reader characteristics.
21   * 
22   * @author Olivier Godineau
23   * 
24   * 
25   */
26  public abstract class AbstractSheetReader implements IReader {
27  	/**
28  	 * Indicate if emtpy cells are skipping.
29  	 */
30  	protected boolean skipEmptyCell = false;
31  	/**
32  	 * the sheet num. 0 is the first.
33  	 */
34  	protected int sheetNum;
35  	/**
36  	 * Record index. first is 1.
37  	 */
38  	protected int recordIndex = 1;
39  	/**
40  	 * Record size.
41  	 */
42  	protected int rowSize = 0;
43  
44  	/**
45  	 * Sheet name.
46  	 */
47  	protected String sheetName = null;
48  
49  	/**
50  	 * Indicate if an header row must be skipped.
51  	 */
52  	protected boolean withHeaders;
53  	/**
54  	 * First row to read.
55  	 */
56  	protected Integer beginAtRow = 1;
57  	/**
58  	 * last row to read.
59  	 */
60  	protected Integer endAtRow = null;
61  
62  	/**
63  	 * First cell to read in each row.
64  	 */
65  	protected Integer beginAtColumn = 0;
66  	/**
67  	 * Last cell to read in each row.
68  	 */
69  	protected Integer endAtColumn = null;
70  
71  	/**
72  	 * {@inheritDoc}
73  	 */
74  	public final boolean hasNext() {
75  		return getRows() >= recordIndex && (endAtRow == null ? true : endAtRow >= recordIndex);
76  	}
77  
78  	/**
79  	 * {@inheritDoc}
80  	 */
81  	public final Row next() {
82  		if (!hasNext()) {
83  			throw new NoSuchElementException();
84  		}
85  		return setNext();
86  
87  	}
88  
89  	/**
90  	 * Unsupported Operation. Throw UnsupportedOperationException
91  	 */
92  	public final void remove() {
93  		throw new UnsupportedOperationException();
94  
95  	}
96  
97  	/**
98  	 * {@inheritDoc}
99  	 */
100 	public boolean isWithHeaders() {
101 		return this.withHeaders;
102 	}
103 
104 	/**
105 	 * {@inheritDoc}
106 	 */
107 	public abstract void close();
108 
109 	/**
110 	 * Returns the next Row.
111 	 * 
112 	 * @return the next row.
113 	 */
114 	protected abstract Row setNext();
115 
116 	/**
117 	 * Method called by {@link #initSheet()} to allow concret SheetReader to do
118 	 * some stuff on its instanciation.
119 	 * 
120 	 * @throws IOException
121 	 *             if I/O error occurs.
122 	 */
123 	protected abstract void doOnInitSheet() throws IOException;
124 
125 	/**
126 	 * Complete cell lists in parameter with empty cells.
127 	 * 
128 	 * @param cells
129 	 *            list to complete
130 	 * @param columnBegin
131 	 *            index colum from which begins the padding (inclusive)
132 	 * @param columnEnd
133 	 *            index column to which ends the padding (exclusive).
134 	 * @return the completed list
135 	 */
136 	protected List<Cell> padding(List<Cell> cells, int columnBegin, int columnEnd) {
137 		if (!skipEmptyCell) {
138 			for (int j = columnBegin; j < columnEnd; j++) {
139 				cells.add(new Cell(j, null)); // NOPMD by olivier on 27/01/12
140 												// 00:32
141 			}
142 		}
143 		return cells;
144 	}
145 
146 	/**
147 	 * Returns the index of the current sheet this reader has opened.
148 	 * 
149 	 * @return the index.
150 	 */
151 	public int getSheetNum() {
152 		return sheetNum;
153 	}
154 	/**
155 	 * Returns sheet name corresponding to the sheet this reader has opened.
156 	 * 
157 	 * @return the sheet name
158 	 */
159 	public String getSheetName() {
160 		return sheetName;
161 	}
162 
163 	/**
164 	 * Get the row count of this sheet.
165 	 * 
166 	 * @return total count of rows
167 	 */
168 	protected abstract int getRows();
169 
170 	/**
171 	 * Method to call by concret constructor to initialize some stuff. By
172 	 * default, skip headers if specified, and define row size. If redefined by
173 	 * concret child class, initSheet must call parent initSheet to guaranty
174 	 * correct initialization
175 	 * 
176 	 * @throws IOException
177 	 *             if I/O error occurs during initialization.
178 	 * 
179 	 * @see #doOnInitSheet()
180 	 */
181 	protected void initSheet() throws IOException {
182 		doOnInitSheet();
183 		this.rowSize = defineRowSize();
184 
185 	}
186 
187 	/**
188 	 * Returns the expected rows length of each line.
189 	 * 
190 	 * @return the rows size.
191 	 */
192 	protected abstract int defineRowSize();
193 
194 	/**
195 	 * Check and set parameters.
196 	 * <p>
197 	 * Throws IllegalArgumentException if one of these parameters.
198 	 * </p>
199 	 * 
200 	 * @param beginAtRow
201 	 *            the row index from which begins the reading. lines number
202 	 *            begin at 1
203 	 * @param endAtRow
204 	 *            the last index to which ends the reading.
205 	 * @param beginAtColumn
206 	 *            the cell num from which begins the row reading. columns begin
207 	 *            at 0. Could be in sheet cell format or a number.
208 	 * @param endAtColumn
209 	 *            the cell num to which ends the row reading. Could be null.
210 	 */
211 	private void checkParameters(Integer beginAtRow, Integer endAtRow, String beginAtColumn, String endAtColumn) {
212 		if (beginAtRow != null) {
213 			this.beginAtRow = beginAtRow;
214 			if (this.beginAtRow < 1) {
215 				throw new IllegalArgumentException("SheetReader Constructor settings argument: beginAtRow parameter["
216 						+ beginAtRow
217 						+ "] must be a positive number  or null (in this case reading begins at the first row)");
218 
219 			}
220 		}
221 
222 		if (endAtRow != null) {
223 			this.endAtRow = endAtRow;
224 
225 			if (this.endAtRow < 1 || this.endAtRow <= this.beginAtRow) {
226 				throw new IllegalArgumentException("SheetReader Constructor settings argument endAtRow parameter["
227 						+ endAtRow + "] must be a positive number and be greater than " + this.beginAtRow
228 						+ " or null(in this case reading ends at the last row)");
229 			}
230 		}
231 
232 		if (beginAtColumn != null) {
233 			try {
234 				this.beginAtColumn = Cell.fromSheetCellNumber(beginAtColumn);
235 			} catch (IllegalArgumentException ex) {
236 				throw new IllegalArgumentException(
237 						"SheetReader Constructor settings argument: beginAtColumn parameter[" + beginAtColumn
238 								+ "] must be a positive number greater "
239 								+ "than 0 or an expression conformed to spreadsheet column Notation or "
240 								+ "null(in this case rows reading begins at the first column)", ex);
241 			}
242 
243 		}
244 
245 		if (endAtColumn != null) {
246 			try {
247 				this.endAtColumn = Cell.fromSheetCellNumber(endAtColumn);
248 			} catch (IllegalArgumentException ex) {
249 				throw new IllegalArgumentException("SheetReader Constructor settings argument: endAtColumn parameter["
250 						+ endAtColumn + "] must be a positive number greater than 0 or an expression conformed "
251 						+ "to spreadsheet column Notation "
252 						+ "or null (in this case rows reading ends at the last column", ex);
253 			}
254 
255 			if (this.endAtColumn <= this.beginAtColumn) {
256 				throw new IllegalArgumentException("SheetReader Constructor settings argument: endAtColumn parameter["
257 						+ endAtColumn + "] must be greater than " + (beginAtColumn == null ? "A" : beginAtColumn));
258 			}
259 		}
260 	}
261 
262 	/**
263 	 * 
264 	 * @param settings
265 	 *            the reader settings. Must not be <code>null</code>.
266 	 */
267 	public AbstractSheetReader(AbstractSheetSettings<? extends AbstractSheetSettings<?>> settings) {
268 		super();
269 		if (settings == null) {
270 			throw new IllegalArgumentException("SheetReader Constructor settings argument must not be null");
271 		}
272 		checkParameters(settings.getBeginAtRow(), settings.getEndAtRow(), settings.getBeginAtColumn(),
273 				settings.getEndAtColumn());
274 		this.withHeaders = settings.isWithHeaders();
275 		this.sheetNum = settings.getSheetNum();
276 		this.sheetName = settings.getSheetName();
277 
278 		this.recordIndex = this.beginAtRow;
279 
280 	}
281 
282 }