Statistics
| Revision:

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
}