001: /* SAXAdapter.java NanoXML/SAX
002: *
003: * $Revision: 1.4 $
004: * $Date: 2002/01/04 21:03:28 $
005: * $Name: RELEASE_2_2_1 $
006: *
007: * This file is part of the SAX adapter for NanoXML 2 for Java.
008: * Copyright (C) 2000-2002 Marc De Scheemaecker, All Rights Reserved.
009: *
010: * This software is provided 'as-is', without any express or implied warranty.
011: * In no event will the authors be held liable for any damages arising from the
012: * use of this software.
013: *
014: * Permission is granted to anyone to use this software for any purpose,
015: * including commercial applications, and to alter it and redistribute it
016: * freely, subject to the following restrictions:
017: *
018: * 1. The origin of this software must not be misrepresented; you must not
019: * claim that you wrote the original software. If you use this software in
020: * a product, an acknowledgment in the product documentation would be
021: * appreciated but is not required.
022: *
023: * 2. Altered source versions must be plainly marked as such, and must not be
024: * misrepresented as being the original software.
025: *
026: * 3. This notice may not be removed or altered from any source distribution.
027: */
028:
029: package net.n3.nanoxml.sax;
030:
031: import java.io.Reader;
032: import java.io.FileNotFoundException;
033: import java.io.IOException;
034: import java.net.MalformedURLException;
035: import net.n3.nanoxml.IXMLBuilder;
036: import net.n3.nanoxml.IXMLReader;
037: import org.xml.sax.AttributeList;
038: import org.xml.sax.DocumentHandler;
039: import org.xml.sax.ErrorHandler;
040: import org.xml.sax.HandlerBase;
041: import org.xml.sax.Locator;
042: import org.xml.sax.helpers.AttributeListImpl;
043: import org.xml.sax.helpers.LocatorImpl;
044:
045: /**
046: * SAXAdapter is the core adapter for using NanoXML/Java with SAX, the "Simple"
047: * API For XML.
048: *
049: * @see net.n3.nanoxml.IXMLBuilder
050: *
051: * @author Marc De Scheemaecker
052: * @version $Name: RELEASE_2_2_1 $, $Revision: 1.4 $
053: */
054: public class SAXAdapter implements IXMLBuilder {
055:
056: /**
057: * The NanoXML reader.
058: */
059: private IXMLReader nanoxmlReader;
060:
061: /**
062: * The SAX document handler.
063: */
064: private DocumentHandler saxDocumentHandler;
065:
066: /**
067: * The SAX error handler.
068: */
069: private ErrorHandler saxErrorHandler;
070:
071: /**
072: * The SAX locator.
073: */
074: private LocatorImpl saxLocator;
075:
076: /**
077: * The SAX attribute list.
078: */
079: private AttributeListImpl saxAttributes;
080:
081: /**
082: * Creates the adapter.
083: */
084: public SAXAdapter() {
085: this .saxDocumentHandler = new HandlerBase();
086: this .saxLocator = new LocatorImpl();
087: this .saxLocator.setColumnNumber(-1);
088: }
089:
090: /**
091: * Cleans up the object when it's destroyed.
092: */
093: protected void finalize() throws Throwable {
094: this .nanoxmlReader = null;
095: this .saxDocumentHandler = null;
096: this .saxErrorHandler = null;
097: this .saxLocator = null;
098: this .saxAttributes = null;
099: super .finalize();
100: }
101:
102: /**
103: * Sets the document handler.
104: *
105: * @param handler the document handler
106: */
107: public void setDocumentHandler(DocumentHandler handler) {
108: this .saxDocumentHandler = handler;
109: }
110:
111: /**
112: * Sets the reader.
113: *
114: * @param reader the reader.
115: */
116: public void setReader(IXMLReader reader) {
117: this .nanoxmlReader = reader;
118: }
119:
120: /**
121: * This method is called before the parser starts processing its input.
122: *
123: * @param systemID the system ID of the data source
124: * @param lineNr the line on which the parsing starts
125: */
126: public void startBuilding(String systemID, int lineNr)
127: throws Exception {
128: this .saxLocator.setLineNumber(lineNr);
129: this .saxLocator.setSystemId(systemID);
130: this .saxDocumentHandler.setDocumentLocator(this .saxLocator);
131: this .saxDocumentHandler.startDocument();
132: }
133:
134: /**
135: * This method is called when a processing instruction is encountered.
136: * PIs with target "xml" are handled by the parser.
137: *
138: * @param target the PI target
139: * @param reader to read the data from the PI
140: */
141: public void newProcessingInstruction(String target, Reader reader)
142: throws Exception {
143: StringBuffer data = new StringBuffer();
144: char[] chars = new char[1024];
145: int charsRead = reader.read(chars);
146:
147: while (charsRead > 0) {
148: data.append(chars, 0, charsRead);
149: charsRead = reader.read(chars);
150: }
151:
152: this .saxDocumentHandler.processingInstruction(target, data
153: .toString());
154: }
155:
156: /**
157: * This method is called when a new XML element is encountered.
158: *
159: * @see #endElement
160: *
161: * @param name the name of the element
162: * @param nsPrefix the prefix used to identify the namespace
163: * @param nsSystemId the system ID associated with the namespace
164: * @param systemID the system ID of the data source
165: * @param lineNr the line in the source where the element starts
166: */
167: public void startElement(String name, String nsPrefix,
168: String nsSystemId, String systemID, int lineNr)
169: throws Exception {
170: if (nsPrefix != null) {
171: name = nsPrefix + ':' + name;
172: }
173:
174: this .saxLocator.setLineNumber(lineNr);
175: this .saxLocator.setSystemId(systemID);
176: this .saxAttributes = new AttributeListImpl();
177: }
178:
179: /**
180: * This method is called when the attributes of an XML element have been
181: * processed.
182: *
183: * @see #startElement
184: * @see #addAttribute
185: *
186: * @param name the name of the element
187: * @param nsPrefix the prefix used to identify the namespace
188: * @param nsSystemId the system ID associated with the namespace
189: */
190: public void elementAttributesProcessed(String name,
191: String nsPrefix, String nsSystemId) throws Exception {
192: if (nsPrefix != null) {
193: name = nsPrefix + ':' + name;
194: }
195:
196: this .saxDocumentHandler.startElement(name, this .saxAttributes);
197: }
198:
199: /**
200: * This method is called when the end of an XML elemnt is encountered.
201: *
202: * @see #startElement
203: *
204: * @param name the name of the element
205: * @param nsPrefix the prefix used to identify the namespace
206: * @param nsSystemId the system ID associated with the namespace
207: */
208: public void endElement(String name, String nsPrefix,
209: String nsSystemId) throws Exception {
210: if (nsPrefix != null) {
211: name = nsPrefix + ':' + name;
212: }
213:
214: this .saxDocumentHandler.endElement(name);
215: }
216:
217: /**
218: * This method is called when a new attribute of an XML element is
219: * encountered.
220: *
221: * @param key the key (name) of the attribute
222: * @param nsPrefix the prefix used to identify the namespace
223: * @param nsSystemId the system ID associated with the namespace
224: * @param value the value of the attribute
225: * @param type the type of the attribute ("CDATA" if unknown)
226: */
227: public void addAttribute(String key, String nsPrefix,
228: String nsSystemId, String value, String type)
229: throws Exception {
230: if (nsPrefix != null) {
231: key = nsPrefix + ':' + key;
232: }
233:
234: this .saxAttributes.addAttribute(key, type, value);
235: }
236:
237: /**
238: * This method is called when a PCDATA element is encountered. A Java
239: * reader is supplied from which you can read the data. The reader will
240: * only read the data of the element. You don't need to check for
241: * boundaries. If you don't read the full element, the rest of the data
242: * is skipped. You also don't have to care about entities; they are
243: * resolved by the parser.
244: *
245: * @param reader the Java reader from which you can retrieve the data
246: * @param systemID the system ID of the data source
247: * @param lineNr the line in the source where the element starts
248: *
249: * @throws java.io.IOException
250: * when the reader throws such exception
251: */
252: public void addPCData(Reader reader, String systemID, int lineNr)
253: throws Exception {
254: this .saxLocator.setLineNumber(lineNr);
255: this .saxLocator.setSystemId(systemID);
256: char[] chars = new char[2048];
257: int charsRead = reader.read(chars);
258:
259: while (charsRead > 0) {
260: this .saxDocumentHandler.characters(chars, 0, charsRead);
261: charsRead = reader.read(chars);
262: }
263: }
264:
265: /**
266: * Returns the result of the building process. This method is called just
267: * before the parse() method of IXMLParser returns.
268: *
269: * @see net.n3.nanoxml.IXMLParser#parse
270: *
271: * @return the result of the building process.
272: */
273: public Object getResult() throws Exception {
274: return null;
275: }
276:
277: /**
278: * Indicates that parsing has been completed.
279: */
280: public void endDocument() throws Exception {
281: this.saxDocumentHandler.endDocument();
282: }
283:
284: }
|