Android Open Source - piRSS Feed Handler






From Project

Back to project page piRSS.

License

The source code is released under:

GNU General Public License

If you think the Android project piRSS listed in this page is inappropriate, such as containing malicious code/tools or violating the copyright, please email info at java2s dot com, thanks.

Java Source Code

/**
 * Copyright (C) 2011 Matthias Jordan <matthias.jordan@googlemail.com>
 */*from  ww w.  jav  a  2s. c o  m*/
 * This file is part of piRSS.
 *
 * piRSS 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.
 *
 * piRSS 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 piRSS.  If not, see <http://www.gnu.org/licenses/>.
 */
package de.codefu.android.rss.updateservice;

import java.text.ParseException;
import java.util.Stack;
import java.util.TimeZone;

import org.xml.sax.Attributes;
import org.xml.sax.SAXException;
import org.xml.sax.helpers.DefaultHandler;

import de.codefu.android.rss.updateservice.FeedHandlerClient.Item;



/**
 * SAX parser for RSS feeds.
 * 
 * @author mj
 */
class FeedHandler extends DefaultHandler {

    private static final String E_ENTRY = "entry";

    private static final String E_PUB_DATE = "pubDate";

    private static final String E_GUID = "guid";

    private static final String E_ITEM = "item";

    private static final String E_DESCRIPTION = "description";

    private static final String E_LINK = "link";

    private static final String E_TITLE = "title";

    private static final String E_SUBTITLE = "subtitle";

    private static final String E_ID = "id";

    private Stack<String> elements;

    private String channelTitle;
    private String channelLink;
    private String channelDescription;

    private Item item;

    private FeedHandlerClient fhc;

    private String collectAllUntilEndTag;
    private StringBuilder collector;

    private boolean errorOccurred;

    private long feedId;
    private int cleanHtml;

    private TimeZone timezone;


    public FeedHandler(final long feedId, int cleanHtml, FeedHandlerClient fhc, TimeZone tz) {
        this.feedId = feedId;
        this.cleanHtml = cleanHtml;
        this.fhc = fhc;
        this.elements = new Stack<String>();
        this.errorOccurred = false;
        this.timezone = tz;
    }


    public String getChannelLink() {
        return channelLink;
    }


    public String getChannelTitle() {
        return channelTitle;
    }


    @Override
    public void startElement(String uri, String localName, String qName, Attributes attributes) throws SAXException {
        if (isCollectorConsuming(localName)) {
            collector.append('<').append(localName).append('>');
        }
        else if ((elements.size() == 0)) {
            if (E_TITLE.equals(localName) && (channelTitle == null)) {
                elements.push(E_TITLE);
                startCollecting(E_TITLE);
            }
            else if (E_LINK.equals(localName) && (channelLink == null)) {
                final String href = attributes.getValue("href");
                final String rel = attributes.getValue("rel");
                if ((channelLink == null) && (href != null) && (!"self".equals(rel))) {
                    channelLink = href;
                }
                else {
                    elements.push(E_LINK);
                    startCollecting(E_LINK);
                }
            }
            else if ((E_DESCRIPTION.equals(localName) || E_SUBTITLE.equals(localName)) && (channelDescription == null)) {
                elements.push(localName);
                startCollecting(localName);
            }
            else if (E_ITEM.equals(localName) || E_ENTRY.equals(localName)) {
                elements.push(localName);
                item = new Item();
                final String about = attributes.getValue("http://www.w3.org/1999/02/22-rdf-syntax-ns#", "about");
                if (about != null) {
                    item.guid = about;
                }
            }
        }
        else if ((elements.size() == 1) && (E_ITEM.equals(elements.peek()) || E_ENTRY.equals(elements.peek()))) {
            if (E_TITLE.equals(localName)) {
                elements.push(E_TITLE);
                startCollecting(E_TITLE);
            }
            else if (E_LINK.equals(localName)) {
                final String href = attributes.getValue("href");
                final String rel = attributes.getValue("rel");
                if ((item.link == null) && (href != null) && (!"self".equals(rel))) {
                    item.link = href;
                }
                else {
                    elements.push(E_LINK);
                    startCollecting(E_LINK);
                }
            }
            else if (E_DESCRIPTION.equals(localName)) {
                elements.push(E_DESCRIPTION);
                startCollecting(E_DESCRIPTION);
            }
            else if (E_GUID.equals(localName) || E_ID.equals(localName)) {
                elements.push(localName);
                startCollecting(localName);
            }
            else if (E_PUB_DATE.equals(localName) || "published".equals(localName) || "date".equals(localName)) {
                elements.push(localName);
                startCollecting(localName);
            }
        }
    }


    @Override
    public void characters(char[] ch, int start, int length) throws SAXException {
        if (collector != null) {
            collector.append(new String(ch, start, length));
        }
        else if (elements.size() == 1) {
            if (E_TITLE.equals(elements.peek()) && (channelTitle == null)) {
                channelTitle = new String(ch, start, length).trim();
            }
            else if (E_DESCRIPTION.equals(elements.peek()) && (channelDescription == null)) {
                channelDescription = new String(ch, start, length).trim();
            }
            else if (E_LINK.equals(elements.peek()) && (channelLink == null)) {
                channelLink = new String(ch, start, length).trim();
            }
        }
        else if (elements.size() == 2) {
            if (E_TITLE.equals(elements.peek())) {
                if (item != null) {
                    item.headline = new String(ch, start, length).trim();
                }
            }
            else if (E_DESCRIPTION.equals(elements.peek())) {
                if (item != null) {
                    item.content = new String(ch, start, length).trim();
                }
            }
            else if (E_GUID.equals(elements.peek()) || E_ID.equals(elements.peek())) {
                if (item != null) {
                    item.guid = new String(ch, start, length).trim();
                }
            }
            else if (E_LINK.equals(elements.peek())) {
                if (item != null) {
                    item.link = new String(ch, start, length).trim();
                }
            }
            else if (E_PUB_DATE.equals(elements.peek())) {
                if (item != null) {
                    try {
                        item.date = DateFormat3339.parse(new String(ch, start, length), timezone);
                    }
                    catch (ParseException e) {
                    }
                }
            }
        }
    }


    @Override
    public void endElement(String uri, String localName, String qName) throws SAXException {
        if (isCollectorConsuming(localName)) {
            collector.append("</").append(localName).append('>');
        }
        else {
            if ((elements.size() != 0) && elements.peek().equals(localName)) {
                elements.pop();
                if ((elements.size() == 0)) {
                    if (E_TITLE.equals(localName)) {
                        channelTitle = endCollecting();
                    }
                    else if (E_LINK.equals(localName)) {
                        channelLink = endCollecting();
                    }
                    else if (E_DESCRIPTION.equals(localName) || E_SUBTITLE.equals(localName)) {
                        channelDescription = endCollecting();
                    }
                    else if (E_ITEM.equals(localName) || E_ENTRY.equals(localName)) {
                        fhc.addItem(feedId, cleanHtml, item);
                        item = null;
                    }
                }
                else if ((elements.size() == 1) && (E_ITEM.equals(elements.peek())) || E_ENTRY.equals(elements.peek())) {
                    if (E_TITLE.equals(localName)) {
                        if (item != null) {
                            item.headline = endCollecting();
                        }
                    }
                    else if (E_LINK.equals(localName)) {
                        if (item != null) {
                            item.link = endCollecting();
                        }
                    }
                    else if (E_DESCRIPTION.equals(localName)) {
                        if (item != null) {
                            item.content = endCollecting();
                        }
                    }
                    else if (E_GUID.equals(localName) || E_ID.equals(localName)) {
                        if (item != null) {
                            item.guid = endCollecting();
                        }
                    }
                    else if (E_PUB_DATE.equals(localName) || "published".equals(localName) || "date".equals(localName)) {
                        if (item != null) {
                            try {
                                item.date = DateFormat3339.parse(endCollecting(), timezone);
                            }
                            catch (ParseException e) {
                            }
                        }
                    }
                }
            }
        }
    }


    @Override
    public void endDocument() throws SAXException {
        fhc.updateFeed(feedId, channelTitle, channelDescription, channelLink);
    }


    private void startCollecting(String tag) {
        collectAllUntilEndTag = tag;
        collector = new StringBuilder();
    }


    private boolean isCollectorConsuming(String tag) {
        return (collectAllUntilEndTag != null) && (!collectAllUntilEndTag.equals(tag));
    }


    private String endCollecting() {
        if (collectAllUntilEndTag != null) {
            final String out = collector.toString().trim();
            collectAllUntilEndTag = null;
            collector = null;
            return out;
        }
        return null;
    }


    public boolean hasErrorOccurred() {
        return errorOccurred;
    }
}




Java Source Code List

de.codefu.android.rss.AboutActivity.java
de.codefu.android.rss.BootCompletedHandler.java
de.codefu.android.rss.CursorChangedReceiver.java
de.codefu.android.rss.MainPreferences.java
de.codefu.android.rss.UserNotification.java
de.codefu.android.rss.db.DB.java
de.codefu.android.rss.db.FeedProvider.java
de.codefu.android.rss.db.ItemHelper.java
de.codefu.android.rss.db.ItemProvider.java
de.codefu.android.rss.db.UriHelper.java
de.codefu.android.rss.feedlist.FeedListAdapter.java
de.codefu.android.rss.feedlist.FeedList.java
de.codefu.android.rss.feedprops.AddFeed.java
de.codefu.android.rss.feedprops.FeedProps.java
de.codefu.android.rss.item.ItemAct.java
de.codefu.android.rss.itemlist.ItemListAdapter.java
de.codefu.android.rss.itemlist.ItemList.java
de.codefu.android.rss.updateservice.AutoPollService.java
de.codefu.android.rss.updateservice.DateFormat3339.java
de.codefu.android.rss.updateservice.FeedHandlerClient.java
de.codefu.android.rss.updateservice.FeedHandler.java
de.codefu.android.rss.updateservice.InsertService.java
de.codefu.android.rss.updateservice.ServiceComm.java
de.codefu.android.rss.updateservice.UpdateService.java
de.codefu.android.rss.updateservice.UrlHttpRetriever.java
de.codefu.android.rss.updateservice.Utils.java
de.codefu.android.rss.updateservice.WakeLockHolder.java
de.codefu.android.rss.widgets.SimpleWidget.java