1 package org.robsite.extension.rss;
2
3 import java.awt.event.ActionEvent;
4 import java.awt.event.ActionListener;
5 import java.awt.event.MouseAdapter;
6 import java.awt.event.MouseEvent;
7 import java.awt.event.MouseListener;
8
9 import java.io.InputStream;
10
11 import java.net.URL;
12
13 import javax.swing.ImageIcon;
14 import javax.swing.JLabel;
15 import javax.swing.SwingUtilities;
16 import javax.swing.Timer;
17
18 import oracle.ide.Ide;
19 import oracle.ide.controls.StatusBarControl;
20 import oracle.ide.net.URLFactory;
21 import oracle.ide.util.Assert;
22
23 import org.robsite.extension.rss.model.Channel;
24 import org.robsite.extension.rss.model.Channels;
25 import org.robsite.extension.rss.model.DirectoryParser;
26
27 /***
28 * The runnable that periodically checks for new news.
29 *
30 * @author brian_duff@sourceforge.net
31 * @version $Revision: 1.1.1.1 $
32 */
33 final class NewsCheckRunnable implements Runnable, ActionListener
34 {
35 private boolean _isRunning;
36
37 private final NewsFeedExtension _extension;
38
39 private final ResHelper _res = new ResHelper( "NewsChecker." );
40
41 NewsCheckRunnable( NewsFeedExtension extension )
42 {
43 _extension = extension;
44 _isRunning = true;
45 }
46
47 public synchronized void stop()
48 {
49 _isRunning = false;
50 notify();
51 }
52
53 /***
54 * Force an immediate update of all channels.
55 */
56 public synchronized void forceUpdate()
57 {
58 notify();
59 }
60
61 /***
62 * Called on a timer tick.
63 *
64 * @param ae the timer action
65 */
66 public synchronized void actionPerformed( ActionEvent ae )
67 {
68 forceUpdate();
69 }
70
71 private synchronized boolean isRunning()
72 {
73 return _isRunning;
74 }
75
76 public void run()
77 {
78 while ( isRunning() )
79 {
80
81
82 synchronized( this )
83 {
84 try
85 {
86 wait();
87 }
88 catch ( InterruptedException ie )
89 {
90 stop();
91 return;
92 }
93 }
94
95
96
97 if ( !isRunning() )
98 {
99 return;
100 }
101
102 boolean newItems = checkForNews();
103
104
105
106 if ( _extension.getNewsDockable() == null && newItems )
107 {
108 showStatusBarMessage();
109 }
110 }
111 }
112
113 static void checkDirectory( NewsFeedPreferences prefs )
114 throws Exception
115 {
116 URL url = URLFactory.newURL( prefs.getDirectoryURL() );
117 InputStream is = url.openStream();
118 DirectoryParser dirParser = new DirectoryParser();
119 dirParser.parse( is, prefs.getChannels() );
120 }
121
122 private boolean checkForNews()
123 {
124 boolean newUnreadItems = false;
125 boolean hadFailures = false;
126 try
127 {
128 setWindowBusy( true );
129
130 SwingUtilities.invokeLater( new Runnable()
131 {
132 public void run()
133 {
134 Ide.getStatusBar().setText( _res.getRes( "CheckingNews" ) );
135 }
136 } );
137
138 HTTPUtil.setHTTPTimeout(
139 NewsFeedExtension.get().getPreferences().getHTTPTimeout() );
140 Channels channels = NewsFeedExtension.get().getChannels();
141
142
143 setWindowStatus( _res.getRes( "CheckingForChannels" ) );
144 try
145 {
146 checkDirectory( NewsFeedExtension.get().getPreferences() );
147 setWindowStatus( "" );
148 }
149 catch ( Exception e )
150 {
151 hadFailures = true;
152 setWindowStatus( _res.getRes( "FailedToGetChannels" ) );
153 e.printStackTrace();
154 sleep( 2000 );
155 }
156
157
158 for ( int i=0; i < channels.getSubscribedChannels().size(); i++ )
159 {
160
161 if ( !isRunning() ) return false;
162 final Channel c = (Channel) channels.getSubscribedChannels().get( i );
163 try
164 {
165 setWindowStatus( _res.getRes( "CheckingChannel", String.valueOf( c ) ) );
166 if ( channels.checkChannel( i ) > 0 )
167 {
168 newUnreadItems = true;
169 }
170 setWindowStatus( "" );
171 }
172 catch ( Exception e )
173 {
174 hadFailures = true;
175 setWindowStatus( _res.getRes( "FailedToCheck", c.getURL() ) );
176
177 e.printStackTrace();
178
179
180
181 sleep( 2000 );
182 }
183
184
185 }
186
187 }
188 catch ( RuntimeException re )
189 {
190 Assert.println( "Runtime Exception during news check" );
191 re.printStackTrace();
192 }
193 finally
194 {
195 setWindowBusy( false );
196
197 SwingUtilities.invokeLater( new Runnable()
198 {
199 public void run()
200 {
201 Ide.getStatusBar().setText( "" );
202 }
203 } );
204 HTTPUtil.resetHTTPTimeout();
205 if ( hadFailures )
206 {
207 setWindowStatus( _res.getRes( "FailedToConnect" ) );
208 }
209 }
210 return newUnreadItems;
211 }
212
213 private void showStatusBarMessage()
214 {
215 SwingUtilities.invokeLater( new Runnable()
216 {
217 public void run()
218 {
219 Ide.getStatusBar().setText( _res.getRes( "GotNewNews" ) );
220 final JLabel l = new JLabel();
221 l.setIcon( new ImageIcon( NewsCheckRunnable.class.getResource( "xml.gif" )) );
222 l.setText( _res.getRes( "ClickToRead" ) );
223
224 final MouseListener labelListener = new MouseAdapter() {
225 public void mouseClicked( MouseEvent me )
226 {
227 if ( me.getButton() == MouseEvent.BUTTON1 )
228 {
229 try
230 {
231 Commands.getAction( Commands.VIEW_NEWS_DOCKABLE ).performAction();
232 ((StatusBarControl)Ide.getStatusBar()).remove( l );
233 l.removeMouseListener( this );
234 }
235 catch ( Exception e ) {}
236 }
237 }
238 };
239 l.addMouseListener( labelListener );
240
241 ((StatusBarControl)Ide.getStatusBar()).add( l );
242 Timer t = new Timer(
243 1000 * _extension.getPreferences().getStatusMessageDuration(),
244 new ActionListener()
245 {
246 public void actionPerformed( ActionEvent ae )
247 {
248 ((StatusBarControl)Ide.getStatusBar()).remove( l );
249 l.removeMouseListener( labelListener );
250 }
251 });
252 t.setRepeats( false );
253 t.start();
254 }
255 } );
256 }
257
258 private void sleep( int ms )
259 {
260 try
261 {
262 Thread.sleep( ms );
263 }
264 catch ( InterruptedException ie )
265 {
266
267 }
268 }
269
270 private void setWindowBusy( final boolean isBusy )
271 {
272 if ( _extension.getNewsDockable() != null )
273 {
274 SwingUtilities.invokeLater( new Runnable()
275 {
276 public void run()
277 {
278 _extension.getNewsDockable().getPanel().setBusy( isBusy );
279 }
280 } );
281 }
282 }
283
284 private void setWindowStatus( final String text )
285 {
286 if ( _extension.getNewsDockable() != null )
287 {
288 SwingUtilities.invokeLater( new Runnable()
289 {
290 public void run()
291 {
292 _extension.getNewsDockable().getPanel().setStatusText( text );
293 }
294 } );
295 }
296 }
297 }