1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: IniFile.java,v $
12 * This file is part of OpenOffice.org.
14 * OpenOffice.org is free software: you can redistribute it and/or modify
15 * it under the terms of the GNU Lesser General Public License version 3
16 * only, as published by the Free Software Foundation.
18 * OpenOffice.org is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU Lesser General Public License version 3 for more details
22 * (a copy is included in the LICENSE file that accompanied this code).
24 * You should have received a copy of the GNU Lesser General Public License
25 * version 3 along with OpenOffice.org. If not, see
26 * <http://www.openoffice.org/license.html>
27 * for a copy of the LGPLv3 License.
29 ************************************************************************/
34 import java
.io
.RandomAccessFile
;
35 import java
.util
.ArrayList
;
38 Helper class to give a simple API to read/write windows like ini files
40 /* public */ // is only need, if we need this class outside package convwatch
44 * internal representation of the ini file content.
45 * Problem, if ini file changed why other write something difference, we don't realise this.
49 boolean m_bListContainUnsavedChanges
= false;
52 open a ini file by it's name
53 @param _sFilename string a filename, if the file doesn't exist, a new empty ini file will create.
54 write back to disk only if there are really changes.
56 public IniFile(String _sFilename
)
58 m_sFilename
= _sFilename
;
59 m_aList
= loadLines();
64 File aFile
= new File(m_sFilename
);
65 ArrayList aLines
= new ArrayList();
68 GlobalLogWriter
.get().println("couldn't find file " + m_sFilename
);
69 // DebugHelper.exception(BasicErrorCode.SbERR_FILE_NOT_FOUND, "");
70 // m_bListContainUnsavedChanges = false;
73 RandomAccessFile aReader
= null;
76 aReader
= new RandomAccessFile(aFile
,"r");
80 aLine
= aReader
.readLine();
87 catch (java
.io
.FileNotFoundException fne
)
89 GlobalLogWriter
.get().println("couldn't open file " + m_sFilename
);
90 GlobalLogWriter
.get().println("Message: " + fne
.getMessage());
91 // DebugHelper.exception(BasicErrorCode.SbERR_FILE_NOT_FOUND, "");
93 catch (java
.io
.IOException ie
)
95 GlobalLogWriter
.get().println("Exception occurs while reading from file " + m_sFilename
);
96 GlobalLogWriter
.get().println("Message: " + ie
.getMessage());
97 // DebugHelper.exception(BasicErrorCode.SbERR_INTERNAL_ERROR, ie.getMessage());
103 catch (java
.io
.IOException ie
)
105 GlobalLogWriter
.get().println("Couldn't close file " + m_sFilename
);
106 GlobalLogWriter
.get().println("Message: " + ie
.getMessage());
107 // DebugHelper.exception(BasicErrorCode.SbERR_INTERNAL_ERROR, ie.getMessage());
113 * @return true, if the ini file contain some readable data
117 return m_aList
.size() > 1 ?
true : false;
120 // -----------------------------------------------------------------------------
122 boolean isRemark(String _sLine
)
124 if ( ((_sLine
.length() < 2) ) ||
125 ( _sLine
.startsWith("#")) ||
126 ( _sLine
.startsWith(";")) )
133 String
getItem(int i
)
135 return (String
)m_aList
.get(i
);
138 String
buildSectionName(String _sSectionName
)
140 String sFindSection
= "[" + _sSectionName
+ "]";
143 String
toLowerIfNeed(String _sName
)
145 return _sName
.toLowerCase();
148 // return the number where this section starts
149 int findSection(String _sSection
)
151 String sFindSection
= toLowerIfNeed(buildSectionName(_sSection
));
152 // ----------- find _sSection ---------------
154 for (i
=0; i
<m_aList
.size();i
++)
156 String sLine
= toLowerIfNeed(getItem(i
).trim());
161 if (sFindSection
.equals("[]"))
163 // special case, empty Section.
166 if (sLine
.startsWith(sFindSection
))
174 // return the line number, where the key is found.
175 int findKey(String _sSection
, String _sKey
)
177 int i
= findSection(_sSection
);
180 // Section not found, therefore the value can't exist
183 return findKeyFromKnownSection(i
, _sKey
);
186 // i must be the index in the list, where the well known section starts
187 int findKeyFromKnownSection(int _nSectionIndex
, String _sKey
)
189 _sKey
= toLowerIfNeed(_sKey
);
190 for (int j
=_nSectionIndex
+ 1; j
<m_aList
.size();j
++)
192 String sLine
= getItem(j
).trim();
199 if (sLine
.startsWith("[") /* && sLine.endsWith("]") */)
205 int nEqual
= sLine
.indexOf("=");
208 String sKey
= toLowerIfNeed(sLine
.substring(0, nEqual
).trim());
209 if (sKey
.equals(_sKey
))
218 // i must be the index in the list, where the well known section starts
219 int findLastKnownKeyIndex(int _nSectionIndex
, String _sKey
)
221 _sKey
= toLowerIfNeed(_sKey
);
222 int i
= _nSectionIndex
+ 1;
223 for (int j
=i
; j
<m_aList
.size();j
++)
225 String sLine
= getItem(j
).trim();
232 if (sLine
.startsWith("[") /* && sLine.endsWith("]") */)
238 int nEqual
= sLine
.indexOf("=");
241 String sKey
= toLowerIfNeed(sLine
.substring(0, nEqual
).trim());
242 if (sKey
.equals(_sKey
))
251 String
getValue(int _nIndex
)
253 String sLine
= getItem(_nIndex
).trim();
258 int nEqual
= sLine
.indexOf("=");
261 String sKey
= sLine
.substring(0, nEqual
).trim();
262 String sValue
= sLine
.substring(nEqual
+ 1).trim();
269 @param _sSection string
271 @return the value found in the inifile which is given by the section and key parameter
273 public String
getValue(String _sSection
, String _sKey
)
276 int i
= findKey(_sSection
, _sKey
);
279 // Section not found, therefore the value can't exist
283 sValue
= getValue(i
);
289 write back the ini file to the disk, only if there exist changes
293 if (m_bListContainUnsavedChanges
== false)
295 // nothing has changed, so no need to store
299 File aFile
= new File(m_sFilename
);
302 // System.out.println("couldn't find file " + m_sFilename);
306 GlobalLogWriter
.get().println("Couldn't delete the file " + m_sFilename
);
308 // DebugHelper.exception(BasicErrorCode.SbERR_INTERNAL_ERROR, "Couldn't delete the file " + m_sFilename);
311 // if (! aFile.canWrite())
313 // System.out.println("Couldn't write to file " + m_sFilename);
314 // DebugHelper.exception(BasicErrorCode.SbERR_INTERNAL_ERROR, "");
318 RandomAccessFile aWriter
= new RandomAccessFile(aFile
, "rw");
319 for (int i
=0; i
<m_aList
.size();i
++)
321 String sLine
= getItem(i
);
322 aWriter
.writeBytes(sLine
);
323 aWriter
.writeByte((int)'\n');
328 catch (java
.io
.FileNotFoundException fne
)
330 GlobalLogWriter
.get().println("couldn't open file for writing " + m_sFilename
);
331 GlobalLogWriter
.get().println("Message: " + fne
.getMessage());
332 // DebugHelper.exception(BasicErrorCode.SbERR_FILE_NOT_FOUND, "");
334 catch(java
.io
.IOException ie
)
336 GlobalLogWriter
.get().println("Exception occurs while writing to file " + m_sFilename
);
337 GlobalLogWriter
.get().println("Message: " + ie
.getMessage());
338 // DebugHelper.exception(BasicErrorCode.SbERR_INTERNAL_ERROR, ie.getMessage());
347 1. section doesn't exist, goto end and insert a new section, insert a new key value pair
348 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
349 3. section exist and key exist, remove the old key and insert the key value pair at the same position
351 public void insertValue(String _sSection
, String _sKey
, String _sValue
)
353 int i
= findSection(_sSection
);
356 // case 1: section doesn't exist
357 String sFindSection
= buildSectionName(_sSection
);
359 m_aList
.add(sFindSection
);
360 String sKeyValuePair
= _sKey
+ "=" + _sValue
;
361 m_aList
.add(sKeyValuePair
);
362 m_bListContainUnsavedChanges
= true;
365 int j
= findKeyFromKnownSection(i
, _sKey
);
368 // case 2: section exist, but not the key
369 j
= findLastKnownKeyIndex(i
, _sKey
);
370 String sKeyValuePair
= _sKey
+ "=" + _sValue
;
371 m_aList
.add(j
, sKeyValuePair
);
372 m_bListContainUnsavedChanges
= true;
377 // case 3: section exist, and also the key
378 String sKeyValuePair
= _sKey
+ "=" + _sValue
;
379 m_aList
.set(j
, sKeyValuePair
);
380 m_bListContainUnsavedChanges
= true;
383 // -----------------------------------------------------------------------------
384 // String replaceEvaluatedValue(String _sSection, String _sValue)
386 // String sValue = _sValue;
388 // while (( nIndex = sValue.indexOf("$(", nIndex)) >= 0)
390 // int nNextIndex = sValue.indexOf(")", nIndex);
391 // if (nNextIndex >= 0)
393 // String sKey = sValue.substring(nIndex + 2, nNextIndex);
394 // String sNewValue = getValue(_sSection, sKey);
395 // if (sNewValue != null && sNewValue.length() > 0)
397 // String sRegexpKey = "\\$\\(" + sKey + "\\)";
398 // sValue = sValue.replaceAll(sRegexpKey, sNewValue);
400 // nIndex = nNextIndex;
409 // -----------------------------------------------------------------------------
411 // public String getLocalEvaluatedValue(String _sSection, String _sKey)
413 // String sValue = getValue(_sSection, _sKey);
414 // sValue = replaceEvaluatedValue(_sSection, sValue);
418 // -----------------------------------------------------------------------------
420 // this is a special behaviour.
421 // public String getGlobalLocalEvaluatedValue(String _sSection, String _sKey)
423 // String sGlobalValue = getKey("global", _sKey);
424 // String sLocalValue = getKey(_sSection, _sKey);
425 // if (sLocalValue.length() == 0)
427 // sGlobalValue = replaceEvaluatedKey(_sSection, sGlobalValue);
428 // sGlobalValue = replaceEvaluatedKey("global", sGlobalValue);
429 // return sGlobalValue;
431 // sLocalValue = replaceEvaluatedKey(_sSection, sLocalValue);
432 // sLocalValue = replaceEvaluatedKey("global", sLocalValue);
434 // return sLocalValue;
439 * some tests for this class
441 public static void main(String
[] args
)
443 IniFile aIniFile
= new IniFile("/tmp/inifile");
444 String sValue
= aIniFile
.getValue("Section","Key");
445 // insert a new value to a already exist section
446 aIniFile
.insertValue("Section","Key2","a new value in a existing section");
448 aIniFile
.insertValue("Section","Key","replaced value");
449 // create a new value
450 aIniFile
.insertValue("New Section", "Key", "a new key value pair");
452 String sValue2
= aIniFile
.getValue("Section2","Key");