1 /*
2  * Copyright (C) 2007 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 package libcore.xml;
18 
19 import junit.framework.TestCase;
20 
21 import org.xml.sax.Attributes;
22 import org.xml.sax.ContentHandler;
23 import org.xml.sax.InputSource;
24 import org.xml.sax.Locator;
25 import org.xml.sax.SAXException;
26 import org.xml.sax.helpers.DefaultHandler;
27 
28 import java.io.ByteArrayInputStream;
29 import java.io.IOException;
30 import java.io.InputStreamReader;
31 import java.util.HashMap;
32 import java.util.Map;
33 
34 import javax.xml.parsers.SAXParser;
35 import javax.xml.parsers.SAXParserFactory;
36 
37 public class SimpleParserTest extends TestCase {
38 
39     private SAXParser parser;
40 
41     private StringBuffer instructions;
42 
43     private Map<String, String> namespaces1;
44     private Map<String, String> namespaces2;
45 
46     private StringBuffer elements1;
47     private StringBuffer elements2;
48 
49     private Map<String, String> attributes1;
50     private Map<String, String> attributes2;
51 
52     private StringBuffer text;
53 
54     @Override
setUp()55     protected void setUp() throws Exception {
56         SAXParserFactory factory = SAXParserFactory.newInstance();
57         factory.setValidating(false);
58         factory.setNamespaceAware(true);
59 
60         parser = factory.newSAXParser();
61         parser.getXMLReader().setContentHandler(contentHandler);
62 
63         instructions = new StringBuffer();
64         namespaces1 = new HashMap<String, String>();
65         namespaces2 = new HashMap<String, String>();
66         elements1 = new StringBuffer();
67         elements2 = new StringBuffer();
68         attributes1 = new HashMap<String, String>();
69         attributes2 = new HashMap<String, String>();
70         text = new StringBuffer();
71     }
72 
73     @Override
tearDown()74     protected void tearDown() throws Exception {
75         instructions = null;
76         parser = null;
77         namespaces1 = null;
78         namespaces2 = null;
79         attributes1 = null;
80         attributes2 = null;
81         elements1 = null;
82         elements2 = null;
83         text = null;
84     }
85 
86     private final ContentHandler contentHandler = new ContentHandler() {
87         public void characters(char[] ch, int start, int length) {
88             String s = new String(ch, start, length).trim();
89             if (!s.isEmpty()) {
90                 if (text.length() != 0) {
91                     text.append(",");
92                 }
93                 text.append(s);
94             }
95         }
96 
97         public void processingInstruction(String target, String data) {
98             String s = target + ":" + data;
99             if (instructions.length() != 0) {
100                 instructions.append(",");
101             }
102             instructions.append(s);
103         }
104 
105 
106         public void startElement(String uri, String localName, String qName, Attributes atts) {
107 
108             if (elements1.length() != 0) {
109                 elements1.append(",");
110             }
111 
112             elements1.append(localName);
113 
114             if (!"".equals(uri)) {
115                 namespaces1.put(localName, uri);
116             }
117 
118             for (int i = 0; i < atts.getLength(); i++) {
119                 attributes1.put(atts.getLocalName(i), atts.getValue(i));
120             }
121 
122             if (elements2.length() != 0) {
123                 elements2.append(",");
124             }
125 
126             elements2.append(qName);
127 
128             if (!"".equals(uri)) {
129                 namespaces2.put(qName, uri);
130             }
131 
132             for (int i = 0; i < atts.getLength(); i++) {
133                 attributes2.put(atts.getQName(i), atts.getValue(i));
134             }
135         }
136 
137         public void endDocument() {}
138         public void endElement(String uri, String localName, String qName) {}
139         public void endPrefixMapping(String prefix) {}
140         public void ignorableWhitespace(char[] ch, int start, int length) {}
141         public void setDocumentLocator(Locator locator) {}
142         public void skippedEntity(String name) {}
143         public void startDocument() {}
144         public void startPrefixMapping(String prefix, String uri) {}
145     };
146 
testWorkingFile1()147     public void testWorkingFile1() throws Exception {
148         SAXParserFactory factory = SAXParserFactory.newInstance();
149         factory.setValidating(false);
150         factory.setNamespaceAware(true);
151 
152         SAXParser parser = factory.newSAXParser();
153         parser.getXMLReader().setContentHandler(contentHandler);
154 
155         parser.parse(getClass().getResourceAsStream("/SimpleParserTest.xml"),
156                 (DefaultHandler) null);
157 
158         assertEquals("The:quick,brown:fox", instructions.toString());
159 
160         assertEquals("stuff,nestedStuff,nestedStuff,nestedStuff", elements1
161                 .toString());
162 
163         assertEquals("Some text here,some more here...", text.toString());
164 
165         assertEquals("eins", attributes1.get("one"));
166         assertEquals("zwei", attributes1.get("two"));
167         assertEquals("drei", attributes1.get("three"));
168 
169         assertEquals("http://www.foobar.org", namespaces1.get("stuff"));
170     }
testWorkingFile2()171     public void testWorkingFile2() throws Exception {
172         SAXParserFactory factory = SAXParserFactory.newInstance();
173 
174         factory.setValidating(false);
175         factory.setNamespaceAware(false);
176         factory.setFeature("http://xml.org/sax/features/namespace-prefixes",
177                 true);
178 
179         SAXParser parser = factory.newSAXParser();
180         parser.getXMLReader().setContentHandler(contentHandler);
181         parser.parse(getClass().getResourceAsStream("/SimpleParserTest.xml"),
182                 (DefaultHandler) null);
183 
184         assertFalse(parser.isNamespaceAware());
185 
186         assertEquals("The:quick,brown:fox", instructions.toString());
187 
188         assertEquals("t:stuff,nestedStuff,nestedStuff,nestedStuff", elements2
189                 .toString());
190 
191         assertEquals("Some text here,some more here...", text.toString());
192 
193         assertEquals("eins", attributes2.get("one"));
194         assertEquals("zwei", attributes2.get("two"));
195         assertEquals("drei", attributes2.get("three"));
196 
197         assertEquals(0, namespaces2.size());
198     }
testEntityResolver()199     public void testEntityResolver() throws Exception {
200         final StringBuilder text = new StringBuilder();
201         DefaultHandler handler = new DefaultHandler() {
202             public void characters(char[] ch, int start, int length) {
203                 String s = new String(ch, start, length).trim();
204                 if (s.length() != 0) {
205                     if (text.length() != 0) {
206                         text.append(",");
207                     }
208                     text.append(s);
209                 }
210             }
211 
212             public InputSource resolveEntity(String publicId, String systemId)
213                     throws IOException, SAXException {
214                 return new InputSource(new InputStreamReader(
215                         new ByteArrayInputStream("test".getBytes())));
216             }
217         };
218 
219         SAXParserFactory spf = SAXParserFactory.newInstance();
220         spf.setValidating(false);
221         parser = spf.newSAXParser();
222         parser.parse(this.getClass().getResourceAsStream("/staffEntRes.xml"),
223                 handler);
224         assertTrue(
225                 "resolved external entity must be in parser character stream",
226                 text.toString().contains("test"));
227     }
testGetValue()228     public void testGetValue() throws Exception{
229         parser.parse(getClass().getResourceAsStream("/staffNS.xml"),
230                 new DefaultHandler() {
231             boolean firstAddressElem = true;
232             @Override
233             public void startElement (String uri, String localName,
234                     String qName, Attributes attributes) {
235                 if(firstAddressElem && localName.equals("address")) {
236                     firstAddressElem = false;
237                     assertNotNull(attributes.getValue("http://www.usa.com",
238                             "domestic"));
239                 }
240             }
241         });
242     }
243 }
244