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