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