KickJava   Java API By Example, From Geeks To Geeks.

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


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

26
27 // $Id: ChannelRegistry.java,v 1.37 2004/10/08 21:38:13 niko_schmuck Exp $
28

29 package de.nava.informa.utils;
30
31 import java.net.URL JavaDoc;
32 import java.util.Collection JavaDoc;
33 import java.util.HashMap JavaDoc;
34 import java.util.Iterator JavaDoc;
35 import java.util.Map JavaDoc;
36 import java.util.Timer JavaDoc;
37
38 import org.apache.commons.logging.Log;
39 import org.apache.commons.logging.LogFactory;
40
41 import de.nava.informa.core.ChannelBuilderIF;
42 import de.nava.informa.core.ChannelGroupIF;
43 import de.nava.informa.core.ChannelIF;
44
45 /**
46  * This class can be used as central repository for storing a
47  * collection of channel objects and maintaining them (by specifying
48  * update intervals).
49  *
50  * @author Niko Schmuck (niko@nava.de)
51  */

52 public class ChannelRegistry {
53
54   private static Log logger = LogFactory.getLog(ChannelRegistry.class);
55   public static final int DEFAULT_ACCEPT_NR_ERRORS = 10;
56
57   private int acceptNrOfErrors;
58   private ChannelBuilderIF builder;
59   private ChannelGroupIF channels;
60   private Timer JavaDoc updateDaemon;
61   private Map JavaDoc updateTasks;
62   private Map JavaDoc channelInfos;
63
64   /**
65    * Constructor for a new ChannelRegistry object, the new items found by
66    * scanning the are created using the given <code>builder</code>.
67    *
68    * @param builder The ChannelBuilderIF to use for creating news items.
69    */

70   public ChannelRegistry(ChannelBuilderIF builder) {
71     this.builder = builder;
72     this.channels = builder.createChannelGroup("Default");
73     // start a new timer 'daemon' which controls updating tasks
74
updateDaemon = new Timer JavaDoc(true);
75     updateTasks = new HashMap JavaDoc();
76     channelInfos = new HashMap JavaDoc();
77     acceptNrOfErrors = DEFAULT_ACCEPT_NR_ERRORS;
78   }
79
80   /**
81    * Adds one new channel object (instantiated with the help of the
82    * given URL from where the channel can be retrieved from) to the
83    * registry.
84    *
85    * @param url - the URL where the channel news can be retrieved.
86    * @param interval - time in seconds between update retrieval.
87    * @param active - wether regular updates should be executed.
88    */

89   public ChannelIF addChannel(URL JavaDoc url, int interval, boolean active) {
90     return addChannel(url, null, interval, active);
91   }
92
93   /**
94    * Adds one new channel object in the given category to the
95    * registry.
96    *
97    * @param url - the URL where the channel news can be retrieved.
98    * @param categories - the categories to which this channel should be
99    * added to (collection of CategoryIF objects).
100    * @param interval - time in seconds between update retrieval.
101    * @param active - wether regular updates should be executed.
102    */

103   public ChannelIF addChannel(URL JavaDoc url, Collection JavaDoc categories,
104                               int interval, boolean active) {
105
106     ChannelIF channel = builder.createChannel("[uninitialized channel]");
107     channel.setCategories(categories);
108     channel.setLocation(url);
109
110     channel = addChannel(channel, active, interval);
111     return channel;
112   }
113   
114   /**
115    * Given a stand-alone Channel (i.e. just read in from disk) we
116    * add it into the ChannelGroup and activated if necessary.
117    *
118    * @param channel - Fully realized Channel
119    * @param active - Same as above
120    * @param interval - Same as above
121    */

122   public ChannelIF addChannel(ChannelIF channel, boolean active, int interval) {
123     channels.add(channel);
124     logger.debug("added channel " + channel.getId() + " to registry");
125     if (active) {
126       activateChannel(channel, interval);
127     }
128     return channel;
129   }
130
131   /**
132    * Activates a channel and looks for new items for the given channel.
133    *
134    * @param channel The ChannelIF to scan for updates
135    * @param interval Difference between channel updates in seconds
136    */

137   public void activateChannel(ChannelIF channel, int interval) {
138     // TODO: what about changed interval setting?
139
// (workaround, deactivate, set interval, activate again)
140
// only create one update task per channel
141
if (updateTasks.get(channel.getLocation()) == null) {
142       // auto-deactivation after 10 times an channel parse error occurred
143
UpdateChannelInfo info = (UpdateChannelInfo)
144                                  channelInfos.get(channel.getLocation());
145       if (info == null) {
146         info = new UpdateChannelInfo(acceptNrOfErrors);
147         info.setFormatDetected(false);
148         channelInfos.put(channel.getLocation(), info);
149       } else {
150         info.reset();
151       }
152       // create new task
153
UpdateChannelTask task = new UpdateChannelTask(this, builder,
154                                                      channel, info);
155       // schedule the task for periodic execution, first time after
156
// 100 ms, and then regularly in <interval> secs.
157
updateDaemon.schedule(task, 100, interval * 1000);
158       logger.info("activating channel updates for " + channel.getTitle());
159       updateTasks.put(channel.getLocation(), task);
160       // TODO: Adapt to new UserIF
161
// channel.getSubscription().setActive(true);
162
// channel.getSubscription().setUpdateInterval(interval);
163
}
164   }
165
166   public ChannelIF getChannel(long id) {
167      return channels.getById(id);
168   }
169
170   /**
171    * Gets all the channels in the registry.
172    *
173    * @return A collection of ChannelIF objects.
174    */

175   public Collection JavaDoc getChannels() {
176     return channels.getAll();
177   }
178
179   public ChannelGroupIF getChannelGroup() {
180     return channels;
181   }
182
183   public void setChannelGroup(ChannelGroupIF channels) {
184     this.channels = channels;
185     // loop over channels and activate if necessary
186
Iterator JavaDoc it = channels.getAll().iterator();
187     while (it.hasNext()) {
188       ChannelIF channel = (ChannelIF) it.next();
189       // TODO: Adapt to new UserIF
190
// if (channel.getSubscription().isActive()) {
191
// activateChannel(channel,
192
// channel.getSubscription().getUpdateInterval());
193
// }
194
}
195   }
196
197   /**
198    * Removes a channel from the registry. First it is cleanly deactivated.
199    *
200    * @param channel The ChannelIF object to remove.
201    */

202   public void removeChannel(ChannelIF channel) {
203     deactivateChannel(channel);
204     channels.remove(channel);
205     logger.debug("removing channel from registry: " + channel.getTitle());
206   }
207
208   /**
209    * Deactivates a channel, no more updates are made.
210    */

211   public void deactivateChannel(ChannelIF channel) {
212     UpdateChannelTask task = (UpdateChannelTask)
213             updateTasks.get(channel.getLocation());
214     if (task != null) {
215       logger.debug("update task canceled for " + channel.getTitle());
216       task.cancel();
217       updateTasks.remove(channel.getLocation());
218       // TODO: Adapt to new UserIF
219
// channel.getSubscription().setActive(false);
220
}
221   }
222
223   /**
224    * Returns wether the channel update task is still active or not.
225    */

226   public boolean isActiveChannel(ChannelIF channel) {
227     UpdateChannelTask task = (UpdateChannelTask)
228             updateTasks.get(channel.getLocation());
229     return (task != null);
230   }
231
232   public UpdateChannelInfo getUpdateInfo(ChannelIF channel) {
233     return (UpdateChannelInfo) channelInfos.get(channel.getLocation());
234   }
235
236   /**
237    * Gets the scheduled time of the next channel update.
238    *
239    * @param channel The ChannelIF to retrieve information for.
240    * @return The date of the next execution, 0 if not available
241    */

242   public long getScheduledUpdateTime(ChannelIF channel) {
243     UpdateChannelTask task = (UpdateChannelTask)
244             updateTasks.get(channel.getLocation());
245     if (task != null) {
246       return task.scheduledExecutionTime();
247     }
248     return 0;
249   }
250
251   public int getAcceptNrOfErrors() {
252     return acceptNrOfErrors;
253   }
254
255   /**
256    * Set number of channel parser errors acceptable after channel is not
257    * longer automatically updated.
258    */

259   public void setAcceptNrOfErrors(int acceptNrOfErrors) {
260     this.acceptNrOfErrors = acceptNrOfErrors;
261   }
262
263 }
264
Popular Tags