/* * Copyright (c) 2007 Henri Sivonen * Copyright (c) 2008-2009 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.htmlparser.sax; import nu.validator.htmlparser.impl.HtmlAttributes; import nu.validator.htmlparser.impl.TreeBuilder; import org.xml.sax.Attributes; import org.xml.sax.ContentHandler; import org.xml.sax.SAXException; import org.xml.sax.SAXParseException; import org.xml.sax.ext.LexicalHandler; class SAXStreamer extends TreeBuilder<Attributes>{ private static final char[] ISINDEX_PROMPT = "This is a searchable index. Enter search keywords: ".toCharArray(); private ContentHandler contentHandler = null; private LexicalHandler lexicalHandler = null; SAXStreamer() { super(); } @Override protected void addAttributesToElement(Attributes element, HtmlAttributes attributes) throws SAXException { Attributes existingAttrs = element; for (int i = 0; i < attributes.getLength(); i++) { String qName = attributes.getQNameNoBoundsCheck(i); if (existingAttrs.getIndex(qName) < 0) { fatal(); } } } @Override protected void appendCharacters(Attributes parent, char[] buf, int start, int length) throws SAXException { contentHandler.characters(buf, start, length); } /** * @see nu.validator.htmlparser.impl.TreeBuilder#appendIsindexPrompt(java.lang.Object) */ @Override protected void appendIsindexPrompt(Attributes parent) throws SAXException { contentHandler.characters(ISINDEX_PROMPT, 0, ISINDEX_PROMPT.length); } @Override protected void appendChildrenToNewParent(Attributes oldParent, Attributes newParent) throws SAXException { fatal(); } @Override protected void appendComment(Attributes parent, char[] buf, int start, int length) throws SAXException { if (lexicalHandler != null) { lexicalHandler.comment(buf, start, length); } } @Override protected void appendCommentToDocument(char[] buf, int start, int length) throws SAXException { if (lexicalHandler != null) { lexicalHandler.comment(buf, start, length); } } @Override protected Attributes createElement(String ns, String name, HtmlAttributes attributes, Attributes intendedParent) throws SAXException { return attributes; } @Override protected Attributes createHtmlElementSetAsRoot(HtmlAttributes attributes) throws SAXException { return attributes; } @Override protected void detachFromParent(Attributes element) throws SAXException { fatal(); } @Override protected void appendElement(Attributes child, Attributes newParent) throws SAXException { } @Override protected boolean hasChildren(Attributes element) throws SAXException { return false; } public void setContentHandler(ContentHandler handler) { contentHandler = handler; } public void setLexicalHandler(LexicalHandler handler) { lexicalHandler = handler; } /** * @see nu.validator.htmlparser.impl.TreeBuilder#appendDoctypeToDocument(java.lang.String, java.lang.String, java.lang.String) */ @Override protected void appendDoctypeToDocument(String name, String publicIdentifier, String systemIdentifier) throws SAXException { if (lexicalHandler != null) { lexicalHandler.startDTD(name, publicIdentifier, systemIdentifier); lexicalHandler.endDTD(); } } /** * @see nu.validator.htmlparser.impl.TreeBuilder#elementPopped(String, java.lang.String, java.lang.Object) */ @Override protected void elementPopped(String ns, String name, Attributes node) throws SAXException { contentHandler.endElement(ns, name, name); } /** * @see nu.validator.htmlparser.impl.TreeBuilder#elementPushed(String, java.lang.String, java.lang.Object) */ @Override protected void elementPushed(String ns, String name, Attributes node) throws SAXException { contentHandler.startElement(ns, name, name, node); } /** * @see nu.validator.htmlparser.impl.TreeBuilder#end() */ @Override protected void end() throws SAXException { contentHandler.endDocument(); } /** * @see nu.validator.htmlparser.impl.TreeBuilder#start() */ @Override protected void start(boolean fragment) throws SAXException { contentHandler.setDocumentLocator(tokenizer); if (!fragment) { contentHandler.startDocument(); } } protected void fatal() throws SAXException { SAXParseException spe = new SAXParseException( "Cannot recover after last error. Any further errors will be ignored.", tokenizer); if (errorHandler != null) { errorHandler.fatalError(spe); } throw spe; } @Override protected Attributes createAndInsertFosterParentedElement(String ns, String name, HtmlAttributes attributes, Attributes table, Attributes stackParent) throws SAXException { fatal(); throw new RuntimeException("Unreachable"); } @Override protected void insertFosterParentedCharacters(char[] buf, int start, int length, Attributes table, Attributes stackParent) throws SAXException { fatal(); } @Override protected void insertFosterParentedChild(Attributes child, Attributes table, Attributes stackParent) throws SAXException { fatal(); } }