| /* |
| * Licensed to the Apache Software Foundation (ASF) under one or more |
| * contributor license agreements. See the NOTICE file distributed with |
| * this work for additional information regarding copyright ownership. |
| * The ASF licenses this file to You under the Apache License, Version 2.0 |
| * (the "License"); you may not use this file except in compliance with |
| * the License. You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, software |
| * distributed under the License is distributed on an "AS IS" BASIS, |
| * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| * See the License for the specific language governing permissions and |
| * limitations under the License. |
| */ |
| package org.apache.cocoon.forms.transformation; |
| |
| import java.util.LinkedList; |
| |
| import org.apache.cocoon.xml.AbstractXMLPipe; |
| import org.apache.cocoon.xml.SaxBuffer; |
| |
| import org.xml.sax.Attributes; |
| import org.xml.sax.ContentHandler; |
| import org.xml.sax.Locator; |
| import org.xml.sax.SAXException; |
| import org.xml.sax.ext.LexicalHandler; |
| import org.xml.sax.helpers.LocatorImpl; |
| |
| /** |
| * Base class for XMLPipe's. Allows the structure of the source code of |
| * the XMLPipe to match the structure of the data being transformed. |
| * |
| * @version $Id$ |
| */ |
| public class EffectPipe extends AbstractXMLPipe { |
| |
| /** |
| * Java 1.3 contentHandler access method. |
| * <br> |
| * Access to {#contentHandler} from inner class on Java 1.3 causes NoSuchMethod error. |
| */ |
| private ContentHandler getContentHandler() { |
| return super.contentHandler; |
| } |
| |
| /** |
| * Java 1.3 lexicalHandler access method. |
| * <br> |
| * Access to {#lexicalHandler} from inner class on Java 1.3 causes NoSuchMethod error. |
| */ |
| private LexicalHandler getLexicalHandler() { |
| return super.lexicalHandler; |
| } |
| |
| /** |
| * Handler interface. Accepts SAX events, can return other handler |
| * to replace self for further events. |
| */ |
| protected interface Handler { |
| public Handler startDocument() |
| throws SAXException; |
| |
| public void endDocument() |
| throws SAXException; |
| |
| public void startPrefixMapping(String prefix, String uri) |
| throws SAXException; |
| |
| public void endPrefixMapping(String prefix) |
| throws SAXException; |
| |
| public Handler startElement(String uri, String loc, String raw, Attributes attrs) |
| throws SAXException; |
| |
| /** |
| * Called before startElement, handler can decide what other handler should process |
| * next startElement. |
| */ |
| public Handler nestedElement(String uri, String loc, String raw, Attributes attrs) |
| throws SAXException; |
| |
| public void endElement(String uri, String loc, String raw) |
| throws SAXException; |
| |
| public Handler characters(char ch[], int start, int length) |
| throws SAXException; |
| |
| public Handler ignorableWhitespace(char ch[], int start, int length) |
| throws SAXException; |
| |
| public Handler processingInstruction(String target, String data) |
| throws SAXException; |
| |
| public Handler skippedEntity(String name) |
| throws SAXException; |
| |
| public Handler startDTD(String name, String publicId, String systemId) |
| throws SAXException; |
| |
| public Handler endDTD() |
| throws SAXException; |
| |
| public Handler startEntity(String name) |
| throws SAXException; |
| |
| public Handler endEntity(String name) |
| throws SAXException; |
| |
| public Handler startCDATA() |
| throws SAXException; |
| |
| public Handler endCDATA() |
| throws SAXException; |
| |
| public Handler comment(char c[], int start, int len) |
| throws SAXException; |
| } |
| |
| /** |
| * Ignores all events |
| */ |
| protected class NullHandler implements Handler { |
| public Handler startDocument() throws SAXException { |
| return this; |
| } |
| |
| public void endDocument() throws SAXException { |
| } |
| |
| public void startPrefixMapping(String prefix, String uri) throws SAXException { |
| } |
| |
| public void endPrefixMapping(String prefix) throws SAXException { |
| } |
| |
| public Handler nestedElement(String uri, String loc, String raw, Attributes attrs) throws SAXException { |
| return this; |
| } |
| |
| public Handler startElement(String uri, String loc, String raw, Attributes attrs) throws SAXException { |
| return this; |
| } |
| |
| public void endElement(String uri, String loc, String raw) throws SAXException { |
| } |
| |
| public Handler characters(char ch[], int start, int length) throws SAXException { |
| return this; |
| } |
| |
| public Handler ignorableWhitespace(char ch[], int start, int length) throws SAXException { |
| return this; |
| } |
| |
| public Handler processingInstruction(String target, String data) throws SAXException { |
| return this; |
| } |
| |
| public Handler skippedEntity(String name) throws SAXException { |
| return this; |
| } |
| |
| public Handler startDTD(String name, String publicId, String systemId) throws SAXException { |
| return this; |
| } |
| |
| public Handler endDTD() throws SAXException { |
| return this; |
| } |
| |
| public Handler startEntity(String name) throws SAXException { |
| return this; |
| } |
| |
| public Handler endEntity(String name) throws SAXException { |
| return this; |
| } |
| |
| public Handler startCDATA() throws SAXException { |
| return this; |
| } |
| |
| public Handler endCDATA() throws SAXException { |
| return this; |
| } |
| |
| public Handler comment(char c[], int start, int len) throws SAXException { |
| return this; |
| } |
| } |
| |
| /** |
| * Buffers content into the pipe's SAX buffer. |
| */ |
| protected class BufferHandler extends NullHandler { |
| public Handler startDocument() throws SAXException { |
| if (buffer != null) buffer.startDocument(); |
| return this; |
| } |
| |
| public void setDocumentLocator(Locator paramLocator) { |
| locator = new LocatorImpl(paramLocator); |
| if (buffer != null) buffer.setDocumentLocator(paramLocator); |
| } |
| |
| public void endDocument() throws SAXException { |
| if (buffer != null) buffer.endDocument(); |
| } |
| |
| public void startPrefixMapping(String prefix, String uri) throws SAXException { |
| if (buffer != null) buffer.startPrefixMapping(prefix, uri); |
| } |
| |
| public void endPrefixMapping(String prefix) throws SAXException { |
| if (buffer != null) buffer.endPrefixMapping(prefix); |
| } |
| |
| public Handler startElement(String uri, String loc, String raw, Attributes attrs) throws SAXException { |
| if (buffer != null) buffer.startElement(uri, loc, raw, attrs); |
| return this; |
| } |
| |
| public void endElement(String uri, String loc, String raw) throws SAXException { |
| if (buffer != null) buffer.endElement(uri, loc, raw); |
| } |
| |
| public Handler characters(char ch[], int start, int length) throws SAXException { |
| if (buffer != null) buffer.characters(ch, start, length); |
| return this; |
| } |
| |
| public Handler ignorableWhitespace(char ch[], int start, int length) throws SAXException { |
| if (buffer != null) buffer.ignorableWhitespace(ch, start, length); |
| return this; |
| } |
| |
| public Handler processingInstruction(String target, String data) throws SAXException { |
| if (buffer != null) buffer.processingInstruction(target, data); |
| return this; |
| } |
| |
| public Handler skippedEntity(String name) throws SAXException { |
| if (buffer != null) buffer.skippedEntity(name); |
| return this; |
| } |
| |
| public Handler startDTD(String name, String publicId, String systemId) throws SAXException { |
| if (buffer != null) buffer.startDTD(name, publicId, systemId); |
| return this; |
| } |
| |
| public Handler endDTD() throws SAXException { |
| if (buffer != null) buffer.endDTD(); |
| return this; |
| } |
| |
| public Handler startEntity(String name) throws SAXException { |
| if (buffer != null) buffer.startEntity(name); |
| return this; |
| } |
| |
| public Handler endEntity(String name) throws SAXException { |
| if (buffer != null) buffer.endEntity(name); |
| return this; |
| } |
| |
| public Handler startCDATA() throws SAXException { |
| if (buffer != null) buffer.startCDATA(); |
| return this; |
| } |
| |
| public Handler endCDATA() throws SAXException { |
| if (buffer != null) buffer.endCDATA(); |
| return this; |
| } |
| |
| public Handler comment(char c[], int start, int len) throws SAXException { |
| if (buffer != null) buffer.comment(c, start, len); |
| return this; |
| } |
| } |
| |
| /** |
| * Copies events over into the contentHandler |
| */ |
| protected class CopyHandler extends NullHandler { |
| public Handler startDocument() throws SAXException { |
| getContentHandler().startDocument(); |
| return this; |
| } |
| |
| public void endDocument() throws SAXException { |
| getContentHandler().endDocument(); |
| } |
| |
| public void startPrefixMapping(String prefix, String uri) throws SAXException { |
| getContentHandler().startPrefixMapping(prefix, uri); |
| } |
| |
| public void endPrefixMapping(String prefix) throws SAXException { |
| getContentHandler().endPrefixMapping(prefix); |
| } |
| |
| public Handler startElement(String uri, String loc, String raw, Attributes attrs) throws SAXException { |
| getContentHandler().startElement(uri, loc, raw, attrs); |
| return this; |
| } |
| |
| public void endElement(String uri, String loc, String raw) throws SAXException { |
| getContentHandler().endElement(uri, loc, raw); |
| } |
| |
| public Handler characters(char ch[], int start, int length) throws SAXException { |
| getContentHandler().characters(ch, start, length); |
| return this; |
| } |
| |
| public Handler ignorableWhitespace(char ch[], int start, int length) throws SAXException { |
| getContentHandler().ignorableWhitespace(ch, start, length); |
| return this; |
| } |
| |
| public Handler processingInstruction(String target, String data) throws SAXException { |
| getContentHandler().processingInstruction(target, data); |
| return this; |
| } |
| |
| public Handler skippedEntity(String name) throws SAXException { |
| getContentHandler().skippedEntity(name); |
| return this; |
| } |
| |
| public Handler startDTD(String name, String publicId, String systemId) throws SAXException { |
| if (getLexicalHandler() != null) getLexicalHandler().startDTD(name, publicId, systemId); |
| return this; |
| } |
| |
| public Handler endDTD() throws SAXException { |
| if (getLexicalHandler() != null) getLexicalHandler().endDTD(); |
| return this; |
| } |
| |
| public Handler startEntity(String name) throws SAXException { |
| if (getLexicalHandler() != null) getLexicalHandler().startEntity(name); |
| return this; |
| } |
| |
| public Handler endEntity(String name) throws SAXException { |
| if (getLexicalHandler() != null) getLexicalHandler().endEntity(name); |
| return this; |
| } |
| |
| public Handler startCDATA() throws SAXException { |
| if (getLexicalHandler() != null) getLexicalHandler().startCDATA(); |
| return this; |
| } |
| |
| public Handler endCDATA() throws SAXException { |
| if (getLexicalHandler() != null) getLexicalHandler().endCDATA(); |
| return this; |
| } |
| |
| public Handler comment(char c[], int start, int len) throws SAXException { |
| if (getLexicalHandler() != null) getLexicalHandler().comment(c, start, len); |
| return this; |
| } |
| } |
| |
| /** |
| * Throws exception on most events, with the exception of ignorableWhitespace. |
| */ |
| protected class ErrorHandler extends NullHandler { |
| protected String getName() { |
| return "<unknown>"; |
| } |
| |
| public Handler startDocument() throws SAXException { |
| throw new SAXException("Unexpected startDocument in '" + getName() + "' (" + getLocation() + ")"); |
| } |
| |
| public void endDocument() throws SAXException { |
| throw new SAXException("Unexpected endDocument in '" + getName() + "' (" + getLocation() + ")"); |
| } |
| |
| public void startPrefixMapping(String prefix, String uri) throws SAXException { |
| throw new SAXException("Unexpected startPrefixMapping in '" + getName() + "' (" + getLocation() + ")"); |
| } |
| |
| public void endPrefixMapping(String prefix) throws SAXException { |
| throw new SAXException("Unexpected endPrefixMapping in '" + getName() + "' (" + getLocation() + ")"); |
| } |
| |
| public Handler startElement(String uri, String loc, String raw, Attributes attrs) throws SAXException { |
| throw new SAXException("Unexpected startElement in '" + getName() + "' (" + getLocation() + ")"); |
| } |
| |
| public void endElement(String uri, String loc, String raw) throws SAXException { |
| throw new SAXException("Unexpected endElement in '" + getName() + "' (" + getLocation() + ")"); |
| } |
| |
| public Handler characters(char ch[], int start, int length) throws SAXException { |
| throw new SAXException("Unexpected characters in '" + getName() + "' (" + getLocation() + ")"); |
| } |
| |
| public Handler processingInstruction(String target, String data) throws SAXException { |
| throw new SAXException("Unexpected processingInstruction in '" + getName() + "' (" + getLocation() + ")"); |
| } |
| |
| public Handler skippedEntity(String name) throws SAXException { |
| throw new SAXException("Unexpected skippedEntity in '" + getName() + "' (" + getLocation() + ")"); |
| } |
| |
| public Handler startDTD(String name, String publicId, String systemId) throws SAXException { |
| throw new SAXException("Unexpected startDTD in '" + getName() + "' (" + getLocation() + ")"); |
| } |
| |
| public Handler endDTD() throws SAXException { |
| throw new SAXException("Unexpected endDTD in '" + getName() + "' (" + getLocation() + ")"); |
| } |
| |
| public Handler startEntity(String name) throws SAXException { |
| throw new SAXException("Unexpected startEntity in '" + getName() + "' (" + getLocation() + ")"); |
| } |
| |
| public Handler endEntity(String name) throws SAXException { |
| throw new SAXException("Unexpected endEntity in '" + getName() + "' (" + getLocation() + ")"); |
| } |
| |
| public Handler startCDATA() throws SAXException { |
| throw new SAXException("Unexpected startCDATA in '" + getName() + "' (" + getLocation() + ")"); |
| } |
| |
| public Handler endCDATA() throws SAXException { |
| throw new SAXException("Unexpected endCDATA in '" + getName() + "' (" + getLocation() + ")"); |
| } |
| |
| public Handler comment(char c[], int start, int len) throws SAXException { |
| throw new SAXException("Unexpected comment in '" + getName() + "' (" + getLocation() + ")"); |
| } |
| } |
| |
| protected final Handler hNull = new NullHandler(); |
| protected final Handler hBuffer = new BufferHandler(); |
| |
| protected Locator locator; |
| private LinkedList handlers; |
| private Handler handler; |
| |
| private LinkedList buffers; |
| private LinkedList locators; |
| protected SaxBuffer buffer; |
| |
| |
| /** |
| * Initialize the pipe before starting processing |
| */ |
| protected void init(Handler top) { |
| locators = new LinkedList(); |
| handlers = new LinkedList(); |
| handler = top; |
| } |
| |
| /** |
| * Recycle the pipe after processing |
| */ |
| public void recycle() { |
| super.recycle(); |
| handlers = null; |
| handler = null; |
| buffers = null; |
| buffer = null; |
| locator = null; |
| locators = null; |
| } |
| |
| /** |
| * @return current location (if known) |
| */ |
| protected String getLocation() { |
| if (locator == null) { |
| return "unknown"; |
| } |
| |
| return " (" + locator.getSystemId() + ":" + |
| locator.getLineNumber() + ":" + |
| locator.getColumnNumber() + ")"; |
| } |
| |
| protected void pushHandler(Handler handler) { |
| this.handlers.addFirst(this.handler); |
| this.handler = handler; |
| } |
| |
| protected void popHandler() { |
| this.handler = (Handler) this.handlers.removeFirst(); |
| } |
| |
| protected void beginBuffer() { |
| if (this.buffer != null) { |
| if (this.buffers == null) { |
| this.buffers = new LinkedList(); |
| } |
| this.buffers.addFirst(this.buffer); |
| } |
| if (locator != null) { |
| locators.addFirst(locator); |
| locator = new LocatorImpl(locator); |
| } |
| this.buffer = new SaxBuffer(); |
| } |
| |
| protected SaxBuffer endBuffer() { |
| SaxBuffer buffer = this.buffer; |
| if (this.buffers != null && this.buffers.size() > 0) { |
| this.buffer = (SaxBuffer) this.buffers.removeFirst(); |
| } else { |
| this.buffer = null; |
| } |
| if (locator != null) { |
| locator = (Locator)locators.removeFirst(); |
| } |
| return buffer; |
| } |
| |
| // |
| // ContentHandler methods |
| // |
| |
| public void setDocumentLocator(Locator locator) { |
| this.locator = locator; |
| } |
| |
| public void startDocument() throws SAXException { |
| pushHandler(handler.startDocument()); |
| } |
| |
| public void endDocument() throws SAXException { |
| handler.endDocument(); |
| popHandler(); |
| } |
| |
| public void startPrefixMapping(String prefix, String uri) throws SAXException { |
| handler.startPrefixMapping(prefix, uri); |
| } |
| |
| public void endPrefixMapping(String prefix) throws SAXException { |
| handler.endPrefixMapping(prefix); |
| } |
| |
| public void startElement(String uri, String loc, String raw, Attributes attrs) throws SAXException { |
| pushHandler(handler.nestedElement(uri, loc, raw, attrs)); |
| handler = handler.startElement(uri, loc, raw, attrs); |
| } |
| |
| public void endElement(String uri, String loc, String raw) throws SAXException { |
| handler.endElement(uri, loc, raw); |
| popHandler(); |
| } |
| |
| public void characters(char ch[], int start, int len) throws SAXException { |
| handler = handler.characters(ch, start, len); |
| } |
| |
| public void ignorableWhitespace(char ch[], int start, int len) throws SAXException { |
| handler = handler.ignorableWhitespace(ch, start, len); |
| } |
| |
| public void processingInstruction(String target, String data) throws SAXException { |
| handler = handler.processingInstruction(target, data); |
| } |
| |
| public void skippedEntity(String name) throws SAXException { |
| handler = handler.skippedEntity(name); |
| } |
| |
| // |
| // LexicalHandler methods |
| // |
| |
| public void startDTD(String name, String publicId, String systemId) throws SAXException { |
| handler = handler.startDTD(name, publicId, systemId); |
| } |
| |
| public void endDTD() throws SAXException { |
| handler = handler.endDTD(); |
| } |
| |
| public void startEntity(String name) throws SAXException { |
| handler = handler.startEntity(name); |
| } |
| |
| public void endEntity(String name) throws SAXException { |
| handler = handler.endEntity(name); |
| } |
| |
| public void startCDATA() throws SAXException { |
| handler = handler.startCDATA(); |
| } |
| |
| public void endCDATA() throws SAXException { |
| handler = handler.endCDATA(); |
| } |
| |
| public void comment(char ch[], int start, int len) throws SAXException { |
| handler = handler.comment(ch, start, len); |
| } |
| } |