Add prebuilt browseable samples as static files.
Change-Id: Ifb5382223343400882834d2dd9c182c3df602e34
This commit is contained in:
@@ -0,0 +1,278 @@
|
||||
/*
|
||||
* Copyright 2013 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 com.example.android.basicsyncadapter.net;
|
||||
|
||||
import android.text.format.Time;
|
||||
import android.util.Xml;
|
||||
|
||||
import org.xmlpull.v1.XmlPullParser;
|
||||
import org.xmlpull.v1.XmlPullParserException;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.text.ParseException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* This class parses generic Atom feeds.
|
||||
*
|
||||
* <p>Given an InputStream representation of a feed, it returns a List of entries,
|
||||
* where each list element represents a single entry (post) in the XML feed.
|
||||
*
|
||||
* <p>An example of an Atom feed can be found at:
|
||||
* http://en.wikipedia.org/w/index.php?title=Atom_(standard)&oldid=560239173#Example_of_an_Atom_1.0_feed
|
||||
*/
|
||||
public class FeedParser {
|
||||
|
||||
// Constants indicting XML element names that we're interested in
|
||||
private static final int TAG_ID = 1;
|
||||
private static final int TAG_TITLE = 2;
|
||||
private static final int TAG_PUBLISHED = 3;
|
||||
private static final int TAG_LINK = 4;
|
||||
|
||||
// We don't use XML namespaces
|
||||
private static final String ns = null;
|
||||
|
||||
/** Parse an Atom feed, returning a collection of Entry objects.
|
||||
*
|
||||
* @param in Atom feed, as a stream.
|
||||
* @return List of {@link com.example.android.basicsyncadapter.net.FeedParser.Entry} objects.
|
||||
* @throws org.xmlpull.v1.XmlPullParserException on error parsing feed.
|
||||
* @throws java.io.IOException on I/O error.
|
||||
*/
|
||||
public List<Entry> parse(InputStream in)
|
||||
throws XmlPullParserException, IOException, ParseException {
|
||||
try {
|
||||
XmlPullParser parser = Xml.newPullParser();
|
||||
parser.setFeature(XmlPullParser.FEATURE_PROCESS_NAMESPACES, false);
|
||||
parser.setInput(in, null);
|
||||
parser.nextTag();
|
||||
return readFeed(parser);
|
||||
} finally {
|
||||
in.close();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Decode a feed attached to an XmlPullParser.
|
||||
*
|
||||
* @param parser Incoming XMl
|
||||
* @return List of {@link com.example.android.basicsyncadapter.net.FeedParser.Entry} objects.
|
||||
* @throws org.xmlpull.v1.XmlPullParserException on error parsing feed.
|
||||
* @throws java.io.IOException on I/O error.
|
||||
*/
|
||||
private List<Entry> readFeed(XmlPullParser parser)
|
||||
throws XmlPullParserException, IOException, ParseException {
|
||||
List<Entry> entries = new ArrayList<Entry>();
|
||||
|
||||
// Search for <feed> tags. These wrap the beginning/end of an Atom document.
|
||||
//
|
||||
// Example:
|
||||
// <?xml version="1.0" encoding="utf-8"?>
|
||||
// <feed xmlns="http://www.w3.org/2005/Atom">
|
||||
// ...
|
||||
// </feed>
|
||||
parser.require(XmlPullParser.START_TAG, ns, "feed");
|
||||
while (parser.next() != XmlPullParser.END_TAG) {
|
||||
if (parser.getEventType() != XmlPullParser.START_TAG) {
|
||||
continue;
|
||||
}
|
||||
String name = parser.getName();
|
||||
// Starts by looking for the <entry> tag. This tag repeates inside of <feed> for each
|
||||
// article in the feed.
|
||||
//
|
||||
// Example:
|
||||
// <entry>
|
||||
// <title>Article title</title>
|
||||
// <link rel="alternate" type="text/html" href="http://example.com/article/1234"/>
|
||||
// <link rel="edit" href="http://example.com/admin/article/1234"/>
|
||||
// <id>urn:uuid:218AC159-7F68-4CC6-873F-22AE6017390D</id>
|
||||
// <published>2003-06-27T12:00:00Z</published>
|
||||
// <updated>2003-06-28T12:00:00Z</updated>
|
||||
// <summary>Article summary goes here.</summary>
|
||||
// <author>
|
||||
// <name>Rick Deckard</name>
|
||||
// <email>deckard@example.com</email>
|
||||
// </author>
|
||||
// </entry>
|
||||
if (name.equals("entry")) {
|
||||
entries.add(readEntry(parser));
|
||||
} else {
|
||||
skip(parser);
|
||||
}
|
||||
}
|
||||
return entries;
|
||||
}
|
||||
|
||||
/**
|
||||
* Parses the contents of an entry. If it encounters a title, summary, or link tag, hands them
|
||||
* off to their respective "read" methods for processing. Otherwise, skips the tag.
|
||||
*/
|
||||
private Entry readEntry(XmlPullParser parser)
|
||||
throws XmlPullParserException, IOException, ParseException {
|
||||
parser.require(XmlPullParser.START_TAG, ns, "entry");
|
||||
String id = null;
|
||||
String title = null;
|
||||
String link = null;
|
||||
long publishedOn = 0;
|
||||
|
||||
while (parser.next() != XmlPullParser.END_TAG) {
|
||||
if (parser.getEventType() != XmlPullParser.START_TAG) {
|
||||
continue;
|
||||
}
|
||||
String name = parser.getName();
|
||||
if (name.equals("id")){
|
||||
// Example: <id>urn:uuid:218AC159-7F68-4CC6-873F-22AE6017390D</id>
|
||||
id = readTag(parser, TAG_ID);
|
||||
} else if (name.equals("title")) {
|
||||
// Example: <title>Article title</title>
|
||||
title = readTag(parser, TAG_TITLE);
|
||||
} else if (name.equals("link")) {
|
||||
// Example: <link rel="alternate" type="text/html" href="http://example.com/article/1234"/>
|
||||
//
|
||||
// Multiple link types can be included. readAlternateLink() will only return
|
||||
// non-null when reading an "alternate"-type link. Ignore other responses.
|
||||
String tempLink = readTag(parser, TAG_LINK);
|
||||
if (tempLink != null) {
|
||||
link = tempLink;
|
||||
}
|
||||
} else if (name.equals("published")) {
|
||||
// Example: <published>2003-06-27T12:00:00Z</published>
|
||||
Time t = new Time();
|
||||
t.parse3339(readTag(parser, TAG_PUBLISHED));
|
||||
publishedOn = t.toMillis(false);
|
||||
} else {
|
||||
skip(parser);
|
||||
}
|
||||
}
|
||||
return new Entry(id, title, link, publishedOn);
|
||||
}
|
||||
|
||||
/**
|
||||
* Process an incoming tag and read the selected value from it.
|
||||
*/
|
||||
private String readTag(XmlPullParser parser, int tagType)
|
||||
throws IOException, XmlPullParserException {
|
||||
String tag = null;
|
||||
String endTag = null;
|
||||
|
||||
switch (tagType) {
|
||||
case TAG_ID:
|
||||
return readBasicTag(parser, "id");
|
||||
case TAG_TITLE:
|
||||
return readBasicTag(parser, "title");
|
||||
case TAG_PUBLISHED:
|
||||
return readBasicTag(parser, "published");
|
||||
case TAG_LINK:
|
||||
return readAlternateLink(parser);
|
||||
default:
|
||||
throw new IllegalArgumentException("Unknown tag type: " + tagType);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Reads the body of a basic XML tag, which is guaranteed not to contain any nested elements.
|
||||
*
|
||||
* <p>You probably want to call readTag().
|
||||
*
|
||||
* @param parser Current parser object
|
||||
* @param tag XML element tag name to parse
|
||||
* @return Body of the specified tag
|
||||
* @throws java.io.IOException
|
||||
* @throws org.xmlpull.v1.XmlPullParserException
|
||||
*/
|
||||
private String readBasicTag(XmlPullParser parser, String tag)
|
||||
throws IOException, XmlPullParserException {
|
||||
parser.require(XmlPullParser.START_TAG, ns, tag);
|
||||
String result = readText(parser);
|
||||
parser.require(XmlPullParser.END_TAG, ns, tag);
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Processes link tags in the feed.
|
||||
*/
|
||||
private String readAlternateLink(XmlPullParser parser)
|
||||
throws IOException, XmlPullParserException {
|
||||
String link = null;
|
||||
parser.require(XmlPullParser.START_TAG, ns, "link");
|
||||
String tag = parser.getName();
|
||||
String relType = parser.getAttributeValue(null, "rel");
|
||||
if (relType.equals("alternate")) {
|
||||
link = parser.getAttributeValue(null, "href");
|
||||
}
|
||||
while (true) {
|
||||
if (parser.nextTag() == XmlPullParser.END_TAG) break;
|
||||
// Intentionally break; consumes any remaining sub-tags.
|
||||
}
|
||||
return link;
|
||||
}
|
||||
|
||||
/**
|
||||
* For the tags title and summary, extracts their text values.
|
||||
*/
|
||||
private String readText(XmlPullParser parser) throws IOException, XmlPullParserException {
|
||||
String result = null;
|
||||
if (parser.next() == XmlPullParser.TEXT) {
|
||||
result = parser.getText();
|
||||
parser.nextTag();
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Skips tags the parser isn't interested in. Uses depth to handle nested tags. i.e.,
|
||||
* if the next tag after a START_TAG isn't a matching END_TAG, it keeps going until it
|
||||
* finds the matching END_TAG (as indicated by the value of "depth" being 0).
|
||||
*/
|
||||
private void skip(XmlPullParser parser) throws XmlPullParserException, IOException {
|
||||
if (parser.getEventType() != XmlPullParser.START_TAG) {
|
||||
throw new IllegalStateException();
|
||||
}
|
||||
int depth = 1;
|
||||
while (depth != 0) {
|
||||
switch (parser.next()) {
|
||||
case XmlPullParser.END_TAG:
|
||||
depth--;
|
||||
break;
|
||||
case XmlPullParser.START_TAG:
|
||||
depth++;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* This class represents a single entry (post) in the XML feed.
|
||||
*
|
||||
* <p>It includes the data members "title," "link," and "summary."
|
||||
*/
|
||||
public static class Entry {
|
||||
public final String id;
|
||||
public final String title;
|
||||
public final String link;
|
||||
public final long published;
|
||||
|
||||
Entry(String id, String title, String link, long published) {
|
||||
this.id = id;
|
||||
this.title = title;
|
||||
this.link = link;
|
||||
this.published = published;
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user