001: /*
002: * Copyright (c) 1998-2008 Caucho Technology -- all rights reserved
003: *
004: * This file is part of Resin(R) Open Source
005: *
006: * Each copy or derived work must preserve the copyright notice and this
007: * notice unmodified.
008: *
009: * Resin Open Source is free software; you can redistribute it and/or modify
010: * it under the terms of the GNU General Public License as published by
011: * the Free Software Foundation; either version 2 of the License, or
012: * (at your option) any later version.
013: *
014: * Resin Open Source is distributed in the hope that it will be useful,
015: * but WITHOUT ANY WARRANTY; without even the implied warranty of
016: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, or any warranty
017: * of NON-INFRINGEMENT. See the GNU General Public License for more
018: * details.
019: *
020: * You should have received a copy of the GNU General Public License
021: * along with Resin Open Source; if not, write to the
022: * Free SoftwareFoundation, Inc.
023: * 59 Temple Place, Suite 330
024: * Boston, MA 02111-1307 USA
025: *
026: * @author Scott Ferguson
027: */
028:
029: package com.caucho.xml2;
030:
031: import com.caucho.util.CharBuffer;
032:
033: import org.xml.sax.ContentHandler;
034: import org.xml.sax.Locator;
035: import org.xml.sax.SAXException;
036: import org.xml.sax.XMLReader;
037:
038: import javax.xml.namespace.QName;
039: import java.io.IOException;
040:
041: /**
042: * XMLWriter to create a SAX events.
043: */
044: public class SAXBuilder implements XMLWriter, Locator {
045: private XMLReader _saxReader;
046: private ContentHandler _contentHandler;
047:
048: private QAttributes _attributes;
049: private CharBuffer _text;
050: private boolean _escapeText;
051:
052: private boolean _hasElement;
053:
054: private String _elementUri;
055: private String _elementLocalName;
056: private String _elementQName;
057:
058: private String _filename;
059: private int _line;
060:
061: private String _elementSystemId;
062: private int _elementLine;
063:
064: private Locator _locator;
065:
066: public SAXBuilder() {
067: _text = new CharBuffer();
068: _attributes = new QAttributes();
069: }
070:
071: public SAXBuilder(XMLReader saxReader) {
072: this ();
073:
074: init(saxReader);
075: }
076:
077: public void init(XMLReader saxReader) {
078: _saxReader = saxReader;
079:
080: _contentHandler = saxReader.getContentHandler();
081:
082: init();
083: }
084:
085: public void init() {
086: _text.clear();
087: _attributes.clear();
088: _hasElement = false;
089:
090: _filename = null;
091: _line = 0;
092: }
093:
094: /**
095: * Sets the SAX content handler.
096: */
097: public void setContentHandler(ContentHandler handler) {
098: _contentHandler = handler;
099: }
100:
101: public void setDocumentLocator(Locator locator) {
102: _locator = locator;
103: }
104:
105: public void startDocument() throws IOException, SAXException {
106: _contentHandler.setDocumentLocator(this );
107: _contentHandler.startDocument();
108: }
109:
110: public void endDocument() throws IOException, SAXException {
111: pop();
112:
113: _contentHandler.endDocument();
114: }
115:
116: public void setLocation(String filename, int line, int column) {
117: _filename = filename;
118: _line = line;
119: }
120:
121: /**
122: * Returns the current filename.
123: */
124: public String getSystemId() {
125: if (_elementSystemId != null)
126: return _elementSystemId;
127: else if (_locator != null)
128: return _locator.getSystemId();
129: else
130: return _filename;
131: }
132:
133: /**
134: * Don't really have a public id (?).
135: */
136: public String getPublicId() {
137: if (_locator != null)
138: return _locator.getPublicId();
139: else
140: return null;
141: }
142:
143: /**
144: * Returns the current line.
145: */
146: public int getLineNumber() {
147: if (_elementSystemId != null)
148: return _elementLine;
149: else if (_locator != null)
150: return _locator.getLineNumber();
151: else
152: return 0;
153: }
154:
155: /**
156: * The column number is always 0.
157: */
158: public int getColumnNumber() {
159: if (_locator != null)
160: return _locator.getColumnNumber();
161: else
162: return 0;
163: }
164:
165: /**
166: * Starts the building of an element.
167: *
168: * @param uri the element's namespace URI
169: * @param localName the element's local name
170: * @param qName the element's fully qualified name
171: */
172: public void startElement(String uri, String localName, String qName)
173: throws IOException, SAXException {
174: pop();
175:
176: _elementUri = uri;
177: _elementLocalName = localName;
178: _elementQName = qName;
179: _hasElement = true;
180:
181: if (_locator != null) {
182: _elementSystemId = _locator.getSystemId();
183: _elementLine = _locator.getLineNumber();
184: }
185: }
186:
187: public void startPrefixMapping(String prefix, String uri)
188: throws IOException, SAXException {
189: _contentHandler.startPrefixMapping(prefix, uri);
190: }
191:
192: public void endPrefixMapping(String prefix) throws IOException,
193: SAXException {
194: _contentHandler.endPrefixMapping(prefix);
195: }
196:
197: public void attribute(String uri, String localName, String qName,
198: String value) throws IOException, SAXException {
199: QName name = new QName(qName, uri);
200:
201: _attributes.add(name, value);
202: }
203:
204: public void endElement(String uri, String localName, String qName)
205: throws IOException, SAXException {
206: pop();
207:
208: if (uri != null)
209: _contentHandler.endElement(uri, localName, qName);
210: else
211: _contentHandler.endElement("", null, qName);
212: }
213:
214: public void processingInstruction(String name, String data)
215: throws IOException, SAXException {
216: pop();
217:
218: _contentHandler.processingInstruction(name, data);
219: }
220:
221: public void comment(String data) throws IOException, SAXException {
222: pop();
223: }
224:
225: public boolean getEscapeText() {
226: return _escapeText;
227: }
228:
229: public void setEscapeText(boolean isEscaped) {
230: _escapeText = isEscaped;
231: }
232:
233: public void text(String text) throws IOException, SAXException {
234: popElement();
235:
236: _text.append(text);
237: }
238:
239: public void text(char[] buffer, int offset, int length)
240: throws IOException, SAXException {
241: popElement();
242:
243: _text.append(buffer, offset, length);
244: }
245:
246: public void cdata(String text) throws IOException, SAXException {
247: popElement();
248:
249: text(text);
250: }
251:
252: public void cdata(char[] buffer, int offset, int length)
253: throws IOException, SAXException {
254: popElement();
255:
256: text(buffer, offset, length);
257: }
258:
259: private void pop() throws IOException, SAXException {
260: popElement();
261:
262: if (_text.length() == 0)
263: return;
264:
265: _contentHandler.characters(_text.getBuffer(), 0, _text
266: .getLength());
267:
268: _text.clear();
269: }
270:
271: /**
272: * Completes the open element processing.
273: */
274: private void popElement() throws IOException, SAXException {
275: if (_hasElement) {
276: if (_elementUri == null)
277: _contentHandler.startElement("", null, _elementQName,
278: _attributes);
279: else
280: _contentHandler.startElement(_elementUri,
281: _elementLocalName, _elementQName, _attributes);
282:
283: _hasElement = false;
284: _elementSystemId = null;
285: _attributes.clear();
286: }
287: }
288: }
|