001: package org.drools.decisiontable.parser.csv;
002:
003: /*
004: * Copyright 2005 JBoss Inc
005: *
006: * Licensed under the Apache License, Version 2.0 (the "License");
007: * you may not use this file except in compliance with the License.
008: * You may obtain a copy of the License at
009: *
010: * http://www.apache.org/licenses/LICENSE-2.0
011: *
012: * Unless required by applicable law or agreed to in writing, software
013: * distributed under the License is distributed on an "AS IS" BASIS,
014: * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
015: * See the License for the specific language governing permissions and
016: * limitations under the License.
017: */
018:
019: import java.io.BufferedReader;
020: import java.io.IOException;
021: import java.io.InputStream;
022: import java.io.InputStreamReader;
023: import java.util.ArrayList;
024: import java.util.Iterator;
025: import java.util.List;
026:
027: import org.drools.decisiontable.parser.DecisionTableParseException;
028: import org.drools.decisiontable.parser.DecisionTableParser;
029: import org.drools.decisiontable.parser.SheetListener;
030:
031: /**
032: * Csv implementation. This implementation removes empty "cells" at the end of
033: * each line. Different CSV tools may or may not put heaps of empty cells in.
034: *
035: * Csv format is almost identical to XLS, with the one limitation: Merged cells
036: * are not supported. To allow constraints to span across cells for the one
037: * column, this is achieved by using "..." at the end of a cell value. If a cell
038: * value ends with "..." then it will be taken as spanned from the previous
039: * cell.
040: *
041: *
042: *
043: * @author <a href="mailto:michael.neale@gmail.com"> Michael Neale</a>
044: */
045: public class CsvParser implements DecisionTableParser {
046:
047: private List _listeners;
048:
049: private CsvLineParser _lineParser;
050:
051: public CsvParser(final SheetListener listener,
052: final CsvLineParser lineParser) {
053: _listeners = new ArrayList();
054: _listeners.add(listener);
055: this ._lineParser = lineParser;
056: }
057:
058: public CsvParser(final List listeners,
059: final CsvLineParser lineParser) {
060: this ._listeners = listeners;
061: this ._lineParser = lineParser;
062: }
063:
064: public void parseFile(final InputStream inStream) {
065: final BufferedReader reader = new BufferedReader(
066: new InputStreamReader(inStream));
067: try {
068: startSheet();
069: processRows(reader);
070: finishSheet();
071: } catch (final IOException e) {
072: throw new DecisionTableParseException(
073: "An error occurred reading the CSV data.", e);
074: }
075: }
076:
077: private void startSheet() {
078: for (Iterator it = _listeners.iterator(); it.hasNext();) {
079: SheetListener listener = (SheetListener) it.next();
080: listener.startSheet("csv");
081: }
082: }
083:
084: private void finishSheet() {
085: for (Iterator it = _listeners.iterator(); it.hasNext();) {
086: SheetListener listener = (SheetListener) it.next();
087: listener.finishSheet();
088: }
089: }
090:
091: private void newRow(final int row, final int numCells) {
092: for (Iterator it = _listeners.iterator(); it.hasNext();) {
093: SheetListener listener = (SheetListener) it.next();
094: listener.newRow(row, numCells);
095: }
096: }
097:
098: private void newCell(final int row, final int column,
099: final String value, final int mergedColStart) {
100: for (Iterator it = _listeners.iterator(); it.hasNext();) {
101: SheetListener listener = (SheetListener) it.next();
102: listener.newCell(row, column, value, mergedColStart);
103: }
104: }
105:
106: private void processRows(final BufferedReader reader)
107: throws IOException {
108: String line = reader.readLine();
109:
110: int row = 0;
111: while (line != null) {
112:
113: final List cells = this ._lineParser.parse(line);
114: // remove the trailing empty "cells" which some tools smatter around
115: // trimCells(cells);
116: newRow(row, cells.size());
117:
118: int startMergeCol = SheetListener.NON_MERGED;
119: for (int col = 0; col < cells.size(); col++) {
120: String cell = (String) cells.get(col);
121:
122: startMergeCol = calcStartMerge(startMergeCol, col, cell);
123:
124: cell = calcCellText(startMergeCol, cell);
125:
126: newCell(row, col, cell, startMergeCol);
127: }
128: row++;
129: line = reader.readLine();
130: }
131: finishSheet();
132: }
133:
134: String calcCellText(int startMergeCol, String cell) {
135: if (startMergeCol != SheetListener.NON_MERGED) {
136: cell = cell.substring(0, cell.length() - 3);
137: }
138: return cell;
139: }
140:
141: int calcStartMerge(int startMergeCol, int col, String cell) {
142: if (cell.endsWith("...")
143: && startMergeCol == SheetListener.NON_MERGED) {
144: startMergeCol = col;
145: } else if (!cell.endsWith("...")) {
146: startMergeCol = SheetListener.NON_MERGED;
147: }
148: return startMergeCol;
149: }
150:
151: /** remove the trailing empty cells */
152: private void trimCells(final List cells) {
153: for (int i = cells.size() - 1; i > 0; i--) {
154: final String cell = (String) cells.get(i);
155: if (!cell.trim().equals("")) {
156: return;
157: } else {
158: cells.remove(i);
159: }
160: }
161:
162: }
163:
164: }
|