KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > de > nava > informa > utils > FeedManager


1 //
2
// // Informa -- RSS Library for Java
3
// Copyright (c) 2002 by Niko Schmuck
4
//
5
// Niko Schmuck
6
// http://sourceforge.net/projects/informa
7
// mailto:niko_schmuck@users.sourceforge.net
8
//
9
// This library is free software.
10
//
11
// You may redistribute it and/or modify it under the terms of the GNU
12
// Lesser General Public License as published by the Free Software Foundation.
13
//
14
// Version 2.1 of the license should be included with this distribution in
15
// the file LICENSE. If the license is not included with this distribution,
16
// you may find a copy at the FSF web site at 'www.gnu.org' or 'www.fsf.org',
17
// or you may write to the Free Software Foundation, 675 Mass Ave, Cambridge,
18
// MA 02139 USA.
19
//
20
// This library is distributed in the hope that it will be useful,
21
// but WITHOUT ANY WARRANTY; without even the implied waranty of
22
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
23
// Lesser General Public License for more details.
24

25 // $Id: FeedManager.java,v 1.11 2004/06/28 19:33:44 niko_schmuck Exp $
26

27 package de.nava.informa.utils;
28
29 import de.nava.informa.core.ChannelBuilderIF;
30 import de.nava.informa.core.ChannelIF;
31 import de.nava.informa.core.FeedIF;
32 import de.nava.informa.core.ParseException;
33 import de.nava.informa.parsers.OPMLParser;
34
35 import java.io.IOException JavaDoc;
36
37 import java.util.ArrayList JavaDoc;
38 import java.util.Collection JavaDoc;
39 import java.util.HashMap JavaDoc;
40 import java.util.Iterator JavaDoc;
41 import java.util.Map JavaDoc;
42
43 /**
44  * A class used to manage feeds. Feeds are parsed and stored using the
45  * <code>addFeed</code> method. Subsequent requests for the same feed URI
46  * (using either <code>addFeed</code> or <code>getFeed</code>) will return
47  * a cached copy, unless the feed is due to be refreshed direct from the source.
48  * <br>
49  * The time before a feed is considered out of date will be read from the feed
50  * if possible, failing that a default UpdatePeriod and UpdateFrequency are
51  * used. <br>
52  *
53  * @author Sam Newman
54  * @version $Id: FeedManager.java,v 1.11 2004/06/28 19:33:44 niko_schmuck Exp $
55  */

56 public class FeedManager {
57
58   /** Default channel builder used if no explicit channel builder was set */
59   private static final ChannelBuilderIF DEFAULT_BUILDER = new de.nava.informa.impl.basic.ChannelBuilder();
60
61   private ChannelBuilderIF channelBuilder;
62
63   private String JavaDoc defaultUpdatePeriod;
64
65   private int defaultUpdateFrequency;
66
67   /** Internal store of FeedEntry's, keyed by feed uri */
68   private Map JavaDoc feeds;
69
70   /** cache settings variable */
71   private CacheSettingsIF cacheSettings = new CacheSettings();
72
73   /** feed Daemon */
74   private FeedRefreshDaemon refreshDaemon = new FeedRefreshDaemon();
75
76   /**
77    * Creates a new FeedManager object.
78    */

79   public FeedManager() {
80     feeds = new HashMap JavaDoc();
81     this.defaultUpdatePeriod = ChannelIF.UPDATE_DAILY;
82     this.defaultUpdateFrequency = 1;
83     setCacheSettings(defaultUpdatePeriod, defaultUpdateFrequency);
84   }
85
86   /**
87    * Creates a new FeedManager object.
88    *
89    * @param defaultUpdatePeriod
90    * @param defaultUpdateFrequency
91    */

92   public FeedManager(String JavaDoc defaultUpdatePeriod, int defaultUpdateFrequency) {
93     feeds = new HashMap JavaDoc();
94     this.defaultUpdatePeriod = defaultUpdatePeriod;
95     this.defaultUpdateFrequency = defaultUpdateFrequency;
96     setCacheSettings(defaultUpdatePeriod, defaultUpdateFrequency);
97   }
98
99   /**
100    * initialiation of the cacheSettings private variable
101    */

102   private void setCacheSettings(String JavaDoc updatePeriod, int updateFrequency) {
103     // TODO refactoring constants declarations
104
long MILLISECONDS_IN_HOUR = 3600000L;
105     long MILLISECONDS_IN_DAY = 86400000L;
106     long MILLISECONDS_IN_MONTH = 2419200000L;
107     long MILLISECONDS_IN_YEAR = 31536000000L;
108
109     long msInPeriod = 0L;
110
111     if (updatePeriod.equals(ChannelIF.UPDATE_HOURLY)) {
112       msInPeriod = MILLISECONDS_IN_HOUR;
113     } else if (updatePeriod.equals(ChannelIF.UPDATE_DAILY)) {
114       msInPeriod = MILLISECONDS_IN_DAY;
115     } else if (updatePeriod.equals(ChannelIF.UPDATE_MONTHLY)) {
116       msInPeriod = MILLISECONDS_IN_MONTH;
117     } else if (updatePeriod.equals(ChannelIF.UPDATE_YEARLY)) {
118       msInPeriod = MILLISECONDS_IN_YEAR;
119     } else {
120       throw new IllegalArgumentException JavaDoc("updatePeriod " + updatePeriod
121           + " is not valid");
122     }
123     this.cacheSettings.setDefaultTtl(msInPeriod / updateFrequency);
124   }
125
126   /**
127    * Loads a feed given the metadata information contained in the given FeedIF
128    * object
129    *
130    * @param feed
131    * @return FeedIF object
132    * @throws FeedManagerException
133    * DOCUMENT ME!
134    */

135   public FeedIF addFeed(FeedIF feed) throws FeedManagerException {
136     return addFeed(feed.getLocation().toString());
137   }
138
139   /**
140    * Loads a feed given the metadata information contained in the given FeedIF
141    * object
142    *
143    * @param feed
144    * @param ttl
145    * in minutes
146    * @return FeedIF object
147    * @throws FeedManagerException
148    * DOCUMENT ME!
149    */

150   public FeedIF addFeed(FeedIF feed, int ttl) throws FeedManagerException {
151     return addFeed(feed.getLocation().toString(), ttl);
152   }
153
154   /**
155    * Attempts to load the feeds specified in the given OPML file into the
156    * manager
157    *
158    * @param opmlFeedUri
159    * An OPML file containing a list of feeds
160    * @return A list of FeedIF files representing the feeds added
161    * @throws FeedManagerException
162    * DOCUMENT ME!
163    */

164   public Collection JavaDoc addFeeds(String JavaDoc opmlFeedUri) throws FeedManagerException {
165     Collection JavaDoc retFeeds = null;
166
167     try {
168       Collection JavaDoc feedsColl = OPMLParser.parse(opmlFeedUri);
169       retFeeds = new ArrayList JavaDoc();
170
171       for (Iterator JavaDoc iter = feedsColl.iterator(); iter.hasNext();) {
172         FeedIF element = (FeedIF) iter.next();
173         retFeeds.add(addFeed(element));
174       }
175     } catch (IOException JavaDoc e) {
176       throw new FeedManagerException(e);
177     } catch (ParseException e) {
178       throw new FeedManagerException(e);
179     }
180
181     return retFeeds;
182   }
183
184   /**
185    * Attempts to load the feeds specified in the given OPML file into the
186    * manager
187    *
188    * @param opmlFeedUri
189    * An OPML file containing a list of feeds
190    * @param ttl
191    * a ttl for all feeds (in minutes)
192    * @return A list of FeedIF files representing the feeds added
193    * @throws FeedManagerException
194    * DOCUMENT ME!
195    */

196   public Collection JavaDoc addFeeds(String JavaDoc opmlFeedUri, int ttl)
197       throws FeedManagerException {
198     Collection JavaDoc retFeeds = null;
199
200     try {
201       Collection JavaDoc feedsColl = OPMLParser.parse(opmlFeedUri);
202       retFeeds = new ArrayList JavaDoc();
203
204       for (Iterator JavaDoc iter = feedsColl.iterator(); iter.hasNext();) {
205         FeedIF element = (FeedIF) iter.next();
206         retFeeds.add(addFeed(element, ttl));
207       }
208     } catch (IOException JavaDoc e) {
209       throw new FeedManagerException(e);
210     } catch (ParseException e) {
211       throw new FeedManagerException(e);
212     }
213
214     return retFeeds;
215   }
216
217   /**
218    * Sets the channel builder used when reading the news feeds.
219    *
220    * @param chBuilder
221    */

222   public void setChannelBuilder(ChannelBuilderIF chBuilder) {
223     channelBuilder = chBuilder;
224   }
225
226   /**
227    * Gets the channel builder used by the feed entries.
228    *
229    * @return ChannelBuilderIF
230    */

231   public ChannelBuilderIF getChannelBuilder() {
232     if (channelBuilder == null) {
233       return DEFAULT_BUILDER;
234     } else {
235       return channelBuilder;
236     }
237   }
238
239   /**
240    * Determines if the manager is handling the feed
241    *
242    * @param feedUri
243    * The URI for the feed
244    * @return true if the feed is managed, else false
245    */

246   public boolean hasFeed(String JavaDoc feedUri) {
247     return feeds.containsKey(feedUri);
248   }
249
250   /**
251    * Adds the specified feed to the manager. If the feed is already managed
252    * nothing happens
253    *
254    * @param feedUri
255    * The URI of the feed to add
256    * @return The feed being managed
257    * @throws FeedManagerException
258    * If the feed specified is invalid
259    */

260   public FeedIF addFeed(String JavaDoc feedUri) throws FeedManagerException {
261     if (!hasFeed(feedUri)) {
262       FeedManagerEntry fme = new FeedManagerEntry(feedUri, getChannelBuilder(),
263           defaultUpdatePeriod, defaultUpdateFrequency);
264       feeds.put(feedUri, fme);
265       refreshDaemon.addFeed(fme);
266     }
267
268     return getFeed(feedUri);
269   }
270
271   /**
272    * Adds the specified feed to the manager with a specific Ttl. The ttl
273    * specified may superseded the global ttl (deducted from
274    * <code>updatePeriod</code> and <code>updateFrequency</code>), depending
275    * on the feed type. This behavior is implemented in the differents
276    * <code>CacheSettingsIF</code> implementations provided.
277    *
278    * @see de.nava.informa.utils.CacheSettingsIF
279    * @param feedUri
280    * The URI of the feed to add
281    * @param wantedTtlmins
282    * The ttl wanted for this feed (in minutes)
283    * @return The feed being managed
284    * @throws FeedManagerException
285    * If the feed specified is invalid
286    */

287   public FeedIF addFeed(String JavaDoc feedUri, int wantedTtlmins)
288       throws FeedManagerException {
289     if (!hasFeed(feedUri)) {
290       FeedManagerEntry FMEntry = new FeedManagerEntry(feedUri,
291           getChannelBuilder(), defaultUpdatePeriod, defaultUpdateFrequency);
292
293       if (wantedTtlmins > 0) {
294         FMEntry.setWantedTtl(wantedTtlmins * (60 * 1000));
295       }
296       feeds.put(feedUri, FMEntry);
297       refreshDaemon.addFeed(FMEntry);
298     } else {
299       // TODO : what behavior when the ttl is different ?
300
}
301
302     return getFeed(feedUri);
303   }
304
305   /**
306    * Removes the specified feed from the manager
307    *
308    * @param feedUri
309    * The URI for the feed to remove
310    */

311   public void removeFeed(String JavaDoc feedUri) {
312     feeds.remove(feedUri);
313   }
314
315   /**
316    * Retrieves the feed being managed. Note that null will be returned if the
317    * feed is not being managed. If you want to add a feed and return it in the
318    * same method, use <code>addFeed</code> instead.
319    *
320    * @param feedUri
321    * The feed to return
322    * @return The feed being managed, or null if the feed is not present
323    * @throws FeedManagerException
324    * If the feed specified is invalid
325    */

326   public FeedIF getFeed(String JavaDoc feedUri) throws FeedManagerException {
327     FeedIF feed = null;
328
329     if (hasFeed(feedUri)) {
330       FeedManagerEntry entry = (FeedManagerEntry) feeds.get(feedUri);
331       feed = entry.getFeed();
332     }
333
334     return feed;
335   }
336
337 }
Popular Tags