diff options
Diffstat (limited to 'libjava/classpath/gnu/xml/stream/XMLParser.java')
-rw-r--r-- | libjava/classpath/gnu/xml/stream/XMLParser.java | 179 |
1 files changed, 90 insertions, 89 deletions
diff --git a/libjava/classpath/gnu/xml/stream/XMLParser.java b/libjava/classpath/gnu/xml/stream/XMLParser.java index 6f10b9303dc..9bb4834267e 100644 --- a/libjava/classpath/gnu/xml/stream/XMLParser.java +++ b/libjava/classpath/gnu/xml/stream/XMLParser.java @@ -137,6 +137,10 @@ public class XMLParser final static int ATTRIBUTE_DEFAULT_REQUIRED = 33; final static int ATTRIBUTE_DEFAULT_FIXED = 34; + // -- additional event types -- + final static int START_ENTITY = 50; + final static int END_ENTITY = 51; + /** * The current input. */ @@ -318,6 +322,12 @@ public class XMLParser private final boolean baseAware; /** + * Whether to report extended event types (START_ENTITY and END_ENTITY) + * in addition to the standard event types. Used by the SAX parser. + */ + private final boolean extendedEventTypes; + + /** * The reporter to receive parsing warnings. */ final XMLReporter reporter; @@ -389,6 +399,7 @@ public class XMLParser boolean supportDTD, boolean baseAware, boolean stringInterning, + boolean extendedEventTypes, XMLReporter reporter, XMLResolver resolver) { @@ -400,6 +411,7 @@ public class XMLParser this.supportDTD = supportDTD; this.baseAware = baseAware; this.stringInterning = stringInterning; + this.extendedEventTypes = extendedEventTypes; this.reporter = reporter; this.resolver = resolver; if (validating) @@ -446,6 +458,7 @@ public class XMLParser boolean supportDTD, boolean baseAware, boolean stringInterning, + boolean extendedEventTypes, XMLReporter reporter, XMLResolver resolver) { @@ -457,6 +470,7 @@ public class XMLParser this.supportDTD = supportDTD; this.baseAware = baseAware; this.stringInterning = stringInterning; + this.extendedEventTypes = extendedEventTypes; this.reporter = reporter; this.resolver = resolver; if (validating) @@ -561,7 +575,7 @@ public class XMLParser return attrs.size(); } - public String getAttributeName(int index) + public String getAttributeLocalName(int index) { Attribute a = (Attribute) attrs.get(index); return a.localName; @@ -579,7 +593,7 @@ public class XMLParser return a.prefix; } - public QName getAttributeQName(int index) + public QName getAttributeName(int index) { Attribute a = (Attribute) attrs.get(index); String namespaceURI = getNamespaceURI(a.prefix); @@ -710,7 +724,7 @@ public class XMLParser public int getNamespaceCount() { - if (!namespaceAware) + if (!namespaceAware || namespaces.isEmpty()) return 0; switch (event) { @@ -984,10 +998,10 @@ public class XMLParser if (event == XMLStreamConstants.END_ELEMENT) { // Pop namespace context - if (namespaceAware) + if (namespaceAware && !namespaces.isEmpty()) namespaces.removeFirst(); // Pop base context - if (baseAware) + if (baseAware && !bases.isEmpty()) bases.removeFirst(); } if (!startEntityStack.isEmpty()) @@ -995,16 +1009,16 @@ public class XMLParser String entityName = (String) startEntityStack.removeFirst(); buf.setLength(0); buf.append(entityName); - event = XMLStreamConstants.START_ENTITY; - return event; + event = START_ENTITY; + return extendedEventTypes ? event : next(); } else if (!endEntityStack.isEmpty()) { String entityName = (String) endEntityStack.removeFirst(); buf.setLength(0); buf.append(entityName); - event = XMLStreamConstants.END_ENTITY; - return event; + event = END_ENTITY; + return extendedEventTypes ? event : next(); } try { @@ -1484,7 +1498,6 @@ public class XMLParser { if (!externalEntities) return; - InputStream in = null; String url = absolutize(input.systemId, ids.systemId); // Check for recursion for (Iterator i = inputStack.iterator(); i.hasNext(); ) @@ -1497,12 +1510,13 @@ public class XMLParser } if (name == null || "".equals(name)) report = false; - if (in == null && url != null && resolver != null) + InputStream in = null; + if (resolver != null) { - if (resolver instanceof XMLResolver2) - in = ((XMLResolver2) resolver).resolve(ids.publicId, url); - else - in = resolver.resolve(url); + Object obj = resolver.resolveEntity(ids.publicId, url, getXMLBase(), + null); + if (obj instanceof InputStream) + in = (InputStream) obj; } if (in == null) in = resolve(url); @@ -1535,12 +1549,13 @@ public class XMLParser * @param base the current base URL * @param href the (absolute or relative) URL to resolve */ - static String absolutize(String base, String href) + public static String absolutize(String base, String href) + throws MalformedURLException { if (href == null) return null; int ci = href.indexOf(':'); - if (ci > 1 && isLowercaseAscii(href.substring(0, ci))) + if (ci > 1 && isURLScheme(href.substring(0, ci))) { // href is absolute already return href; @@ -1565,40 +1580,23 @@ public class XMLParser if (!base.endsWith("/")) base += "/"; } - if (href.startsWith("/")) - { - if (base.startsWith("file:")) - return "file://" + href; - int i = base.indexOf("://"); - if (i != -1) - { - i = base.indexOf('/', i + 3); - if (i != -1) - base = base.substring(0, i); - } - } - else - { - while (href.startsWith("..")) - { - int i = base.lastIndexOf('/', base.length() - 2); - if (i != -1) - base = base.substring(0, i + 1); - href = href.substring(2); - if (href.startsWith("/")) - href = href.substring(1); - } - } - return base + href; + return new URL(new URL(base), href).toString(); } - private static boolean isLowercaseAscii(String text) + /** + * Indicates whether the specified characters match the scheme portion of + * a URL. + * @see RFC 1738 section 2.1 + */ + private static boolean isURLScheme(String text) { int len = text.length(); for (int i = 0; i < len; i++) { char c = text.charAt(i); - if (c < 97 || c > 122) + if (c == '+' || c == '.' || c == '-') + continue; + if (c < 65 || (c > 90 && c < 97) || c > 122) return false; } return true; @@ -1607,7 +1605,7 @@ public class XMLParser /** * Returns an input stream for the given URL. */ - private InputStream resolve(String url) + static InputStream resolve(String url) throws IOException { try @@ -1618,6 +1616,12 @@ public class XMLParser { return null; } + catch (IOException e) + { + IOException e2 = new IOException("error resolving " + url); + e2.initCause(e); + throw e2; + } } /** @@ -1891,7 +1895,10 @@ public class XMLParser throws IOException, XMLStreamException { requireWhitespace(); + boolean saved = expandPE; + expandPE = (inputStack.size() > 1); String name = readNmtoken(true); + expandPE = saved; requireWhitespace(); readContentspec(name); skipWhitespace(); @@ -2106,7 +2113,10 @@ public class XMLParser throws IOException, XMLStreamException { requireWhitespace(); + boolean saved = expandPE; + expandPE = (inputStack.size() > 1); String elementName = readNmtoken(true); + expandPE = saved; boolean white = tryWhitespace(); while (!tryRead('>')) { @@ -2419,11 +2429,11 @@ public class XMLParser } else { - if (!isNameStartCharacter(cp[0])) + if (!isNameStartCharacter(cp[0], input.xml11)) error("malformed reference in entity value", value); for (int i = 1; i < cp.length; i++) { - if (!isNameCharacter(cp[i])) + if (!isNameCharacter(cp[i], input.xml11)) error("malformed reference in entity value", value); } } @@ -2838,8 +2848,6 @@ public class XMLParser error("Duplicate default namespace declaration"); if (XMLConstants.XML_NS_URI.equals(attr.value)) error("can't bind XML namespace"); - if ("".equals(attr.value) && !input.xml11) - error("illegal use of 1.1-style prefix unbinding in 1.0 document"); ctx.put(XMLConstants.DEFAULT_NS_PREFIX, attr.value); return true; } @@ -3087,7 +3095,15 @@ public class XMLParser break; case 0x3c: // '<' reset(); - read(tmpBuf, 0, i); + // read i characters + int count = 0, remaining = i; + do + { + int r = read(tmpBuf, 0, remaining); + count += r; + remaining -= r; + } + while (count < i); i = len; if (coalescing && tryRead(TEST_CDATA)) readUntil(TEST_END_CDATA); // read CDATA section into buf @@ -3258,15 +3274,7 @@ public class XMLParser reset(); char[] ref = readCharacterRef(hex ? 16 : 10); for (int i = 0; i < ref.length; i++) - { - char x = ref[i]; - if ((flags & (LIT_ATTRIBUTE | LIT_PUBID)) != 0 && - (x == 0x0a || x == 0x0d)) - x = 0x20; // normalize - else if ((flags & LIT_ATTRIBUTE) != 0 && x == 0x09) - x = 0x20; // normalize - literalBuf.append(x); - } + literalBuf.append(ref[i]); entities = true; continue; } @@ -3469,13 +3477,13 @@ public class XMLParser int c = readCh(); if (isName) { - if (!isNameStartCharacter(c)) + if (!isNameStartCharacter(c, input.xml11)) error("not a name start character", "U+" + Integer.toHexString(c)); } else { - if (!isNameCharacter(c)) + if (!isNameCharacter(c, input.xml11)) error("not a name character", "U+" + Integer.toHexString(c)); } @@ -3510,7 +3518,7 @@ public class XMLParser reset(); return intern(buf.toString()); default: - if (!isNameCharacter(c)) + if (!isNameCharacter(c, input.xml11)) error("not a name character", "U+" + Integer.toHexString(c)); else @@ -3523,7 +3531,7 @@ public class XMLParser /** * Indicates whether the specified Unicode character is an XML 1.1 Char. */ - private boolean isXML11Char(int c) + public static boolean isXML11Char(int c) { return ((c >= 0x0001 && c <= 0xD7FF) || (c >= 0xE000 && c < 0xFFFD) || // NB exclude 0xfffd @@ -3534,7 +3542,7 @@ public class XMLParser * Indicates whether the specified Unicode character is an XML 1.1 * RestrictedChar. */ - private boolean isXML11RestrictedChar(int c) + public static boolean isXML11RestrictedChar(int c) { return ((c >= 0x0001 && c <= 0x0008) || (c >= 0x000B && c <= 0x000C) || @@ -3556,17 +3564,17 @@ public class XMLParser return false; if (isName) { - if (!isNameStartCharacter(cp[0])) + if (!isNameStartCharacter(cp[0], input.xml11)) return false; } else { - if (!isNameCharacter(cp[0])) + if (!isNameCharacter(cp[0], input.xml11)) return false; } for (int i = 1; i < cp.length; i++) { - if (!isNameCharacter(cp[i])) + if (!isNameCharacter(cp[i], input.xml11)) return false; } return true; @@ -3581,9 +3589,9 @@ public class XMLParser * Indicates whether the specified Unicode character is a Name start * character. */ - private boolean isNameStartCharacter(int c) + public static boolean isNameStartCharacter(int c, boolean xml11) { - if (input.xml11) + if (xml11) return ((c >= 0x0041 && c <= 0x005a) || (c >= 0x0061 && c <= 0x007a) || c == 0x3a | @@ -3608,9 +3616,9 @@ public class XMLParser * Indicates whether the specified Unicode character is a Name non-initial * character. */ - private boolean isNameCharacter(int c) + public static boolean isNameCharacter(int c, boolean xml11) { - if (input.xml11) + if (xml11) return ((c >= 0x0041 && c <= 0x005a) || (c >= 0x0061 && c <= 0x007a) || (c >= 0x0030 && c <= 0x0039) || @@ -4255,6 +4263,7 @@ public class XMLParser true, // supportDTD true, // baseAware true, // stringInterning + true, // extendedEventTypes null, null); XMLStreamReader reader = p; @@ -4286,7 +4295,7 @@ public class XMLParser "='"+reader.getNamespaceURI(i)+"'"); l = reader.getAttributeCount(); for (int i = 0; i < l; i++) - System.out.println("\tattribute "+reader.getAttributeQName(i)+ + System.out.println("\tattribute "+reader.getAttributeName(i)+ "='"+reader.getAttributeValue(i)+"'"); break; case XMLStreamConstants.END_ELEMENT: @@ -4314,10 +4323,10 @@ public class XMLParser System.out.println("PROCESSING_INSTRUCTION "+reader.getPITarget()+ " "+reader.getPIData()); break; - case XMLStreamConstants.START_ENTITY: + case START_ENTITY: System.out.println("START_ENTITY "+reader.getText()); break; - case XMLStreamConstants.END_ENTITY: + case END_ENTITY: System.out.println("END_ENTITY "+reader.getText()); break; default: @@ -4330,7 +4339,7 @@ public class XMLParser Location l = reader.getLocation(); System.out.println("At line "+l.getLineNumber()+ ", column "+l.getColumnNumber()+ - " of "+l.getLocationURI()); + " of "+l.getSystemId()); throw e; } } @@ -4939,19 +4948,6 @@ public class XMLParser } /** - * Compatibility interface that can be used to resolve based on a public - * ID, not just an URL. - */ - interface XMLResolver2 - extends XMLResolver - { - - InputStream resolve(String publicId, String systemId) - throws XMLStreamException; - - } - - /** * An XML input source. */ static class Input @@ -5019,7 +5015,12 @@ public class XMLParser return line; } - public String getLocationURI() + public String getPublicId() + { + return publicId; + } + + public String getSystemId() { return systemId; } |