1adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project/*
2adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Copyright (C) 2007 The Android Open Source Project
3adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project *
4adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Licensed under the Apache License, Version 2.0 (the "License");
5adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * you may not use this file except in compliance with the License.
6adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * You may obtain a copy of the License at
7adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project *
8adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project *      http://www.apache.org/licenses/LICENSE-2.0
9adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project *
10adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Unless required by applicable law or agreed to in writing, software
11adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * distributed under the License is distributed on an "AS IS" BASIS,
12adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * See the License for the specific language governing permissions and
14adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * limitations under the License.
15adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */
16adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
17c4145311fb4a343f59851aea9f36dcabc84ff737Jesse Wilsonpackage libcore.xml;
18adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
1909336c914b4fc813e493acc82469b9ad89fd8694Jesse Wilsonimport com.google.mockwebserver.MockResponse;
2009336c914b4fc813e493acc82469b9ad89fd8694Jesse Wilsonimport com.google.mockwebserver.MockWebServer;
2128b429ad56d2c595141e66a69c66e83f6739f143Jesse Wilsonimport java.io.ByteArrayInputStream;
2228b429ad56d2c595141e66a69c66e83f6739f143Jesse Wilsonimport java.io.IOException;
2328b429ad56d2c595141e66a69c66e83f6739f143Jesse Wilsonimport java.io.InputStream;
2428b429ad56d2c595141e66a69c66e83f6739f143Jesse Wilsonimport java.io.Reader;
2528b429ad56d2c595141e66a69c66e83f6739f143Jesse Wilsonimport java.io.StringReader;
2628b429ad56d2c595141e66a69c66e83f6739f143Jesse Wilsonimport java.util.ArrayList;
2728b429ad56d2c595141e66a69c66e83f6739f143Jesse Wilsonimport java.util.Arrays;
2828b429ad56d2c595141e66a69c66e83f6739f143Jesse Wilsonimport java.util.HashMap;
2928b429ad56d2c595141e66a69c66e83f6739f143Jesse Wilsonimport java.util.List;
3028b429ad56d2c595141e66a69c66e83f6739f143Jesse Wilsonimport java.util.Map;
31adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Projectimport junit.framework.Assert;
32adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Projectimport junit.framework.TestCase;
33c4145311fb4a343f59851aea9f36dcabc84ff737Jesse Wilsonimport org.apache.harmony.xml.ExpatReader;
34adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Projectimport org.xml.sax.Attributes;
35adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Projectimport org.xml.sax.ContentHandler;
36adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Projectimport org.xml.sax.InputSource;
37adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Projectimport org.xml.sax.Locator;
38adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Projectimport org.xml.sax.SAXException;
39adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Projectimport org.xml.sax.XMLReader;
40adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Projectimport org.xml.sax.ext.DefaultHandler2;
41adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Projectimport org.xml.sax.helpers.DefaultHandler;
42adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
43b076473aecb31da29217acbc5f9832345aeb4784Jesse Wilsonpublic class ExpatSaxParserTest extends TestCase {
44adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
45adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    private static final String SNIPPET = "<dagny dad=\"bob\">hello</dagny>";
46adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
472c5126c5440e149eea6cabf3f356094edcc4395cElliott Hughes    public void testGlobalReferenceTableOverflow() throws Exception {
482c5126c5440e149eea6cabf3f356094edcc4395cElliott Hughes        // We used to use a JNI global reference per interned string.
492c5126c5440e149eea6cabf3f356094edcc4395cElliott Hughes        // Framework apps have a limit of 2000 JNI global references per VM.
502c5126c5440e149eea6cabf3f356094edcc4395cElliott Hughes        StringBuilder xml = new StringBuilder();
512c5126c5440e149eea6cabf3f356094edcc4395cElliott Hughes        xml.append("<root>");
522c5126c5440e149eea6cabf3f356094edcc4395cElliott Hughes        for (int i = 0; i < 4000; ++i) {
532c5126c5440e149eea6cabf3f356094edcc4395cElliott Hughes            xml.append("<tag" + i + ">");
542c5126c5440e149eea6cabf3f356094edcc4395cElliott Hughes            xml.append("</tag" + i + ">");
552c5126c5440e149eea6cabf3f356094edcc4395cElliott Hughes        }
562c5126c5440e149eea6cabf3f356094edcc4395cElliott Hughes        xml.append("</root>");
572c5126c5440e149eea6cabf3f356094edcc4395cElliott Hughes        parse(xml.toString(), new DefaultHandler());
582c5126c5440e149eea6cabf3f356094edcc4395cElliott Hughes    }
592c5126c5440e149eea6cabf3f356094edcc4395cElliott Hughes
60adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public void testExceptions() {
61adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        // From startElement().
62adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        ContentHandler contentHandler = new DefaultHandler() {
63adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            @Override
64adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            public void startElement(String uri, String localName,
65adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                    String qName, Attributes attributes)
66adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                    throws SAXException {
67adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                throw new SAXException();
68adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            }
69adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        };
70adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        try {
71adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            parse(SNIPPET, contentHandler);
72adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            fail();
73adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        } catch (SAXException checked) { /* expected */ }
74adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
75adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        // From endElement().
76adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        contentHandler = new DefaultHandler() {
77adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            @Override
78adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            public void endElement(String uri, String localName,
79adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                    String qName)
80adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                    throws SAXException {
81adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                throw new SAXException();
82adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            }
83adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        };
84adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        try {
85adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            parse(SNIPPET, contentHandler);
86adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            fail();
87adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        } catch (SAXException checked) { /* expected */ }
88adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
89adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        // From characters().
90adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        contentHandler = new DefaultHandler() {
91adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            @Override
92adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            public void characters(char ch[], int start, int length)
93adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                    throws SAXException {
94adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                throw new SAXException();
95adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            }
96adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        };
97adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        try {
98adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            parse(SNIPPET, contentHandler);
99adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            fail();
100adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        } catch (SAXException checked) { /* expected */ }
101adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
102adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
103adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public void testSax() {
104adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        try {
105adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            // Parse String.
106adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            TestHandler handler = new TestHandler();
107adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            parse(SNIPPET, handler);
108adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            validate(handler);
109adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
110adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            // Parse Reader.
111adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            handler = new TestHandler();
112adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            parse(new StringReader(SNIPPET), handler);
113adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            validate(handler);
114adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
115adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            // Parse InputStream.
116adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            handler = new TestHandler();
117adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            parse(new ByteArrayInputStream(SNIPPET.getBytes()),
118adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                    Encoding.UTF_8, handler);
119adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            validate(handler);
120adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        } catch (SAXException e) {
121adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            throw new RuntimeException(e);
122adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        } catch (IOException e) {
123adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            throw new RuntimeException(e);
124adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
125adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
126adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
127adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    static void validate(TestHandler handler) {
128adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        assertEquals("dagny", handler.startElementName);
129adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        assertEquals("dagny", handler.endElementName);
130adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        assertEquals("hello", handler.text.toString());
131adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
132adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
133adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    static class TestHandler extends DefaultHandler {
134adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
135adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        String startElementName;
136adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        String endElementName;
137adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        StringBuilder text = new StringBuilder();
138adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
139adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        @Override
140adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        public void startElement(String uri, String localName, String qName,
141adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                Attributes attributes) throws SAXException {
142adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
143adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            assertNull(this.startElementName);
144adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            this.startElementName = localName;
145adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
146adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            // Validate attributes.
147adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            assertEquals(1, attributes.getLength());
148adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            assertEquals("", attributes.getURI(0));
149adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            assertEquals("dad", attributes.getLocalName(0));
150adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            assertEquals("bob", attributes.getValue(0));
151adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            assertEquals(0, attributes.getIndex("", "dad"));
152adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            assertEquals("bob", attributes.getValue("", "dad"));
153adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
154adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
155adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        @Override
156adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        public void endElement(String uri, String localName, String qName)
157adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                throws SAXException {
158adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            assertNull(this.endElementName);
159adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            this.endElementName = localName;
160adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
161adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
162adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        @Override
163adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        public void characters(char ch[], int start, int length)
164adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                throws SAXException {
165adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            this.text.append(ch, start, length);
166adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
167adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
168adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
169adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    static final String XML =
170adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        "<one xmlns='ns:default' xmlns:n1='ns:1' a='b'>\n"
171adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project              + "  <n1:two c='d' n1:e='f' xmlns:n2='ns:2'>text</n1:two>\n"
172adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project              + "</one>";
173adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
174adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public void testNamespaces() {
175adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        try {
176adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            NamespaceHandler handler = new NamespaceHandler();
177adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            parse(XML, handler);
178adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            handler.validate();
179adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        } catch (SAXException e) {
180adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            throw new RuntimeException(e);
181adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
182adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
183adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
184adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    static class NamespaceHandler implements ContentHandler {
185adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
186adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        Locator locator;
187adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        boolean documentStarted;
188adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        boolean documentEnded;
189adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        Map<String, String> prefixMappings = new HashMap<String, String>();
190adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
191adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        boolean oneStarted;
192adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        boolean twoStarted;
193adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        boolean oneEnded;
194adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        boolean twoEnded;
195adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
196adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        public void validate() {
197adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            assertTrue(documentEnded);
198adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
199adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
200adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        public void setDocumentLocator(Locator locator) {
201adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            this.locator = locator;
202adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
203adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
204adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        public void startDocument() throws SAXException {
205adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            documentStarted = true;
206adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            assertNotNull(locator);
207adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            assertEquals(0, prefixMappings.size());
208adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            assertFalse(documentEnded);
209adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
210adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
211adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        public void endDocument() throws SAXException {
212adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            assertTrue(documentStarted);
213adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            assertTrue(oneEnded);
214adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            assertTrue(twoEnded);
215adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            assertEquals(0, prefixMappings.size());
216adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            documentEnded = true;
217adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
218adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
219adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        public void startPrefixMapping(String prefix, String uri)
220adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                throws SAXException {
221adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            prefixMappings.put(prefix, uri);
222adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
223adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
224adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        public void endPrefixMapping(String prefix) throws SAXException {
225adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            assertNotNull(prefixMappings.remove(prefix));
226adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
227adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
228adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        public void startElement(String uri, String localName, String qName,
229adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                Attributes atts) throws SAXException {
230adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
231adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            if (localName == "one") {
232adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                assertEquals(2, prefixMappings.size());
233adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
234adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                assertEquals(1, locator.getLineNumber());
235adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
236adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                assertFalse(oneStarted);
237adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                assertFalse(twoStarted);
238adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                assertFalse(oneEnded);
239adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                assertFalse(twoEnded);
240adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
241adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                oneStarted = true;
242adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
243adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                assertSame("ns:default", uri);
244df36e8c24af4f150726d13296ee982f2ba5cf9beJesse Wilson                assertEquals("one", qName);
245adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
246adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                // Check atts.
247adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                assertEquals(1, atts.getLength());
248adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
249adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                assertSame("", atts.getURI(0));
250adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                assertSame("a", atts.getLocalName(0));
251adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                assertEquals("b", atts.getValue(0));
252adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                assertEquals(0, atts.getIndex("", "a"));
253adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                assertEquals("b", atts.getValue("", "a"));
254adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
255adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                return;
256adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            }
257adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
258adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            if (localName == "two") {
259adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                assertEquals(3, prefixMappings.size());
260adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
261adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                assertTrue(oneStarted);
262adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                assertFalse(twoStarted);
263adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                assertFalse(oneEnded);
264adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                assertFalse(twoEnded);
265adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
266adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                twoStarted = true;
267adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
268adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                assertSame("ns:1", uri);
269df36e8c24af4f150726d13296ee982f2ba5cf9beJesse Wilson                Assert.assertEquals("n1:two", qName);
270adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
271adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                // Check atts.
272adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                assertEquals(2, atts.getLength());
273adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
274adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                assertSame("", atts.getURI(0));
275adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                assertSame("c", atts.getLocalName(0));
276adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                assertEquals("d", atts.getValue(0));
277adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                assertEquals(0, atts.getIndex("", "c"));
278adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                assertEquals("d", atts.getValue("", "c"));
279adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
280adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                assertSame("ns:1", atts.getURI(1));
281adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                assertSame("e", atts.getLocalName(1));
282adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                assertEquals("f", atts.getValue(1));
283adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                assertEquals(1, atts.getIndex("ns:1", "e"));
284adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                assertEquals("f", atts.getValue("ns:1", "e"));
285adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
286adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                // We shouldn't find these.
287adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                assertEquals(-1, atts.getIndex("ns:default", "e"));
288adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                assertEquals(null, atts.getValue("ns:default", "e"));
289adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
290adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                return;
291adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            }
292adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
293adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            fail();
294adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project         }
295adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
296adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        public void endElement(String uri, String localName, String qName)
297adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                throws SAXException {
298adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            if (localName == "one") {
299adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                assertEquals(3, locator.getLineNumber());
300adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
301adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                assertTrue(oneStarted);
302adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                assertTrue(twoStarted);
303adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                assertTrue(twoEnded);
304adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                assertFalse(oneEnded);
305adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
306adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                oneEnded = true;
307adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
308adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                assertSame("ns:default", uri);
309df36e8c24af4f150726d13296ee982f2ba5cf9beJesse Wilson                assertEquals("one", qName);
310adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
311adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                return;
312adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            }
313adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
314adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            if (localName == "two") {
315adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                assertTrue(oneStarted);
316adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                assertTrue(twoStarted);
317adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                assertFalse(twoEnded);
318adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                assertFalse(oneEnded);
319adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
320adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                twoEnded = true;
321adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
322adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                assertSame("ns:1", uri);
323df36e8c24af4f150726d13296ee982f2ba5cf9beJesse Wilson                assertEquals("n1:two", qName);
324adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
325adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                return;
326adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            }
327adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
328adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            fail();
329adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
330adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
331adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        public void characters(char ch[], int start, int length)
332adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                throws SAXException {
333adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            String s = new String(ch, start, length).trim();
334adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
335adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            if (!s.equals("")) {
336adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                assertTrue(oneStarted);
337adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                assertTrue(twoStarted);
338adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                assertFalse(oneEnded);
339adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                assertFalse(twoEnded);
340adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                assertEquals("text", s);
341adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            }
342adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
343adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
344adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        public void ignorableWhitespace(char ch[], int start, int length)
345adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                throws SAXException {
346adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            fail();
347adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
348adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
349adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        public void processingInstruction(String target, String data)
350adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                throws SAXException {
351adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            fail();
352adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
353adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
354adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        public void skippedEntity(String name) throws SAXException {
355adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            fail();
356adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
357adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
358adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
359c9b92b4c79529c5308b2621ac1abe9a5ab039f8dElliott Hughes    private TestDtdHandler runDtdTest(String s) throws Exception {
360c9b92b4c79529c5308b2621ac1abe9a5ab039f8dElliott Hughes        Reader in = new StringReader(s);
361adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        ExpatReader reader = new ExpatReader();
362adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        TestDtdHandler handler = new TestDtdHandler();
363adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        reader.setContentHandler(handler);
364c9b92b4c79529c5308b2621ac1abe9a5ab039f8dElliott Hughes        reader.setDTDHandler(handler);
365adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        reader.setLexicalHandler(handler);
366adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        reader.parse(new InputSource(in));
367c9b92b4c79529c5308b2621ac1abe9a5ab039f8dElliott Hughes        return handler;
368c9b92b4c79529c5308b2621ac1abe9a5ab039f8dElliott Hughes    }
369adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
370c9b92b4c79529c5308b2621ac1abe9a5ab039f8dElliott Hughes    public void testDtdDoctype() throws Exception {
371c9b92b4c79529c5308b2621ac1abe9a5ab039f8dElliott Hughes        TestDtdHandler handler = runDtdTest("<?xml version=\"1.0\"?><!DOCTYPE foo PUBLIC 'bar' 'tee'><a></a>");
372adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        assertEquals("foo", handler.name);
373adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        assertEquals("bar", handler.publicId);
374adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        assertEquals("tee", handler.systemId);
375adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        assertTrue(handler.ended);
376adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
377adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
378c9b92b4c79529c5308b2621ac1abe9a5ab039f8dElliott Hughes    public void testDtdUnparsedEntity_system() throws Exception {
379c9b92b4c79529c5308b2621ac1abe9a5ab039f8dElliott Hughes        TestDtdHandler handler = runDtdTest("<?xml version=\"1.0\"?><!DOCTYPE foo PUBLIC 'bar' 'tee' [ <!ENTITY ent SYSTEM 'blah' NDATA poop> ]><a></a>");
380c9b92b4c79529c5308b2621ac1abe9a5ab039f8dElliott Hughes        assertEquals("ent", handler.ueName);
381c9b92b4c79529c5308b2621ac1abe9a5ab039f8dElliott Hughes        assertEquals(null, handler.uePublicId);
382c9b92b4c79529c5308b2621ac1abe9a5ab039f8dElliott Hughes        assertEquals("blah", handler.ueSystemId);
383c9b92b4c79529c5308b2621ac1abe9a5ab039f8dElliott Hughes        assertEquals("poop", handler.ueNotationName);
384c9b92b4c79529c5308b2621ac1abe9a5ab039f8dElliott Hughes    }
385c9b92b4c79529c5308b2621ac1abe9a5ab039f8dElliott Hughes
386c9b92b4c79529c5308b2621ac1abe9a5ab039f8dElliott Hughes    public void testDtdUnparsedEntity_public() throws Exception {
387c9b92b4c79529c5308b2621ac1abe9a5ab039f8dElliott Hughes        TestDtdHandler handler = runDtdTest("<?xml version=\"1.0\"?><!DOCTYPE foo PUBLIC 'bar' 'tee' [ <!ENTITY ent PUBLIC 'a' 'b' NDATA poop> ]><a></a>");
388c9b92b4c79529c5308b2621ac1abe9a5ab039f8dElliott Hughes        assertEquals("ent", handler.ueName);
389c9b92b4c79529c5308b2621ac1abe9a5ab039f8dElliott Hughes        assertEquals("a", handler.uePublicId);
390c9b92b4c79529c5308b2621ac1abe9a5ab039f8dElliott Hughes        assertEquals("b", handler.ueSystemId);
391c9b92b4c79529c5308b2621ac1abe9a5ab039f8dElliott Hughes        assertEquals("poop", handler.ueNotationName);
392c9b92b4c79529c5308b2621ac1abe9a5ab039f8dElliott Hughes    }
393c9b92b4c79529c5308b2621ac1abe9a5ab039f8dElliott Hughes
394c9b92b4c79529c5308b2621ac1abe9a5ab039f8dElliott Hughes    public void testDtdNotation_system() throws Exception {
395c9b92b4c79529c5308b2621ac1abe9a5ab039f8dElliott Hughes        TestDtdHandler handler = runDtdTest("<?xml version=\"1.0\"?><!DOCTYPE foo PUBLIC 'bar' 'tee' [ <!NOTATION sn SYSTEM 'nf2'> ]><a></a>");
396c9b92b4c79529c5308b2621ac1abe9a5ab039f8dElliott Hughes        assertEquals("sn", handler.ndName);
397c9b92b4c79529c5308b2621ac1abe9a5ab039f8dElliott Hughes        assertEquals(null, handler.ndPublicId);
398c9b92b4c79529c5308b2621ac1abe9a5ab039f8dElliott Hughes        assertEquals("nf2", handler.ndSystemId);
399c9b92b4c79529c5308b2621ac1abe9a5ab039f8dElliott Hughes    }
400c9b92b4c79529c5308b2621ac1abe9a5ab039f8dElliott Hughes
401c9b92b4c79529c5308b2621ac1abe9a5ab039f8dElliott Hughes    public void testDtdNotation_public() throws Exception {
402c9b92b4c79529c5308b2621ac1abe9a5ab039f8dElliott Hughes        TestDtdHandler handler = runDtdTest("<?xml version=\"1.0\"?><!DOCTYPE foo PUBLIC 'bar' 'tee' [ <!NOTATION pn PUBLIC 'nf1'> ]><a></a>");
403c9b92b4c79529c5308b2621ac1abe9a5ab039f8dElliott Hughes        assertEquals("pn", handler.ndName);
404c9b92b4c79529c5308b2621ac1abe9a5ab039f8dElliott Hughes        assertEquals("nf1", handler.ndPublicId);
405c9b92b4c79529c5308b2621ac1abe9a5ab039f8dElliott Hughes        assertEquals(null, handler.ndSystemId);
406c9b92b4c79529c5308b2621ac1abe9a5ab039f8dElliott Hughes    }
407c9b92b4c79529c5308b2621ac1abe9a5ab039f8dElliott Hughes
408adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    static class TestDtdHandler extends DefaultHandler2 {
409adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
410adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        String name;
411adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        String publicId;
412adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        String systemId;
413c9b92b4c79529c5308b2621ac1abe9a5ab039f8dElliott Hughes        String ndName;
414c9b92b4c79529c5308b2621ac1abe9a5ab039f8dElliott Hughes        String ndPublicId;
415c9b92b4c79529c5308b2621ac1abe9a5ab039f8dElliott Hughes        String ndSystemId;
416c9b92b4c79529c5308b2621ac1abe9a5ab039f8dElliott Hughes        String ueName;
417c9b92b4c79529c5308b2621ac1abe9a5ab039f8dElliott Hughes        String uePublicId;
418c9b92b4c79529c5308b2621ac1abe9a5ab039f8dElliott Hughes        String ueSystemId;
419c9b92b4c79529c5308b2621ac1abe9a5ab039f8dElliott Hughes        String ueNotationName;
420adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
421adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        boolean ended;
422adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
423adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        Locator locator;
424adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
425adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        @Override
426adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        public void startDTD(String name, String publicId, String systemId) {
427adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            this.name = name;
428adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            this.publicId = publicId;
429adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            this.systemId = systemId;
430adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
431adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
432adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        @Override
433adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        public void endDTD() {
434adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            ended = true;
435adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
436adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
437adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        @Override
438adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        public void setDocumentLocator(Locator locator) {
439adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            this.locator = locator;
440adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
441c9b92b4c79529c5308b2621ac1abe9a5ab039f8dElliott Hughes
442c9b92b4c79529c5308b2621ac1abe9a5ab039f8dElliott Hughes        @Override
443c9b92b4c79529c5308b2621ac1abe9a5ab039f8dElliott Hughes        public void notationDecl(String name, String publicId, String systemId) {
444c9b92b4c79529c5308b2621ac1abe9a5ab039f8dElliott Hughes            this.ndName = name;
445c9b92b4c79529c5308b2621ac1abe9a5ab039f8dElliott Hughes            this.ndPublicId = publicId;
446c9b92b4c79529c5308b2621ac1abe9a5ab039f8dElliott Hughes            this.ndSystemId = systemId;
447c9b92b4c79529c5308b2621ac1abe9a5ab039f8dElliott Hughes        }
448c9b92b4c79529c5308b2621ac1abe9a5ab039f8dElliott Hughes
449c9b92b4c79529c5308b2621ac1abe9a5ab039f8dElliott Hughes        @Override
450c9b92b4c79529c5308b2621ac1abe9a5ab039f8dElliott Hughes        public void unparsedEntityDecl(String entityName, String publicId, String systemId, String notationName) {
451c9b92b4c79529c5308b2621ac1abe9a5ab039f8dElliott Hughes            this.ueName = entityName;
452c9b92b4c79529c5308b2621ac1abe9a5ab039f8dElliott Hughes            this.uePublicId = publicId;
453c9b92b4c79529c5308b2621ac1abe9a5ab039f8dElliott Hughes            this.ueSystemId = systemId;
454c9b92b4c79529c5308b2621ac1abe9a5ab039f8dElliott Hughes            this.ueNotationName = notationName;
455c9b92b4c79529c5308b2621ac1abe9a5ab039f8dElliott Hughes        }
456adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
457adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
458adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public void testCdata() throws Exception {
459adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        Reader in = new StringReader(
460adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            "<a><![CDATA[<b></b>]]> <![CDATA[<c></c>]]></a>");
461adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
462adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        ExpatReader reader = new ExpatReader();
463adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        TestCdataHandler handler = new TestCdataHandler();
464adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        reader.setContentHandler(handler);
465adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        reader.setLexicalHandler(handler);
466adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
467adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        reader.parse(new InputSource(in));
468adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
469adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        assertEquals(2, handler.startCdata);
470adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        assertEquals(2, handler.endCdata);
471adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        assertEquals("<b></b> <c></c>", handler.buffer.toString());
472adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
473adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
474adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    static class TestCdataHandler extends DefaultHandler2 {
475adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
476adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        int startCdata, endCdata;
477adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        StringBuffer buffer = new StringBuffer();
478adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
479adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        @Override
480adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        public void characters(char ch[], int start, int length) {
481adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            buffer.append(ch, start, length);
482adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
483adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
484adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        @Override
485adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        public void startCDATA() throws SAXException {
486adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            startCdata++;
487adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
488adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
489adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        @Override
490adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        public void endCDATA() throws SAXException {
491adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            endCdata++;
492adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
493adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
494adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
495adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public void testProcessingInstructions() throws IOException, SAXException {
496adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        Reader in = new StringReader(
497adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            "<?bob lee?><a></a>");
498adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
499adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        ExpatReader reader = new ExpatReader();
500adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        TestProcessingInstrutionHandler handler
501adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                = new TestProcessingInstrutionHandler();
502adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        reader.setContentHandler(handler);
503adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
504adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        reader.parse(new InputSource(in));
505adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
506adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        assertEquals("bob", handler.target);
507adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        assertEquals("lee", handler.data);
508adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
509adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
510adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    static class TestProcessingInstrutionHandler extends DefaultHandler2 {
511adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
512adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        String target;
513adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        String data;
514adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
515adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        @Override
516adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        public void processingInstruction(String target, String data) {
517adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            this.target = target;
518adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            this.data = data;
519adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
520adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
521adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
522adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public void testExternalEntity() throws IOException, SAXException {
523adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        class Handler extends DefaultHandler {
524adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
525adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            List<String> elementNames = new ArrayList<String>();
526adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            StringBuilder text = new StringBuilder();
527adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
528adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            public InputSource resolveEntity(String publicId, String systemId)
529adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                    throws IOException, SAXException {
530adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                if (publicId.equals("publicA") && systemId.equals("systemA")) {
531adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                    return new InputSource(new StringReader("<a/>"));
532adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                } else if (publicId.equals("publicB")
533adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                        && systemId.equals("systemB")) {
534adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                    /*
535adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                     * Explicitly set the encoding here or else the parser will
536adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                     * try to use the parent parser's encoding which is utf-16.
537adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                     */
538adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                    InputSource inputSource = new InputSource(
539adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                            new ByteArrayInputStream("bob".getBytes("utf-8")));
540adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                    inputSource.setEncoding("utf-8");
541adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                    return inputSource;
542adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                }
543adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
544adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                throw new AssertionError();
545adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            }
546adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
547adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            @Override
548adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            public void startElement(String uri, String localName, String qName,
549adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                    Attributes attributes) throws SAXException {
550adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                elementNames.add(localName);
551adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            }
552adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
553adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            @Override
554adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            public void endElement(String uri, String localName, String qName)
555adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                    throws SAXException {
556adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                elementNames.add("/" + localName);
557adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            }
558adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
559adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            @Override
560adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            public void characters(char ch[], int start, int length)
561adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                    throws SAXException {
562adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                text.append(ch, start, length);
563adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            }
564adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
565adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
566adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        Reader in = new StringReader("<?xml version=\"1.0\"?>\n"
567adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            + "<!DOCTYPE foo [\n"
568adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            + "  <!ENTITY a PUBLIC 'publicA' 'systemA'>\n"
569adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            + "  <!ENTITY b PUBLIC 'publicB' 'systemB'>\n"
570adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            + "]>\n"
571adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            + "<foo>\n"
572adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            + "  &a;<b>&b;</b></foo>");
573adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
574adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        ExpatReader reader = new ExpatReader();
575adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        Handler handler = new Handler();
576adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        reader.setContentHandler(handler);
577adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        reader.setEntityResolver(handler);
578adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
579adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        reader.parse(new InputSource(in));
580adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
581adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        assertEquals(Arrays.asList("foo", "a", "/a", "b", "/b", "/foo"),
582adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                handler.elementNames);
583adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        assertEquals("bob", handler.text.toString().trim());
584adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
585adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
586adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public void testExternalEntityDownload() throws IOException, SAXException {
58728b429ad56d2c595141e66a69c66e83f6739f143Jesse Wilson        final MockWebServer server = new MockWebServer();
58828b429ad56d2c595141e66a69c66e83f6739f143Jesse Wilson        server.enqueue(new MockResponse().setBody("<bar></bar>"));
58928b429ad56d2c595141e66a69c66e83f6739f143Jesse Wilson        server.play();
590adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
591adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        class Handler extends DefaultHandler {
59228b429ad56d2c595141e66a69c66e83f6739f143Jesse Wilson            final List<String> elementNames = new ArrayList<String>();
593adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
59428b429ad56d2c595141e66a69c66e83f6739f143Jesse Wilson            @Override public InputSource resolveEntity(String publicId, String systemId)
59528b429ad56d2c595141e66a69c66e83f6739f143Jesse Wilson                    throws IOException {
596adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                // The parser should have resolved the systemId.
59728b429ad56d2c595141e66a69c66e83f6739f143Jesse Wilson                assertEquals(server.getUrl("/systemBar").toString(), systemId);
598adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                return new InputSource(systemId);
599adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            }
600adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
60128b429ad56d2c595141e66a69c66e83f6739f143Jesse Wilson            @Override public void startElement(String uri, String localName, String qName,
60228b429ad56d2c595141e66a69c66e83f6739f143Jesse Wilson                    Attributes attributes) {
603adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                elementNames.add(localName);
604adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            }
605adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
60628b429ad56d2c595141e66a69c66e83f6739f143Jesse Wilson            @Override public void endElement(String uri, String localName, String qName) {
607adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                elementNames.add("/" + localName);
608adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            }
609adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
610adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
611adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        // 'systemBar', the external entity, is relative to 'systemFoo':
612adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        Reader in = new StringReader("<?xml version=\"1.0\"?>\n"
613adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            + "<!DOCTYPE foo [\n"
614adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            + "  <!ENTITY bar SYSTEM 'systemBar'>\n"
615adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            + "]>\n"
616adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            + "<foo>&bar;</foo>");
617adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        ExpatReader reader = new ExpatReader();
618adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        Handler handler = new Handler();
619adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        reader.setContentHandler(handler);
620adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        reader.setEntityResolver(handler);
621adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        InputSource source = new InputSource(in);
62228b429ad56d2c595141e66a69c66e83f6739f143Jesse Wilson        source.setSystemId(server.getUrl("/systemFoo").toString());
623adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        reader.parse(source);
62428b429ad56d2c595141e66a69c66e83f6739f143Jesse Wilson        assertEquals(Arrays.asList("foo", "bar", "/bar", "/foo"), handler.elementNames);
625adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
626adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
627adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
628adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * Parses the given xml string and fires events on the given SAX handler.
629adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
630adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    private static void parse(String xml, ContentHandler contentHandler)
631adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            throws SAXException {
632adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        try {
633adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            XMLReader reader = new ExpatReader();
634adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            reader.setContentHandler(contentHandler);
635adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            reader.parse(new InputSource(new StringReader(xml)));
6362c5126c5440e149eea6cabf3f356094edcc4395cElliott Hughes        } catch (IOException e) {
637adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            throw new AssertionError(e);
638adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
639adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
640adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
641adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
642adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * Parses xml from the given reader and fires events on the given SAX
643adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * handler.
644adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
645adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    private static void parse(Reader in, ContentHandler contentHandler)
646adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            throws IOException, SAXException {
647adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        XMLReader reader = new ExpatReader();
648adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        reader.setContentHandler(contentHandler);
649adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        reader.parse(new InputSource(in));
650adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
651adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
652adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
653adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * Parses xml from the given input stream and fires events on the given SAX
654adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * handler.
655adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
656adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    private static void parse(InputStream in, Encoding encoding,
657adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            ContentHandler contentHandler) throws IOException, SAXException {
658adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        try {
659adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            XMLReader reader = new ExpatReader();
660adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            reader.setContentHandler(contentHandler);
661adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            InputSource source = new InputSource(in);
662adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            source.setEncoding(encoding.expatName);
663adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            reader.parse(source);
664adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        } catch (IOException e) {
665adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            throw new AssertionError(e);
666adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
667adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
668adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
669adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
670adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * Supported character encodings.
671adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
672adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    private enum Encoding {
673adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
674adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        US_ASCII("US-ASCII"),
675adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        UTF_8("UTF-8"),
676adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        UTF_16("UTF-16"),
677adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        ISO_8859_1("ISO-8859-1");
678adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
679adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        final String expatName;
680adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
681adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        Encoding(String expatName) {
682adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            this.expatName = expatName;
683adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
684adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
685adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project}
686