/*
* To change this template, choose Tools | Templates
* and open the template in the editor.
*/
package Readers;
import Core.Data;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.Reader;
import java.util.ArrayList;
import java.util.List;
import java.util.logging.Level;
import java.util.logging.Logger;
/**
*
* @author Amir
*/
public class CSVReader extends FileReader{
private BufferedReader br;
private boolean hasNext = true;
private char separator;
private char quotechar;
private int skipLines;
private boolean linesSkiped;
/** The default separator to use if none is supplied to the constructor. */
public static final char DEFAULT_SEPARATOR = ',';
/**
* The default quote character to use if none is supplied to the
* constructor.
*/
public static final char DEFAULT_QUOTE_CHARACTER = '"';
/**
* The default line to start reading.
*/
public static final int DEFAULT_SKIP_LINES = 0;
/**
* Constructs CSVReader using a comma for the separator.
*
* @param reader
* the reader to an underlying CSV source.
*/
public CSVReader(Reader reader) {
this(reader, DEFAULT_SEPARATOR);
}
/**
* Constructs CSVReader with supplied separator.
*
* @param reader
* the reader to an underlying CSV source.
* @param separator
* the delimiter to use for separating entries.
*/
public CSVReader(Reader reader, char separator) {
this(reader, separator, DEFAULT_QUOTE_CHARACTER);
}
/**
* Constructs CSVReader with supplied separator and quote char.
*
* @param reader
* the reader to an underlying CSV source.
* @param separator
* the delimiter to use for separating entries
* @param quotechar
* the character to use for quoted elements
*/
public CSVReader(Reader reader, char separator, char quotechar) {
this(reader, separator, quotechar, DEFAULT_SKIP_LINES);
}
/**
* Constructs CSVReader with supplied separator and quote char.
*
* @param reader
* the reader to an underlying CSV source.
* @param separator
* the delimiter to use for separating entries
* @param quotechar
* the character to use for quoted elements
* @param line
* the line number to skip for start reading
*/
public CSVReader(Reader reader, char separator, char quotechar, int line) {
this.br = new BufferedReader(reader);
this.separator = separator;
this.quotechar = quotechar;
this.skipLines = line;
}
/**
* Reads the entire file into a List with each element being a String[] of
* tokens.
*
* @return a List of String[], with each String[] representing a line of the
* file.
*
* @throws IOException
* if bad things happen during the read
*/
public List readAll() throws IOException {
List allElements = new ArrayList();
while (hasNext) {
String[] nextLineAsTokens = readNext();
if (nextLineAsTokens != null)
allElements.add(nextLineAsTokens);
}
return allElements;
}
/**
* Reads the next line from the buffer and converts to a string array.
*
* @return a string array with each comma-separated element as a separate
* entry.
*
* @throws IOException
* if bad things happen during the read
*/
public String[] readNext() throws IOException {
String nextLine = getNextLine();
return hasNext ? parseLine(nextLine) : null;
}
/**
* Reads the next line from the file.
*
* @return the next line from the file without trailing newline
* @throws IOException
* if bad things happen during the read
*/
private String getNextLine() throws IOException {
if (!this.linesSkiped) {
for (int i = 0; i < skipLines; i++) {
br.readLine();
}
this.linesSkiped = true;
}
String nextLine = br.readLine();
if (nextLine == null) {
hasNext = false;
}
return hasNext ? nextLine : null;
}
/**
* Parses an incoming String and returns an array of elements.
*
* @param nextLine
* the string to parse
* @return the comma-tokenized list of elements, or null if nextLine is null
* @throws IOException if bad things happen during the read
*/
private String[] parseLine(String nextLine) throws IOException {
if (nextLine == null) {
return null;
}
List tokensOnThisLine = new ArrayList();
StringBuffer sb = new StringBuffer();
boolean inQuotes = false;
do {
if (inQuotes) {
// continuing a quoted section, reappend newline
sb.append("\n");
nextLine = getNextLine();
if (nextLine == null)
break;
}
for (int i = 0; i < nextLine.length(); i++) {
char c = nextLine.charAt(i);
if (c == quotechar) {
// this gets complex... the quote may end a quoted block, or escape another quote.
// do a 1-char lookahead:
if( inQuotes // we are in quotes, therefore there can be escaped quotes in here.
&& nextLine.length() > (i+1) // there is indeed another character to check.
&& nextLine.charAt(i+1) == quotechar ){ // ..and that char. is a quote also.
// we have two quote chars in a row == one quote char, so consume them both and
// put one on the token. we do *not* exit the quoted text.
sb.append(nextLine.charAt(i+1));
i++;
}else{
inQuotes = !inQuotes;
// the tricky case of an embedded quote in the middle: a,bc"d"ef,g
if(i>2 //not on the begining of the line
&& nextLine.charAt(i-1) != this.separator //not at the begining of an escape sequence
&& nextLine.length()>(i+1) &&
nextLine.charAt(i+1) != this.separator //not at the end of an escape sequence
){
sb.append(c);
}
}
} else if (c == separator && !inQuotes) {
tokensOnThisLine.add(sb.toString());
sb = new StringBuffer(); // start work on next token
} else {
sb.append(c);
}
}
} while (inQuotes);
tokensOnThisLine.add(sb.toString());
return (String[]) tokensOnThisLine.toArray(new String[0]);
}
/**
* Closes the underlying reader.
*
* @throws IOException if the close fails
*/
public void close() throws IOException{
br.close();
}
@Override
public Data readData() {
Data toBeSent=null;
List fileLines = null;
String[] firstLine;
String[] pileNodeCoLine;
String[] ModOfSubReactionLine;
String[] lateralSoilMovementLine;
String[] limitSoilPressureLine;
String[] pileCoLine;
while(true){
try {
fileLines= readAll();
} catch (IOException ex) {
Logger.getLogger(CSVReader.class.getName()).log(Level.SEVERE, null, ex);
toBeSent = null;
break;
}
try{
firstLine = (String[]) fileLines.get(0);
pileNodeCoLine = (String[]) fileLines.get(1);
ModOfSubReactionLine = (String[])fileLines.get(2);
lateralSoilMovementLine = (String[]) fileLines.get(3);
limitSoilPressureLine = (String[]) fileLines.get(4);
pileCoLine = (String[])fileLines.get(5);
}catch(IndexOutOfBoundsException ex){
toBeSent = null;
break;
}
int numOfElements = Integer.parseInt(firstLine[0]);
double pileLength = Double.parseDouble(firstLine[1]);
double EI = Double.parseDouble(firstLine[2]);
double pileDiameter = Double.parseDouble(firstLine[3]);
int noOfPiles = Integer.parseInt(firstLine[4]);
double poissonRation = Double.parseDouble(firstLine[5]);
int iterationNo = Integer.parseInt(firstLine[6]);
toBeSent = new Data();
toBeSent.setNumOfElements(numOfElements);
toBeSent.setPileLength(pileLength);
toBeSent.setEI(EI);
toBeSent.setPileDiameter(pileDiameter);
toBeSent.setNumOfPiles(noOfPiles);
toBeSent.setPoissonRation(poissonRation);
toBeSent.setIterationNumber(iterationNo);
for(int elNo=0;elNo<=numOfElements;elNo++){
double tmpPileNodeCo = 0;
tmpPileNodeCo = Double.parseDouble(pileNodeCoLine[elNo]);
toBeSent.addPileNodeCoordinate(tmpPileNodeCo);
}
for(int elNo=0;elNo<=numOfElements;elNo++){
double tmpModOfSubReaction = 0;
tmpModOfSubReaction = Double.parseDouble(ModOfSubReactionLine[elNo]);
toBeSent.addModOfSubgradeReaction(tmpModOfSubReaction);
}
for(int elNo=0;elNo<=numOfElements;elNo++){
double tmpLateralSoilMovement = 0;
tmpLateralSoilMovement = Double.parseDouble(lateralSoilMovementLine[elNo]);
toBeSent.addLateralSoilMovement(tmpLateralSoilMovement);
}
for(int elNo=0;elNo<=numOfElements;elNo++){
double tmplimitSoilPressure = 0;
tmplimitSoilPressure = Double.parseDouble(limitSoilPressureLine[elNo]);
toBeSent.addLimitSoilPressure(tmplimitSoilPressure);
}
for(int elNo=0;elNo<=noOfPiles;elNo++){
double tmpPileCo = 0;
tmpPileCo = Double.parseDouble(pileCoLine[elNo]);
toBeSent.addPileNodeCoordinate(tmpPileCo);
}
break;
}
return toBeSent;
}
}