merge the formfield patch from ooo-build
[ooovba.git] / qadevOOo / runner / graphical / IniFile.java
blob6b13715751d7b4c679df32f701cda62642d03b5b
1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: IniFile.java,v $
10 * $Revision: 1.1.2.5 $
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 ************************************************************************/
30 package graphical;
32 import java.io.BufferedReader;
33 import java.io.File;
34 import java.io.RandomAccessFile;
35 import java.util.ArrayList;
36 import java.util.Enumeration;
38 /**
39 Helper class to give a simple API to read/write windows like ini files
41 /* public */ // is only need, if we need this class outside package convwatch
42 public class IniFile implements Enumeration
45 /**
46 * internal representation of the ini file content.
47 * Problem, if ini file changed why other write something difference, we don't realise this.
49 private String m_sFilename;
50 private ArrayList m_aList;
51 boolean m_bListContainUnsavedChanges = false;
52 private int m_aEnumerationPos = 0;
54 /**
55 open a ini file by it's name
56 @param _sFilename string a filename, if the file doesn't exist, a new empty ini file will create.
57 write back to disk only if there are really changes.
59 public IniFile(String _sFilename)
61 m_sFilename = _sFilename;
62 m_aList = loadLines();
63 m_aEnumerationPos = findNextSection(0);
64 // if (_sFilename.endsWith(".odb.ps.ini"))
65 // {
66 // int dummy = 0;
67 // }
70 public void insertFirstComment(String[] _aList)
72 if (m_aList.size() == 0)
74 // can only insert if there is nothing else already in the ini file
75 for (int i = 0; i < _aList.length; i++)
77 m_aList.add(_aList[i]);
82 private ArrayList loadLines()
84 File aFile = new File(m_sFilename);
85 ArrayList aLines = new ArrayList();
86 if (!aFile.exists())
88 GlobalLogWriter.get().println("couldn't find file '" + m_sFilename + "', will be created.");
89 // DebugHelper.exception(BasicErrorCode.SbERR_FILE_NOT_FOUND, "");
90 // m_bListContainUnsavedChanges = false;
91 return aLines;
93 RandomAccessFile aReader = null;
94 // BufferedReader aReader;
95 try
97 aReader = new RandomAccessFile(aFile, "r");
98 String aLine = "";
99 while (aLine != null)
101 aLine = aReader.readLine();
102 if (aLine != null && aLine.length() > 0)
104 aLines.add(aLine);
108 catch (java.io.FileNotFoundException fne)
110 GlobalLogWriter.get().println("couldn't open file " + m_sFilename);
111 GlobalLogWriter.get().println("Message: " + fne.getMessage());
112 // DebugHelper.exception(BasicErrorCode.SbERR_FILE_NOT_FOUND, "");
114 catch (java.io.IOException ie)
116 GlobalLogWriter.get().println("Exception occurs while reading from file " + m_sFilename);
117 GlobalLogWriter.get().println("Message: " + ie.getMessage());
118 // DebugHelper.exception(BasicErrorCode.SbERR_INTERNAL_ERROR, ie.getMessage());
122 aReader.close();
124 catch (java.io.IOException ie)
126 GlobalLogWriter.get().println("Couldn't close file " + m_sFilename);
127 GlobalLogWriter.get().println("Message: " + ie.getMessage());
128 // DebugHelper.exception(BasicErrorCode.SbERR_INTERNAL_ERROR, ie.getMessage());
130 return aLines;
134 * @return true, if the ini file contain some readable data
136 public boolean is()
138 return m_aList.size() > 1 ? true : false;
142 * Check if a given Section and Key exists in the ini file
143 * @param _sSectionName
144 * @param _sKey
145 * @return true if the given Section, Key exists, now you can get the value
147 public boolean hasValue(String _sSectionName, String _sKey)
149 int n = findKey(_sSectionName, _sKey);
150 if (n > 0)
152 return true;
154 return false;
156 // -----------------------------------------------------------------------------
158 private boolean isRemark(String _sLine)
160 if (((_sLine.length() < 2)) ||
161 (_sLine.startsWith("#")) ||
162 (_sLine.startsWith(";")))
164 return true;
166 return false;
169 private String getItem(int i)
171 return (String) m_aList.get(i);
174 private String buildSectionName(String _sSectionName)
176 String sFindSection = "[" + _sSectionName + "]";
177 return sFindSection;
180 private String sectionToString(String _sSectionName)
182 String sKeyName = _sSectionName;
183 if (sKeyName.startsWith("[") &&
184 sKeyName.endsWith("]"))
186 sKeyName = sKeyName.substring(1, sKeyName.length() - 1);
188 return sKeyName;
191 private String toLowerIfNeed(String _sName)
193 return _sName.toLowerCase();
196 // return the number where this section starts
197 private int findSection(String _sSection)
199 String sFindSection = toLowerIfNeed(buildSectionName(_sSection));
200 // ----------- find _sSection ---------------
201 int i;
202 for (i = 0; i < m_aList.size(); i++)
204 String sLine = toLowerIfNeed(getItem(i).trim());
205 if (isRemark(sLine))
207 continue;
209 if (sFindSection.equals("[]"))
211 // special case, empty Section.
212 return i - 1;
214 if (sLine.startsWith(sFindSection))
216 return i;
219 return -1;
223 * Checks if a given section exists in the ini file
224 * @param _sSection
225 * @return true if the given _sSection was found
227 public boolean hasSection(String _sSection)
229 int i = findSection(_sSection);
230 if (i == -1)
232 return false;
234 return true;
237 // return the line number, where the key is found.
238 private int findKey(String _sSection, String _sKey)
240 int i = findSection(_sSection);
241 if (i == -1)
243 // Section not found, therefore the value can't exist
244 return -1;
246 return findKeyFromKnownSection(i, _sKey);
249 // i must be the index in the list, where the well known section starts
250 private int findKeyFromKnownSection(int _nSectionIndex, String _sKey)
252 _sKey = toLowerIfNeed(_sKey);
253 for (int j = _nSectionIndex + 1; j < m_aList.size(); j++)
255 String sLine = getItem(j).trim();
257 if (isRemark(sLine))
259 continue;
261 if (sLine.startsWith("[") /* && sLine.endsWith("]") */)
263 // TODO: due to the fact we would like to insert an empty line before new sections
264 // TODO: we should check if we are in an empty line and if, go back one line.
266 // found end.
267 break;
270 int nEqual = sLine.indexOf("=");
271 if (nEqual >= 0)
273 String sKey = toLowerIfNeed(sLine.substring(0, nEqual).trim());
274 if (sKey.equals(_sKey))
276 return j;
280 return -1;
283 // i must be the index in the list, where the well known section starts
284 private int findLastKnownKeyIndex(int _nSectionIndex, String _sKey)
286 _sKey = toLowerIfNeed(_sKey);
287 int i = _nSectionIndex + 1;
288 for (int j = i; j < m_aList.size(); j++)
290 String sLine = getItem(j).trim();
292 if (isRemark(sLine))
294 continue;
297 if (sLine.startsWith("[") /* && sLine.endsWith("]") */)
299 // found end.
300 return j;
303 int nEqual = sLine.indexOf("=");
304 if (nEqual >= 0)
306 String sKey = toLowerIfNeed(sLine.substring(0, nEqual).trim());
307 if (sKey.equals(_sKey))
309 return j;
313 return i;
316 private String getValue(int _nIndex)
318 String sLine = getItem(_nIndex).trim();
319 if (isRemark(sLine))
321 return "";
323 int nEqual = sLine.indexOf("=");
324 if (nEqual >= 0)
326 String sKey = sLine.substring(0, nEqual).trim();
327 String sValue = sLine.substring(nEqual + 1).trim();
328 return sValue;
330 return "";
334 @param _sSection string
335 @param _sKey string
336 @return the value found in the inifile which is given by the section and key parameter
338 // private int m_nCurrentPosition;
339 // private String m_sOldKey;
340 public String getValue(String _sSection, String _sKey)
342 String sValue = "";
343 int m_nCurrentPosition = findKey(_sSection, _sKey);
344 if (m_nCurrentPosition == -1)
346 // Section not found, therefore the value can't exist
347 return "";
350 // m_sOldKey = _sKey;
351 sValue = getValue(m_nCurrentPosition);
353 return sValue;
356 // private String getNextValue()
357 // {
358 // if (m_nCurrentPosition >= 0)
359 // {
360 // ++m_nCurrentPosition;
361 // String sValue = getValue(m_nCurrentPosition);
362 // return sValue;
363 // }
364 // return "";
365 // }
367 * Returns the value at Section, Key converted to an integer
368 * Check with hasValue(Section, Key) to check before you get into trouble.
369 * @param _sSection
370 * @param _sKey
371 * @param _nDefault if there is a problem, key not found... this value will return
372 * @return
374 public int getIntValue(String _sSection, String _sKey, int _nDefault)
376 String sValue = getValue(_sSection, _sKey);
377 int nValue = _nDefault;
378 if (sValue.length() > 0)
382 nValue = Integer.valueOf(sValue).intValue();
384 catch (java.lang.NumberFormatException e)
386 GlobalLogWriter.get().println("IniFile.getIntValue(): Caught a number format exception, return the default value.");
389 return nValue;
392 public void close()
394 store();
398 write back the ini file to the disk, only if there exist changes
399 * @deprecated use close() instead!
401 public void store()
403 if (m_bListContainUnsavedChanges == false)
405 // nothing has changed, so no need to store
406 return;
409 File aFile = new File(m_sFilename);
410 if (aFile.exists())
412 // System.out.println("couldn't find file " + m_sFilename);
413 // TODO: little bit unsafe here, first rename, after write is complete, delete the old.
414 aFile.delete();
415 if (aFile.exists())
417 GlobalLogWriter.get().println("Couldn't delete the file " + m_sFilename);
418 return;
419 // DebugHelper.exception(BasicErrorCode.SbERR_INTERNAL_ERROR, "Couldn't delete the file " + m_sFilename);
422 // if (! aFile.canWrite())
423 // {
424 // System.out.println("Couldn't write to file " + m_sFilename);
425 // DebugHelper.exception(BasicErrorCode.SbERR_INTERNAL_ERROR, "");
426 // }
429 RandomAccessFile aWriter = new RandomAccessFile(aFile, "rw");
430 for (int i = 0; i < m_aList.size(); i++)
432 String sLine = getItem(i);
433 if (sLine.startsWith("["))
435 // write an extra empty line before next section.
436 aWriter.writeByte((int) '\n');
438 aWriter.writeBytes(sLine);
439 aWriter.writeByte((int) '\n');
441 aWriter.close();
443 catch (java.io.FileNotFoundException fne)
445 GlobalLogWriter.get().println("couldn't open file for writing " + m_sFilename);
446 GlobalLogWriter.get().println("Message: " + fne.getMessage());
447 // DebugHelper.exception(BasicErrorCode.SbERR_FILE_NOT_FOUND, "");
449 catch (java.io.IOException ie)
451 GlobalLogWriter.get().println("Exception occurs while writing to file " + m_sFilename);
452 GlobalLogWriter.get().println("Message: " + ie.getMessage());
453 // DebugHelper.exception(BasicErrorCode.SbERR_INTERNAL_ERROR, ie.getMessage());
457 public void insertValue(String _sSection, String _sKey, int _nValue)
459 insertValue(_sSection, _sKey, String.valueOf(_nValue));
462 public void insertValue(String _sSection, String _sKey, long _nValue)
464 insertValue(_sSection, _sKey, String.valueOf(_nValue));
468 insert a value
469 there are 3 cases
470 1. section doesn't exist, goto end and insert a new section, insert a new key value pair
471 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
472 3. section exist and key exist, remove the old key and insert the key value pair at the same position
474 public void insertValue(String _sSection, String _sKey, String _sValue)
476 int i = findSection(_sSection);
477 if (i == -1)
479 // case 1: section doesn't exist
480 String sFindSection = buildSectionName(_sSection);
482 // TODO: before create a new Section, insert a empty line
483 m_aList.add(sFindSection);
484 if (_sKey.length() > 0)
486 String sKeyValuePair = _sKey + "=" + _sValue;
487 m_aList.add(sKeyValuePair);
489 m_bListContainUnsavedChanges = true;
490 return;
492 int j = findKeyFromKnownSection(i, _sKey);
493 if (j == -1)
495 // case 2: section exist, but not the key
496 j = findLastKnownKeyIndex(i, _sKey);
497 if (_sKey.length() > 0)
499 String sKeyValuePair = _sKey + "=" + _sValue;
500 m_aList.add(j, sKeyValuePair);
501 m_bListContainUnsavedChanges = true;
503 return;
505 else
507 // case 3: section exist, and also the key
508 String sKeyValuePair = _sKey + "=" + _sValue;
509 m_aList.set(j, sKeyValuePair);
510 m_bListContainUnsavedChanges = true;
513 // -----------------------------------------------------------------------------
514 // String replaceEvaluatedValue(String _sSection, String _sValue)
515 // {
516 // String sValue = _sValue;
517 // int nIndex = 0;
518 // while (( nIndex = sValue.indexOf("$(", nIndex)) >= 0)
519 // {
520 // int nNextIndex = sValue.indexOf(")", nIndex);
521 // if (nNextIndex >= 0)
522 // {
523 // String sKey = sValue.substring(nIndex + 2, nNextIndex);
524 // String sNewValue = getValue(_sSection, sKey);
525 // if (sNewValue != null && sNewValue.length() > 0)
526 // {
527 // String sRegexpKey = "\\$\\(" + sKey + "\\)";
528 // sValue = sValue.replaceAll(sRegexpKey, sNewValue);
529 // }
530 // nIndex = nNextIndex;
531 // }
532 // else
533 // {
534 // nIndex += 2;
535 // }
536 // }
537 // return sValue;
538 // }
539 // -----------------------------------------------------------------------------
541 // public String getLocalEvaluatedValue(String _sSection, String _sKey)
542 // {
543 // String sValue = getValue(_sSection, _sKey);
544 // sValue = replaceEvaluatedValue(_sSection, sValue);
545 // return sValue;
546 // }
548 // -----------------------------------------------------------------------------
550 // this is a special behaviour.
551 // public String getGlobalLocalEvaluatedValue(String _sSection, String _sKey)
552 // {
553 // String sGlobalValue = getKey("global", _sKey);
554 // String sLocalValue = getKey(_sSection, _sKey);
555 // if (sLocalValue.length() == 0)
556 // {
557 // sGlobalValue = replaceEvaluatedKey(_sSection, sGlobalValue);
558 // sGlobalValue = replaceEvaluatedKey("global", sGlobalValue);
559 // return sGlobalValue;
560 // }
561 // sLocalValue = replaceEvaluatedKey(_sSection, sLocalValue);
562 // sLocalValue = replaceEvaluatedKey("global", sLocalValue);
564 // return sLocalValue;
565 // }
566 public void removeSection(String _sSectionToRemove)
568 // first, search for the name
569 int i = findSection(_sSectionToRemove);
570 if (i == -1)
572 // Section to remove not found, do nothing.
573 return;
575 // second, find the next section
576 int j = findNextSection(i + 1);
577 if (j == -1)
579 // if we are at the end, use size() as second section
580 j = m_aList.size();
582 // remove all between first and second section
583 for (int k = i; k < j; k++)
585 m_aList.remove(i);
587 // mark the list as changed
588 m_bListContainUnsavedChanges = true;
592 * some tests for this class
594 public static void main(String[] args)
596 String sTempFile = System.getProperty("java.io.tmpdir");
597 sTempFile += "inifile";
600 IniFile aIniFile = new IniFile(sTempFile);
601 String sValue = aIniFile.getValue("Section", "Key");
602 // insert a new value to a already exist section
603 aIniFile.insertValue("Section", "Key2", "a new value in a existing section");
604 // replace a value
605 aIniFile.insertValue("Section", "Key", "replaced value");
606 // create a new value
607 aIniFile.insertValue("New Section", "Key", "a new key value pair");
608 aIniFile.insertValue("New Section", "Key2", "a new second key value pair");
610 String sValue2 = aIniFile.getValue("Section2", "Key");
612 aIniFile.removeSection("Section");
613 aIniFile.removeSection("New Section");
615 aIniFile.close();
619 * Enumeration Interface
620 * @return true, if there are more Key values
622 public boolean hasMoreElements()
624 if (m_aEnumerationPos >= 0 &&
625 m_aEnumerationPos < m_aList.size())
627 return true;
629 return false;
633 * Find the next line, which starts with '['
634 * @param i start position
635 * @return the line where '[' found or -1
637 private int findNextSection(int i)
639 if (i >= 0)
641 while (i < m_aList.size())
643 String sLine = (String) m_aList.get(i);
644 if (sLine.startsWith("["))
646 return i;
648 i++;
651 return -1;
655 * Enumeration Interface
656 * @return a key without the enveloped '[' ']'
658 public Object nextElement()
660 int nLineWithSection = findNextSection(m_aEnumerationPos);
661 if (nLineWithSection != -1)
663 String sSection = (String) m_aList.get(nLineWithSection);
664 m_aEnumerationPos = findNextSection(nLineWithSection + 1);
665 sSection = sectionToString(sSection);
666 return sSection;
668 else
670 m_aEnumerationPos = m_aList.size();
672 return null;
676 * Helper to count the occurence of Sections
677 * @return returns the count of '^['.*']$' Elements
679 public int getElementCount()
681 int nCount = 0;
682 int nPosition = 0;
683 while ((nPosition = findNextSection(nPosition)) != -1)
685 nCount++;
686 nPosition++;
688 return nCount;