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