2 * This file is part of the LibreOffice project.
4 * This Source Code Form is subject to the terms of the Mozilla Public
5 * License, v. 2.0. If a copy of the MPL was not distributed with this
6 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
8 * This file incorporates work covered by the following license notice:
10 * Licensed to the Apache Software Foundation (ASF) under one or more
11 * contributor license agreements. See the NOTICE file distributed
12 * with this work for additional information regarding copyright
13 * ownership. The ASF licenses this file to you under the Apache
14 * License, Version 2.0 (the "License"); you may not use this file
15 * except in compliance with the License. You may obtain a copy of
16 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
22 import java
.io
.RandomAccessFile
;
23 import java
.util
.ArrayList
;
26 Helper class to give a simple API to read/write windows like ini files
28 /* public */ // is only need, if we need this class outside package convwatch
32 * internal representation of the ini file content.
33 * Problem, if ini file changed why other write something difference, we don't realise this.
36 ArrayList
<String
> m_aList
;
37 boolean m_bListContainUnsavedChanges
= false;
40 open a ini file by it's name
41 @param _sFilename string a filename, if the file doesn't exist, a new empty ini file will create.
42 write back to disk only if there are really changes.
44 public IniFile(String _sFilename
)
46 m_sFilename
= _sFilename
;
47 m_aList
= loadLines();
50 ArrayList
<String
> loadLines()
52 File aFile
= new File(m_sFilename
);
53 ArrayList
<String
> aLines
= new ArrayList
<String
>();
56 GlobalLogWriter
.get().println("couldn't find file " + m_sFilename
);
57 // DebugHelper.exception(BasicErrorCode.SbERR_FILE_NOT_FOUND, "");
58 // m_bListContainUnsavedChanges = false;
61 RandomAccessFile aReader
= null;
64 aReader
= new RandomAccessFile(aFile
,"r");
68 aLine
= aReader
.readLine();
75 catch (java
.io
.FileNotFoundException fne
)
77 GlobalLogWriter
.get().println("couldn't open file " + m_sFilename
);
78 GlobalLogWriter
.get().println("Message: " + fne
.getMessage());
79 // DebugHelper.exception(BasicErrorCode.SbERR_FILE_NOT_FOUND, "");
81 catch (java
.io
.IOException ie
)
83 GlobalLogWriter
.get().println("Exception occurs while reading from file " + m_sFilename
);
84 GlobalLogWriter
.get().println("Message: " + ie
.getMessage());
85 // DebugHelper.exception(BasicErrorCode.SbERR_INTERNAL_ERROR, ie.getMessage());
91 catch (java
.io
.IOException ie
)
93 GlobalLogWriter
.get().println("Couldn't close file " + m_sFilename
);
94 GlobalLogWriter
.get().println("Message: " + ie
.getMessage());
95 // DebugHelper.exception(BasicErrorCode.SbERR_INTERNAL_ERROR, ie.getMessage());
101 * @return true, if the ini file contain some readable data
105 return m_aList
.size() > 1 ?
true : false;
108 // -----------------------------------------------------------------------------
110 boolean isRemark(String _sLine
)
112 if ( ((_sLine
.length() < 2) ) ||
113 ( _sLine
.startsWith("#")) ||
114 ( _sLine
.startsWith(";")) )
121 String
getItem(int i
)
123 return m_aList
.get(i
);
126 String
buildSectionName(String _sSectionName
)
128 String sFindSection
= "[" + _sSectionName
+ "]";
131 String
toLowerIfNeed(String _sName
)
133 return _sName
.toLowerCase();
136 // return the number where this section starts
137 int findSection(String _sSection
)
139 String sFindSection
= toLowerIfNeed(buildSectionName(_sSection
));
140 // ----------- find _sSection ---------------
142 for (i
=0; i
<m_aList
.size();i
++)
144 String sLine
= toLowerIfNeed(getItem(i
).trim());
149 if (sFindSection
.equals("[]"))
151 // special case, empty Section.
154 if (sLine
.startsWith(sFindSection
))
162 // return the line number, where the key is found.
163 int findKey(String _sSection
, String _sKey
)
165 int i
= findSection(_sSection
);
168 // Section not found, therefore the value can't exist
171 return findKeyFromKnownSection(i
, _sKey
);
174 // i must be the index in the list, where the well known section starts
175 int findKeyFromKnownSection(int _nSectionIndex
, String _sKey
)
177 _sKey
= toLowerIfNeed(_sKey
);
178 for (int j
=_nSectionIndex
+ 1; j
<m_aList
.size();j
++)
180 String sLine
= getItem(j
).trim();
187 if (sLine
.startsWith("[") /* && sLine.endsWith("]") */)
193 int nEqual
= sLine
.indexOf("=");
196 String sKey
= toLowerIfNeed(sLine
.substring(0, nEqual
).trim());
197 if (sKey
.equals(_sKey
))
206 // i must be the index in the list, where the well known section starts
207 int findLastKnownKeyIndex(int _nSectionIndex
, String _sKey
)
209 _sKey
= toLowerIfNeed(_sKey
);
210 int i
= _nSectionIndex
+ 1;
211 for (int j
=i
; j
<m_aList
.size();j
++)
213 String sLine
= getItem(j
).trim();
220 if (sLine
.startsWith("[") /* && sLine.endsWith("]") */)
226 int nEqual
= sLine
.indexOf("=");
229 String sKey
= toLowerIfNeed(sLine
.substring(0, nEqual
).trim());
230 if (sKey
.equals(_sKey
))
239 String
getValue(int _nIndex
)
241 String sLine
= getItem(_nIndex
).trim();
246 int nEqual
= sLine
.indexOf("=");
249 sLine
.substring(0, nEqual
).trim();
250 String sValue
= sLine
.substring(nEqual
+ 1).trim();
257 @param _sSection string
259 @return the value found in the inifile which is given by the section and key parameter
261 public String
getValue(String _sSection
, String _sKey
)
264 int i
= findKey(_sSection
, _sKey
);
267 // Section not found, therefore the value can't exist
271 sValue
= getValue(i
);
277 write back the ini file to the disk, only if there exist changes
281 if (m_bListContainUnsavedChanges
== false)
283 // nothing has changed, so no need to store
287 File aFile
= new File(m_sFilename
);
290 // System.out.println("couldn't find file " + m_sFilename);
294 GlobalLogWriter
.get().println("Couldn't delete the file " + m_sFilename
);
296 // DebugHelper.exception(BasicErrorCode.SbERR_INTERNAL_ERROR, "Couldn't delete the file " + m_sFilename);
299 // if (! aFile.canWrite())
301 // System.out.println("Couldn't write to file " + m_sFilename);
302 // DebugHelper.exception(BasicErrorCode.SbERR_INTERNAL_ERROR, "");
306 RandomAccessFile aWriter
= new RandomAccessFile(aFile
, "rw");
307 for (int i
=0; i
<m_aList
.size();i
++)
309 String sLine
= getItem(i
);
310 aWriter
.writeBytes(sLine
);
311 aWriter
.writeByte('\n');
316 catch (java
.io
.FileNotFoundException fne
)
318 GlobalLogWriter
.get().println("couldn't open file for writing " + m_sFilename
);
319 GlobalLogWriter
.get().println("Message: " + fne
.getMessage());
320 // DebugHelper.exception(BasicErrorCode.SbERR_FILE_NOT_FOUND, "");
322 catch(java
.io
.IOException ie
)
324 GlobalLogWriter
.get().println("Exception occurs while writing to file " + m_sFilename
);
325 GlobalLogWriter
.get().println("Message: " + ie
.getMessage());
326 // DebugHelper.exception(BasicErrorCode.SbERR_INTERNAL_ERROR, ie.getMessage());
335 1. section doesn't exist, goto end and insert a new section, insert a new key value pair
336 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
337 3. section exist and key exist, remove the old key and insert the key value pair at the same position
339 public void insertValue(String _sSection
, String _sKey
, String _sValue
)
341 int i
= findSection(_sSection
);
344 // case 1: section doesn't exist
345 String sFindSection
= buildSectionName(_sSection
);
347 m_aList
.add(sFindSection
);
348 String sKeyValuePair
= _sKey
+ "=" + _sValue
;
349 m_aList
.add(sKeyValuePair
);
350 m_bListContainUnsavedChanges
= true;
353 int j
= findKeyFromKnownSection(i
, _sKey
);
356 // case 2: section exist, but not the key
357 j
= findLastKnownKeyIndex(i
, _sKey
);
358 String sKeyValuePair
= _sKey
+ "=" + _sValue
;
359 m_aList
.add(j
, sKeyValuePair
);
360 m_bListContainUnsavedChanges
= true;
365 // case 3: section exist, and also the key
366 String sKeyValuePair
= _sKey
+ "=" + _sValue
;
367 m_aList
.set(j
, sKeyValuePair
);
368 m_bListContainUnsavedChanges
= true;
371 // -----------------------------------------------------------------------------
372 // String replaceEvaluatedValue(String _sSection, String _sValue)
374 // String sValue = _sValue;
376 // while (( nIndex = sValue.indexOf("$(", nIndex)) >= 0)
378 // int nNextIndex = sValue.indexOf(")", nIndex);
379 // if (nNextIndex >= 0)
381 // String sKey = sValue.substring(nIndex + 2, nNextIndex);
382 // String sNewValue = getValue(_sSection, sKey);
383 // if (sNewValue != null && sNewValue.length() > 0)
385 // String sRegexpKey = "\\$\\(" + sKey + "\\)";
386 // sValue = sValue.replaceAll(sRegexpKey, sNewValue);
388 // nIndex = nNextIndex;
397 // -----------------------------------------------------------------------------
399 // public String getLocalEvaluatedValue(String _sSection, String _sKey)
401 // String sValue = getValue(_sSection, _sKey);
402 // sValue = replaceEvaluatedValue(_sSection, sValue);
406 // -----------------------------------------------------------------------------
408 // this is a special behaviour.
409 // public String getGlobalLocalEvaluatedValue(String _sSection, String _sKey)
411 // String sGlobalValue = getKey("global", _sKey);
412 // String sLocalValue = getKey(_sSection, _sKey);
413 // if (sLocalValue.length() == 0)
415 // sGlobalValue = replaceEvaluatedKey(_sSection, sGlobalValue);
416 // sGlobalValue = replaceEvaluatedKey("global", sGlobalValue);
417 // return sGlobalValue;
419 // sLocalValue = replaceEvaluatedKey(_sSection, sLocalValue);
420 // sLocalValue = replaceEvaluatedKey("global", sLocalValue);
422 // return sLocalValue;
427 * some tests for this class
429 // public static void main(String[] args)
431 // IniFile aIniFile = new IniFile("/tmp/inifile");
432 // String sValue = aIniFile.getValue("Section","Key");
433 // // insert a new value to a already exist section
434 // aIniFile.insertValue("Section","Key2","a new value in a existing section");
435 // // replace a value
436 // aIniFile.insertValue("Section","Key","replaced value");
437 // // create a new value
438 // aIniFile.insertValue("New Section", "Key", "a new key value pair");
440 // String sValue2 = aIniFile.getValue("Section2","Key");