KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > net > n3 > nanoxml > StdXMLBuilder


1 /* StdXMLBuilder.java NanoXML/Java
2  *
3  * $Revision: 1421 $
4  * $Date: 2006-03-12 17:32:32 +0100 (Sun, 12 Mar 2006) $
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 import java.io.Reader JavaDoc;
32 import java.util.Stack JavaDoc;
33
34 /**
35  * StdXMLBuilder is a concrete implementation of IXMLBuilder which creates a tree of XMLElement from
36  * an XML data source.
37  *
38  * @see net.n3.nanoxml.XMLElement
39  *
40  * @author Marc De Scheemaecker
41  * @version $Name$, $Revision: 1421 $
42  */

43 public class StdXMLBuilder implements IXMLBuilder
44 {
45
46     /**
47      * This stack contains the current element and its parents.
48      */

49     private Stack JavaDoc stack;
50
51     /**
52      * The root element of the parsed XML tree.
53      */

54     private XMLElement root;
55
56     /**
57      * Creates the builder.
58      */

59     public StdXMLBuilder()
60     {
61         this.stack = null;
62         this.root = null;
63     }
64
65     /**
66      * Cleans up the object when it's destroyed.
67      */

68     protected void finalize() throws Throwable JavaDoc
69     {
70         this.root = null;
71         this.stack.clear();
72         this.stack = null;
73         super.finalize();
74     }
75
76     /**
77      * This method is called before the parser starts processing its input.
78      *
79      * @param systemID the system ID of the XML data source
80      * @param lineNr the line on which the parsing starts
81      */

82     public void startBuilding(String JavaDoc systemID, int lineNr)
83     {
84         this.stack = new Stack JavaDoc();
85         this.root = null;
86     }
87
88     /**
89      * This method is called when a processing instruction is encountered. PIs with target "xml" are
90      * handled by the parser.
91      *
92      * @param target the PI target
93      * @param reader to read the data from the PI
94      */

95     public void newProcessingInstruction(String JavaDoc target, Reader JavaDoc reader)
96     {
97         // nothing to do
98
}
99
100     /**
101      * This method is called when a new XML element is encountered.
102      *
103      * @see #endElement
104      *
105      * @param name the name of the element
106      * @param nsPrefix the prefix used to identify the namespace
107      * @param nsSystemID the system ID associated with the namespace
108      * @param systemID the system ID of the XML data source
109      * @param lineNr the line in the source where the element starts
110      */

111     public void startElement(String JavaDoc name, String JavaDoc nsPrefix, String JavaDoc nsSystemID, String JavaDoc systemID,
112             int lineNr)
113     {
114         XMLElement elt = new XMLElement(name, systemID, lineNr);
115
116         if (this.stack.empty())
117         {
118             this.root = elt;
119         }
120         else
121         {
122             XMLElement top = (XMLElement) this.stack.peek();
123             top.addChild(elt);
124         }
125
126         this.stack.push(elt);
127     }
128
129     /**
130      * This method is called when the attributes of an XML element have been processed.
131      *
132      * @see #startElement
133      * @see #addAttribute
134      *
135      * @param name the name of the element
136      * @param nsPrefix the prefix used to identify the namespace
137      * @param nsSystemID the system ID associated with the namespace
138      */

139     public void elementAttributesProcessed(String JavaDoc name, String JavaDoc nsPrefix, String JavaDoc nsSystemID)
140     {
141         // nothing to do
142
}
143
144     /**
145      * This method is called when the end of an XML elemnt is encountered.
146      *
147      * @see #startElement
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 endElement(String JavaDoc name, String JavaDoc nsPrefix, String JavaDoc nsSystemID)
154     {
155         XMLElement elt = (XMLElement) this.stack.pop();
156
157         if (elt.getChildrenCount() == 1)
158         {
159             XMLElement child = elt.getChildAtIndex(0);
160
161             if (child.getName() == null)
162             {
163                 elt.setContent(child.getContent());
164                 elt.removeChildAtIndex(0);
165             }
166         }
167     }
168
169     /**
170      * This method is called when a new attribute of an XML element is encountered.
171      *
172      * @param key the key (name) of the attribute
173      * @param nsPrefix the prefix used to identify the namespace
174      * @param nsSystemID the system ID associated with the namespace
175      * @param value the value of the attribute
176      * @param type the type of the attribute ("CDATA" if unknown)
177      *
178      * @throws java.lang.Exception If an exception occurred while processing the event.
179      */

180     public void addAttribute(String JavaDoc key, String JavaDoc nsPrefix, String JavaDoc nsSystemID, String JavaDoc value,
181             String JavaDoc type) throws Exception JavaDoc
182     {
183         XMLElement top = (XMLElement) this.stack.peek();
184
185         if (top.hasAttribute(key)) { throw new XMLParseException(top.getSystemID(),
186                 top.getLineNr(), "Duplicate attribute: " + key); }
187
188         top.setAttribute(key, value);
189     }
190
191     /**
192      * This method is called when a PCDATA element is encountered. A Java reader is supplied from
193      * which you can read the data. The reader will only read the data of the element. You don't
194      * need to check for boundaries. If you don't read the full element, the rest of the data is
195      * skipped. You also don't have to care about entities; they are resolved by the parser.
196      *
197      * @param reader the Java reader from which you can retrieve the data
198      * @param systemID the system ID of the XML data source
199      * @param lineNr the line in the source where the element starts
200      *
201      * @throws java.lang.Exception If an exception occurred while processing the event.
202      */

203     public void addPCData(Reader JavaDoc reader, String JavaDoc systemID, int lineNr) throws Exception JavaDoc
204     {
205         int bufSize = 2048;
206         int sizeRead = 0;
207         StringBuffer JavaDoc str = new StringBuffer JavaDoc(bufSize);
208         char[] buf = new char[bufSize];
209
210         for (;;)
211         {
212             if (sizeRead >= bufSize)
213             {
214                 bufSize *= 2;
215                 str.ensureCapacity(bufSize);
216             }
217
218             int size = reader.read(buf);
219
220             if (size < 0)
221             {
222                 break;
223             }
224
225             str.append(buf, 0, size);
226             sizeRead += size;
227         }
228
229         XMLElement elt = new XMLElement(null, systemID, lineNr);
230         elt.setContent(str.toString());
231
232         if (!this.stack.empty())
233         {
234             XMLElement top = (XMLElement) this.stack.peek();
235             top.addChild(elt);
236         }
237     }
238
239     /**
240      * Returns the result of the building process. This method is called just before the parse()
241      * method of IXMLParser returns.
242      *
243      * @see net.n3.nanoxml.IXMLParser#parse
244      *
245      * @return the result of the building process.
246      */

247     public Object JavaDoc getResult()
248     {
249         return this.root;
250     }
251
252 }
253
Popular Tags