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

org.apache.cocoon.components.serializers.util.XHTMLSerializer Maven / Gradle / Ivy

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

import org.apache.cocoon.components.serializers.encoding.XHTMLEncoder;
import org.xml.sax.SAXException;

/**
 * 

A pedantic XHTML serializer encoding all recognized entities with their * proper HTML names.

* *

For configuration options of this serializer, please look at the * {@link EncodingSerializer}, in addition to those, this serializer also * support the specification of a default doctype. This default will be used * if no document type is received in the SAX events, and can be configured * in the following way:

* *
 * <serializer class="org.apache.cocoon.components.serializers..." ... >
 *   <doctype-default>mytype</doctype-default>
 * </serializer>
 * 
* *

The value mytype can be one of:

* *
*
"none"
*
Not to emit any document type declaration.
*
"strict"
*
The XHTML 1.0 Strict document type.
*
"loose"
*
The XHTML 1.0 Transitional document type.
*
"frameset"
*
The XHTML 1.0 Frameset document type.
*
* * @version $Id: XHTMLSerializer.java 737005 2009-01-23 11:14:38Z andreas $ */ public class XHTMLSerializer extends XMLSerializer { /** The namespace URI for XHTML 1.0. */ public static final String XHTML1_NAMESPACE = "http://www.w3.org/1999/xhtml"; /** A representation of the XHTML 1.0 strict document type. */ public static final DocType XHTML1_DOCTYPE_STRICT = new DocType( "html", "-//W3C//DTD XHTML 1.0 Strict//EN", "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"); /** A representation of the XHTML 1.0 transitional document type. */ public static final DocType XHTML1_DOCTYPE_TRANSITIONAL = new DocType( "html", "-//W3C//DTD XHTML 1.0 Transitional//EN", "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"); /** A representation of the XHTML 1.0 frameset document type. */ public static final DocType XHTML1_DOCTYPE_FRAMESET = new DocType( "html", "-//W3C//DTD XHTML 1.0 Frameset//EN", "http://www.w3.org/TR/xhtml1/DTD/xhtml1-frameset.dtd"); /* ====================================================================== */ private static final XHTMLEncoder XHTML_ENCODER = new XHTMLEncoder(); protected boolean encodeCharacters = true; /* ====================================================================== */ /** The DocType instance representing the document. */ protected DocType doctype_default = null; /** Define whether to put XML declaration in the head of the document. */ private String omitXmlDeclaration = null; /* ====================================================================== */ /** * Create a new instance of this XHTMLSerializer */ public XHTMLSerializer() { super(XHTML_ENCODER); } /** * Create a new instance of this XHTMLSerializer */ protected XHTMLSerializer(XHTMLEncoder encoder) { super(encoder); } /** * Return the MIME Content-Type produced by this serializer. */ public String getMimeType() { if (this.charset == null) return("text/html"); return("text/html; charset=" + this.charset.getName()); } public void setDoctypeDefault(String doctype) { if ("none".equalsIgnoreCase(doctype)) { this.doctype_default = null; } else if ("strict".equalsIgnoreCase(doctype)) { this.doctype_default = XHTML1_DOCTYPE_STRICT; } else if ("loose".equalsIgnoreCase(doctype)) { this.doctype_default = XHTML1_DOCTYPE_TRANSITIONAL; } else if ("frameset".equalsIgnoreCase(doctype)) { this.doctype_default = XHTML1_DOCTYPE_FRAMESET; } else { /* Default is transitional */ this.doctype_default = XHTML1_DOCTYPE_TRANSITIONAL; } } public void setOmitXmlDeclaration(String value) { this.omitXmlDeclaration = value; } /* ====================================================================== */ /** * Write the XML document header. *

* This method will write out the <?xml version="1.0" * ...> header unless omit-xml-declaration is set. *

*/ protected void head() throws SAXException { if (!"yes".equals(this.omitXmlDeclaration)) { super.head(); } } /** * Receive notification of the beginning of the document body. * * @param uri 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 uri, String local, String qual) throws SAXException { if (this.doctype == null) this.doctype = this.doctype_default; if (this.namespaces.getUri("").length() == 0) { this.namespaces.push("", XHTML1_NAMESPACE); } super.body(uri, local, qual); } /** * Receive notification of the beginning of an element. * * @param uri 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. * @param namespaces An array of String objects containing * the namespaces to be declared by this element. * @param attributes An array of String objects containing * all attributes of this element. */ public void startElementImpl(String uri, String local, String qual, String namespaces[][], String attributes[][]) throws SAXException { if (uri.length() == 0) uri = XHTML1_NAMESPACE; if (isCdataElement(local)) { this.encodeCharacters = false; } super.startElementImpl(uri, local, qual, namespaces, attributes); } /** * Receive notification of the end of an element. * * @param uri 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 endElementImpl(String uri, String local, String qual) throws SAXException { if (uri.length() == 0) uri = XHTML1_NAMESPACE; if (XHTML1_NAMESPACE.equals(uri)) { if ((local.equalsIgnoreCase("textarea")) || (local.equalsIgnoreCase("script")) || (local.equalsIgnoreCase("style"))) { this.closeElement(false); } else if (local.equalsIgnoreCase("head")) { String loc = "meta"; String qua = namespaces.qualify(XHTML1_NAMESPACE, loc, "meta"); String nsp[][] = new String[0][0]; String att[][] = new String[2][ATTRIBUTE_LENGTH]; att[0][ATTRIBUTE_NSURI] = att[1][ATTRIBUTE_NSURI] = ""; att[0][ATTRIBUTE_LOCAL] = att[0][ATTRIBUTE_QNAME] = "http-equiv"; att[1][ATTRIBUTE_LOCAL] = att[1][ATTRIBUTE_QNAME] = "content"; att[0][ATTRIBUTE_VALUE] = "Content-Type"; att[1][ATTRIBUTE_VALUE] = this.getMimeType(); this.closeElement(false); this.startElementImpl(XHTML1_NAMESPACE, loc, qua, nsp, att); this.endElementImpl(XHTML1_NAMESPACE, loc, qua); } } if (isCdataElement(local)) { this.encodeCharacters = true; } super.endElementImpl(uri, local, qual); } /** * script and style are CDATA sections by default, so no encoding * @param localName The local name of the element. * @return If the element should be serialized without encoding. */ protected boolean isCdataElement(String localName) { String upperCase = localName.toUpperCase(); return "SCRIPT".equals(upperCase) || "STYLE".equals(upperCase); } /** * Encode and write a specific part of an array of characters. */ protected void encode(char data[], int start, int length) throws SAXException { if (this.encodeCharacters) { super.encode(data, start, length); } else { this.write(data, start, length); } } }




© 2015 - 2025 Weber Informatics LLC | Privacy Policy