Merge "Fix XML DOM test failures and close guard warnings." into dalvik-dev
diff --git a/luni/src/main/java/libcore/base/Streams.java b/luni/src/main/java/libcore/base/Streams.java
index 0ef5189..037d988 100644
--- a/luni/src/main/java/libcore/base/Streams.java
+++ b/luni/src/main/java/libcore/base/Streams.java
@@ -20,6 +20,7 @@
import java.io.EOFException;
import java.io.IOException;
import java.io.InputStream;
+import java.io.OutputStream;
import java.util.concurrent.atomic.AtomicReference;
public final class Streams {
@@ -112,4 +113,19 @@
return skipped;
}
+
+ /**
+ * Copies all of the bytes from {@code in} to {@code out}. Neither stream is closed.
+ * Returns the total number of bytes transferred.
+ */
+ public static int copy(InputStream in, OutputStream out) throws IOException {
+ int total = 0;
+ byte[] buffer = new byte[8192];
+ int c;
+ while ((c = in.read(buffer)) != -1) {
+ total += c;
+ out.write(buffer, 0, c);
+ }
+ return total;
+ }
}
diff --git a/luni/src/main/java/org/apache/harmony/xml/parsers/DocumentBuilderImpl.java b/luni/src/main/java/org/apache/harmony/xml/parsers/DocumentBuilderImpl.java
index 224e59e..e2ff801 100644
--- a/luni/src/main/java/org/apache/harmony/xml/parsers/DocumentBuilderImpl.java
+++ b/luni/src/main/java/org/apache/harmony/xml/parsers/DocumentBuilderImpl.java
@@ -19,8 +19,8 @@
import java.io.IOException;
import java.net.URL;
import java.net.URLConnection;
-import java.util.StringTokenizer;
import javax.xml.parsers.DocumentBuilder;
+import libcore.io.IoUtils;
import org.apache.harmony.xml.dom.CDATASectionImpl;
import org.apache.harmony.xml.dom.DOMImplementationImpl;
import org.apache.harmony.xml.dom.DocumentImpl;
@@ -93,7 +93,7 @@
@Override
public Document parse(InputSource source) throws SAXException, IOException {
if (source == null) {
- throw new IllegalArgumentException();
+ throw new IllegalArgumentException("source == null");
}
String namespaceURI = null;
@@ -105,8 +105,8 @@
dom, namespaceURI, qualifiedName, doctype, inputEncoding);
document.setDocumentURI(systemId);
+ KXmlParser parser = new KXmlParser();
try {
- KXmlParser parser = new KXmlParser();
parser.keepNamespaceAttributes();
parser.setFeature(XmlPullParser.FEATURE_PROCESS_NAMESPACES, namespaceAware);
@@ -121,24 +121,22 @@
// TODO: if null, extract the inputEncoding from the Content-Type header?
parser.setInput(urlConnection.getInputStream(), inputEncoding);
} else {
- throw new SAXParseException(
- "InputSource needs a stream, reader or URI", null);
+ throw new SAXParseException("InputSource needs a stream, reader or URI", null);
}
- if(parser.nextToken() == XmlPullParser.END_DOCUMENT) {
- throw new SAXParseException(
- "Unexpected end of document", null);
+ if (parser.nextToken() == XmlPullParser.END_DOCUMENT) {
+ throw new SAXParseException("Unexpected end of document", null);
}
parse(parser, document, document, XmlPullParser.END_DOCUMENT);
parser.require(XmlPullParser.END_DOCUMENT, null, null);
} catch (XmlPullParserException ex) {
- if(ex.getDetail() instanceof IOException) {
- throw (IOException)ex.getDetail();
+ if (ex.getDetail() instanceof IOException) {
+ throw (IOException) ex.getDetail();
}
- if(ex.getDetail() instanceof RuntimeException) {
- throw (RuntimeException)ex.getDetail();
+ if (ex.getDetail() instanceof RuntimeException) {
+ throw (RuntimeException) ex.getDetail();
}
LocatorImpl locator = new LocatorImpl();
@@ -148,14 +146,15 @@
locator.setLineNumber(ex.getLineNumber());
locator.setColumnNumber(ex.getColumnNumber());
- SAXParseException newEx = new SAXParseException(ex.getMessage(),
- locator);
+ SAXParseException newEx = new SAXParseException(ex.getMessage(), locator);
if (errorHandler != null) {
errorHandler.error(newEx);
}
throw newEx;
+ } finally {
+ IoUtils.closeQuietly(parser);
}
return document;
@@ -178,7 +177,7 @@
* @throws XmlPullParserException If a parsing error occurs.
* @throws IOException If a general IO error occurs.
*/
- private void parse(XmlPullParser parser, DocumentImpl document, Node node,
+ private void parse(KXmlParser parser, DocumentImpl document, Node node,
int endToken) throws XmlPullParserException, IOException {
int token = parser.getEventType();
@@ -205,45 +204,10 @@
node.appendChild(document.createProcessingInstruction(target,
data));
} else if (token == XmlPullParser.DOCDECL) {
- /*
- * Found a document type declaration. Unfortunately KXML doesn't
- * have the necessary details. Do we parse it ourselves, or do
- * we silently ignore it, since it isn't mandatory in DOM 2
- * anyway?
- */
- StringTokenizer tokenizer = new StringTokenizer(parser.getText());
- if (tokenizer.hasMoreTokens()) {
- String name = tokenizer.nextToken();
- String pubid = null;
- String sysid = null;
-
- if (tokenizer.hasMoreTokens()) {
- String text = tokenizer.nextToken();
-
- if ("SYSTEM".equals(text)) {
- if (tokenizer.hasMoreTokens()) {
- sysid = tokenizer.nextToken();
- }
- } else if ("PUBLIC".equals(text)) {
- if (tokenizer.hasMoreTokens()) {
- pubid = tokenizer.nextToken();
- }
- if (tokenizer.hasMoreTokens()) {
- sysid = tokenizer.nextToken();
- }
- }
- }
-
- if (pubid != null && pubid.length() >= 2 && pubid.startsWith("\"") && pubid.endsWith("\"")) {
- pubid = pubid.substring(1, pubid.length() - 1);
- }
-
- if (sysid != null && sysid.length() >= 2 && sysid.startsWith("\"") && sysid.endsWith("\"")) {
- sysid = sysid.substring(1, sysid.length() - 1);
- }
-
- document.appendChild(new DocumentTypeImpl(document, name, pubid, sysid));
- }
+ String name = parser.getRootElementName();
+ String publicId = parser.getPublicId();
+ String systemId = parser.getSystemId();
+ document.appendChild(new DocumentTypeImpl(document, name, publicId, systemId));
} else if (token == XmlPullParser.COMMENT) {
/*
diff --git a/luni/src/test/java/libcore/java/util/jar/DalvikExecTest.java b/luni/src/test/java/libcore/java/util/jar/DalvikExecTest.java
index 1f66653..24ecd84 100644
--- a/luni/src/test/java/libcore/java/util/jar/DalvikExecTest.java
+++ b/luni/src/test/java/libcore/java/util/jar/DalvikExecTest.java
@@ -27,6 +27,7 @@
import java.util.jar.JarOutputStream;
import java.util.jar.Manifest;
import junit.framework.TestCase;
+import libcore.base.Streams;
import static tests.support.Support_Exec.execAndGetOutput;
import tests.support.resource.Support_Resources;
@@ -113,7 +114,7 @@
// Fill in the classes.dex contents, i.e. the Dalvik executable code:
// (See below for the detailed source code contents.)
- Support_Resources.writeResourceToStream("cts_dalvikExecTest_classes.dex", jarOut);
+ Streams.copy(Support_Resources.getResourceStream("cts_dalvikExecTest_classes.dex"), jarOut);
// Now add a resource file:
//
@@ -168,7 +169,7 @@
// Fill in the classes.dex contents, i.e. the Dalvik executable code:
// (See below for the detailed source code contents.)
- Support_Resources.writeResourceToStream("cts_dalvikExecTest_classes.dex", jarOut);
+ Streams.copy(Support_Resources.getResourceStream("cts_dalvikExecTest_classes.dex"), jarOut);
// Now add a resource file:
//
diff --git a/luni/src/test/java/libcore/xml/PullParserTest.java b/luni/src/test/java/libcore/xml/PullParserTest.java
index dc5a133..21342b2 100644
--- a/luni/src/test/java/libcore/xml/PullParserTest.java
+++ b/luni/src/test/java/libcore/xml/PullParserTest.java
@@ -254,7 +254,8 @@
assertEquals(XmlPullParser.START_TAG, parser.next());
assertEquals(XmlPullParser.TEXT, parser.next());
assertEquals(null, parser.getName());
- assertEquals("&aaa;", parser.getText());
+ assertEquals("Expected unresolved entities to be left in-place. The old parser "
+ + "would resolve these to the empty string.", "&aaa;", parser.getText());
assertEquals(XmlPullParser.END_TAG, parser.next());
}
@@ -279,7 +280,7 @@
assertEquals(XmlPullParser.END_TAG, parser.next());
}
- public void testEntityInAttributeWithNextToken() throws Exception {
+ public void testEntityInAttributeUsingNextToken() throws Exception {
XmlPullParser parser = newPullParser();
parser.setInput(new StringReader("<foo bar=\"&\"></foo>"));
assertEquals(XmlPullParser.START_TAG, parser.nextToken());
@@ -287,6 +288,45 @@
assertEquals("&", parser.getAttributeValue(null, "bar"));
}
+ public void testMissingEntitiesInAttributesUsingNext() throws Exception {
+ XmlPullParser parser = newPullParser();
+ parser.setInput(new StringReader("<foo b='&aaa;'></foo>"));
+ assertNextFails(parser);
+ }
+
+ public void testMissingEntitiesInAttributesUsingNextWithRelaxed() throws Exception {
+ XmlPullParser parser = newPullParser();
+ parser.setInput(new StringReader("<foo b='&aaa;'></foo>"));
+ parser.setFeature("http://xmlpull.org/v1/doc/features.html#relaxed", true);
+ assertEquals(XmlPullParser.START_TAG, parser.nextToken());
+ assertEquals(1, parser.getAttributeCount());
+ assertEquals("b", parser.getAttributeName(0));
+ assertEquals("Expected unresolved entities to be left in-place. The old parser "
+ + "would resolve these to the empty string.", "&aaa;", parser.getAttributeValue(0));
+ }
+
+ public void testMissingEntitiesInAttributesUsingNextToken() throws Exception {
+ XmlPullParser parser = newPullParser();
+ parser.setInput(new StringReader("<foo b='&aaa;'></foo>"));
+ testMissingEntitiesInAttributesUsingNextToken(parser);
+ }
+
+ public void testMissingEntitiesInAttributesUsingNextTokenWithRelaxed() throws Exception {
+ XmlPullParser parser = newPullParser();
+ parser.setInput(new StringReader("<foo b='&aaa;'></foo>"));
+ parser.setFeature("http://xmlpull.org/v1/doc/features.html#relaxed", true);
+ testMissingEntitiesInAttributesUsingNextToken(parser);
+ }
+
+ private void testMissingEntitiesInAttributesUsingNextToken(XmlPullParser parser)
+ throws IOException, XmlPullParserException {
+ assertEquals(XmlPullParser.START_TAG, parser.nextToken());
+ assertEquals(1, parser.getAttributeCount());
+ assertEquals("b", parser.getAttributeName(0));
+ assertEquals("Expected unresolved entities to be left in-place. The old parser "
+ + "would resolve these to the empty string.", "&aaa;", parser.getAttributeValue(0));
+ }
+
public void testGreaterThanInText() throws Exception {
XmlPullParser parser = newPullParser();
parser.setInput(new StringReader("<foo>></foo>"));
@@ -392,7 +432,7 @@
assertEquals("]]]]]]]]]]]]]]]]]]]]]]]", parser.getText());
}
- public void testCommentWithNext() throws Exception {
+ public void testCommentUsingNext() throws Exception {
XmlPullParser parser = newPullParser();
parser.setInput(new StringReader("<foo>ab<!-- comment! -->cd</foo>"));
assertEquals(XmlPullParser.START_TAG, parser.next());
@@ -400,7 +440,7 @@
assertEquals("abcd", parser.getText());
}
- public void testCommentWithNextToken() throws Exception {
+ public void testCommentUsingNextToken() throws Exception {
XmlPullParser parser = newPullParser();
parser.setInput(new StringReader("<foo>ab<!-- comment! -->cd</foo>"));
assertEquals(XmlPullParser.START_TAG, parser.next());
@@ -412,7 +452,7 @@
assertEquals("cd", parser.getText());
}
- public void testCdataWithNext() throws Exception {
+ public void testCdataUsingNext() throws Exception {
XmlPullParser parser = newPullParser();
parser.setInput(new StringReader("<foo>ab<![CDATA[cdef]]gh&i]]>jk</foo>"));
assertEquals(XmlPullParser.START_TAG, parser.next());
@@ -421,7 +461,7 @@
assertEquals(XmlPullParser.END_TAG, parser.next());
}
- public void testCdataWithNextToken() throws Exception {
+ public void testCdataUsingNextToken() throws Exception {
XmlPullParser parser = newPullParser();
parser.setInput(new StringReader("<foo>ab<![CDATA[cdef]]gh&i]]>jk</foo>"));
assertEquals(XmlPullParser.START_TAG, parser.next());
@@ -442,7 +482,7 @@
assertEquals("]]>", parser.getText());
}
- public void testProcessingInstructionWithNext() throws Exception {
+ public void testProcessingInstructionUsingNext() throws Exception {
XmlPullParser parser = newPullParser();
parser.setInput(new StringReader("<foo>ab<?cd efg hij?>kl</foo>"));
assertEquals(XmlPullParser.START_TAG, parser.next());
@@ -451,7 +491,7 @@
assertEquals(XmlPullParser.END_TAG, parser.next());
}
- public void testProcessingInstructionWithNextToken() throws Exception {
+ public void testProcessingInstructionUsingNextToken() throws Exception {
XmlPullParser parser = newPullParser();
parser.setInput(new StringReader("<foo>ab<?cd efg hij?>kl</foo>"));
assertEquals(XmlPullParser.START_TAG, parser.nextToken());
@@ -464,7 +504,7 @@
assertEquals(XmlPullParser.END_TAG, parser.next());
}
- public void testWhitespaceWithNextToken() throws Exception {
+ public void testWhitespaceUsingNextToken() throws Exception {
XmlPullParser parser = newPullParser();
parser.setInput(new StringReader(" \n <foo> \n </foo> \n "));
assertEquals(XmlPullParser.IGNORABLE_WHITESPACE, parser.nextToken());
@@ -513,7 +553,7 @@
assertEquals("7,7", parser.getLineNumber() + "," + parser.getColumnNumber());
}
- public void testEmptyEntityReferenceWithNext() throws Exception {
+ public void testEmptyEntityReferenceUsingNext() throws Exception {
XmlPullParser parser = newPullParser();
parser.setInput(new StringReader("<foo>∅</foo>"));
parser.defineEntityReplacementText("empty", "");
@@ -521,7 +561,7 @@
assertEquals(XmlPullParser.END_TAG, parser.next());
}
- public void testEmptyEntityReferenceWithNextToken() throws Exception {
+ public void testEmptyEntityReferenceUsingNextToken() throws Exception {
XmlPullParser parser = newPullParser();
parser.setInput(new StringReader("<foo>∅</foo>"));
parser.defineEntityReplacementText("empty", "");
@@ -532,14 +572,14 @@
assertEquals(XmlPullParser.END_TAG, parser.nextToken());
}
- public void testEmptyCdataWithNext() throws Exception {
+ public void testEmptyCdataUsingNext() throws Exception {
XmlPullParser parser = newPullParser();
parser.setInput(new StringReader("<foo><![CDATA[]]></foo>"));
assertEquals(XmlPullParser.START_TAG, parser.next());
assertEquals(XmlPullParser.END_TAG, parser.next());
}
- public void testEmptyCdataWithNextToken() throws Exception {
+ public void testEmptyCdataUsingNextToken() throws Exception {
XmlPullParser parser = newPullParser();
parser.setInput(new StringReader("<foo><![CDATA[]]></foo>"));
assertEquals(XmlPullParser.START_TAG, parser.next());
diff --git a/luni/src/test/java/tests/api/javax/xml/parsers/SAXParserTest.java b/luni/src/test/java/tests/api/javax/xml/parsers/SAXParserTest.java
index 04e2c53..5bcc7ac 100644
--- a/luni/src/test/java/tests/api/javax/xml/parsers/SAXParserTest.java
+++ b/luni/src/test/java/tests/api/javax/xml/parsers/SAXParserTest.java
@@ -15,22 +15,22 @@
*/
package tests.api.javax.xml.parsers;
+import dalvik.annotation.KnownFailure;
+import dalvik.annotation.TestLevel;
+import dalvik.annotation.TestTargetClass;
+import dalvik.annotation.TestTargetNew;
+import dalvik.annotation.TestTargets;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
-import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
-import java.io.OutputStream;
import java.util.HashMap;
import java.util.Vector;
-
import javax.xml.parsers.SAXParser;
import javax.xml.parsers.SAXParserFactory;
-
import junit.framework.TestCase;
-
import org.xml.sax.HandlerBase;
import org.xml.sax.InputSource;
import org.xml.sax.Parser;
@@ -40,18 +40,12 @@
import org.xml.sax.XMLReader;
import org.xml.sax.ext.LexicalHandler;
import org.xml.sax.helpers.DefaultHandler;
-
import tests.api.javax.xml.parsers.SAXParserTestSupport.MyDefaultHandler;
import tests.api.javax.xml.parsers.SAXParserTestSupport.MyHandler;
import tests.api.org.xml.sax.support.BrokenInputStream;
import tests.api.org.xml.sax.support.MethodLogger;
import tests.api.org.xml.sax.support.MockHandler;
import tests.support.resource.Support_Resources;
-import dalvik.annotation.KnownFailure;
-import dalvik.annotation.TestLevel;
-import dalvik.annotation.TestTargetClass;
-import dalvik.annotation.TestTargetNew;
-import dalvik.annotation.TestTargets;
@SuppressWarnings("deprecation")
@TestTargetClass(SAXParser.class)
@@ -454,10 +448,8 @@
args = {org.xml.sax.InputSource.class, org.xml.sax.helpers.DefaultHandler.class}
)
public void test_parseLorg_xml_sax_InputSourceLorg_xml_sax_helpers_DefaultHandler()
- throws Exception {
-
+ throws Exception {
for(int i = 0; i < list_wf.length; i++) {
-
HashMap<String, String> hm = new SAXParserTestSupport().readFile(
list_out_dh[i].getPath());
MyDefaultHandler dh = new MyDefaultHandler();
@@ -466,15 +458,13 @@
assertTrue(SAXParserTestSupport.equalsMaps(hm, dh.createData()));
}
- for(int i = 0; i < list_nwf.length; i++) {
+ for (File file : list_nwf) {
try {
MyDefaultHandler dh = new MyDefaultHandler();
- InputSource is = new InputSource(
- new FileInputStream(list_nwf[i]));
+ InputSource is = new InputSource(new FileInputStream(file));
parser.parse(is, dh);
fail("SAXException is not thrown");
- } catch(org.xml.sax.SAXException se) {
- //expected
+ } catch (SAXException expected) {
}
}
@@ -482,23 +472,21 @@
MyDefaultHandler dh = new MyDefaultHandler();
parser.parse((InputSource) null, dh);
fail("java.lang.IllegalArgumentException is not thrown");
- } catch(java.lang.IllegalArgumentException iae) {
- //expected
+ } catch (IllegalArgumentException expected) {
}
- try {
- InputSource is = new InputSource(new FileInputStream(list_wf[0]));
- parser.parse(is, (DefaultHandler) null);
- } catch(java.lang.IllegalArgumentException iae) {
- fail("java.lang.IllegalArgumentException is thrown");
- }
+ InputSource is = new InputSource(new FileInputStream(list_wf[0]));
+ parser.parse(is, (DefaultHandler) null);
+ InputStream in = null;
try {
- InputSource is = new InputSource(new BrokenInputStream(new FileInputStream(list_wf[0]), 10));
+ in = new BrokenInputStream(new FileInputStream(list_wf[0]), 10);
+ is = new InputSource(in);
parser.parse(is, (DefaultHandler) null);
fail("IOException expected");
- } catch(IOException e) {
- // Expected
+ } catch(IOException expected) {
+ } finally {
+ in.close();
}
}
@@ -508,35 +496,22 @@
method = "parse",
args = {org.xml.sax.InputSource.class, org.xml.sax.HandlerBase.class}
)
- public void testParseInputSourceHandlerBase() {
+ public void testParseInputSourceHandlerBase() throws Exception {
for(int i = 0; i < list_wf.length; i++) {
- try {
- HashMap<String, String> hm = sp.readFile(
- list_out_hb[i].getPath());
- MyHandler dh = new MyHandler();
- InputSource is = new InputSource(new FileInputStream(list_wf[i]));
- parser.parse(is, dh);
- assertTrue(SAXParserTestSupport.equalsMaps(hm,
- dh.createData()));
- } catch (IOException ioe) {
- fail("Unexpected IOException " + ioe.toString());
- } catch (SAXException sax) {
- fail("Unexpected SAXException " + sax.toString());
- }
+ HashMap<String, String> hm = sp.readFile(list_out_hb[i].getPath());
+ MyHandler dh = new MyHandler();
+ InputSource is = new InputSource(new FileInputStream(list_wf[i]));
+ parser.parse(is, dh);
+ assertTrue(SAXParserTestSupport.equalsMaps(hm, dh.createData()));
}
- for(int i = 0; i < list_nwf.length; i++) {
+ for (File file : list_nwf) {
try {
MyHandler dh = new MyHandler();
- InputSource is = new InputSource(new FileInputStream(list_nwf[i]));
+ InputSource is = new InputSource(new FileInputStream(file));
parser.parse(is, dh);
fail("SAXException is not thrown");
- } catch(org.xml.sax.SAXException se) {
- //expected
- } catch (FileNotFoundException fne) {
- fail("Unexpected FileNotFoundException " + fne.toString());
- } catch (IOException ioe) {
- fail("Unexpected IOException " + ioe.toString());
+ } catch (SAXException expected) {
}
}
@@ -544,67 +519,29 @@
MyHandler dh = new MyHandler();
parser.parse((InputSource) null, dh);
fail("java.lang.IllegalArgumentException is not thrown");
- } catch(java.lang.IllegalArgumentException iae) {
- //expected
- } catch (IOException ioe) {
- fail("Unexpected IOException " + ioe.toString());
- } catch(SAXException sax) {
- fail("Unexpected SAXException " + sax.toString());
+ } catch(IllegalArgumentException expected) {
}
- try {
- InputSource is = new InputSource(new FileInputStream(list_wf[0]));
- parser.parse(is, (HandlerBase) null);
- } catch(java.lang.IllegalArgumentException iae) {
- fail("java.lang.IllegalArgumentException is thrown");
- } catch (FileNotFoundException fne) {
- fail("Unexpected FileNotFoundException " + fne.toString());
- } catch(IOException ioe) {
- fail("Unexpected IOException " + ioe.toString());
- } catch(SAXException sax) {
- fail("Unexpected SAXException " + sax.toString());
- }
+ InputSource is = new InputSource(new FileInputStream(list_wf[0]));
+ parser.parse(is, (HandlerBase) null);
// Reader case
- try {
- InputSource is = new InputSource(new InputStreamReader(
- new FileInputStream(list_wf[0])));
- parser.parse(is, (HandlerBase) null);
- } catch(java.lang.IllegalArgumentException iae) {
- fail("java.lang.IllegalArgumentException is thrown");
- } catch (FileNotFoundException fne) {
- fail("Unexpected FileNotFoundException " + fne.toString());
- } catch(IOException ioe) {
- fail("Unexpected IOException " + ioe.toString());
- } catch(SAXException sax) {
- fail("Unexpected SAXException " + sax.toString());
- }
+ is = new InputSource(new InputStreamReader(new FileInputStream(list_wf[0])));
+ parser.parse(is, (HandlerBase) null);
// SystemID case
- try {
- InputSource is = new InputSource(list_wf[0].toURI().toString());
- parser.parse(is, (HandlerBase) null);
- } catch(java.lang.IllegalArgumentException iae) {
- fail("java.lang.IllegalArgumentException is thrown");
- } catch (FileNotFoundException fne) {
- fail("Unexpected FileNotFoundException " + fne.toString());
- } catch(IOException ioe) {
- fail("Unexpected IOException " + ioe.toString());
- } catch(SAXException sax) {
- fail("Unexpected SAXException " + sax.toString());
- }
+ is = new InputSource(list_wf[0].toURI().toString());
+ parser.parse(is, (HandlerBase) null);
// Inject IOException
+ InputStream in = null;
try {
- InputStream is = new BrokenInputStream(
- new FileInputStream(list_wf[0]), 10);
- parser.parse(is, (HandlerBase) null,
- SAXParserTestSupport.XML_SYSTEM_ID);
+ in = new BrokenInputStream(new FileInputStream(list_wf[0]), 10);
+ parser.parse(in, (HandlerBase) null, SAXParserTestSupport.XML_SYSTEM_ID);
fail("IOException expected");
- } catch(IOException e) {
- // Expected
- } catch (Exception e) {
- throw new RuntimeException("Unexpected exception", e);
+ } catch(IOException expected) {
+ } finally {
+ in.close();
}
}
@@ -784,35 +721,22 @@
method = "parse",
args = {java.io.InputStream.class, org.xml.sax.HandlerBase.class}
)
- public void testParseInputStreamHandlerBase() {
+ public void testParseInputStreamHandlerBase() throws Exception {
for(int i = 0; i < list_wf.length; i++) {
- try {
- HashMap<String, String> hm = sp.readFile(
- list_out_hb[i].getPath());
- MyHandler dh = new MyHandler();
- InputStream is = new FileInputStream(list_wf[i]);
- parser.parse(is, dh);
- assertTrue(SAXParserTestSupport.equalsMaps(hm,
- dh.createData()));
- } catch (IOException ioe) {
- fail("Unexpected IOException " + ioe.toString());
- } catch (SAXException sax) {
- fail("Unexpected SAXException " + sax.toString());
- }
+ HashMap<String, String> hm = sp.readFile(list_out_hb[i].getPath());
+ MyHandler dh = new MyHandler();
+ InputStream is = new FileInputStream(list_wf[i]);
+ parser.parse(is, dh);
+ assertTrue(SAXParserTestSupport.equalsMaps(hm, dh.createData()));
}
- for(int i = 0; i < list_nwf.length; i++) {
+ for (File file : list_nwf) {
try {
MyHandler dh = new MyHandler();
- InputStream is = new FileInputStream(list_nwf[i]);
+ InputStream is = new FileInputStream(file);
parser.parse(is, dh);
fail("SAXException is not thrown");
- } catch(org.xml.sax.SAXException se) {
- //expected
- } catch (FileNotFoundException fne) {
- fail("Unexpected FileNotFoundException " + fne.toString());
- } catch (IOException ioe) {
- fail("Unexpected IOException " + ioe.toString());
+ } catch (SAXException expected) {
}
}
@@ -820,37 +744,21 @@
MyHandler dh = new MyHandler();
parser.parse((InputStream) null, dh);
fail("java.lang.IllegalArgumentException is not thrown");
- } catch(java.lang.IllegalArgumentException iae) {
- //expected
- } catch (IOException ioe) {
- fail("Unexpected IOException " + ioe.toString());
- } catch(SAXException sax) {
- fail("Unexpected SAXException " + sax.toString());
+ } catch (IllegalArgumentException expected) {
}
- try {
- InputStream is = new FileInputStream(list_wf[0]);
- parser.parse(is, (HandlerBase) null);
- } catch(java.lang.IllegalArgumentException iae) {
- fail("java.lang.IllegalArgumentException is thrown");
- } catch (FileNotFoundException fne) {
- fail("Unexpected FileNotFoundException " + fne.toString());
- } catch(IOException ioe) {
- fail("Unexpected IOException " + ioe.toString());
- } catch(SAXException sax) {
- fail("Unexpected SAXException " + sax.toString());
- }
+ InputStream is = new FileInputStream(list_wf[0]);
+ parser.parse(is, (HandlerBase) null);
// Inject IOException
try {
- InputStream is = new BrokenInputStream(
- new FileInputStream(list_wf[0]), 10);
+ is = new BrokenInputStream(new FileInputStream(list_wf[0]), 10);
parser.parse(is, (HandlerBase) null);
fail("IOException expected");
} catch(IOException e) {
// Expected
- } catch (Exception e) {
- throw new RuntimeException("Unexpected exception", e);
+ } finally {
+ is.close();
}
}
@@ -860,76 +768,43 @@
method = "parse",
args = {java.io.InputStream.class, org.xml.sax.HandlerBase.class, java.lang.String.class}
)
- public void testParseInputStreamHandlerBaseString() {
+ public void testParseInputStreamHandlerBaseString() throws Exception {
for(int i = 0; i < list_wf.length; i++) {
- try {
- HashMap<String, String> hm = sp.readFile(
- list_out_hb[i].getPath());
- MyHandler dh = new MyHandler();
- InputStream is = new FileInputStream(list_wf[i]);
- parser.parse(is, dh, SAXParserTestSupport.XML_SYSTEM_ID);
- assertTrue(SAXParserTestSupport.equalsMaps(hm,
- dh.createData()));
- } catch (IOException ioe) {
- fail("Unexpected IOException " + ioe.toString());
- } catch (SAXException sax) {
- fail("Unexpected SAXException " + sax.toString());
- }
+ HashMap<String, String> hm = sp.readFile(list_out_hb[i].getPath());
+ MyHandler dh = new MyHandler();
+ InputStream is = new FileInputStream(list_wf[i]);
+ parser.parse(is, dh, SAXParserTestSupport.XML_SYSTEM_ID);
+ assertTrue(SAXParserTestSupport.equalsMaps(hm, dh.createData()));
}
- for(int i = 0; i < list_nwf.length; i++) {
+ for (File file : list_nwf) {
try {
MyHandler dh = new MyHandler();
- InputStream is = new FileInputStream(list_nwf[i]);
+ InputStream is = new FileInputStream(file);
parser.parse(is, dh, SAXParserTestSupport.XML_SYSTEM_ID);
fail("SAXException is not thrown");
- } catch(org.xml.sax.SAXException se) {
- //expected
- } catch (FileNotFoundException fne) {
- fail("Unexpected FileNotFoundException " + fne.toString());
- } catch (IOException ioe) {
- fail("Unexpected IOException " + ioe.toString());
+ } catch (SAXException expected) {
}
}
try {
MyHandler dh = new MyHandler();
- parser.parse((InputStream) null, dh,
- SAXParserTestSupport.XML_SYSTEM_ID);
+ parser.parse(null, dh, SAXParserTestSupport.XML_SYSTEM_ID);
fail("java.lang.IllegalArgumentException is not thrown");
- } catch(java.lang.IllegalArgumentException iae) {
- //expected
- } catch (IOException ioe) {
- fail("Unexpected IOException " + ioe.toString());
- } catch(SAXException sax) {
- fail("Unexpected SAXException " + sax.toString());
+ } catch(IllegalArgumentException expected) {
}
- try {
- InputStream is = new FileInputStream(list_wf[0]);
- parser.parse(is, (HandlerBase) null,
- SAXParserTestSupport.XML_SYSTEM_ID);
- } catch(java.lang.IllegalArgumentException iae) {
- fail("java.lang.IllegalArgumentException is thrown");
- } catch (FileNotFoundException fne) {
- fail("Unexpected FileNotFoundException " + fne.toString());
- } catch(IOException ioe) {
- fail("Unexpected IOException " + ioe.toString());
- } catch(SAXException sax) {
- fail("Unexpected SAXException " + sax.toString());
- }
+ InputStream is = new FileInputStream(list_wf[0]);
+ parser.parse(is, (HandlerBase) null, SAXParserTestSupport.XML_SYSTEM_ID);
// Inject IOException
try {
- InputStream is = new BrokenInputStream(
- new FileInputStream(list_wf[0]), 10);
- parser.parse(is, (HandlerBase) null,
- SAXParserTestSupport.XML_SYSTEM_ID);
+ is = new BrokenInputStream(new FileInputStream(list_wf[0]), 10);
+ parser.parse(is, (HandlerBase) null, SAXParserTestSupport.XML_SYSTEM_ID);
fail("IOException expected");
- } catch(IOException e) {
- // Expected
- } catch (Exception e) {
- throw new RuntimeException("Unexpected exception", e);
+ } catch(IOException expected) {
+ } finally {
+ is.close();
}
}
diff --git a/luni/src/test/java/tests/api/org/xml/sax/support/BrokenInputStream.java b/luni/src/test/java/tests/api/org/xml/sax/support/BrokenInputStream.java
index 578fb60..8136b86 100644
--- a/luni/src/test/java/tests/api/org/xml/sax/support/BrokenInputStream.java
+++ b/luni/src/test/java/tests/api/org/xml/sax/support/BrokenInputStream.java
@@ -47,4 +47,8 @@
return stream.read();
}
+ @Override
+ public void close() throws IOException {
+ stream.close();
+ }
}
\ No newline at end of file
diff --git a/luni/src/test/java/tests/xml/DomTest.java b/luni/src/test/java/tests/xml/DomTest.java
index eb3a842..0966c5d 100644
--- a/luni/src/test/java/tests/xml/DomTest.java
+++ b/luni/src/test/java/tests/xml/DomTest.java
@@ -1385,6 +1385,38 @@
assertEquals(root.getChildNodes().item(0), current);
}
+ public void testPublicIdAndSystemId() throws Exception {
+ document = builder.parse(new InputSource(new StringReader(
+ " <!DOCTYPE html PUBLIC \"-//W3C//DTD HTML 4.01//EN\""
+ + " \"http://www.w3.org/TR/html4/strict.dtd\">"
+ + "<html></html>")));
+ doctype = document.getDoctype();
+ assertEquals("html", doctype.getName());
+ assertEquals("-//W3C//DTD HTML 4.01//EN", doctype.getPublicId());
+ assertEquals("http://www.w3.org/TR/html4/strict.dtd", doctype.getSystemId());
+ }
+
+ public void testSystemIdOnly() throws Exception {
+ document = builder.parse(new InputSource(new StringReader(
+ " <!DOCTYPE html SYSTEM \"http://www.w3.org/TR/html4/strict.dtd\">"
+ + "<html></html>")));
+ doctype = document.getDoctype();
+ assertEquals("html", doctype.getName());
+ assertNull(doctype.getPublicId());
+ assertEquals("http://www.w3.org/TR/html4/strict.dtd", doctype.getSystemId());
+ }
+
+ public void testSingleQuotedPublicIdAndSystemId() throws Exception {
+ document = builder.parse(new InputSource(new StringReader(
+ " <!DOCTYPE html PUBLIC '-//W3C//DTD HTML 4.01//EN'"
+ + " 'http://www.w3.org/TR/html4/strict.dtd'>"
+ + "<html></html>")));
+ doctype = document.getDoctype();
+ assertEquals("html", doctype.getName());
+ assertEquals("-//W3C//DTD HTML 4.01//EN", doctype.getPublicId());
+ assertEquals("http://www.w3.org/TR/html4/strict.dtd", doctype.getSystemId());
+ }
+
private class RecordingHandler implements UserDataHandler {
final Set<String> calls = new HashSet<String>();
public void handle(short operation, String key, Object data, Node src, Node dst) {
diff --git a/support/src/test/java/tests/support/resource/Support_Resources.java b/support/src/test/java/tests/support/resource/Support_Resources.java
index 9643347..3927883 100644
--- a/support/src/test/java/tests/support/resource/Support_Resources.java
+++ b/support/src/test/java/tests/support/resource/Support_Resources.java
@@ -17,6 +17,7 @@
package tests.support.resource;
+import libcore.base.Streams;
import tests.support.Support_Configuration;
import java.io.File;
@@ -24,9 +25,7 @@
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
-import java.io.OutputStream;
import java.net.MalformedURLException;
-import java.net.URISyntaxException;
import java.net.URL;
public class Support_Resources {
@@ -116,23 +115,17 @@
return File.createTempFile("hyts_", suffix, null);
}
- public static void copyLocalFileto(File dest, InputStream in)
- throws FileNotFoundException, IOException {
+ public static void copyLocalFileto(File dest, InputStream in) throws IOException {
if (!dest.exists()) {
FileOutputStream out = new FileOutputStream(dest);
- int result;
- byte[] buf = new byte[4096];
- while ((result = in.read(buf)) != -1) {
- out.write(buf, 0, result);
- }
- in.close();
+ Streams.copy(in, out);
out.close();
dest.deleteOnExit();
}
+ in.close();
}
- public static File getExternalLocalFile(String url) throws IOException,
- MalformedURLException {
+ public static File getExternalLocalFile(String url) throws IOException {
File resources = createTempFolder();
InputStream in = new URL(url).openStream();
File temp = new File(resources.toString() + "/local.tmp");
@@ -151,7 +144,6 @@
* @return - resource input stream
*/
public static InputStream getResourceStream(String name) {
-
InputStream is = Support_Resources.class.getResourceAsStream(name);
if (is == null) {
@@ -165,51 +157,6 @@
return is;
}
- /**
- * Util method to write resource files directly to an OutputStream.
- *
- * @param name - name of resource file.
- * @param out - OutputStream to write to.
- * @return - number of bytes written to out.
- */
- public static int writeResourceToStream(String name, OutputStream out) {
- InputStream input = getResourceStream(name);
- byte[] buffer = new byte[512];
- int total = 0;
- int count;
- try {
- count = input.read(buffer);
- while (count != -1) {
- out.write(buffer, 0, count);
- total = total + count;
- count = input.read(buffer);
- }
- return total;
- } catch (IOException e) {
- throw new RuntimeException("Failed to write to passed stream.", e);
- }
- }
-
- /**
- * Util method to get absolute path to resource file
- *
- * @param name - name of resource file
- * @return - path to resource
- */
- public static String getAbsoluteResourcePath(String name) {
-
- URL url = ClassLoader.getSystemClassLoader().getResource(name);
- if (url == null) {
- throw new RuntimeException("Failed to load resource: " + name);
- }
-
- try {
- return new File(url.toURI()).getAbsolutePath();
- } catch (URISyntaxException e) {
- throw new RuntimeException("Failed to load resource: " + name);
- }
- }
-
public static File resourceToTempFile(String path) throws IOException {
File f = File.createTempFile("out", ".xml");
f.deleteOnExit();
diff --git a/xml/src/main/java/org/kxml2/io/KXmlParser.java b/xml/src/main/java/org/kxml2/io/KXmlParser.java
index 5b84d93..ba905a9 100644
--- a/xml/src/main/java/org/kxml2/io/KXmlParser.java
+++ b/xml/src/main/java/org/kxml2/io/KXmlParser.java
@@ -22,6 +22,7 @@
package org.kxml2.io;
+import java.io.Closeable;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
@@ -35,7 +36,7 @@
/**
* An XML pull parser with limited support for parsing internal DTDs.
*/
-public class KXmlParser implements XmlPullParser {
+public class KXmlParser implements XmlPullParser, Closeable {
private final String PROPERTY_XMLDECL_VERSION
= "http://xmlpull.org/v1/doc/properties.html#xmldecl-version";
@@ -89,6 +90,9 @@
private String version;
private Boolean standalone;
+ private String rootElementName;
+ private String systemId;
+ private String publicId;
/**
* True if the {@code <!DOCTYPE>} contents are handled. The DTD defines
@@ -345,6 +349,7 @@
name = null;
namespace = null;
attributeCount = -1;
+ boolean throwOnResolveFailure = !justOneToken;
while (true) {
switch (type) {
@@ -354,7 +359,7 @@
* the end of the document.
*/
case START_TAG:
- parseStartTag(false);
+ parseStartTag(false, throwOnResolveFailure);
return type;
case END_TAG:
readEndTag();
@@ -369,13 +374,13 @@
case ENTITY_REF:
if (justOneToken) {
StringBuilder entityTextBuilder = new StringBuilder();
- readEntity(entityTextBuilder, true, ValueContext.TEXT);
+ readEntity(entityTextBuilder, true, throwOnResolveFailure, ValueContext.TEXT);
text = entityTextBuilder.toString();
break;
}
// fall-through
case TEXT:
- text = readValue('<', !justOneToken, ValueContext.TEXT);
+ text = readValue('<', !justOneToken, throwOnResolveFailure, ValueContext.TEXT);
if (depth == 0 && isWhitespace) {
type = IGNORABLE_WHITESPACE;
}
@@ -504,7 +509,7 @@
}
read(START_PROCESSING_INSTRUCTION);
- parseStartTag(true);
+ parseStartTag(true, true);
if (attributeCount < 1 || !"version".equals(attributes[2])) {
checkRelaxed("version expected");
@@ -561,8 +566,8 @@
private void readDoctype() throws IOException, XmlPullParserException {
read(START_DOCTYPE);
skip();
- readName();
- readExternalId(true);
+ rootElementName = readName();
+ readExternalId(true, true);
skip();
if (peekCharacter() == '[') {
readInternalSubset();
@@ -582,7 +587,7 @@
*
* Returns true if any ID was read.
*/
- private boolean readExternalId(boolean requireSystemName)
+ private boolean readExternalId(boolean requireSystemName, boolean assignFields)
throws IOException, XmlPullParserException {
skip();
int c = peekCharacter();
@@ -592,7 +597,11 @@
} else if (c == 'P') {
read(PUBLIC);
skip();
- readQuotedId();
+ if (assignFields) {
+ publicId = readQuotedId(true);
+ } else {
+ readQuotedId(false);
+ }
} else {
return false;
}
@@ -606,23 +615,32 @@
}
}
- readQuotedId();
+ if (assignFields) {
+ systemId = readQuotedId(true);
+ } else {
+ readQuotedId(false);
+ }
return true;
}
+ private static final char[] SINGLE_QUOTE = new char[] { '\'' };
+ private static final char[] DOUBLE_QUOTE = new char[] { '"' };
+
/**
* Reads a quoted string, performing no entity escaping of the contents.
*/
- private void readQuotedId() throws IOException, XmlPullParserException {
+ private String readQuotedId(boolean returnText) throws IOException, XmlPullParserException {
int quote = peekCharacter();
- if (quote != '"' && quote != '\'') {
+ char[] delimiter;
+ if (quote == '"') {
+ delimiter = DOUBLE_QUOTE;
+ } else if (quote == '\'') {
+ delimiter = SINGLE_QUOTE;
+ } else {
throw new XmlPullParserException("Expected a quoted string", this, null);
}
position++;
- while (peekCharacter() != quote) {
- position++;
- }
- position++;
+ return readUntil(delimiter, returnText);
}
private void readInternalSubset() throws IOException, XmlPullParserException {
@@ -814,7 +832,7 @@
if (c == '"' || c == '\'') {
position++;
// TODO: does this do escaping correctly?
- String value = readValue((char) c, true, ValueContext.ATTRIBUTE);
+ String value = readValue((char) c, true, true, ValueContext.ATTRIBUTE);
position++;
defineAttributeDefault(elementName, attributeName, value);
}
@@ -863,7 +881,7 @@
int quote = peekCharacter();
if (quote == '"' || quote == '\'') {
position++;
- String value = readValue((char) quote, true, ValueContext.ENTITY_DECLARATION);
+ String value = readValue((char) quote, true, false, ValueContext.ENTITY_DECLARATION);
position++;
if (generalEntity && processDocDecl) {
if (documentEntities == null) {
@@ -871,7 +889,7 @@
}
documentEntities.put(name, value.toCharArray());
}
- } else if (readExternalId(true)) {
+ } else if (readExternalId(true, false)) {
skip();
if (peekCharacter() == NDATA[0]) {
read(NDATA);
@@ -890,7 +908,7 @@
read(START_NOTATION);
skip();
readName();
- if (!readExternalId(false)) {
+ if (!readExternalId(false, false)) {
throw new XmlPullParserException(
"Expected external ID or public ID for notation", this, null);
}
@@ -988,7 +1006,8 @@
/**
* Sets name and attributes
*/
- private void parseStartTag(boolean xmldecl) throws IOException, XmlPullParserException {
+ private void parseStartTag(boolean xmldecl, boolean throwOnResolveFailure)
+ throws IOException, XmlPullParserException {
if (!xmldecl) {
read('<');
}
@@ -1056,7 +1075,8 @@
throw new XmlPullParserException("attr value delimiter missing!", this, null);
}
- attributes[i + 3] = readValue(delimiter, true, ValueContext.ATTRIBUTE);
+ attributes[i + 3] = readValue(delimiter, true, throwOnResolveFailure,
+ ValueContext.ATTRIBUTE);
if (delimiter != ' ') {
position++; // end quote
@@ -1116,8 +1136,8 @@
* resolved entity to {@code out}. If the entity cannot be read or resolved,
* {@code out} will contain the partial entity reference.
*/
- private void readEntity(StringBuilder out, boolean isEntityToken, ValueContext valueContext)
- throws IOException, XmlPullParserException {
+ private void readEntity(StringBuilder out, boolean isEntityToken, boolean throwOnResolveFailure,
+ ValueContext valueContext) throws IOException, XmlPullParserException {
int start = out.length();
if (buffer[position++] != '&') {
@@ -1202,7 +1222,7 @@
// keep the unresolved entity "&code;" in the text for relaxed clients
unresolved = true;
- if (!isEntityToken) {
+ if (throwOnResolveFailure) {
checkRelaxed("unresolved: &" + code + ";");
}
}
@@ -1227,7 +1247,7 @@
* @param delimiter {@code <} for text, {@code "} and {@code '} for quoted
* attributes, or a space for unquoted attributes.
*/
- private String readValue(char delimiter, boolean resolveEntities,
+ private String readValue(char delimiter, boolean resolveEntities, boolean throwOnResolveFailure,
ValueContext valueContext) throws IOException, XmlPullParserException {
/*
@@ -1318,7 +1338,7 @@
} else if (c == '&') {
isWhitespace = false; // TODO: what if the entity resolves to whitespace?
- readEntity(result, false, valueContext);
+ readEntity(result, false, throwOnResolveFailure, valueContext);
start = position;
continue;
@@ -1649,6 +1669,12 @@
}
}
+ public void close() throws IOException {
+ if (reader != null) {
+ reader.close();
+ }
+ }
+
public boolean getFeature(String feature) {
if (XmlPullParser.FEATURE_PROCESS_NAMESPACES.equals(feature)) {
return processNsp;
@@ -1693,6 +1719,30 @@
}
}
+ /**
+ * Returns the root element's name if it was declared in the DTD. This
+ * equals the first tag's name for valid documents.
+ */
+ public String getRootElementName() {
+ return rootElementName;
+ }
+
+ /**
+ * Returns the document's system ID if it was declared. This is typically a
+ * string like {@code http://www.w3.org/TR/html4/strict.dtd}.
+ */
+ public String getSystemId() {
+ return systemId;
+ }
+
+ /**
+ * Returns the document's public ID if it was declared. This is typically a
+ * string like {@code -//W3C//DTD HTML 4.01//EN}.
+ */
+ public String getPublicId() {
+ return publicId;
+ }
+
public int getNamespaceCount(int depth) {
if (depth > this.depth) {
throw new IndexOutOfBoundsException();
@@ -1709,7 +1759,6 @@
}
public String getNamespace(String prefix) {
-
if ("xml".equals(prefix)) {
return "http://www.w3.org/XML/1998/namespace";
}