root / import / ext3D / trunk / install-extension3d / IzPack / src / lib / net / n3 / nanoxml / StdXMLBuilder.java @ 15280
History | View | Annotate | Download (8.56 KB)
1 |
/* StdXMLBuilder.java NanoXML/Java
|
---|---|
2 |
*
|
3 |
* $Revision: 1.1 $
|
4 |
* $Date: 2006/06/14 07:29:07 $
|
5 |
* $Name: $
|
6 |
*
|
7 |
* This file is part of NanoXML 2 for Java.
|
8 |
* Copyright (C) 2001 Marc De Scheemaecker, All Rights Reserved.
|
9 |
*
|
10 |
* This software is provided 'as-is', without any express or implied warranty.
|
11 |
* In no event will the authors be held liable for any damages arising from the
|
12 |
* use of this software.
|
13 |
*
|
14 |
* Permission is granted to anyone to use this software for any purpose,
|
15 |
* including commercial applications, and to alter it and redistribute it
|
16 |
* freely, subject to the following restrictions:
|
17 |
*
|
18 |
* 1. The origin of this software must not be misrepresented; you must not
|
19 |
* claim that you wrote the original software. If you use this software in
|
20 |
* a product, an acknowledgment in the product documentation would be
|
21 |
* appreciated but is not required.
|
22 |
*
|
23 |
* 2. Altered source versions must be plainly marked as such, and must not be
|
24 |
* misrepresented as being the original software.
|
25 |
*
|
26 |
* 3. This notice may not be removed or altered from any source distribution.
|
27 |
*/
|
28 |
|
29 |
package net.n3.nanoxml; |
30 |
|
31 |
|
32 |
import java.io.Reader; |
33 |
import java.util.Stack; |
34 |
|
35 |
|
36 |
/**
|
37 |
* StdXMLBuilder is a concrete implementation of IXMLBuilder which creates a
|
38 |
* tree of XMLElement from an XML data source.
|
39 |
*
|
40 |
* @see net.n3.nanoxml.XMLElement
|
41 |
*
|
42 |
* @author Marc De Scheemaecker
|
43 |
* @version $Name: $, $Revision: 1.1 $
|
44 |
*/
|
45 |
public class StdXMLBuilder |
46 |
implements IXMLBuilder
|
47 |
{ |
48 |
|
49 |
/**
|
50 |
* This stack contains the current element and its parents.
|
51 |
*/
|
52 |
private Stack stack; |
53 |
|
54 |
|
55 |
/**
|
56 |
* The root element of the parsed XML tree.
|
57 |
*/
|
58 |
private XMLElement root;
|
59 |
|
60 |
|
61 |
/**
|
62 |
* Creates the builder.
|
63 |
*/
|
64 |
public StdXMLBuilder()
|
65 |
{ |
66 |
this.stack = null; |
67 |
this.root = null; |
68 |
} |
69 |
|
70 |
|
71 |
/**
|
72 |
* Cleans up the object when it's destroyed.
|
73 |
*/
|
74 |
protected void finalize() |
75 |
throws Throwable |
76 |
{ |
77 |
this.root = null; |
78 |
this.stack.clear();
|
79 |
this.stack = null; |
80 |
super.finalize();
|
81 |
} |
82 |
|
83 |
|
84 |
/**
|
85 |
* This method is called before the parser starts processing its input.
|
86 |
*
|
87 |
* @param systemID the system ID of the XML data source
|
88 |
* @param lineNr the line on which the parsing starts
|
89 |
*/
|
90 |
public void startBuilding(String systemID, |
91 |
int lineNr)
|
92 |
{ |
93 |
this.stack = new Stack(); |
94 |
this.root = null; |
95 |
} |
96 |
|
97 |
|
98 |
/**
|
99 |
* This method is called when a processing instruction is encountered.
|
100 |
* PIs with target "xml" are handled by the parser.
|
101 |
*
|
102 |
* @param target the PI target
|
103 |
* @param reader to read the data from the PI
|
104 |
*/
|
105 |
public void newProcessingInstruction(String target, |
106 |
Reader reader)
|
107 |
{ |
108 |
// nothing to do
|
109 |
} |
110 |
|
111 |
|
112 |
/**
|
113 |
* This method is called when a new XML element is encountered.
|
114 |
*
|
115 |
* @see #endElement
|
116 |
*
|
117 |
* @param name the name of the element
|
118 |
* @param nsPrefix the prefix used to identify the namespace
|
119 |
* @param nsSystemID the system ID associated with the namespace
|
120 |
* @param systemID the system ID of the XML data source
|
121 |
* @param lineNr the line in the source where the element starts
|
122 |
*/
|
123 |
public void startElement(String name, |
124 |
String nsPrefix,
|
125 |
String nsSystemID,
|
126 |
String systemID,
|
127 |
int lineNr)
|
128 |
{ |
129 |
XMLElement elt = new XMLElement(name, systemID, lineNr);
|
130 |
|
131 |
if (this.stack.empty()) { |
132 |
this.root = elt;
|
133 |
} else {
|
134 |
XMLElement top = (XMLElement) this.stack.peek();
|
135 |
top.addChild(elt); |
136 |
} |
137 |
|
138 |
this.stack.push(elt);
|
139 |
} |
140 |
|
141 |
|
142 |
/**
|
143 |
* This method is called when the attributes of an XML element have been
|
144 |
* processed.
|
145 |
*
|
146 |
* @see #startElement
|
147 |
* @see #addAttribute
|
148 |
*
|
149 |
* @param name the name of the element
|
150 |
* @param nsPrefix the prefix used to identify the namespace
|
151 |
* @param nsSystemID the system ID associated with the namespace
|
152 |
*/
|
153 |
public void elementAttributesProcessed(String name, |
154 |
String nsPrefix,
|
155 |
String nsSystemID)
|
156 |
{ |
157 |
// nothing to do
|
158 |
} |
159 |
|
160 |
|
161 |
/**
|
162 |
* This method is called when the end of an XML elemnt is encountered.
|
163 |
*
|
164 |
* @see #startElement
|
165 |
*
|
166 |
* @param name the name of the element
|
167 |
* @param nsPrefix the prefix used to identify the namespace
|
168 |
* @param nsSystemID the system ID associated with the namespace
|
169 |
*/
|
170 |
public void endElement(String name, |
171 |
String nsPrefix,
|
172 |
String nsSystemID)
|
173 |
{ |
174 |
XMLElement elt = (XMLElement) this.stack.pop();
|
175 |
|
176 |
if (elt.getChildrenCount() == 1) { |
177 |
XMLElement child = elt.getChildAtIndex(0);
|
178 |
|
179 |
if (child.getName() == null) { |
180 |
elt.setContent(child.getContent()); |
181 |
elt.removeChildAtIndex(0);
|
182 |
} |
183 |
} |
184 |
} |
185 |
|
186 |
|
187 |
/**
|
188 |
* This method is called when a new attribute of an XML element is
|
189 |
* encountered.
|
190 |
*
|
191 |
* @param key the key (name) of the attribute
|
192 |
* @param nsPrefix the prefix used to identify the namespace
|
193 |
* @param nsSystemID the system ID associated with the namespace
|
194 |
* @param value the value of the attribute
|
195 |
* @param type the type of the attribute ("CDATA" if unknown)
|
196 |
*
|
197 |
* @throws java.lang.Exception
|
198 |
* If an exception occurred while processing the event.
|
199 |
*/
|
200 |
public void addAttribute(String key, |
201 |
String nsPrefix,
|
202 |
String nsSystemID,
|
203 |
String value,
|
204 |
String type)
|
205 |
throws Exception |
206 |
{ |
207 |
XMLElement top = (XMLElement) this.stack.peek();
|
208 |
|
209 |
if (top.hasAttribute(key)) {
|
210 |
throw new XMLParseException(top.getSystemID(), |
211 |
top.getLineNr(), |
212 |
"Duplicate attribute: " + key);
|
213 |
} |
214 |
|
215 |
top.setAttribute(key, value); |
216 |
} |
217 |
|
218 |
|
219 |
/**
|
220 |
* This method is called when a PCDATA element is encountered. A Java
|
221 |
* reader is supplied from which you can read the data. The reader will
|
222 |
* only read the data of the element. You don't need to check for
|
223 |
* boundaries. If you don't read the full element, the rest of the data
|
224 |
* is skipped. You also don't have to care about entities; they are
|
225 |
* resolved by the parser.
|
226 |
*
|
227 |
* @param reader the Java reader from which you can retrieve the data
|
228 |
* @param systemID the system ID of the XML data source
|
229 |
* @param lineNr the line in the source where the element starts
|
230 |
*
|
231 |
* @throws java.lang.Exception
|
232 |
* If an exception occurred while processing the event.
|
233 |
*/
|
234 |
public void addPCData(Reader reader, |
235 |
String systemID,
|
236 |
int lineNr)
|
237 |
throws Exception |
238 |
{ |
239 |
int bufSize = 2048; |
240 |
int sizeRead = 0; |
241 |
StringBuffer str = new StringBuffer(bufSize); |
242 |
char[] buf = new char[bufSize]; |
243 |
|
244 |
|
245 |
for (;;) {
|
246 |
if (sizeRead >= bufSize) {
|
247 |
bufSize *= 2;
|
248 |
str.ensureCapacity(bufSize); |
249 |
} |
250 |
|
251 |
int size = reader.read(buf);
|
252 |
|
253 |
if (size < 0) { |
254 |
break;
|
255 |
} |
256 |
|
257 |
str.append(buf, 0, size);
|
258 |
sizeRead += size; |
259 |
} |
260 |
|
261 |
XMLElement elt = new XMLElement(null, systemID, lineNr); |
262 |
elt.setContent(str.toString()); |
263 |
|
264 |
if (! this.stack.empty()) { |
265 |
XMLElement top = (XMLElement) this.stack.peek();
|
266 |
top.addChild(elt); |
267 |
} |
268 |
} |
269 |
|
270 |
|
271 |
/**
|
272 |
* Returns the result of the building process. This method is called just
|
273 |
* before the parse() method of IXMLParser returns.
|
274 |
*
|
275 |
* @see net.n3.nanoxml.IXMLParser#parse
|
276 |
*
|
277 |
* @return the result of the building process.
|
278 |
*/
|
279 |
public Object getResult() |
280 |
{ |
281 |
return this.root; |
282 |
} |
283 |
|
284 |
} |