All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.ajax4jsf.io.SAXResponseWriter Maven / Gradle / Ivy

The newest version!
/*
 * JBoss, Home of Professional Open Source
 * Copyright 2013, Red Hat, Inc. and individual contributors
 * by the @authors tag. See the copyright.txt in the distribution for a
 * full listing of individual contributors.
 *
 * This is free software; you can redistribute it and/or modify it
 * under the terms of the GNU Lesser General Public License as
 * published by the Free Software Foundation; either version 2.1 of
 * the License, or (at your option) any later version.
 *
 * This software is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this software; if not, write to the Free
 * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
 * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
 */
package org.ajax4jsf.io;

import java.io.IOException;
import java.io.Writer;

import javax.faces.component.UIComponent;
import javax.faces.context.ResponseWriter;

import org.xml.sax.ContentHandler;
import org.xml.sax.SAXException;
import org.xml.sax.ext.LexicalHandler;
import org.xml.sax.helpers.AttributesImpl;

/**
 * Realization of Faces ResponseWriter for Cocoon Environment. Use ONLY Markup-specific calls , send it as
 * SAX events to XMLConsumer Use "State" pattern for control of events flow. TODO - implement namespace
 * capabilites
 *
 * @author shura
 */
public class SAXResponseWriter extends ResponseWriter {
    /**
     * As we in XML framework, only UTF-8 supported for CHARTER_ENCODING
     */
    private static final String CHARTER_ENCODING = "UTF-8";
    /**
     * As we in XML framework, only xml supported for CONTENT_TYPE
     */
    private static final String CONTENT_TYPE = "text/xml";
    private String namespaceURI = "http://www.w3.org/1999/xhtml";
    private LexicalHandler xmlLexicalHandler = null;
    private AttributesImpl attributes;
    private XMLResponseWriterState cdataState;
    private String element;
    /**
     * State after startElement. Collect Attributes for SAX startElement elementState
     */
    private XMLResponseWriterState elementState;
    /**
     * State in normal document inDocumentState
     */
    private XMLResponseWriterState inDocumentState;
    /**
     * Before StartDocument or after EndDocument notDocumentState
     */
    private XMLResponseWriterState notDocumentState;
    private XMLResponseWriterState state;
    /**
     * Hold Cocoon Generator XML consumer
     */
    private ContentHandler xmlConsumer;

    /**
     * @param consumer - SAX events receiver for Cocoon pipeline.
     */
    public SAXResponseWriter(ContentHandler consumer) {
        super();
        this.xmlConsumer = consumer;

        if (consumer instanceof LexicalHandler) {
            xmlLexicalHandler = (LexicalHandler) consumer;
        }

        // Initialise states. May be must implemented in static block ?
        this.notDocumentState = new NotDocumentState();

        // inside document. allow any events exclude attributes and
        // startDocument.
        this.inDocumentState = new InDocumentState();
        this.cdataState = new CDATAState();

        // In element, collect attributes ...
        this.elementState = new ElementState();
        this.state = notDocumentState;
    }

    public ContentHandler getXmlConsumer() {
        return xmlConsumer;
    }

    /**
     * @return Returns the namespaceURI.
     */
    public String getNamespaceURI() {
        return namespaceURI;
    }

    /**
     * @param namespaceURI The namespaceURI to set.
     */
    public void setNamespaceURI(String namespaceURI) {
        this.namespaceURI = namespaceURI;
    }

    /*
     * (non-Javadoc)
     *
     * @see javax.faces.context.ResponseWriter#getContentType()
     */
    public String getContentType() {
        return CONTENT_TYPE;
    }

    /*
     * (non-Javadoc)
     *
     * @see javax.faces.context.ResponseWriter#getCharacterEncoding()
     */
    public String getCharacterEncoding() {
        return CHARTER_ENCODING;
    }

    /*
     * (non-Javadoc)
     *
     * @see java.io.Flushable#flush()
     */
    public void flush() throws IOException {

        // DO NOTHING...
    }

    /*
     * (non-Javadoc)
     *
     * @see javax.faces.context.ResponseWriter#startDocument()
     */
    public void startDocument() throws IOException {
        state.startDocument();
    }

    /*
     * (non-Javadoc)
     *
     * @see javax.faces.context.ResponseWriter#endDocument()
     */
    public void endDocument() throws IOException {
        state.endDocument();
    }

    /*
     * (non-Javadoc)
     *
     * @see javax.faces.context.ResponseWriter#startElement(java.lang.String, javax.faces.component.UIComponent)
     */
    public void startElement(String name, UIComponent component) throws IOException {
        state.startElement(name, component);
    }

    /*
     * (non-Javadoc)
     *
     * @see javax.faces.context.ResponseWriter#endElement(java.lang.String)
     */
    public void endElement(String name) throws IOException {
        state.endElement(name);
    }

    /*
     * (non-Javadoc)
     *
     * @see javax.faces.context.ResponseWriter#writeAttribute(java.lang.String, java.lang.Object, java.lang.String)
     */
    public void writeAttribute(String name, Object value, String property) throws IOException {
        state.writeAttribute(name, value, property);
    }

    /*
     * (non-Javadoc)
     *
     * @see javax.faces.context.ResponseWriter#writeURIAttribute(java.lang.String, java.lang.Object, java.lang.String)
     */
    public void writeURIAttribute(String name, Object value, String property) throws IOException {
        state.writeURIAttribute(name, value, property);
    }

    /*
     * (non-Javadoc)
     *
     * @see javax.faces.context.ResponseWriter#writeComment(java.lang.Object)
     */
    public void writeComment(Object comment) throws IOException {
        state.writeComment(comment);
    }

    /*
     * (non-Javadoc)
     *
     * @see javax.faces.context.ResponseWriter#writeText(java.lang.Object, java.lang.String)
     */
    public void writeText(Object text, String property) throws IOException {
        state.writeText(text, property);
    }

    /*
     * (non-Javadoc)
     *
     * @see javax.faces.context.ResponseWriter#writeText(char[], int, int)
     */
    public void writeText(char[] text, int off, int len) throws IOException {
        state.writeText(text, off, len);
    }

    /*
     * (non-Javadoc)
     *
     * @see javax.faces.context.ResponseWriter#cloneWithWriter(java.io.Writer)
     */
    public ResponseWriter cloneWithWriter(Writer writer) {

        // TODO as used XML consumer to get sax Events, we simple return current
        // instance.
        // if will used wrapper to combine XML Consumer with plain Servlet
        // responce writer, must
        // perform real clone ...
        // We can use org.apache.cocoon.xml.SaxBuffer;
        return this;
    }

    /*
     * (non-Javadoc)
     *
     * @see java.io.Writer#write(char[], int, int)
     */
    public void write(char[] cbuf, int off, int len) throws IOException {
        state.writeText(cbuf, off, len);
    }

    /*
     * (non-Javadoc)
     *
     * @see java.io.Closeable#close()
     */
    public void close() throws IOException {

        // TODO Auto-generated method stub
    }

    /**
     * @author shura
     *         

* CDATA section. allow regular write() functions, write any text. */ private final class CDATAState extends XMLResponseWriterState { void flushCDATA() throws IOException { // try { // xmlConsumer.endCDATA(); // } catch (SAXException e) { // throw new IOException("Exception in endCDATA: "+ e.getMessage()); // } } /* * (non-Javadoc) * * @see org.apache.cocoon.components.faces.context.XMLResponseWriterState#endDocument() */ void endDocument() throws IOException { flushCDATA(); state = inDocumentState; state.endDocument(); } /* * (non-Javadoc) * * @see org.apache.cocoon.components.faces.context.XMLResponseWriterState#endElement(java.lang.String) */ void endElement(String name) throws IOException { flushCDATA(); state = inDocumentState; state.endElement(name); } /* * (non-Javadoc) * * @see org.apache.cocoon.components.faces.context.XMLResponseWriterState#startElement(java.lang.String, * javax.faces.component.UIComponent) */ void startElement(String name, UIComponent component) throws IOException { flushCDATA(); element = name; attributes = new AttributesImpl(); state = elementState; } /* * (non-Javadoc) * * @see org.apache.cocoon.components.faces.context.XMLResponseWriterState#writeComment(java.lang.Object) */ void writeComment(Object comment) throws IOException { flushCDATA(); state = inDocumentState; state.writeComment(comment); } /* * (non-Javadoc) * * @see org.apache.cocoon.components.faces.context.XMLResponseWriterState#writeText(char[], int, int) */ void writeText(char[] text, int off, int len) throws IOException { try { xmlConsumer.characters(text, off, len); } catch (SAXException e) { throw new IOException("Sax exceptions in writeText: " + e.getMessage()); } } /* * (non-Javadoc) * * @see org.apache.cocoon.components.faces.context.XMLResponseWriterState#writeText(java.lang.Object, java.lang.String) */ void writeText(Object text, String property) throws IOException { writeText(text.toString().toCharArray(), 0, text.toString().length()); } /* * (non-Javadoc) * * @see org.apache.cocoon.components.faces.context.XMLResponseWriterState#write(char[], int, int) */ void write(char[] cbuf, int off, int len) throws IOException { writeText(cbuf, off, len); } } /** * @author shura State in element declsration. Collect attributes, on any other eventss - generate SAX startElement() */ private final class ElementState extends XMLResponseWriterState { /** * Generate SAX StartElement event * * @throws IOException */ void flushElement() throws IOException { try { xmlConsumer.startElement(getNamespaceURI(), element, element, attributes); } catch (SAXException e) { throw new IOException("Exception in startElement: " + e.getMessage()); } finally { element = null; attributes = null; } } void writeAttribute(String name, Object value, String property) throws IOException { attributes.addAttribute(getNamespaceURI(), name, name, "id".equalsIgnoreCase(name) ? "ID" : "CDATA", value.toString()); } void writeURIAttribute(String name, Object value, String property) throws IOException { String uri = value.toString(); // TODO - perform encodeActionURL() or ??? attributes.addAttribute(getNamespaceURI(), name, name, "CDATA", uri); } /* * (non-Javadoc) * * @see org.apache.cocoon.components.faces.context.XMLResponseWriterState#endElement(java.lang.String) */ void endElement(String name) throws IOException { // flushElement(); state = inDocumentState; state.endElement(name); } /* * (non-Javadoc) * * @see org.apache.cocoon.components.faces.context.XMLResponseWriterState#startElement(java.lang.String, * javax.faces.component.UIComponent) */ void startElement(String name, UIComponent component) throws IOException { // flushElement(); element = name; attributes = new AttributesImpl(); } /* * (non-Javadoc) * * @see org.apache.cocoon.components.faces.context.XMLResponseWriterState#writeComment(java.lang.Object) */ void writeComment(Object comment) throws IOException { // TODO Auto-generated method stub flushElement(); state = inDocumentState; state.writeComment(comment); } /* * (non-Javadoc) * * @see org.apache.cocoon.components.faces.context.XMLResponseWriterState#writeText(char[], int, int) */ void writeText(char[] text, int off, int len) throws IOException { // TODO Auto-generated method stub flushElement(); state = cdataState; state.writeText(text, off, len); } /* * (non-Javadoc) * * @see org.apache.cocoon.components.faces.context.XMLResponseWriterState#writeText(java.lang.Object, java.lang.String) */ void writeText(Object text, String property) throws IOException { // TODO Auto-generated method stub flushElement(); state = cdataState; state.writeText(text, property); } } /** * @author shura *

* State in regular document. Disabled attributes & startDocument. */ private final class InDocumentState extends XMLResponseWriterState { void startElement(String name, UIComponent component) { element = name; attributes = new AttributesImpl(); state = elementState; } void writeComment(Object comment) throws IOException { String remark = comment.toString(); try { xmlLexicalHandler.comment(remark.toCharArray(), 0, remark.length()); } catch (SAXException e) { throw new IOException("Comment SAX exception :" + e.getMessage()); } } void writeText(Object o, String property) throws IOException { writeText(o.toString().toCharArray(), 0, o.toString().length()); } void writeText(char[] text, int start, int lenght) throws IOException { // try { // xmlConsumer.startCDATA(); // } catch (SAXException e) { // throw new IOException("Sax exceptions in writeText: "+ // e.getMessage()); // } finally { state = cdataState; // } state.writeText(text, start, lenght); } void endElement(String name) throws IOException { try { xmlConsumer.endElement(getNamespaceURI(), name, name); } catch (SAXException e) { throw new IOException("Sax exceptions in endElement: " + e.getMessage()); } } void endDocument() throws IOException { try { xmlConsumer.endDocument(); } catch (SAXException e) { throw new IOException("Sax exceptions in endDocument" + e.getMessage()); } finally { // after endDocument all events disabled ... state = new XMLResponseWriterState(); } } } // Private classes /** * @author shura *

* state before startDocument - only allow startDocument. */ private final class NotDocumentState extends XMLResponseWriterState { /* * (non-Javadoc) * * @see org.apache.cocoon.components.faces.context.XMLResponseWriterState#startDocument() */ void startDocument() throws IOException { try { // xmlConsumer.startDocument(); } catch (SAXException e) { // throw new IOException("StartDocument SAX exception :" + e.getMessage()); } finally { state = inDocumentState; } } } }





© 2015 - 2024 Weber Informatics LLC | Privacy Policy