001/*------------------------------------------------------------------------------ 002 * PACKAGE: com.freeware.IniFiles 003 * FILE : IniFile.java 004 * CREATED: Jun 30, 2004 005 * AUTHOR : Prasad P. Khandekar 006 *------------------------------------------------------------------------------ 007 * Change Log: 008 * 05/07/2004 - Added support for date time formats. 009 * Added support for environment variables. 010 * 07/07/2004 - Added support for data type specific getters and setters. 011 * Updated main method to reflect above changes. 012 * 26/08/2004 - Added support for section level and property level comments. 013 * Introduction of seperate class for property values. 014 * Added addSection method. 015 * Sections and properties now retail their order (LinkedHashMap) 016 * Method implementation changes. 017 *-----------------------------------------------------------------------------*/ 018package org.hl7.fhir.utilities; 019 020import java.io.BufferedReader; 021import java.io.File; 022import java.io.FileNotFoundException; 023import java.io.FileReader; 024import java.io.FileWriter; 025import java.io.IOException; 026import java.io.InputStream; 027import java.io.InputStreamReader; 028import java.io.OutputStream; 029import java.io.OutputStreamWriter; 030import java.io.Reader; 031import java.io.Writer; 032import java.sql.Timestamp; 033import java.text.DateFormat; 034import java.text.ParseException; 035import java.text.SimpleDateFormat; 036import java.util.Collections; 037import java.util.Date; 038import java.util.Iterator; 039import java.util.LinkedHashMap; 040import java.util.Map; 041import java.util.NoSuchElementException; 042import java.util.Properties; 043import java.util.Set; 044 045 046/** 047 * IniFile class provides methods for manipulating (Read/Write) windows ini files. 048 * 049 * @author Prasad P. Khandekar 050 * @version 1.0 051 * @since 1.0 052 */ 053public final class IniFile 054{ 055 /** Variable to represent the date format */ 056 private String mstrDateFmt = "yyyy-MM-dd"; 057 058 /** Variable to represent the timestamp format */ 059 private String mstrTimeStampFmt = "yyyy-MM-dd HH:mm:ss"; 060 061 /** Variable to denote the successful load operation. */ 062 @SuppressWarnings("unused") 063 private boolean mblnLoaded = false; 064 065 /** Variable to hold the ini file name and full path */ 066 private String mstrFile; 067 068 /** Variable to hold the sections in an ini file. */ 069 private LinkedHashMap<String, INISection> mhmapSections; 070 071 /** Variable to hold environment variables **/ 072 private Properties mpropEnv; 073 074 /** 075 * Create a IniFile object from the file named in the parameter. 076 * @param pstrPathAndName The full path and name of the ini file to be used. 077 */ 078 public IniFile(String pstrPathAndName) 079 { 080 this.mpropEnv = getEnvVars(); 081 this.mhmapSections = new LinkedHashMap<String, INISection>(); 082 this.mstrFile = pstrPathAndName; 083 // Load the specified INI file. 084 if (checkFile(pstrPathAndName)) loadFile(); 085 } 086 087 public IniFile(InputStream stream) { 088 this.mpropEnv = getEnvVars(); 089 this.mhmapSections = new LinkedHashMap<String, INISection>(); 090 this.mstrFile = null; 091 // Load the specified INI file. 092 loadStream(stream); 093 } 094 095 /*------------------------------------------------------------------------------ 096 * Getters 097------------------------------------------------------------------------------*/ 098 /** 099 * Returns the ini file name being used. 100 * @return the INI file name. 101 */ 102 public String getFileName() 103 { 104 return this.mstrFile; 105 } 106 107 /** 108 * Returns the specified string property from the specified section. 109 * @param pstrSection the INI section name. 110 * @param pstrProp the property to be retrieved. 111 * @return the string property value. 112 */ 113 public String getStringProperty(String pstrSection, String pstrProp) 114 { 115 String strRet = null; 116 INIProperty objProp = null; 117 INISection objSec = null; 118 119 objSec = (INISection) this.mhmapSections.get(pstrSection); 120 if (objSec != null) 121 { 122 objProp = objSec.getProperty(pstrProp); 123 if (objProp != null) 124 { 125 strRet = objProp.getPropValue(); 126 objProp = null; 127 } 128 objSec = null; 129 } 130 return strRet; 131 } 132 133 /** 134 * Returns the specified boolean property from the specified section. 135 * This method considers the following values as boolean values. 136 * <ol> 137 * <li>YES/yes/Yes - boolean true</li> 138 * <li>NO/no/No - boolean false</li> 139 * <li>1 - boolean true</li> 140 * <li>0 - boolean false</li> 141 * <li>TRUE/True/true - boolean true</li> 142 * <li>FALSE/False/false - boolean false</li> 143 * </ol> 144 * @param pstrSection the INI section name. 145 * @param pstrProp the property to be retrieved. 146 * @return the boolean value 147 */ 148 public Boolean getBooleanProperty(String pstrSection, String pstrProp) 149 { 150 boolean blnRet = false; 151 String strVal = null; 152 INIProperty objProp = null; 153 INISection objSec = null; 154 155 objSec = (INISection) this.mhmapSections.get(pstrSection); 156 if (objSec != null) 157 { 158 objProp = objSec.getProperty(pstrProp); 159 if (objProp != null) 160 { 161 strVal = objProp.getPropValue().toUpperCase(); 162 if (strVal.equals("YES") || strVal.equals("TRUE") || 163 strVal.equals("1")) 164 { 165 blnRet = true; 166 } 167 objProp = null; 168 } 169 objSec = null; 170 } 171 return new Boolean(blnRet); 172 } 173 174 /** 175 * Returns the specified integer property from the specified section. 176 * @param pstrSection the INI section name. 177 * @param pstrProp the property to be retrieved. 178 * @return the integer property value. 179 */ 180 public Integer getIntegerProperty(String pstrSection, String pstrProp) 181 { 182 Integer intRet = null; 183 String strVal = null; 184 INIProperty objProp = null; 185 INISection objSec = null; 186 187 objSec = (INISection) this.mhmapSections.get(pstrSection); 188 if (objSec != null) 189 { 190 objProp = objSec.getProperty(pstrProp); 191 try 192 { 193 if (objProp != null) 194 { 195 strVal = objProp.getPropValue(); 196 if (strVal != null) intRet = new Integer(strVal); 197 } 198 } 199 catch (NumberFormatException NFExIgnore) 200 { 201 } 202 finally 203 { 204 if (objProp != null) objProp = null; 205 } 206 objSec = null; 207 } 208 return intRet; 209 } 210 211 /** 212 * Returns the specified long property from the specified section. 213 * @param pstrSection the INI section name. 214 * @param pstrProp the property to be retrieved. 215 * @return the long property value. 216 */ 217 public Long getLongProperty(String pstrSection, String pstrProp) 218 { 219 Long lngRet = null; 220 String strVal = null; 221 INIProperty objProp = null; 222 INISection objSec = null; 223 224 objSec = (INISection) this.mhmapSections.get(pstrSection); 225 if (objSec != null) 226 { 227 objProp = objSec.getProperty(pstrProp); 228 try 229 { 230 if (objProp != null) 231 { 232 strVal = objProp.getPropValue(); 233 if (strVal != null) lngRet = new Long(strVal); 234 } 235 } 236 catch (NumberFormatException NFExIgnore) 237 { 238 } 239 finally 240 { 241 if (objProp != null) objProp = null; 242 } 243 objSec = null; 244 } 245 return lngRet; 246 } 247 248 /** 249 * Returns the specified double property from the specified section. 250 * @param pstrSection the INI section name. 251 * @param pstrProp the property to be retrieved. 252 * @return the double property value. 253 */ 254 public Double getDoubleProperty(String pstrSection, String pstrProp) 255 { 256 Double dblRet = null; 257 String strVal = null; 258 INIProperty objProp = null; 259 INISection objSec = null; 260 261 objSec = (INISection) this.mhmapSections.get(pstrSection); 262 if (objSec != null) 263 { 264 objProp = objSec.getProperty(pstrProp); 265 try 266 { 267 if (objProp != null) 268 { 269 strVal = objProp.getPropValue(); 270 if (strVal != null) dblRet = new Double(strVal); 271 } 272 } 273 catch (NumberFormatException NFExIgnore) 274 { 275 } 276 finally 277 { 278 if (objProp != null) objProp = null; 279 } 280 objSec = null; 281 } 282 return dblRet; 283 } 284 285 /** 286 * Returns the specified date property from the specified section. 287 * @param pstrSection the INI section name. 288 * @param pstrProp the property to be retrieved. 289 * @return the date property value. 290 */ 291 public Date getDateProperty(String pstrSection, String pstrProp) 292 { 293 Date dtRet = null; 294 String strVal = null; 295 DateFormat dtFmt = null; 296 INIProperty objProp = null; 297 INISection objSec = null; 298 299 objSec = (INISection) this.mhmapSections.get(pstrSection); 300 if (objSec != null) 301 { 302 objProp = objSec.getProperty(pstrProp); 303 try 304 { 305 if (objProp != null) strVal = objProp.getPropValue(); 306 if (strVal != null) 307 { 308 dtFmt = new SimpleDateFormat(this.mstrDateFmt); 309 dtRet = dtFmt.parse(strVal); 310 } 311 } 312 catch (ParseException PExIgnore) 313 { 314 } 315 catch (IllegalArgumentException IAEx) 316 { 317 } 318 finally 319 { 320 if (objProp != null) objProp = null; 321 } 322 objSec = null; 323 } 324 return dtRet; 325 } 326 327 /** 328 * Returns the specified date property from the specified section. 329 * @param pstrSection the INI section name. 330 * @param pstrProp the property to be retrieved. 331 * @return the date property value. 332 */ 333 public Date getTimestampProperty(String pstrSection, String pstrProp) 334 { 335 Timestamp tsRet = null; 336 Date dtTmp = null; 337 String strVal = null; 338 DateFormat dtFmt = null; 339 INIProperty objProp = null; 340 INISection objSec = null; 341 342 objSec = (INISection) this.mhmapSections.get(pstrSection); 343 if (objSec != null) 344 { 345 objProp = objSec.getProperty(pstrProp); 346 try 347 { 348 if (objProp != null) strVal = objProp.getPropValue(); 349 if (strVal != null) 350 { 351 dtFmt = new SimpleDateFormat(this.mstrDateFmt); 352 dtTmp = dtFmt.parse(strVal); 353 tsRet = new Timestamp(dtTmp.getTime()); 354 } 355 } 356 catch (ParseException PExIgnore) 357 { 358 } 359 catch (IllegalArgumentException IAEx) 360 { 361 } 362 finally 363 { 364 if (objProp != null) objProp = null; 365 } 366 objSec = null; 367 } 368 return tsRet; 369 } 370 371/*------------------------------------------------------------------------------ 372 * Setters 373------------------------------------------------------------------------------*/ 374 /** 375 * Sets the comments associated with a section. 376 * @param pstrSection the section name 377 * @param pstrComments the comments. 378 */ 379 public void addSection(String pstrSection, String pstrComments) 380 { 381 INISection objSec = null; 382 383 objSec = (INISection) this.mhmapSections.get(pstrSection); 384 if (objSec == null) 385 { 386 objSec = new INISection(pstrSection); 387 this.mhmapSections.put(pstrSection, objSec); 388 } 389 objSec.setSecComments(delRemChars(pstrComments)); 390 objSec = null; 391 } 392 393 /** 394 * Sets the specified string property. 395 * @param pstrSection the INI section name. 396 * @param pstrProp the property to be set. 397 * @pstrVal the string value to be persisted 398 */ 399 public void setStringProperty(String pstrSection, String pstrProp, 400 String pstrVal, String pstrComments) 401 { 402 INISection objSec = null; 403 404 objSec = (INISection) this.mhmapSections.get(pstrSection); 405 if (objSec == null) 406 { 407 objSec = new INISection(pstrSection); 408 this.mhmapSections.put(pstrSection, objSec); 409 } 410 objSec.setProperty(pstrProp, pstrVal, pstrComments); 411 } 412 413 /** 414 * Sets the specified boolean property. 415 * @param pstrSection the INI section name. 416 * @param pstrProp the property to be set. 417 * @param pblnVal the boolean value to be persisted 418 */ 419 public void setBooleanProperty(String pstrSection, String pstrProp, 420 boolean pblnVal, String pstrComments) 421 { 422 INISection objSec = null; 423 424 objSec = (INISection) this.mhmapSections.get(pstrSection); 425 if (objSec == null) 426 { 427 objSec = new INISection(pstrSection); 428 this.mhmapSections.put(pstrSection, objSec); 429 } 430 if (pblnVal) 431 objSec.setProperty(pstrProp, "TRUE", pstrComments); 432 else 433 objSec.setProperty(pstrProp, "FALSE", pstrComments); 434 } 435 436 /** 437 * Sets the specified integer property. 438 * @param pstrSection the INI section name. 439 * @param pstrProp the property to be set. 440 * @param pintVal the int property to be persisted. 441 */ 442 public void setIntegerProperty(String pstrSection, String pstrProp, 443 int pintVal, String pstrComments) 444 { 445 INISection objSec = null; 446 447 objSec = (INISection) this.mhmapSections.get(pstrSection); 448 if (objSec == null) 449 { 450 objSec = new INISection(pstrSection); 451 this.mhmapSections.put(pstrSection, objSec); 452 } 453 objSec.setProperty(pstrProp, Integer.toString(pintVal), pstrComments); 454 } 455 456 /** 457 * Sets the specified long property. 458 * @param pstrSection the INI section name. 459 * @param pstrProp the property to be set. 460 * @param plngVal the long value to be persisted. 461 */ 462 public void setLongProperty(String pstrSection, String pstrProp, 463 long plngVal, String pstrComments) 464 { 465 INISection objSec = null; 466 467 objSec = (INISection) this.mhmapSections.get(pstrSection); 468 if (objSec == null) 469 { 470 objSec = new INISection(pstrSection); 471 this.mhmapSections.put(pstrSection, objSec); 472 } 473 objSec.setProperty(pstrProp, Long.toString(plngVal), pstrComments); 474 } 475 476 /** 477 * Sets the specified double property. 478 * @param pstrSection the INI section name. 479 * @param pstrProp the property to be set. 480 * @param pdblVal the double value to be persisted. 481 */ 482 public void setDoubleProperty(String pstrSection, String pstrProp, 483 double pdblVal, String pstrComments) 484 { 485 INISection objSec = null; 486 487 objSec = (INISection) this.mhmapSections.get(pstrSection); 488 if (objSec == null) 489 { 490 objSec = new INISection(pstrSection); 491 this.mhmapSections.put(pstrSection, objSec); 492 } 493 objSec.setProperty(pstrProp, Double.toString(pdblVal), pstrComments); 494 } 495 496 /** 497 * Sets the specified java.util.Date property. 498 * @param pstrSection the INI section name. 499 * @param pstrProp the property to be set. 500 * @param pdtVal the date value to be persisted. 501 */ 502 public void setDateProperty(String pstrSection, String pstrProp, 503 Date pdtVal, String pstrComments) 504 { 505 INISection objSec = null; 506 507 objSec = (INISection) this.mhmapSections.get(pstrSection); 508 if (objSec == null) 509 { 510 objSec = new INISection(pstrSection); 511 this.mhmapSections.put(pstrSection, objSec); 512 } 513 objSec.setProperty(pstrProp, utilDateToStr(pdtVal, this.mstrDateFmt), 514 pstrComments); 515 } 516 517 /** 518 * Sets the specified java.sql.Timestamp property. 519 * @param pstrSection the INI section name. 520 * @param pstrProp the property to be set. 521 * @param ptsVal the timestamp value to be persisted. 522 */ 523 public void setTimestampProperty(String pstrSection, String pstrProp, 524 Timestamp ptsVal, String pstrComments) 525 { 526 INISection objSec = null; 527 528 objSec = (INISection) this.mhmapSections.get(pstrSection); 529 if (objSec == null) 530 { 531 objSec = new INISection(pstrSection); 532 this.mhmapSections.put(pstrSection, objSec); 533 } 534 objSec.setProperty(pstrProp, timeToStr(ptsVal, this.mstrTimeStampFmt), 535 pstrComments); 536 } 537 538 /** 539 * Sets the format to be used to interpreat date values. 540 * @param pstrDtFmt the format string 541 * @throws IllegalArgumentException if the if the given pattern is invalid 542 */ 543 public void setDateFormat(String pstrDtFmt) throws IllegalArgumentException 544 { 545 if (!checkDateTimeFormat(pstrDtFmt)) 546 throw new IllegalArgumentException("The specified date pattern is invalid!"); 547 this.mstrDateFmt = pstrDtFmt; 548 } 549 550 /** 551 * Sets the format to be used to interpreat timestamp values. 552 * @param pstrTSFmt the format string 553 * @throws IllegalArgumentException if the if the given pattern is invalid 554 */ 555 public void setTimeStampFormat(String pstrTSFmt) 556 { 557 if (!checkDateTimeFormat(pstrTSFmt)) 558 throw new IllegalArgumentException("The specified timestamp pattern is invalid!"); 559 this.mstrTimeStampFmt = pstrTSFmt; 560 } 561 562/*------------------------------------------------------------------------------ 563 * Public methods 564------------------------------------------------------------------------------*/ 565 public int getTotalSections() 566 { 567 return this.mhmapSections.size(); 568 } 569 570 /** 571 * Returns a string array containing names of all sections in INI file. 572 * @return the string array of section names 573 */ 574 public String[] getAllSectionNames() 575 { 576 int iCntr = 0; 577 Iterator<String> iter = null; 578 String[] arrRet = null; 579 580 try 581 { 582 if (this.mhmapSections.size() > 0) 583 { 584 arrRet = new String[this.mhmapSections.size()]; 585 for (iter = this.mhmapSections.keySet().iterator();;iter.hasNext()) 586 { 587 arrRet[iCntr] = (String) iter.next(); 588 iCntr++; 589 } 590 } 591 } 592 catch (NoSuchElementException NSEExIgnore) 593 { 594 } 595 finally 596 { 597 if (iter != null) iter = null; 598 } 599 return arrRet; 600 } 601 602 /** 603 * Returns a string array containing names of all the properties under specified section. 604 * @param pstrSection the name of the section for which names of properties is to be retrieved. 605 * @return the string array of property names. 606 */ 607 public String[] getPropertyNames(String pstrSection) 608 { 609 String[] arrRet = null; 610 INISection objSec = null; 611 612 objSec = (INISection) this.mhmapSections.get(pstrSection); 613 if (objSec != null) 614 { 615 arrRet = objSec.getPropNames(); 616 objSec = null; 617 } 618 return arrRet; 619 } 620 621 /** 622 * Returns a map containing all the properties under specified section. 623 * @param pstrSection the name of the section for which properties are to be retrieved. 624 * @return the map of properties. 625 */ 626 public Map<String, INIProperty> getProperties(String pstrSection) 627 { 628 Map<String, INIProperty> hmRet = null; 629 INISection objSec = null; 630 631 objSec = (INISection) this.mhmapSections.get(pstrSection); 632 if (objSec != null) 633 { 634 hmRet = objSec.getProperties(); 635 objSec = null; 636 } 637 return hmRet; 638 } 639 640 /** 641 * Removed specified property from the specified section. If the specified 642 * section or the property does not exist, does nothing. 643 * @param pstrSection the section name. 644 * @param pstrProp the name of the property to be removed. 645 */ 646 public void removeProperty(String pstrSection, String pstrProp) 647 { 648 INISection objSec = null; 649 650 objSec = (INISection) this.mhmapSections.get(pstrSection); 651 if (objSec != null) 652 { 653 objSec.removeProperty(pstrProp); 654 objSec = null; 655 } 656 } 657 658 /** 659 * Removes the specified section if one exists, otherwise does nothing. 660 * @param pstrSection the name of the section to be removed. 661 */ 662 public void removeSection(String pstrSection) 663 { 664 if (this.mhmapSections.containsKey(pstrSection)) 665 this.mhmapSections.remove(pstrSection); 666 } 667 668 /** 669 * Flush changes back to the disk file. If the disk file does not exists then 670 * creates the new one. 671 * @ 672 */ 673 public boolean save() 674 { 675 boolean blnRet = false; 676 File objFile = null; 677 String strName = null; 678 String strTemp = null; 679 Iterator<String> itrSec = null; 680 INISection objSec = null; 681 FileWriter objWriter = null; 682 683 try 684 { 685 if (this.mhmapSections.size() == 0) return false; 686 objFile = new CSFile(this.mstrFile); 687 if (objFile.exists()) objFile.delete(); 688 objWriter = new FileWriter(objFile); 689 itrSec = this.mhmapSections.keySet().iterator(); 690 while (itrSec.hasNext()) 691 { 692 strName = (String) itrSec.next(); 693 objSec = (INISection) this.mhmapSections.get(strName); 694 strTemp = objSec.toString(); 695 objWriter.write(strTemp); 696 objWriter.write("\r\n"); 697 objSec = null; 698 } 699 blnRet = true; 700 } 701 catch (IOException IOExIgnore) 702 { 703 } 704 finally 705 { 706 if (objWriter != null) 707 { 708 closeWriter(objWriter); 709 objWriter = null; 710 } 711 if (objFile != null) objFile = null; 712 if (itrSec != null) itrSec = null; 713 } 714 return blnRet; 715 } 716 717 public boolean save(OutputStream stream) 718 { 719 boolean blnRet = false; 720 String strName = null; 721 String strTemp = null; 722 Iterator<String> itrSec = null; 723 INISection objSec = null; 724 OutputStreamWriter objWriter = null; 725 726 try 727 { 728 if (this.mhmapSections.size() == 0) return false; 729 objWriter = new OutputStreamWriter(stream, "UTF-8"); 730 itrSec = this.mhmapSections.keySet().iterator(); 731 while (itrSec.hasNext()) 732 { 733 strName = (String) itrSec.next(); 734 objSec = (INISection) this.mhmapSections.get(strName); 735 strTemp = objSec.toString(); 736 objWriter.write(strTemp); 737 objWriter.write("\r\n"); 738 objSec = null; 739 } 740 blnRet = true; 741 } 742 catch (IOException IOExIgnore) 743 { 744 } 745 finally 746 { 747 if (objWriter != null) 748 { 749 closeWriter(objWriter); 750 objWriter = null; 751 } 752 if (itrSec != null) itrSec = null; 753 } 754 return blnRet; 755 } 756 757 758/*------------------------------------------------------------------------------ 759 * Helper functions 760 *----------------------------------------------------------------------------*/ 761 /** 762 * Procedure to read environment variables. 763 * Thanx to http://www.rgagnon.com/howto.html for this implementation. 764 */ 765 private Properties getEnvVars() 766 { 767 Process p = null; 768 Properties envVars = new Properties(); 769 770 try 771 { 772 Runtime r = Runtime.getRuntime(); 773 String OS = System.getProperty("os.name").toLowerCase(); 774 775 if (OS.indexOf("windows 9") > -1) 776 { 777 p = r.exec("command.com /c set"); 778 } 779 else if ((OS.indexOf("nt") > -1) || 780 (OS.indexOf("windows 2000") > -1) || 781 (OS.indexOf("windows xp") > -1)) 782 { 783 p = r.exec("cmd.exe /c set"); 784 } 785 else 786 { 787 // our last hope, we assume Unix (thanks to H. Ware for the fix) 788 p = r.exec("env"); 789 } 790 BufferedReader br = new BufferedReader(new InputStreamReader(p.getInputStream())); 791 String line; 792 while((line = br.readLine()) != null) 793 { 794 int idx = line.indexOf('='); 795 String key = line.substring(0, idx); 796 String value = line.substring(idx + 1); 797 envVars.setProperty(key, value); 798 } 799 } 800 catch (Exception ExIgnore) 801 { 802 } 803 return envVars; 804 } 805 806 /** 807 * Helper function to check the date time formats. 808 * @param pstrDtFmt the date time format string to be checked. 809 * @return true for valid date/time format, false otherwise. 810 */ 811 private boolean checkDateTimeFormat(String pstrDtFmt) 812 { 813 boolean blnRet = false; 814 DateFormat objFmt = null; 815 816 try 817 { 818 objFmt = new SimpleDateFormat(pstrDtFmt); 819 blnRet = true; 820 } 821 catch (NullPointerException NPExIgnore) 822 { 823 } 824 catch (IllegalArgumentException IAExIgnore) 825 { 826 } 827 finally 828 { 829 if (objFmt != null) objFmt = null; 830 } 831 return blnRet; 832 } 833 834 /** 835 * Reads the INI file and load its contentens into a section collection after 836 * parsing the file line by line. 837 */ 838 private void loadStream(InputStream stream) 839 { 840 int iPos = -1; 841 String strLine = null; 842 String strSection = null; 843 String strRemarks = null; 844 BufferedReader objBRdr = null; 845 InputStreamReader objFRdr = null; 846 INISection objSec = null; 847 848 try 849 { 850 objFRdr = new InputStreamReader(stream); 851 if (objFRdr != null) 852 { 853 objBRdr = new BufferedReader(objFRdr); 854 if (objBRdr != null) 855 { 856 while (objBRdr.ready()) 857 { 858 iPos = -1; 859 strLine = null; 860 strLine = objBRdr.readLine().trim(); 861 if (strLine == null) 862 { 863 } 864 else if (strLine.length() == 0) 865 { 866 } 867 else if (strLine.substring(0, 1).equals(";")) 868 { 869 if (strRemarks == null) 870 strRemarks = strLine.substring(1); 871 else if (strRemarks.length() == 0) 872 strRemarks = strLine.substring(1); 873 else 874 strRemarks = strRemarks + "\r\n" + strLine.substring(1); 875 } 876 else if (strLine.startsWith("[") && strLine.endsWith("]")) 877 { 878 // Section start reached create new section 879 if (objSec != null) 880 this.mhmapSections.put(strSection.trim(), objSec); 881 objSec = null; 882 strSection = strLine.substring(1, strLine.length() - 1); 883 objSec = new INISection(strSection.trim(), strRemarks); 884 strRemarks = null; 885 } 886 else if ((iPos = strLine.indexOf("=")) > 0 && objSec != null) 887 { 888 // read the key value pair 012345=789 889 objSec.setProperty(strLine.substring(0, iPos).trim(), 890 strLine.substring(iPos + 1).trim(), 891 strRemarks); 892 strRemarks = null; 893 } 894 else 895 { 896 objSec.setProperty(strLine, "", strRemarks); 897 898 } 899 } 900 if (objSec != null) 901 this.mhmapSections.put(strSection.trim(), objSec); 902 this.mblnLoaded = true; 903 } 904 } 905 } 906 catch (FileNotFoundException FNFExIgnore) 907 { 908 this.mhmapSections.clear(); 909 } 910 catch (IOException IOExIgnore) 911 { 912 this.mhmapSections.clear(); 913 } 914 catch (NullPointerException NPExIgnore) 915 { 916 this.mhmapSections.clear(); 917 } 918 finally 919 { 920 if (objBRdr != null) 921 { 922 closeReader(objBRdr); 923 objBRdr = null; 924 } 925 if (objFRdr != null) 926 { 927 closeReader(objFRdr); 928 objFRdr = null; 929 } 930 if (objSec != null) objSec = null; 931 } 932 } 933 934 /** 935 * Reads the INI file and load its contentens into a section collection after 936 * parsing the file line by line. 937 */ 938 private void loadFile() 939 { 940 int iPos = -1; 941 String strLine = null; 942 String strSection = null; 943 String strRemarks = null; 944 BufferedReader objBRdr = null; 945 FileReader objFRdr = null; 946 INISection objSec = null; 947 948 try 949 { 950 objFRdr = new FileReader(this.mstrFile); 951 if (objFRdr != null) 952 { 953 objBRdr = new BufferedReader(objFRdr); 954 if (objBRdr != null) 955 { 956 while (objBRdr.ready()) 957 { 958 iPos = -1; 959 strLine = null; 960 strLine = objBRdr.readLine().trim(); 961 if (strLine == null) 962 { 963 } 964 else if (strLine.length() == 0) 965 { 966 } 967 else if (strLine.substring(0, 1).equals(";")) 968 { 969 if (strRemarks == null) 970 strRemarks = strLine.substring(1); 971 else if (strRemarks.length() == 0) 972 strRemarks = strLine.substring(1); 973 else 974 strRemarks = strRemarks + "\r\n" + strLine.substring(1); 975 } 976 else if (strLine.startsWith("[") && strLine.endsWith("]")) 977 { 978 // Section start reached create new section 979 if (objSec != null) 980 this.mhmapSections.put(strSection.trim(), objSec); 981 objSec = null; 982 strSection = strLine.substring(1, strLine.length() - 1); 983 objSec = new INISection(strSection.trim(), strRemarks); 984 strRemarks = null; 985 } 986 else if ((iPos = strLine.indexOf("=")) > 0 && objSec != null) 987 { 988 // read the key value pair 012345=789 989 objSec.setProperty(strLine.substring(0, iPos).trim(), 990 strLine.substring(iPos + 1).trim(), 991 strRemarks); 992 strRemarks = null; 993 } 994 else 995 { 996 objSec.setProperty(strLine, "", strRemarks); 997 998 } 999 } 1000 if (objSec != null) 1001 this.mhmapSections.put(strSection.trim(), objSec); 1002 this.mblnLoaded = true; 1003 } 1004 } 1005 } 1006 catch (FileNotFoundException FNFExIgnore) 1007 { 1008 this.mhmapSections.clear(); 1009 } 1010 catch (IOException IOExIgnore) 1011 { 1012 this.mhmapSections.clear(); 1013 } 1014 catch (NullPointerException NPExIgnore) 1015 { 1016 this.mhmapSections.clear(); 1017 } 1018 finally 1019 { 1020 if (objBRdr != null) 1021 { 1022 closeReader(objBRdr); 1023 objBRdr = null; 1024 } 1025 if (objFRdr != null) 1026 { 1027 closeReader(objFRdr); 1028 objFRdr = null; 1029 } 1030 if (objSec != null) objSec = null; 1031 } 1032 } 1033 1034 /** 1035 * Helper function to close a reader object. 1036 * @param pobjRdr the reader to be closed. 1037 */ 1038 private void closeReader(Reader pobjRdr) 1039 { 1040 if (pobjRdr == null) return; 1041 try 1042 { 1043 pobjRdr.close(); 1044 } 1045 catch (IOException IOExIgnore) 1046 { 1047 } 1048 } 1049 1050 /** 1051 * Helper function to close a writer object. 1052 * @param pobjWriter the writer to be closed. 1053 */ 1054 private void closeWriter(Writer pobjWriter) 1055 { 1056 if (pobjWriter == null) return; 1057 1058 try 1059 { 1060 pobjWriter.close(); 1061 } 1062 catch (IOException IOExIgnore) 1063 { 1064 } 1065 } 1066 1067 /** 1068 * Helper method to check the existance of a file. 1069 * @param the full path and name of the file to be checked. 1070 * @return true if file exists, false otherwise. 1071 */ 1072 private boolean checkFile(String pstrFile) 1073 { 1074 boolean blnRet = false; 1075 File objFile = null; 1076 1077 try 1078 { 1079 objFile = new CSFile(pstrFile); 1080 blnRet = (objFile.exists() && objFile.isFile()); 1081 } 1082 catch (Exception e) 1083 { 1084 blnRet = false; 1085 } 1086 finally 1087 { 1088 if (objFile != null) objFile = null; 1089 } 1090 return blnRet; 1091 } 1092 1093 /** 1094 * Converts a java.util.date into String 1095 * @param pd Date that need to be converted to String 1096 * @param pstrFmt The date format pattern. 1097 * @return String 1098 */ 1099 private String utilDateToStr(Date pdt, String pstrFmt) 1100 { 1101 String strRet = null; 1102 SimpleDateFormat dtFmt = null; 1103 1104 try 1105 { 1106 dtFmt = new SimpleDateFormat(pstrFmt); 1107 strRet = dtFmt.format(pdt); 1108 } 1109 catch (Exception e) 1110 { 1111 strRet = null; 1112 } 1113 finally 1114 { 1115 if (dtFmt != null) dtFmt = null; 1116 } 1117 return strRet; 1118 } 1119 1120 /** 1121 * Converts the given sql timestamp object to a string representation. The format 1122 * to be used is to be obtained from the configuration file. 1123 * 1124 * @param pobjTS the sql timestamp object to be converted. 1125 * @param pblnGMT If true formats the string using GMT timezone 1126 * otherwise using local timezone. 1127 * @return the formatted string representation of the timestamp. 1128 */ 1129 private String timeToStr(Timestamp pobjTS, String pstrFmt) 1130 { 1131 String strRet = null; 1132 SimpleDateFormat dtFmt = null; 1133 1134 try 1135 { 1136 dtFmt = new SimpleDateFormat(pstrFmt); 1137 strRet = dtFmt.format(pobjTS); 1138 } 1139 catch (IllegalArgumentException iae) 1140 { 1141 strRet = ""; 1142 } 1143 catch (NullPointerException npe) 1144 { 1145 strRet = ""; 1146 } 1147 finally 1148 { 1149 if (dtFmt != null) dtFmt = null; 1150 } 1151 return strRet; 1152 } 1153 1154 /** 1155 * This function deletes the remark characters ';' from source string 1156 * @param pstrSrc the source string 1157 * @return the converted string 1158 */ 1159 private String delRemChars(String pstrSrc) 1160 { 1161 int intPos = 0; 1162 1163 if (pstrSrc == null) return null; 1164 while ((intPos = pstrSrc.indexOf(";")) >= 0) 1165 { 1166 if (intPos == 0) 1167 pstrSrc = pstrSrc.substring(intPos + 1); 1168 else if (intPos > 0) 1169 pstrSrc = pstrSrc.substring(0, intPos) + pstrSrc.substring(intPos + 1); 1170 } 1171 return pstrSrc; 1172 } 1173 1174 /** 1175 * This function adds a remark character ';' in source string. 1176 * @param pstrSrc source string 1177 * @return converted string. 1178 */ 1179 private String addRemChars(String pstrSrc) 1180 { 1181 int intLen = 2; 1182 int intPos = 0; 1183 int intPrev = 0; 1184 1185 String strLeft = null; 1186 String strRight = null; 1187 1188 if (pstrSrc == null) return null; 1189 while (intPos >= 0) 1190 { 1191 intLen = 2; 1192 intPos = pstrSrc.indexOf("\r\n", intPrev); 1193 if (intPos < 0) 1194 { 1195 intLen = 1; 1196 intPos = pstrSrc.indexOf("\n", intPrev); 1197 if (intPos < 0) intPos = pstrSrc.indexOf("\r", intPrev); 1198 } 1199 if (intPos == 0) 1200 { 1201 pstrSrc = ";\r\n" + pstrSrc.substring(intPos + intLen); 1202 intPrev = intPos + intLen + 1; 1203 } 1204 else if (intPos > 0) 1205 { 1206 strLeft = pstrSrc.substring(0, intPos); 1207 strRight = pstrSrc.substring(intPos + intLen); 1208 if (strRight == null) 1209 pstrSrc = strLeft; 1210 else if (strRight.length() == 0) 1211 pstrSrc = strLeft; 1212 else 1213 pstrSrc = strLeft + "\r\n;" + strRight; 1214 intPrev = intPos + intLen + 1; 1215 } 1216 } 1217 if (!pstrSrc.substring(0, 1).equals(";")) 1218 pstrSrc = ";" + pstrSrc; 1219 pstrSrc = pstrSrc + "\r\n"; 1220 return pstrSrc; 1221 } 1222/*------------------------------------------------------------------------------ 1223 * Main entry point to test the functionality. 1224 *----------------------------------------------------------------------------*/ 1225 /** 1226 * The main entry point for testing. 1227 * @param pstrArgs the command line arguments array if any. 1228 * @ 1229 */ 1230 public static void main(String[] pstrArgs) 1231 { 1232 IniFile objINI = null; 1233 String strFile = null; 1234 1235 if (pstrArgs.length == 0) return; 1236 1237 strFile = pstrArgs[0]; 1238 // Following call will load the strFile if one exists. 1239 objINI = new IniFile(strFile); 1240 1241// objINI.addSection("QADatabase", "QA database connection details\nUsed for QA Testing"); 1242// objINI.setStringProperty("QADatabase", "SID", "ORCL", null); 1243// objINI.setStringProperty("QADatabase", "UserId", "System", null); 1244// objINI.setStringProperty("QADatabase", "Password", "Manager", null); 1245// objINI.setStringProperty("QADatabase", "HostName", "DBServer", null); 1246// objINI.setIntegerProperty("QADatabase", "Port", 1521, null); 1247// objINI.setStringProperty("QADatabase", "OracleHome", "%ORACLE_HOME%", null); 1248// 1249 // objINI.setSectionComments("Folders", "Directories where generated files are stored"); 1250 objINI.setStringProperty("Folders", "folder1", "G:\\Temp", null); 1251 objINI.setStringProperty("Folders", "folder2", "G:\\Temp\\Backup", null); 1252 1253 // Save changes back to strFile. 1254 objINI.save(); 1255 objINI = null; 1256 } 1257 1258/*------------------------------------------------------------------------------ 1259 * Private class representing the INI Section. 1260 *----------------------------------------------------------------------------*/ 1261 /** 1262 * Class to represent the individual ini file section. 1263 * @author Prasad P. Khandekar 1264 * @version 1.0 1265 * @since 1.0 1266 */ 1267 private class INISection 1268 { 1269 /** Variable to hold any comments associated with this section */ 1270 private String mstrComment; 1271 1272 /** Variable to hold the section name. */ 1273 private String mstrName; 1274 1275 /** Variable to hold the properties falling under this section. */ 1276 private LinkedHashMap<String, INIProperty> mhmapProps; 1277 1278 /** 1279 * Construct a new section object identified by the name specified in 1280 * parameter. 1281 * @param pstrSection The new sections name. 1282 */ 1283 public INISection(String pstrSection) 1284 { 1285 this.mstrName = pstrSection; 1286 this.mhmapProps = new LinkedHashMap<String, INIProperty>(); 1287 } 1288 1289 /** 1290 * Construct a new section object identified by the name specified in 1291 * parameter and associated comments. 1292 * @param pstrSection The new sections name. 1293 * @param pstrComments the comments associated with this section. 1294 */ 1295 public INISection(String pstrSection, String pstrComments) 1296 { 1297 this.mstrName = pstrSection; 1298 this.mstrComment = delRemChars(pstrComments); 1299 this.mhmapProps = new LinkedHashMap<String, INIProperty>(); 1300 } 1301 1302 /** 1303 * Sets the comments associated with this section. 1304 * @param pstrComments the comments 1305 */ 1306 public void setSecComments(String pstrComments) 1307 { 1308 this.mstrComment = delRemChars(pstrComments); 1309 } 1310 1311 /** 1312 * Removes specified property value from this section. 1313 * @param pstrProp The name of the property to be removed. 1314 */ 1315 public void removeProperty(String pstrProp) 1316 { 1317 if (this.mhmapProps.containsKey(pstrProp)) 1318 this.mhmapProps.remove(pstrProp); 1319 } 1320 1321 /** 1322 * Creates or modifies the specified property value. 1323 * @param pstrProp The name of the property to be created or modified. 1324 * @param pstrValue The new value for the property. 1325 * @param pstrComments the associated comments 1326 */ 1327 public void setProperty(String pstrProp, String pstrValue, String pstrComments) 1328 { 1329 this.mhmapProps.put(pstrProp, new INIProperty(pstrProp, pstrValue, pstrComments)); 1330 } 1331 1332 /** 1333 * Returns a map of all properties. 1334 * @return a map of all properties 1335 */ 1336 public Map<String, INIProperty> getProperties() 1337 { 1338 return Collections.unmodifiableMap(this.mhmapProps); 1339 } 1340 1341 /** 1342 * Returns a string array containing names of all the properties under 1343 * this section. 1344 * @return the string array of property names. 1345 */ 1346 public String[] getPropNames() 1347 { 1348 int iCntr = 0; 1349 String[] arrRet = null; 1350 Iterator<String> iter = null; 1351 1352 try 1353 { 1354 if (this.mhmapProps.size() > 0) 1355 { 1356 arrRet = new String[this.mhmapProps.size()]; 1357 for (iter = this.mhmapProps.keySet().iterator();iter.hasNext();) 1358 { 1359 arrRet[iCntr] = (String) iter.next(); 1360 iCntr++; 1361 } 1362 } 1363 } 1364 catch (NoSuchElementException NSEExIgnore) 1365 { 1366 arrRet = null; 1367 } 1368 return arrRet; 1369 } 1370 1371 /** 1372 * Returns underlying value of the specified property. 1373 * @param pstrProp the property whose underlying value is to be etrieved. 1374 * @return the property value. 1375 */ 1376 public INIProperty getProperty(String pstrProp) 1377 { 1378 INIProperty objRet = null; 1379 1380 if (this.mhmapProps.containsKey(pstrProp)) 1381 objRet = (INIProperty) this.mhmapProps.get(pstrProp); 1382 return objRet; 1383 } 1384 1385 /* (non-Javadoc) 1386 * @see java.lang.Object#toString() 1387 */ 1388 @Override 1389 public String toString() 1390 { 1391 Set<String> colKeys = null; 1392 String strRet = ""; 1393 Iterator<String> iter = null; 1394 INIProperty objProp = null; 1395 StringBuffer objBuf = new StringBuffer(); 1396 1397 if (this.mstrComment != null) 1398 objBuf.append(addRemChars(this.mstrComment)); 1399 objBuf.append("[" + this.mstrName + "]\r\n"); 1400 colKeys = this.mhmapProps.keySet(); 1401 if (colKeys != null) 1402 { 1403 iter = colKeys.iterator(); 1404 if (iter != null) 1405 { 1406 while (iter.hasNext()) 1407 { 1408 objProp = (INIProperty) this.mhmapProps.get(iter.next()); 1409 objBuf.append(objProp.toString()); 1410 objBuf.append("\r\n"); 1411 objProp = null; 1412 } 1413 } 1414 } 1415 strRet = objBuf.toString(); 1416 1417 objBuf = null; 1418 iter = null; 1419 colKeys = null; 1420 return strRet; 1421 } 1422 } 1423 1424/*------------------------------------------------------------------------------ 1425 * Private class representing the INI Property. 1426 *----------------------------------------------------------------------------*/ 1427 /** 1428 * This class represents a key value pair called property in an INI file. 1429 * @author Prasad P. Khandekar 1430 * @version 1.0 1431 * @since 1.0 1432 */ 1433 private class INIProperty 1434 { 1435 /** Variable to hold name of this property */ 1436 private String mstrName; 1437 /** Variable to hold value of this property */ 1438 private String mstrValue; 1439 /** Variable to hold comments associated with this property */ 1440 private String mstrComments; 1441 1442 /** 1443 * Constructor 1444 * @param pstrName the name of this property. 1445 * @param pstrValue the value of this property. 1446 * @param pstrComments the comments associated with this property. 1447 */ 1448 public INIProperty(String pstrName, String pstrValue, String pstrComments) 1449 { 1450 this.mstrName = pstrName; 1451 this.mstrValue = pstrValue; 1452 this.mstrComments = delRemChars(pstrComments); 1453 } 1454 1455 /** 1456 * Returns value of this property. If value contains a reference to 1457 * environment avriable then this reference is replaced by actual value 1458 * before the value is returned. 1459 * @return the value of this property. 1460 */ 1461 public String getPropValue() 1462 { 1463 int intStart = 0; 1464 int intEnd = 0; 1465 String strVal = null; 1466 String strVar = null; 1467 String strRet = null; 1468 1469 strRet = this.mstrValue; 1470 intStart = strRet.indexOf("%"); 1471 if (intStart >= 0) 1472 { 1473 intEnd = strRet.indexOf("%", intStart + 1); 1474 strVar = strRet.substring(intStart + 1, intEnd); 1475 strVal = mpropEnv.getProperty(strVar); 1476 if (strVal != null) 1477 { 1478 strRet = strRet.substring(0, intStart) + strVal + 1479 strRet.substring(intEnd + 1); 1480 } 1481 } 1482 return strRet; 1483 } 1484 1485 /* (non-Javadoc) 1486 * @see java.lang.Object#toString() 1487 */ 1488 @Override 1489 public String toString() 1490 { 1491 String strRet = ""; 1492 1493 if (this.mstrComments != null) 1494 strRet = addRemChars(mstrComments); 1495 strRet = strRet + this.mstrName + " = " + this.mstrValue; 1496 return strRet; 1497 } 1498 } 1499}