FeedHelper.java :  » Portal » Open-Portal » com » sun » portal » rssportlet » Java Open Source

Java Open Source » Portal » Open Portal 
Open Portal » com » sun » portal » rssportlet » FeedHelper.java
/*
 * Copyright  2006 Sun Microsystems, Inc. All rights reserved. 
 *
 * Sun Microsystems, Inc. has intellectual property rights relating to
 * technology embodied in the product that is described in this document. 
 * In particular, and without limitation, these intellectual property 
 * rights may include one or more of the U.S. patents listed at 
 * http://www.sun.com/patents and one or more additional patents or
 * pending patent applications in the U.S. and in other countries.
 * 
 * U.S. Government Rights - Commercial software. Government users are subject
 * to the Sun Microsystems, Inc. standard license agreement and applicable 
 * provisions of the FAR and its supplements. Use is subject to license terms. 
 * This distribution may include materials developed by third parties.
 * Sun, Sun Microsystems, the Sun logo and Java are trademarks or registered 
 * trademarks of Sun Microsystems, Inc. in the U.S. and other countries. 
 */
package com.sun.portal.rssportlet;

import com.sun.syndication.feed.synd.SyndFeed;
import com.sun.syndication.io.FeedException;
import com.sun.syndication.io.SyndFeedInput;
import java.io.IOException;
import java.net.URL;
import java.net.URLConnection;
import java.util.Collections;
import java.util.HashMap;
import java.util.Map;
import org.xml.sax.InputSource;

/**
 * This class manages a cache of ROME feeds.
 */
public class FeedHelper {
  // singleton instance
  private static FeedHelper feedHelper = new FeedHelper();

    // 
    // sync the map, not the method. 
    // if the method is sync'd, we end up spinning whenever a feed host
    // fails to respond. with the map sync'd, we still may fetch
    // feeds twice under some extreme race condition, but that is
    // very unlikely and will not cause data corruption.
    //
    private Map feeds = Collections.synchronizedMap(new HashMap());
      
    /**
     * This class is the cached representation of a ROME feed.
     */
    private static final class FeedElement {
        private SyndFeed feed = null;
        private long cacheTime;
        private long timeout;
        
        public FeedElement(SyndFeed feed, int timeout) {
            this.feed = feed;
            this.cacheTime = System.currentTimeMillis();
            this.timeout = timeout * 1000;
        }
        
        public SyndFeed getFeed() {
            return feed;
        }
        
        public boolean isExpired() {
            // negative timeout means that the cached element never expires
            if (timeout < 0) {
                return false;
            }
            
            // otherwise, is the time cached plus the timeout still
            // less than the current time? if so, then the cache
            // has not expired
            if ((cacheTime + timeout) < System.currentTimeMillis()) {
                return true;
            }
            
            return false;
        }
    }
  
  private FeedHelper() {
    // nothing, cannot be called
  }
  
  /**
   * Get the feed handler singleton instance.
   */
  public static FeedHelper getInstance() {
    return feedHelper;
  }
    
    /**
     * Get the ROME SyndFeed object for the specified feed. The object may come
     * from a cache; the data in the feed may not be read at the time
     * this method is called.
     *
     * The <code>RssPortletBean</code> object is used to identify the feed
     * of interest, and the timeout value to be used when managing this
     * feed's cached value.
     *
     * @param bean an <code>RssPortletBean</code> object that describes
     * the feed of interest, and the cache timeout value for the feed.
     * @return a ROME <code>SyndFeed</code> object encapsulating the
     * feed specified by the URL.
     */
    public SyndFeed getFeed(SettingsBean bean, String selectedFeed) throws IOException, FeedException {
        SyndFeed feed = null;
        FeedElement feedElement = (FeedElement)feeds.get(selectedFeed);
        
        if (feedElement != null && !feedElement.isExpired()) {
            feed = feedElement.getFeed();
        } else {
            URL feedUrl = new URL(selectedFeed);
            URLConnection urlc = feedUrl.openConnection();
            urlc.connect();
            SyndFeedInput input = new SyndFeedInput();
            InputSource src = new InputSource(urlc.getInputStream());
            feed = input.build(src);
            
            //
            // only cache the feed if the cache timeout is not equal to 0
            // a cache timeout of 0 means "don't cache"
            //
            int timeout = bean.getCacheTimeout();
            if (timeout != 0) {
                putFeed(selectedFeed, feed, timeout);
            }
        }
        
        return feed;        
    }
  
  /**
   * Get the ROME SyndFeed object for the feed specified by the 
   * SettingsBean's selectedFeed field.
   */
    public SyndFeed getFeed(SettingsBean bean) throws IOException, FeedException {
    return getFeed(bean, bean.getSelectedFeed());
  }
    
    /**
     * Put a ROME feed into the cache.
     * This method must be called from within a synchronzied block.
     */
    private void putFeed(String url, SyndFeed feed, int timeout) {
        FeedElement feedElement = new FeedElement(feed, timeout);
        feeds.put(url, feedElement);
    }
}
java2s.com  | Contact Us | Privacy Policy
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.