/* * ____.____ __.____ ___ _____ * | | |/ _| | \ / _ \ ______ ______ * | | < | | / / /_\ \\____ \\____ \ * /\__| | | \| | / / | \ |_> > |_> > * \________|____|__ \______/ \____|__ / __/| __/ * \/ \/|__| |__| * * Copyright (c) 2014-2015 Paul "Marunjar" Pretsch * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see <http://www.gnu.org/licenses/> * */ package org.voidsink.anewjkuapp.rss.lib; import android.util.Log; import org.xmlpull.v1.XmlPullParser; import org.xmlpull.v1.XmlPullParserException; import org.xmlpull.v1.XmlPullParserFactory; import java.io.BufferedInputStream; import java.io.ByteArrayInputStream; import java.io.IOException; import java.io.InputStream; import java.net.HttpURLConnection; import java.net.URL; import java.util.List; import java.util.Stack; public class FeedPullParser implements FeedParser { private final XmlPullParser mXmlParser; public FeedPullParser() { // Initialize XmlPullParser object with a common configuration XmlPullParser parser = null; try { XmlPullParserFactory factory = XmlPullParserFactory.newInstance(); factory.setNamespaceAware(false); parser = factory.newPullParser(); } catch (XmlPullParserException e) { Log.e(getClass().getSimpleName(), "ctor failed", e); } mXmlParser = parser; } @Override public List<FeedEntry> parse(URL url) { try { HttpURLConnection connection = (HttpURLConnection) url.openConnection(); try { connection.setRequestProperty("Cache-Control", "public, max-age=" + 7200); connection.setConnectTimeout(3000); connection.setReadTimeout(3000); return parse(new BufferedInputStream(connection.getInputStream())); } finally { connection.disconnect(); } } catch (IOException e) { Log.e(getClass().getSimpleName(), "parse failed", e); return null; } } @Override public List<FeedEntry> parse(String xml) { return parse(new ByteArrayInputStream(xml.getBytes())); } @Override public synchronized List<FeedEntry> parse(InputStream is) { List<FeedEntry> entries; final Stack<PullParserElement> mParseItems = new Stack<>(); PullParserHandler handler = new RssHandler(); handler.start(); try { mXmlParser.setInput(is, null); int eventType = mXmlParser.getEventType(); while (eventType != XmlPullParser.END_DOCUMENT) { try { final String mTag = mXmlParser.getName(); PullParserElement p = null; switch (eventType) { case XmlPullParser.START_DOCUMENT: handler.processStartDocument(mTag, mXmlParser); break; case XmlPullParser.END_DOCUMENT: handler.processEndDocument(mTag, mXmlParser); break; case XmlPullParser.START_TAG: p = handler.createElement(mTag, mXmlParser); if (p != null) { mParseItems.push(p); } else if (!mParseItems.empty()) { p = mParseItems.peek(); } if (p != null) { p.processStartElement(mTag, mXmlParser); } break; case XmlPullParser.END_TAG: if (!mParseItems.empty()) { p = mParseItems.peek(); } if (p != null) { p.processEndElement(mTag, mXmlParser); if (mTag.equalsIgnoreCase(p.getTag())) { handler.finishElement(mTag, p); mParseItems.pop(); } } break; case XmlPullParser.TEXT: if (!mParseItems.empty()) { p = mParseItems.peek(); } if (p != null) { p.processText(mTag, mXmlParser); } break; } } catch (IOException | XmlPullParserException e) { Log.e(getClass().getSimpleName(), "parse element failed", e); } eventType = mXmlParser.next(); } handler.finish(); entries = handler.getFeedEntries(); } catch (XmlPullParserException | IOException e) { Log.e(getClass().getSimpleName(), "parse next failed", e); entries = null; } return entries; } }