/**
* Copyright 2011 meltmedia
*
* 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.xchain.framework.sax.util;
import org.xchain.framework.sax.HandlerWrapper;
import org.xml.sax.ErrorHandler;
import org.xml.sax.Attributes;
import org.xml.sax.helpers.AttributesImpl;
import org.xml.sax.SAXException;
/**
* This class wraps an apache serializer for html. It will remap the html namespace (http://www.w3c.org/1999/xhtml) into the
* default namespace and then pass the elements along. It also caches namespace mapping to prevent extra namespaces from being passed to the document.
*
* @author Christian Trimble
*/
public class XHtmlHandler
extends HandlerWrapper
{
public static String HTML_NAMESPACE = "http://www.w3.org/1999/xhtml";
protected NamespaceContext inputNamespaceContext = new NamespaceContext();
public void startElement( String namespaceUri, String localName, String qName, Attributes attributes )
throws SAXException
{
if( HTML_NAMESPACE.equals(namespaceUri) ) {
super.startElement("", localName, localName, filterAttributes(attributes));
}
else {
super.startElement(namespaceUri, localName, qName, attributes);
}
}
public void endElement( String namespaceUri, String localName, String qName )
throws SAXException
{
if( HTML_NAMESPACE.equals(namespaceUri) ) {
super.endElement("", localName, localName);
}
else {
super.endElement(namespaceUri, localName, qName);
}
}
public void startPrefixMapping( String prefix, String namespaceUri )
throws SAXException
{
inputNamespaceContext.startPrefixMapping(prefix, namespaceUri);
// only pass the mapping if it is not the html namespace.
if( HTML_NAMESPACE.equals(namespaceUri) ) {
// translate this into the default mapping.
super.startPrefixMapping("", "");
}
else if( inputNamespaceContext.isPrefixMappingNeeded(prefix) ) {
// only pass mappings that are needed.
super.startPrefixMapping(prefix, namespaceUri);
}
}
public void endPrefixMapping( String prefix )
throws SAXException
{
String namespaceUri = inputNamespaceContext.lookupUri( prefix );
if( HTML_NAMESPACE.equals(namespaceUri) ) {
super.endPrefixMapping("");
}
else if( inputNamespaceContext.isPrefixMappingNeeded(prefix) ) {
super.endPrefixMapping(prefix);
}
inputNamespaceContext.endPrefixMapping(prefix);
}
public Attributes filterAttributes( Attributes attributes )
{
if( attributes.getLength() == 0 ) {
return attributes;
}
// if any of the attributes is in the html namespace, then filter them into the default namespace.
AttributesImpl filteredAttributes = new AttributesImpl();
for( int i = 0; i < attributes.getLength(); i++ ) {
if( HTML_NAMESPACE.equals(attributes.getURI(i)) ) {
if( attributes.getIndex(attributes.getLocalName(i)) == -1 ) {
filteredAttributes.addAttribute("", attributes.getLocalName(i), attributes.getLocalName(i), attributes.getType(i), attributes.getValue(i));
}
}
else {
filteredAttributes.addAttribute(attributes.getURI(i), attributes.getLocalName(i), attributes.getQName(i), attributes.getType(i), attributes.getValue(i));
}
}
return filteredAttributes;
}
}