KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > com > sslexplorer > rss > FeedManager


1 /*
2  * SSL-Explorer
3  *
4  * Copyright (C) 2003-2006 3SP LTD. All Rights Reserved
5  *
6  * This program is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU General Public License
8  * as published by the Free Software Foundation; either version 2 of
9  * the License, or (at your option) any later version.
10  * This program is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13  * GNU General Public License for more details.
14  *
15  * You should have received a copy of the GNU General Public
16  * License along with this program; if not, write to the Free Software
17  * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
18  */

19             
20 package com.sslexplorer.rss;
21
22 import java.io.BufferedReader JavaDoc;
23 import java.io.IOException JavaDoc;
24 import java.io.InputStream JavaDoc;
25 import java.io.InputStreamReader JavaDoc;
26 import java.net.MalformedURLException JavaDoc;
27 import java.net.URL JavaDoc;
28 import java.net.URLConnection JavaDoc;
29 import java.text.DateFormat JavaDoc;
30 import java.util.ArrayList JavaDoc;
31 import java.util.Collection JavaDoc;
32 import java.util.Date JavaDoc;
33 import java.util.HashMap JavaDoc;
34 import java.util.List JavaDoc;
35 import java.util.Map JavaDoc;
36
37 import org.apache.commons.logging.Log;
38 import org.apache.commons.logging.LogFactory;
39
40 import com.sslexplorer.boot.Util;
41 import com.sun.syndication.io.SyndFeedInput;
42
43 /**
44  * Manages RSS feeds used for context sensitive online help.
45  *
46  * @author Brett Smith <a HREF="mailto: brett@3sp.com">&lt;brett@3sp.com&gt;</a>
47  */

48 public final class FeedManager implements Runnable JavaDoc {
49     
50     /**
51      * Feed connect timeout
52      */

53     public static final int CONNECT_TIMEOUT = 30000;
54     
55     /**
56      * Feed read timeout
57      */

58     public static final int READ_TIMEOUT = 30000;
59
60     private static final Log log = LogFactory.getLog(FeedManager.class);
61     private static final int ONE_DAY_MILLIS = 1000 * 60 * 60 * 24;
62     private static final int FOUR_HOURS_MILLIS = 1000 * 60 * 60 * 4;
63     private static final String JavaDoc HOME_URL = "http://download.3sp.com/";
64     private static final String JavaDoc FEED_3SP_URL = HOME_URL + "feeds/";
65
66     private Map JavaDoc<String JavaDoc, Feed> feeds;
67     private List JavaDoc<String JavaDoc> availableFeeds;
68     private boolean running = false;
69     private Thread JavaDoc thread;
70     private int interval = ONE_DAY_MILLIS;
71     private URL JavaDoc baseLocation;
72
73     private static FeedManager instance;
74
75     /**
76      * Default consuctor
77      *
78      * @param baseLocation base feed location
79      */

80     protected FeedManager(URL JavaDoc baseLocation) {
81         this.baseLocation = baseLocation;
82         feeds = new HashMap JavaDoc<String JavaDoc, Feed>();
83         availableFeeds = new ArrayList JavaDoc<String JavaDoc>();
84     }
85
86     /**
87      * Get an instance of the feed manager
88      *
89      * @return feed manager
90      */

91     public static FeedManager getInstance() {
92         if (instance == null) {
93             try {
94                 URL JavaDoc baseLocation = new URL JavaDoc(System.getProperty("sslexplorer.rssFeeds.baseLocation", FEED_3SP_URL));
95                 instance = new FeedManager(baseLocation);
96             }
97             catch(MalformedURLException JavaDoc murle) {
98                 try {
99                     URL JavaDoc baseLocation = new URL JavaDoc(FEED_3SP_URL);
100                     instance = new FeedManager(baseLocation);
101                 }
102                 catch(MalformedURLException JavaDoc murle2) {
103                     // Should not happen
104
throw new Error JavaDoc("Invalid default feed location.");
105                 }
106             }
107         }
108         return instance;
109     }
110
111     /**
112      * Get if the feed manager is currently checking for updates
113      *
114      * @return checking for updates
115      */

116     public boolean isUpdating() {
117         return running;
118     }
119
120     /**
121      * Start checking for feed updates
122      *
123      * @throws IllegalStateException if already updating
124      */

125     public void startUpdating() {
126         if (running) {
127             throw new IllegalStateException JavaDoc("Already updating.");
128         }
129         try {
130             loadAvailable();
131         }
132         catch(Exception JavaDoc e) {
133             log.error("Failed to get initial feeds. Next update attempt will occur in 4 hours", e);
134             interval = FOUR_HOURS_MILLIS;
135         }
136         
137         thread = new Thread JavaDoc(this, "FeedManager");
138         thread.setPriority(Thread.MIN_PRIORITY);
139         running = true;
140         
141         if (!isTestMode()) {
142             thread.start();
143         }
144     }
145
146     private boolean isTestMode() {
147         return Boolean.valueOf(System.getProperty("sslexplorer.testing", "false"));
148     }
149
150     public void run() {
151         try {
152             while (running) {
153
154                 if (!running)
155                     break;
156
157                 if (log.isInfoEnabled())
158                     log.info("Checking for feed updates");
159                 
160                 try {
161                     retrieveFeeds();
162                     interval = ONE_DAY_MILLIS;
163                 }
164                 catch (Exception JavaDoc e) {
165                     log.error("Failed to check for updated feeds. Will check again in 4 hours");
166                     interval = FOUR_HOURS_MILLIS;
167                 }
168                 sleep(interval);
169             }
170         } catch(InterruptedException JavaDoc ie) {
171             
172         } finally {
173             running = false;
174             if(log.isInfoEnabled()) {
175                 log.info("Stopped checking for RSS updates");
176             }
177         }
178     }
179
180     /**
181      * Stop checking for feed updates
182      *
183      * @throws IllegalStateException if not updating
184      */

185     public void stopUpdating() {
186         if (running) {
187             running = false;
188             synchronized (this) {
189                 thread.interrupt();
190             }
191         } else {
192             if(!isTestMode()) {
193                 throw new IllegalStateException JavaDoc("Not updating.");
194             }
195         }
196     }
197
198     /**
199      * Get a list of available RSS feeds as {@link Feed} objects.
200      *
201      * @param feedName
202      * @return list of feeds
203      */

204     public Feed getFeed(String JavaDoc feedName) {
205
206         synchronized (feeds) {
207             if (!feeds.containsKey(feedName) && !feedName.equals("${rssFeed}") &&
208                             availableFeeds.contains(feedName)) {
209                 try {
210                     Feed feed = new Feed(feedName, new SyndFeedInput(), new URL JavaDoc(baseLocation, feedName + ".xml"));
211                     feeds.put(feedName, feed);
212                     feed.load();
213                     return feed;
214                 } catch (Exception JavaDoc ex) {
215                     log.error("Failed to load feed.", ex);
216                 }
217             }
218             return (Feed) feeds.get(feedName);
219         }
220     }
221     
222     protected Collection JavaDoc<String JavaDoc> getAvailableFeedNames() {
223         return availableFeeds;
224     }
225
226     private static void sleep(int checkAgainIn) throws InterruptedException JavaDoc {
227         if (log.isInfoEnabled())
228             log.info("Finished checking for updates / feeds, next check will occur at " + getDateAsString(checkAgainIn));
229         Thread.sleep(checkAgainIn);
230     }
231
232     private static String JavaDoc getDateAsString(int checkAgainIn) {
233         return DateFormat.getDateTimeInstance().format(new Date JavaDoc(System.currentTimeMillis() + checkAgainIn));
234     }
235
236     protected void retrieveFeeds() throws IOException JavaDoc {
237         
238         if (log.isInfoEnabled())
239             log.info("Retrieving RSS feeds");
240
241         Map JavaDoc<String JavaDoc, Feed> updatedFeeds = new HashMap JavaDoc<String JavaDoc, Feed>();
242         synchronized (feeds) {
243             for (String JavaDoc feedName : availableFeeds) {
244                 try {
245                     Feed feed = new Feed(feedName, new SyndFeedInput(), new URL JavaDoc(baseLocation, feedName + ".xml"));
246                     updatedFeeds.put(feedName, feed);
247                     feed.load();
248                 } catch (Exception JavaDoc ex) {
249                     log.error("Failed to load feed.", ex);
250                 }
251             }
252             feeds = updatedFeeds;
253         }
254     }
255
256     protected void loadAvailable() throws IOException JavaDoc {
257         URL JavaDoc location = new URL JavaDoc(baseLocation, "index.txt");
258         
259         availableFeeds.clear();
260         URLConnection JavaDoc conx = location.openConnection();
261         conx.setConnectTimeout(CONNECT_TIMEOUT);
262         conx.setReadTimeout(READ_TIMEOUT);
263
264         if (log.isInfoEnabled()) {
265             log.info("Retrieving RSS feeds index from " + location);
266         }
267         InputStream JavaDoc inputStream = null;
268         try {
269             inputStream = conx.getInputStream();
270             BufferedReader JavaDoc reader = new BufferedReader JavaDoc(new InputStreamReader JavaDoc(inputStream));
271             String JavaDoc line;
272             while ( ( line = reader.readLine() ) != null) {
273                 availableFeeds.add(line);
274             }
275         } finally {
276             Util.closeStream(inputStream);
277         }
278         if (log.isInfoEnabled())
279             log.info("There are " + availableFeeds.size() + " available feeds");
280     }
281 }
Popular Tags