1 /************************************************************************* 2 * 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * Copyright 2000, 2010 Oracle and/or its affiliates. 6 * 7 * OpenOffice.org - a multi-platform office productivity suite 8 * 9 * This file is part of OpenOffice.org. 10 * 11 * OpenOffice.org is free software: you can redistribute it and/or modify 12 * it under the terms of the GNU Lesser General Public License version 3 13 * only, as published by the Free Software Foundation. 14 * 15 * OpenOffice.org is distributed in the hope that it will be useful, 16 * but WITHOUT ANY WARRANTY; without even the implied warranty of 17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 18 * GNU Lesser General Public License version 3 for more details 19 * (a copy is included in the LICENSE file that accompanied this code). 20 * 21 * You should have received a copy of the GNU Lesser General Public License 22 * version 3 along with OpenOffice.org. If not, see 23 * <http://www.openoffice.org/license.html> 24 * for a copy of the LGPLv3 License. 25 * 26 ************************************************************************/ 27 28 package convwatch; 29 30 import java.io.File; 31 import java.io.RandomAccessFile; 32 import java.util.ArrayList; 33 34 /** 35 Helper class to give a simple API to read/write windows like ini files 36 */ 37 /* public */ // is only need, if we need this class outside package convwatch 38 class IniFile 39 { 40 /** 41 * internal representation of the ini file content. 42 * Problem, if ini file changed why other write something difference, we don't realise this. 43 */ 44 String m_sFilename; 45 ArrayList m_aList; 46 boolean m_bListContainUnsavedChanges = false; 47 48 /** 49 open a ini file by it's name 50 @param _sFilename string a filename, if the file doesn't exist, a new empty ini file will create. 51 write back to disk only if there are really changes. 52 */ 53 public IniFile(String _sFilename) 54 { 55 m_sFilename = _sFilename; 56 m_aList = loadLines(); 57 } 58 59 ArrayList loadLines() 60 { 61 File aFile = new File(m_sFilename); 62 ArrayList aLines = new ArrayList(); 63 if (! aFile.exists()) 64 { 65 GlobalLogWriter.get().println("couldn't find file " + m_sFilename); 66 // DebugHelper.exception(BasicErrorCode.SbERR_FILE_NOT_FOUND, ""); 67 // m_bListContainUnsavedChanges = false; 68 return aLines; 69 } 70 RandomAccessFile aReader = null; 71 try 72 { 73 aReader = new RandomAccessFile(aFile,"r"); 74 String aLine = ""; 75 while (aLine != null) 76 { 77 aLine = aReader.readLine(); 78 if (aLine != null) 79 { 80 aLines.add(aLine); 81 } 82 } 83 } 84 catch (java.io.FileNotFoundException fne) 85 { 86 GlobalLogWriter.get().println("couldn't open file " + m_sFilename); 87 GlobalLogWriter.get().println("Message: " + fne.getMessage()); 88 // DebugHelper.exception(BasicErrorCode.SbERR_FILE_NOT_FOUND, ""); 89 } 90 catch (java.io.IOException ie) 91 { 92 GlobalLogWriter.get().println("Exception occurs while reading from file " + m_sFilename); 93 GlobalLogWriter.get().println("Message: " + ie.getMessage()); 94 // DebugHelper.exception(BasicErrorCode.SbERR_INTERNAL_ERROR, ie.getMessage()); 95 } 96 try 97 { 98 aReader.close(); 99 } 100 catch (java.io.IOException ie) 101 { 102 GlobalLogWriter.get().println("Couldn't close file " + m_sFilename); 103 GlobalLogWriter.get().println("Message: " + ie.getMessage()); 104 // DebugHelper.exception(BasicErrorCode.SbERR_INTERNAL_ERROR, ie.getMessage()); 105 } 106 return aLines; 107 } 108 109 /** 110 * @return true, if the ini file contain some readable data 111 */ 112 public boolean is() 113 { 114 return m_aList.size() > 1 ? true : false; 115 } 116 117 // ----------------------------------------------------------------------------- 118 119 boolean isRemark(String _sLine) 120 { 121 if ( ((_sLine.length() < 2) ) || 122 ( _sLine.startsWith("#")) || 123 ( _sLine.startsWith(";")) ) 124 { 125 return true; 126 } 127 return false; 128 } 129 130 String getItem(int i) 131 { 132 return (String)m_aList.get(i); 133 } 134 135 String buildSectionName(String _sSectionName) 136 { 137 String sFindSection = "[" + _sSectionName + "]"; 138 return sFindSection; 139 } 140 String toLowerIfNeed(String _sName) 141 { 142 return _sName.toLowerCase(); 143 } 144 145 // return the number where this section starts 146 int findSection(String _sSection) 147 { 148 String sFindSection = toLowerIfNeed(buildSectionName(_sSection)); 149 // ----------- find _sSection --------------- 150 int i; 151 for (i=0; i<m_aList.size();i++) 152 { 153 String sLine = toLowerIfNeed(getItem(i).trim()); 154 if (isRemark(sLine)) 155 { 156 continue; 157 } 158 if (sFindSection.equals("[]")) 159 { 160 // special case, empty Section. 161 return i - 1; 162 } 163 if (sLine.startsWith(sFindSection)) 164 { 165 return i; 166 } 167 } 168 return -1; 169 } 170 171 // return the line number, where the key is found. 172 int findKey(String _sSection, String _sKey) 173 { 174 int i = findSection(_sSection); 175 if (i == -1) 176 { 177 // Section not found, therefore the value can't exist 178 return -1; 179 } 180 return findKeyFromKnownSection(i, _sKey); 181 } 182 183 // i must be the index in the list, where the well known section starts 184 int findKeyFromKnownSection(int _nSectionIndex, String _sKey) 185 { 186 _sKey = toLowerIfNeed(_sKey); 187 for (int j=_nSectionIndex + 1; j<m_aList.size();j++) 188 { 189 String sLine = getItem(j).trim(); 190 191 if (isRemark(sLine)) 192 { 193 continue; 194 } 195 196 if (sLine.startsWith("[") /* && sLine.endsWith("]") */) 197 { 198 // found end. 199 break; 200 } 201 202 int nEqual = sLine.indexOf("="); 203 if (nEqual >= 0) 204 { 205 String sKey = toLowerIfNeed(sLine.substring(0, nEqual).trim()); 206 if (sKey.equals(_sKey)) 207 { 208 return j; 209 } 210 } 211 } 212 return -1; 213 } 214 215 // i must be the index in the list, where the well known section starts 216 int findLastKnownKeyIndex(int _nSectionIndex, String _sKey) 217 { 218 _sKey = toLowerIfNeed(_sKey); 219 int i = _nSectionIndex + 1; 220 for (int j=i; j<m_aList.size();j++) 221 { 222 String sLine = getItem(j).trim(); 223 224 if (isRemark(sLine)) 225 { 226 continue; 227 } 228 229 if (sLine.startsWith("[") /* && sLine.endsWith("]") */) 230 { 231 // found end. 232 return j; 233 } 234 235 int nEqual = sLine.indexOf("="); 236 if (nEqual >= 0) 237 { 238 String sKey = toLowerIfNeed(sLine.substring(0, nEqual).trim()); 239 if (sKey.equals(_sKey)) 240 { 241 return j; 242 } 243 } 244 } 245 return i; 246 } 247 248 String getValue(int _nIndex) 249 { 250 String sLine = getItem(_nIndex).trim(); 251 if (isRemark(sLine)) 252 { 253 return ""; 254 } 255 int nEqual = sLine.indexOf("="); 256 if (nEqual >= 0) 257 { 258 String sKey = sLine.substring(0, nEqual).trim(); 259 String sValue = sLine.substring(nEqual + 1).trim(); 260 return sValue; 261 } 262 return ""; 263 } 264 265 /** 266 @param _sSection string 267 @param _sKey string 268 @return the value found in the inifile which is given by the section and key parameter 269 */ 270 public String getValue(String _sSection, String _sKey) 271 { 272 String sValue = ""; 273 int i = findKey(_sSection, _sKey); 274 if (i == -1) 275 { 276 // Section not found, therefore the value can't exist 277 return ""; 278 } 279 280 sValue = getValue(i); 281 282 return sValue; 283 } 284 285 /** 286 write back the ini file to the disk, only if there exist changes 287 */ 288 public void store() 289 { 290 if (m_bListContainUnsavedChanges == false) 291 { 292 // nothing has changed, so no need to store 293 return; 294 } 295 296 File aFile = new File(m_sFilename); 297 if (aFile.exists()) 298 { 299 // System.out.println("couldn't find file " + m_sFilename); 300 aFile.delete(); 301 if (aFile.exists()) 302 { 303 GlobalLogWriter.get().println("Couldn't delete the file " + m_sFilename); 304 return; 305 // DebugHelper.exception(BasicErrorCode.SbERR_INTERNAL_ERROR, "Couldn't delete the file " + m_sFilename); 306 } 307 } 308 // if (! aFile.canWrite()) 309 // { 310 // System.out.println("Couldn't write to file " + m_sFilename); 311 // DebugHelper.exception(BasicErrorCode.SbERR_INTERNAL_ERROR, ""); 312 // } 313 try 314 { 315 RandomAccessFile aWriter = new RandomAccessFile(aFile, "rw"); 316 for (int i=0; i<m_aList.size();i++) 317 { 318 String sLine = getItem(i); 319 aWriter.writeBytes(sLine); 320 aWriter.writeByte((int)'\n'); 321 } 322 aWriter.close(); 323 } 324 325 catch (java.io.FileNotFoundException fne) 326 { 327 GlobalLogWriter.get().println("couldn't open file for writing " + m_sFilename); 328 GlobalLogWriter.get().println("Message: " + fne.getMessage()); 329 // DebugHelper.exception(BasicErrorCode.SbERR_FILE_NOT_FOUND, ""); 330 } 331 catch(java.io.IOException ie) 332 { 333 GlobalLogWriter.get().println("Exception occurs while writing to file " + m_sFilename); 334 GlobalLogWriter.get().println("Message: " + ie.getMessage()); 335 // DebugHelper.exception(BasicErrorCode.SbERR_INTERNAL_ERROR, ie.getMessage()); 336 } 337 } 338 339 340 341 /** 342 insert a value 343 there are 3 cases 344 1. section doesn't exist, goto end and insert a new section, insert a new key value pair 345 2. section exist but key not, search section, search key, if key is -1 get last known key position and insert new key value pair there 346 3. section exist and key exist, remove the old key and insert the key value pair at the same position 347 */ 348 public void insertValue(String _sSection, String _sKey, String _sValue) 349 { 350 int i = findSection(_sSection); 351 if (i == -1) 352 { 353 // case 1: section doesn't exist 354 String sFindSection = buildSectionName(_sSection); 355 356 m_aList.add(sFindSection); 357 String sKeyValuePair = _sKey + "=" + _sValue; 358 m_aList.add(sKeyValuePair); 359 m_bListContainUnsavedChanges = true; 360 return; 361 } 362 int j = findKeyFromKnownSection(i, _sKey); 363 if (j == -1) 364 { 365 // case 2: section exist, but not the key 366 j = findLastKnownKeyIndex(i, _sKey); 367 String sKeyValuePair = _sKey + "=" + _sValue; 368 m_aList.add(j, sKeyValuePair); 369 m_bListContainUnsavedChanges = true; 370 return; 371 } 372 else 373 { 374 // case 3: section exist, and also the key 375 String sKeyValuePair = _sKey + "=" + _sValue; 376 m_aList.set(j, sKeyValuePair); 377 m_bListContainUnsavedChanges = true; 378 } 379 } 380 // ----------------------------------------------------------------------------- 381 // String replaceEvaluatedValue(String _sSection, String _sValue) 382 // { 383 // String sValue = _sValue; 384 // int nIndex = 0; 385 // while (( nIndex = sValue.indexOf("$(", nIndex)) >= 0) 386 // { 387 // int nNextIndex = sValue.indexOf(")", nIndex); 388 // if (nNextIndex >= 0) 389 // { 390 // String sKey = sValue.substring(nIndex + 2, nNextIndex); 391 // String sNewValue = getValue(_sSection, sKey); 392 // if (sNewValue != null && sNewValue.length() > 0) 393 // { 394 // String sRegexpKey = "\\$\\(" + sKey + "\\)"; 395 // sValue = sValue.replaceAll(sRegexpKey, sNewValue); 396 // } 397 // nIndex = nNextIndex; 398 // } 399 // else 400 // { 401 // nIndex += 2; 402 // } 403 // } 404 // return sValue; 405 // } 406 // ----------------------------------------------------------------------------- 407 408 // public String getLocalEvaluatedValue(String _sSection, String _sKey) 409 // { 410 // String sValue = getValue(_sSection, _sKey); 411 // sValue = replaceEvaluatedValue(_sSection, sValue); 412 // return sValue; 413 // } 414 415 // ----------------------------------------------------------------------------- 416 417 // this is a special behaviour. 418 // public String getGlobalLocalEvaluatedValue(String _sSection, String _sKey) 419 // { 420 // String sGlobalValue = getKey("global", _sKey); 421 // String sLocalValue = getKey(_sSection, _sKey); 422 // if (sLocalValue.length() == 0) 423 // { 424 // sGlobalValue = replaceEvaluatedKey(_sSection, sGlobalValue); 425 // sGlobalValue = replaceEvaluatedKey("global", sGlobalValue); 426 // return sGlobalValue; 427 // } 428 // sLocalValue = replaceEvaluatedKey(_sSection, sLocalValue); 429 // sLocalValue = replaceEvaluatedKey("global", sLocalValue); 430 // 431 // return sLocalValue; 432 // } 433 434 435 /** 436 * some tests for this class 437 */ 438 // public static void main(String[] args) 439 // { 440 // IniFile aIniFile = new IniFile("/tmp/inifile"); 441 // String sValue = aIniFile.getValue("Section","Key"); 442 // // insert a new value to a already exist section 443 // aIniFile.insertValue("Section","Key2","a new value in a existing section"); 444 // // replace a value 445 // aIniFile.insertValue("Section","Key","replaced value"); 446 // // create a new value 447 // aIniFile.insertValue("New Section", "Key", "a new key value pair"); 448 // 449 // String sValue2 = aIniFile.getValue("Section2","Key"); 450 // aIniFile.store(); 451 // } 452 } 453