diff options
author | daniel oeh <daniel.oeh@gmail.com> | 2012-07-13 12:23:47 +0200 |
---|---|---|
committer | daniel oeh <daniel.oeh@gmail.com> | 2012-07-13 12:23:47 +0200 |
commit | ba2d2afbbc6cbb79fc75493703425b5d6d040530 (patch) | |
tree | e731a1209160e8224679cb238c0a964c3e757590 /src/de/danoeh/antennapod/syndication/handler | |
parent | 1ae00a0f2531fdb05a44877dda88ee2300e3ffec (diff) | |
download | AntennaPod-ba2d2afbbc6cbb79fc75493703425b5d6d040530.zip |
Renamed package and application
Diffstat (limited to 'src/de/danoeh/antennapod/syndication/handler')
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"; + } + } + + +} |