1 |
| |
2 |
| |
3 |
| |
4 |
| |
5 |
| |
6 |
| |
7 |
| |
8 |
| |
9 |
| |
10 |
| |
11 |
| |
12 |
| |
13 |
| |
14 |
| |
15 |
| |
16 |
| |
17 |
| package org.ini4j; |
18 |
| |
19 |
| import java.io.IOException; |
20 |
| import java.io.InputStream; |
21 |
| import java.io.InputStreamReader; |
22 |
| import java.io.LineNumberReader; |
23 |
| import java.io.Reader; |
24 |
| import java.net.URL; |
25 |
| |
26 |
| import org.xml.sax.*; |
27 |
| import org.xml.sax.helpers.*; |
28 |
| import javax.xml.parsers.*; |
29 |
| |
30 |
| public class IniParser |
31 |
| { |
32 |
| public static final String COMMENTS = ";#"; |
33 |
| public static final char OPERATOR = '='; |
34 |
| public static final char SECTION_BEGIN = '['; |
35 |
| public static final char SECTION_END = ']'; |
36 |
| |
37 |
| public static final String SERVICE_ID = "org.ini4j.IniParser"; |
38 |
| public static final String DEFAULT_SERVICE = SERVICE_ID; |
39 |
| |
40 |
33
| public static IniParser newInstance()
|
41 |
| { |
42 |
33
| return (IniParser) ServiceFinder.findService(SERVICE_ID, DEFAULT_SERVICE);
|
43 |
| } |
44 |
| |
45 |
23
| public void parse(InputStream input, IniHandler handler) throws IOException, InvalidIniFormatException
|
46 |
| { |
47 |
23
| parse(new InputStreamReader(input), handler);
|
48 |
| } |
49 |
| |
50 |
27
| public void parse(Reader input, IniHandler handler) throws IOException, InvalidIniFormatException
|
51 |
| { |
52 |
27
| LineNumberReader reader = new LineNumberReader(input);
|
53 |
| |
54 |
27
| handler.startIni();
|
55 |
| |
56 |
27
| String sectionName = null;
|
57 |
| |
58 |
27
| for (String line = reader.readLine(); line != null; line = reader.readLine())
|
59 |
| { |
60 |
876
| line = line.trim();
|
61 |
| |
62 |
876
| if ( (line.length() == 0) || (COMMENTS.indexOf(line.charAt(0)) >= 0))
|
63 |
| { |
64 |
240
| continue;
|
65 |
| } |
66 |
| |
67 |
636
| if ( line.charAt(0) == SECTION_BEGIN )
|
68 |
| { |
69 |
140
| if ( sectionName != null )
|
70 |
| { |
71 |
117
| handler.endSection();
|
72 |
| } |
73 |
| |
74 |
140
| if ( line.charAt(line.length()-1) != SECTION_END )
|
75 |
| { |
76 |
1
| parseError(line, reader.getLineNumber());
|
77 |
| } |
78 |
| |
79 |
139
| sectionName = unescape(line.substring(1, line.length()-1).trim());
|
80 |
| |
81 |
139
| if ( sectionName.length() == 0 )
|
82 |
| { |
83 |
1
| parseError(line, reader.getLineNumber());
|
84 |
| } |
85 |
| |
86 |
138
| handler.startSection(sectionName);
|
87 |
| } |
88 |
| else |
89 |
| { |
90 |
496
| if ( sectionName == null )
|
91 |
| { |
92 |
1
| parseError(line, reader.getLineNumber());
|
93 |
| } |
94 |
| |
95 |
495
| int idx = line.indexOf(OPERATOR);
|
96 |
| |
97 |
495
| if ( idx <= 0 )
|
98 |
| { |
99 |
2
| parseError(line, reader.getLineNumber());
|
100 |
| } |
101 |
| |
102 |
493
| String name = unescape(line.substring(0, idx)).trim();
|
103 |
493
| String value = unescape(line.substring(idx+1)).trim();
|
104 |
| |
105 |
493
| if ( name.length() == 0)
|
106 |
| { |
107 |
1
| parseError(line, reader.getLineNumber());
|
108 |
| } |
109 |
| |
110 |
492
| handler.handleOption(name, value);
|
111 |
| } |
112 |
| } |
113 |
| |
114 |
21
| if ( sectionName != null )
|
115 |
| { |
116 |
18
| handler.endSection();
|
117 |
| } |
118 |
| |
119 |
21
| handler.endIni();
|
120 |
| } |
121 |
| |
122 |
7
| public void parse(URL input, IniHandler handler) throws IOException, InvalidIniFormatException
|
123 |
| { |
124 |
7
| parse(input.openStream(), handler);
|
125 |
| } |
126 |
| |
127 |
7
| public void parseXML(InputStream input, IniHandler handler) throws IOException, InvalidIniFormatException
|
128 |
| { |
129 |
7
| parseXML(new InputStreamReader(input), handler);
|
130 |
| } |
131 |
| |
132 |
10
| public void parseXML(Reader input, final IniHandler handler) throws IOException, InvalidIniFormatException
|
133 |
| { |
134 |
| class XML2Ini extends DefaultHandler |
135 |
| { |
136 |
| static final String TAG_SECTION = "section"; |
137 |
| static final String TAG_OPTION = "option"; |
138 |
| static final String TAG_INI = "ini"; |
139 |
| static final String ATTR_KEY = "key"; |
140 |
| static final String ATTR_VALUE = "value"; |
141 |
| static final String ATTR_VERSION = "version"; |
142 |
| |
143 |
| static final String CURRENT_VERSION = "1.0"; |
144 |
| |
145 |
153
| public void startElement(String uri, String localName, String qname, Attributes attrs) throws SAXException
|
146 |
| { |
147 |
153
| String key = attrs.getValue(ATTR_KEY);
|
148 |
| |
149 |
153
| if ( qname.equals(TAG_INI) )
|
150 |
| { |
151 |
9
| String ver = attrs.getValue(ATTR_VERSION);
|
152 |
| |
153 |
9
| if ( (ver == null) || ! ver.equals(CURRENT_VERSION))
|
154 |
| { |
155 |
2
| throw new SAXException("Missing or invalid 'version' attribute");
|
156 |
| } |
157 |
| } |
158 |
| else |
159 |
| { |
160 |
144
| if ( key == null )
|
161 |
| { |
162 |
2
| throw new SAXException("missing '" + ATTR_KEY + "' attribute");
|
163 |
| } |
164 |
| |
165 |
142
| if ( qname.equals(TAG_SECTION) )
|
166 |
| { |
167 |
29
| handler.startSection(key);
|
168 |
| } |
169 |
113
| else if ( qname.equals(TAG_OPTION) )
|
170 |
| { |
171 |
112
| handler.handleOption(key, attrs.getValue(ATTR_VALUE));
|
172 |
| } |
173 |
| else |
174 |
| { |
175 |
1
| throw new SAXException("Invalid element: " + qname);
|
176 |
| } |
177 |
| } |
178 |
| } |
179 |
| |
180 |
144
| public void endElement(String uri, String localName, String qname) throws SAXException
|
181 |
| { |
182 |
144
| if ( qname.equals(TAG_SECTION) )
|
183 |
| { |
184 |
28
| handler.endSection();
|
185 |
| } |
186 |
| } |
187 |
| } |
188 |
| |
189 |
10
| XML2Ini xml2ini = new XML2Ini();
|
190 |
| |
191 |
10
| try
|
192 |
| { |
193 |
10
| SAXParserFactory.newInstance().newSAXParser().parse(new InputSource(input), xml2ini);
|
194 |
| } |
195 |
| catch (Exception x) |
196 |
| { |
197 |
6
| throw new InvalidIniFormatException(x);
|
198 |
| } |
199 |
| } |
200 |
| |
201 |
1
| public void parseXML(URL input, IniHandler handler) throws IOException, InvalidIniFormatException
|
202 |
| { |
203 |
1
| parseXML(input.openStream(), handler);
|
204 |
| } |
205 |
| |
206 |
1297
| protected String unescape(String line)
|
207 |
| { |
208 |
1297
| return Convert.unescape(line);
|
209 |
| } |
210 |
| |
211 |
11
| protected void parseError(String line, int lineNumber) throws InvalidIniFormatException
|
212 |
| { |
213 |
11
| throw new InvalidIniFormatException("parse error (at line: " + lineNumber + "): " + line);
|
214 |
| } |
215 |
| } |