1 /*
2  * Copyright (C) 2008 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 android.util.cts;
18 
19 import org.xml.sax.Attributes;
20 import org.xml.sax.ContentHandler;
21 import org.xml.sax.Locator;
22 import org.xml.sax.SAXException;
23 import org.xmlpull.v1.XmlPullParser;
24 import org.xmlpull.v1.XmlPullParserException;
25 import org.xmlpull.v1.XmlSerializer;
26 
27 import android.content.res.XmlResourceParser;
28 import android.test.AndroidTestCase;
29 import android.util.AttributeSet;
30 import android.util.Xml;
31 import android.util.Xml.Encoding;
32 
33 
34 import java.io.BufferedReader;
35 import java.io.ByteArrayInputStream;
36 import java.io.ByteArrayOutputStream;
37 import java.io.DataOutputStream;
38 import java.io.IOException;
39 import java.io.InputStream;
40 import java.io.InputStreamReader;
41 import java.io.Reader;
42 import java.io.UnsupportedEncodingException;
43 import java.util.Vector;
44 
45 /**
46  * TestCase for android.util.Xml.
47  */
48 public class XmlTest extends AndroidTestCase {
49 
50     private static final String STR_INVALIDATE_EN_CODING = "invalidateEnCoding";
51     private static final String STR_N2 = "-2";
52     private static final String STR_N1 = "-1";
53     private static final String STR_LAYOUT_HEIGHT = "layout_height";
54     private static final String STR_LAYOUT_WIDTH = "layout_width";
55     private static final String STR_ISO_8859_1 = "ISO-8859-1";
56     private static final String STR_US_ASCII = "US-ASCII";
57     private static final String STR_UTF_16 = "UTF-16";
58     private static final String STR_UTF_8 = "UTF-8";
59     private static final String STR_END_DOCUMENT = "endDocument";
60     private static final String STR_1_NUMBER = "1";
61     private static final String STR_0_NUMBER = "0";
62     private static final String STR_EMPTY = "";
63     private static final String STR_END_ELEMENT = "endElement";
64     private static final String STR_ABC = "abc";
65     private static final String ATT_NAME = "name";
66     private static final String TAG_SON = "Son";
67     private static final String TAG_TEST = "Test";
68     private static final String STR_START_ELEMENT = "startElement:";
69     private static final String STR_START_DOCUMENT = "startDocument";
70     private static final String STR_SET_DOCUMENT_LOCATOR = "setDocumentLocator:Locator[publicId: "
71                + "null, systemId: null, line: 1, column: 0]";
72 
73     // used for ContentHandler to pause XML.
74     private static final String STR_START_PREFIX_MAPPING_TAG = "startPrefixMapping:";
75     private static final String STR_SKIPPED_ENTITY_TAG = "skippedEntity:";
76     private static final String STR_SET_DOCUMENT_LOCATOR_TAG = "setDocumentLocator:";
77     private static final String STR_PROCESSING_INSTRUCTION_TAG = "processingInstruction:";
78     private static final String STR_IGNORABLE_WHITESPACE_TAG = "ignorableWhitespace:";
79     private static final String STR_END_PREFIX_MAPPING_TAG = "endPrefixMapping:";
80     private static final String STR_LENGTH_TAG = "length:";
81     private static final String STR_START_TAG = "start:";
82     private static final String STR_CHARACTERS_TAG = "characters:";
83 
84     final String sourceStr = "<" + TAG_TEST + "><" + TAG_SON + " " + ATT_NAME + "=\"" + STR_ABC
85             + "\"/></" + TAG_TEST + ">";
86 
testParseStringContentHandler()87     public void testParseStringContentHandler() {
88         final String xmlStr = "<Test><Son name=\"abc\"/></Test>";
89         DefaultContentHandler dc = new DefaultContentHandler();
90         try {
91             Xml.parse(xmlStr, dc);
92             assertEquals(STR_SET_DOCUMENT_LOCATOR, dc.mVec.elementAt(0));
93             assertEquals(STR_START_DOCUMENT, dc.mVec.elementAt(1));
94             assertEquals(STR_START_ELEMENT, dc.mVec.elementAt(2));
95             assertEquals(TAG_TEST, dc.mVec.elementAt(3));
96             assertEqualsOrEmpty(TAG_TEST, dc.mVec.elementAt(4));
97             assertEquals(STR_0_NUMBER, dc.mVec.elementAt(5));
98             assertEquals(STR_START_ELEMENT, dc.mVec.elementAt(6));
99             assertEquals(TAG_SON, dc.mVec.elementAt(7));
100             assertEqualsOrEmpty(TAG_SON, dc.mVec.elementAt(8));
101             assertEquals(STR_1_NUMBER, dc.mVec.elementAt(9));
102             assertEquals(ATT_NAME, dc.mVec.elementAt(10));
103             assertEquals(STR_ABC, dc.mVec.elementAt(11));
104             assertEquals(STR_END_ELEMENT, dc.mVec.elementAt(12));
105             assertEquals(STR_EMPTY, dc.mVec.elementAt(13));
106             assertEquals(TAG_SON, dc.mVec.elementAt(14));
107             assertEqualsOrEmpty(TAG_SON, dc.mVec.elementAt(15));
108             assertEquals(STR_END_ELEMENT, dc.mVec.elementAt(16));
109             assertEquals(STR_EMPTY, dc.mVec.elementAt(17));
110             assertEquals(TAG_TEST, dc.mVec.elementAt(18));
111             assertEqualsOrEmpty(TAG_TEST, dc.mVec.elementAt(19));
112             assertEquals(STR_END_DOCUMENT, dc.mVec.elementAt(20));
113 
114         } catch (SAXException e) {
115             fail(e.getMessage());
116         }
117     }
118 
119     class DefaultContentHandler implements ContentHandler {
120 
121         public Vector<String> mVec = new Vector<String>();
122 
characters(char[] ch, int start, int length)123         public void characters(char[] ch, int start, int length) throws SAXException {
124             mVec.add(STR_CHARACTERS_TAG + new String(ch));
125             mVec.add(STR_START_TAG + start);
126             mVec.add(STR_LENGTH_TAG + length);
127         }
128 
endDocument()129         public void endDocument() throws SAXException {
130             mVec.add(STR_END_DOCUMENT);
131         }
132 
endElement(String uri, String localName, String name)133         public void endElement(String uri, String localName, String name) throws SAXException {
134             mVec.add(STR_END_ELEMENT);
135             mVec.add(uri);
136             mVec.add(localName);
137             mVec.add(name);
138         }
139 
endPrefixMapping(String prefix)140         public void endPrefixMapping(String prefix) throws SAXException {
141             mVec.add(STR_END_PREFIX_MAPPING_TAG + prefix);
142         }
143 
ignorableWhitespace(char[] ch, int start, int length)144         public void ignorableWhitespace(char[] ch, int start, int length) throws SAXException {
145             mVec.add(STR_IGNORABLE_WHITESPACE_TAG + new String(ch));
146             mVec.add(STR_START_TAG + start);
147             mVec.add(STR_LENGTH_TAG + length);
148         }
149 
processingInstruction(String target, String data)150         public void processingInstruction(String target, String data) throws SAXException {
151             mVec.add(STR_PROCESSING_INSTRUCTION_TAG + target);
152             mVec.add(data);
153         }
154 
setDocumentLocator(Locator locator)155         public void setDocumentLocator(Locator locator) {
156             mVec.add(STR_SET_DOCUMENT_LOCATOR_TAG + locator);
157         }
158 
skippedEntity(String name)159         public void skippedEntity(String name) throws SAXException {
160             mVec.add(STR_SKIPPED_ENTITY_TAG + name);
161         }
162 
startDocument()163         public void startDocument() throws SAXException {
164             mVec.add(STR_START_DOCUMENT);
165         }
166 
startElement(String uri, String localName, String name, Attributes atts)167         public void startElement(String uri, String localName, String name, Attributes atts)
168                 throws SAXException {
169             mVec.add(STR_START_ELEMENT + uri);
170             mVec.add(localName);
171             mVec.add(name);
172             mVec.add(atts.getLength() + STR_EMPTY);
173             for (int i = 0; i < atts.getLength(); i++) {
174                 mVec.add(atts.getLocalName(i));
175                 mVec.add(atts.getValue(i));
176             }
177         }
178 
startPrefixMapping(String prefix, String uri)179         public void startPrefixMapping(String prefix, String uri) throws SAXException {
180             mVec.add(STR_START_PREFIX_MAPPING_TAG + prefix);
181             mVec.add(uri);
182         }
183 
184     }
185 
testParseReaderContentHander()186     public void testParseReaderContentHander() {
187         ByteArrayOutputStream bout = new ByteArrayOutputStream();
188         DataOutputStream dout = new DataOutputStream(bout);
189         for (int i = 0; i < sourceStr.length(); i++) {
190             try {
191                 dout.write(sourceStr.charAt(i));
192             } catch (IOException e) {
193                 fail(e.getMessage());
194             }
195         }
196         try {
197             dout.flush();
198         } catch (IOException e) {
199             fail(e.getMessage());
200         }
201         BufferedReader reader = new BufferedReader(new InputStreamReader(new ByteArrayInputStream(
202                 bout.toByteArray())));
203         DefaultContentHandler dc = new DefaultContentHandler();
204         try {
205             Xml.parse(reader, dc);
206             assertEquals(STR_SET_DOCUMENT_LOCATOR, dc.mVec.elementAt(0));
207             assertEquals(STR_START_DOCUMENT, dc.mVec.elementAt(1));
208             assertEquals(STR_START_ELEMENT, dc.mVec.elementAt(2));
209             assertEquals(TAG_TEST, dc.mVec.elementAt(3));
210             assertEqualsOrEmpty(TAG_TEST, dc.mVec.elementAt(4));
211             assertEquals(STR_0_NUMBER, dc.mVec.elementAt(5));
212             assertEquals(STR_START_ELEMENT, dc.mVec.elementAt(6));
213             assertEquals(TAG_SON, dc.mVec.elementAt(7));
214             assertEqualsOrEmpty(TAG_SON, dc.mVec.elementAt(8));
215             assertEquals(STR_1_NUMBER, dc.mVec.elementAt(9));
216             assertEquals(ATT_NAME, dc.mVec.elementAt(10));
217             assertEquals(STR_ABC, dc.mVec.elementAt(11));
218             assertEquals(STR_END_ELEMENT, dc.mVec.elementAt(12));
219             assertEquals(STR_EMPTY, dc.mVec.elementAt(13));
220             assertEquals(TAG_SON, dc.mVec.elementAt(14));
221             assertEqualsOrEmpty(TAG_SON, dc.mVec.elementAt(15));
222             assertEquals(STR_END_ELEMENT, dc.mVec.elementAt(16));
223             assertEquals(STR_EMPTY, dc.mVec.elementAt(17));
224             assertEquals(TAG_TEST, dc.mVec.elementAt(18));
225             assertEqualsOrEmpty(TAG_TEST, dc.mVec.elementAt(19));
226             assertEquals(STR_END_DOCUMENT, dc.mVec.elementAt(20));
227         } catch (SAXException e) {
228             fail(e.getMessage());
229         } catch (IOException e) {
230             fail(e.getMessage());
231         }
232     }
233 
testParseInputStreamEncodingContentHandler()234     public void testParseInputStreamEncodingContentHandler() {
235 
236         // test US-ASCII
237         DefaultContentHandler dc = new DefaultContentHandler();
238         try {
239             Xml.parse(new ByteArrayInputStream(sourceStr.getBytes(STR_US_ASCII)),
240                             Xml.Encoding.US_ASCII, dc);
241             assertEquals(STR_SET_DOCUMENT_LOCATOR, dc.mVec.elementAt(0));
242             assertEquals(STR_START_DOCUMENT, dc.mVec.elementAt(1));
243             assertEquals(STR_START_ELEMENT, dc.mVec.elementAt(2));
244             assertEquals(TAG_TEST, dc.mVec.elementAt(3));
245             assertEqualsOrEmpty(TAG_TEST, dc.mVec.elementAt(4));
246             assertEquals(STR_0_NUMBER, dc.mVec.elementAt(5));
247             assertEquals(STR_START_ELEMENT, dc.mVec.elementAt(6));
248             assertEquals(TAG_SON, dc.mVec.elementAt(7));
249             assertEqualsOrEmpty(TAG_SON, dc.mVec.elementAt(8));
250             assertEquals(STR_1_NUMBER, dc.mVec.elementAt(9));
251             assertEquals(ATT_NAME, dc.mVec.elementAt(10));
252             assertEquals(STR_ABC, dc.mVec.elementAt(11));
253             assertEquals(STR_END_ELEMENT, dc.mVec.elementAt(12));
254             assertEquals(STR_EMPTY, dc.mVec.elementAt(13));
255             assertEquals(TAG_SON, dc.mVec.elementAt(14));
256             assertEqualsOrEmpty(TAG_SON, dc.mVec.elementAt(15));
257             assertEquals(STR_END_ELEMENT, dc.mVec.elementAt(16));
258             assertEquals(STR_EMPTY, dc.mVec.elementAt(17));
259             assertEquals(TAG_TEST, dc.mVec.elementAt(18));
260             assertEqualsOrEmpty(TAG_TEST, dc.mVec.elementAt(19));
261             assertEquals(STR_END_DOCUMENT, dc.mVec.elementAt(20));
262         } catch (SAXException e) {
263             fail(e.getMessage());
264         } catch (IOException e) {
265             fail(e.getMessage());
266         }
267 
268         // test UTF-8
269         dc = new DefaultContentHandler();
270         try {
271             Xml.parse(new ByteArrayInputStream(sourceStr.getBytes(STR_UTF_8)),
272                             Xml.Encoding.UTF_8, dc);
273             assertEquals(STR_SET_DOCUMENT_LOCATOR, dc.mVec.elementAt(0));
274             assertEquals(STR_START_DOCUMENT, dc.mVec.elementAt(1));
275             assertEquals(STR_START_ELEMENT, dc.mVec.elementAt(2));
276             assertEquals(TAG_TEST, dc.mVec.elementAt(3));
277             assertEqualsOrEmpty(TAG_TEST, dc.mVec.elementAt(4));
278             assertEquals(STR_0_NUMBER, dc.mVec.elementAt(5));
279             assertEquals(STR_START_ELEMENT, dc.mVec.elementAt(6));
280             assertEquals(TAG_SON, dc.mVec.elementAt(7));
281             assertEqualsOrEmpty(TAG_SON, dc.mVec.elementAt(8));
282             assertEquals(STR_1_NUMBER, dc.mVec.elementAt(9));
283             assertEquals(ATT_NAME, dc.mVec.elementAt(10));
284             assertEquals(STR_ABC, dc.mVec.elementAt(11));
285             assertEquals(STR_END_ELEMENT, dc.mVec.elementAt(12));
286             assertEquals(STR_EMPTY, dc.mVec.elementAt(13));
287             assertEquals(TAG_SON, dc.mVec.elementAt(14));
288             assertEqualsOrEmpty(TAG_SON, dc.mVec.elementAt(15));
289             assertEquals(STR_END_ELEMENT, dc.mVec.elementAt(16));
290             assertEquals(STR_EMPTY, dc.mVec.elementAt(17));
291             assertEquals(TAG_TEST, dc.mVec.elementAt(18));
292             assertEqualsOrEmpty(TAG_TEST, dc.mVec.elementAt(19));
293             assertEquals(STR_END_DOCUMENT, dc.mVec.elementAt(20));
294         } catch (SAXException e) {
295             fail(e.getMessage());
296         } catch (IOException e) {
297             fail(e.getMessage());
298         }
299 
300         // test UTF-16
301         dc = new DefaultContentHandler();
302         try {
303             Xml.parse(new ByteArrayInputStream(sourceStr.getBytes(STR_UTF_16)),
304                             Xml.Encoding.UTF_16, dc);
305             assertEquals(STR_SET_DOCUMENT_LOCATOR, dc.mVec.elementAt(0));
306             assertEquals(STR_START_DOCUMENT, dc.mVec.elementAt(1));
307             assertEquals(STR_START_ELEMENT, dc.mVec.elementAt(2));
308             assertEquals(TAG_TEST, dc.mVec.elementAt(3));
309             assertEqualsOrEmpty(TAG_TEST, dc.mVec.elementAt(4));
310             assertEquals(STR_0_NUMBER, dc.mVec.elementAt(5));
311             assertEquals(STR_START_ELEMENT, dc.mVec.elementAt(6));
312             assertEquals(TAG_SON, dc.mVec.elementAt(7));
313             assertEqualsOrEmpty(TAG_SON, dc.mVec.elementAt(8));
314             assertEquals(STR_1_NUMBER, dc.mVec.elementAt(9));
315             assertEquals(ATT_NAME, dc.mVec.elementAt(10));
316             assertEquals(STR_ABC, dc.mVec.elementAt(11));
317             assertEquals(STR_END_ELEMENT, dc.mVec.elementAt(12));
318             assertEquals(STR_EMPTY, dc.mVec.elementAt(13));
319             assertEquals(TAG_SON, dc.mVec.elementAt(14));
320             assertEqualsOrEmpty(TAG_SON, dc.mVec.elementAt(15));
321             assertEquals(STR_END_ELEMENT, dc.mVec.elementAt(16));
322             assertEquals(STR_EMPTY, dc.mVec.elementAt(17));
323             assertEquals(TAG_TEST, dc.mVec.elementAt(18));
324             assertEqualsOrEmpty(TAG_TEST, dc.mVec.elementAt(19));
325             assertEquals(STR_END_DOCUMENT, dc.mVec.elementAt(20));
326         } catch (SAXException e) {
327             fail(e.getMessage());
328         } catch (IOException e) {
329             fail(e.getMessage());
330         }
331 
332         // test ISO-8859-1
333         dc = new DefaultContentHandler();
334         try {
335             Xml.parse(new ByteArrayInputStream(sourceStr.getBytes(STR_ISO_8859_1)),
336                             Xml.Encoding.ISO_8859_1, dc);
337             assertEquals(STR_SET_DOCUMENT_LOCATOR, dc.mVec.elementAt(0));
338             assertEquals(STR_START_DOCUMENT, dc.mVec.elementAt(1));
339             assertEquals(STR_START_ELEMENT, dc.mVec.elementAt(2));
340             assertEquals(TAG_TEST, dc.mVec.elementAt(3));
341             assertEqualsOrEmpty(TAG_TEST, dc.mVec.elementAt(4));
342             assertEquals(STR_0_NUMBER, dc.mVec.elementAt(5));
343             assertEquals(STR_START_ELEMENT, dc.mVec.elementAt(6));
344             assertEquals(TAG_SON, dc.mVec.elementAt(7));
345             assertEqualsOrEmpty(TAG_SON, dc.mVec.elementAt(8));
346             assertEquals(STR_1_NUMBER, dc.mVec.elementAt(9));
347             assertEquals(ATT_NAME, dc.mVec.elementAt(10));
348             assertEquals(STR_ABC, dc.mVec.elementAt(11));
349             assertEquals(STR_END_ELEMENT, dc.mVec.elementAt(12));
350             assertEquals(STR_EMPTY, dc.mVec.elementAt(13));
351             assertEquals(TAG_SON, dc.mVec.elementAt(14));
352             assertEqualsOrEmpty(TAG_SON, dc.mVec.elementAt(15));
353             assertEquals(STR_END_ELEMENT, dc.mVec.elementAt(16));
354             assertEquals(STR_EMPTY, dc.mVec.elementAt(17));
355             assertEquals(TAG_TEST, dc.mVec.elementAt(18));
356             assertEqualsOrEmpty(TAG_TEST, dc.mVec.elementAt(19));
357             assertEquals(STR_END_DOCUMENT, dc.mVec.elementAt(20));
358         } catch (SAXException e) {
359             fail(e.getMessage());
360         } catch (IOException e) {
361             fail(e.getMessage());
362         }
363     }
364 
testNewSerializer()365     public void testNewSerializer() {
366         XmlSerializer xs = Xml.newSerializer();
367         assertNotNull(xs);
368 
369         XmlPullParser xp = Xml.newPullParser();
370         assertNotNull(xp);
371     }
372 
testFindEncodingByName()373     public void testFindEncodingByName() {
374 
375         try {
376             assertEquals(Xml.Encoding.UTF_8, Xml.findEncodingByName(STR_UTF_8));
377             assertEquals(Xml.Encoding.UTF_16, Xml.findEncodingByName(STR_UTF_16));
378             assertEquals(Xml.Encoding.US_ASCII, Xml.findEncodingByName(STR_US_ASCII));
379             assertEquals(Xml.Encoding.ISO_8859_1, Xml.findEncodingByName(STR_ISO_8859_1));
380         } catch (UnsupportedEncodingException e) {
381             fail(e.getMessage());
382         }
383 
384         try {
385             Xml.findEncodingByName(STR_INVALIDATE_EN_CODING);
386             fail("should throw out exception");
387         } catch (UnsupportedEncodingException e) {
388             // expect
389         }
390     }
391 
testAsAttributeSet()392     public void testAsAttributeSet() {
393         XmlResourceParser xp = getContext().getResources().getLayout(
394                 android.util.cts.R.layout.xml_test);
395         int eventType = -1;
396         try {
397             eventType = xp.getEventType();
398         } catch (XmlPullParserException e) {
399             fail(e.getMessage());
400         }
401 
402         // start to parse XML document
403         while (eventType != XmlResourceParser.START_TAG
404                 && eventType != XmlResourceParser.END_DOCUMENT) {
405             try {
406                 eventType = xp.next();
407             } catch (XmlPullParserException e) {
408                 fail(e.getMessage());
409             } catch (IOException e) {
410                 fail(e.getMessage());
411             }
412         }
413         if (eventType == XmlResourceParser.START_TAG) {
414             AttributeSet set = Xml.asAttributeSet(xp);
415             assertEquals(2, set.getAttributeCount());
416             assertEquals(STR_LAYOUT_WIDTH, set.getAttributeName(0));
417 
418             assertEquals(STR_N1, set.getAttributeValue(0));
419             assertEquals(STR_LAYOUT_HEIGHT, set.getAttributeName(1));
420             assertEquals(STR_N2, set.getAttributeValue(1));
421         } else {
422             fail("XML parser didn't find the start element of the specified xml file.");
423         }
424     }
425 
assertEqualsOrEmpty(String expected, String actual)426     private void assertEqualsOrEmpty(String expected, String actual) {
427         if (actual.length() != 0) {
428             assertEquals(expected, actual);
429         }
430     }
431 }
432