summaryrefslogtreecommitdiffstats
path: root/libjava/classpath/gnu/xml/dom/ls/SAXEventSink.java
diff options
context:
space:
mode:
Diffstat (limited to 'libjava/classpath/gnu/xml/dom/ls/SAXEventSink.java')
-rw-r--r--libjava/classpath/gnu/xml/dom/ls/SAXEventSink.java182
1 files changed, 104 insertions, 78 deletions
diff --git a/libjava/classpath/gnu/xml/dom/ls/SAXEventSink.java b/libjava/classpath/gnu/xml/dom/ls/SAXEventSink.java
index a850460b1e2..aad5ac76e70 100644
--- a/libjava/classpath/gnu/xml/dom/ls/SAXEventSink.java
+++ b/libjava/classpath/gnu/xml/dom/ls/SAXEventSink.java
@@ -37,6 +37,7 @@ exception statement from your version. */
package gnu.xml.dom.ls;
+import java.util.HashSet;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;
@@ -45,20 +46,26 @@ import org.w3c.dom.Attr;
import org.w3c.dom.DocumentType;
import org.w3c.dom.Element;
import org.w3c.dom.Entity;
+import org.w3c.dom.EntityReference;
import org.w3c.dom.NamedNodeMap;
import org.w3c.dom.Node;
import org.w3c.dom.Text;
import org.xml.sax.Attributes;
+import org.xml.sax.ContentHandler;
import org.xml.sax.DTDHandler;
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;
import org.xml.sax.ext.Attributes2;
import org.xml.sax.ext.DeclHandler;
import org.xml.sax.ext.LexicalHandler;
-import gnu.xml.aelfred2.ContentHandler2;
+import org.xml.sax.ext.Locator2;
import gnu.xml.dom.DomAttr;
import gnu.xml.dom.DomDocument;
import gnu.xml.dom.DomDoctype;
+import gnu.xml.dom.DomNode;
/**
* A SAX content and lexical handler used to construct a DOM document.
@@ -66,17 +73,28 @@ import gnu.xml.dom.DomDoctype;
* @author <a href='mailto:dog@gnu.org'>Chris Burdess</a>
*/
class SAXEventSink
- implements ContentHandler2, LexicalHandler, DTDHandler, DeclHandler
+ implements ContentHandler, LexicalHandler, DTDHandler, DeclHandler
{
private static final String XMLNS_URI = XMLConstants.XMLNS_ATTRIBUTE_NS_URI;
private static final String XMLNS_PREFIX = XMLConstants.XMLNS_ATTRIBUTE;
+ private static final HashSet PREDEFINED_ENTITIES = new HashSet();
+ static
+ {
+ PREDEFINED_ENTITIES.add("amp");
+ PREDEFINED_ENTITIES.add("lt");
+ PREDEFINED_ENTITIES.add("gt");
+ PREDEFINED_ENTITIES.add("quot");
+ PREDEFINED_ENTITIES.add("apos");
+ }
boolean namespaceAware;
boolean ignoreWhitespace;
boolean expandEntityReferences;
boolean ignoreComments;
boolean coalescing;
+
+ XMLReader reader; // reference back to the parser to get features
DomDocument doc; // document being constructed
Node ctx; // current context (parent node)
@@ -110,20 +128,42 @@ class SAXEventSink
doc.setStrictErrorChecking(false);
doc.setBuilding(true);
ctx = doc;
- }
- public void xmlDecl(String version, String encoding, boolean standalone,
- String inputEncoding)
- throws SAXException
- {
- if (interrupted)
+ final String FEATURES = "http://xml.org/sax/features/";
+ final String PROPERTIES = "http://xml.org/sax/properties/";
+ final String GNU_PROPERTIES = "http://gnu.org/sax/properties/";
+
+ boolean standalone = reader.getFeature(FEATURES + "is-standalone");
+ doc.setXmlStandalone(standalone);
+ try
+ {
+ String version = (String) reader.getProperty(PROPERTIES +
+ "document-xml-version");
+ doc.setXmlVersion(version);
+ }
+ catch (SAXNotRecognizedException e)
+ {
+ }
+ catch (SAXNotSupportedException e)
+ {
+ }
+ if (locator != null && locator instanceof Locator2)
+ {
+ String encoding = ((Locator2) locator).getEncoding();
+ doc.setInputEncoding(encoding);
+ }
+ try
+ {
+ String encoding = (String) reader.getProperty(GNU_PROPERTIES +
+ "document-xml-encoding");
+ doc.setXmlEncoding(encoding);
+ }
+ catch (SAXNotRecognizedException e)
+ {
+ }
+ catch (SAXNotSupportedException e)
{
- return;
}
- doc.setXmlVersion(version);
- doc.setXmlEncoding(encoding);
- doc.setXmlStandalone(standalone);
- doc.setInputEncoding(inputEncoding);
}
public void endDocument()
@@ -265,7 +305,7 @@ class SAXEventSink
public void characters(char[] c, int off, int len)
throws SAXException
{
- if (interrupted)
+ if (interrupted || len < 1)
{
return;
}
@@ -301,11 +341,8 @@ class SAXEventSink
{
return;
}
- if (!inDTD)
- {
- Node pi = createProcessingInstruction(target, data);
- ctx.appendChild(pi);
- }
+ Node pi = createProcessingInstruction(target, data);
+ ctx.appendChild(pi);
}
protected Node createProcessingInstruction(String target, String data)
@@ -354,6 +391,8 @@ class SAXEventSink
public void startEntity(String name)
throws SAXException
{
+ if (interrupted)
+ return;
DocumentType doctype = doc.getDoctype();
if (doctype == null)
{
@@ -361,19 +400,9 @@ class SAXEventSink
"reference to entity in undeclared doctype");
}
if ("[dtd]".equals(name) || name.charAt(0) == '%')
- {
- // Ignore DTD and parameter entities
- ctx = doctype;
- return;
- }
- if ("lt".equals(name) ||
- "gt".equals(name) ||
- "amp".equals(name) ||
- "apos".equals(name) ||
- "quot".equals(name))
- {
- return;
- }
+ return;
+ if (PREDEFINED_ENTITIES.contains(name))
+ return;
// Get entity
NamedNodeMap entities = doctype.getEntities();
Entity entity = (Entity) entities.getNamedItem(name);
@@ -382,59 +411,47 @@ class SAXEventSink
throw new SAXException("SAX parser error: " +
"reference to undeclared entity: " + name);
}
- pushEntity(entity);
+ EntityReference ref = doc.createEntityReference(name);
+ // DomDocument populates with the entity replacement text, remove this
+ Node child = ref.getFirstChild();
+ while (child != null)
+ {
+ Node nextChild = child.getNextSibling();
+ ref.removeChild(child);
+ child = nextChild;
+ }
+ ctx.appendChild(ref);
+ ctx = ref;
}
public void endEntity(String name)
throws SAXException
{
+ if (interrupted)
+ return;
if ("[dtd]".equals(name) || name.charAt(0) == '%')
- {
- // Ignore DTD and parameter entities
- return;
- }
- if ("lt".equals(name) ||
- "gt".equals(name) ||
- "amp".equals(name) ||
- "apos".equals(name) ||
- "quot".equals(name))
- {
- return;
- }
- // Get entity
- Entity entity = popEntity();
- // TODO resolve external entities to ensure that entity has content
+ return;
+ if (PREDEFINED_ENTITIES.contains(name))
+ return;
+ // Get entity reference
+ EntityReference ref = (EntityReference) ctx;
+ if (!ref.getNodeName().equals(name))
+ throw new SAXException("expecting end of "+ref.getNodeName()+" entity");
+ ctx = ctx.getParentNode();
+ if (ref instanceof DomNode)
+ ((DomNode) ref).makeReadonly();
if (expandEntityReferences)
{
- // Get entity content
- for (Node child = entity.getFirstChild(); child != null;
- child = child.getNextSibling())
+ // Move entity content from reference node onto context
+ Node child = ref.getFirstChild();
+ while (child != null)
{
+ Node nextChild = child.getNextSibling();
ctx.appendChild(child);
+ child = nextChild;
}
+ ctx.removeChild(ref);
}
- else
- {
- Node entityReference = doc.createEntityReference(name);
- ctx.appendChild(entityReference);
- }
- }
-
- void pushEntity(Node entity)
- {
- if (entityCtx == null)
- {
- entityCtx = new LinkedList();
- }
- entityCtx.addLast(ctx);
- ctx = entity;
- }
-
- Entity popEntity()
- {
- Entity ret = (Entity) ctx;
- ctx = (Node) entityCtx.removeLast();
- return ret;
}
public void startCDATA()
@@ -456,11 +473,8 @@ class SAXEventSink
{
return;
}
- if (!inDTD)
- {
- Node comment = createComment(c, off, len);
- ctx.appendChild(comment);
- }
+ Node comment = createComment(c, off, len);
+ ctx.appendChild(comment);
}
protected Node createComment(char[] c, int off, int len)
@@ -477,6 +491,8 @@ class SAXEventSink
{
return;
}
+ if (!inDTD)
+ throw new SAXException("notation decl outside DTD");
DomDoctype doctype = (DomDoctype) ctx;
doctype.declareNotation(name, publicId, systemId);
}
@@ -489,6 +505,8 @@ class SAXEventSink
{
return;
}
+ if (!inDTD)
+ throw new SAXException("unparsed entity decl outside DTD");
DomDoctype doctype = (DomDoctype) ctx;
Entity entity = doctype.declareEntity(name, publicId, systemId,
notationName);
@@ -503,6 +521,8 @@ class SAXEventSink
{
return;
}
+ if (!inDTD)
+ throw new SAXException("element decl outside DTD");
// Ignore fake element declarations generated by ValidationConsumer.
// If an element is not really declared in the DTD it will not be
// declared in the document model.
@@ -522,6 +542,8 @@ class SAXEventSink
{
return;
}
+ if (!inDTD)
+ throw new SAXException("attribute decl outside DTD");
DomDoctype doctype = (DomDoctype) ctx;
doctype.attributeDecl(eName, aName, type, mode, value);
}
@@ -533,6 +555,8 @@ class SAXEventSink
{
return;
}
+ if (!inDTD)
+ throw new SAXException("internal entity decl outside DTD");
DomDoctype doctype = (DomDoctype) ctx;
Entity entity = doctype.declareEntity(name, null, null, null);
if (entity != null)
@@ -549,6 +573,8 @@ class SAXEventSink
{
return;
}
+ if (!inDTD)
+ throw new SAXException("external entity decl outside DTD");
DomDoctype doctype = (DomDoctype) ctx;
Entity entity = doctype.declareEntity(name, publicId, systemId, null);
}
OpenPOWER on IntegriCloud