Package org.apache.cocoon.components.serializers

Source Code of org.apache.cocoon.components.serializers.HTMLSerializer

/*
* 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.components.serializers;

import org.apache.avalon.framework.configuration.Configuration;
import org.apache.avalon.framework.configuration.ConfigurationException;
import org.apache.cocoon.components.serializers.encoding.HTMLEncoder;
import org.apache.cocoon.components.serializers.util.DocType;
import org.apache.cocoon.components.serializers.util.SGMLDocType;
import org.xml.sax.SAXException;

/**
* <p>A serializer converting XHTML into plain old HTML.</p>
*
* <p>For configuration options of this serializer, please look at the
* {@link XHTMLSerializer} and {@link EncodingSerializer}.</p>
*
* <p>Any of the XHTML document type declared or used will be converted into
* its HTML 4.01 counterpart, and in addition to those a "compatible" doctype
* can be supported to exploit a couple of shortcuts into MSIE's rendering
* engine. The values for the <code>doctype-default</code> can then be:</p>
*
* <dl>
*   <dt>"<code>none</code>"</dt>
*   <dd>Not to emit any dococument type declaration.</dd>
*   <dt>"<code>compatible</code>"</dt>
*   <dd>The HTML 4.01 Transitional (exploiting MSIE shortcut).</dd>
*   <dt>"<code>strict</code>"</dt>
*   <dd>The HTML 4.01 Strict document type.</dd>
*   <dt>"<code>loose</code>"</dt>
*   <dd>The HTML 4.01 Transitional document type.</dd>
*   <dt>"<code>frameset</code>"</dt>
*   <dd>The HTML 4.01 Frameset document type.</dd>
* </dl>
*
* @version CVS $Id: HTMLSerializer.java 736988 2009-01-23 10:31:55Z andreas $
*/
public class HTMLSerializer extends XHTMLSerializer {

    /** A cross-browser compatible very simple document type declaration. */
    public static final DocType HTML401_DOCTYPE_COMPATIBLE = new SGMLDocType(
            "HTML", "-//W3C//DTD HTML 4.01 Transitional//EN", null);

    /** A representation of the HTML 4.01 strict document type. */
    public static final DocType HTML401_DOCTYPE_STRICT = new SGMLDocType(
            "HTML", "-//W3C//DTD HTML 4.01//EN",
            "http://www.w3.org/TR/html4/strict.dtd");

    /** A representation of the HTML 4.01 transitional document type. */
    public static final DocType HTML401_DOCTYPE_TRANSITIONAL = new SGMLDocType(
            "HTML", "-//W3C//DTD HTML 4.01 Transitional//EN",
            "http://www.w3.org/TR/html4/loose.dtd");

    /** A representation of the HTML 4.01 frameset document type. */
    public static final DocType HTML401_DOCTYPE_FRAMESET = new SGMLDocType(
            "HTML", "-//W3C//DTD HTML 4.01 Frameset//EN",
            "http://www.w3.org/TR/html4/frameset.dtd");

    /* ====================================================================== */

    private static final HTMLEncoder HTML_ENCODER = new HTMLEncoder();

    /**
     * Create a new instance of this <code>HTMLSerializer</code>
     */
    public HTMLSerializer() {
        super(HTML_ENCODER);
    }

    /**
     * Configure this instance by selecting the default document type to use.
     */
    public void configure(Configuration conf)
    throws ConfigurationException {
        super.configure(conf);

        String doctype = conf.getChild("doctype-default").getValue(null);
        if ("none".equalsIgnoreCase(doctype)) {
            this.doctype_default = null;
        } else if ("compatible".equalsIgnoreCase(doctype)) {
            this.doctype_default = HTML401_DOCTYPE_COMPATIBLE;
        } else if ("strict".equalsIgnoreCase(doctype)) {
            this.doctype_default = HTML401_DOCTYPE_STRICT;
        } else if ("loose".equalsIgnoreCase(doctype)) {
            this.doctype_default = HTML401_DOCTYPE_TRANSITIONAL;
        } else if ("frameset".equalsIgnoreCase(doctype)) {
            this.doctype_default = HTML401_DOCTYPE_FRAMESET;
        } else {
            /* Default is compatible (MSIE hack) */
            this.doctype_default = HTML401_DOCTYPE_COMPATIBLE;
        }
    }

    /* ====================================================================== */

    /** Empty namespaces declaration. */
    private static final String NAMESPACES[][] = new String[0][0];

    /** Check if the URI is allowed by this serializer. */
    private boolean checkNamespace(String nsuri) {
        if (nsuri.length() == 0) return(true);
        if (XHTML1_NAMESPACE.equals(nsuri)) return(true);
        return(false);
    }

    /* ====================================================================== */

    /**
     * Write the XML document header.
     * <p>
     * This method overrides the default <code>XMLSerializer</code>.behaviour.
     * </p>
     */
    public void head()
    throws SAXException {
        // NO NOTHING!
    }

    /**
     * Receive notification of the beginning of the document body.
     *
     * @param nsuri The namespace URI of the root element.
     * @param local The local name of the root element.
     * @param qual The fully-qualified name of the root element.
     */
    public void body(String nsuri, String local, String qual)
    throws SAXException {
        String name = local.toUpperCase();
        if (! this.checkNamespace(nsuri)) {
            throw new SAXException("Unsupported namespace \"" + nsuri + "\" "
                                   + "for HTML root element \"" + qual + "\""
                                   + this.getLocation());
        }

        if (this.doctype == null) this.doctype = this.doctype_default;

        if (XHTML1_DOCTYPE_STRICT.equals(this.doctype)) {
            this.doctype = HTML401_DOCTYPE_STRICT;
        } else if (XHTML1_DOCTYPE_TRANSITIONAL.equals(this.doctype)) {
            this.doctype = HTML401_DOCTYPE_TRANSITIONAL;
        } else if (XHTML1_DOCTYPE_FRAMESET.equals(this.doctype)) {
            this.doctype = HTML401_DOCTYPE_FRAMESET;
        } else if (this.doctype != null) {
            /* The root element is uppercase, always!!! */
            this.doctype = new SGMLDocType(this.doctype.getName().toUpperCase(),
                                       this.doctype.getPublicId(),
                                       this.doctype.getSystemId());
        }
        super.body(XHTML1_NAMESPACE, name, name);
    }

    /**
     * Receive notification of the beginning of an element.
     */
    public void startElementImpl(String nsuri, String local, String qual,
                             String namespaces[][], String attributes[][])
    throws SAXException {
        String name = local.toUpperCase();
        if (! this.checkNamespace(nsuri)) {
            throw new SAXException("Unsupported namespace \"" + nsuri + "\" "
                                   + "for HTML element \"" + qual + "\""
                                   + this.getLocation());
        }

        int length = 0;
        for (int x = 0; x < attributes.length; x ++) {
            if (checkNamespace(attributes[x][ATTRIBUTE_NSURI])) length ++;
        }

        String at[][] = new String[length][ATTRIBUTE_LENGTH];
        length = 0;
        for (int x = 0; x < attributes.length; x ++) {
            if (!checkNamespace(attributes[x][ATTRIBUTE_NSURI])) continue;

            String at_name = attributes[x][ATTRIBUTE_LOCAL].toLowerCase();
            at[length][ATTRIBUTE_NSURI] = XHTML1_NAMESPACE;
            at[length][ATTRIBUTE_LOCAL] = at_name;
            at[length][ATTRIBUTE_QNAME] = at_name;
            at[length][ATTRIBUTE_VALUE] = attributes[x][ATTRIBUTE_VALUE];
            length++;
        }

        super.startElementImpl(XHTML1_NAMESPACE, name, name, NAMESPACES, at);
    }

    /**
     * Receive notification of the end of an element.
     */
    public void endElementImpl(String nsuri, String local, String qual)
    throws SAXException {
        this.closeElement(false);

        String name = local.toUpperCase();
        if (! this.checkNamespace(nsuri)) {
            throw new SAXException("Unsupported namespace \"" + nsuri + "\" "
                                   + "for HTML element \"" + qual + "\""
                                   + this.getLocation());
        }

        if (name.equals("AREA")) return;
        if (name.equals("BASE")) return;
        if (name.equals("BASEFONT")) return;
        if (name.equals("BR")) return;
        if (name.equals("COL")) return;
        if (name.equals("FRAME")) return;
        if (name.equals("HR")) return;
        if (name.equals("IMG")) return;
        if (name.equals("INPUT")) return;
        if (name.equals("ISINDEX")) return;
        if (name.equals("LINK")) return;
        if (name.equals("META")) return;
        if (name.equals("PARAM")) return;

        super.endElementImpl(XHTML1_NAMESPACE, name, name);
    }

}
TOP

Related Classes of org.apache.cocoon.components.serializers.HTMLSerializer

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.