/sax/tests/saxtests/src/android/sax/SafeSaxTest.java
https://github.com/aizuzi/platform_frameworks_base · Java · 541 lines · 432 code · 89 blank · 20 comment · 55 complexity · 8f04bd0e2cc1a1c734d202a9a0f6b991 MD5 · raw file
- /*
- * Copyright (C) 2007 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
- package android.sax;
- import android.graphics.Bitmap;
- import android.sax.Element;
- import android.sax.ElementListener;
- import android.sax.EndTextElementListener;
- import android.sax.RootElement;
- import android.sax.StartElementListener;
- import android.sax.TextElementListener;
- import android.test.AndroidTestCase;
- import android.test.suitebuilder.annotation.LargeTest;
- import android.test.suitebuilder.annotation.SmallTest;
- import android.text.format.Time;
- import android.util.Log;
- import android.util.Xml;
- import com.android.internal.util.XmlUtils;
- import org.xml.sax.Attributes;
- import org.xml.sax.ContentHandler;
- import org.xml.sax.SAXException;
- import org.xml.sax.helpers.DefaultHandler;
- import java.io.ByteArrayInputStream;
- import java.io.ByteArrayOutputStream;
- import java.io.IOException;
- import java.io.InputStream;
- import com.android.frameworks.saxtests.R;
- public class SafeSaxTest extends AndroidTestCase {
- private static final String TAG = SafeSaxTest.class.getName();
- private static final String ATOM_NAMESPACE = "http://www.w3.org/2005/Atom";
- private static final String MEDIA_NAMESPACE = "http://search.yahoo.com/mrss/";
- private static final String YOUTUBE_NAMESPACE = "http://gdata.youtube.com/schemas/2007";
- private static final String GDATA_NAMESPACE = "http://schemas.google.com/g/2005";
- private static class ElementCounter implements ElementListener {
- int starts = 0;
- int ends = 0;
- public void start(Attributes attributes) {
- starts++;
- }
- public void end() {
- ends++;
- }
- }
- private static class TextElementCounter implements TextElementListener {
- int starts = 0;
- String bodies = "";
- public void start(Attributes attributes) {
- starts++;
- }
- public void end(String body) {
- this.bodies += body;
- }
- }
- @SmallTest
- public void testListener() throws Exception {
- String xml = "<feed xmlns='http://www.w3.org/2005/Atom'>\n"
- + "<entry>\n"
- + "<id>a</id>\n"
- + "</entry>\n"
- + "<entry>\n"
- + "<id>b</id>\n"
- + "</entry>\n"
- + "</feed>\n";
- RootElement root = new RootElement(ATOM_NAMESPACE, "feed");
- Element entry = root.requireChild(ATOM_NAMESPACE, "entry");
- Element id = entry.requireChild(ATOM_NAMESPACE, "id");
- ElementCounter rootCounter = new ElementCounter();
- ElementCounter entryCounter = new ElementCounter();
- TextElementCounter idCounter = new TextElementCounter();
- root.setElementListener(rootCounter);
- entry.setElementListener(entryCounter);
- id.setTextElementListener(idCounter);
- Xml.parse(xml, root.getContentHandler());
- assertEquals(1, rootCounter.starts);
- assertEquals(1, rootCounter.ends);
- assertEquals(2, entryCounter.starts);
- assertEquals(2, entryCounter.ends);
- assertEquals(2, idCounter.starts);
- assertEquals("ab", idCounter.bodies);
- }
- @SmallTest
- public void testMissingRequiredChild() throws Exception {
- String xml = "<feed></feed>";
- RootElement root = new RootElement("feed");
- root.requireChild("entry");
- try {
- Xml.parse(xml, root.getContentHandler());
- fail("expected exception not thrown");
- } catch (SAXException e) {
- // Expected.
- }
- }
- @SmallTest
- public void testMixedContent() throws Exception {
- String xml = "<feed><entry></entry></feed>";
- RootElement root = new RootElement("feed");
- root.setEndTextElementListener(new EndTextElementListener() {
- public void end(String body) {
- }
- });
- try {
- Xml.parse(xml, root.getContentHandler());
- fail("expected exception not thrown");
- } catch (SAXException e) {
- // Expected.
- }
- }
- @LargeTest
- public void testPerformance() throws Exception {
- InputStream in = mContext.getResources().openRawResource(R.raw.youtube);
- byte[] xmlBytes;
- try {
- ByteArrayOutputStream out = new ByteArrayOutputStream();
- byte[] buffer = new byte[1024];
- int length;
- while ((length = in.read(buffer)) != -1) {
- out.write(buffer, 0, length);
- }
- xmlBytes = out.toByteArray();
- } finally {
- in.close();
- }
- Log.i("***", "File size: " + (xmlBytes.length / 1024) + "k");
- VideoAdapter videoAdapter = new VideoAdapter();
- ContentHandler handler = newContentHandler(videoAdapter);
- for (int i = 0; i < 2; i++) {
- pureSaxTest(new ByteArrayInputStream(xmlBytes));
- saxyModelTest(new ByteArrayInputStream(xmlBytes));
- saxyModelTest(new ByteArrayInputStream(xmlBytes), handler);
- }
- }
- private static void pureSaxTest(InputStream inputStream) throws IOException, SAXException {
- long start = System.currentTimeMillis();
- VideoAdapter videoAdapter = new VideoAdapter();
- Xml.parse(inputStream, Xml.Encoding.UTF_8, new YouTubeContentHandler(videoAdapter));
- long elapsed = System.currentTimeMillis() - start;
- Log.i(TAG, "pure SAX: " + elapsed + "ms");
- }
- private static void saxyModelTest(InputStream inputStream) throws IOException, SAXException {
- long start = System.currentTimeMillis();
- VideoAdapter videoAdapter = new VideoAdapter();
- Xml.parse(inputStream, Xml.Encoding.UTF_8, newContentHandler(videoAdapter));
- long elapsed = System.currentTimeMillis() - start;
- Log.i(TAG, "Saxy Model: " + elapsed + "ms");
- }
- private static void saxyModelTest(InputStream inputStream, ContentHandler contentHandler)
- throws IOException, SAXException {
- long start = System.currentTimeMillis();
- Xml.parse(inputStream, Xml.Encoding.UTF_8, contentHandler);
- long elapsed = System.currentTimeMillis() - start;
- Log.i(TAG, "Saxy Model (preloaded): " + elapsed + "ms");
- }
- private static class VideoAdapter {
- public void addVideo(YouTubeVideo video) {
- }
- }
- private static ContentHandler newContentHandler(VideoAdapter videoAdapter) {
- return new HandlerFactory().newContentHandler(videoAdapter);
- }
- private static class HandlerFactory {
- YouTubeVideo video;
- public ContentHandler newContentHandler(VideoAdapter videoAdapter) {
- RootElement root = new RootElement(ATOM_NAMESPACE, "feed");
- final VideoListener videoListener = new VideoListener(videoAdapter);
- Element entry = root.getChild(ATOM_NAMESPACE, "entry");
- entry.setElementListener(videoListener);
- entry.getChild(ATOM_NAMESPACE, "id")
- .setEndTextElementListener(new EndTextElementListener() {
- public void end(String body) {
- video.videoId = body;
- }
- });
- entry.getChild(ATOM_NAMESPACE, "published")
- .setEndTextElementListener(new EndTextElementListener() {
- public void end(String body) {
- // TODO(tomtaylor): programmatically get the timezone
- video.dateAdded = new Time(Time.TIMEZONE_UTC);
- video.dateAdded.parse3339(body);
- }
- });
- Element author = entry.getChild(ATOM_NAMESPACE, "author");
- author.getChild(ATOM_NAMESPACE, "name")
- .setEndTextElementListener(new EndTextElementListener() {
- public void end(String body) {
- video.authorName = body;
- }
- });
- Element mediaGroup = entry.getChild(MEDIA_NAMESPACE, "group");
- mediaGroup.getChild(MEDIA_NAMESPACE, "thumbnail")
- .setStartElementListener(new StartElementListener() {
- public void start(Attributes attributes) {
- String url = attributes.getValue("", "url");
- if (video.thumbnailUrl == null && url.length() > 0) {
- video.thumbnailUrl = url;
- }
- }
- });
- mediaGroup.getChild(MEDIA_NAMESPACE, "content")
- .setStartElementListener(new StartElementListener() {
- public void start(Attributes attributes) {
- String url = attributes.getValue("", "url");
- if (url != null) {
- video.videoUrl = url;
- }
- }
- });
- mediaGroup.getChild(MEDIA_NAMESPACE, "player")
- .setStartElementListener(new StartElementListener() {
- public void start(Attributes attributes) {
- String url = attributes.getValue("", "url");
- if (url != null) {
- video.playbackUrl = url;
- }
- }
- });
- mediaGroup.getChild(MEDIA_NAMESPACE, "title")
- .setEndTextElementListener(new EndTextElementListener() {
- public void end(String body) {
- video.title = body;
- }
- });
- mediaGroup.getChild(MEDIA_NAMESPACE, "category")
- .setEndTextElementListener(new EndTextElementListener() {
- public void end(String body) {
- video.category = body;
- }
- });
- mediaGroup.getChild(MEDIA_NAMESPACE, "description")
- .setEndTextElementListener(new EndTextElementListener() {
- public void end(String body) {
- video.description = body;
- }
- });
- mediaGroup.getChild(MEDIA_NAMESPACE, "keywords")
- .setEndTextElementListener(new EndTextElementListener() {
- public void end(String body) {
- video.tags = body;
- }
- });
- mediaGroup.getChild(YOUTUBE_NAMESPACE, "duration")
- .setStartElementListener(new StartElementListener() {
- public void start(Attributes attributes) {
- String seconds = attributes.getValue("", "seconds");
- video.lengthInSeconds
- = XmlUtils.convertValueToInt(seconds, 0);
- }
- });
- mediaGroup.getChild(YOUTUBE_NAMESPACE, "statistics")
- .setStartElementListener(new StartElementListener() {
- public void start(Attributes attributes) {
- String viewCount = attributes.getValue("", "viewCount");
- video.viewCount
- = XmlUtils.convertValueToInt(viewCount, 0);
- }
- });
- entry.getChild(GDATA_NAMESPACE, "rating")
- .setStartElementListener(new StartElementListener() {
- public void start(Attributes attributes) {
- String average = attributes.getValue("", "average");
- video.rating = average == null
- ? 0.0f : Float.parseFloat(average);
- }
- });
- return root.getContentHandler();
- }
- class VideoListener implements ElementListener {
- final VideoAdapter videoAdapter;
- public VideoListener(VideoAdapter videoAdapter) {
- this.videoAdapter = videoAdapter;
- }
- public void start(Attributes attributes) {
- video = new YouTubeVideo();
- }
- public void end() {
- videoAdapter.addVideo(video);
- video = null;
- }
- }
- }
- private static class YouTubeContentHandler extends DefaultHandler {
- final VideoAdapter videoAdapter;
- YouTubeVideo video = null;
- StringBuilder builder = null;
- public YouTubeContentHandler(VideoAdapter videoAdapter) {
- this.videoAdapter = videoAdapter;
- }
- @Override
- public void startElement(String uri, String localName, String qName,
- Attributes attributes) throws SAXException {
- if (uri.equals(ATOM_NAMESPACE)) {
- if (localName.equals("entry")) {
- video = new YouTubeVideo();
- return;
- }
- if (video == null) {
- return;
- }
- if (!localName.equals("id")
- && !localName.equals("published")
- && !localName.equals("name")) {
- return;
- }
- this.builder = new StringBuilder();
- return;
- }
- if (video == null) {
- return;
- }
- if (uri.equals(MEDIA_NAMESPACE)) {
- if (localName.equals("thumbnail")) {
- String url = attributes.getValue("", "url");
- if (video.thumbnailUrl == null && url.length() > 0) {
- video.thumbnailUrl = url;
- }
- return;
- }
- if (localName.equals("content")) {
- String url = attributes.getValue("", "url");
- if (url != null) {
- video.videoUrl = url;
- }
- return;
- }
- if (localName.equals("player")) {
- String url = attributes.getValue("", "url");
- if (url != null) {
- video.playbackUrl = url;
- }
- return;
- }
- if (localName.equals("title")
- || localName.equals("category")
- || localName.equals("description")
- || localName.equals("keywords")) {
- this.builder = new StringBuilder();
- return;
- }
- return;
- }
- if (uri.equals(YOUTUBE_NAMESPACE)) {
- if (localName.equals("duration")) {
- video.lengthInSeconds = XmlUtils.convertValueToInt(
- attributes.getValue("", "seconds"), 0);
- return;
- }
- if (localName.equals("statistics")) {
- video.viewCount = XmlUtils.convertValueToInt(
- attributes.getValue("", "viewCount"), 0);
- return;
- }
- return;
- }
- if (uri.equals(GDATA_NAMESPACE)) {
- if (localName.equals("rating")) {
- String average = attributes.getValue("", "average");
- video.rating = average == null
- ? 0.0f : Float.parseFloat(average);
- }
- }
- }
- @Override
- public void characters(char text[], int start, int length)
- throws SAXException {
- if (builder != null) {
- builder.append(text, start, length);
- }
- }
- String takeText() {
- try {
- return builder.toString();
- } finally {
- builder = null;
- }
- }
- @Override
- public void endElement(String uri, String localName, String qName)
- throws SAXException {
- if (video == null) {
- return;
- }
- if (uri.equals(ATOM_NAMESPACE)) {
- if (localName.equals("published")) {
- // TODO(tomtaylor): programmatically get the timezone
- video.dateAdded = new Time(Time.TIMEZONE_UTC);
- video.dateAdded.parse3339(takeText());
- return;
- }
- if (localName.equals("name")) {
- video.authorName = takeText();
- return;
- }
- if (localName.equals("id")) {
- video.videoId = takeText();
- return;
- }
- if (localName.equals("entry")) {
- // Add the video!
- videoAdapter.addVideo(video);
- video = null;
- return;
- }
- return;
- }
- if (uri.equals(MEDIA_NAMESPACE)) {
- if (localName.equals("description")) {
- video.description = takeText();
- return;
- }
- if (localName.equals("keywords")) {
- video.tags = takeText();
- return;
- }
- if (localName.equals("category")) {
- video.category = takeText();
- return;
- }
- if (localName.equals("title")) {
- video.title = takeText();
- }
- }
- }
- }
- private static class YouTubeVideo {
- public String videoId; // the id used to lookup on YouTube
- public String videoUrl; // the url to play the video
- public String playbackUrl; // the url to share for users to play video
- public String thumbnailUrl; // the url of the thumbnail image
- public String title;
- public Bitmap bitmap; // cached bitmap of the thumbnail
- public int lengthInSeconds;
- public int viewCount; // number of times the video has been viewed
- public float rating; // ranges from 0.0 to 5.0
- public Boolean triedToLoadThumbnail;
- public String authorName;
- public Time dateAdded;
- public String category;
- public String tags;
- public String description;
- }
- }