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.xml;
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 java.io.IOException;
039:
040: /**
041: * XMLWriter to create a SAX events.
042: */
043: public class SAXBuilder implements XMLWriter, Locator {
044: private XMLReader _saxReader;
045: private ContentHandler _contentHandler;
046:
047: private QAttributes _attributes;
048: private CharBuffer _text;
049: private boolean _escapeText;
050:
051: private boolean _hasElement;
052:
053: private String _elementUri;
054: private String _elementLocalName;
055: private String _elementQName;
056:
057: private String _filename;
058: private int _line;
059:
060: private String _elementSystemId;
061: private int _elementLine;
062:
063: private Locator _locator;
064:
065: public SAXBuilder() {
066: _text = new CharBuffer();
067: _attributes = new QAttributes();
068: }
069:
070: public SAXBuilder(XMLReader saxReader) {
071: this ();
072:
073: init(saxReader);
074: }
075:
076: public void init(XMLReader saxReader) {
077: _saxReader = saxReader;
078:
079: _contentHandler = saxReader.getContentHandler();
080:
081: init();
082: }
083:
084: public void init() {
085: _text.clear();
086: _attributes.clear();
087: _hasElement = false;
088:
089: _filename = null;
090: _line = 0;
091: }
092:
093: /**
094: * Sets the SAX content handler.
095: */
096: public void setContentHandler(ContentHandler handler) {
097: _contentHandler = handler;
098: }
099:
100: public void setDocumentLocator(Locator locator) {
101: _locator = locator;
102: }
103:
104: public void startDocument() throws IOException, SAXException {
105: _contentHandler.setDocumentLocator(this );
106: _contentHandler.startDocument();
107: }
108:
109: public void endDocument() throws IOException, SAXException {
110: pop();
111:
112: _contentHandler.endDocument();
113: }
114:
115: public void setLocation(String filename, int line, int column) {
116: _filename = filename;
117: _line = line;
118: }
119:
120: /**
121: * Returns the current filename.
122: */
123: public String getSystemId() {
124: if (_elementSystemId != null)
125: return _elementSystemId;
126: else if (_locator != null)
127: return _locator.getSystemId();
128: else
129: return _filename;
130: }
131:
132: /**
133: * Don't really have a public id (?).
134: */
135: public String getPublicId() {
136: if (_locator != null)
137: return _locator.getPublicId();
138: else
139: return null;
140: }
141:
142: /**
143: * Returns the current line.
144: */
145: public int getLineNumber() {
146: if (_elementSystemId != null)
147: return _elementLine;
148: else if (_locator != null)
149: return _locator.getLineNumber();
150: else
151: return 0;
152: }
153:
154: /**
155: * The column number is always 0.
156: */
157: public int getColumnNumber() {
158: if (_locator != null)
159: return _locator.getColumnNumber();
160: else
161: return 0;
162: }
163:
164: /**
165: * Starts the building of an element.
166: *
167: * @param uri the element's namespace URI
168: * @param localName the element's local name
169: * @param qName the element's fully qualified name
170: */
171: public void startElement(String uri, String localName, String qName)
172: throws IOException, SAXException {
173: pop();
174:
175: _elementUri = uri;
176: _elementLocalName = localName;
177: _elementQName = qName;
178: _hasElement = true;
179:
180: if (_locator != null) {
181: _elementSystemId = _locator.getSystemId();
182: _elementLine = _locator.getLineNumber();
183: }
184: }
185:
186: public void startPrefixMapping(String prefix, String uri)
187: throws IOException, SAXException {
188: _contentHandler.startPrefixMapping(prefix, uri);
189: }
190:
191: public void endPrefixMapping(String prefix) throws IOException,
192: SAXException {
193: _contentHandler.endPrefixMapping(prefix);
194: }
195:
196: public void attribute(String uri, String localName, String qName,
197: String value) throws IOException, SAXException {
198: QName name = new QName(qName, uri);
199:
200: _attributes.add(name, value);
201: }
202:
203: public void endElement(String uri, String localName, String qName)
204: throws IOException, SAXException {
205: pop();
206:
207: if (uri != null)
208: _contentHandler.endElement(uri, localName, qName);
209: else
210: _contentHandler.endElement("", null, qName);
211: }
212:
213: public void processingInstruction(String name, String data)
214: throws IOException, SAXException {
215: pop();
216:
217: _contentHandler.processingInstruction(name, data);
218: }
219:
220: public void comment(String data) throws IOException, SAXException {
221: pop();
222: }
223:
224: public boolean getEscapeText() {
225: return _escapeText;
226: }
227:
228: public void setEscapeText(boolean isEscaped) {
229: _escapeText = isEscaped;
230: }
231:
232: public void text(String text) throws IOException, SAXException {
233: popElement();
234:
235: _text.append(text);
236: }
237:
238: public void text(char[] buffer, int offset, int length)
239: throws IOException, SAXException {
240: popElement();
241:
242: _text.append(buffer, offset, length);
243: }
244:
245: public void cdata(String text) throws IOException, SAXException {
246: popElement();
247:
248: text(text);
249: }
250:
251: public void cdata(char[] buffer, int offset, int length)
252: throws IOException, SAXException {
253: popElement();
254:
255: text(buffer, offset, length);
256: }
257:
258: private void pop() throws IOException, SAXException {
259: popElement();
260:
261: if (_text.length() == 0)
262: return;
263:
264: _contentHandler.characters(_text.getBuffer(), 0, _text
265: .getLength());
266:
267: _text.clear();
268: }
269:
270: /**
271: * Completes the open element processing.
272: */
273: private void popElement() throws IOException, SAXException {
274: if (_hasElement) {
275: if (_elementUri == null)
276: _contentHandler.startElement("", null, _elementQName,
277: _attributes);
278: else
279: _contentHandler.startElement(_elementUri,
280: _elementLocalName, _elementQName, _attributes);
281:
282: _hasElement = false;
283: _elementSystemId = null;
284: _attributes.clear();
285: }
286: }
287: }
|