merged tag ooo/DEV300_m102
[LibreOffice.git] / qadevOOo / runner / graphical / IniFile.java
blobbd54a66b65fd799cf8be7a6a4d555c49f02c9412
1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 * Copyright 2000, 2010 Oracle and/or its affiliates.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * This file is part of OpenOffice.org.
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.
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).
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.
26 ************************************************************************/
27 package graphical;
29 // import java.io.BufferedReader;
30 import java.io.File;
31 import java.io.RandomAccessFile;
32 import java.util.ArrayList;
33 import java.util.Enumeration;
35 /**
36 Helper class to give a simple API to read/write windows like ini files
38 /* public */ // is only need, if we need this class outside package convwatch
39 public class IniFile implements Enumeration
42 /**
43 * internal representation of the ini file content.
44 * Problem, if ini file changed why other write something difference, we don't realise this.
46 private String m_sFilename;
47 private ArrayList<String> m_aList;
48 boolean m_bListContainUnsavedChanges = false;
49 private int m_aEnumerationPos = 0;
51 /**
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();
60 m_aEnumerationPos = findNextSection(0);
61 // if (_sFilename.endsWith(".odb.ps.ini"))
62 // {
63 // int dummy = 0;
64 // }
67 public void insertFirstComment(String[] _aList)
69 if (m_aList.size() == 0)
71 // can only insert if there is nothing else already in the ini file
72 for (int i = 0; i < _aList.length; i++)
74 m_aList.add(_aList[i]);
79 private ArrayList<String> loadLines()
81 File aFile = new File(m_sFilename);
82 ArrayList<String> aLines = new ArrayList<String>();
83 if (!aFile.exists())
85 // GlobalLogWriter.println("couldn't find file '" + m_sFilename + "', will be created.");
86 // DebugHelper.exception(BasicErrorCode.SbERR_FILE_NOT_FOUND, "");
87 // m_bListContainUnsavedChanges = false;
88 return aLines;
90 RandomAccessFile aReader = null;
91 // BufferedReader aReader;
92 try
94 aReader = new RandomAccessFile(aFile, "r");
95 String aLine = "";
96 while (aLine != null)
98 aLine = aReader.readLine();
99 if (aLine != null && aLine.length() > 0)
101 aLines.add(aLine);
105 catch (java.io.FileNotFoundException fne)
107 GlobalLogWriter.println("couldn't open file " + m_sFilename);
108 GlobalLogWriter.println("Message: " + fne.getMessage());
109 // DebugHelper.exception(BasicErrorCode.SbERR_FILE_NOT_FOUND, "");
111 catch (java.io.IOException ie)
113 GlobalLogWriter.println("Exception occurs while reading from file " + m_sFilename);
114 GlobalLogWriter.println("Message: " + ie.getMessage());
115 // DebugHelper.exception(BasicErrorCode.SbERR_INTERNAL_ERROR, ie.getMessage());
119 aReader.close();
121 catch (java.io.IOException ie)
123 GlobalLogWriter.println("Couldn't close file " + m_sFilename);
124 GlobalLogWriter.println("Message: " + ie.getMessage());
125 // DebugHelper.exception(BasicErrorCode.SbERR_INTERNAL_ERROR, ie.getMessage());
127 return aLines;
131 * @return true, if the ini file contain some readable data
133 public boolean is()
135 return m_aList.size() > 1 ? true : false;
139 * Check if a given Section and Key exists in the ini file
140 * @param _sSectionName
141 * @param _sKey
142 * @return true if the given Section, Key exists, now you can get the value
144 public boolean hasValue(String _sSectionName, String _sKey)
146 int n = findKey(_sSectionName, _sKey);
147 if (n > 0)
149 return true;
151 return false;
153 // -----------------------------------------------------------------------------
155 private boolean isRemark(String _sLine)
157 if (((_sLine.length() < 2)) ||
158 (_sLine.startsWith("#")) ||
159 (_sLine.startsWith(";")))
161 return true;
163 return false;
166 private String getItem(int i)
168 return m_aList.get(i);
171 private String buildSectionName(String _sSectionName)
173 String sFindSection = "[" + _sSectionName + "]";
174 return sFindSection;
177 private String sectionToString(String _sSectionName)
179 String sKeyName = _sSectionName;
180 if (sKeyName.startsWith("[") &&
181 sKeyName.endsWith("]"))
183 sKeyName = sKeyName.substring(1, sKeyName.length() - 1);
185 return sKeyName;
188 private String toLowerIfNeed(String _sName)
190 return _sName.toLowerCase();
193 // return the number where this section starts
194 private int findSection(String _sSection)
196 String sFindSection = toLowerIfNeed(buildSectionName(_sSection));
197 // ----------- find _sSection ---------------
198 int i;
199 for (i = 0; i < m_aList.size(); i++)
201 String sLine = toLowerIfNeed(getItem(i).trim());
202 if (isRemark(sLine))
204 continue;
206 if (sFindSection.equals("[]"))
208 // special case, empty Section.
209 return i - 1;
211 if (sLine.startsWith(sFindSection))
213 return i;
216 return -1;
220 * Checks if a given section exists in the ini file
221 * @param _sSection
222 * @return true if the given _sSection was found
224 public boolean hasSection(String _sSection)
226 int i = findSection(_sSection);
227 if (i == -1)
229 return false;
231 return true;
234 // return the line number, where the key is found.
235 private int findKey(String _sSection, String _sKey)
237 int i = findSection(_sSection);
238 if (i == -1)
240 // Section not found, therefore the value can't exist
241 return -1;
243 return findKeyFromKnownSection(i, _sKey);
246 // i must be the index in the list, where the well known section starts
247 private int findKeyFromKnownSection(int _nSectionIndex, String _sKey)
249 _sKey = toLowerIfNeed(_sKey);
250 for (int j = _nSectionIndex + 1; j < m_aList.size(); j++)
252 String sLine = getItem(j).trim();
254 if (isRemark(sLine))
256 continue;
258 if (sLine.startsWith("[") /* && sLine.endsWith("]") */)
260 // TODO: due to the fact we would like to insert an empty line before new sections
261 // TODO: we should check if we are in an empty line and if, go back one line.
263 // found end.
264 break;
267 int nEqual = sLine.indexOf("=");
268 if (nEqual >= 0)
270 String sKey = toLowerIfNeed(sLine.substring(0, nEqual).trim());
271 if (sKey.equals(_sKey))
273 return j;
277 return -1;
280 // i must be the index in the list, where the well known section starts
281 private int findLastKnownKeyIndex(int _nSectionIndex, String _sKey)
283 _sKey = toLowerIfNeed(_sKey);
284 int i = _nSectionIndex + 1;
285 for (int j = i; j < m_aList.size(); j++)
287 String sLine = getItem(j).trim();
289 if (isRemark(sLine))
291 continue;
294 if (sLine.startsWith("[") /* && sLine.endsWith("]") */)
296 // found end.
297 return j;
300 int nEqual = sLine.indexOf("=");
301 if (nEqual >= 0)
303 String sKey = toLowerIfNeed(sLine.substring(0, nEqual).trim());
304 if (sKey.equals(_sKey))
306 return j;
310 return i;
313 private String getValue(int _nIndex)
315 String sLine = getItem(_nIndex).trim();
316 if (isRemark(sLine))
318 return "";
320 int nEqual = sLine.indexOf("=");
321 if (nEqual >= 0)
323 String sKey = sLine.substring(0, nEqual).trim();
324 String sValue = sLine.substring(nEqual + 1).trim();
325 return sValue;
327 return "";
331 @param _sSection string
332 @param _sKey string
333 @return the value found in the inifile which is given by the section and key parameter
335 // private int m_nCurrentPosition;
336 // private String m_sOldKey;
337 public String getValue(String _sSection, String _sKey)
339 String sValue = "";
340 int m_nCurrentPosition = findKey(_sSection, _sKey);
341 if (m_nCurrentPosition == -1)
343 // Section not found, therefore the value can't exist
344 return "";
347 // m_sOldKey = _sKey;
348 sValue = getValue(m_nCurrentPosition);
350 return sValue;
353 // private String getNextValue()
354 // {
355 // if (m_nCurrentPosition >= 0)
356 // {
357 // ++m_nCurrentPosition;
358 // String sValue = getValue(m_nCurrentPosition);
359 // return sValue;
360 // }
361 // return "";
362 // }
364 * Returns the value at Section, Key converted to an integer
365 * Check with hasValue(Section, Key) to check before you get into trouble.
366 * @param _sSection
367 * @param _sKey
368 * @param _nDefault if there is a problem, key not found... this value will return
369 * @return
371 public int getIntValue(String _sSection, String _sKey, int _nDefault)
373 String sValue = getValue(_sSection, _sKey);
374 int nValue = _nDefault;
375 if (sValue.length() > 0)
379 nValue = Integer.valueOf(sValue).intValue();
381 catch (java.lang.NumberFormatException e)
383 GlobalLogWriter.println("IniFile.getIntValue(): Caught a number format exception, return the default value.");
386 return nValue;
389 public void close()
391 store();
395 write back the ini file to the disk, only if there exist changes
396 * @deprecated use close() instead!
399 // TODO: make private
400 public void store()
402 if (m_bListContainUnsavedChanges == false)
404 // nothing has changed, so no need to store
405 return;
408 File aFile = new File(m_sFilename);
409 if (aFile.exists())
411 // System.out.println("couldn't find file " + m_sFilename);
412 // TODO: little bit unsafe here, first rename, after write is complete, delete the old.
413 aFile.delete();
414 if (aFile.exists())
416 GlobalLogWriter.println("Couldn't delete the file " + m_sFilename);
417 return;
418 // DebugHelper.exception(BasicErrorCode.SbERR_INTERNAL_ERROR, "Couldn't delete the file " + m_sFilename);
421 // if (! aFile.canWrite())
422 // {
423 // System.out.println("Couldn't write to file " + m_sFilename);
424 // DebugHelper.exception(BasicErrorCode.SbERR_INTERNAL_ERROR, "");
425 // }
428 RandomAccessFile aWriter = new RandomAccessFile(aFile, "rw");
429 for (int i = 0; i < m_aList.size(); i++)
431 String sLine = getItem(i);
432 if (sLine.startsWith("["))
434 // write an extra empty line before next section.
435 aWriter.writeByte((int) '\n');
437 aWriter.writeBytes(sLine);
438 aWriter.writeByte((int) '\n');
440 aWriter.close();
442 catch (java.io.FileNotFoundException fne)
444 GlobalLogWriter.println("couldn't open file for writing " + m_sFilename);
445 GlobalLogWriter.println("Message: " + fne.getMessage());
446 // DebugHelper.exception(BasicErrorCode.SbERR_FILE_NOT_FOUND, "");
448 catch (java.io.IOException ie)
450 GlobalLogWriter.println("Exception occurs while writing to file " + m_sFilename);
451 GlobalLogWriter.println("Message: " + ie.getMessage());
452 // DebugHelper.exception(BasicErrorCode.SbERR_INTERNAL_ERROR, ie.getMessage());
456 public void insertValue(String _sSection, String _sKey, int _nValue)
458 insertValue(_sSection, _sKey, String.valueOf(_nValue));
461 public void insertValue(String _sSection, String _sKey, long _nValue)
463 insertValue(_sSection, _sKey, String.valueOf(_nValue));
467 insert a value
468 there are 3 cases
469 1. section doesn't exist, goto end and insert a new section, insert a new key value pair
470 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
471 3. section exist and key exist, remove the old key and insert the key value pair at the same position
472 * @param _sSection
473 * @param _sKey
474 * @param _sValue
476 public void insertValue(String _sSection, String _sKey, String _sValue)
478 int i = findSection(_sSection);
479 if (i == -1)
481 // case 1: section doesn't exist
482 String sFindSection = buildSectionName(_sSection);
484 // TODO: before create a new Section, insert a empty line
485 m_aList.add(sFindSection);
486 if (_sKey.length() > 0)
488 String sKeyValuePair = _sKey + "=" + _sValue;
489 m_aList.add(sKeyValuePair);
491 m_bListContainUnsavedChanges = true;
492 return;
494 int j = findKeyFromKnownSection(i, _sKey);
495 if (j == -1)
497 // case 2: section exist, but not the key
498 j = findLastKnownKeyIndex(i, _sKey);
499 if (_sKey.length() > 0)
501 String sKeyValuePair = _sKey + "=" + _sValue;
502 m_aList.add(j, sKeyValuePair);
503 m_bListContainUnsavedChanges = true;
505 return;
507 else
509 // case 3: section exist, and also the key
510 String sKeyValuePair = _sKey + "=" + _sValue;
511 m_aList.set(j, sKeyValuePair);
512 m_bListContainUnsavedChanges = true;
515 // -----------------------------------------------------------------------------
516 // String replaceEvaluatedValue(String _sSection, String _sValue)
517 // {
518 // String sValue = _sValue;
519 // int nIndex = 0;
520 // while (( nIndex = sValue.indexOf("$(", nIndex)) >= 0)
521 // {
522 // int nNextIndex = sValue.indexOf(")", nIndex);
523 // if (nNextIndex >= 0)
524 // {
525 // String sKey = sValue.substring(nIndex + 2, nNextIndex);
526 // String sNewValue = getValue(_sSection, sKey);
527 // if (sNewValue != null && sNewValue.length() > 0)
528 // {
529 // String sRegexpKey = "\\$\\(" + sKey + "\\)";
530 // sValue = sValue.replaceAll(sRegexpKey, sNewValue);
531 // }
532 // nIndex = nNextIndex;
533 // }
534 // else
535 // {
536 // nIndex += 2;
537 // }
538 // }
539 // return sValue;
540 // }
541 // -----------------------------------------------------------------------------
543 // public String getLocalEvaluatedValue(String _sSection, String _sKey)
544 // {
545 // String sValue = getValue(_sSection, _sKey);
546 // sValue = replaceEvaluatedValue(_sSection, sValue);
547 // return sValue;
548 // }
550 // -----------------------------------------------------------------------------
552 // this is a special behaviour.
553 // public String getGlobalLocalEvaluatedValue(String _sSection, String _sKey)
554 // {
555 // String sGlobalValue = getKey("global", _sKey);
556 // String sLocalValue = getKey(_sSection, _sKey);
557 // if (sLocalValue.length() == 0)
558 // {
559 // sGlobalValue = replaceEvaluatedKey(_sSection, sGlobalValue);
560 // sGlobalValue = replaceEvaluatedKey("global", sGlobalValue);
561 // return sGlobalValue;
562 // }
563 // sLocalValue = replaceEvaluatedKey(_sSection, sLocalValue);
564 // sLocalValue = replaceEvaluatedKey("global", sLocalValue);
566 // return sLocalValue;
567 // }
568 public void removeSection(String _sSectionToRemove)
570 // first, search for the name
571 int i = findSection(_sSectionToRemove);
572 if (i == -1)
574 // Section to remove not found, do nothing.
575 return;
577 // second, find the next section
578 int j = findNextSection(i + 1);
579 if (j == -1)
581 // if we are at the end, use size() as second section
582 j = m_aList.size();
584 // remove all between first and second section
585 for (int k = i; k < j; k++)
587 m_aList.remove(i);
589 // mark the list as changed
590 m_bListContainUnsavedChanges = true;
594 * some tests for this class
596 // public static void main(String[] args)
597 // {
598 // String sTempFile = System.getProperty("java.io.tmpdir");
599 // sTempFile += "inifile";
602 // IniFile aIniFile = new IniFile(sTempFile);
603 // String sValue = aIniFile.getValue("Section", "Key");
604 // // insert a new value to a already exist section
605 // aIniFile.insertValue("Section", "Key2", "a new value in a existing section");
606 // // replace a value
607 // aIniFile.insertValue("Section", "Key", "replaced value");
608 // // create a new value
609 // aIniFile.insertValue("New Section", "Key", "a new key value pair");
610 // aIniFile.insertValue("New Section", "Key2", "a new second key value pair");
612 // String sValue2 = aIniFile.getValue("Section2", "Key");
614 // aIniFile.removeSection("Section");
615 // aIniFile.removeSection("New Section");
617 // aIniFile.close();
618 // }
621 * Enumeration Interface
622 * @return true, if there are more Key values
624 public boolean hasMoreElements()
626 if (m_aEnumerationPos >= 0 &&
627 m_aEnumerationPos < m_aList.size())
629 return true;
631 return false;
635 * Find the next line, which starts with '['
636 * @param i start position
637 * @return the line where '[' found or -1
639 private int findNextSection(int i)
641 if (i >= 0)
643 while (i < m_aList.size())
645 String sLine = m_aList.get(i);
646 if (sLine.startsWith("["))
648 return i;
650 i++;
653 return -1;
657 * Enumeration Interface
658 * @return a key without the enveloped '[' ']'
660 public Object nextElement()
662 int nLineWithSection = findNextSection(m_aEnumerationPos);
663 if (nLineWithSection != -1)
665 String sSection = m_aList.get(nLineWithSection);
666 m_aEnumerationPos = findNextSection(nLineWithSection + 1);
667 sSection = sectionToString(sSection);
668 return sSection;
670 else
672 m_aEnumerationPos = m_aList.size();
674 return null;
678 * Helper to count the occurence of Sections
679 * @return returns the count of '^['.*']$' Elements
681 public int getElementCount()
683 int nCount = 0;
684 int nPosition = 0;
685 while ((nPosition = findNextSection(nPosition)) != -1)
687 nCount++;
688 nPosition++;
690 return nCount;