1 25 package org.ofbiz.datafile; 26 27 import java.io.Serializable ; 28 import java.text.NumberFormat ; 29 import java.text.ParseException ; 30 import java.text.SimpleDateFormat ; 31 import java.util.ArrayList ; 32 import java.util.Date ; 33 import java.util.HashMap ; 34 import java.util.List ; 35 import java.util.Map ; 36 import java.util.StringTokenizer ; 37 import java.util.NoSuchElementException ; 38 39 46 public class Record implements Serializable { 47 48 49 protected Map fields; 50 51 52 protected String recordName; 53 54 55 protected transient ModelRecord modelRecord; 56 57 protected Record parentRecord = null; 58 protected List childRecords = new ArrayList (); 59 60 61 protected Record(ModelRecord modelRecord) { 62 if (modelRecord == null) 63 throw new IllegalArgumentException ("Cannont create a Record with a null modelRecord parameter"); 64 this.recordName = modelRecord.name; 65 this.modelRecord = modelRecord; 66 this.fields = new HashMap (); 67 } 68 69 70 protected Record(ModelRecord modelRecord, Map fields) { 71 if (modelRecord == null) 72 throw new IllegalArgumentException ("Cannont create a Record with a null modelRecord parameter"); 73 this.recordName = modelRecord.name; 74 this.modelRecord = modelRecord; 75 this.fields = (fields == null ? new HashMap () : new HashMap (fields)); 76 } 77 78 public String getRecordName() { 79 return recordName; 80 } 81 82 public ModelRecord getModelRecord() { 83 if (modelRecord == null) { 84 throw new IllegalStateException ("[Record.getModelRecord] could not find modelRecord for recordName " + recordName); 85 } 86 return modelRecord; 87 } 88 89 public Object get(String name) { 90 if (getModelRecord().getModelField(name) == null) { 91 throw new IllegalArgumentException ("[Record.get] \"" + name + "\" is not a field of " + recordName); 92 } 94 return fields.get(name); 95 } 96 97 public String getString(String name) { 98 Object object = get(name); 99 100 if (object == null) 101 return null; 102 if (object instanceof java.lang.String ) 103 return (String ) object; 104 else 105 return object.toString(); 106 } 107 108 public java.sql.Timestamp getTimestamp(String name) { 109 return (java.sql.Timestamp ) get(name); 110 } 111 112 public java.sql.Time getTime(String name) { 113 return (java.sql.Time ) get(name); 114 } 115 116 public java.sql.Date getDate(String name) { 117 return (java.sql.Date ) get(name); 118 } 119 120 public Integer getInteger(String name) { 121 return (Integer ) get(name); 122 } 123 124 public Long getLong(String name) { 125 return (Long ) get(name); 126 } 127 128 public Float getFloat(String name) { 129 return (Float ) get(name); 130 } 131 132 public Double getDouble(String name) { 133 return (Double ) get(name); 134 } 135 136 140 public void set(String name, Object value) { 141 set(name, value, true); 142 } 143 144 150 public synchronized void set(String name, Object value, boolean setIfNull) { 151 if (getModelRecord().getModelField(name) == null) { 152 throw new IllegalArgumentException ("[Record.set] \"" + name + "\" is not a field of " + recordName); 153 } 155 if (value != null || setIfNull) { 156 if (value instanceof Boolean ) { 157 value = ((Boolean ) value).booleanValue() ? "Y" : "N"; 158 } 159 fields.put(name, value); 160 } 161 } 162 163 166 public final short readLEShort(byte[] byteArray) { 167 return (short)( 168 (byteArray[1]&0xff) << 8 | 169 (byteArray[0]&0xff)); 170 171 } 172 173 176 public final int readLEInt(byte []byteArray) { 177 return 178 (byteArray[3]) << 24 | 179 (byteArray[2]&0xff) << 16 | 180 (byteArray[1]&0xff) << 8 | 181 (byteArray[0]&0xff); 182 } 183 184 187 public final long readLELong(byte []byteArray) { 188 return 189 (long)(byteArray[7]) << 56 | 190 (long)(byteArray[6]&0xff) << 48 | 191 (long)(byteArray[5]&0xff) << 40 | 192 (long)(byteArray[4]&0xff) << 32 | 193 (long)(byteArray[3]&0xff) << 24 | 194 (long)(byteArray[2]&0xff) << 16 | 195 (long)(byteArray[1]&0xff) << 8 | 196 (long)(byteArray[0]&0xff); 197 } 198 199 203 public void setString(String name, String value) throws ParseException { 204 if (name == null || value == null || value.equals("")) 205 return; 206 ModelField field = getModelRecord().getModelField(name); 207 208 if (field == null) 209 set(name, value); 211 boolean nonSpace = false; 213 214 for (int i = 0; i < value.length(); i++) { 215 if (value.charAt(i) != ' ') { 216 nonSpace = true; 217 break; 218 } 219 } 220 if (!nonSpace) 221 return; 222 223 225 String fieldType = field.type; 226 227 if (fieldType.equals("CustomTimestamp")) { 229 SimpleDateFormat sdf = new SimpleDateFormat (field.format); 233 java.util.Date tempDate = sdf.parse(value); 234 java.sql.Timestamp timestamp = new java.sql.Timestamp (tempDate.getTime()); 235 236 set(name, timestamp); 237 } else if (fieldType.equals("CustomDate")) { 238 SimpleDateFormat sdf = new SimpleDateFormat (field.format); 240 java.util.Date tempDate = sdf.parse(value); 241 java.sql.Date date = new java.sql.Date (tempDate.getTime()); 242 243 set(name, date); 244 } else if (fieldType.equals("CustomTime")) { 245 SimpleDateFormat sdf = new SimpleDateFormat (field.format); 247 java.util.Date tempDate = sdf.parse(value); 248 java.sql.Time time = new java.sql.Time (tempDate.getTime()); 249 250 set(name, time); 251 } else if (fieldType.equals("FixedPointDouble")) { 252 NumberFormat nf = NumberFormat.getNumberInstance(); 255 Number tempNum = nf.parse(value); 256 double number = tempNum.doubleValue(); 257 double decimalPlaces = Double.parseDouble(field.format); 258 double divisor = Math.pow(10.0, decimalPlaces); 259 260 number = number / divisor; 261 set(name, new Double (number)); 262 } else if (fieldType.equals("java.lang.String") || fieldType.equals("String")) 264 set(name, value); 265 else if (fieldType.equals("NullTerminatedString")) { 266 int terminate = value.indexOf(0x0); 267 set(name, terminate>0?value.substring(0,terminate):value); 268 } else if (fieldType.equals("java.sql.Timestamp") || fieldType.equals("Timestamp")) 269 set(name, java.sql.Timestamp.valueOf(value)); 270 else if (fieldType.equals("java.sql.Time") || fieldType.equals("Time")) 271 set(name, java.sql.Time.valueOf(value)); 272 else if (fieldType.equals("java.sql.Date") || fieldType.equals("Date")) 273 set(name, java.sql.Date.valueOf(value)); 274 else if (fieldType.equals("java.lang.Integer") || fieldType.equals("Integer")) 275 set(name, Integer.valueOf(value)); 276 else if (fieldType.equals("java.lang.Long") || fieldType.equals("Long")) 277 set(name, Long.valueOf(value)); 278 else if (fieldType.equals("java.lang.Float") || fieldType.equals("Float")) 279 set(name, Float.valueOf(value)); 280 else if (fieldType.equals("java.lang.Double") || fieldType.equals("Double")) 281 set(name, Double.valueOf(value)); 282 else if (fieldType.equals("LEShort")) 283 set(name, new Short (readLEShort(value.getBytes()))); 284 else if (fieldType.equals("LEInteger")) 285 set(name, new Integer (readLEInt(value.getBytes()))); 286 else if (fieldType.equals("LELong")) 287 set(name, new Long (readLELong(value.getBytes()))); 288 else { 289 throw new IllegalArgumentException ("Field type " + fieldType + " not currently supported. Sorry."); 290 } 291 } 292 293 public String getFixedString(String name) { 294 if (name == null) 295 return null; 296 if (getModelRecord() == null) 297 throw new IllegalArgumentException ("Could not find modelrecord for field named \"" + name + "\""); 298 ModelField field = getModelRecord().getModelField(name); 299 300 if (field == null) 301 throw new IllegalArgumentException ("Could not find model for field named \"" + name + "\""); 302 303 Object value = get(name); 304 305 if (value == null) { 306 return null; 307 } 308 309 String fieldType = field.type; 310 String str = null; 311 312 if (fieldType.equals("CustomTimestamp")) { 314 SimpleDateFormat sdf = new SimpleDateFormat (field.format); 316 java.sql.Timestamp timestamp = (java.sql.Timestamp ) value; 317 318 str = sdf.format(new Date (timestamp.getTime())); 319 } else if (fieldType.equals("CustomDate")) { 320 SimpleDateFormat sdf = new SimpleDateFormat (field.format); 322 java.sql.Date date = (java.sql.Date ) value; 323 324 str = sdf.format(new Date (date.getTime())); 325 } else if (fieldType.equals("CustomTime")) { 326 SimpleDateFormat sdf = new SimpleDateFormat (field.format); 328 java.sql.Time time = (java.sql.Time ) value; 329 330 str = sdf.format(new Date (time.getTime())); 331 } else if (fieldType.equals("FixedPointDouble")) { 332 NumberFormat nf = NumberFormat.getNumberInstance(); 335 double decimalPlaces = Double.parseDouble(field.format); 336 double multiplier = Math.pow(10.0, decimalPlaces); 337 double dnum = multiplier * ((Double ) value).doubleValue(); 338 long number = Math.round(dnum); 339 340 str = padFrontZeros(Long.toString(number), field.length); 341 } else if (fieldType.equals("java.lang.String") || fieldType.equals("String")) 344 str = value.toString(); 345 else if (fieldType.equals("java.sql.Timestamp") || fieldType.equals("Timestamp")) 346 str = value.toString(); 347 else if (fieldType.equals("java.sql.Time") || fieldType.equals("Time")) 348 str = value.toString(); 349 else if (fieldType.equals("java.sql.Date") || fieldType.equals("Date")) 350 str = value.toString(); 351 else if (fieldType.equals("java.lang.Integer") || fieldType.equals("Integer")) 353 str = padFrontZeros(value.toString(), field.length); 354 else if (fieldType.equals("java.lang.Long") || fieldType.equals("Long")) 355 str = padFrontZeros(value.toString(), field.length); 356 else if (fieldType.equals("java.lang.Float") || fieldType.equals("Float")) 357 str = padFrontZeros(value.toString(), field.length); 358 else if (fieldType.equals("java.lang.Double") || fieldType.equals("Double")) 359 str = padFrontZeros(value.toString(), field.length); 360 else { 361 throw new IllegalArgumentException ("Field type " + fieldType + " not currently supported. Sorry."); 362 } 363 364 if (str != null && field.length > 0 && str.length() < field.length) { 365 StringBuffer strBuf = new StringBuffer (str); 367 368 while (strBuf.length() < field.length) 369 strBuf.append(' '); 370 str = strBuf.toString(); 371 } 372 return str; 373 } 374 375 public String writeLineString(ModelDataFile modelDataFile) throws DataFileException { 376 ModelRecord modelRecord = getModelRecord(); 377 boolean isFixedRecord = ModelDataFile.SEP_FIXED_RECORD.equals(modelDataFile.separatorStyle); 378 boolean isFixedLength = ModelDataFile.SEP_FIXED_LENGTH.equals(modelDataFile.separatorStyle); 379 boolean isDelimited = ModelDataFile.SEP_DELIMITED.equals(modelDataFile.separatorStyle); 380 381 StringBuffer lineBuf = new StringBuffer (); 382 383 for (int f = 0; f < modelRecord.fields.size(); f++) { 384 ModelField modelField = (ModelField) modelRecord.fields.get(f); 385 String data = this.getFixedString(modelField.name); 386 387 char PAD_CHAR = ' '; 389 390 if (data == null) { 391 StringBuffer sb = new StringBuffer (""); 392 393 for (int i = 0; i < modelField.length; i++) 394 sb.append(PAD_CHAR); 395 data = new String (sb); 396 } 397 398 if (isFixedRecord) { 400 while (modelField.position > lineBuf.length()) 401 lineBuf.append(" "); 402 } 403 405 if (modelField.length > 0 && data.length() != modelField.length) 407 throw new DataFileException("Got field length " + data.length() + " but expected field length is " + modelField.length + " for field \"" + 408 modelField.name + "\" of record \"" + modelRecord.name + "\" data is: \"" + data + "\""); 409 410 lineBuf.append(data); 411 if (isDelimited) 412 lineBuf.append(modelDataFile.delimiter); 413 } 414 if ((isFixedRecord || isFixedLength) && modelDataFile.recordLength > 0 && lineBuf.length() != modelDataFile.recordLength) 415 throw new DataFileException("Got record length " + lineBuf.length() + " but expected record length is " + modelDataFile.recordLength + 416 " for record \"" + modelRecord.name + "\" data line is: \"" + lineBuf + "\""); 417 418 if (modelRecord.tcPosition > 0 && modelRecord.typeCode.length() > 0) { 420 lineBuf.replace(modelRecord.tcPosition, modelRecord.tcPosition + modelRecord.tcLength, modelRecord.typeCode); 421 } 422 423 if (isFixedLength || isDelimited) 424 lineBuf.append('\n'); 425 426 return lineBuf.toString(); 427 } 428 429 String padFrontZeros(String str, int totalLength) { 430 if (totalLength > 0 && str.length() < totalLength) { 431 StringBuffer zeros = new StringBuffer (); 433 int numZeros = totalLength - str.length(); 434 435 for (int i = 0; i < numZeros; i++) 436 zeros.append('0'); 437 zeros.append(str); 438 return zeros.toString(); 439 } else 440 return str; 441 } 442 443 public Record getParentRecord() { 444 return parentRecord; 445 } 446 447 public List getChildRecords() { 448 return childRecords; 449 } 450 451 public void addChildRecord(Record record) { 452 childRecords.add(record); 453 } 454 455 460 public static Record createRecord(ModelRecord modelRecord) throws DataFileException { 461 Record record = new Record(modelRecord); 462 463 return record; 464 } 465 466 472 public static Record createRecord(ModelRecord modelRecord, Map fields) throws DataFileException { 473 Record record = new Record(modelRecord, fields); 474 475 return record; 476 } 477 478 485 public static Record createRecord(String line, int lineNum, ModelRecord modelRecord) throws DataFileException { 486 Record record = new Record(modelRecord); 487 488 for (int i = 0; i < modelRecord.fields.size(); i++) { 489 ModelField modelField = (ModelField) modelRecord.fields.get(i); 490 String strVal = null; 491 492 493 try { 494 strVal = line.substring(modelField.position, modelField.position + modelField.length); 495 } catch (IndexOutOfBoundsException ioobe) { 496 throw new DataFileException("Field " + modelField.name + " from " + modelField.position + 497 " for " + modelField.length + " chars could not be read from a line (" + lineNum + ") with only " + 498 line.length() + " chars.", ioobe); 499 } 500 try { 501 record.setString(modelField.name, strVal); 502 } catch (java.text.ParseException e) { 503 throw new DataFileException("Could not parse field " + modelField.name + ", format string \"" + modelField.format + "\" with value " + strVal + 504 " on line " + lineNum, e); 505 } catch (java.lang.NumberFormatException e) { 506 throw new DataFileException("Number not valid for field " + modelField.name + ", format string \"" + modelField.format + "\" with value " + 507 strVal + " on line " + lineNum, e); 508 } 509 } 510 return record; 511 } 512 513 521 public static Record createDelimitedRecord(String line, int lineNum, ModelRecord modelRecord, char delimiter) throws DataFileException { 522 Record record = new Record(modelRecord); 523 524 StringTokenizer st = new StringTokenizer (line, "" + delimiter, true); 525 for (int i = 0; i < modelRecord.fields.size(); i++) { 526 ModelField modelField = (ModelField) modelRecord.fields.get(i); 527 String strVal = null; 528 529 if (modelField.expression) { 530 if (modelField.refField != null && modelField.refField.length() > 0) { 531 strVal = record.getString(modelField.refField); 532 } 533 if (strVal == null) { 534 strVal = (String )modelField.defaultValue; 535 } 536 } else { 537 try { 538 strVal = st.nextToken(); 539 if (strVal.equals("" + delimiter)) { 540 strVal = null; 541 } else { 542 if (st.hasMoreTokens()) { 543 st.nextToken(); 544 } 545 } 546 } catch (NoSuchElementException nsee) { 547 throw new DataFileException("Field " + modelField.name + " could not be read from a line (" + lineNum + ") with only " + 548 line.length() + " chars.", nsee); 549 } 550 } 551 try { 552 record.setString(modelField.name, strVal); 553 } catch (java.text.ParseException e) { 554 throw new DataFileException("Could not parse field " + modelField.name + ", format string \"" + modelField.format + "\" with value " + strVal + 555 " on line " + lineNum, e); 556 } catch (java.lang.NumberFormatException e) { 557 throw new DataFileException("Number not valid for field " + modelField.name + ", format string \"" + modelField.format + "\" with value " + 558 strVal + " on line " + lineNum, e); 559 } 560 } 561 return record; 562 } 563 564 } 565 566 | Popular Tags |