14a5c3fdcab5bffc6b8258c8029b02d97b0dd3f9dJesse Wilson/* 24a5c3fdcab5bffc6b8258c8029b02d97b0dd3f9dJesse Wilson * Copyright (C) 2010 The Android Open Source Project 34a5c3fdcab5bffc6b8258c8029b02d97b0dd3f9dJesse Wilson * 44a5c3fdcab5bffc6b8258c8029b02d97b0dd3f9dJesse Wilson * Licensed under the Apache License, Version 2.0 (the "License"); 54a5c3fdcab5bffc6b8258c8029b02d97b0dd3f9dJesse Wilson * you may not use this file except in compliance with the License. 64a5c3fdcab5bffc6b8258c8029b02d97b0dd3f9dJesse Wilson * You may obtain a copy of the License at 74a5c3fdcab5bffc6b8258c8029b02d97b0dd3f9dJesse Wilson * 84a5c3fdcab5bffc6b8258c8029b02d97b0dd3f9dJesse Wilson * http://www.apache.org/licenses/LICENSE-2.0 94a5c3fdcab5bffc6b8258c8029b02d97b0dd3f9dJesse Wilson * 104a5c3fdcab5bffc6b8258c8029b02d97b0dd3f9dJesse Wilson * Unless required by applicable law or agreed to in writing, software 114a5c3fdcab5bffc6b8258c8029b02d97b0dd3f9dJesse Wilson * distributed under the License is distributed on an "AS IS" BASIS, 124a5c3fdcab5bffc6b8258c8029b02d97b0dd3f9dJesse Wilson * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 134a5c3fdcab5bffc6b8258c8029b02d97b0dd3f9dJesse Wilson * See the License for the specific language governing permissions and 144a5c3fdcab5bffc6b8258c8029b02d97b0dd3f9dJesse Wilson * limitations under the License. 154a5c3fdcab5bffc6b8258c8029b02d97b0dd3f9dJesse Wilson */ 164a5c3fdcab5bffc6b8258c8029b02d97b0dd3f9dJesse Wilson 171c92541d38ed4d0b6e958f478cd7b129f140cd44Jesse Wilsonpackage libcore.xml; 184a5c3fdcab5bffc6b8258c8029b02d97b0dd3f9dJesse Wilson 196789e65622548dd7d2842ec77c19004afc9d4426Jesse Wilsonimport java.io.StringReader; 206789e65622548dd7d2842ec77c19004afc9d4426Jesse Wilsonimport java.util.Arrays; 216789e65622548dd7d2842ec77c19004afc9d4426Jesse Wilsonimport java.util.List; 226789e65622548dd7d2842ec77c19004afc9d4426Jesse Wilsonimport javax.xml.parsers.SAXParser; 236789e65622548dd7d2842ec77c19004afc9d4426Jesse Wilsonimport javax.xml.parsers.SAXParserFactory; 246789e65622548dd7d2842ec77c19004afc9d4426Jesse Wilsonimport junit.framework.AssertionFailedError; 254a5c3fdcab5bffc6b8258c8029b02d97b0dd3f9dJesse Wilsonimport junit.framework.TestCase; 264a5c3fdcab5bffc6b8258c8029b02d97b0dd3f9dJesse Wilsonimport org.xml.sax.Attributes; 274a5c3fdcab5bffc6b8258c8029b02d97b0dd3f9dJesse Wilsonimport org.xml.sax.ContentHandler; 284a5c3fdcab5bffc6b8258c8029b02d97b0dd3f9dJesse Wilsonimport org.xml.sax.InputSource; 296789e65622548dd7d2842ec77c19004afc9d4426Jesse Wilsonimport org.xml.sax.SAXParseException; 304a5c3fdcab5bffc6b8258c8029b02d97b0dd3f9dJesse Wilsonimport org.xml.sax.XMLReader; 314a5c3fdcab5bffc6b8258c8029b02d97b0dd3f9dJesse Wilsonimport org.xml.sax.helpers.DefaultHandler; 324a5c3fdcab5bffc6b8258c8029b02d97b0dd3f9dJesse Wilson 334a5c3fdcab5bffc6b8258c8029b02d97b0dd3f9dJesse Wilson/** 344a5c3fdcab5bffc6b8258c8029b02d97b0dd3f9dJesse Wilson * Initiate and observe a SAX parse session. 354a5c3fdcab5bffc6b8258c8029b02d97b0dd3f9dJesse Wilson */ 366789e65622548dd7d2842ec77c19004afc9d4426Jesse Wilsonpublic final class SaxTest extends TestCase { 374a5c3fdcab5bffc6b8258c8029b02d97b0dd3f9dJesse Wilson 384a5c3fdcab5bffc6b8258c8029b02d97b0dd3f9dJesse Wilson public void testNoPrefixesNoNamespaces() throws Exception { 394a5c3fdcab5bffc6b8258c8029b02d97b0dd3f9dJesse Wilson parse(false, false, "<foo bar=\"baz\"/>", new DefaultHandler() { 404a5c3fdcab5bffc6b8258c8029b02d97b0dd3f9dJesse Wilson @Override public void startElement(String uri, String localName, 414a5c3fdcab5bffc6b8258c8029b02d97b0dd3f9dJesse Wilson String qName, Attributes attributes) { 424a5c3fdcab5bffc6b8258c8029b02d97b0dd3f9dJesse Wilson assertEquals("", uri); 434a5c3fdcab5bffc6b8258c8029b02d97b0dd3f9dJesse Wilson assertEquals("", localName); 444a5c3fdcab5bffc6b8258c8029b02d97b0dd3f9dJesse Wilson assertEquals("foo", qName); 454a5c3fdcab5bffc6b8258c8029b02d97b0dd3f9dJesse Wilson assertEquals(1, attributes.getLength()); 464a5c3fdcab5bffc6b8258c8029b02d97b0dd3f9dJesse Wilson assertEquals("", attributes.getURI(0)); 474a5c3fdcab5bffc6b8258c8029b02d97b0dd3f9dJesse Wilson assertOneOf("bar", "", attributes.getLocalName(0)); 484a5c3fdcab5bffc6b8258c8029b02d97b0dd3f9dJesse Wilson assertEquals("bar", attributes.getQName(0)); 494a5c3fdcab5bffc6b8258c8029b02d97b0dd3f9dJesse Wilson } 504a5c3fdcab5bffc6b8258c8029b02d97b0dd3f9dJesse Wilson }); 514a5c3fdcab5bffc6b8258c8029b02d97b0dd3f9dJesse Wilson 524a5c3fdcab5bffc6b8258c8029b02d97b0dd3f9dJesse Wilson parse(false, false, "<a:foo a:bar=\"baz\"/>", new DefaultHandler() { 534a5c3fdcab5bffc6b8258c8029b02d97b0dd3f9dJesse Wilson @Override public void startElement(String uri, String localName, 544a5c3fdcab5bffc6b8258c8029b02d97b0dd3f9dJesse Wilson String qName, Attributes attributes) { 554a5c3fdcab5bffc6b8258c8029b02d97b0dd3f9dJesse Wilson assertEquals("", uri); 564a5c3fdcab5bffc6b8258c8029b02d97b0dd3f9dJesse Wilson assertEquals("", localName); 574a5c3fdcab5bffc6b8258c8029b02d97b0dd3f9dJesse Wilson assertEquals("a:foo", qName); 584a5c3fdcab5bffc6b8258c8029b02d97b0dd3f9dJesse Wilson assertEquals(1, attributes.getLength()); 594a5c3fdcab5bffc6b8258c8029b02d97b0dd3f9dJesse Wilson assertEquals("", attributes.getURI(0)); 604a5c3fdcab5bffc6b8258c8029b02d97b0dd3f9dJesse Wilson assertOneOf("a:bar", "", attributes.getLocalName(0)); 614a5c3fdcab5bffc6b8258c8029b02d97b0dd3f9dJesse Wilson assertEquals("a:bar", attributes.getQName(0)); 624a5c3fdcab5bffc6b8258c8029b02d97b0dd3f9dJesse Wilson } 634a5c3fdcab5bffc6b8258c8029b02d97b0dd3f9dJesse Wilson }); 644a5c3fdcab5bffc6b8258c8029b02d97b0dd3f9dJesse Wilson } 654a5c3fdcab5bffc6b8258c8029b02d97b0dd3f9dJesse Wilson 664a5c3fdcab5bffc6b8258c8029b02d97b0dd3f9dJesse Wilson public void testNoPrefixesYesNamespaces() throws Exception { 674a5c3fdcab5bffc6b8258c8029b02d97b0dd3f9dJesse Wilson parse(false, true, "<foo bar=\"baz\"/>", new DefaultHandler() { 684a5c3fdcab5bffc6b8258c8029b02d97b0dd3f9dJesse Wilson @Override public void startElement(String uri, String localName, 694a5c3fdcab5bffc6b8258c8029b02d97b0dd3f9dJesse Wilson String qName, Attributes attributes) { 704a5c3fdcab5bffc6b8258c8029b02d97b0dd3f9dJesse Wilson assertEquals("", uri); 714a5c3fdcab5bffc6b8258c8029b02d97b0dd3f9dJesse Wilson assertEquals("foo", localName); 724a5c3fdcab5bffc6b8258c8029b02d97b0dd3f9dJesse Wilson assertEquals("foo", qName); 734a5c3fdcab5bffc6b8258c8029b02d97b0dd3f9dJesse Wilson assertEquals(1, attributes.getLength()); 744a5c3fdcab5bffc6b8258c8029b02d97b0dd3f9dJesse Wilson assertEquals("", attributes.getURI(0)); 754a5c3fdcab5bffc6b8258c8029b02d97b0dd3f9dJesse Wilson assertEquals("bar", attributes.getLocalName(0)); 764a5c3fdcab5bffc6b8258c8029b02d97b0dd3f9dJesse Wilson assertEquals("bar", attributes.getQName(0)); 774a5c3fdcab5bffc6b8258c8029b02d97b0dd3f9dJesse Wilson } 784a5c3fdcab5bffc6b8258c8029b02d97b0dd3f9dJesse Wilson }); 794a5c3fdcab5bffc6b8258c8029b02d97b0dd3f9dJesse Wilson 804a5c3fdcab5bffc6b8258c8029b02d97b0dd3f9dJesse Wilson parse(false, true, "<a:foo a:bar=\"baz\" xmlns:a=\"http://quux\"/>", new DefaultHandler() { 814a5c3fdcab5bffc6b8258c8029b02d97b0dd3f9dJesse Wilson @Override public void startElement(String uri, String localName, 824a5c3fdcab5bffc6b8258c8029b02d97b0dd3f9dJesse Wilson String qName, Attributes attributes) { 834a5c3fdcab5bffc6b8258c8029b02d97b0dd3f9dJesse Wilson assertEquals("http://quux", uri); 844a5c3fdcab5bffc6b8258c8029b02d97b0dd3f9dJesse Wilson assertEquals("foo", localName); 854a5c3fdcab5bffc6b8258c8029b02d97b0dd3f9dJesse Wilson assertEquals("a:foo", qName); 864a5c3fdcab5bffc6b8258c8029b02d97b0dd3f9dJesse Wilson assertEquals(1, attributes.getLength()); 874a5c3fdcab5bffc6b8258c8029b02d97b0dd3f9dJesse Wilson assertEquals("http://quux", attributes.getURI(0)); 884a5c3fdcab5bffc6b8258c8029b02d97b0dd3f9dJesse Wilson assertEquals("bar", attributes.getLocalName(0)); 894a5c3fdcab5bffc6b8258c8029b02d97b0dd3f9dJesse Wilson assertEquals("a:bar", attributes.getQName(0)); 904a5c3fdcab5bffc6b8258c8029b02d97b0dd3f9dJesse Wilson } 914a5c3fdcab5bffc6b8258c8029b02d97b0dd3f9dJesse Wilson }); 924a5c3fdcab5bffc6b8258c8029b02d97b0dd3f9dJesse Wilson } 934a5c3fdcab5bffc6b8258c8029b02d97b0dd3f9dJesse Wilson 944a5c3fdcab5bffc6b8258c8029b02d97b0dd3f9dJesse Wilson /** 954a5c3fdcab5bffc6b8258c8029b02d97b0dd3f9dJesse Wilson * Android's Expat-based SAX parser fails this test because Expat doesn't 964a5c3fdcab5bffc6b8258c8029b02d97b0dd3f9dJesse Wilson * supply us with our much desired {@code xmlns="http://..."} attributes. 974a5c3fdcab5bffc6b8258c8029b02d97b0dd3f9dJesse Wilson */ 984a5c3fdcab5bffc6b8258c8029b02d97b0dd3f9dJesse Wilson public void testYesPrefixesYesNamespaces() throws Exception { 994a5c3fdcab5bffc6b8258c8029b02d97b0dd3f9dJesse Wilson parse(true, true, "<foo bar=\"baz\"/>", new DefaultHandler() { 1004a5c3fdcab5bffc6b8258c8029b02d97b0dd3f9dJesse Wilson @Override public void startElement(String uri, String localName, 1014a5c3fdcab5bffc6b8258c8029b02d97b0dd3f9dJesse Wilson String qName, Attributes attributes) { 1024a5c3fdcab5bffc6b8258c8029b02d97b0dd3f9dJesse Wilson assertEquals("", uri); 1034a5c3fdcab5bffc6b8258c8029b02d97b0dd3f9dJesse Wilson assertEquals("foo", localName); 1044a5c3fdcab5bffc6b8258c8029b02d97b0dd3f9dJesse Wilson assertEquals("foo", qName); 1054a5c3fdcab5bffc6b8258c8029b02d97b0dd3f9dJesse Wilson assertEquals(1, attributes.getLength()); 1064a5c3fdcab5bffc6b8258c8029b02d97b0dd3f9dJesse Wilson assertEquals("", attributes.getURI(0)); 1074a5c3fdcab5bffc6b8258c8029b02d97b0dd3f9dJesse Wilson assertEquals("bar", attributes.getLocalName(0)); 1084a5c3fdcab5bffc6b8258c8029b02d97b0dd3f9dJesse Wilson assertEquals("bar", attributes.getQName(0)); 1094a5c3fdcab5bffc6b8258c8029b02d97b0dd3f9dJesse Wilson } 1104a5c3fdcab5bffc6b8258c8029b02d97b0dd3f9dJesse Wilson }); 1114a5c3fdcab5bffc6b8258c8029b02d97b0dd3f9dJesse Wilson 1124a5c3fdcab5bffc6b8258c8029b02d97b0dd3f9dJesse Wilson parse(true, true, "<a:foo a:bar=\"baz\" xmlns:a=\"http://quux\"/>", new DefaultHandler() { 1134a5c3fdcab5bffc6b8258c8029b02d97b0dd3f9dJesse Wilson @Override public void startElement(String uri, String localName, 1144a5c3fdcab5bffc6b8258c8029b02d97b0dd3f9dJesse Wilson String qName, Attributes attributes) { 1154a5c3fdcab5bffc6b8258c8029b02d97b0dd3f9dJesse Wilson assertEquals("http://quux", uri); 1164a5c3fdcab5bffc6b8258c8029b02d97b0dd3f9dJesse Wilson assertEquals("foo", localName); 1174a5c3fdcab5bffc6b8258c8029b02d97b0dd3f9dJesse Wilson assertEquals("a:foo", qName); 1184a5c3fdcab5bffc6b8258c8029b02d97b0dd3f9dJesse Wilson assertEquals(2, attributes.getLength()); 1194a5c3fdcab5bffc6b8258c8029b02d97b0dd3f9dJesse Wilson assertEquals("http://quux", attributes.getURI(0)); 1204a5c3fdcab5bffc6b8258c8029b02d97b0dd3f9dJesse Wilson assertEquals("bar", attributes.getLocalName(0)); 1214a5c3fdcab5bffc6b8258c8029b02d97b0dd3f9dJesse Wilson assertEquals("a:bar", attributes.getQName(0)); 1224a5c3fdcab5bffc6b8258c8029b02d97b0dd3f9dJesse Wilson assertEquals("", attributes.getURI(1)); 1234a5c3fdcab5bffc6b8258c8029b02d97b0dd3f9dJesse Wilson assertEquals("", attributes.getLocalName(1)); 1244a5c3fdcab5bffc6b8258c8029b02d97b0dd3f9dJesse Wilson assertEquals("xmlns:a", attributes.getQName(1)); 1254a5c3fdcab5bffc6b8258c8029b02d97b0dd3f9dJesse Wilson } 1264a5c3fdcab5bffc6b8258c8029b02d97b0dd3f9dJesse Wilson }); 1274a5c3fdcab5bffc6b8258c8029b02d97b0dd3f9dJesse Wilson } 1284a5c3fdcab5bffc6b8258c8029b02d97b0dd3f9dJesse Wilson 1294a5c3fdcab5bffc6b8258c8029b02d97b0dd3f9dJesse Wilson public void testYesPrefixesNoNamespaces() throws Exception { 1304a5c3fdcab5bffc6b8258c8029b02d97b0dd3f9dJesse Wilson parse(true, false, "<foo bar=\"baz\"/>", new DefaultHandler() { 1314a5c3fdcab5bffc6b8258c8029b02d97b0dd3f9dJesse Wilson @Override public void startElement(String uri, String localName, 1324a5c3fdcab5bffc6b8258c8029b02d97b0dd3f9dJesse Wilson String qName, Attributes attributes) { 1334a5c3fdcab5bffc6b8258c8029b02d97b0dd3f9dJesse Wilson assertEquals("", uri); 1344a5c3fdcab5bffc6b8258c8029b02d97b0dd3f9dJesse Wilson assertEquals("", localName); 1354a5c3fdcab5bffc6b8258c8029b02d97b0dd3f9dJesse Wilson assertEquals("foo", qName); 1364a5c3fdcab5bffc6b8258c8029b02d97b0dd3f9dJesse Wilson assertEquals(1, attributes.getLength()); 1374a5c3fdcab5bffc6b8258c8029b02d97b0dd3f9dJesse Wilson assertEquals("", attributes.getURI(0)); 1384a5c3fdcab5bffc6b8258c8029b02d97b0dd3f9dJesse Wilson assertOneOf("bar", "", attributes.getLocalName(0)); 1394a5c3fdcab5bffc6b8258c8029b02d97b0dd3f9dJesse Wilson assertEquals("bar", attributes.getQName(0)); 1404a5c3fdcab5bffc6b8258c8029b02d97b0dd3f9dJesse Wilson } 1414a5c3fdcab5bffc6b8258c8029b02d97b0dd3f9dJesse Wilson }); 1424a5c3fdcab5bffc6b8258c8029b02d97b0dd3f9dJesse Wilson 1434a5c3fdcab5bffc6b8258c8029b02d97b0dd3f9dJesse Wilson parse(true, false, "<a:foo a:bar=\"baz\"/>", new DefaultHandler() { 1444a5c3fdcab5bffc6b8258c8029b02d97b0dd3f9dJesse Wilson @Override public void startElement(String uri, String localName, 1454a5c3fdcab5bffc6b8258c8029b02d97b0dd3f9dJesse Wilson String qName, Attributes attributes) { 1464a5c3fdcab5bffc6b8258c8029b02d97b0dd3f9dJesse Wilson assertEquals("", uri); 1474a5c3fdcab5bffc6b8258c8029b02d97b0dd3f9dJesse Wilson assertEquals("", localName); 1484a5c3fdcab5bffc6b8258c8029b02d97b0dd3f9dJesse Wilson assertEquals("a:foo", qName); 1494a5c3fdcab5bffc6b8258c8029b02d97b0dd3f9dJesse Wilson assertEquals(1, attributes.getLength()); 1504a5c3fdcab5bffc6b8258c8029b02d97b0dd3f9dJesse Wilson assertEquals("", attributes.getURI(0)); 1514a5c3fdcab5bffc6b8258c8029b02d97b0dd3f9dJesse Wilson assertOneOf("a:bar", "", attributes.getLocalName(0)); 1524a5c3fdcab5bffc6b8258c8029b02d97b0dd3f9dJesse Wilson assertEquals("a:bar", attributes.getQName(0)); 1534a5c3fdcab5bffc6b8258c8029b02d97b0dd3f9dJesse Wilson } 1544a5c3fdcab5bffc6b8258c8029b02d97b0dd3f9dJesse Wilson }); 1554a5c3fdcab5bffc6b8258c8029b02d97b0dd3f9dJesse Wilson } 1564a5c3fdcab5bffc6b8258c8029b02d97b0dd3f9dJesse Wilson 1576789e65622548dd7d2842ec77c19004afc9d4426Jesse Wilson /** 1586789e65622548dd7d2842ec77c19004afc9d4426Jesse Wilson * Test that the external-general-entities feature can be disabled. 1596789e65622548dd7d2842ec77c19004afc9d4426Jesse Wilson * http://code.google.com/p/android/issues/detail?id=9493 1606789e65622548dd7d2842ec77c19004afc9d4426Jesse Wilson */ 1616789e65622548dd7d2842ec77c19004afc9d4426Jesse Wilson public void testDisableExternalGeneralEntities() throws Exception { 1626789e65622548dd7d2842ec77c19004afc9d4426Jesse Wilson String xml = "<!DOCTYPE foo [" 1636789e65622548dd7d2842ec77c19004afc9d4426Jesse Wilson + " <!ENTITY bar SYSTEM \"/no-such-document.xml\">" 1646789e65622548dd7d2842ec77c19004afc9d4426Jesse Wilson + "]>" 1656789e65622548dd7d2842ec77c19004afc9d4426Jesse Wilson + "<foo>&bar;</foo>"; 1666789e65622548dd7d2842ec77c19004afc9d4426Jesse Wilson testDisableExternalEntities("http://xml.org/sax/features/external-general-entities", xml); 1676789e65622548dd7d2842ec77c19004afc9d4426Jesse Wilson } 1686789e65622548dd7d2842ec77c19004afc9d4426Jesse Wilson 1696789e65622548dd7d2842ec77c19004afc9d4426Jesse Wilson /** 1706789e65622548dd7d2842ec77c19004afc9d4426Jesse Wilson * Test that the external-parameter-entities feature can be disabled. 1716789e65622548dd7d2842ec77c19004afc9d4426Jesse Wilson * http://code.google.com/p/android/issues/detail?id=9493 1726789e65622548dd7d2842ec77c19004afc9d4426Jesse Wilson */ 1736789e65622548dd7d2842ec77c19004afc9d4426Jesse Wilson public void testDisableExternalParameterEntities() throws Exception { 1746789e65622548dd7d2842ec77c19004afc9d4426Jesse Wilson String xml = "<!DOCTYPE foo [" 1756789e65622548dd7d2842ec77c19004afc9d4426Jesse Wilson + " <!ENTITY % bar SYSTEM \"/no-such-document.xml\">" 1766789e65622548dd7d2842ec77c19004afc9d4426Jesse Wilson + " %bar;" 1776789e65622548dd7d2842ec77c19004afc9d4426Jesse Wilson + "]>" 1786789e65622548dd7d2842ec77c19004afc9d4426Jesse Wilson + "<foo/>"; 1796789e65622548dd7d2842ec77c19004afc9d4426Jesse Wilson testDisableExternalEntities("http://xml.org/sax/features/external-parameter-entities", xml); 1806789e65622548dd7d2842ec77c19004afc9d4426Jesse Wilson } 1816789e65622548dd7d2842ec77c19004afc9d4426Jesse Wilson 1826789e65622548dd7d2842ec77c19004afc9d4426Jesse Wilson /** 1836789e65622548dd7d2842ec77c19004afc9d4426Jesse Wilson * Disables the named feature and then parses the supplied XML. The content 1846789e65622548dd7d2842ec77c19004afc9d4426Jesse Wilson * is expected to be equivalent to "<foo/>". 1856789e65622548dd7d2842ec77c19004afc9d4426Jesse Wilson */ 1866789e65622548dd7d2842ec77c19004afc9d4426Jesse Wilson private void testDisableExternalEntities(String feature, String xml) throws Exception { 1876789e65622548dd7d2842ec77c19004afc9d4426Jesse Wilson SAXParser parser = SAXParserFactory.newInstance().newSAXParser(); 1886789e65622548dd7d2842ec77c19004afc9d4426Jesse Wilson XMLReader reader = parser.getXMLReader(); 1896789e65622548dd7d2842ec77c19004afc9d4426Jesse Wilson reader.setFeature(feature, false); 1906789e65622548dd7d2842ec77c19004afc9d4426Jesse Wilson assertFalse(reader.getFeature(feature)); 1916789e65622548dd7d2842ec77c19004afc9d4426Jesse Wilson reader.setContentHandler(new ThrowingHandler() { 1926789e65622548dd7d2842ec77c19004afc9d4426Jesse Wilson @Override public void startElement( 1936789e65622548dd7d2842ec77c19004afc9d4426Jesse Wilson String uri, String localName, String qName, Attributes attributes) { 1946789e65622548dd7d2842ec77c19004afc9d4426Jesse Wilson assertEquals("foo", qName); 1956789e65622548dd7d2842ec77c19004afc9d4426Jesse Wilson } 1966789e65622548dd7d2842ec77c19004afc9d4426Jesse Wilson @Override public void endElement(String uri, String localName, String qName) { 1976789e65622548dd7d2842ec77c19004afc9d4426Jesse Wilson assertEquals("foo", qName); 1986789e65622548dd7d2842ec77c19004afc9d4426Jesse Wilson } 1996789e65622548dd7d2842ec77c19004afc9d4426Jesse Wilson }); 2006789e65622548dd7d2842ec77c19004afc9d4426Jesse Wilson reader.parse(new InputSource(new StringReader(xml))); 2016789e65622548dd7d2842ec77c19004afc9d4426Jesse Wilson } 2026789e65622548dd7d2842ec77c19004afc9d4426Jesse Wilson 2034a5c3fdcab5bffc6b8258c8029b02d97b0dd3f9dJesse Wilson private void parse(boolean prefixes, boolean namespaces, String xml, 2044a5c3fdcab5bffc6b8258c8029b02d97b0dd3f9dJesse Wilson ContentHandler handler) throws Exception { 2054a5c3fdcab5bffc6b8258c8029b02d97b0dd3f9dJesse Wilson SAXParser parser = SAXParserFactory.newInstance().newSAXParser(); 2064a5c3fdcab5bffc6b8258c8029b02d97b0dd3f9dJesse Wilson XMLReader reader = parser.getXMLReader(); 2074a5c3fdcab5bffc6b8258c8029b02d97b0dd3f9dJesse Wilson reader.setFeature("http://xml.org/sax/features/namespace-prefixes", prefixes); 2084a5c3fdcab5bffc6b8258c8029b02d97b0dd3f9dJesse Wilson reader.setFeature("http://xml.org/sax/features/namespaces", namespaces); 2094a5c3fdcab5bffc6b8258c8029b02d97b0dd3f9dJesse Wilson reader.setContentHandler(handler); 2104a5c3fdcab5bffc6b8258c8029b02d97b0dd3f9dJesse Wilson reader.parse(new InputSource(new StringReader(xml))); 2114a5c3fdcab5bffc6b8258c8029b02d97b0dd3f9dJesse Wilson } 2124a5c3fdcab5bffc6b8258c8029b02d97b0dd3f9dJesse Wilson 2134a5c3fdcab5bffc6b8258c8029b02d97b0dd3f9dJesse Wilson /** 2144a5c3fdcab5bffc6b8258c8029b02d97b0dd3f9dJesse Wilson * @param expected an optional value that may or may have not been supplied 2154a5c3fdcab5bffc6b8258c8029b02d97b0dd3f9dJesse Wilson * @param sentinel a marker value that means the expected value was omitted 2164a5c3fdcab5bffc6b8258c8029b02d97b0dd3f9dJesse Wilson */ 2174a5c3fdcab5bffc6b8258c8029b02d97b0dd3f9dJesse Wilson private void assertOneOf(String expected, String sentinel, String actual) { 2184a5c3fdcab5bffc6b8258c8029b02d97b0dd3f9dJesse Wilson List<String> optionsList = Arrays.asList(sentinel, expected); 2194a5c3fdcab5bffc6b8258c8029b02d97b0dd3f9dJesse Wilson assertTrue("Expected one of " + optionsList + " but was " + actual, 2204a5c3fdcab5bffc6b8258c8029b02d97b0dd3f9dJesse Wilson optionsList.contains(actual)); 2214a5c3fdcab5bffc6b8258c8029b02d97b0dd3f9dJesse Wilson } 2226789e65622548dd7d2842ec77c19004afc9d4426Jesse Wilson 2236789e65622548dd7d2842ec77c19004afc9d4426Jesse Wilson /** 2246789e65622548dd7d2842ec77c19004afc9d4426Jesse Wilson * This SAX handler throws on everything but startDocument, endDocument, 2256789e65622548dd7d2842ec77c19004afc9d4426Jesse Wilson * and setDocumentLocator(). Override the methods that are expected to be 2266789e65622548dd7d2842ec77c19004afc9d4426Jesse Wilson * called. 2276789e65622548dd7d2842ec77c19004afc9d4426Jesse Wilson */ 2286789e65622548dd7d2842ec77c19004afc9d4426Jesse Wilson static class ThrowingHandler extends DefaultHandler { 2296789e65622548dd7d2842ec77c19004afc9d4426Jesse Wilson @Override public InputSource resolveEntity(String publicId, String systemId) { 2306789e65622548dd7d2842ec77c19004afc9d4426Jesse Wilson throw new AssertionFailedError(); 2316789e65622548dd7d2842ec77c19004afc9d4426Jesse Wilson } 2326789e65622548dd7d2842ec77c19004afc9d4426Jesse Wilson @Override public void notationDecl(String name, String publicId, String systemId) { 2336789e65622548dd7d2842ec77c19004afc9d4426Jesse Wilson throw new AssertionFailedError(); 2346789e65622548dd7d2842ec77c19004afc9d4426Jesse Wilson } 2356789e65622548dd7d2842ec77c19004afc9d4426Jesse Wilson @Override public void unparsedEntityDecl( 2366789e65622548dd7d2842ec77c19004afc9d4426Jesse Wilson String name, String publicId, String systemId, String notationName) { 2376789e65622548dd7d2842ec77c19004afc9d4426Jesse Wilson throw new AssertionFailedError(); 2386789e65622548dd7d2842ec77c19004afc9d4426Jesse Wilson } 2396789e65622548dd7d2842ec77c19004afc9d4426Jesse Wilson @Override public void startPrefixMapping(String prefix, String uri) { 2406789e65622548dd7d2842ec77c19004afc9d4426Jesse Wilson throw new AssertionFailedError(); 2416789e65622548dd7d2842ec77c19004afc9d4426Jesse Wilson } 2426789e65622548dd7d2842ec77c19004afc9d4426Jesse Wilson @Override public void endPrefixMapping(String prefix) { 2436789e65622548dd7d2842ec77c19004afc9d4426Jesse Wilson throw new AssertionFailedError(); 2446789e65622548dd7d2842ec77c19004afc9d4426Jesse Wilson } 2456789e65622548dd7d2842ec77c19004afc9d4426Jesse Wilson @Override public void startElement( 2466789e65622548dd7d2842ec77c19004afc9d4426Jesse Wilson String uri, String localName, String qName, Attributes attributes) { 2476789e65622548dd7d2842ec77c19004afc9d4426Jesse Wilson throw new AssertionFailedError(); 2486789e65622548dd7d2842ec77c19004afc9d4426Jesse Wilson } 2496789e65622548dd7d2842ec77c19004afc9d4426Jesse Wilson @Override public void endElement(String uri, String localName, String qName) { 2506789e65622548dd7d2842ec77c19004afc9d4426Jesse Wilson throw new AssertionFailedError(); 2516789e65622548dd7d2842ec77c19004afc9d4426Jesse Wilson } 2526789e65622548dd7d2842ec77c19004afc9d4426Jesse Wilson @Override public void characters(char[] ch, int start, int length) { 2536789e65622548dd7d2842ec77c19004afc9d4426Jesse Wilson throw new AssertionFailedError(); 2546789e65622548dd7d2842ec77c19004afc9d4426Jesse Wilson } 2556789e65622548dd7d2842ec77c19004afc9d4426Jesse Wilson @Override public void ignorableWhitespace(char[] ch, int start, int length) { 2566789e65622548dd7d2842ec77c19004afc9d4426Jesse Wilson throw new AssertionFailedError(); 2576789e65622548dd7d2842ec77c19004afc9d4426Jesse Wilson } 2586789e65622548dd7d2842ec77c19004afc9d4426Jesse Wilson @Override public void processingInstruction(String target, String data) { 2596789e65622548dd7d2842ec77c19004afc9d4426Jesse Wilson throw new AssertionFailedError(); 2606789e65622548dd7d2842ec77c19004afc9d4426Jesse Wilson } 2616789e65622548dd7d2842ec77c19004afc9d4426Jesse Wilson @Override public void skippedEntity(String name) { 2626789e65622548dd7d2842ec77c19004afc9d4426Jesse Wilson throw new AssertionFailedError(); 2636789e65622548dd7d2842ec77c19004afc9d4426Jesse Wilson } 2646789e65622548dd7d2842ec77c19004afc9d4426Jesse Wilson @Override public void warning(SAXParseException e) { 2656789e65622548dd7d2842ec77c19004afc9d4426Jesse Wilson throw new AssertionFailedError(); 2666789e65622548dd7d2842ec77c19004afc9d4426Jesse Wilson } 2676789e65622548dd7d2842ec77c19004afc9d4426Jesse Wilson @Override public void error(SAXParseException e) { 2686789e65622548dd7d2842ec77c19004afc9d4426Jesse Wilson throw new AssertionFailedError(); 2696789e65622548dd7d2842ec77c19004afc9d4426Jesse Wilson } 2706789e65622548dd7d2842ec77c19004afc9d4426Jesse Wilson @Override public void fatalError(SAXParseException e) { 2716789e65622548dd7d2842ec77c19004afc9d4426Jesse Wilson throw new AssertionFailedError(); 2726789e65622548dd7d2842ec77c19004afc9d4426Jesse Wilson } 2736789e65622548dd7d2842ec77c19004afc9d4426Jesse Wilson } 2744a5c3fdcab5bffc6b8258c8029b02d97b0dd3f9dJesse Wilson} 275