bump product version to 4.2.0.1
[LibreOffice.git] / qadevOOo / runner / graphical / IniFile.java
blob1c1c807c52206d403ab1a94ebeabee7780e8f796
1 /*
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 .
18 package graphical;
20 // import java.io.BufferedReader;
21 import java.io.File;
22 import java.io.RandomAccessFile;
23 import java.util.ArrayList;
24 import java.util.Enumeration;
26 /**
27 Helper class to give a simple API to read/write windows like ini files
29 /* public */ // is only need, if we need this class outside package convwatch
30 public class IniFile implements Enumeration<String>
33 /**
34 * internal representation of the ini file content.
35 * Problem, if ini file changed why other write something difference, we don't realise this.
37 private String m_sFilename;
38 private ArrayList<String> m_aList;
39 boolean m_bListContainUnsavedChanges = false;
40 private int m_aEnumerationPos = 0;
42 /**
43 open a ini file by it's name
44 @param _sFilename string a filename, if the file doesn't exist, a new empty ini file will create.
45 write back to disk only if there are really changes.
47 public IniFile(String _sFilename)
49 m_sFilename = _sFilename;
50 m_aList = loadLines();
51 m_aEnumerationPos = findNextSection(0);
52 // if (_sFilename.endsWith(".odb.ps.ini"))
53 // {
54 // int dummy = 0;
55 // }
58 public void insertFirstComment(String[] _aList)
60 if (m_aList.size() == 0)
62 // can only insert if there is nothing else already in the ini file
63 for (int i = 0; i < _aList.length; i++)
65 m_aList.add(_aList[i]);
70 private ArrayList<String> loadLines()
72 File aFile = new File(m_sFilename);
73 ArrayList<String> aLines = new ArrayList<String>();
74 if (!aFile.exists())
76 // GlobalLogWriter.println("couldn't find file '" + m_sFilename + "', will be created.");
77 // DebugHelper.exception(BasicErrorCode.SbERR_FILE_NOT_FOUND, "");
78 // m_bListContainUnsavedChanges = false;
79 return aLines;
81 RandomAccessFile aReader = null;
82 // BufferedReader aReader;
83 try
85 aReader = new RandomAccessFile(aFile, "r");
86 String aLine = "";
87 while (aLine != null)
89 aLine = aReader.readLine();
90 if (aLine != null && aLine.length() > 0)
92 aLines.add(aLine);
96 catch (java.io.FileNotFoundException fne)
98 GlobalLogWriter.println("couldn't open file " + m_sFilename);
99 GlobalLogWriter.println("Message: " + fne.getMessage());
100 // DebugHelper.exception(BasicErrorCode.SbERR_FILE_NOT_FOUND, "");
102 catch (java.io.IOException ie)
104 GlobalLogWriter.println("Exception occurs while reading from file " + m_sFilename);
105 GlobalLogWriter.println("Message: " + ie.getMessage());
106 // DebugHelper.exception(BasicErrorCode.SbERR_INTERNAL_ERROR, ie.getMessage());
110 aReader.close();
112 catch (java.io.IOException ie)
114 GlobalLogWriter.println("Couldn't close file " + m_sFilename);
115 GlobalLogWriter.println("Message: " + ie.getMessage());
116 // DebugHelper.exception(BasicErrorCode.SbERR_INTERNAL_ERROR, ie.getMessage());
118 return aLines;
122 * @return true, if the ini file contain some readable data
124 public boolean is()
126 return m_aList.size() > 1 ? true : false;
130 * Check if a given Section and Key exists in the ini file
131 * @param _sSectionName
132 * @param _sKey
133 * @return true if the given Section, Key exists, now you can get the value
135 public boolean hasValue(String _sSectionName, String _sKey)
137 int n = findKey(_sSectionName, _sKey);
138 if (n > 0)
140 return true;
142 return false;
144 // -----------------------------------------------------------------------------
146 private boolean isRemark(String _sLine)
148 if (((_sLine.length() < 2)) ||
149 (_sLine.startsWith("#")) ||
150 (_sLine.startsWith(";")))
152 return true;
154 return false;
157 private String getItem(int i)
159 return m_aList.get(i);
162 private String buildSectionName(String _sSectionName)
164 String sFindSection = "[" + _sSectionName + "]";
165 return sFindSection;
168 private String sectionToString(String _sSectionName)
170 String sKeyName = _sSectionName;
171 if (sKeyName.startsWith("[") &&
172 sKeyName.endsWith("]"))
174 sKeyName = sKeyName.substring(1, sKeyName.length() - 1);
176 return sKeyName;
179 private String toLowerIfNeed(String _sName)
181 return _sName.toLowerCase();
184 // return the number where this section starts
185 private int findSection(String _sSection)
187 String sFindSection = toLowerIfNeed(buildSectionName(_sSection));
188 // ----------- find _sSection ---------------
189 int i;
190 for (i = 0; i < m_aList.size(); i++)
192 String sLine = toLowerIfNeed(getItem(i).trim());
193 if (isRemark(sLine))
195 continue;
197 if (sFindSection.equals("[]"))
199 // special case, empty Section.
200 return i - 1;
202 if (sLine.startsWith(sFindSection))
204 return i;
207 return -1;
211 * Checks if a given section exists in the ini file
212 * @param _sSection
213 * @return true if the given _sSection was found
215 public boolean hasSection(String _sSection)
217 int i = findSection(_sSection);
218 if (i == -1)
220 return false;
222 return true;
225 // return the line number, where the key is found.
226 private int findKey(String _sSection, String _sKey)
228 int i = findSection(_sSection);
229 if (i == -1)
231 // Section not found, therefore the value can't exist
232 return -1;
234 return findKeyFromKnownSection(i, _sKey);
237 // i must be the index in the list, where the well known section starts
238 private int findKeyFromKnownSection(int _nSectionIndex, String _sKey)
240 _sKey = toLowerIfNeed(_sKey);
241 for (int j = _nSectionIndex + 1; j < m_aList.size(); j++)
243 String sLine = getItem(j).trim();
245 if (isRemark(sLine))
247 continue;
249 if (sLine.startsWith("[") /* && sLine.endsWith("]") */)
251 // TODO: due to the fact we would like to insert an empty line before new sections
252 // TODO: we should check if we are in an empty line and if, go back one line.
254 // found end.
255 break;
258 int nEqual = sLine.indexOf("=");
259 if (nEqual >= 0)
261 String sKey = toLowerIfNeed(sLine.substring(0, nEqual).trim());
262 if (sKey.equals(_sKey))
264 return j;
268 return -1;
271 // i must be the index in the list, where the well known section starts
272 private int findLastKnownKeyIndex(int _nSectionIndex, String _sKey)
274 _sKey = toLowerIfNeed(_sKey);
275 int i = _nSectionIndex + 1;
276 for (int j = i; j < m_aList.size(); j++)
278 String sLine = getItem(j).trim();
280 if (isRemark(sLine))
282 continue;
285 if (sLine.startsWith("[") /* && sLine.endsWith("]") */)
287 // found end.
288 return j;
291 int nEqual = sLine.indexOf("=");
292 if (nEqual >= 0)
294 String sKey = toLowerIfNeed(sLine.substring(0, nEqual).trim());
295 if (sKey.equals(_sKey))
297 return j;
301 return i;
304 private String getValue(int _nIndex)
306 String sLine = getItem(_nIndex).trim();
307 if (isRemark(sLine))
309 return "";
311 int nEqual = sLine.indexOf("=");
312 if (nEqual >= 0)
314 sLine.substring(0, nEqual).trim();
315 String sValue = sLine.substring(nEqual + 1).trim();
316 return sValue;
318 return "";
322 @param _sSection string
323 @param _sKey string
324 @return the value found in the inifile which is given by the section and key parameter
326 // private int m_nCurrentPosition;
327 // private String m_sOldKey;
328 public String getValue(String _sSection, String _sKey)
330 String sValue = "";
331 int m_nCurrentPosition = findKey(_sSection, _sKey);
332 if (m_nCurrentPosition == -1)
334 // Section not found, therefore the value can't exist
335 return "";
338 // m_sOldKey = _sKey;
339 sValue = getValue(m_nCurrentPosition);
341 return sValue;
344 // private String getNextValue()
345 // {
346 // if (m_nCurrentPosition >= 0)
347 // {
348 // ++m_nCurrentPosition;
349 // String sValue = getValue(m_nCurrentPosition);
350 // return sValue;
351 // }
352 // return "";
353 // }
355 * Returns the value at Section, Key converted to an integer
356 * Check with hasValue(Section, Key) to check before you get into trouble.
357 * @param _sSection
358 * @param _sKey
359 * @param _nDefault if there is a problem, key not found... this value will return
360 * @return
362 public int getIntValue(String _sSection, String _sKey, int _nDefault)
364 String sValue = getValue(_sSection, _sKey);
365 int nValue = _nDefault;
366 if (sValue.length() > 0)
370 nValue = Integer.valueOf(sValue).intValue();
372 catch (java.lang.NumberFormatException e)
374 GlobalLogWriter.println("IniFile.getIntValue(): Caught a number format exception, return the default value.");
377 return nValue;
380 public void close()
382 store();
386 write back the ini file to the disk, only if there exist changes
387 * @deprecated use close() instead!
390 // TODO: make private
391 public void store()
393 if (m_bListContainUnsavedChanges == false)
395 // nothing has changed, so no need to store
396 return;
399 File aFile = new File(m_sFilename);
400 if (aFile.exists())
402 // System.out.println("couldn't find file " + m_sFilename);
403 // TODO: little bit unsafe here, first rename, after write is complete, delete the old.
404 aFile.delete();
405 if (aFile.exists())
407 GlobalLogWriter.println("Couldn't delete the file " + m_sFilename);
408 return;
409 // DebugHelper.exception(BasicErrorCode.SbERR_INTERNAL_ERROR, "Couldn't delete the file " + m_sFilename);
412 // if (! aFile.canWrite())
413 // {
414 // System.out.println("Couldn't write to file " + m_sFilename);
415 // DebugHelper.exception(BasicErrorCode.SbERR_INTERNAL_ERROR, "");
416 // }
419 RandomAccessFile aWriter = new RandomAccessFile(aFile, "rw");
420 for (int i = 0; i < m_aList.size(); i++)
422 String sLine = getItem(i);
423 if (sLine.startsWith("["))
425 // write an extra empty line before next section.
426 aWriter.writeByte('\n');
428 aWriter.writeBytes(sLine);
429 aWriter.writeByte('\n');
431 aWriter.close();
433 catch (java.io.FileNotFoundException fne)
435 GlobalLogWriter.println("couldn't open file for writing " + m_sFilename);
436 GlobalLogWriter.println("Message: " + fne.getMessage());
437 // DebugHelper.exception(BasicErrorCode.SbERR_FILE_NOT_FOUND, "");
439 catch (java.io.IOException ie)
441 GlobalLogWriter.println("Exception occurs while writing to file " + m_sFilename);
442 GlobalLogWriter.println("Message: " + ie.getMessage());
443 // DebugHelper.exception(BasicErrorCode.SbERR_INTERNAL_ERROR, ie.getMessage());
447 public void insertValue(String _sSection, String _sKey, int _nValue)
449 insertValue(_sSection, _sKey, String.valueOf(_nValue));
452 public void insertValue(String _sSection, String _sKey, long _nValue)
454 insertValue(_sSection, _sKey, String.valueOf(_nValue));
458 insert a value
459 there are 3 cases
460 1. section doesn't exist, goto end and insert a new section, insert a new key value pair
461 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
462 3. section exist and key exist, remove the old key and insert the key value pair at the same position
463 * @param _sSection
464 * @param _sKey
465 * @param _sValue
467 public void insertValue(String _sSection, String _sKey, String _sValue)
469 int i = findSection(_sSection);
470 if (i == -1)
472 // case 1: section doesn't exist
473 String sFindSection = buildSectionName(_sSection);
475 // TODO: before create a new Section, insert a empty line
476 m_aList.add(sFindSection);
477 if (_sKey.length() > 0)
479 String sKeyValuePair = _sKey + "=" + _sValue;
480 m_aList.add(sKeyValuePair);
482 m_bListContainUnsavedChanges = true;
483 return;
485 int j = findKeyFromKnownSection(i, _sKey);
486 if (j == -1)
488 // case 2: section exist, but not the key
489 j = findLastKnownKeyIndex(i, _sKey);
490 if (_sKey.length() > 0)
492 String sKeyValuePair = _sKey + "=" + _sValue;
493 m_aList.add(j, sKeyValuePair);
494 m_bListContainUnsavedChanges = true;
496 return;
498 else
500 // case 3: section exist, and also the key
501 String sKeyValuePair = _sKey + "=" + _sValue;
502 m_aList.set(j, sKeyValuePair);
503 m_bListContainUnsavedChanges = true;
506 // -----------------------------------------------------------------------------
507 // String replaceEvaluatedValue(String _sSection, String _sValue)
508 // {
509 // String sValue = _sValue;
510 // int nIndex = 0;
511 // while (( nIndex = sValue.indexOf("$(", nIndex)) >= 0)
512 // {
513 // int nNextIndex = sValue.indexOf(")", nIndex);
514 // if (nNextIndex >= 0)
515 // {
516 // String sKey = sValue.substring(nIndex + 2, nNextIndex);
517 // String sNewValue = getValue(_sSection, sKey);
518 // if (sNewValue != null && sNewValue.length() > 0)
519 // {
520 // String sRegexpKey = "\\$\\(" + sKey + "\\)";
521 // sValue = sValue.replaceAll(sRegexpKey, sNewValue);
522 // }
523 // nIndex = nNextIndex;
524 // }
525 // else
526 // {
527 // nIndex += 2;
528 // }
529 // }
530 // return sValue;
531 // }
532 // -----------------------------------------------------------------------------
534 // public String getLocalEvaluatedValue(String _sSection, String _sKey)
535 // {
536 // String sValue = getValue(_sSection, _sKey);
537 // sValue = replaceEvaluatedValue(_sSection, sValue);
538 // return sValue;
539 // }
541 // -----------------------------------------------------------------------------
543 // this is a special behaviour.
544 // public String getGlobalLocalEvaluatedValue(String _sSection, String _sKey)
545 // {
546 // String sGlobalValue = getKey("global", _sKey);
547 // String sLocalValue = getKey(_sSection, _sKey);
548 // if (sLocalValue.length() == 0)
549 // {
550 // sGlobalValue = replaceEvaluatedKey(_sSection, sGlobalValue);
551 // sGlobalValue = replaceEvaluatedKey("global", sGlobalValue);
552 // return sGlobalValue;
553 // }
554 // sLocalValue = replaceEvaluatedKey(_sSection, sLocalValue);
555 // sLocalValue = replaceEvaluatedKey("global", sLocalValue);
557 // return sLocalValue;
558 // }
559 public void removeSection(String _sSectionToRemove)
561 // first, search for the name
562 int i = findSection(_sSectionToRemove);
563 if (i == -1)
565 // Section to remove not found, do nothing.
566 return;
568 // second, find the next section
569 int j = findNextSection(i + 1);
570 if (j == -1)
572 // if we are at the end, use size() as second section
573 j = m_aList.size();
575 // remove all between first and second section
576 for (int k = i; k < j; k++)
578 m_aList.remove(i);
580 // mark the list as changed
581 m_bListContainUnsavedChanges = true;
585 * some tests for this class
587 // public static void main(String[] args)
588 // {
589 // String sTempFile = System.getProperty("java.io.tmpdir");
590 // sTempFile += "inifile";
593 // IniFile aIniFile = new IniFile(sTempFile);
594 // String sValue = aIniFile.getValue("Section", "Key");
595 // // insert a new value to a already exist section
596 // aIniFile.insertValue("Section", "Key2", "a new value in a existing section");
597 // // replace a value
598 // aIniFile.insertValue("Section", "Key", "replaced value");
599 // // create a new value
600 // aIniFile.insertValue("New Section", "Key", "a new key value pair");
601 // aIniFile.insertValue("New Section", "Key2", "a new second key value pair");
603 // String sValue2 = aIniFile.getValue("Section2", "Key");
605 // aIniFile.removeSection("Section");
606 // aIniFile.removeSection("New Section");
608 // aIniFile.close();
609 // }
612 * Enumeration Interface
613 * @return true, if there are more Key values
615 public boolean hasMoreElements()
617 if (m_aEnumerationPos >= 0 &&
618 m_aEnumerationPos < m_aList.size())
620 return true;
622 return false;
626 * Find the next line, which starts with '['
627 * @param i start position
628 * @return the line where '[' found or -1
630 private int findNextSection(int i)
632 if (i >= 0)
634 while (i < m_aList.size())
636 String sLine = m_aList.get(i);
637 if (sLine.startsWith("["))
639 return i;
641 i++;
644 return -1;
648 * Enumeration Interface
649 * @return a key without the enveloped '[' ']'
651 public String nextElement()
653 int nLineWithSection = findNextSection(m_aEnumerationPos);
654 if (nLineWithSection != -1)
656 String sSection = m_aList.get(nLineWithSection);
657 m_aEnumerationPos = findNextSection(nLineWithSection + 1);
658 sSection = sectionToString(sSection);
659 return sSection;
661 else
663 m_aEnumerationPos = m_aList.size();
665 return null;
669 * Helper to count the occurrence of Sections
670 * @return returns the count of '^['.*']$' Elements
672 public int getElementCount()
674 int nCount = 0;
675 int nPosition = 0;
676 while ((nPosition = findNextSection(nPosition)) != -1)
678 nCount++;
679 nPosition++;
681 return nCount;