org.drools.decisiontable.parser.csv.CsvParser Maven / Gradle / Ivy
/*
* Copyright 2005 Red Hat, Inc. and/or its affiliates.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.drools.decisiontable.parser.csv;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.List;
import org.drools.core.util.IoUtils;
import org.drools.decisiontable.parser.DecisionTableParser;
import org.drools.template.parser.DataListener;
import org.drools.template.parser.DecisionTableParseException;
/**
* Csv implementation. This implementation removes empty "cells" at the end of
* each line. Different CSV tools may or may not put heaps of empty cells in.
*
* Csv format is almost identical to XLS, with the one limitation: Merged cells
* are not supported. To allow constraints to span across cells for the one
* column, this is achieved by using "..." at the end of a cell value. If a cell
* value ends with "..." then it will be taken as spanned from the previous
* cell.
*/
public class CsvParser implements DecisionTableParser {
private List _listeners;
private CsvLineParser _lineParser;
public CsvParser(final DataListener listener,
final CsvLineParser lineParser) {
_listeners = new ArrayList();
_listeners.add(listener);
this._lineParser = lineParser;
}
public CsvParser(final List listeners, final CsvLineParser lineParser) {
this._listeners = listeners;
this._lineParser = lineParser;
}
public void parseFile(final InputStream inStream) {
final BufferedReader reader = new BufferedReader(new InputStreamReader(inStream, IoUtils.UTF8_CHARSET));
try {
startSheet();
processRows(reader);
finishSheet();
} catch (final IOException e) {
throw new DecisionTableParseException(
"An error occurred reading the CSV data.", e);
}
}
public void parseFile(final File file) {
try {
parseFile( new FileInputStream( file ) );
} catch (FileNotFoundException e) {
throw new DecisionTableParseException(
"An error occurred reading the CSV data.", e);
}
}
private void startSheet() {
for ( DataListener listener : _listeners ) {
listener.startSheet("csv");
}
}
private void finishSheet() {
for ( DataListener listener : _listeners ) {
listener.finishSheet();
}
}
private void newRow(final int row, final int numCells) {
for ( DataListener listener : _listeners ) {
listener.newRow(row, numCells);
}
}
private void newCell(final int row, final int column, final String value,
final int mergedColStart) {
for ( DataListener listener : _listeners ) {
listener.newCell(row, column, value, mergedColStart);
}
}
private void processRows(final BufferedReader reader) throws IOException {
String line = reader.readLine();
int row = 0;
while (line != null) {
final List cells = this._lineParser.parse(line);
// remove the trailing empty "cells" which some tools smatter around
// trimCells(cells);
newRow(row, cells.size());
int startMergeCol = DataListener.NON_MERGED;
for (int col = 0; col < cells.size(); col++) {
String cell = (String) cells.get(col);
startMergeCol = calcStartMerge(startMergeCol, col, cell);
cell = calcCellText(startMergeCol, cell);
newCell(row, col, cell, startMergeCol);
}
row++;
line = reader.readLine();
}
}
String calcCellText(int startMergeCol, String cell) {
if (startMergeCol != DataListener.NON_MERGED) {
cell = cell.substring(0, cell.length() - 3);
}
return cell;
}
int calcStartMerge(int startMergeCol, int col, String cell) {
if (cell.endsWith("...") && startMergeCol == DataListener.NON_MERGED) {
startMergeCol = col;
} else if (!cell.endsWith("...")) {
startMergeCol = DataListener.NON_MERGED;
}
return startMergeCol;
}
}