Package org.apache.cocoon.woody.transformation

Source Code of org.apache.cocoon.woody.transformation.EffectPipe

/*
* Copyright 1999-2004 The Apache Software Foundation.
*
* Licensed 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.woody.transformation;

import java.util.LinkedList;

import org.apache.cocoon.woody.Constants;
import org.apache.cocoon.xml.AbstractXMLPipe;
import org.apache.cocoon.xml.SaxBuffer;
import org.apache.cocoon.xml.XMLConsumer;
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.AttributesImpl;

// TODO: Reduce the Element creation and deletion churn by providing startElement
// and endElement methods which do not create or use Elements on the stack.
/*
* Base class for XMLPipe's. Allows the structure of the source code of
* the XMLPipe to match the structure of the data being transformed.
*
* @author Timothy Larson
* @version $Id: EffectPipe.java,v 1.11 2004/03/09 13:54:12 reinhard Exp $
*/
public class EffectPipe extends AbstractXMLPipe {

    protected static final int EVENT_SET_DOCUMENT_LOCATOR   = 0;
    protected static final int EVENT_START_DOCUMENT         = 1;
    protected static final int EVENT_END_DOCUMENT           = 2;
    protected static final int EVENT_START_PREFIX_MAPPING   = 3;
    protected static final int EVENT_END_PREFIX_MAPPING     = 4;
    protected static final int EVENT_START_ELEMENT          = 5;
    protected static final int EVENT_END_ELEMENT            = 6;
    protected static final int EVENT_ELEMENT                = 7;
    protected static final int EVENT_CHARACTERS             = 8;
    protected static final int EVENT_IGNORABLE_WHITESPACE   = 9;
    protected static final int EVENT_PROCESSING_INSTRUCTION =10;
    protected static final int EVENT_SKIPPED_ENTITY         =11;
    protected static final int EVENT_START_DTD              =12;
    protected static final int EVENT_END_DTD                =13;
    protected static final int EVENT_START_ENTITY           =14;
    protected static final int EVENT_END_ENTITY             =15;
    protected static final int EVENT_START_CDATA            =16;
    protected static final int EVENT_END_CDATA              =17;
    protected static final int EVENT_COMMENT                =18;

    protected class Element {
        public String prefix;
        public String uri;
        public String loc;
        public String raw;
        public Attributes attrs;
        public boolean mine;

        public Element() {
            prefix = null; uri = null; loc = null; raw = null; attrs = Constants.EMPTY_ATTRS; mine = true;
        }

        public Element(String prefix, String uri) {
            this.prefix = prefix;
            this.uri = uri;
        }

        public Element(String uri, String loc, String raw, Attributes attrs) {
            this.uri = uri;
            this.loc = loc;
            this.raw = raw;
            this.attrs = Constants.EMPTY_ATTRS;
            if (attrs == null) {
                this.attrs = Constants.EMPTY_ATTRS;
                mine = true;
            } else {
                this.attrs = attrs;
                mine = false;
            }
        }

        public void addAttributes(Attributes attrs) {
            if (attrs != null) {
                if (mine == true) {
                    if (this.attrs == Constants.EMPTY_ATTRS) {
                        this.attrs = attrs;
                        mine = false;
                    } else {
                        ((AttributesImpl)this.attrs).setAttributes(attrs);
                    }
                } else {
                    this.attrs = new AttributesImpl(this.attrs);
                    ((AttributesImpl)this.attrs).setAttributes(attrs);
                    mine = true;
                }
            }
        }

        public void addAttribute(String uri, String loc, String raw, String type, String value) {
            if (!mine || attrs == Constants.EMPTY_ATTRS) {
                attrs = new AttributesImpl(attrs);
                mine = true;
            }
            ((AttributesImpl)attrs).addAttribute(uri, loc, raw, type, value);
        }

        public void addAttribute(String prefix, String uri, String loc, String value) {
            if (!mine || attrs == Constants.EMPTY_ATTRS) {
                attrs = new AttributesImpl(attrs);
                mine = true;
            }
            ((AttributesImpl)attrs).addAttribute(uri, loc, prefix + ":" +loc, "CDATA", value);
        }

        public void addAttribute(String loc, String value) {
            if (!mine || attrs == Constants.EMPTY_ATTRS) {
                attrs = new AttributesImpl(attrs);
                mine = true;
            }
            ((AttributesImpl)attrs).addAttribute("", loc, loc, "CDATA", value);
        }

        public void claimAttributes() {
            if (!mine) {
                attrs = new AttributesImpl(attrs);
                mine = true;
            }
        }
    }

    protected abstract class Handler {
        public abstract Handler process() throws SAXException;
    }

    protected class NullHandler extends Handler {
        public Handler process() throws SAXException {
            return this;
        }
    }

    protected class BufferHandler extends Handler {
        public Handler process() throws SAXException {
            switch (event) {
            case EVENT_ELEMENT:
                return this;
            default:
                out.buffer();
                return this;
            }
        }
    }

    protected class Output extends AbstractXMLPipe {
        private LinkedList buffers = null;
        private SaxBuffer saxBuffer = null;
        private LinkedList elements  = null;
        protected Element element  = null;

        public Output() { elements = new LinkedList(); }

        public void startPrefixMapping() throws SAXException {
            super.startPrefixMapping(input.prefix, input.uri);
        }

        public void endPrefixMapping() throws SAXException {
            super.endPrefixMapping(input.prefix);
        }

        public void element(String prefix, String uri, String loc, Attributes attrs) throws SAXException {
            element = new Element(uri, loc, prefix + ":" + loc, attrs);
        }

        public void element(String prefix, String uri, String loc) throws SAXException {
            element(prefix, uri, loc, null);
        }

        public void element(String loc, Attributes attrs) throws SAXException {
            element = new Element("", loc, loc, attrs);
        }

        public void element(String loc) throws SAXException {
            element(loc, null);
        }

        public void element() throws SAXException {
            element = new Element(input.uri, input.loc, input.raw, input.attrs);
        }

        public void attribute(String prefix, String uri, String name, String value) throws SAXException {
            element.addAttribute(prefix, uri, name, value);
        }

        public void attribute(String name, String value) throws SAXException {
            element.addAttribute(name, value);
        }

        public void copyAttribute(String prefix, String uri, String name) throws SAXException {
            String value = null;
            if (input.attrs != null && (value = input.attrs.getValue(uri, name)) != null) {
                attribute(prefix, uri, name, value);
            } else {
                throw new SAXException("Attribute \"" + name + "\" cannot be copied because it does not exist.");
            }
        }

        public void attributes(Attributes attrs) throws SAXException {
            element.addAttributes(attrs);
        }

        public void attributes() throws SAXException {
            attributes(input.attrs);
        }

        public void startElement() throws SAXException {
            if (element.attrs == null) {
                element.attrs = Constants.EMPTY_ATTRS;
            }
            super.startElement(element.uri, element.loc, element.raw, element.attrs);
            elements.addFirst(element);
            element = null;
        }

        public void endElement() throws SAXException {
            element = (Element)elements.removeFirst();
            super.endElement(element.uri, element.loc, element.raw);
            element = null;
        }

        public void startElement(String uri, String loc, String raw, Attributes attrs) throws SAXException {
            super.startElement(uri, loc, raw, attrs);
        }

        public void endElement(String uri, String loc, String raw) throws SAXException {
            super.endElement(uri, loc, raw);
        }

        public void copy() throws SAXException {
            switch(event) {
            case EVENT_SET_DOCUMENT_LOCATOR:   this.setDocumentLocator(locator); break;
            case EVENT_START_DOCUMENT:         this.startDocument(); break;
            case EVENT_END_DOCUMENT:           this.endDocument(); break;
            case EVENT_START_PREFIX_MAPPING:   this.startPrefixMapping(); break;
            case EVENT_END_PREFIX_MAPPING:     this.endPrefixMapping(); break;
            case EVENT_START_ELEMENT:          this.element(); attributes(); startElement(); break;
            case EVENT_END_ELEMENT:            this.endElement(); break;
            case EVENT_CHARACTERS:             this.characters(c, start, len); break;
            case EVENT_IGNORABLE_WHITESPACE:   this.ignorableWhitespace(c, start, len); break;
            case EVENT_PROCESSING_INSTRUCTION: this.processingInstruction(target, data); break;
            case EVENT_SKIPPED_ENTITY:         this.skippedEntity(name); break;
            case EVENT_START_DTD:              this.startDTD(name, publicId, systemId); break;
            case EVENT_END_DTD:                this.endDTD(); break;
            case EVENT_START_ENTITY:           this.startEntity(name); break;
            case EVENT_END_ENTITY:             this.endEntity(name); break;
            case EVENT_START_CDATA:            this.startCDATA(); break;
            case EVENT_END_CDATA:              this.endCDATA(); break;
            case EVENT_COMMENT:                this.comment(c, start, len); break;
            }
        }

        protected void bufferInit() {
            if (saxBuffer != null) {
                if (buffers == null) {
                    buffers = new LinkedList();
                }
                buffers.addFirst(saxBuffer);
            }
            saxBuffer = new SaxBuffer();
        }

        protected void bufferFini() {
            if (buffers != null && buffers.size() > 0) {
                saxBuffer = (SaxBuffer)buffers.removeFirst();
            } else {
                saxBuffer = null;
            }
        }

        protected SaxBuffer getBuffer() {
            return saxBuffer;
        }

        public void buffer() throws SAXException {
            switch(event) {
            case EVENT_SET_DOCUMENT_LOCATOR:   saxBuffer.setDocumentLocator(locator); break;
            case EVENT_START_DOCUMENT:         saxBuffer.startDocument(); break;
            case EVENT_END_DOCUMENT:           saxBuffer.endDocument(); break;
            case EVENT_START_PREFIX_MAPPING:   saxBuffer.startPrefixMapping(prefix, uri); break;
            case EVENT_END_PREFIX_MAPPING:     saxBuffer.endPrefixMapping(prefix); break;
            case EVENT_START_ELEMENT:          saxBuffer.startElement(input.uri, input.loc, input.raw, input.attrs); break;
            case EVENT_END_ELEMENT:            saxBuffer.endElement(input.uri, input.loc, input.raw); break;
            case EVENT_CHARACTERS:             saxBuffer.characters(c, start, len); break;
            case EVENT_IGNORABLE_WHITESPACE:   saxBuffer.ignorableWhitespace(c, start, len); break;
            case EVENT_PROCESSING_INSTRUCTION: saxBuffer.processingInstruction(target, data); break;
            case EVENT_SKIPPED_ENTITY:         saxBuffer.skippedEntity(name); break;
            case EVENT_START_DTD:              saxBuffer.startDTD(name, publicId, systemId); break;
            case EVENT_END_DTD:                saxBuffer.endDTD(); break;
            case EVENT_START_ENTITY:           saxBuffer.startEntity(name); break;
            case EVENT_END_ENTITY:             saxBuffer.endEntity(name); break;
            case EVENT_START_CDATA:            saxBuffer.startCDATA(); break;
            case EVENT_END_CDATA:              saxBuffer.endCDATA(); break;
            case EVENT_COMMENT:                saxBuffer.comment(c, start, len); break;
            }
        }
    }


    protected int event = 0;

    protected Handler nullHandler = new NullHandler();
    protected Handler bufferHandler = new BufferHandler();

    protected LinkedList handlers = null;
    protected Handler handler = null;

    protected LinkedList elements = null;
    protected Element input = null;

    protected Locator locator = null;
    protected String name     = null;
    protected String publicId = null;
    protected String systemId = null;
    protected String target   = null;
    protected String data     = null;
    protected String prefix   = null;
    protected String uri      = null;
    protected char   c[]      = null;
    protected int start = 0;
    protected int len = 0;

    public Output out = null;

    public void init() {
        handlers = new LinkedList();
        elements = new LinkedList();
        out = new Output();
    }

    //====================================
    // Methods overriding AbstractXMLPipe
    //====================================

    public void setConsumer(XMLConsumer consumer) {
        super.setConsumer(consumer);
        out.setConsumer(consumer);
    }

    public void setContentHandler(ContentHandler handler) {
        super.setContentHandler(handler);
        out.setContentHandler(handler);
    }

    public void setLexicalHandler(LexicalHandler handler) {
        super.setLexicalHandler(handler);
        out.setLexicalHandler(handler);
    }

    public void recycle() {
        super.recycle();
        handlers = null;
        elements = null;
        out = null;
    }

    public void setDocumentLocator(Locator locator) {
        this.locator = locator;
        try {
            event = EVENT_SET_DOCUMENT_LOCATOR; handler = handler.process();
        } catch(Exception e) {
            throw new RuntimeException(e.getMessage());
        }
    }

    public void startDocument() throws SAXException { event = EVENT_START_DOCUMENT; handler = handler.process(); }

    public void endDocument() throws SAXException { event = EVENT_END_DOCUMENT; handler = handler.process(); }

    public void startPrefixMapping(String prefix, String uri) throws SAXException {
        input = new Element(prefix, uri);
        elements.addFirst(input);
        //this.prefix = prefix; this.uri = uri;
        event = EVENT_START_PREFIX_MAPPING; handler = handler.process();
    }

    public void endPrefixMapping(String prefix) throws SAXException {
        input = (Element)elements.removeFirst();
        //this.prefix = prefix;
        event = EVENT_END_PREFIX_MAPPING; handler = handler.process();
        input = null;
    }

    public void startElement(String uri, String loc, String raw, Attributes attrs) throws SAXException {
        input = new Element(uri, loc, raw, attrs);
        elements.addFirst(input);
        handlers.addFirst(handler);
        event = EVENT_ELEMENT;       handler = handler.process();
        event = EVENT_START_ELEMENT; handler = handler.process();
    }

    public void endElement(String uri, String loc, String raw) throws SAXException {
        input = (Element)elements.removeFirst();
        event = EVENT_END_ELEMENT; handler.process();
        handler = (Handler)handlers.removeFirst();
        input = null;
    }

    public void characters(char c[], int start, int len) throws SAXException {
        this.c = c; this.start = start; this.len = len;
        event = EVENT_CHARACTERS; handler = handler.process();
    }

    public void ignorableWhitespace(char c[], int start, int len) throws SAXException {
        this.c = c; this.start = start; this.len = len;
        event = EVENT_IGNORABLE_WHITESPACE; handler = handler.process();
    }

    public void processingInstruction(String target, String data) throws SAXException {
        this.target = target; this.data = data;
        event = EVENT_PROCESSING_INSTRUCTION; handler = handler.process();
    }

    public void skippedEntity(String name) throws SAXException {
        this.name = name;
        event = EVENT_SKIPPED_ENTITY; handler = handler.process();
    }

    public void startDTD(String name, String publicId, String systemId) throws SAXException {
        this.name = name; this.publicId = publicId; this.systemId = systemId;
        event = EVENT_START_DTD; handler = handler.process();
    }

    public void endDTD() throws SAXException { event = EVENT_END_DTD; handler = handler.process(); }

    public void startEntity(String name) throws SAXException {
        this.name = name;
        event = EVENT_START_ENTITY; handler = handler.process();
    }

    public void endEntity(String name) throws SAXException {
        this.name = name;
        event = EVENT_END_ENTITY; handler = handler.process();
    }

    public void startCDATA() throws SAXException {
        event = EVENT_START_CDATA; handler = handler.process();
    }

    public void endCDATA() throws SAXException {
        event = EVENT_END_CDATA; handler = handler.process();
    }

    public void comment(char c[], int start, int len) throws SAXException {
        this.c = c; this.start = start; this.len = len;
        event = EVENT_COMMENT; handler = handler.process();
    }
}
TOP

Related Classes of org.apache.cocoon.woody.transformation.EffectPipe

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.