diff options
author | Chris Burdess <dog@bluezoo.org> | 2005-12-23 12:43:20 +0000 |
---|---|---|
committer | Chris Burdess <dog@bluezoo.org> | 2005-12-23 12:43:20 +0000 |
commit | 62c67d308f3ef692726e7aa3efa579523a0719f9 (patch) | |
tree | 94bf61e28b6f2821964cc15e4f6b776629876477 | |
parent | 602e4b40fba62a3e487eadb8426cd39645a5e1ca (diff) | |
download | classpath-62c67d308f3ef692726e7aa3efa579523a0719f9.tar.gz |
2005-12-23 Chris Burdess <dog@gnu.org>
* gnu/xml/stream/SAXParser.java,
gnu/xml/stream/XMLParser.java: Interim commit during W3C XML
conformance testing.
-rw-r--r-- | ChangeLog | 6 | ||||
-rw-r--r-- | gnu/xml/stream/SAXParser.java | 78 | ||||
-rw-r--r-- | gnu/xml/stream/XMLParser.java | 431 |
3 files changed, 376 insertions, 139 deletions
@@ -1,3 +1,9 @@ +2005-12-23 Chris Burdess <dog@gnu.org> + + * gnu/xml/stream/SAXParser.java, + gnu/xml/stream/XMLParser.java: Interim commit during W3C XML + conformance testing. + 2005-12-22 Lillian Angel <langel@redhat.com> * javax/swing/JInternalFrame.java diff --git a/gnu/xml/stream/SAXParser.java b/gnu/xml/stream/SAXParser.java index f17c11199..2ed6872c8 100644 --- a/gnu/xml/stream/SAXParser.java +++ b/gnu/xml/stream/SAXParser.java @@ -76,7 +76,8 @@ import org.xml.sax.ext.Locator2; */ public class SAXParser extends javax.xml.parsers.SAXParser - implements XMLReader, Attributes2, Locator2, XMLResolver, XMLReporter + implements XMLReader, Attributes2, Locator2, XMLReporter, + XMLParser.XMLResolver2 { ContentHandler contentHandler; @@ -377,6 +378,16 @@ public class SAXParser uri = ""; localName = ""; } + else + { + int nc = reader.getNamespaceCount(); + for (int i = 0; i < nc; i++) + { + String nsuri = reader.getNamespaceURI(i); + String nsprefix = reader.getNamespacePrefix(i); + contentHandler.startPrefixMapping(nsprefix, nsuri); + } + } contentHandler.startElement(uri, localName, qName, this); } break; @@ -396,6 +407,15 @@ public class SAXParser localName = ""; } contentHandler.endElement(uri, localName, qName); + if (namespaceAware) + { + int nc = reader.getNamespaceCount(); + for (int i = 0; i < nc; i++) + { + String nsprefix = reader.getNamespacePrefix(i); + contentHandler.endPrefixMapping(nsprefix); + } + } } break; case XMLStreamConstants.COMMENT: @@ -499,17 +519,26 @@ public class SAXParser if (ids.notationName != null) { if (dtdHandler != null) - dtdHandler.unparsedEntityDecl(name, - ids.publicId, - ids.systemId, - ids.notationName); + { + String pub = ids.publicId; + String url = ids.systemId; + String not = ids.notationName; + dtdHandler.unparsedEntityDecl(name, + pub, + url, + not); + } } else { if (declHandler != null) - declHandler.externalEntityDecl(name, - ids.publicId, - ids.systemId); + { + String pub = ids.publicId; + String url = ids.systemId; + declHandler.externalEntityDecl(name, + pub, + url); + } } } } @@ -520,8 +549,9 @@ public class SAXParser { XMLParser.ExternalIds ids = doctype.getNotation(name); - dtdHandler.notationDecl(name, ids.publicId, - ids.systemId); + String pub = ids.publicId; + String url = ids.systemId; + dtdHandler.notationDecl(name, pub, url); } } } @@ -536,6 +566,10 @@ public class SAXParser contentHandler.startDocument(); SAXParseException e2 = new SAXParseException(e.getMessage(), this); e2.initCause(e); + if (errorHandler != null) + errorHandler.fatalError(e2); + if (contentHandler != null) + contentHandler.endDocument(); throw e2; } finally @@ -607,7 +641,9 @@ public class SAXParser public String getType(int index) { - return reader.getAttributeType(index); + String ret = reader.getAttributeType(index); + // SAX doesn't permit ENUMERATION? + return ("ENUMERATION".equals(ret)) ? "NMTOKEN" : ret; } public String getType(String qName) @@ -715,15 +751,22 @@ public class SAXParser } // -- XMLResolver -- - + public InputStream resolve(String uri) throws XMLStreamException { + return resolve(null, uri); + } + + public InputStream resolve(String publicId, String systemId) + throws XMLStreamException + { if (entityResolver != null) { try { - InputSource input = entityResolver.resolveEntity(null, uri); + InputSource input = + entityResolver.resolveEntity(publicId, systemId); if (input != null) return input.getByteStream(); } @@ -777,5 +820,14 @@ public class SAXParser } } } + + public static void main(String[] args) + throws Exception + { + SAXParser parser = new SAXParser(); + InputSource input = new InputSource(args[0]); + parser.parse(input, new org.xml.sax.helpers.DefaultHandler()); + + } } diff --git a/gnu/xml/stream/XMLParser.java b/gnu/xml/stream/XMLParser.java index 82f860201..127382bfe 100644 --- a/gnu/xml/stream/XMLParser.java +++ b/gnu/xml/stream/XMLParser.java @@ -66,8 +66,9 @@ import java.net.MalformedURLException; import java.net.URL; import java.util.ArrayList; import java.util.Collections; -import java.util.LinkedHashMap; +import java.util.HashSet; import java.util.Iterator; +import java.util.LinkedHashMap; import java.util.LinkedList; import java.util.Map; import java.util.NoSuchElementException; @@ -91,7 +92,7 @@ import gnu.java.net.CRLFInputStream; * @author <a href='mailto:dog@gnu.org'>Chris Burdess</a> */ public class XMLParser - implements XMLStreamReader, NamespaceContext, Location + implements XMLStreamReader, NamespaceContext { private static final int INIT = 0; @@ -128,6 +129,7 @@ public class XMLParser private ArrayList attrs = new ArrayList(); private StringBuffer buf = new StringBuffer(); private StringBuffer nmtokenBuf = new StringBuffer(); + private StringBuffer literalBuf = new StringBuffer(); private char[] tmpBuf = new char[1024]; private String piTarget, piData; @@ -148,15 +150,15 @@ public class XMLParser private final boolean namespaceAware; private final boolean baseAware; - private final XMLReporter reporter; - private final XMLResolver resolver; + final XMLReporter reporter; + final XMLResolver resolver; private static final String TEST_START_ELEMENT = "<"; private static final String TEST_END_ELEMENT = "</"; private static final String TEST_COMMENT = "<!--"; private static final String TEST_PI = "<?"; private static final String TEST_CDATA = "<![CDATA["; - private static final String TEST_XML_DECL = "<?xml "; + private static final String TEST_XML_DECL = "<?xml"; private static final String TEST_DOCTYPE_DECL = "<!DOCTYPE"; private static final String TEST_ELEMENT_DECL = "<!ELEMENT"; private static final String TEST_ATTLIST_DECL = "<!ATTLIST"; @@ -286,28 +288,6 @@ public class XMLParser return acc.iterator(); } - // -- Location -- - - public int getCharacterOffset() - { - return input.offset; - } - - public int getColumnNumber() - { - return input.column; - } - - public int getLineNumber() - { - return input.line; - } - - public String getLocationURI() - { - return input.systemId; - } - // -- XMLStreamReader -- public void close() @@ -370,7 +350,7 @@ public class XMLParser if (att != null) return att.type; } - return null; + return "CDATA"; } public String getAttributeValue(int index) @@ -458,7 +438,7 @@ public class XMLParser public Location getLocation() { - return this; + return input; } public QName getName() @@ -782,6 +762,8 @@ public class XMLParser } try { + if (!input.initialized) + input.init(); //System.out.println("input="+input.name+" "+input.inputEncoding); switch (state) { @@ -840,7 +822,7 @@ public class XMLParser } else if (replaceERefs) { - expandEntity(ref); //report start-entity + expandEntity(ref, false); //report start-entity event = next(); } else @@ -857,6 +839,9 @@ public class XMLParser } break; case EMPTY_ELEMENT: + String elementName = (String) stack.removeLast(); + buf.setLength(0); + buf.append(elementName); state = stack.isEmpty() ? MISC : CONTENT; event = XMLStreamConstants.END_ELEMENT; break; @@ -1072,7 +1057,7 @@ public class XMLParser if (c == '\uffff') throw new EOFException(); else if (c < 32 && c != 10 && c != 9 && c != 13) - error("Illegal XML character:", Character.toString(c)); + error("illegal XML character", Character.toString(c)); buf.append(c); } } @@ -1096,7 +1081,12 @@ public class XMLParser if (white) ret = true; else if (c == '\uffff') - throw new EOFException(); + { + if (inputStack.size() > 1) + popInput(); + else + throw new EOFException(); + } } while (white); reset(); @@ -1114,6 +1104,11 @@ public class XMLParser { mark(1); char c = readCh(); + while (c == '\uffff' && inputStack.size() > 1) + { + popInput(); + c = readCh(); + } white = (c == ' ' || c == '\t' || c == '\n' || c == '\r'); } while (white); @@ -1150,6 +1145,13 @@ public class XMLParser private void pushInput(String name, String text) throws IOException, XMLStreamException { + // Check for recursion + for (Iterator i = inputStack.iterator(); i.hasNext(); ) + { + Input ctx = (Input) i.next(); + if (name.equals(ctx.name)) + error("entities may not be self-recursive", name); + } pushInput(new Input(null, new StringReader(text), input.publicId, input.systemId, name, input.inputEncoding)); //System.out.println("pushInput "+name+" "+text); @@ -1166,18 +1168,47 @@ public class XMLParser InputStream in = null; String base = getXMLBase(); String url = absolutize(base, ids.systemId); - // TODO try to resolve via public ID + // Unparsed entity? + boolean unparsedEntity = false; + if (ids.notationName != null) + { + ExternalIds notation = doctype.getNotation(ids.notationName); + if (notation == null) + error("reference to undeclared notation", ids.notationName); + unparsedEntity = true; + } + // Check for recursion + for (Iterator i = inputStack.iterator(); i.hasNext(); ) + { + Input ctx = (Input) i.next(); + if (url.equals(ctx.systemId)) + error("entities may not be self-recursive", url); + if (name.equals(ctx.name)) + error("entities may not be self-recursive", name); + } if (in == null && url != null && resolver != null) - in = resolver.resolve(url); + { + if (resolver instanceof XMLResolver2) + in = ((XMLResolver2) resolver).resolve(ids.publicId, url); + else + in = resolver.resolve(url); + } if (in == null) in = resolve(url); if (in == null) error("unable to resolve external entity", (ids.systemId != null) ? ids.systemId : ids.publicId); - pushInput(new Input(in, ids.publicId, url, name, input.inputEncoding)); - input.init(); - if (tryRead(TEST_XML_DECL)) - readTextDecl(); + if (unparsedEntity) + { + // TODO read unparsed entity into buf + } + else + { + pushInput(new Input(in, ids.publicId, url, name, input.inputEncoding)); + input.init(); + if (tryRead(TEST_XML_DECL)) + readTextDecl(); + } //System.out.println("pushInput "+name+" "+url); } @@ -1273,7 +1304,7 @@ public class XMLParser private void popInput() { Input old = (Input) inputStack.removeLast(); - if (startEntityStack.contains(old.name)) + if (!"".equals(old.name)) endEntityStack.addFirst(old.name); input = (Input) inputStack.getLast(); //System.out.print("\n(-input:"+input.systemId+")"); @@ -1287,6 +1318,7 @@ public class XMLParser throws IOException, XMLStreamException { final int flags = LIT_DISABLE_CREF | LIT_DISABLE_PE | LIT_DISABLE_EREF; + requireWhitespace(); if (tryRead("version")) { readEq(); @@ -1316,6 +1348,7 @@ public class XMLParser { final int flags = LIT_DISABLE_CREF | LIT_DISABLE_PE | LIT_DISABLE_EREF; + requireWhitespace(); require("version"); readEq(); xmlVersion = readLiteral(flags); @@ -1386,7 +1419,7 @@ public class XMLParser else { peIsError = expandPE = true; - readMarkupdecl(); + readMarkupdecl(false); peIsError = expandPE = false; } } @@ -1397,7 +1430,7 @@ public class XMLParser // Parse external subset if (ids.systemId != null && externalEntities) { - pushInput(null, ">"); + pushInput("", ">"); pushInput("[dtd]", ids); // loop until we get back to ">" while (true) @@ -1414,9 +1447,11 @@ public class XMLParser else { reset(); - peIsError = expandPE = true; - readMarkupdecl(); - peIsError = expandPE = false; + //peIsError = expandPE = true; + expandPE = true; + readMarkupdecl(true); + //peIsError = expandPE = false; + expandPE = true; } } if (inputStack.size() != 2) @@ -1429,7 +1464,7 @@ public class XMLParser buf.append(rootName); } - private void readMarkupdecl() + private void readMarkupdecl(boolean inExternalSubset) throws IOException, XMLStreamException { boolean saved = expandPE; @@ -1450,12 +1485,12 @@ public class XMLParser else if (tryRead(TEST_ENTITY_DECL)) { expandPE = saved; - readEntityDecl(); + readEntityDecl(inExternalSubset); } else if (tryRead(TEST_NOTATION_DECL)) { expandPE = saved; - readNotationDecl(); + readNotationDecl(inExternalSubset); } else if (tryRead(TEST_PI)) { @@ -1481,7 +1516,7 @@ public class XMLParser skipWhitespace(); while (!tryRead("]]>")) { - readMarkupdecl(); + readMarkupdecl(inExternalSubset); skipWhitespace(); } } @@ -1823,7 +1858,7 @@ public class XMLParser doctype.addAttributeDecl(elementName, name, attribute); } - private void readEntityDecl() + private void readEntityDecl(boolean inExternalSubset) throws IOException, XMLStreamException { int flags = 0; @@ -1840,7 +1875,7 @@ public class XMLParser // Read entity name String name = readNmtoken(true); if (name.indexOf(':') != -1) - error("Illegal character ':' in entity name", name); + error("illegal character ':' in entity name", name); if (peFlag) name = "%" + name; requireWhitespace(); @@ -1850,8 +1885,8 @@ public class XMLParser if (c == '"' || c == '\'') { // Internal entity replacement text - String value = readLiteral(flags); - doctype.addEntityDecl(name, value); + String value = readLiteral(flags | LIT_DISABLE_EREF); + doctype.addEntityDecl(name, value, inExternalSubset); } else { @@ -1865,30 +1900,30 @@ public class XMLParser requireWhitespace(); ids.notationName = readNmtoken(true); } - doctype.addEntityDecl(name, ids); + doctype.addEntityDecl(name, ids, inExternalSubset); } // finish skipWhitespace(); require('>'); } - private void readNotationDecl() + private void readNotationDecl(boolean inExternalSubset) throws IOException, XMLStreamException { requireWhitespace(); String notationName = readNmtoken(true); if (notationName.indexOf(':') != -1) - error("Illegal character ':' in notation name", notationName); + error("illegal character ':' in notation name", notationName); requireWhitespace(); ExternalIds ids = readExternalIds(true, false); ids.notationName = notationName; - doctype.addNotationDecl(notationName, ids); + doctype.addNotationDecl(notationName, ids, inExternalSubset); skipWhitespace(); require('>'); } /** - * Returns a tuple {publicId, syatemId}. + * Returns a tuple {publicId, systemId}. */ private ExternalIds readExternalIds(boolean inNotation, boolean isSubset) throws IOException, XMLStreamException @@ -1908,12 +1943,12 @@ public class XMLParser c = readCh(); reset(); if (c == '"' || c == '\'') - ids.systemId = readLiteral(flags); + ids.systemId = absolutize(input.systemId, readLiteral(flags)); } else { requireWhitespace(); - ids.systemId = readLiteral(flags); + ids.systemId = absolutize(input.systemId, readLiteral(flags)); } for (int i = 0; i < ids.publicId.length(); i++) @@ -1932,7 +1967,7 @@ public class XMLParser else if (tryRead("SYSTEM")) { requireWhitespace(); - ids.systemId = readLiteral(flags); + ids.systemId = absolutize(input.systemId, readLiteral(flags)); } else if (!isSubset) { @@ -2000,15 +2035,8 @@ public class XMLParser if (ctx.containsKey(attName.substring(6))) continue; // namespace was specified } - else - { - for (Iterator j = attrs.iterator(); j.hasNext(); ) - { - Attribute a = (Attribute) j.next(); - if (attName.equals(a.name)) - continue; // attribute was specified - } - } + else if (attributeSpecified(attName)) + continue; AttributeDecl decl = (AttributeDecl) entry.getValue(); if (decl.value == null) continue; @@ -2031,11 +2059,11 @@ public class XMLParser // make element name available for read buf.setLength(0); buf.append(elementName); + // push element onto stack + stack.addLast(elementName); switch (c) { case '>': - // push element onto stack - stack.addLast(elementName); return CONTENT; case '/': require('>'); @@ -2044,6 +2072,17 @@ public class XMLParser return -1; // to satisfy compiler } + private boolean attributeSpecified(String attName) + { + for (Iterator j = attrs.iterator(); j.hasNext(); ) + { + Attribute a = (Attribute) j.next(); + if (attName.equals(a.name)) + return true; + } + return false; + } + /** * Parse an attribute. */ @@ -2155,9 +2194,9 @@ public class XMLParser expandPE = false; piTarget = readNmtoken(true); if (piTarget.indexOf(':') != -1) - error("Illegal character in PI target", new Character(':')); + error("illegal character in PI target", new Character(':')); if ("xml".equalsIgnoreCase(piTarget)) - error("Illegal PI target", piTarget); + error("illegal PI target", piTarget); if (tryRead(TEST_END_PI)) piData = null; else @@ -2278,10 +2317,11 @@ public class XMLParser buf.append(text); else { - if (replaceERefs) - expandEntity(entityName); //report start-entity - else - reset(); // report reference + //if (replaceERefs) + // expandEntity(entityName, false); //report start-entity + //else + // reset(); // report reference + pushInput("", "&" + entityName + ";"); done = true; break; } @@ -2302,6 +2342,14 @@ public class XMLParser } entities = true; break; // end of text sequence + case '>': + int l = buf.length(); + if (l > 1 && + buf.charAt(l - 1) == ']' && + buf.charAt(l - 2) == ']') + error("Character data may not contain unescaped ']]>'"); + buf.append(c); + break; case '<': reset(); read(tmpBuf, 0, i); @@ -2325,14 +2373,14 @@ public class XMLParser done = true; } if (entities) - normalizeCRLF(); + normalizeCRLF(buf); return white ? XMLStreamConstants.SPACE : XMLStreamConstants.CHARACTERS; } /** * Expands the specified entity. */ - private void expandEntity(String name) + private void expandEntity(String name, boolean inAttr) throws IOException, XMLStreamException { if (doctype != null) @@ -2340,8 +2388,28 @@ public class XMLParser Object value = doctype.getEntity(name); if (value != null) { + if (xmlStandalone == Boolean.TRUE) + { + if (doctype.isEntityExternal(name)) + error("reference to external entity in standalone document"); + else if (value instanceof ExternalIds) + { + ExternalIds ids = (ExternalIds) value; + if (ids.notationName != null && + doctype.isNotationExternal(ids.notationName)) + error("reference to external notation in " + + "standalone document"); + } + } if (value instanceof String) - pushInput(name, (String) value); + { + String text = (String) value; + if (inAttr && text.indexOf('<') != -1) + error("< in attribute value"); + pushInput(name, text); + } + else if (inAttr) + error("reference to external entity in attribute value", name); else pushInput(name, (ExternalIds) value); if (name != null) @@ -2349,7 +2417,7 @@ public class XMLParser return; } } - error("Reference to undeclared entity", name); + error("reference to undeclared entity", name); } /** @@ -2389,12 +2457,16 @@ public class XMLParser char delim = readCh(); if (delim != '\'' && delim != '"') error("expected '\"' or \"'\"", new Character(delim)); - buf.setLength(0); + literalBuf.setLength(0); if ((flags & LIT_DISABLE_PE) != 0) expandPE = false; boolean entities = false; - for (char c = literalReadCh(); c != delim; c = literalReadCh()) + int inputStackSize = inputStack.size(); + do { + char c = literalReadCh(); + if (c == delim && inputStackSize == inputStack.size()) + break; switch (c) { case '\n': @@ -2412,61 +2484,83 @@ public class XMLParser if (c == '#') { if ((flags & LIT_DISABLE_CREF) != 0) - error("literal may not contain character reference"); - mark(1); - c = readCh(); - boolean hex = (c == 'x'); - if (!hex) - reset(); - char[] ref = readCharacterRef(hex ? 16 : 10); - for (int i = 0; i < ref.length; i++) { - c = ref[i]; - if ((flags & (LIT_ATTRIBUTE | LIT_PUBID)) != 0 && - (c == '\n' || c == '\r')) - c = ' '; // normalize - else if ((flags & LIT_ATTRIBUTE) != 0 && c == '\t') - c = ' '; // normalize - buf.append(c); + reset(); + c = '&'; + } + else + { + mark(1); + c = readCh(); + boolean hex = (c == 'x'); + if (!hex) + reset(); + char[] ref = readCharacterRef(hex ? 16 : 10); + for (int i = 0; i < ref.length; i++) + { + c = ref[i]; + if ((flags & (LIT_ATTRIBUTE | LIT_PUBID)) != 0 && + (c == '\n' || c == '\r')) + c = ' '; // normalize + else if ((flags & LIT_ATTRIBUTE) != 0 && c == '\t') + c = ' '; // normalize + literalBuf.append(c); + } + entities = true; + continue; } - entities = true; - continue; } else { if ((flags & LIT_DISABLE_EREF) != 0) - error("literal may not contain entity reference"); - reset(); - if (replaceERefs || (flags & LIT_NORMALIZE) > 0) { - String entityName = readNmtoken(true); - require(';'); - String text = (String) PREDEFINED_ENTITIES.get(entityName); - if (text != null) - buf.append(text); - else - expandEntity(entityName); - entities = true; - continue; + reset(); + c = '&'; } else - error("parser is configured not to replace entity " + - "references"); + { + reset(); + if (replaceERefs || (flags & LIT_NORMALIZE) > 0) + { + String entityName = readNmtoken(true); + require(';'); + String text = + (String) PREDEFINED_ENTITIES.get(entityName); + if (text != null) + literalBuf.append(text); + else + expandEntity(entityName, + (flags & LIT_ATTRIBUTE) != 0); + entities = true; + continue; + } + else + error("parser is configured not to replace entity " + + "references"); + } } break; case '<': if ((flags & LIT_ATTRIBUTE) != 0) error("attribute values may not contain '<'"); break; + case '\uffff': + if (inputStack.size() > 1) + { + popInput(); + continue; + } + throw new EOFException(); } - buf.append(c); + literalBuf.append(c); } + while (true); expandPE = saved; if (entities) - normalizeCRLF(); + normalizeCRLF(literalBuf); if ((flags & LIT_NORMALIZE) > 0) - normalize(); - return buf.toString(); + literalBuf = normalize(literalBuf); + return literalBuf.toString(); } /** @@ -2474,7 +2568,7 @@ public class XMLParser * This discards leading and trailing whitespace, and replaces sequences * of whitespace with a single space. */ - private void normalize() + private StringBuffer normalize(StringBuffer buf) { StringBuffer acc = new StringBuffer(); int len = buf.length(); @@ -2492,7 +2586,7 @@ public class XMLParser avState = 2; } } - buf = acc; + return acc; } /** @@ -2500,7 +2594,7 @@ public class XMLParser * This may be necessary if combinations of CR or LF were declared as * (character) entity references in the input. */ - private void normalizeCRLF() + private void normalizeCRLF(StringBuffer buf) { int len = buf.length() - 1; for (int i = 0; i < len; i++) @@ -2522,18 +2616,29 @@ public class XMLParser { String name = readNmtoken(true); require(';'); + mark(1); // ensure we don't reset to before the semicolon if (doctype != null) { - Object entity = doctype.getEntity("%" + name); + String entityName = "%" + name; + Object entity = doctype.getEntity(entityName); if (entity != null) { + if (xmlStandalone == Boolean.TRUE) + { + if (doctype.isEntityExternal(entityName)) + error("reference to external parameter entity in " + + "standalone document"); + } if (entity instanceof String) pushInput(name, (String) entity); else pushInput(name, (ExternalIds) entity); } + else + error("reference to undeclared parameter entity", name); } - error("reference to undeclared parameter entity", name); + else + error("reference to parameter entity without doctype", name); } private char[] readCharacterRef(int base) @@ -2888,6 +2993,8 @@ public class XMLParser private final LinkedHashMap entities = new LinkedHashMap(); private final LinkedHashMap notations = new LinkedHashMap(); private final LinkedList entries = new LinkedList(); + private final HashSet externalEntities = new HashSet(); + private final HashSet externalNotations = new HashSet(); Doctype(String rootName, String publicId, String systemId) { @@ -2920,28 +3027,34 @@ public class XMLParser entries.add(key); } - void addEntityDecl(String name, String text) + void addEntityDecl(String name, String text, boolean inExternalSubset) { if (entities.containsKey(name)) return; entities.put(name, text); entries.add("e" + name); + if (inExternalSubset) + externalEntities.add(name); } - void addEntityDecl(String name, ExternalIds ids) + void addEntityDecl(String name, ExternalIds ids, boolean inExternalSubset) { if (entities.containsKey(name)) return; entities.put(name, ids); entries.add("e" + name); + if (inExternalSubset) + externalEntities.add(name); } - void addNotationDecl(String name, ExternalIds ids) + void addNotationDecl(String name, ExternalIds ids, boolean inExternalSubset) { if (notations.containsKey(name)) return; notations.put(name, ids); entries.add("n" + name); + if (inExternalSubset) + externalNotations.add(name); } String getElementModel(String name) @@ -2973,11 +3086,21 @@ public class XMLParser return entities.get(name); } + boolean isEntityExternal(String name) + { + return externalEntities.contains(name); + } + ExternalIds getNotation(String name) { return (ExternalIds) notations.get(name); } + boolean isNotationExternal(String name) + { + return externalNotations.contains(name); + } + Iterator entryIterator() { return entries.iterator(); @@ -3011,7 +3134,17 @@ public class XMLParser } + interface XMLResolver2 + extends XMLResolver + { + + InputStream resolve(String publicId, String systemId) + throws XMLStreamException; + + } + static class Input + implements Location { int line = 1, markLine; @@ -3075,6 +3208,29 @@ public class XMLParser reader = new CRLFReader(reader); } this.reader = reader; + initialized = false; + } + + // -- Location -- + + public int getCharacterOffset() + { + return offset; + } + + public int getColumnNumber() + { + return column; + } + + public int getLineNumber() + { + return line; + } + + public String getLocationURI() + { + return systemId; } void init() @@ -3106,6 +3262,8 @@ public class XMLParser offset++; int ret = reader.read(); //System.out.println("read1:"+((char) ret)); + if (ret == 0x0d) + ret = 0x0a; if (ret == 0x0a) { line++; @@ -3129,6 +3287,11 @@ public class XMLParser for (int i = 0; i < ret; i++) { char c = b[off + i]; + if (c == 0x0d) + { + c = 0x0a; + b[off + i] = c; + } if (c == 0x0a) { line++; @@ -3251,6 +3414,22 @@ public class XMLParser reader = new XMLInputStreamReader((XMLInputStreamReader) reader, encoding); } + else + { + /*if (reporter != null) + { + try + { + reporter.report("unable to set input encoding '" + encoding + + "': input is specified as reader", "WARNING", + encoding, this); + } + catch (XMLStreamException e) + { + // Am I bothered? + }}*/ + System.err.println("Can't set input encoding "+encoding); + } } } |