1 21 22 package org.dbunit.dataset.csv; 23 24 import org.dbunit.dataset.csv.handlers.*; 25 26 import java.io.*; 27 import java.text.CharacterIterator ; 28 import java.text.StringCharacterIterator ; 29 import java.util.ArrayList ; 30 import java.util.List ; 31 32 public class CsvParserImpl implements CsvParser { 33 34 private Pipeline pipeline; 35 36 public CsvParserImpl() { 37 resetThePipeline(); 38 } 39 40 private void resetThePipeline() { 41 pipeline = new Pipeline(); 42 getPipeline().putFront(SeparatorHandler.ENDPIECE()); 43 getPipeline().putFront(EscapeHandler.ACCEPT()); 44 getPipeline().putFront(IsAlnumHandler.QUOTE()); 45 getPipeline().putFront(QuoteHandler.QUOTE()); 46 getPipeline().putFront(EscapeHandler.ESCAPE()); 47 getPipeline().putFront(WhitespacesHandler.IGNORE()); 48 getPipeline().putFront(TransparentHandler.IGNORE()); 49 } 50 51 public List parse(String csv) throws PipelineException, IllegalInputCharacterException { 52 53 getPipeline().resetProducts(); 54 CharacterIterator iterator = new StringCharacterIterator (csv); 55 for (char c = iterator.first(); c != CharacterIterator.DONE; c = iterator.next()) { 56 getPipeline().handle(c); 57 } 58 getPipeline().noMoreInput(); 59 getPipeline().thePieceIsDone(); 60 return getPipeline().getProducts(); 61 } 62 63 public List parse(File file) throws IOException, CsvParserException { 64 65 BufferedReader reader = new BufferedReader(new InputStreamReader(new FileInputStream(file))); 66 LineNumberReader lineNumberReader = new LineNumberReader(reader); 67 List rows = new ArrayList (); 68 69 List columnsInFirstLine = parseFirstLine(lineNumberReader, file, rows); 70 parseTheData(columnsInFirstLine, lineNumberReader, rows); 71 return rows; 72 } 73 74 private List parseFirstLine(LineNumberReader lineNumberReader, File file, List rows) throws IOException, CsvParserException { 75 String firstLine = lineNumberReader.readLine(); 76 if (firstLine == null) 77 throw new CsvParserException("The null first line in file " + file.getAbsolutePath()); 78 79 final List columnsInFirstLine = parse(firstLine); 80 rows.add(columnsInFirstLine); 81 return columnsInFirstLine; 82 } 83 84 private void parseTheData(final List columnsInFirstLine, LineNumberReader lineNumberReader, List rows) throws IOException, CsvParserException { 85 int nColumns = columnsInFirstLine.size(); 86 List columns; 87 while ((columns = collectExpectedNumberOfColumns(nColumns, lineNumberReader)) != null) { 88 rows.add(columns); 89 } 90 } 91 92 private List collectExpectedNumberOfColumns(int expectedNumberOfColumns, LineNumberReader lineNumberReader) throws IOException, CsvParserException { 93 94 List columns = null; 95 int columnsCollectedSoFar = 0; 96 StringBuffer buffer = new StringBuffer (); 97 String anotherLine = lineNumberReader.readLine(); 98 if(anotherLine == null) 99 return null; 100 boolean shouldProceed = false; 101 while (columnsCollectedSoFar < expectedNumberOfColumns) { 102 try { 103 buffer.append(anotherLine); 104 columns = parse(buffer.toString()); 105 columnsCollectedSoFar = columns.size(); 106 } catch (IllegalStateException e) { 107 resetThePipeline(); 108 anotherLine = lineNumberReader.readLine(); 109 if(anotherLine == null) 110 break; 111 buffer.append("\n"); 112 shouldProceed = true; 113 } 114 if (!shouldProceed) 115 break; 116 } 117 if (columnsCollectedSoFar != expectedNumberOfColumns) { 118 String message = new StringBuffer ("Expected ").append(expectedNumberOfColumns) 119 .append(" columns on line ").append(lineNumberReader.getLineNumber()) 120 .append(", got ").append(columnsCollectedSoFar).append(". Offending line: ").append(buffer).toString(); 121 throw new CsvParserException(message); 122 } 123 return columns; 124 } 125 126 Pipeline getPipeline() { 127 return pipeline; 128 } 129 130 void setPipeline(Pipeline pipeline) { 131 this.pipeline = pipeline; 132 } 133 } 134 | Popular Tags |