summaryrefslogtreecommitdiffstats
path: root/parser/html/java/htmlparser/src/nu/validator/saxtree
diff options
context:
space:
mode:
Diffstat (limited to 'parser/html/java/htmlparser/src/nu/validator/saxtree')
-rw-r--r--parser/html/java/htmlparser/src/nu/validator/saxtree/CDATA.java70
-rw-r--r--parser/html/java/htmlparser/src/nu/validator/saxtree/CharBufferNode.java62
-rw-r--r--parser/html/java/htmlparser/src/nu/validator/saxtree/Characters.java65
-rw-r--r--parser/html/java/htmlparser/src/nu/validator/saxtree/Comment.java66
-rw-r--r--parser/html/java/htmlparser/src/nu/validator/saxtree/DTD.java118
-rw-r--r--parser/html/java/htmlparser/src/nu/validator/saxtree/Document.java70
-rw-r--r--parser/html/java/htmlparser/src/nu/validator/saxtree/DocumentFragment.java58
-rw-r--r--parser/html/java/htmlparser/src/nu/validator/saxtree/Element.java172
-rw-r--r--parser/html/java/htmlparser/src/nu/validator/saxtree/Entity.java86
-rw-r--r--parser/html/java/htmlparser/src/nu/validator/saxtree/IgnorableWhitespace.java65
-rw-r--r--parser/html/java/htmlparser/src/nu/validator/saxtree/LocatorImpl.java104
-rw-r--r--parser/html/java/htmlparser/src/nu/validator/saxtree/Node.java307
-rw-r--r--parser/html/java/htmlparser/src/nu/validator/saxtree/NodeType.java76
-rw-r--r--parser/html/java/htmlparser/src/nu/validator/saxtree/NullLexicalHandler.java85
-rw-r--r--parser/html/java/htmlparser/src/nu/validator/saxtree/ParentNode.java208
-rw-r--r--parser/html/java/htmlparser/src/nu/validator/saxtree/PrefixMapping.java65
-rw-r--r--parser/html/java/htmlparser/src/nu/validator/saxtree/ProcessingInstruction.java94
-rw-r--r--parser/html/java/htmlparser/src/nu/validator/saxtree/SkippedEntity.java77
-rw-r--r--parser/html/java/htmlparser/src/nu/validator/saxtree/TreeBuilder.java250
-rw-r--r--parser/html/java/htmlparser/src/nu/validator/saxtree/TreeParser.java301
-rw-r--r--parser/html/java/htmlparser/src/nu/validator/saxtree/package.html46
21 files changed, 2445 insertions, 0 deletions
diff --git a/parser/html/java/htmlparser/src/nu/validator/saxtree/CDATA.java b/parser/html/java/htmlparser/src/nu/validator/saxtree/CDATA.java
new file mode 100644
index 000000000..f17ce3f89
--- /dev/null
+++ b/parser/html/java/htmlparser/src/nu/validator/saxtree/CDATA.java
@@ -0,0 +1,70 @@
+/*
+ * Copyright (c) 2007 Henri Sivonen
+ * Copyright (c) 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.saxtree;
+
+import org.xml.sax.Locator;
+import org.xml.sax.SAXException;
+
+/**
+ * A CDATA section.
+ * @version $Id$
+ * @author hsivonen
+ */
+public final class CDATA extends ParentNode {
+
+ /**
+ * The constructor.
+ * @param locator the locator
+ */
+ public CDATA(Locator locator) {
+ super(locator);
+ }
+
+ /**
+ * @see nu.validator.saxtree.Node#visit(nu.validator.saxtree.TreeParser)
+ */
+ @Override
+ void visit(TreeParser treeParser) throws SAXException {
+ treeParser.startCDATA(this);
+ }
+
+ /**
+ *
+ * @throws SAXException if things go wrong
+ * @see nu.validator.saxtree.Node#revisit(nu.validator.saxtree.TreeParser)
+ */
+ @Override
+ void revisit(TreeParser treeParser) throws SAXException {
+ treeParser.endCDATA(endLocator);
+ }
+
+ /**
+ * @see nu.validator.saxtree.Node#getNodeType()
+ */
+ @Override
+ public NodeType getNodeType() {
+ return NodeType.CDATA;
+ }
+
+}
diff --git a/parser/html/java/htmlparser/src/nu/validator/saxtree/CharBufferNode.java b/parser/html/java/htmlparser/src/nu/validator/saxtree/CharBufferNode.java
new file mode 100644
index 000000000..55c7715f6
--- /dev/null
+++ b/parser/html/java/htmlparser/src/nu/validator/saxtree/CharBufferNode.java
@@ -0,0 +1,62 @@
+/*
+ * Copyright (c) 2007 Henri Sivonen
+ * Copyright (c) 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.saxtree;
+
+import org.xml.sax.Locator;
+
+/**
+ * A common superclass for character buffer node classes.
+ * @version $Id$
+ * @author hsivonen
+ */
+public abstract class CharBufferNode extends Node {
+
+ /**
+ * The buffer.
+ */
+ protected final char[] buffer;
+
+ /**
+ * The constructor.
+ * @param locator the locator
+ * @param buf the buffer
+ * @param start the offset
+ * @param length the length
+ */
+ CharBufferNode(Locator locator, char[] buf, int start, int length) {
+ super(locator);
+ this.buffer = new char[length];
+ System.arraycopy(buf, start, buffer, 0, length);
+ }
+
+ /**
+ * Returns the wrapped buffer as a string.
+ *
+ * @see java.lang.Object#toString()
+ */
+ @Override
+ public String toString() {
+ return new String(buffer);
+ }
+}
diff --git a/parser/html/java/htmlparser/src/nu/validator/saxtree/Characters.java b/parser/html/java/htmlparser/src/nu/validator/saxtree/Characters.java
new file mode 100644
index 000000000..b8cc2d6d6
--- /dev/null
+++ b/parser/html/java/htmlparser/src/nu/validator/saxtree/Characters.java
@@ -0,0 +1,65 @@
+/*
+ * Copyright (c) 2007 Henri Sivonen
+ * Copyright (c) 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.saxtree;
+
+import org.xml.sax.Locator;
+import org.xml.sax.SAXException;
+
+/**
+ * A run of characters
+ * @version $Id$
+ * @author hsivonen
+ */
+public final class Characters extends CharBufferNode {
+
+ /**
+ * The constructor.
+ * @param locator the locator
+ * @param buf the buffer
+ * @param start the offset in the buffer
+ * @param length the length
+ */
+ public Characters(Locator locator, char[] buf, int start, int length) {
+ super(locator, buf, start, length);
+ }
+
+ /**
+ *
+ * @see nu.validator.saxtree.Node#visit(nu.validator.saxtree.TreeParser)
+ */
+ @Override
+ void visit(TreeParser treeParser) throws SAXException {
+ treeParser.characters(buffer, 0, buffer.length, this);
+ }
+
+ /**
+ *
+ * @see nu.validator.saxtree.Node#getNodeType()
+ */
+ @Override
+ public NodeType getNodeType() {
+ return NodeType.CHARACTERS;
+ }
+
+}
diff --git a/parser/html/java/htmlparser/src/nu/validator/saxtree/Comment.java b/parser/html/java/htmlparser/src/nu/validator/saxtree/Comment.java
new file mode 100644
index 000000000..f010462fb
--- /dev/null
+++ b/parser/html/java/htmlparser/src/nu/validator/saxtree/Comment.java
@@ -0,0 +1,66 @@
+/*
+ * Copyright (c) 2007 Henri Sivonen
+ * Copyright (c) 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.saxtree;
+
+import org.xml.sax.Locator;
+import org.xml.sax.SAXException;
+
+/**
+ * A comment.
+ *
+ * @version $Id$
+ * @author hsivonen
+ */
+public final class Comment extends CharBufferNode {
+
+ /**
+ * The constructor.
+ * @param locator the locator
+ * @param buf the buffer
+ * @param start the offset
+ * @param length the length
+ */
+ public Comment(Locator locator, char[] buf, int start, int length) {
+ super(locator, buf, start, length);
+ }
+
+ /**
+ *
+ * @see nu.validator.saxtree.Node#visit(nu.validator.saxtree.TreeParser)
+ */
+ @Override
+ void visit(TreeParser treeParser) throws SAXException {
+ treeParser.comment(buffer, 0, buffer.length, this);
+ }
+
+ /**
+ *
+ * @see nu.validator.saxtree.Node#getNodeType()
+ */
+ @Override
+ public NodeType getNodeType() {
+ return NodeType.COMMENT;
+ }
+
+}
diff --git a/parser/html/java/htmlparser/src/nu/validator/saxtree/DTD.java b/parser/html/java/htmlparser/src/nu/validator/saxtree/DTD.java
new file mode 100644
index 000000000..2169e0571
--- /dev/null
+++ b/parser/html/java/htmlparser/src/nu/validator/saxtree/DTD.java
@@ -0,0 +1,118 @@
+/*
+ * Copyright (c) 2007 Henri Sivonen
+ * Copyright (c) 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.saxtree;
+
+import org.xml.sax.Locator;
+import org.xml.sax.SAXException;
+
+/**
+ * A doctype.
+ * @version $Id$
+ * @author hsivonen
+ */
+public final class DTD extends ParentNode {
+
+ /**
+ * The name.
+ */
+ private final String name;
+
+ /**
+ * The public id.
+ */
+ private final String publicIdentifier;
+
+ /**
+ * The system id.
+ */
+ private final String systemIdentifier;
+
+ /**
+ * The constructor.
+ * @param locator the locator
+ * @param name the name
+ * @param publicIdentifier the public id
+ * @param systemIdentifier the system id
+ */
+ public DTD(Locator locator, String name, String publicIdentifier, String systemIdentifier) {
+ super(locator);
+ this.name = name;
+ this.publicIdentifier = publicIdentifier;
+ this.systemIdentifier = systemIdentifier;
+ }
+
+ /**
+ *
+ * @see nu.validator.saxtree.Node#visit(nu.validator.saxtree.TreeParser)
+ */
+ @Override
+ void visit(TreeParser treeParser) throws SAXException {
+ treeParser.startDTD(name, publicIdentifier, systemIdentifier, this);
+ }
+
+ /**
+ * @see nu.validator.saxtree.Node#revisit(nu.validator.saxtree.TreeParser)
+ */
+ @Override
+ void revisit(TreeParser treeParser) throws SAXException {
+ treeParser.endDTD(endLocator);
+ }
+
+ /**
+ * Returns the name.
+ *
+ * @return the name
+ */
+ public String getName() {
+ return name;
+ }
+
+ /**
+ * Returns the publicIdentifier.
+ *
+ * @return the publicIdentifier
+ */
+ public String getPublicIdentifier() {
+ return publicIdentifier;
+ }
+
+ /**
+ * Returns the systemIdentifier.
+ *
+ * @return the systemIdentifier
+ */
+ public String getSystemIdentifier() {
+ return systemIdentifier;
+ }
+
+ /**
+ *
+ * @see nu.validator.saxtree.Node#getNodeType()
+ */
+ @Override
+ public NodeType getNodeType() {
+ return NodeType.DTD;
+ }
+
+}
diff --git a/parser/html/java/htmlparser/src/nu/validator/saxtree/Document.java b/parser/html/java/htmlparser/src/nu/validator/saxtree/Document.java
new file mode 100644
index 000000000..3bb6f09c7
--- /dev/null
+++ b/parser/html/java/htmlparser/src/nu/validator/saxtree/Document.java
@@ -0,0 +1,70 @@
+/*
+ * Copyright (c) 2007 Henri Sivonen
+ * Copyright (c) 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.saxtree;
+
+import org.xml.sax.Locator;
+import org.xml.sax.SAXException;
+
+/**
+ * A document.
+ * @version $Id$
+ * @author hsivonen
+ */
+public final class Document extends ParentNode {
+
+ /**
+ * The constructor.
+ * @param locator the locator
+ */
+ public Document(Locator locator) {
+ super(locator);
+ }
+
+ /**
+ *
+ * @see nu.validator.saxtree.Node#visit(nu.validator.saxtree.TreeParser)
+ */
+ @Override
+ void visit(TreeParser treeParser) throws SAXException {
+ treeParser.startDocument(this);
+ }
+
+ /**
+ * @see nu.validator.saxtree.Node#revisit(nu.validator.saxtree.TreeParser)
+ */
+ @Override
+ void revisit(TreeParser treeParser) throws SAXException {
+ treeParser.endDocument(endLocator);
+ }
+
+ /**
+ *
+ * @see nu.validator.saxtree.Node#getNodeType()
+ */
+ @Override
+ public NodeType getNodeType() {
+ return NodeType.DOCUMENT;
+ }
+
+}
diff --git a/parser/html/java/htmlparser/src/nu/validator/saxtree/DocumentFragment.java b/parser/html/java/htmlparser/src/nu/validator/saxtree/DocumentFragment.java
new file mode 100644
index 000000000..06816932f
--- /dev/null
+++ b/parser/html/java/htmlparser/src/nu/validator/saxtree/DocumentFragment.java
@@ -0,0 +1,58 @@
+/*
+ * Copyright (c) 2007 Henri Sivonen
+ * Copyright (c) 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.saxtree;
+
+import org.xml.sax.helpers.LocatorImpl;
+
+/**
+ * A document fragment.
+ *
+ * @version $Id$
+ * @author hsivonen
+ */
+public final class DocumentFragment extends ParentNode {
+
+ /**
+ * The constructor.
+ */
+ public DocumentFragment() {
+ super(new LocatorImpl());
+ }
+
+ /**
+ *
+ * @see nu.validator.saxtree.Node#visit(nu.validator.saxtree.TreeParser)
+ */
+ @Override void visit(TreeParser treeParser) {
+ // nothing
+ }
+
+ /**
+ *
+ * @see nu.validator.saxtree.Node#getNodeType()
+ */
+ @Override public NodeType getNodeType() {
+ return NodeType.DOCUMENT_FRAGMENT;
+ }
+}
diff --git a/parser/html/java/htmlparser/src/nu/validator/saxtree/Element.java b/parser/html/java/htmlparser/src/nu/validator/saxtree/Element.java
new file mode 100644
index 000000000..3d33164e5
--- /dev/null
+++ b/parser/html/java/htmlparser/src/nu/validator/saxtree/Element.java
@@ -0,0 +1,172 @@
+/*
+ * Copyright (c) 2007 Henri Sivonen
+ * Copyright (c) 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.saxtree;
+
+import java.util.List;
+
+import org.xml.sax.Attributes;
+import org.xml.sax.Locator;
+import org.xml.sax.SAXException;
+import org.xml.sax.helpers.AttributesImpl;
+
+/**
+ * An element.
+ * @version $Id$
+ * @author hsivonen
+ */
+public final class Element extends ParentNode {
+
+ /**
+ * The namespace URI.
+ */
+ private final String uri;
+
+ /**
+ * The local name.
+ */
+ private final String localName;
+
+ /**
+ * The qualified name.
+ */
+ private final String qName;
+
+ /**
+ * The attributes.
+ */
+ private final Attributes attributes;
+
+ /**
+ * The namespace prefix mappings.
+ */
+ private final List<PrefixMapping> prefixMappings;
+
+ /**
+ * The contructor.
+ * @param locator the locator.
+ * @param uri the namespace URI
+ * @param localName the local name
+ * @param qName the qualified name
+ * @param atts the attributes
+ * @param retainAttributes <code>true</code> to retain the attributes instead of copying
+ * @param prefixMappings the prefix mappings
+ */
+ public Element(Locator locator, String uri, String localName, String qName,
+ Attributes atts, boolean retainAttributes,
+ List<PrefixMapping> prefixMappings) {
+ super(locator);
+ this.uri = uri;
+ this.localName = localName;
+ this.qName = qName;
+ if (retainAttributes) {
+ this.attributes = atts;
+ } else {
+ this.attributes = new AttributesImpl(atts);
+ }
+ this.prefixMappings = prefixMappings;
+ }
+
+ /**
+ *
+ * @see nu.validator.saxtree.Node#visit(nu.validator.saxtree.TreeParser)
+ */
+ @Override
+ void visit(TreeParser treeParser) throws SAXException {
+ if (prefixMappings != null) {
+ for (PrefixMapping mapping : prefixMappings) {
+ treeParser.startPrefixMapping(mapping.getPrefix(),
+ mapping.getUri(), this);
+ }
+ }
+ treeParser.startElement(uri, localName, qName, attributes, this);
+ }
+
+ /**
+ * @see nu.validator.saxtree.Node#revisit(nu.validator.saxtree.TreeParser)
+ */
+ @Override
+ void revisit(TreeParser treeParser) throws SAXException {
+ treeParser.endElement(uri, localName, qName, endLocator);
+ if (prefixMappings != null) {
+ for (PrefixMapping mapping : prefixMappings) {
+ treeParser.endPrefixMapping(mapping.getPrefix(), endLocator);
+ }
+ }
+ }
+
+ /**
+ * Returns the attributes.
+ *
+ * @return the attributes
+ */
+ public Attributes getAttributes() {
+ return attributes;
+ }
+
+ /**
+ * Returns the localName.
+ *
+ * @return the localName
+ */
+ public String getLocalName() {
+ return localName;
+ }
+
+ /**
+ * Returns the prefixMappings.
+ *
+ * @return the prefixMappings
+ */
+ public List<PrefixMapping> getPrefixMappings() {
+ return prefixMappings;
+ }
+
+ /**
+ * Returns the qName.
+ *
+ * @return the qName
+ */
+ public String getQName() {
+ return qName;
+ }
+
+ /**
+ * Returns the uri.
+ *
+ * @return the uri
+ */
+ public String getUri() {
+ return uri;
+ }
+
+ /**
+ *
+ * @see nu.validator.saxtree.Node#getNodeType()
+ */
+ @Override
+ public NodeType getNodeType() {
+ return NodeType.ELEMENT;
+ }
+
+}
diff --git a/parser/html/java/htmlparser/src/nu/validator/saxtree/Entity.java b/parser/html/java/htmlparser/src/nu/validator/saxtree/Entity.java
new file mode 100644
index 000000000..091013736
--- /dev/null
+++ b/parser/html/java/htmlparser/src/nu/validator/saxtree/Entity.java
@@ -0,0 +1,86 @@
+/*
+ * Copyright (c) 2007 Henri Sivonen
+ * Copyright (c) 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.saxtree;
+
+import org.xml.sax.Locator;
+import org.xml.sax.SAXException;
+
+/**
+ * An entity.
+ * @version $Id$
+ * @author hsivonen
+ */
+public final class Entity extends ParentNode {
+
+ /**
+ * The name.
+ */
+ private final String name;
+
+ /**
+ * The constructor.
+ * @param locator the locator
+ * @param name the name
+ */
+ public Entity(Locator locator, String name) {
+ super(locator);
+ this.name = name;
+ }
+
+ /**
+ *
+ * @see nu.validator.saxtree.Node#visit(nu.validator.saxtree.TreeParser)
+ */
+ @Override
+ void visit(TreeParser treeParser) throws SAXException {
+ treeParser.startEntity(name, this);
+ }
+
+ /**
+ * @see nu.validator.saxtree.Node#revisit(nu.validator.saxtree.TreeParser)
+ */
+ @Override
+ void revisit(TreeParser treeParser) throws SAXException {
+ treeParser.endEntity(name, endLocator);
+ }
+
+ /**
+ *
+ * @see nu.validator.saxtree.Node#getNodeType()
+ */
+ @Override
+ public NodeType getNodeType() {
+ return NodeType.ENTITY;
+ }
+
+ /**
+ * Returns the name.
+ *
+ * @return the name
+ */
+ public String getName() {
+ return name;
+ }
+
+}
diff --git a/parser/html/java/htmlparser/src/nu/validator/saxtree/IgnorableWhitespace.java b/parser/html/java/htmlparser/src/nu/validator/saxtree/IgnorableWhitespace.java
new file mode 100644
index 000000000..e5fcf350f
--- /dev/null
+++ b/parser/html/java/htmlparser/src/nu/validator/saxtree/IgnorableWhitespace.java
@@ -0,0 +1,65 @@
+/*
+ * Copyright (c) 2007 Henri Sivonen
+ * Copyright (c) 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.saxtree;
+
+import org.xml.sax.Locator;
+import org.xml.sax.SAXException;
+
+/**
+ * A run ignorable whitespace.
+ * @version $Id$
+ * @author hsivonen
+ */
+public final class IgnorableWhitespace extends CharBufferNode {
+
+ /**
+ * The constructor.
+ * @param locator the locator
+ * @param buf the buffer
+ * @param start the offset
+ * @param length the length
+ */
+ public IgnorableWhitespace(Locator locator, char[] buf, int start, int length) {
+ super(locator, buf, start, length);
+ }
+
+ /**
+ *
+ * @see nu.validator.saxtree.Node#visit(nu.validator.saxtree.TreeParser)
+ */
+ @Override
+ void visit(TreeParser treeParser) throws SAXException {
+ treeParser.ignorableWhitespace(buffer, 0, buffer.length, this);
+ }
+
+ /**
+ *
+ * @see nu.validator.saxtree.Node#getNodeType()
+ */
+ @Override
+ public NodeType getNodeType() {
+ return NodeType.IGNORABLE_WHITESPACE;
+ }
+
+}
diff --git a/parser/html/java/htmlparser/src/nu/validator/saxtree/LocatorImpl.java b/parser/html/java/htmlparser/src/nu/validator/saxtree/LocatorImpl.java
new file mode 100644
index 000000000..37c0c6325
--- /dev/null
+++ b/parser/html/java/htmlparser/src/nu/validator/saxtree/LocatorImpl.java
@@ -0,0 +1,104 @@
+/*
+ * Copyright (c) 2007 Henri Sivonen
+ * 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.saxtree;
+
+import org.xml.sax.Locator;
+
+/**
+ * A locator implementation.
+ * @version $Id$
+ * @author hsivonen
+ */
+public final class LocatorImpl implements Locator {
+
+ /**
+ * The system id.
+ */
+ private final String systemId;
+
+ /**
+ * The public id.
+ */
+ private final String publicId;
+
+ /**
+ * The column.
+ */
+ private final int column;
+
+ /**
+ * The line.
+ */
+ private final int line;
+
+ /**
+ * The constructor.
+ * @param locator the locator
+ */
+ public LocatorImpl(Locator locator) {
+ if (locator == null) {
+ this.systemId = null;
+ this.publicId = null;
+ this.column = -1;
+ this.line = -1;
+ } else {
+ this.systemId = locator.getSystemId();
+ this.publicId = locator.getPublicId();
+ this.column = locator.getColumnNumber();
+ this.line = locator.getLineNumber();
+ }
+ }
+
+ /**
+ *
+ * @see org.xml.sax.Locator#getColumnNumber()
+ */
+ public int getColumnNumber() {
+ return column;
+ }
+
+ /**
+ *
+ * @see org.xml.sax.Locator#getLineNumber()
+ */
+ public int getLineNumber() {
+ return line;
+ }
+
+ /**
+ *
+ * @see org.xml.sax.Locator#getPublicId()
+ */
+ public String getPublicId() {
+ return publicId;
+ }
+
+ /**
+ *
+ * @see org.xml.sax.Locator#getSystemId()
+ */
+ public String getSystemId() {
+ return systemId;
+ }
+}
diff --git a/parser/html/java/htmlparser/src/nu/validator/saxtree/Node.java b/parser/html/java/htmlparser/src/nu/validator/saxtree/Node.java
new file mode 100644
index 000000000..7aed83b75
--- /dev/null
+++ b/parser/html/java/htmlparser/src/nu/validator/saxtree/Node.java
@@ -0,0 +1,307 @@
+/*
+ * Copyright (c) 2007 Henri Sivonen
+ * Copyright (c) 2007-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.saxtree;
+
+import java.util.List;
+
+import org.xml.sax.Attributes;
+import org.xml.sax.Locator;
+import org.xml.sax.SAXException;
+
+/**
+ * The common node superclass.
+ * @version $Id$
+ * @author hsivonen
+ */
+public abstract class Node implements Locator {
+
+ /**
+ * The system id.
+ */
+ private final String systemId;
+
+ /**
+ * The public id.
+ */
+ private final String publicId;
+
+ /**
+ * The column.
+ */
+ private final int column;
+
+ /**
+ * The line.
+ */
+ private final int line;
+
+ /**
+ * The next sibling.
+ */
+ private Node nextSibling = null;
+
+ /**
+ * The parent.
+ */
+ private ParentNode parentNode = null;
+
+ /**
+ * The constructor.
+ *
+ * @param locator the locator
+ */
+ Node(Locator locator) {
+ if (locator == null) {
+ this.systemId = null;
+ this.publicId = null;
+ this.column = -1;
+ this.line = -1;
+ } else {
+ this.systemId = locator.getSystemId();
+ this.publicId = locator.getPublicId();
+ this.column = locator.getColumnNumber();
+ this.line = locator.getLineNumber();
+ }
+ }
+
+ /**
+ *
+ * @see org.xml.sax.Locator#getColumnNumber()
+ */
+ public int getColumnNumber() {
+ return column;
+ }
+
+ /**
+ *
+ * @see org.xml.sax.Locator#getLineNumber()
+ */
+ public int getLineNumber() {
+ return line;
+ }
+
+ /**
+ *
+ * @see org.xml.sax.Locator#getPublicId()
+ */
+ public String getPublicId() {
+ return publicId;
+ }
+
+ /**
+ *
+ * @see org.xml.sax.Locator#getSystemId()
+ */
+ public String getSystemId() {
+ return systemId;
+ }
+
+ /**
+ * Visit the node.
+ *
+ * @param treeParser the visitor
+ * @throws SAXException if stuff goes wrong
+ */
+ abstract void visit(TreeParser treeParser) throws SAXException;
+
+ /**
+ * Revisit the node.
+ *
+ * @param treeParser the visitor
+ * @throws SAXException if stuff goes wrong
+ */
+ void revisit(TreeParser treeParser) throws SAXException {
+ return;
+ }
+
+ /**
+ * Return the first child.
+ * @return the first child
+ */
+ public Node getFirstChild() {
+ return null;
+ }
+
+ /**
+ * Returns the nextSibling.
+ *
+ * @return the nextSibling
+ */
+ public final Node getNextSibling() {
+ return nextSibling;
+ }
+
+ /**
+ * Returns the previous sibling
+ * @return the previous sibling
+ */
+ public final Node getPreviousSibling() {
+ Node prev = null;
+ Node next = parentNode.getFirstChild();
+ for(;;) {
+ if (this == next) {
+ return prev;
+ }
+ prev = next;
+ next = next.nextSibling;
+ }
+ }
+
+ /**
+ * Sets the nextSibling.
+ *
+ * @param nextSibling the nextSibling to set
+ */
+ void setNextSibling(Node nextSibling) {
+ this.nextSibling = nextSibling;
+ }
+
+
+ /**
+ * Returns the parentNode.
+ *
+ * @return the parentNode
+ */
+ public final ParentNode getParentNode() {
+ return parentNode;
+ }
+
+ /**
+ * Sets the parentNode.
+ *
+ * @param parentNode the parentNode to set
+ */
+ void setParentNode(ParentNode parentNode) {
+ this.parentNode = parentNode;
+ }
+
+ /**
+ * Return the node type.
+ * @return the node type
+ */
+ public abstract NodeType getNodeType();
+
+ // Subclass-specific accessors that are hoisted here to
+ // avoid casting.
+
+ /**
+ * Detach this node from its parent.
+ */
+ public void detach() {
+ if (parentNode != null) {
+ parentNode.removeChild(this);
+ parentNode = null;
+ }
+ }
+
+ /**
+ * Returns the name.
+ *
+ * @return the name
+ */
+ public String getName() {
+ throw new UnsupportedOperationException();
+ }
+
+ /**
+ * Returns the publicIdentifier.
+ *
+ * @return the publicIdentifier
+ */
+ public String getPublicIdentifier() {
+ throw new UnsupportedOperationException();
+ }
+
+ /**
+ * Returns the systemIdentifier.
+ *
+ * @return the systemIdentifier
+ */
+ public String getSystemIdentifier() {
+ throw new UnsupportedOperationException();
+ }
+
+ /**
+ * Returns the attributes.
+ *
+ * @return the attributes
+ */
+ public Attributes getAttributes() {
+ throw new UnsupportedOperationException();
+ }
+
+ /**
+ * Returns the localName.
+ *
+ * @return the localName
+ */
+ public String getLocalName() {
+ throw new UnsupportedOperationException();
+ }
+
+ /**
+ * Returns the prefixMappings.
+ *
+ * @return the prefixMappings
+ */
+ public List<PrefixMapping> getPrefixMappings() {
+ throw new UnsupportedOperationException();
+ }
+
+ /**
+ * Returns the qName.
+ *
+ * @return the qName
+ */
+ public String getQName() {
+ throw new UnsupportedOperationException();
+ }
+
+ /**
+ * Returns the uri.
+ *
+ * @return the uri
+ */
+ public String getUri() {
+ throw new UnsupportedOperationException();
+ }
+
+ /**
+ * Returns the data.
+ *
+ * @return the data
+ */
+ public String getData() {
+ throw new UnsupportedOperationException();
+ }
+
+ /**
+ * Returns the target.
+ *
+ * @return the target
+ */
+ public String getTarget() {
+ throw new UnsupportedOperationException();
+ }
+}
diff --git a/parser/html/java/htmlparser/src/nu/validator/saxtree/NodeType.java b/parser/html/java/htmlparser/src/nu/validator/saxtree/NodeType.java
new file mode 100644
index 000000000..c3c927f0d
--- /dev/null
+++ b/parser/html/java/htmlparser/src/nu/validator/saxtree/NodeType.java
@@ -0,0 +1,76 @@
+/*
+ * Copyright (c) 2007 Henri Sivonen
+ * Copyright (c) 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.saxtree;
+
+/**
+ * The node type.
+ * @version $Id$
+ * @author hsivonen
+ */
+public enum NodeType {
+ /**
+ * A CDATA section.
+ */
+ CDATA,
+ /**
+ * A run of characters.
+ */
+ CHARACTERS,
+ /**
+ * A comment.
+ */
+ COMMENT,
+ /**
+ * A document.
+ */
+ DOCUMENT,
+ /**
+ * A document fragment.
+ */
+ DOCUMENT_FRAGMENT,
+ /**
+ * A DTD.
+ */
+ DTD,
+ /**
+ * An element.
+ */
+ ELEMENT,
+ /**
+ * An entity.
+ */
+ ENTITY,
+ /**
+ * A run of ignorable whitespace.
+ */
+ IGNORABLE_WHITESPACE,
+ /**
+ * A processing instruction.
+ */
+ PROCESSING_INSTRUCTION,
+ /**
+ * A skipped entity.
+ */
+ SKIPPED_ENTITY
+}
diff --git a/parser/html/java/htmlparser/src/nu/validator/saxtree/NullLexicalHandler.java b/parser/html/java/htmlparser/src/nu/validator/saxtree/NullLexicalHandler.java
new file mode 100644
index 000000000..de63f3b57
--- /dev/null
+++ b/parser/html/java/htmlparser/src/nu/validator/saxtree/NullLexicalHandler.java
@@ -0,0 +1,85 @@
+/*
+ * Copyright (c) 2007 Henri Sivonen
+ * Copyright (c) 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.saxtree;
+
+import org.xml.sax.SAXException;
+import org.xml.sax.ext.LexicalHandler;
+
+/**
+ * A lexical handler that does nothing.
+ * @version $Id$
+ * @author hsivonen
+ */
+final class NullLexicalHandler implements LexicalHandler {
+
+ /**
+ *
+ * @see org.xml.sax.ext.LexicalHandler#comment(char[], int, int)
+ */
+ public void comment(char[] arg0, int arg1, int arg2) throws SAXException {
+ }
+
+ /**
+ *
+ * @see org.xml.sax.ext.LexicalHandler#endCDATA()
+ */
+ public void endCDATA() throws SAXException {
+ }
+
+ /**
+ *
+ * @see org.xml.sax.ext.LexicalHandler#endDTD()
+ */
+ public void endDTD() throws SAXException {
+ }
+
+ /**
+ *
+ * @see org.xml.sax.ext.LexicalHandler#endEntity(java.lang.String)
+ */
+ public void endEntity(String arg0) throws SAXException {
+ }
+
+ /**
+ *
+ * @see org.xml.sax.ext.LexicalHandler#startCDATA()
+ */
+ public void startCDATA() throws SAXException {
+ }
+
+ /**
+ *
+ * @see org.xml.sax.ext.LexicalHandler#startDTD(java.lang.String, java.lang.String, java.lang.String)
+ */
+ public void startDTD(String arg0, String arg1, String arg2) throws SAXException {
+ }
+
+ /**
+ *
+ * @see org.xml.sax.ext.LexicalHandler#startEntity(java.lang.String)
+ */
+ public void startEntity(String arg0) throws SAXException {
+ }
+
+}
diff --git a/parser/html/java/htmlparser/src/nu/validator/saxtree/ParentNode.java b/parser/html/java/htmlparser/src/nu/validator/saxtree/ParentNode.java
new file mode 100644
index 000000000..6cc96003f
--- /dev/null
+++ b/parser/html/java/htmlparser/src/nu/validator/saxtree/ParentNode.java
@@ -0,0 +1,208 @@
+/*
+ * Copyright (c) 2007 Henri Sivonen
+ * Copyright (c) 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.saxtree;
+
+import org.xml.sax.Locator;
+
+/**
+ * Common superclass for parent nodes.
+ * @version $Id$
+ * @author hsivonen
+ */
+public abstract class ParentNode extends Node {
+
+ /**
+ * The end locator.
+ */
+ protected Locator endLocator;
+
+ /**
+ * The first child.
+ */
+ private Node firstChild = null;
+
+ /**
+ * The last child (for efficiency).
+ */
+ private Node lastChild = null;
+
+ /**
+ * The constuctor.
+ * @param locator the locator
+ */
+ ParentNode(Locator locator) {
+ super(locator);
+ }
+
+ /**
+ * Sets the endLocator.
+ *
+ * @param endLocator the endLocator to set
+ */
+ public void setEndLocator(Locator endLocator) {
+ this.endLocator = new LocatorImpl(endLocator);
+ }
+
+ /**
+ * Copies the endLocator from another node.
+ *
+ * @param another the another node
+ */
+ public void copyEndLocator(ParentNode another) {
+ this.endLocator = another.endLocator;
+ }
+
+ /**
+ * Returns the firstChild.
+ *
+ * @return the firstChild
+ */
+ public final Node getFirstChild() {
+ return firstChild;
+ }
+
+ /**
+ * Returns the lastChild.
+ *
+ * @return the lastChild
+ */
+ public final Node getLastChild() {
+ return lastChild;
+ }
+
+ /**
+ * Insert a new child before a pre-existing child and return the newly inserted child.
+ * @param child the new child
+ * @param sibling the existing child before which to insert (must be a child of this node) or <code>null</code> to append
+ * @return <code>child</code>
+ */
+ public Node insertBefore(Node child, Node sibling) {
+ assert sibling == null || this == sibling.getParentNode();
+ if (sibling == null) {
+ return appendChild(child);
+ }
+ child.detach();
+ child.setParentNode(this);
+ if (firstChild == sibling) {
+ child.setNextSibling(sibling);
+ firstChild = child;
+ } else {
+ Node prev = firstChild;
+ Node next = firstChild.getNextSibling();
+ while (next != sibling) {
+ prev = next;
+ next = next.getNextSibling();
+ }
+ prev.setNextSibling(child);
+ child.setNextSibling(next);
+ }
+ return child;
+ }
+
+ public Node insertBetween(Node child, Node prev, Node next) {
+ assert prev == null || this == prev.getParentNode();
+ assert next == null || this == next.getParentNode();
+ assert prev != null || next == firstChild;
+ assert next != null || prev == lastChild;
+ assert prev == null || next == null || prev.getNextSibling() == next;
+ if (next == null) {
+ return appendChild(child);
+ }
+ child.detach();
+ child.setParentNode(this);
+ child.setNextSibling(next);
+ if (prev == null) {
+ firstChild = child;
+ } else {
+ prev.setNextSibling(child);
+ }
+ return child;
+ }
+
+ /**
+ * Append a child to this node and return the child.
+ *
+ * @param child the child to append.
+ * @return <code>child</code>
+ */
+ public Node appendChild(Node child) {
+ child.detach();
+ child.setParentNode(this);
+ if (firstChild == null) {
+ firstChild = child;
+ } else {
+ lastChild.setNextSibling(child);
+ }
+ lastChild = child;
+ return child;
+ }
+
+ /**
+ * Append the children of another node to this node removing them from the other node .
+ * @param parent the other node whose children to append to this one
+ */
+ public void appendChildren(Node parent) {
+ Node child = parent.getFirstChild();
+ if (child == null) {
+ return;
+ }
+ ParentNode another = (ParentNode) parent;
+ if (firstChild == null) {
+ firstChild = child;
+ } else {
+ lastChild.setNextSibling(child);
+ }
+ lastChild = another.lastChild;
+ do {
+ child.setParentNode(this);
+ } while ((child = child.getNextSibling()) != null);
+ another.firstChild = null;
+ another.lastChild = null;
+ }
+
+ /**
+ * Remove a child from this node.
+ * @param node the child to remove
+ */
+ void removeChild(Node node) {
+ assert this == node.getParentNode();
+ if (firstChild == node) {
+ firstChild = node.getNextSibling();
+ if (lastChild == node) {
+ lastChild = null;
+ }
+ } else {
+ Node prev = firstChild;
+ Node next = firstChild.getNextSibling();
+ while (next != node) {
+ prev = next;
+ next = next.getNextSibling();
+ }
+ prev.setNextSibling(node.getNextSibling());
+ if (lastChild == node) {
+ lastChild = prev;
+ }
+ }
+ }
+}
diff --git a/parser/html/java/htmlparser/src/nu/validator/saxtree/PrefixMapping.java b/parser/html/java/htmlparser/src/nu/validator/saxtree/PrefixMapping.java
new file mode 100644
index 000000000..8ffaf4a2c
--- /dev/null
+++ b/parser/html/java/htmlparser/src/nu/validator/saxtree/PrefixMapping.java
@@ -0,0 +1,65 @@
+/*
+ * Copyright (c) 2007 Henri Sivonen
+ * Copyright (c) 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.saxtree;
+
+/**
+ * A prefix mapping.
+ * @version $Id$
+ * @author hsivonen
+ */
+public final class PrefixMapping {
+ /**
+ * The namespace prefix.
+ */
+ private final String prefix;
+ /**
+ * The namespace URI.
+ */
+ private final String uri;
+ /**
+ * Constructor.
+ * @param prefix the prefix
+ * @param uri the URI
+ */
+ public PrefixMapping(final String prefix, final String uri) {
+ this.prefix = prefix;
+ this.uri = uri;
+ }
+ /**
+ * Returns the prefix.
+ *
+ * @return the prefix
+ */
+ public String getPrefix() {
+ return prefix;
+ }
+ /**
+ * Returns the uri.
+ *
+ * @return the uri
+ */
+ public String getUri() {
+ return uri;
+ }
+}
diff --git a/parser/html/java/htmlparser/src/nu/validator/saxtree/ProcessingInstruction.java b/parser/html/java/htmlparser/src/nu/validator/saxtree/ProcessingInstruction.java
new file mode 100644
index 000000000..014e63821
--- /dev/null
+++ b/parser/html/java/htmlparser/src/nu/validator/saxtree/ProcessingInstruction.java
@@ -0,0 +1,94 @@
+/*
+ * Copyright (c) 2007 Henri Sivonen
+ * Copyright (c) 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.saxtree;
+
+import org.xml.sax.Locator;
+import org.xml.sax.SAXException;
+
+/**
+ * A processing instruction.
+ * @version $Id$
+ * @author hsivonen
+ */
+public final class ProcessingInstruction extends Node {
+
+ /**
+ * PI target.
+ */
+ private final String target;
+
+ /**
+ * PI data.
+ */
+ private final String data;
+
+ /**
+ * Constructor.
+ * @param locator the locator
+ * @param target PI target
+ * @param data PI data
+ */
+ public ProcessingInstruction(Locator locator, String target, String data) {
+ super(locator);
+ this.target = target;
+ this.data = data;
+ }
+
+ /**
+ *
+ * @see nu.validator.saxtree.Node#visit(nu.validator.saxtree.TreeParser)
+ */
+ @Override
+ void visit(TreeParser treeParser) throws SAXException {
+ treeParser.processingInstruction(target, data, this);
+ }
+
+ /**
+ *
+ * @see nu.validator.saxtree.Node#getNodeType()
+ */
+ @Override
+ public NodeType getNodeType() {
+ return NodeType.PROCESSING_INSTRUCTION;
+ }
+
+ /**
+ * Returns the data.
+ *
+ * @return the data
+ */
+ public String getData() {
+ return data;
+ }
+
+ /**
+ * Returns the target.
+ *
+ * @return the target
+ */
+ public String getTarget() {
+ return target;
+ }
+
+}
diff --git a/parser/html/java/htmlparser/src/nu/validator/saxtree/SkippedEntity.java b/parser/html/java/htmlparser/src/nu/validator/saxtree/SkippedEntity.java
new file mode 100644
index 000000000..01ca61490
--- /dev/null
+++ b/parser/html/java/htmlparser/src/nu/validator/saxtree/SkippedEntity.java
@@ -0,0 +1,77 @@
+/*
+ * Copyright (c) 2007 Henri Sivonen
+ * Copyright (c) 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.saxtree;
+
+import org.xml.sax.Locator;
+import org.xml.sax.SAXException;
+
+/**
+ * A skipped entity.
+ * @version $Id$
+ * @author hsivonen
+ */
+public final class SkippedEntity extends Node {
+
+ /**
+ * The name.
+ */
+ private final String name;
+
+ /**
+ * Constructor.
+ * @param locator the locator
+ * @param name the name
+ */
+ public SkippedEntity(Locator locator, String name) {
+ super(locator);
+ this.name = name;
+ }
+
+ /**
+ *
+ * @see nu.validator.saxtree.Node#visit(nu.validator.saxtree.TreeParser)
+ */
+ @Override
+ void visit(TreeParser treeParser) throws SAXException {
+ treeParser.skippedEntity(name, this);
+ }
+
+ /**
+ *
+ * @see nu.validator.saxtree.Node#getNodeType()
+ */
+ @Override
+ public NodeType getNodeType() {
+ return NodeType.SKIPPED_ENTITY;
+ }
+
+ /**
+ * Returns the name.
+ *
+ * @return the name
+ */
+ public String getName() {
+ return name;
+ }
+}
diff --git a/parser/html/java/htmlparser/src/nu/validator/saxtree/TreeBuilder.java b/parser/html/java/htmlparser/src/nu/validator/saxtree/TreeBuilder.java
new file mode 100644
index 000000000..39fe236b3
--- /dev/null
+++ b/parser/html/java/htmlparser/src/nu/validator/saxtree/TreeBuilder.java
@@ -0,0 +1,250 @@
+/*
+ * Copyright (c) 2007 Henri Sivonen
+ * Copyright (c) 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.saxtree;
+
+import java.util.LinkedList;
+import java.util.List;
+
+import org.xml.sax.Attributes;
+import org.xml.sax.ContentHandler;
+import org.xml.sax.Locator;
+import org.xml.sax.SAXException;
+import org.xml.sax.ext.LexicalHandler;
+
+/**
+ * Builds a SAX Tree representation of a document or a fragment
+ * streamed as <code>ContentHandler</code> and
+ * <code>LexicalHandler</code> events. The start/end event matching
+ * is expected to adhere to the SAX API contract. Things will
+ * simply break if this is not the case. Fragments are expected to
+ * omit <code>startDocument()</code> and <code>endDocument()</code>
+ * calls.
+ *
+ * @version $Id$
+ * @author hsivonen
+ */
+public class TreeBuilder implements ContentHandler, LexicalHandler {
+
+ /**
+ * The locator.
+ */
+ private Locator locator;
+
+ /**
+ * The current node.
+ */
+ private ParentNode current;
+
+ /**
+ * Whether to retain attribute objects.
+ */
+ private final boolean retainAttributes;
+
+ /**
+ * The prefix mappings for the next element to be inserted.
+ */
+ private List<PrefixMapping> prefixMappings;
+
+ /**
+ * Constructs a reusable <code>TreeBuilder</code> that builds
+ * <code>Document</code>s and copies attributes.
+ */
+ public TreeBuilder() {
+ this(false, false);
+ }
+
+ /**
+ * The constructor. The instance will be reusabe if building a full
+ * document and not reusable if building a fragment.
+ *
+ * @param fragment whether this <code>TreeBuilder</code> should build
+ * a <code>DocumentFragment</code> instead of a <code>Document</code>.
+ * @param retainAttributes whether instances of the <code>Attributes</code>
+ * interface passed to <code>startElement</code> should be retained
+ * (the alternative is copying).
+ */
+ public TreeBuilder(boolean fragment, boolean retainAttributes) {
+ if (fragment) {
+ current = new DocumentFragment();
+ }
+ this.retainAttributes = retainAttributes;
+ }
+
+ /**
+ *
+ * @see org.xml.sax.ContentHandler#characters(char[], int, int)
+ */
+ public void characters(char[] ch, int start, int length) throws SAXException {
+ current.appendChild(new Characters(locator, ch, start, length));
+ }
+
+ /**
+ *
+ * @see org.xml.sax.ContentHandler#endDocument()
+ */
+ public void endDocument() throws SAXException {
+ current.setEndLocator(locator);
+ }
+
+ /**
+ *
+ * @see org.xml.sax.ContentHandler#endElement(java.lang.String, java.lang.String, java.lang.String)
+ */
+ public void endElement(String uri, String localName, String qName) throws SAXException {
+ current.setEndLocator(locator);
+ current = current.getParentNode();
+ }
+
+ /**
+ *
+ * @see org.xml.sax.ContentHandler#endPrefixMapping(java.lang.String)
+ */
+ public void endPrefixMapping(String prefix) throws SAXException {
+ }
+
+ /**
+ *
+ * @see org.xml.sax.ContentHandler#ignorableWhitespace(char[], int, int)
+ */
+ public void ignorableWhitespace(char[] ch, int start, int length) throws SAXException {
+ current.appendChild(new IgnorableWhitespace(locator, ch, start, length));
+ }
+
+ /**
+ *
+ * @see org.xml.sax.ContentHandler#processingInstruction(java.lang.String, java.lang.String)
+ */
+ public void processingInstruction(String target, String data) throws SAXException {
+ current.appendChild(new ProcessingInstruction(locator, target, data));
+ }
+
+ /**
+ *
+ * @see org.xml.sax.ContentHandler#setDocumentLocator(org.xml.sax.Locator)
+ */
+ public void setDocumentLocator(Locator locator) {
+ this.locator = locator;
+ }
+
+ public void skippedEntity(String name) throws SAXException {
+ current.appendChild(new SkippedEntity(locator, name));
+ }
+
+ /**
+ *
+ * @see org.xml.sax.ContentHandler#startDocument()
+ */
+ public void startDocument() throws SAXException {
+ current = new Document(locator);
+ }
+
+ /**
+ *
+ * @see org.xml.sax.ContentHandler#startElement(java.lang.String, java.lang.String, java.lang.String, org.xml.sax.Attributes)
+ */
+ public void startElement(String uri, String localName, String qName, Attributes atts) throws SAXException {
+ current = (ParentNode) current.appendChild(new Element(locator, uri, localName, qName, atts, retainAttributes, prefixMappings));
+ prefixMappings = null;
+ }
+
+ /**
+ *
+ * @see org.xml.sax.ContentHandler#startPrefixMapping(java.lang.String, java.lang.String)
+ */
+ public void startPrefixMapping(String prefix, String uri) throws SAXException {
+ if (prefixMappings == null) {
+ prefixMappings = new LinkedList<PrefixMapping>();
+ }
+ prefixMappings.add(new PrefixMapping(prefix, uri));
+ }
+
+ /**
+ *
+ * @see org.xml.sax.ext.LexicalHandler#comment(char[], int, int)
+ */
+ public void comment(char[] ch, int start, int length) throws SAXException {
+ current.appendChild(new Comment(locator, ch, start, length));
+ }
+
+ /**
+ *
+ * @see org.xml.sax.ext.LexicalHandler#endCDATA()
+ */
+ public void endCDATA() throws SAXException {
+ current.setEndLocator(locator);
+ current = current.getParentNode();
+ }
+
+ /**
+ *
+ * @see org.xml.sax.ext.LexicalHandler#endDTD()
+ */
+ public void endDTD() throws SAXException {
+ current.setEndLocator(locator);
+ current = current.getParentNode();
+ }
+
+ /**
+ *
+ * @see org.xml.sax.ext.LexicalHandler#endEntity(java.lang.String)
+ */
+ public void endEntity(String name) throws SAXException {
+ current.setEndLocator(locator);
+ current = current.getParentNode();
+ }
+
+ /**
+ *
+ * @see org.xml.sax.ext.LexicalHandler#startCDATA()
+ */
+ public void startCDATA() throws SAXException {
+ current = (ParentNode) current.appendChild(new CDATA(locator));
+ }
+
+ /**
+ *
+ * @see org.xml.sax.ext.LexicalHandler#startDTD(java.lang.String, java.lang.String, java.lang.String)
+ */
+ public void startDTD(String name, String publicId, String systemId) throws SAXException {
+ current = (ParentNode) current.appendChild(new DTD(locator, name, publicId, systemId));
+ }
+
+ /**
+ *
+ * @see org.xml.sax.ext.LexicalHandler#startEntity(java.lang.String)
+ */
+ public void startEntity(String name) throws SAXException {
+ current = (ParentNode) current.appendChild(new Entity(locator, name));
+ }
+
+ /**
+ * Returns the root (<code>Document</code> if building a full document or
+ * <code>DocumentFragment</code> if building a fragment.).
+ *
+ * @return the root
+ */
+ public ParentNode getRoot() {
+ return current;
+ }
+}
diff --git a/parser/html/java/htmlparser/src/nu/validator/saxtree/TreeParser.java b/parser/html/java/htmlparser/src/nu/validator/saxtree/TreeParser.java
new file mode 100644
index 000000000..a9d92deb0
--- /dev/null
+++ b/parser/html/java/htmlparser/src/nu/validator/saxtree/TreeParser.java
@@ -0,0 +1,301 @@
+/*
+ * Copyright (c) 2007 Henri Sivonen
+ * Copyright (c) 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.saxtree;
+
+import org.xml.sax.Attributes;
+import org.xml.sax.ContentHandler;
+import org.xml.sax.Locator;
+import org.xml.sax.SAXException;
+import org.xml.sax.ext.LexicalHandler;
+
+/**
+ * A tree visitor that replays a tree as SAX events.
+ * @version $Id$
+ * @author hsivonen
+ */
+public final class TreeParser implements Locator {
+
+ /**
+ * The content handler.
+ */
+ private final ContentHandler contentHandler;
+
+ /**
+ * The lexical handler.
+ */
+ private final LexicalHandler lexicalHandler;
+
+ /**
+ * The current locator.
+ */
+ private Locator locatorDelegate;
+
+ /**
+ * The constructor.
+ *
+ * @param contentHandler
+ * must not be <code>null</code>
+ * @param lexicalHandler
+ * may be <code>null</code>
+ */
+ public TreeParser(final ContentHandler contentHandler,
+ final LexicalHandler lexicalHandler) {
+ if (contentHandler == null) {
+ throw new IllegalArgumentException("contentHandler was null.");
+ }
+ this.contentHandler = contentHandler;
+ if (lexicalHandler == null) {
+ this.lexicalHandler = new NullLexicalHandler();
+ } else {
+ this.lexicalHandler = lexicalHandler;
+ }
+ }
+
+ /**
+ * Causes SAX events for the tree rooted at the argument to be emitted.
+ * <code>startDocument()</code> and <code>endDocument()</code> are only
+ * emitted for a <code>Document</code> node.
+ *
+ * @param node
+ * the root
+ * @throws SAXException
+ */
+ public void parse(Node node) throws SAXException {
+ contentHandler.setDocumentLocator(this);
+ Node current = node;
+ Node next;
+ for (;;) {
+ current.visit(this);
+ if ((next = current.getFirstChild()) != null) {
+ current = next;
+ continue;
+ }
+ for (;;) {
+ current.revisit(this);
+ if (current == node) {
+ return;
+ }
+ if ((next = current.getNextSibling()) != null) {
+ current = next;
+ break;
+ }
+ current = current.getParentNode();
+ }
+ }
+ }
+
+ /**
+ * @see org.xml.sax.ContentHandler#characters(char[], int, int)
+ */
+ void characters(char[] ch, int start, int length, Locator locator)
+ throws SAXException {
+ this.locatorDelegate = locator;
+ contentHandler.characters(ch, start, length);
+ }
+
+ /**
+ * @see org.xml.sax.ContentHandler#endDocument()
+ */
+ void endDocument(Locator locator) throws SAXException {
+ this.locatorDelegate = locator;
+ contentHandler.endDocument();
+ }
+
+ /**
+ * @see org.xml.sax.ContentHandler#endElement(java.lang.String,
+ * java.lang.String, java.lang.String)
+ */
+ void endElement(String uri, String localName, String qName, Locator locator)
+ throws SAXException {
+ this.locatorDelegate = locator;
+ contentHandler.endElement(uri, localName, qName);
+ }
+
+ /**
+ * @see org.xml.sax.ContentHandler#endPrefixMapping(java.lang.String)
+ */
+ void endPrefixMapping(String prefix, Locator locator) throws SAXException {
+ this.locatorDelegate = locator;
+ contentHandler.endPrefixMapping(prefix);
+ }
+
+ /**
+ * @see org.xml.sax.ContentHandler#ignorableWhitespace(char[], int, int)
+ */
+ void ignorableWhitespace(char[] ch, int start, int length, Locator locator)
+ throws SAXException {
+ this.locatorDelegate = locator;
+ contentHandler.ignorableWhitespace(ch, start, length);
+ }
+
+ /**
+ * @see org.xml.sax.ContentHandler#processingInstruction(java.lang.String,
+ * java.lang.String)
+ */
+ void processingInstruction(String target, String data, Locator locator)
+ throws SAXException {
+ this.locatorDelegate = locator;
+ contentHandler.processingInstruction(target, data);
+ }
+
+ /**
+ * @see org.xml.sax.ContentHandler#skippedEntity(java.lang.String)
+ */
+ void skippedEntity(String name, Locator locator) throws SAXException {
+ this.locatorDelegate = locator;
+ contentHandler.skippedEntity(name);
+ }
+
+ /**
+ * @see org.xml.sax.ContentHandler#startDocument()
+ */
+ void startDocument(Locator locator) throws SAXException {
+ this.locatorDelegate = locator;
+ contentHandler.startDocument();
+ }
+
+ /**
+ * @see org.xml.sax.ContentHandler#startElement(java.lang.String,
+ * java.lang.String, java.lang.String, org.xml.sax.Attributes)
+ */
+ void startElement(String uri, String localName, String qName,
+ Attributes atts, Locator locator) throws SAXException {
+ this.locatorDelegate = locator;
+ contentHandler.startElement(uri, localName, qName, atts);
+ }
+
+ /**
+ * @see org.xml.sax.ContentHandler#startPrefixMapping(java.lang.String,
+ * java.lang.String)
+ */
+ void startPrefixMapping(String prefix, String uri, Locator locator)
+ throws SAXException {
+ this.locatorDelegate = locator;
+ contentHandler.startPrefixMapping(prefix, uri);
+ }
+
+ /**
+ * @see org.xml.sax.ext.LexicalHandler#comment(char[], int, int)
+ */
+ void comment(char[] ch, int start, int length, Locator locator)
+ throws SAXException {
+ this.locatorDelegate = locator;
+ lexicalHandler.comment(ch, start, length);
+ }
+
+ /**
+ * @see org.xml.sax.ext.LexicalHandler#endCDATA()
+ */
+ void endCDATA(Locator locator) throws SAXException {
+ this.locatorDelegate = locator;
+ lexicalHandler.endCDATA();
+ }
+
+ /**
+ * @see org.xml.sax.ext.LexicalHandler#endDTD()
+ */
+ void endDTD(Locator locator) throws SAXException {
+ this.locatorDelegate = locator;
+ lexicalHandler.endDTD();
+ }
+
+ /**
+ * @see org.xml.sax.ext.LexicalHandler#endEntity(java.lang.String)
+ */
+ void endEntity(String name, Locator locator) throws SAXException {
+ this.locatorDelegate = locator;
+ lexicalHandler.endEntity(name);
+ }
+
+ /**
+ * @see org.xml.sax.ext.LexicalHandler#startCDATA()
+ */
+ void startCDATA(Locator locator) throws SAXException {
+ this.locatorDelegate = locator;
+ lexicalHandler.startCDATA();
+ }
+
+ /**
+ * @see org.xml.sax.ext.LexicalHandler#startDTD(java.lang.String,
+ * java.lang.String, java.lang.String)
+ */
+ void startDTD(String name, String publicId, String systemId, Locator locator)
+ throws SAXException {
+ this.locatorDelegate = locator;
+ lexicalHandler.startDTD(name, publicId, systemId);
+ }
+
+ /**
+ * @see org.xml.sax.ext.LexicalHandler#startEntity(java.lang.String)
+ */
+ void startEntity(String name, Locator locator) throws SAXException {
+ this.locatorDelegate = locator;
+ lexicalHandler.startEntity(name);
+ }
+
+ /**
+ * @see org.xml.sax.Locator#getColumnNumber()
+ */
+ public int getColumnNumber() {
+ if (locatorDelegate == null) {
+ return -1;
+ } else {
+ return locatorDelegate.getColumnNumber();
+ }
+ }
+
+ /**
+ * @see org.xml.sax.Locator#getLineNumber()
+ */
+ public int getLineNumber() {
+ if (locatorDelegate == null) {
+ return -1;
+ } else {
+ return locatorDelegate.getLineNumber();
+ }
+ }
+
+ /**
+ * @see org.xml.sax.Locator#getPublicId()
+ */
+ public String getPublicId() {
+ if (locatorDelegate == null) {
+ return null;
+ } else {
+
+ return locatorDelegate.getPublicId();
+ }
+ }
+
+ /**
+ * @see org.xml.sax.Locator#getSystemId()
+ */
+ public String getSystemId() {
+ if (locatorDelegate == null) {
+ return null;
+ } else {
+ return locatorDelegate.getSystemId();
+ }
+ }
+}
diff --git a/parser/html/java/htmlparser/src/nu/validator/saxtree/package.html b/parser/html/java/htmlparser/src/nu/validator/saxtree/package.html
new file mode 100644
index 000000000..0c34dad81
--- /dev/null
+++ b/parser/html/java/htmlparser/src/nu/validator/saxtree/package.html
@@ -0,0 +1,46 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN">
+<html>
+<head><title>Package Overview</title>
+<!--
+ Copyright (c) 2007 Henri Sivonen
+
+ 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.
+-->
+</head>
+<body bgcolor="white">
+<p>This package provides SAX Tree: a tree model optimized for creation from SAX
+events and replay as SAX events.</p>
+<h2>Design Principles</h2>
+<ol>
+<li>Preserve information exposed through <code>ContentHandler</code>,
+<code>LexicalHandler</code> <em>and</em> <code>Locator</code>.
+<li>Creation from SAX events or as part of the parse of a conforming
+HTML5 document should be <em>fast</em>.</li>
+<li>Emitting SAX events based on the tree should be <em>fast</em>.</li>
+<li>Mutations should be <em>possible</em> but should not make the above
+"fast" cases slower.</li>
+<li>Concurrent reads should work without locking when there are no
+concurrent mutations.</li>
+<li>The user of the API has the responsibility of using the API properly:
+for the sake of performance, the model does not check if it is being
+used properly. Improper use may, therefore, put the model in and
+inconsistent state.</li>
+</ol>
+</body>
+</html> \ No newline at end of file