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