1 25 package org.ofbiz.datafile; 26 27 28 import java.io.BufferedReader ; 29 import java.io.IOException ; 30 import java.io.InputStream ; 31 import java.io.InputStreamReader ; 32 import java.net.URL ; 33 import java.util.Stack ; 34 35 36 43 44 public class RecordIterator { 45 46 public static final String module = RecordIterator.class.getName(); 47 48 protected BufferedReader br; 49 protected ModelDataFile modelDataFile; 50 protected InputStream dataFileStream; 51 protected boolean closed = false; 52 protected String locationInfo; 53 54 protected int nextLineNum = 0; 55 protected String curLine = null; 56 protected Record curRecord = null; 57 protected String nextLine = null; 58 protected Record nextRecord = null; 59 60 public RecordIterator(URL fileUrl, ModelDataFile modelDataFile) throws DataFileException { 61 this.modelDataFile = modelDataFile; 62 63 InputStream urlStream = null; 64 try { 65 urlStream = fileUrl.openStream(); 66 } catch (IOException e) { 67 throw new DataFileException("Error open URL: " + fileUrl.toString(), e); 68 } 69 this.setupStream(urlStream, fileUrl.toString()); 70 } 71 72 public RecordIterator(InputStream dataFileStream, ModelDataFile modelDataFile, String locationInfo) throws DataFileException { 73 this.modelDataFile = modelDataFile; 74 this.setupStream(dataFileStream, locationInfo); 75 } 76 77 protected void setupStream(InputStream dataFileStream, String locationInfo) throws DataFileException { 78 this.locationInfo = locationInfo; 79 this.dataFileStream = dataFileStream; 80 try { 81 this.br = new BufferedReader (new InputStreamReader (dataFileStream, "UTF-8")); 82 } catch(Exception e) { 83 throw new DataFileException("UTF-8 is not supported"); 84 } 85 86 this.getNextLine(); 88 } 89 90 protected boolean getNextLine() throws DataFileException { 91 this.nextLine = null; 92 this.nextRecord = null; 93 94 boolean isFixedRecord = ModelDataFile.SEP_FIXED_RECORD.equals(modelDataFile.separatorStyle); 95 boolean isFixedLength = ModelDataFile.SEP_FIXED_LENGTH.equals(modelDataFile.separatorStyle); 96 boolean isDelimited = ModelDataFile.SEP_DELIMITED.equals(modelDataFile.separatorStyle); 97 99 if (isFixedRecord) { 100 if (modelDataFile.recordLength <= 0) { 101 throw new DataFileException("Cannot read a fixed record length file if no record length is specified"); 102 } 103 104 try { 105 char[] charData = new char[modelDataFile.recordLength + 1]; 106 107 if (br.read(charData, 0, modelDataFile.recordLength) == -1) { 109 nextLine = null; 110 } else { 112 nextLine = new String (charData); 113 } 115 } catch (IOException e) { 116 throw new DataFileException("Error reading line #" + nextLineNum + " (index " + (nextLineNum - 1) * modelDataFile.recordLength + " length " + 117 modelDataFile.recordLength + ") from location: " + locationInfo, e); 118 } 119 } else { 120 try { 121 nextLine = br.readLine(); 122 } catch (IOException e) { 123 throw new DataFileException("Error reading line #" + nextLineNum + " from location: " + locationInfo, e); 124 } 125 } 126 127 if (nextLine != null) { 128 nextLineNum++; 129 ModelRecord modelRecord = findModelForLine(nextLine, nextLineNum, modelDataFile); 130 if (isDelimited) { 131 this.nextRecord = Record.createDelimitedRecord(nextLine, nextLineNum, modelRecord, modelDataFile.delimiter); 132 } else { 133 this.nextRecord = Record.createRecord(nextLine, nextLineNum, modelRecord); 134 } 135 return true; 136 } else { 137 this.close(); 138 return false; 139 } 140 } 141 142 public int getCurrentLineNumber() { 143 return this.nextLineNum - 1; 144 } 145 146 public boolean hasNext() { 147 return nextLine != null; 148 } 149 150 public Record next() throws DataFileException { 151 if (!hasNext()) { 152 return null; 153 } 154 155 if (ModelDataFile.SEP_DELIMITED.equals(modelDataFile.separatorStyle) || ModelDataFile.SEP_FIXED_RECORD.equals(modelDataFile.separatorStyle) || ModelDataFile.SEP_FIXED_LENGTH.equals(modelDataFile.separatorStyle)) { 156 boolean isFixedRecord = ModelDataFile.SEP_FIXED_RECORD.equals(modelDataFile.separatorStyle); 157 159 this.curLine = this.nextLine; 161 this.curRecord = this.nextRecord; 162 163 this.getNextLine(); 165 166 if (!isFixedRecord && modelDataFile.recordLength > 0 && curLine.length() != modelDataFile.recordLength) { 168 throw new DataFileException("Line number " + this.getCurrentLineNumber() + " was not the expected length; expected: " + modelDataFile.recordLength + ", got: " + curLine.length()); 169 } 170 171 if (this.curRecord.getModelRecord().childRecords.size() > 0) { 173 Stack parentStack = new Stack (); 174 parentStack.push(curRecord); 175 176 while (this.nextRecord != null && this.nextRecord.getModelRecord().parentRecord != null) { 177 Record parentRecord = null; 179 180 while (parentStack.size() > 0) { 181 parentRecord = (Record) parentStack.peek(); 182 if (parentRecord.recordName.equals(this.nextRecord.getModelRecord().parentName)) { 183 break; 184 } else { 185 parentStack.pop(); 186 parentRecord = null; 187 } 188 } 189 190 if (parentRecord == null) { 191 throw new DataFileException("Expected Parent Record not found for line " + this.getCurrentLineNumber() + "; record name of expected parent is " + this.nextRecord.getModelRecord().parentName); 192 } 193 194 parentRecord.addChildRecord(this.nextRecord); 195 196 if (this.nextRecord.getModelRecord().childRecords.size() > 0) { 198 parentStack.push(this.nextRecord); 199 } 200 201 this.getNextLine(); 203 } 204 } 205 } else { 206 throw new DataFileException("Separator style " + modelDataFile.separatorStyle + " not recognized."); 207 } 208 209 return curRecord; 210 } 211 212 public void close() throws DataFileException { 213 if (this.closed) { 214 return; 215 } 216 try { 217 this.br.close(); this.closed = true; 219 } catch (IOException e) { 220 throw new DataFileException("Error closing data file input stream", e); 221 } 222 } 223 224 225 232 protected static ModelRecord findModelForLine(String line, int lineNum, ModelDataFile modelDataFile) throws DataFileException { 233 ModelRecord modelRecord = null; 235 236 for (int i = 0; i < modelDataFile.records.size(); i++) { 237 ModelRecord curModelRecord = (ModelRecord) modelDataFile.records.get(i); 238 239 if (curModelRecord.tcPosition < 0) { 240 modelRecord = curModelRecord; 241 break; 242 } 243 244 String typeCode = line.substring(curModelRecord.tcPosition, curModelRecord.tcPosition + curModelRecord.tcLength); 245 246 if (curModelRecord.typeCode.length() > 0) { 248 if (typeCode != null && typeCode.equals(curModelRecord.typeCode)) { 250 modelRecord = curModelRecord; 251 break; 252 } 253 } else if (curModelRecord.tcMin.length() > 0 || curModelRecord.tcMax.length() > 0) { 255 if (curModelRecord.tcIsNum) { 256 long typeCodeNum = Long.parseLong(typeCode); 258 259 if ((curModelRecord.tcMinNum < 0 || typeCodeNum >= curModelRecord.tcMinNum) && 260 (curModelRecord.tcMaxNum < 0 || typeCodeNum <= curModelRecord.tcMaxNum)) { 261 modelRecord = curModelRecord; 262 break; 263 } 264 } else { 265 if ((typeCode.compareTo(curModelRecord.tcMin) >= 0) && 267 (typeCode.compareTo(curModelRecord.tcMax) <= 0)) { 268 modelRecord = curModelRecord; 269 break; 270 } 271 } 272 } 273 } 274 275 if (modelRecord == null) { 276 throw new DataFileException("Could not find record definition for line " + lineNum + "; first bytes: " + 277 line.substring(0, (line.length() > 5) ? 5 : line.length())); 278 } 279 return modelRecord; 281 } 282 } 283 284 | Popular Tags |