summaryrefslogtreecommitdiff
path: root/src/de/danoeh/antennapod/syndication/handler
diff options
context:
space:
mode:
authordaniel oeh <daniel.oeh@gmail.com>2012-07-13 12:23:47 +0200
committerdaniel oeh <daniel.oeh@gmail.com>2012-07-13 12:23:47 +0200
commitba2d2afbbc6cbb79fc75493703425b5d6d040530 (patch)
treee731a1209160e8224679cb238c0a964c3e757590 /src/de/danoeh/antennapod/syndication/handler
parent1ae00a0f2531fdb05a44877dda88ee2300e3ffec (diff)
downloadAntennaPod-ba2d2afbbc6cbb79fc75493703425b5d6d040530.zip
Renamed package and application
Diffstat (limited to 'src/de/danoeh/antennapod/syndication/handler')
-rw-r--r--src/de/danoeh/antennapod/syndication/handler/FeedHandler.java29
-rw-r--r--src/de/danoeh/antennapod/syndication/handler/HandlerState.java69
-rw-r--r--src/de/danoeh/antennapod/syndication/handler/SyndHandler.java112
-rw-r--r--src/de/danoeh/antennapod/syndication/handler/TypeGetter.java76
-rw-r--r--src/de/danoeh/antennapod/syndication/handler/UnsupportedFeedtypeException.java29
5 files changed, 315 insertions, 0 deletions
diff --git a/src/de/danoeh/antennapod/syndication/handler/FeedHandler.java b/src/de/danoeh/antennapod/syndication/handler/FeedHandler.java
new file mode 100644
index 000000000..dfcfcf98d
--- /dev/null
+++ b/src/de/danoeh/antennapod/syndication/handler/FeedHandler.java
@@ -0,0 +1,29 @@
+package de.danoeh.antennapod.syndication.handler;
+
+import java.io.File;
+import java.io.IOException;
+
+import javax.xml.parsers.ParserConfigurationException;
+import javax.xml.parsers.SAXParser;
+import javax.xml.parsers.SAXParserFactory;
+
+import org.xml.sax.SAXException;
+
+import de.danoeh.antennapod.feed.Feed;
+
+public class FeedHandler {
+
+ public Feed parseFeed(Feed feed) throws SAXException, IOException,
+ ParserConfigurationException, UnsupportedFeedtypeException {
+ TypeGetter tg = new TypeGetter();
+ TypeGetter.Type type = tg.getType(feed);
+ SyndHandler handler = new SyndHandler(feed, type);
+
+ SAXParserFactory factory = SAXParserFactory.newInstance();
+ factory.setNamespaceAware(true);
+ SAXParser saxParser = factory.newSAXParser();
+ saxParser.parse(new File(feed.getFile_url()), handler);
+
+ return handler.state.feed;
+ }
+}
diff --git a/src/de/danoeh/antennapod/syndication/handler/HandlerState.java b/src/de/danoeh/antennapod/syndication/handler/HandlerState.java
new file mode 100644
index 000000000..1d81d0fb1
--- /dev/null
+++ b/src/de/danoeh/antennapod/syndication/handler/HandlerState.java
@@ -0,0 +1,69 @@
+package de.danoeh.antennapod.syndication.handler;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.Stack;
+
+import de.danoeh.antennapod.feed.Feed;
+import de.danoeh.antennapod.feed.FeedItem;
+import de.danoeh.antennapod.syndication.namespace.Namespace;
+import de.danoeh.antennapod.syndication.namespace.SyndElement;
+
+/** Contains all relevant information to describe the current state of a SyndHandler.*/
+public class HandlerState {
+
+ /** Feed that the Handler is currently processing. */
+ protected Feed feed;
+ protected FeedItem currentItem;
+ protected Stack<SyndElement> tagstack;
+ /** Namespaces that have been defined so far. */
+ protected HashMap<String, Namespace> namespaces;
+ protected Stack<Namespace> defaultNamespaces;
+ /** Buffer for saving characters. */
+ protected StringBuffer contentBuf;
+
+ public HandlerState(Feed feed) {
+ this.feed = feed;
+ tagstack = new Stack<SyndElement>();
+ namespaces = new HashMap<String, Namespace>();
+ defaultNamespaces = new Stack<Namespace>();
+ }
+
+
+ public Feed getFeed() {
+ return feed;
+ }
+ public FeedItem getCurrentItem() {
+ return currentItem;
+ }
+ public Stack<SyndElement> getTagstack() {
+ return tagstack;
+ }
+
+
+ public void setFeed(Feed feed) {
+ this.feed = feed;
+ }
+
+
+ public void setCurrentItem(FeedItem currentItem) {
+ this.currentItem = currentItem;
+ }
+
+ /** Returns the SyndElement that comes after the top element of the tagstack. */
+ public SyndElement getSecondTag() {
+ SyndElement top = tagstack.pop();
+ SyndElement second = tagstack.peek();
+ tagstack.push(top);
+ return second;
+ }
+
+ public StringBuffer getContentBuf() {
+ return contentBuf;
+ }
+
+
+
+
+
+}
diff --git a/src/de/danoeh/antennapod/syndication/handler/SyndHandler.java b/src/de/danoeh/antennapod/syndication/handler/SyndHandler.java
new file mode 100644
index 000000000..396f170c5
--- /dev/null
+++ b/src/de/danoeh/antennapod/syndication/handler/SyndHandler.java
@@ -0,0 +1,112 @@
+package de.danoeh.antennapod.syndication.handler;
+
+import org.xml.sax.Attributes;
+import org.xml.sax.SAXException;
+import org.xml.sax.helpers.DefaultHandler;
+
+import android.util.Log;
+
+import de.danoeh.antennapod.feed.Feed;
+import de.danoeh.antennapod.syndication.namespace.Namespace;
+import de.danoeh.antennapod.syndication.namespace.SyndElement;
+import de.danoeh.antennapod.syndication.namespace.atom.NSAtom;
+import de.danoeh.antennapod.syndication.namespace.content.NSContent;
+import de.danoeh.antennapod.syndication.namespace.itunes.NSITunes;
+import de.danoeh.antennapod.syndication.namespace.rss20.NSRSS20;
+import de.danoeh.antennapod.syndication.namespace.simplechapters.NSSimpleChapters;
+
+/** Superclass for all SAX Handlers which process Syndication formats */
+public class SyndHandler extends DefaultHandler {
+ private static final String TAG = "SyndHandler";
+ private static final String DEFAULT_PREFIX = "";
+ protected HandlerState state;
+
+
+ public SyndHandler(Feed feed, TypeGetter.Type type) {
+ state = new HandlerState(feed);
+ if (type == TypeGetter.Type.RSS20) {
+ state.defaultNamespaces.push(new NSRSS20());
+ }
+ }
+
+ @Override
+ public void startElement(String uri, String localName, String qName,
+ Attributes attributes) throws SAXException {
+ state.contentBuf = new StringBuffer();
+ Namespace handler = getHandlingNamespace(uri);
+ if (handler != null) {
+ SyndElement element = handler.handleElementStart(localName, state,
+ attributes);
+ state.tagstack.push(element);
+
+ }
+ }
+
+ @Override
+ public void characters(char[] ch, int start, int length)
+ throws SAXException {
+ if (!state.tagstack.empty()) {
+ if (state.getTagstack().size() >= 2) {
+ if (state.contentBuf != null) {
+ String content = new String(ch, start, length);
+ state.contentBuf.append(content);
+ }
+ }
+ }
+ }
+
+ @Override
+ public void endElement(String uri, String localName, String qName)
+ throws SAXException {
+ Namespace handler = getHandlingNamespace(uri);
+ if (handler != null) {
+ handler.handleElementEnd(localName, state);
+ state.tagstack.pop();
+
+ }
+ state.contentBuf = null;
+
+ }
+
+ @Override
+ public void endPrefixMapping(String prefix) throws SAXException {
+ // TODO remove Namespace
+ }
+
+ @Override
+ public void startPrefixMapping(String prefix, String uri)
+ throws SAXException {
+ // Find the right namespace
+ if (uri.equals(NSAtom.NSURI)) {
+ if (prefix.equals(DEFAULT_PREFIX)) {
+ state.defaultNamespaces.push(new NSAtom());
+ } else if (prefix.equals(NSAtom.NSTAG)) {
+ state.namespaces.put(uri, new NSAtom());
+ Log.d(TAG, "Recognized Atom namespace");
+ }
+ } else if (uri.equals(NSContent.NSURI) && prefix.equals(NSContent.NSTAG)) {
+ state.namespaces.put(uri, new NSContent());
+ Log.d(TAG, "Recognized Content namespace");
+ } else if (uri.equals(NSITunes.NSURI) && prefix.equals(NSITunes.NSTAG)) {
+ state.namespaces.put(uri, new NSITunes());
+ Log.d(TAG, "Recognized ITunes namespace");
+ } else if (uri.equals(NSSimpleChapters.NSURI) && prefix.equals(NSSimpleChapters.NSTAG)) {
+ state.namespaces.put(uri, new NSSimpleChapters());
+ Log.d(TAG, "Recognized SimpleChapters namespace");
+ }
+ }
+
+ private Namespace getHandlingNamespace(String uri) {
+ Namespace handler = state.namespaces.get(uri);
+ if (handler == null && uri.equals(DEFAULT_PREFIX)
+ && !state.defaultNamespaces.empty()) {
+ handler = state.defaultNamespaces.peek();
+ }
+ return handler;
+ }
+
+ public HandlerState getState() {
+ return state;
+ }
+
+}
diff --git a/src/de/danoeh/antennapod/syndication/handler/TypeGetter.java b/src/de/danoeh/antennapod/syndication/handler/TypeGetter.java
new file mode 100644
index 000000000..7e346ca5c
--- /dev/null
+++ b/src/de/danoeh/antennapod/syndication/handler/TypeGetter.java
@@ -0,0 +1,76 @@
+package de.danoeh.antennapod.syndication.handler;
+
+import java.io.File;
+import java.io.FileNotFoundException;
+import java.io.FileReader;
+import java.io.IOException;
+import java.io.Reader;
+
+import org.xmlpull.v1.XmlPullParser;
+import org.xmlpull.v1.XmlPullParserException;
+import org.xmlpull.v1.XmlPullParserFactory;
+
+import android.util.Log;
+
+import de.danoeh.antennapod.feed.Feed;
+
+/** Gets the type of a specific feed by reading the root element. */
+public class TypeGetter {
+ private static final String TAG = "TypeGetter";
+
+ enum Type {
+ RSS20, ATOM, INVALID
+ }
+
+ private static final String ATOM_ROOT = "feed";
+ private static final String RSS_ROOT = "rss";
+
+ public Type getType(Feed feed) throws UnsupportedFeedtypeException {
+ XmlPullParserFactory factory;
+ try {
+ factory = XmlPullParserFactory.newInstance();
+ factory.setNamespaceAware(true);
+ XmlPullParser xpp = factory.newPullParser();
+ xpp.setInput(createReader(feed));
+ int eventType = xpp.getEventType();
+
+ while (eventType != XmlPullParser.END_DOCUMENT) {
+ if (eventType == XmlPullParser.START_TAG) {
+ String tag = xpp.getName();
+ if (tag.equals(ATOM_ROOT)) {
+ Log.d(TAG, "Recognized type Atom");
+ return Type.ATOM;
+ } else if (tag.equals(RSS_ROOT)
+ && (xpp.getAttributeValue(null, "version")
+ .equals("2.0"))) {
+ Log.d(TAG, "Recognized type RSS 2.0");
+ return Type.RSS20;
+ } else {
+ Log.d(TAG, "Type is invalid");
+ throw new UnsupportedFeedtypeException(Type.INVALID);
+ }
+ } else {
+ eventType = xpp.next();
+ }
+ }
+
+ } catch (XmlPullParserException e) {
+ e.printStackTrace();
+ } catch (IOException e) {
+ e.printStackTrace();
+ }
+ Log.d(TAG, "Type is invalid");
+ throw new UnsupportedFeedtypeException(Type.INVALID);
+ }
+
+ private Reader createReader(Feed feed) {
+ FileReader reader;
+ try {
+ reader = new FileReader(new File(feed.getFile_url()));
+ } catch (FileNotFoundException e) {
+ e.printStackTrace();
+ return null;
+ }
+ return reader;
+ }
+}
diff --git a/src/de/danoeh/antennapod/syndication/handler/UnsupportedFeedtypeException.java b/src/de/danoeh/antennapod/syndication/handler/UnsupportedFeedtypeException.java
new file mode 100644
index 000000000..67fbc9cc9
--- /dev/null
+++ b/src/de/danoeh/antennapod/syndication/handler/UnsupportedFeedtypeException.java
@@ -0,0 +1,29 @@
+package de.danoeh.antennapod.syndication.handler;
+
+import de.danoeh.antennapod.syndication.handler.TypeGetter.Type;
+
+public class UnsupportedFeedtypeException extends Exception {
+ private static final long serialVersionUID = 9105878964928170669L;
+ private TypeGetter.Type type;
+
+ public UnsupportedFeedtypeException(Type type) {
+ super();
+ this.type = type;
+
+ }
+
+ public TypeGetter.Type getType() {
+ return type;
+ }
+
+ @Override
+ public String getMessage() {
+ if (type == TypeGetter.Type.INVALID) {
+ return "Invalid type";
+ } else {
+ return "Type " + type + " not supported";
+ }
+ }
+
+
+}