diff options
Diffstat (limited to 'src/de/podfetcher/syndication/handler')
5 files changed, 293 insertions, 0 deletions
diff --git a/src/de/podfetcher/syndication/handler/FeedHandler.java b/src/de/podfetcher/syndication/handler/FeedHandler.java new file mode 100644 index 000000000..46fe4399c --- /dev/null +++ b/src/de/podfetcher/syndication/handler/FeedHandler.java @@ -0,0 +1,47 @@ +package de.podfetcher.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.podfetcher.feed.Feed; + +public class FeedHandler { + public final static String CHANNEL = "channel"; + public final static String ITEM = "item"; + public final static String TITLE = "title"; + public final static String LINK = "link"; + public final static String DESCR = "description"; + public final static String PUBDATE = "pubDate"; + public final static String ENCLOSURE = "enclosure"; + public final static String IMAGE = "image"; + public final static String URL = "url"; + + public final static String ENC_URL = "url"; + public final static String ENC_LEN = "length"; + public final static String ENC_TYPE = "type"; + + public Feed parseFeed(Feed feed) { + TypeGetter tg = new TypeGetter(); + tg.getType(feed); + RSSHandler handler = new RSSHandler(feed); + try { + SAXParserFactory factory = SAXParserFactory.newInstance(); + SAXParser saxParser = factory.newSAXParser(); + saxParser.parse(new File(feed.getFile_url()), handler); + } catch (SAXException e) { + e.printStackTrace(); + } catch (IOException e) { + e.printStackTrace(); + } catch(ParserConfigurationException e) { + e.printStackTrace(); + } + + return handler.feed; + } +} diff --git a/src/de/podfetcher/syndication/handler/HandlerState.java b/src/de/podfetcher/syndication/handler/HandlerState.java new file mode 100644 index 000000000..7e0c07585 --- /dev/null +++ b/src/de/podfetcher/syndication/handler/HandlerState.java @@ -0,0 +1,30 @@ +package de.podfetcher.syndication.handler; + +import java.util.ArrayList; +import java.util.Stack; + +import de.podfetcher.syndication.namespace.Namespace; +import de.podfetcher.feed.Feed; +import de.podfetcher.feed.FeedItem; + +/** 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<String> tagstack; + /** Namespaces that have been defined so far. */ + protected ArrayList<Namespace> namespaces; + + public Feed getFeed() { + return feed; + } + public FeedItem getCurrentItem() { + return currentItem; + } + public Stack<String> getTagstack() { + return tagstack; + } + + +} diff --git a/src/de/podfetcher/syndication/handler/RSSHandler.java b/src/de/podfetcher/syndication/handler/RSSHandler.java new file mode 100644 index 000000000..279cfca63 --- /dev/null +++ b/src/de/podfetcher/syndication/handler/RSSHandler.java @@ -0,0 +1,127 @@ +package de.podfetcher.syndication.handler; + +import java.util.ArrayList; + +import de.podfetcher.feed.Feed; +import de.podfetcher.feed.FeedImage; +import de.podfetcher.feed.FeedItem; +import de.podfetcher.feed.FeedMedia; + +import org.xml.sax.Attributes; +import org.xml.sax.SAXException; +import org.xml.sax.helpers.DefaultHandler; + +/** + * SAX-Parser for reading RSS-Feeds + * + * @author daniel + * + */ +public class RSSHandler extends DefaultHandler { + public ArrayList<FeedItem> items; + public FeedItem currentItem; + public StringBuilder strBuilder; + public Feed feed; + public String active_root_element; // channel or item or image + public String active_sub_element; // Not channel or item + + public RSSHandler(Feed f) { + super(); + this.feed = f; + } + + @Override + public void characters(char[] ch, int start, int length) + throws SAXException { + if (active_sub_element != null) { + strBuilder.append(ch, start, length); + } + } + + @Override + public void endDocument() throws SAXException { + feed.setItems(items); + } + + @Override + public void endElement(String uri, String localName, String qName) + throws SAXException { + if (qName.equalsIgnoreCase(FeedHandler.ITEM)) { + currentItem.setFeed(feed); + items.add(currentItem); + } else if (qName.equalsIgnoreCase(FeedHandler.TITLE)) { + if (active_root_element.equalsIgnoreCase(FeedHandler.CHANNEL)) { + feed.setTitle(strBuilder.toString()); + } else if(active_root_element.equalsIgnoreCase(FeedHandler.ITEM)) { + currentItem.setTitle(strBuilder.toString()); + } else if(active_root_element.equalsIgnoreCase(FeedHandler.IMAGE)) { + feed.getImage().setTitle(strBuilder.toString()); + } + } else if (qName.equalsIgnoreCase(FeedHandler.DESCR)) { + if (active_root_element.equalsIgnoreCase(FeedHandler.CHANNEL)) { + feed.setDescription(strBuilder.toString()); + } else { + currentItem.setDescription(strBuilder.toString()); + } + } else if (qName.equalsIgnoreCase(FeedHandler.LINK)) { + if (active_root_element.equalsIgnoreCase(FeedHandler.CHANNEL)) { + feed.setLink(strBuilder.toString()); + } else if(active_root_element.equalsIgnoreCase(FeedHandler.ITEM)){ + currentItem.setLink(strBuilder.toString()); + } + } else if (qName.equalsIgnoreCase(FeedHandler.PUBDATE)) { + if (active_root_element.equalsIgnoreCase(FeedHandler.ITEM)) { + currentItem.setPubDate(strBuilder.toString()); + } + } else if (qName.equalsIgnoreCase(FeedHandler.URL)) { + if(active_root_element.equalsIgnoreCase(FeedHandler.IMAGE)) { + feed.getImage().setDownload_url(strBuilder.toString()); + } + } else if(qName.equalsIgnoreCase(FeedHandler.IMAGE)) { + active_root_element = FeedHandler.CHANNEL; + } + active_sub_element = null; + strBuilder = new StringBuilder(); + } + + @Override + public void startDocument() throws SAXException { + items = new ArrayList<FeedItem>(); + strBuilder = new StringBuilder(); + + } + + @Override + public void startElement(String uri, String localName, String qName, + Attributes attributes) throws SAXException { + if (qName.equalsIgnoreCase(FeedHandler.CHANNEL)) { + if(feed == null) { + feed = new Feed(); + } + active_root_element = qName; + } else if (qName.equalsIgnoreCase(FeedHandler.ITEM)) { + currentItem = new FeedItem(); + active_root_element = qName; + } else if (qName.equalsIgnoreCase(FeedHandler.TITLE)) { + active_sub_element = qName; + } else if (qName.equalsIgnoreCase(FeedHandler.DESCR)) { + active_sub_element = qName; + } else if (qName.equalsIgnoreCase(FeedHandler.LINK)) { + active_sub_element = qName; + } else if (qName.equalsIgnoreCase(FeedHandler.PUBDATE)) { + active_sub_element = qName; + } else if (qName.equalsIgnoreCase(FeedHandler.ENCLOSURE)) { + currentItem.setMedia(new FeedMedia(currentItem, + attributes.getValue(FeedHandler.ENC_URL), + Long.parseLong(attributes.getValue(FeedHandler.ENC_LEN)), + attributes.getValue(FeedHandler.ENC_TYPE))); + } else if(qName.equalsIgnoreCase(FeedHandler.IMAGE)) { + feed.setImage(new FeedImage()); + active_root_element = qName; + } else if(qName.equalsIgnoreCase(FeedHandler.URL)) { + active_sub_element = qName; + } + + } + +} diff --git a/src/de/podfetcher/syndication/handler/SyndHandler.java b/src/de/podfetcher/syndication/handler/SyndHandler.java new file mode 100644 index 000000000..5f20a2b87 --- /dev/null +++ b/src/de/podfetcher/syndication/handler/SyndHandler.java @@ -0,0 +1,16 @@ +package de.podfetcher.syndication.handler; + +import org.xml.sax.helpers.DefaultHandler; + +import de.podfetcher.feed.Feed; +import de.podfetcher.feed.FeedItem; + +/** Superclass for all SAX Handlers which process Syndication formats */ +public abstract class SyndHandler extends DefaultHandler{ + protected HandlerState state; + + public HandlerState getState() { + return state; + } + +} diff --git a/src/de/podfetcher/syndication/handler/TypeGetter.java b/src/de/podfetcher/syndication/handler/TypeGetter.java new file mode 100644 index 000000000..9dab56af8 --- /dev/null +++ b/src/de/podfetcher/syndication/handler/TypeGetter.java @@ -0,0 +1,73 @@ +package de.podfetcher.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.podfetcher.feed.Feed; + +/** Gets the type of a specific feed. */ +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) { + 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, "Recongnized 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 { + return Type.INVALID; + } + } else { + eventType = xpp.next(); + } + } + + } catch (XmlPullParserException e) { + e.printStackTrace(); + } catch (IOException e) { + e.printStackTrace(); + } + return 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; + } +} |