|
1 /* This Source Code Form is subject to the terms of the Mozilla Public |
|
2 * License, v. 2.0. If a copy of the MPL was not distributed with this file, |
|
3 * You can obtain one at http://mozilla.org/MPL/2.0/. */ |
|
4 |
|
5 package org.mozilla.gecko.util; |
|
6 |
|
7 import java.io.BufferedReader; |
|
8 import java.io.BufferedWriter; |
|
9 import java.io.File; |
|
10 import java.io.FileNotFoundException; |
|
11 import java.io.FileReader; |
|
12 import java.io.FileWriter; |
|
13 import java.io.IOException; |
|
14 import java.util.Enumeration; |
|
15 import java.util.Hashtable; |
|
16 |
|
17 public final class INIParser extends INISection { |
|
18 // default file to read and write to |
|
19 private File mFile = null; |
|
20 |
|
21 // List of sections in the current iniFile. null if the file has not been parsed yet |
|
22 private Hashtable<String, INISection> mSections = null; |
|
23 |
|
24 // create a parser. The file will not be read until you attempt to |
|
25 // access sections or properties inside it. At that point its read synchronously |
|
26 public INIParser(File iniFile) { |
|
27 super(""); |
|
28 mFile = iniFile; |
|
29 } |
|
30 |
|
31 // write ini data to the default file. Will overwrite anything current inside |
|
32 public void write() { |
|
33 writeTo(mFile); |
|
34 } |
|
35 |
|
36 // write to the specified file. Will overwrite anything current inside |
|
37 public void writeTo(File f) { |
|
38 if (f == null) |
|
39 return; |
|
40 |
|
41 FileWriter outputStream = null; |
|
42 try { |
|
43 outputStream = new FileWriter(f); |
|
44 } catch (IOException e1) { |
|
45 e1.printStackTrace(); |
|
46 } |
|
47 |
|
48 BufferedWriter writer = new BufferedWriter(outputStream); |
|
49 try { |
|
50 write(writer); |
|
51 writer.close(); |
|
52 } catch (IOException e) { |
|
53 e.printStackTrace(); |
|
54 } |
|
55 } |
|
56 |
|
57 @Override |
|
58 public void write(BufferedWriter writer) throws IOException { |
|
59 super.write(writer); |
|
60 |
|
61 if (mSections != null) { |
|
62 for (Enumeration<INISection> e = mSections.elements(); e.hasMoreElements();) { |
|
63 INISection section = e.nextElement(); |
|
64 section.write(writer); |
|
65 writer.newLine(); |
|
66 } |
|
67 } |
|
68 } |
|
69 |
|
70 // return all of the sections inside this file |
|
71 public Hashtable<String, INISection> getSections() { |
|
72 if (mSections == null) { |
|
73 try { |
|
74 parse(); |
|
75 } catch (IOException e) { |
|
76 debug("Error parsing: " + e); |
|
77 } |
|
78 } |
|
79 return mSections; |
|
80 } |
|
81 |
|
82 // parse the default file |
|
83 @Override |
|
84 protected void parse() throws IOException { |
|
85 super.parse(); |
|
86 parse(mFile); |
|
87 } |
|
88 |
|
89 // parse a passed in file |
|
90 private void parse(File f) throws IOException { |
|
91 // Set up internal data members |
|
92 mSections = new Hashtable<String, INISection>(); |
|
93 |
|
94 if (f == null || !f.exists()) |
|
95 return; |
|
96 |
|
97 FileReader inputStream = null; |
|
98 try { |
|
99 inputStream = new FileReader(f); |
|
100 } catch (FileNotFoundException e1) { |
|
101 // If the file doesn't exist. Just return; |
|
102 return; |
|
103 } |
|
104 |
|
105 BufferedReader buf = new BufferedReader(inputStream); |
|
106 String line = null; // current line of text we are parsing |
|
107 INISection currentSection = null; // section we are currently parsing |
|
108 |
|
109 while ((line = buf.readLine()) != null) { |
|
110 |
|
111 if (line != null) |
|
112 line = line.trim(); |
|
113 |
|
114 // blank line or a comment. ignore it |
|
115 if (line == null || line.length() == 0 || line.charAt(0) == ';') { |
|
116 debug("Ignore line: " + line); |
|
117 } else if (line.charAt(0) == '[') { |
|
118 debug("Parse as section: " + line); |
|
119 currentSection = new INISection(line.substring(1, line.length()-1)); |
|
120 mSections.put(currentSection.getName(), currentSection); |
|
121 } else { |
|
122 debug("Parse as property: " + line); |
|
123 |
|
124 String[] pieces = line.split("="); |
|
125 if (pieces.length != 2) |
|
126 continue; |
|
127 |
|
128 String key = pieces[0].trim(); |
|
129 String value = pieces[1].trim(); |
|
130 if (currentSection != null) { |
|
131 currentSection.setProperty(key, value); |
|
132 } else { |
|
133 mProperties.put(key, value); |
|
134 } |
|
135 } |
|
136 } |
|
137 buf.close(); |
|
138 } |
|
139 |
|
140 // add a section to the file |
|
141 public void addSection(INISection sect) { |
|
142 // ensure that we have parsed the file |
|
143 getSections(); |
|
144 mSections.put(sect.getName(), sect); |
|
145 } |
|
146 |
|
147 // get a section from the file. will return null if the section doesn't exist |
|
148 public INISection getSection(String key) { |
|
149 // ensure that we have parsed the file |
|
150 getSections(); |
|
151 return mSections.get(key); |
|
152 } |
|
153 |
|
154 // remove an entire section from the file |
|
155 public void removeSection(String name) { |
|
156 // ensure that we have parsed the file |
|
157 getSections(); |
|
158 mSections.remove(name); |
|
159 } |
|
160 |
|
161 // rename a section; nuking any previous section with the new |
|
162 // name in the process |
|
163 public void renameSection(String oldName, String newName) { |
|
164 // ensure that we have parsed the file |
|
165 getSections(); |
|
166 |
|
167 mSections.remove(newName); |
|
168 INISection section = mSections.get(oldName); |
|
169 if (section == null) |
|
170 return; |
|
171 |
|
172 section.setName(newName); |
|
173 mSections.remove(oldName); |
|
174 mSections.put(newName, section); |
|
175 } |
|
176 } |