001: /*--------------------------------------------------------------------------*
002: | Copyright (C) 2006 Christopher Kohlhaas |
003: | |
004: | This program is free software; you can redistribute it and/or modify |
005: | it under the terms of the GNU General Public License as published by the |
006: | Free Software Foundation. A copy of the license has been included with |
007: | these distribution in the COPYING file, if not go to www.fsf.org . |
008: | |
009: | As a special exception, you are granted the permissions to link this |
010: | program with every library, which license fulfills the Open Source |
011: | Definition as published by the Open Source Initiative (OSI). |
012: *--------------------------------------------------------------------------*/
013:
014: package org.rapla.storage.xml;
015:
016: import java.io.PrintWriter;
017: import java.io.StringWriter;
018: import java.util.Collection;
019: import java.util.HashSet;
020: import java.util.Iterator;
021:
022: import org.xml.sax.Attributes;
023: import org.xml.sax.ContentHandler;
024: import org.xml.sax.Locator;
025: import org.xml.sax.SAXException;
026: import org.xml.sax.SAXParseException;
027:
028: class DelegationHandler implements ContentHandler {
029: StringBuffer currentText = null;
030:
031: DelegationHandler parent = null;
032: DelegationHandler delegate = null;
033:
034: int level = 0;
035: int entryLevel = 0;
036: Locator locator;
037:
038: Collection childHandlers;
039:
040: public void setDocumentLocator(Locator locator) {
041: this .locator = locator;
042: if (childHandlers == null)
043: return;
044:
045: Iterator it = childHandlers.iterator();
046: while (it.hasNext()) {
047: ((DelegationHandler) it.next()).setDocumentLocator(locator);
048: }
049: }
050:
051: private void setParent(DelegationHandler parent) {
052: this .parent = parent;
053: }
054:
055: protected Locator getLocator() {
056: return locator;
057: }
058:
059: public void addChildHandler(DelegationHandler childHandler) {
060: if (childHandlers == null)
061: childHandlers = new HashSet();
062: childHandlers.add(childHandler);
063: childHandler.setParent(this );
064: }
065:
066: public final void startDocument() {
067: this .level = 0;
068: this .entryLevel = 0;
069: }
070:
071: public final void endDocument() throws SAXException {
072: if (parent != null)
073: throw new SAXException("Unexpected end of Document");
074: }
075:
076: final public void startElement(String namespaceURI,
077: String localName, String qName, Attributes atts)
078: throws SAXException {
079: try {
080: //printToSystemErr( localName, atts );
081: if (delegate != null) {
082: delegate.startElement(namespaceURI, localName, qName,
083: atts);
084: } else {
085: level++;
086: processElement(namespaceURI, localName, qName, atts);
087: }
088: } catch (SAXException ex) {
089: throw ex;
090: } catch (Exception ex) {
091: throw new SAXException(ex);
092: }
093: }
094:
095: protected void printToSystemErr(String localName, Attributes atts) {
096: int len = atts.getLength();
097: StringBuffer buf = new StringBuffer();
098: for (int i = 0; i < len; i++) {
099: buf.append(" ");
100: buf.append(atts.getLocalName(i));
101: buf.append("=");
102: buf.append(atts.getValue(i));
103:
104: }
105: System.err.println(localName + buf.toString());
106: }
107:
108: final public void endElement(String namespaceURI, String localName,
109: String qName) throws SAXException {
110: if (delegate != null) {
111: delegate.endElement(namespaceURI, localName, qName);
112: //After this call the delegate can be null again.
113: }
114:
115: if (delegate == null) {
116: processEnd(namespaceURI, localName, qName);
117: //Check if end of delegation reached
118: if (entryLevel == level && parent != null) {
119: parent.stopDelegation();
120: }
121: level--;
122: }
123: }
124:
125: public void startPrefixMapping(String prefix, String uri)
126: throws SAXException {
127: if (delegate != null) {
128: delegate.startPrefixMapping(prefix, uri);
129: }
130: }
131:
132: public void skippedEntity(String name) throws SAXException {
133: if (delegate != null) {
134: delegate.skippedEntity(name);
135: }
136: }
137:
138: public void endPrefixMapping(String prefix) throws SAXException {
139: if (delegate != null) {
140: delegate.endPrefixMapping(prefix);
141: }
142: }
143:
144: public void ignorableWhitespace(char[] ch, int start, int length)
145: throws SAXException {
146: if (delegate != null) {
147: delegate.ignorableWhitespace(ch, start, length);
148: }
149: }
150:
151: public void processingInstruction(String target, String data)
152: throws SAXException {
153: if (delegate != null) {
154: delegate.processingInstruction(target, data);
155: }
156: }
157:
158: final public void characters(char[] ch, int start, int length)
159: throws SAXException {
160: if (delegate != null) {
161: delegate.characters(ch, start, length);
162: } else {
163: processCharacters(ch, start, length);
164: }
165: }
166:
167: public void processElement(String namespaceURI, String localName,
168: String qName, Attributes atts) throws SAXException {
169: }
170:
171: public void processEnd(String namespaceURI, String localName,
172: String qName) throws SAXException {
173: }
174:
175: /* Call this method to delegate the processessing of the encountered element with
176: all its subelements to another DelegationHandler.
177: */
178: public final void delegateElement(DelegationHandler child,
179: String namespaceURI, String localName, String qName,
180: Attributes atts) throws SAXException {
181: //System.out.println("Start delegation for " + localName);
182: delegate = child;
183: delegate.setDelegateLevel(level);
184: delegate.processElement(namespaceURI, localName, qName, atts);
185: }
186:
187: private void stopDelegation() {
188: delegate = null;
189: }
190:
191: private void setDelegateLevel(int level) {
192: this .entryLevel = level;
193: this .level = level;
194: }
195:
196: public void startContent() {
197: currentText = new StringBuffer();
198: }
199:
200: public String readContent() {
201: if (currentText == null)
202: return null;
203: String result = currentText.toString().trim();
204: currentText = null;
205: return result;
206: }
207:
208: public SAXParseException createSAXParseException(String message)
209: throws SAXParseException {
210: // This method resolves a bug with crimson. An EmtpyStacTraceException is
211: // thrown when you create a SAXParseException with a Locator
212: SAXParseException ex;
213: try {
214: ex = new SAXParseException(message, getLocator());
215: } catch (Exception e) {
216: ex = new SAXParseException(message, null);
217: }
218: return ex;
219: }
220:
221: public SAXParseException createSAXParseException(Exception ex)
222: throws SAXParseException {
223: String message = ex.getMessage();
224: if (message == null || message.length() == 0) {
225: StringWriter writer = new StringWriter();
226: PrintWriter print = new PrintWriter(writer);
227: ex.printStackTrace(print);
228: message = writer.toString();
229: }
230: return createSAXParseException(message);
231: }
232:
233: public void processCharacters(char ch[], int start, int length)
234: throws SAXException {
235: if (currentText != null)
236: currentText.append(ch, start, length);
237: }
238:
239: }
|