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