Package com.adito.rss

Source Code of com.adito.rss.FeedManager

        /*
*  Adito
*
*  Copyright (C) 2003-2006 3SP LTD. All Rights Reserved
*
*  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 2 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, write to the Free Software
*  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
     
package com.adito.rss;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLConnection;
import java.text.DateFormat;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

import com.adito.boot.SystemProperties;
import com.adito.boot.Util;
import com.sun.syndication.io.SyndFeedInput;

/**
* Manages RSS feeds used for context sensitive online help.
*/
public final class FeedManager implements Runnable {
   
    /**
     * Feed connect timeout
     */
    public static final int CONNECT_TIMEOUT = 30000;
   
    /**
     * Feed read timeout
     */
    public static final int READ_TIMEOUT = 30000;

  private static final Log log = LogFactory.getLog(FeedManager.class);
  private static final int ONE_DAY_MILLIS = 1000 * 60 * 60 * 24;
  private static final int FOUR_HOURS_MILLIS = 1000 * 60 * 60 * 4;
  private static final String HOME_URL = "http://download.localhost/";
  private static final String FEED_3SP_URL = HOME_URL + "feeds/";

  private Map<String, Feed> feeds;
  private List<String> availableFeeds;
  private boolean running = false;
  private Thread thread;
  private int interval = ONE_DAY_MILLIS;
  private URL baseLocation;

  private static FeedManager instance;

  /**
   * Default consuctor
   *
   * @param baseLocation base feed location
   */
  protected FeedManager(URL baseLocation) {
    this.baseLocation = baseLocation;
    feeds = new HashMap<String, Feed>();
    availableFeeds = new ArrayList<String>();
  }

  /**
   * Get an instance of the feed manager
   *
   * @return feed manager
   */
  public static FeedManager getInstance() {
    if (instance == null) {
      try {
        URL baseLocation = new URL(SystemProperties.get("adito.rssFeeds.baseLocation", FEED_3SP_URL));
        instance = new FeedManager(baseLocation);
      }
      catch(MalformedURLException murle) {
        try {
          URL baseLocation = new URL(FEED_3SP_URL);
          instance = new FeedManager(baseLocation);
        }
        catch(MalformedURLException murle2) {
          // Should not happen
          throw new Error("Invalid default feed location.");
        }
      }
    }
    return instance;
  }

  /**
   * Get if the feed manager is currently checking for updates
   *
   * @return checking for updates
   */
  public boolean isUpdating() {
    return running;
  }

  /**
   * Start checking for feed updates
   *
   * @throws IllegalStateException if already updating
   */
  public void startUpdating() {
    if (running) {
      throw new IllegalStateException("Already updating.");
    }
    try {
      loadAvailable();
    }
    catch(Exception e) {
      log.error("Failed to get initial feeds. Next update attempt will occur in 4 hours", e);
      interval = FOUR_HOURS_MILLIS;
    }
   
        thread = new Thread(this, "FeedManager");
        thread.setPriority(Thread.MIN_PRIORITY);
        running = true;
       
        if (!isTestMode()) {
            thread.start();
        }
  }

    private boolean isTestMode() {
        return Boolean.valueOf(SystemProperties.get("adito.testing", "false"));
    }

  public void run() {
    try {
      while (running) {

        if (!running)
          break;

        if (log.isInfoEnabled())
          log.info("Checking for feed updates");
       
        try {
          retrieveFeeds();
          interval = ONE_DAY_MILLIS;
        }
        catch (Exception e) {
          log.error("Failed to check for updated feeds. Will check again in 4 hours");
          interval = FOUR_HOURS_MILLIS;
        }
        sleep(interval);
      }
    } catch(InterruptedException ie) {
     
    } finally {
      running = false;
      if(log.isInfoEnabled()) {
        log.info("Stopped checking for RSS updates");
      }
    }
  }

  /**
   * Stop checking for feed updates
   *
   * @throws IllegalStateException if not updating
   */
  public void stopUpdating() {
    if (running) {
      running = false;
      synchronized (this) {
        thread.interrupt();
      }
    } else {
            if(!isTestMode()) {
                throw new IllegalStateException("Not updating.");
            }
    }
  }

  /**
   * Get a list of available RSS feeds as {@link Feed} objects.
   *
   * @param feedName
   * @return list of feeds
   */
  public Feed getFeed(String feedName) {

    /**
     * LDP - If the feed server is down this causes problems with logging into the system
     * until the server has attempted to obtain all the feeds. If the download server is
         * causing connection timeouts the server wont be usable for a good while. We should
         * not care so much about feeds being available so I've removed the synchronization
         * on the feeds hashtable.
     */
//    synchronized (feeds) {
//    if (!feeds.containsKey(feedName) && !feedName.equals("${rssFeed}") &&
//              availableFeeds.contains(feedName)) {
//        try {
//          Feed feed = new Feed(feedName, new SyndFeedInput(), new URL(baseLocation, feedName + ".xml"));         
//          feeds.put(feedName, feed);
//          feed.load();
//          return feed;
//        } catch (Exception ex) {
//          log.error("Failed to load feed.", ex);
//        }
//      }
      return (Feed) feeds.get(feedName);
//    }
  }
 
  protected Collection<String> getAvailableFeedNames() {
    return availableFeeds;
  }

  private static void sleep(int checkAgainIn) throws InterruptedException {
    if (log.isInfoEnabled())
      log.info("Finished checking for updates / feeds, next check will occur at " + getDateAsString(checkAgainIn));
    Thread.sleep(checkAgainIn);
  }

  private static String getDateAsString(int checkAgainIn) {
    return DateFormat.getDateTimeInstance().format(new Date(System.currentTimeMillis() + checkAgainIn));
  }

  protected void retrieveFeeds() throws IOException {
   
    if (log.isInfoEnabled())
      log.info("Retrieving RSS feeds");

    Map<String, Feed> updatedFeeds = new HashMap<String, Feed>();
    synchronized (feeds) {
      for (String feedName : availableFeeds) {
        try {
          Feed feed = new Feed(feedName, new SyndFeedInput(), new URL(baseLocation, feedName + ".xml"));         
          updatedFeeds.put(feedName, feed);
          feed.load();
        } catch (Exception ex) {
          log.error("Failed to load feed.", ex);
        }
      }
      feeds = updatedFeeds;
    }
  }

  protected void loadAvailable() throws IOException {
    URL location = new URL(baseLocation, "index.txt");
   
    availableFeeds.clear();
    URLConnection conx = location.openConnection();
    conx.setConnectTimeout(CONNECT_TIMEOUT);
    conx.setReadTimeout(READ_TIMEOUT);

    if (log.isInfoEnabled()) {
      log.info("Retrieving RSS feeds index from " + location);
    }
    InputStream inputStream = null;
    try {
      inputStream = conx.getInputStream();
      BufferedReader reader = new BufferedReader(new InputStreamReader(inputStream));
      String line;
      while ( ( line = reader.readLine() ) != null) {
        availableFeeds.add(line);
      }
    } finally {
      Util.closeStream(inputStream);
    }
    if (log.isInfoEnabled())
      log.info("There are " + availableFeeds.size() + " available feeds");
  }
}
TOP

Related Classes of com.adito.rss.FeedManager

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.