19066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project/*
29066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Copyright (C) 2007 The Android Open Source Project
39066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project *
49066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Licensed under the Apache License, Version 2.0 (the "License");
59066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * you may not use this file except in compliance with the License.
69066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * You may obtain a copy of the License at
79066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project *
89066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project *      http://www.apache.org/licenses/LICENSE-2.0
99066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project *
109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Unless required by applicable law or agreed to in writing, software
119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * distributed under the License is distributed on an "AS IS" BASIS,
129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * See the License for the specific language governing permissions and
149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * limitations under the License.
159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */
169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
171a44d5dcabc18cd5ef111f732ccff91683a1a093Neal Nguyenpackage android.sax;
189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.graphics.Bitmap;
209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.sax.Element;
219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.sax.ElementListener;
229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.sax.EndTextElementListener;
239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.sax.RootElement;
249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.sax.StartElementListener;
259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.sax.TextElementListener;
269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.test.AndroidTestCase;
279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.test.suitebuilder.annotation.LargeTest;
289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.test.suitebuilder.annotation.SmallTest;
299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.text.format.Time;
309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.util.Log;
319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.util.Xml;
322269d1572e5fcfb725ea55f5764d8c3280d69f6dDianne Hackbornimport com.android.internal.util.XmlUtils;
339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport org.xml.sax.Attributes;
349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport org.xml.sax.ContentHandler;
359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport org.xml.sax.SAXException;
369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport org.xml.sax.helpers.DefaultHandler;
379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport java.io.ByteArrayInputStream;
399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport java.io.ByteArrayOutputStream;
409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport java.io.IOException;
419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport java.io.InputStream;
429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
431a44d5dcabc18cd5ef111f732ccff91683a1a093Neal Nguyenimport com.android.frameworks.saxtests.R;
441a44d5dcabc18cd5ef111f732ccff91683a1a093Neal Nguyen
459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectpublic class SafeSaxTest extends AndroidTestCase {
469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    private static final String TAG = SafeSaxTest.class.getName();
489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    private static final String ATOM_NAMESPACE = "http://www.w3.org/2005/Atom";
509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    private static final String MEDIA_NAMESPACE = "http://search.yahoo.com/mrss/";
519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    private static final String YOUTUBE_NAMESPACE = "http://gdata.youtube.com/schemas/2007";
529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    private static final String GDATA_NAMESPACE = "http://schemas.google.com/g/2005";
539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    private static class ElementCounter implements ElementListener {
559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        int starts = 0;
569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        int ends = 0;
579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        public void start(Attributes attributes) {
599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            starts++;
609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        public void end() {
639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            ends++;
649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    private static class TextElementCounter implements TextElementListener {
689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        int starts = 0;
699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        String bodies = "";
709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        public void start(Attributes attributes) {
729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            starts++;
739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        public void end(String body) {
769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            this.bodies += body;
779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    @SmallTest
819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public void testListener() throws Exception {
829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        String xml = "<feed xmlns='http://www.w3.org/2005/Atom'>\n"
839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                + "<entry>\n"
849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                + "<id>a</id>\n"
859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                + "</entry>\n"
869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                + "<entry>\n"
879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                + "<id>b</id>\n"
889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                + "</entry>\n"
899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                + "</feed>\n";
909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        RootElement root = new RootElement(ATOM_NAMESPACE, "feed");
929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        Element entry = root.requireChild(ATOM_NAMESPACE, "entry");
939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        Element id = entry.requireChild(ATOM_NAMESPACE, "id");
949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        ElementCounter rootCounter = new ElementCounter();
969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        ElementCounter entryCounter = new ElementCounter();
979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        TextElementCounter idCounter = new TextElementCounter();
989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        root.setElementListener(rootCounter);
1009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        entry.setElementListener(entryCounter);
1019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        id.setTextElementListener(idCounter);
1029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        Xml.parse(xml, root.getContentHandler());
1049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        assertEquals(1, rootCounter.starts);
1069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        assertEquals(1, rootCounter.ends);
1079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        assertEquals(2, entryCounter.starts);
1089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        assertEquals(2, entryCounter.ends);
1099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        assertEquals(2, idCounter.starts);
1109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        assertEquals("ab", idCounter.bodies);
1119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
1129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    @SmallTest
1149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public void testMissingRequiredChild() throws Exception {
1159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        String xml = "<feed></feed>";
1169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        RootElement root = new RootElement("feed");
1179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        root.requireChild("entry");
1189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        try {
1209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            Xml.parse(xml, root.getContentHandler());
1219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            fail("expected exception not thrown");
1229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        } catch (SAXException e) {
1239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            // Expected.
1249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
1259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
1269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    @SmallTest
1289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public void testMixedContent() throws Exception {
1299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        String xml = "<feed><entry></entry></feed>";
1309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        RootElement root = new RootElement("feed");
1329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        root.setEndTextElementListener(new EndTextElementListener() {
1339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            public void end(String body) {
1349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
1359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        });
1369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        try {
1389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            Xml.parse(xml, root.getContentHandler());
1399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            fail("expected exception not thrown");
1409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        } catch (SAXException e) {
1419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            // Expected.
1429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
1439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
1449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    @LargeTest
1469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public void testPerformance() throws Exception {
1479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        InputStream in = mContext.getResources().openRawResource(R.raw.youtube);
1489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        byte[] xmlBytes;
1499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        try {
1509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            ByteArrayOutputStream out = new ByteArrayOutputStream();
1519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            byte[] buffer = new byte[1024];
1529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            int length;
1539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            while ((length = in.read(buffer)) != -1) {
1549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                out.write(buffer, 0, length);
1559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
1569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            xmlBytes = out.toByteArray();
1579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        } finally {
1589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            in.close();
1599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
1609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        Log.i("***", "File size: " + (xmlBytes.length / 1024) + "k");
1629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        VideoAdapter videoAdapter = new VideoAdapter();
1649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        ContentHandler handler = newContentHandler(videoAdapter);
1659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        for (int i = 0; i < 2; i++) {
1669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            pureSaxTest(new ByteArrayInputStream(xmlBytes));
1679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            saxyModelTest(new ByteArrayInputStream(xmlBytes));
1689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            saxyModelTest(new ByteArrayInputStream(xmlBytes), handler);
1699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
1709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
1719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    private static void pureSaxTest(InputStream inputStream) throws IOException, SAXException {
1739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        long start = System.currentTimeMillis();
1749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        VideoAdapter videoAdapter = new VideoAdapter();
1759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        Xml.parse(inputStream, Xml.Encoding.UTF_8, new YouTubeContentHandler(videoAdapter));
1769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        long elapsed = System.currentTimeMillis() - start;
1779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        Log.i(TAG, "pure SAX: " + elapsed + "ms");
1789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
1799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    private static void saxyModelTest(InputStream inputStream) throws IOException, SAXException {
1819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        long start = System.currentTimeMillis();
1829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        VideoAdapter videoAdapter = new VideoAdapter();
1839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        Xml.parse(inputStream, Xml.Encoding.UTF_8, newContentHandler(videoAdapter));
1849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        long elapsed = System.currentTimeMillis() - start;
1859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        Log.i(TAG, "Saxy Model: " + elapsed + "ms");
1869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
1879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    private static void saxyModelTest(InputStream inputStream, ContentHandler contentHandler)
1899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            throws IOException, SAXException {
1909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        long start = System.currentTimeMillis();
1919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        Xml.parse(inputStream, Xml.Encoding.UTF_8, contentHandler);
1929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        long elapsed = System.currentTimeMillis() - start;
1939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        Log.i(TAG, "Saxy Model (preloaded): " + elapsed + "ms");
1949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
1959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    private static class VideoAdapter {
1979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        public void addVideo(YouTubeVideo video) {
1989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
1999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
2009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
2019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    private static ContentHandler newContentHandler(VideoAdapter videoAdapter) {
2029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return new HandlerFactory().newContentHandler(videoAdapter);
2039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
2049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
2059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    private static class HandlerFactory {
2069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        YouTubeVideo video;
2079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
2089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        public ContentHandler newContentHandler(VideoAdapter videoAdapter) {
2099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            RootElement root = new RootElement(ATOM_NAMESPACE, "feed");
2109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
2119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            final VideoListener videoListener = new VideoListener(videoAdapter);
2129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
2139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            Element entry = root.getChild(ATOM_NAMESPACE, "entry");
2149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
2159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            entry.setElementListener(videoListener);
2169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
2179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            entry.getChild(ATOM_NAMESPACE, "id")
2189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    .setEndTextElementListener(new EndTextElementListener() {
2199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        public void end(String body) {
2209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                            video.videoId = body;
2219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        }
2229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    });
2239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
2249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            entry.getChild(ATOM_NAMESPACE, "published")
2259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    .setEndTextElementListener(new EndTextElementListener() {
2269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        public void end(String body) {
2279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                            // TODO(tomtaylor): programmatically get the timezone
2289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                            video.dateAdded = new Time(Time.TIMEZONE_UTC);
2299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                            video.dateAdded.parse3339(body);
2309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        }
2319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    });
2329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
2339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            Element author = entry.getChild(ATOM_NAMESPACE, "author");
2349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            author.getChild(ATOM_NAMESPACE, "name")
2359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    .setEndTextElementListener(new EndTextElementListener() {
2369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        public void end(String body) {
2379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                            video.authorName = body;
2389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        }
2399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    });
2409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
2419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            Element mediaGroup = entry.getChild(MEDIA_NAMESPACE, "group");
2429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
2439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            mediaGroup.getChild(MEDIA_NAMESPACE, "thumbnail")
2449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    .setStartElementListener(new StartElementListener() {
2459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        public void start(Attributes attributes) {
2469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                            String url = attributes.getValue("", "url");
2479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                            if (video.thumbnailUrl == null && url.length() > 0) {
2489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                                video.thumbnailUrl = url;
2499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                            }
2509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        }
2519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    });
2529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
2539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            mediaGroup.getChild(MEDIA_NAMESPACE, "content")
2549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    .setStartElementListener(new StartElementListener() {
2559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        public void start(Attributes attributes) {
2569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                            String url = attributes.getValue("", "url");
2579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                            if (url != null) {
2589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                                video.videoUrl = url;
2599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                            }
2609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        }
2619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    });
2629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
2639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            mediaGroup.getChild(MEDIA_NAMESPACE, "player")
2649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    .setStartElementListener(new StartElementListener() {
2659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        public void start(Attributes attributes) {
2669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                            String url = attributes.getValue("", "url");
2679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                            if (url != null) {
2689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                                video.playbackUrl = url;
2699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                            }
2709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        }
2719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    });
2729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
2739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            mediaGroup.getChild(MEDIA_NAMESPACE, "title")
2749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    .setEndTextElementListener(new EndTextElementListener() {
2759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        public void end(String body) {
2769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                            video.title = body;
2779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        }
2789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    });
2799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
2809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            mediaGroup.getChild(MEDIA_NAMESPACE, "category")
2819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    .setEndTextElementListener(new EndTextElementListener() {
2829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        public void end(String body) {
2839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                            video.category = body;
2849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        }
2859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    });
2869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
2879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            mediaGroup.getChild(MEDIA_NAMESPACE, "description")
2889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    .setEndTextElementListener(new EndTextElementListener() {
2899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        public void end(String body) {
2909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                            video.description = body;
2919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        }
2929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    });
2939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
2949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            mediaGroup.getChild(MEDIA_NAMESPACE, "keywords")
2959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    .setEndTextElementListener(new EndTextElementListener() {
2969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        public void end(String body) {
2979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                            video.tags = body;
2989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        }
2999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    });
3009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
3019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            mediaGroup.getChild(YOUTUBE_NAMESPACE, "duration")
3029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    .setStartElementListener(new StartElementListener() {
3039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        public void start(Attributes attributes) {
3049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                            String seconds = attributes.getValue("", "seconds");
3059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                            video.lengthInSeconds
3069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                                    = XmlUtils.convertValueToInt(seconds, 0);
3079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        }
3089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    });
3099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
3109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            mediaGroup.getChild(YOUTUBE_NAMESPACE, "statistics")
3119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    .setStartElementListener(new StartElementListener() {
3129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        public void start(Attributes attributes) {
3139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                            String viewCount = attributes.getValue("", "viewCount");
3149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                            video.viewCount
3159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                                    = XmlUtils.convertValueToInt(viewCount, 0);
3169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        }
3179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    });
3189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
3199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            entry.getChild(GDATA_NAMESPACE, "rating")
3209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    .setStartElementListener(new StartElementListener() {
3219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        public void start(Attributes attributes) {
3229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                            String average = attributes.getValue("", "average");
3239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                            video.rating = average == null
3249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                                    ? 0.0f : Float.parseFloat(average);
3259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        }
3269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    });
3279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
3289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            return root.getContentHandler();
3299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
3309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
3319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        class VideoListener implements ElementListener {
3329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
3339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            final VideoAdapter videoAdapter;
3349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
3359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            public VideoListener(VideoAdapter videoAdapter) {
3369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                this.videoAdapter = videoAdapter;
3379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
3389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
3399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            public void start(Attributes attributes) {
3409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                video = new YouTubeVideo();
3419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
3429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
3439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            public void end() {
3449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                videoAdapter.addVideo(video);
3459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                video = null;
3469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
3479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
3489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
3499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
3509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    private static class YouTubeContentHandler extends DefaultHandler {
3519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
3529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        final VideoAdapter videoAdapter;
3539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
3549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        YouTubeVideo video = null;
3559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        StringBuilder builder = null;
3569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
3579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        public YouTubeContentHandler(VideoAdapter videoAdapter) {
3589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            this.videoAdapter = videoAdapter;
3599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
3609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
3619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        @Override
3629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        public void startElement(String uri, String localName, String qName,
3639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                Attributes attributes) throws SAXException {
3649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            if (uri.equals(ATOM_NAMESPACE)) {
3659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                if (localName.equals("entry")) {
3669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    video = new YouTubeVideo();
3679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    return;
3689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                }
3699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
3709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                if (video == null) {
3719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    return;
3729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                }
3739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
3749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                if (!localName.equals("id")
3759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        && !localName.equals("published")
3769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        && !localName.equals("name")) {
3779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    return;
3789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                }
3799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                this.builder = new StringBuilder();
3809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                return;
3819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
3829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
3839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
3849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            if (video == null) {
3859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                return;
3869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
3879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
3889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            if (uri.equals(MEDIA_NAMESPACE)) {
3899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                if (localName.equals("thumbnail")) {
3909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    String url = attributes.getValue("", "url");
3919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    if (video.thumbnailUrl == null && url.length() > 0) {
3929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        video.thumbnailUrl = url;
3939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    }
3949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    return;
3959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                }
3969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
3979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                if (localName.equals("content")) {
3989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    String url = attributes.getValue("", "url");
3999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    if (url != null) {
4009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        video.videoUrl = url;
4019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    }
4029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    return;
4039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                }
4049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
4059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                if (localName.equals("player")) {
4069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    String url = attributes.getValue("", "url");
4079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    if (url != null) {
4089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        video.playbackUrl = url;
4099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    }
4109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    return;
4119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                }
4129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
4139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                if (localName.equals("title")
4149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        || localName.equals("category")
4159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        || localName.equals("description")
4169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        || localName.equals("keywords")) {
4179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    this.builder = new StringBuilder();
4189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    return;
4199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                }
4209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
4219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                return;
4229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
4239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
4249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            if (uri.equals(YOUTUBE_NAMESPACE)) {
4259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                if (localName.equals("duration")) {
4269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    video.lengthInSeconds = XmlUtils.convertValueToInt(
4279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                            attributes.getValue("", "seconds"), 0);
4289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    return;
4299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                }
4309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
4319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                if (localName.equals("statistics")) {
4329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    video.viewCount = XmlUtils.convertValueToInt(
4339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                            attributes.getValue("", "viewCount"), 0);
4349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    return;
4359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                }
4369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
4379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                return;
4389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
4399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
4409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            if (uri.equals(GDATA_NAMESPACE)) {
4419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                if (localName.equals("rating")) {
4429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    String average = attributes.getValue("", "average");
4439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    video.rating = average == null
4449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                            ? 0.0f : Float.parseFloat(average);
4459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                }
4469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
4479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
4489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
4499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        @Override
4509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        public void characters(char text[], int start, int length)
4519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                throws SAXException {
4529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            if (builder != null) {
4539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                builder.append(text, start, length);
4549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
4559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
4569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
4579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        String takeText() {
4589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            try {
4599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                return builder.toString();
4609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            } finally {
4619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                builder = null;
4629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
4639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
4649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
4659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        @Override
4669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        public void endElement(String uri, String localName, String qName)
4679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                throws SAXException {
4689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            if (video == null) {
4699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                return;
4709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
4719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
4729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            if (uri.equals(ATOM_NAMESPACE)) {
4739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                if (localName.equals("published")) {
4749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    // TODO(tomtaylor): programmatically get the timezone
4759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    video.dateAdded = new Time(Time.TIMEZONE_UTC);
4769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    video.dateAdded.parse3339(takeText());
4779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    return;
4789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                }
4799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
4809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                if (localName.equals("name")) {
4819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    video.authorName = takeText();
4829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    return;
4839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                }
4849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
4859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                if (localName.equals("id")) {
4869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    video.videoId = takeText();
4879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    return;
4889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                }
4899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
4909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                if (localName.equals("entry")) {
4919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    // Add the video!
4929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    videoAdapter.addVideo(video);
4939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    video = null;
4949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    return;
4959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                }
4969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
4979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                return;
4989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
4999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
5009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            if (uri.equals(MEDIA_NAMESPACE)) {
5019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                if (localName.equals("description")) {
5029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    video.description = takeText();
5039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    return;
5049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                }
5059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
5069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                if (localName.equals("keywords")) {
5079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    video.tags = takeText();
5089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    return;
5099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                }
5109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
5119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                if (localName.equals("category")) {
5129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    video.category = takeText();
5139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    return;
5149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                }
5159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
5169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                if (localName.equals("title")) {
5179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    video.title = takeText();
5189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                }
5199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
5209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
5219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
5229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
5239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    private static class YouTubeVideo {
5249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        public String videoId;     // the id used to lookup on YouTube
5259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        public String videoUrl;       // the url to play the video
5269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        public String playbackUrl;    // the url to share for users to play video
5279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        public String thumbnailUrl;   // the url of the thumbnail image
5289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        public String title;
5299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        public Bitmap bitmap;      // cached bitmap of the thumbnail
5309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        public int lengthInSeconds;
5319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        public int viewCount;      // number of times the video has been viewed
5329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        public float rating;       // ranges from 0.0 to 5.0
5339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        public Boolean triedToLoadThumbnail;
5349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        public String authorName;
5359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        public Time dateAdded;
5369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        public String category;
5379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        public String tags;
5389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        public String description;
5399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
5409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
5419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
542