/*
* Copyright (c) 2007-2008 Mozilla Foundation
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
* to deal in the Software without restriction, including without limitation
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
* and/or sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
* DEALINGS IN THE SOFTWARE.
*/
package nu.validator.xml;
import java.io.IOException;
import org.xml.sax.Attributes;
import org.xml.sax.ContentHandler;
import org.xml.sax.DTDHandler;
import org.xml.sax.EntityResolver;
import org.xml.sax.ErrorHandler;
import org.xml.sax.InputSource;
import org.xml.sax.Locator;
import org.xml.sax.SAXException;
import org.xml.sax.SAXNotRecognizedException;
import org.xml.sax.SAXNotSupportedException;
import org.xml.sax.XMLReader;
/**
* This does not extend XMLFilterImpl, because XMLFilterImpl constructor
* overwrites handlers on the wrapped XMLReader.
*
* @version $Id$
* @author hsivonen
*/
public final class AttributesPermutingXMLReaderWrapper implements XMLReader,
ContentHandler {
private final XMLReader wrappedReader;
private ContentHandler contentHandler;
public AttributesPermutingXMLReaderWrapper(XMLReader wrappedReader) {
this.wrappedReader = wrappedReader;
this.contentHandler = wrappedReader.getContentHandler();
wrappedReader.setContentHandler(this);
}
/**
* @see org.xml.sax.helpers.XMLFilterImpl#characters(char[], int, int)
*/
@Override
public void characters(char[] ch, int start, int length)
throws SAXException {
if (contentHandler == null) {
return;
}
contentHandler.characters(ch, start, length);
}
/**
* @see org.xml.sax.helpers.XMLFilterImpl#endElement(java.lang.String,
* java.lang.String, java.lang.String)
*/
@Override
public void endElement(String uri, String localName, String qName)
throws SAXException {
if (contentHandler == null) {
return;
}
contentHandler.endElement(uri, localName, qName);
}
/**
* @see org.xml.sax.helpers.XMLFilterImpl#startDocument()
*/
@Override
public void startDocument() throws SAXException {
if (contentHandler == null) {
return;
}
contentHandler.startDocument();
}
/**
* @see org.xml.sax.helpers.XMLFilterImpl#startElement(java.lang.String,
* java.lang.String, java.lang.String, org.xml.sax.Attributes)
*/
@Override
public void startElement(String uri, String localName, String qName,
Attributes atts) throws SAXException {
if (contentHandler == null) {
return;
}
if ("http://www.w3.org/1999/xhtml" == uri) {
if (("input" == localName || "command" == localName) && atts.getIndex("", "type") > 0) {
PermutingAttributesWrapper wrap = new PermutingAttributesWrapper(atts);
wrap.pullUp("", "role");
wrap.pullUp("", "type");
wrap.pullUp("", "template");
contentHandler.startElement(uri, localName, qName, wrap);
} else if ("textarea" == localName && atts.getIndex("", "wrap") > 0) {
PermutingAttributesWrapper wrap = new PermutingAttributesWrapper(atts);
wrap.pullUp("", "wrap");
wrap.pullUp("", "template");
contentHandler.startElement(uri, localName, qName, wrap);
} else if ("script" == localName && atts.getIndex("", "src") > 0) {
PermutingAttributesWrapper wrap = new PermutingAttributesWrapper(atts);
wrap.pullUp("", "src");
wrap.pullUp("", "template");
contentHandler.startElement(uri, localName, qName, wrap);
} else if ("meta" == localName && atts.getIndex("", "content") < atts.getLength() - 1) {
PermutingAttributesWrapper wrap = new PermutingAttributesWrapper(atts);
wrap.pushDown("", "content");
wrap.pullUp("", "template");
contentHandler.startElement(uri, localName, qName, wrap);
} else if (atts.getIndex("", "template") > 0 || atts.getIndex("", "role") > 0) {
PermutingAttributesWrapper wrap = new PermutingAttributesWrapper(atts);
wrap.pullUp("", "role");
wrap.pullUp("", "template");
contentHandler.startElement(uri, localName, qName, wrap);
} else {
contentHandler.startElement(uri, localName, qName, atts);
}
} else {
contentHandler.startElement(uri, localName, qName, atts);
}
}
/**
* @see org.xml.sax.helpers.XMLFilterImpl#setDocumentLocator(org.xml.sax.Locator)
*/
@Override
public void setDocumentLocator(Locator locator) {
if (contentHandler == null) {
return;
}
contentHandler.setDocumentLocator(locator);
}
@Override
public ContentHandler getContentHandler() {
return contentHandler;
}
/**
* @throws SAXException
* @see org.xml.sax.ContentHandler#endDocument()
*/
@Override
public void endDocument() throws SAXException {
if (contentHandler == null) {
return;
}
contentHandler.endDocument();
}
/**
* @param prefix
* @throws SAXException
* @see org.xml.sax.ContentHandler#endPrefixMapping(java.lang.String)
*/
@Override
public void endPrefixMapping(String prefix) throws SAXException {
if (contentHandler == null) {
return;
}
contentHandler.endPrefixMapping(prefix);
}
/**
* @param ch
* @param start
* @param length
* @throws SAXException
* @see org.xml.sax.ContentHandler#ignorableWhitespace(char[], int, int)
*/
@Override
public void ignorableWhitespace(char[] ch, int start, int length)
throws SAXException {
if (contentHandler == null) {
return;
}
contentHandler.ignorableWhitespace(ch, start, length);
}
/**
* @param target
* @param data
* @throws SAXException
* @see org.xml.sax.ContentHandler#processingInstruction(java.lang.String,
* java.lang.String)
*/
@Override
public void processingInstruction(String target, String data)
throws SAXException {
if (contentHandler == null) {
return;
}
contentHandler.processingInstruction(target, data);
}
/**
* @param name
* @throws SAXException
* @see org.xml.sax.ContentHandler#skippedEntity(java.lang.String)
*/
@Override
public void skippedEntity(String name) throws SAXException {
if (contentHandler == null) {
return;
}
contentHandler.skippedEntity(name);
}
/**
* @param prefix
* @param uri
* @throws SAXException
* @see org.xml.sax.ContentHandler#startPrefixMapping(java.lang.String,
* java.lang.String)
*/
@Override
public void startPrefixMapping(String prefix, String uri)
throws SAXException {
if (contentHandler == null) {
return;
}
contentHandler.startPrefixMapping(prefix, uri);
}
/**
* @return
* @see org.xml.sax.XMLReader#getDTDHandler()
*/
@Override
public DTDHandler getDTDHandler() {
return wrappedReader.getDTDHandler();
}
/**
* @return
* @see org.xml.sax.XMLReader#getEntityResolver()
*/
@Override
public EntityResolver getEntityResolver() {
return wrappedReader.getEntityResolver();
}
/**
* @return
* @see org.xml.sax.XMLReader#getErrorHandler()
*/
@Override
public ErrorHandler getErrorHandler() {
return wrappedReader.getErrorHandler();
}
/**
* @param name
* @return
* @throws SAXNotRecognizedException
* @throws SAXNotSupportedException
* @see org.xml.sax.XMLReader#getFeature(java.lang.String)
*/
@Override
public boolean getFeature(String name) throws SAXNotRecognizedException,
SAXNotSupportedException {
return wrappedReader.getFeature(name);
}
/**
* @param name
* @return
* @throws SAXNotRecognizedException
* @throws SAXNotSupportedException
* @see org.xml.sax.XMLReader#getProperty(java.lang.String)
*/
@Override
public Object getProperty(String name) throws SAXNotRecognizedException,
SAXNotSupportedException {
return wrappedReader.getProperty(name);
}
/**
* @param input
* @throws IOException
* @throws SAXException
* @see org.xml.sax.XMLReader#parse(org.xml.sax.InputSource)
*/
@Override
public void parse(InputSource input) throws IOException, SAXException {
wrappedReader.parse(input);
}
/**
* @param systemId
* @throws IOException
* @throws SAXException
* @see org.xml.sax.XMLReader#parse(java.lang.String)
*/
@Override
public void parse(String systemId) throws IOException, SAXException {
wrappedReader.parse(systemId);
}
/**
* @param handler
* @see org.xml.sax.XMLReader#setContentHandler(org.xml.sax.ContentHandler)
*/
@Override
public void setContentHandler(ContentHandler handler) {
contentHandler = handler;
}
/**
* @param handler
* @see org.xml.sax.XMLReader#setDTDHandler(org.xml.sax.DTDHandler)
*/
@Override
public void setDTDHandler(DTDHandler handler) {
wrappedReader.setDTDHandler(handler);
}
/**
* @param resolver
* @see org.xml.sax.XMLReader#setEntityResolver(org.xml.sax.EntityResolver)
*/
@Override
public void setEntityResolver(EntityResolver resolver) {
wrappedReader.setEntityResolver(resolver);
}
/**
* @param handler
* @see org.xml.sax.XMLReader#setErrorHandler(org.xml.sax.ErrorHandler)
*/
@Override
public void setErrorHandler(ErrorHandler handler) {
wrappedReader.setErrorHandler(handler);
}
/**
* @param name
* @param value
* @throws SAXNotRecognizedException
* @throws SAXNotSupportedException
* @see org.xml.sax.XMLReader#setFeature(java.lang.String, boolean)
*/
@Override
public void setFeature(String name, boolean value)
throws SAXNotRecognizedException, SAXNotSupportedException {
wrappedReader.setFeature(name, value);
}
/**
* @param name
* @param value
* @throws SAXNotRecognizedException
* @throws SAXNotSupportedException
* @see org.xml.sax.XMLReader#setProperty(java.lang.String,
* java.lang.Object)
*/
@Override
public void setProperty(String name, Object value)
throws SAXNotRecognizedException, SAXNotSupportedException {
wrappedReader.setProperty(name, value);
}
}