1 package org.robsite.extension.rss.model;
2
3 import java.beans.XMLDecoder;
4 import java.beans.XMLEncoder;
5
6 import java.io.IOException;
7 import java.io.InputStream;
8 import java.io.OutputStream;
9
10 import java.net.MalformedURLException;
11
12 import java.util.ArrayList;
13 import java.util.Collection;
14 import java.util.Collections;
15 import java.util.Date;
16 import java.util.Iterator;
17 import java.util.List;
18
19 import javax.swing.AbstractListModel;
20
21 import javax.xml.parsers.ParserConfigurationException;
22
23 import oracle.ide.util.CollectionListener;
24 import oracle.ide.util.Copyable;
25 import oracle.ide.util.Pair;
26 import oracle.ide.util.TransientMarker;
27 import oracle.ide.xml.SAXParserDoneException;
28
29 import org.robsite.extension.rss.util.ListEvent;
30 import org.robsite.extension.rss.util.ListListener;
31
32 import org.xml.sax.SAXException;
33
34 public class Channels implements Copyable
35 {
36 private Pair _channels = new Pair();
37 private List _collectionListeners = null;
38
39 public Channels()
40 {
41 _channels.setFirst( new ArrayList() );
42 _channels.setSecond( new ArrayList() );
43 }
44
45 public void addListListener( ListListener cl )
46 {
47 if ( _collectionListeners == null )
48 {
49 _collectionListeners = new ArrayList();
50 }
51 _collectionListeners.add( cl );
52 }
53
54 public void removeListListener( ListListener cl )
55 {
56 if ( _collectionListeners == null )
57 {
58 throw new IllegalStateException( "No listeners" ) ;
59 }
60 _collectionListeners.remove( cl );
61 }
62
63 private void fireIntervalAdded( int start, int end )
64 {
65 if ( _collectionListeners == null || _collectionListeners.isEmpty() )
66 {
67 return;
68 }
69
70 ListListener[] listeners = (ListListener[]) _collectionListeners.toArray(
71 new ListListener[ _collectionListeners.size() ]);
72 ListEvent le = new ListEvent( getSubscribedChannels(), start, end );
73
74 for ( int i=0; i < listeners.length; i++ )
75 {
76 listeners[ i ].itemsAdded( le );
77 }
78 }
79
80 private void fireIntervalRemoved( int start, int end )
81 {
82 if ( _collectionListeners == null || _collectionListeners.isEmpty() )
83 {
84 return;
85 }
86
87 ListListener[] listeners = (ListListener[]) _collectionListeners.toArray(
88 new ListListener[ _collectionListeners.size() ]);
89 ListEvent le = new ListEvent( getSubscribedChannels(), start, end );
90
91 for ( int i=0; i < listeners.length; i++ )
92 {
93 listeners[ i ].itemsRemoved( le );
94 }
95 }
96
97 private void fireIntervalChanged( int start, int end )
98 {
99 if ( _collectionListeners == null || _collectionListeners.isEmpty() )
100 {
101 return;
102 }
103
104 ListListener[] listeners = (ListListener[]) _collectionListeners.toArray(
105 new ListListener[ _collectionListeners.size() ]);
106 ListEvent le = new ListEvent( getSubscribedChannels(), start, end );
107
108 for ( int i=0; i < listeners.length; i++ )
109 {
110 listeners[ i ].itemsChanged( le );
111 }
112 }
113
114 public Pair getChannelInfo()
115 {
116 return _channels;
117 }
118
119 public void setChannelInfo( Pair pair )
120 {
121 _channels = pair;
122 }
123
124 public List getSubscribedChannels()
125 {
126 if ( _channels != null )
127 {
128 return (List) _channels.getFirst();
129 }
130
131 return Collections.EMPTY_LIST;
132 }
133
134 public List getUnsubscribedChannels()
135 {
136 if ( _channels != null )
137 {
138 return (List) _channels.getSecond();
139 }
140
141 return Collections.EMPTY_LIST;
142 }
143
144 public void setSubscribedChannels( List subscribed )
145 throws TransientMarker
146 {
147 int oldSize = getSubscribedChannels().size();
148 _channels.setFirst( subscribed );
149 fireIntervalRemoved( 0, oldSize -1 );
150 fireIntervalAdded( 0, getSubscribedChannels().size() -1 );
151 }
152
153 public void setUnsubscribedChannels( List unsubscribed )
154 throws TransientMarker
155 {
156 _channels.setSecond( unsubscribed );
157 }
158
159
160 public List getAllChannels()
161 {
162 ArrayList list = new ArrayList();
163 list.addAll( getSubscribedChannels() );
164 list.addAll( getUnsubscribedChannels() );
165
166 return Collections.unmodifiableList( list );
167 }
168
169 public void save( OutputStream os )
170 {
171 XMLEncoder encoder = new XMLEncoder( os );
172 encoder.writeObject( _channels );
173 encoder.close();
174 }
175
176
177 public void load( InputStream is )
178 {
179 XMLDecoder decoder = new XMLDecoder( is );
180 Object o = decoder.readObject();
181
182 if ( o instanceof Pair )
183 {
184 _channels = (Pair) o;
185 }
186
187 decoder.close();
188 }
189
190 public int checkChannel( int channelIndex )
191 throws MalformedURLException, SAXException, IOException, ParserConfigurationException
192 {
193 Channel channel = (Channel) getSubscribedChannels().get( channelIndex );
194
195 int itemCount = channel.getItems() == null ? 0 : channel.getItems().size();
196 SimpleRSSParser.parse( channel );
197 int newItems = channel.getItems().size() - itemCount;
198
199 fireChannelUpdated( channelIndex );
200
201 return newItems;
202 }
203
204 public void fireChannelUpdated( Channel channel )
205 {
206 int index = getSubscribedChannels().indexOf( channel );
207 if ( index >= 0 )
208 {
209 fireChannelUpdated( index );
210 }
211 }
212
213 private void fireChannelUpdated( int channelIndex )
214 {
215 fireIntervalChanged( channelIndex, channelIndex );
216 }
217
218 /***
219 * Add a channel. All channels start off subscribed.
220 *
221 * @param c
222 */
223 public void addChannel( Channel c )
224 {
225
226
227 if ( ! getSubscribedChannels().contains( c ) &&
228 ! getUnsubscribedChannels().contains( c ) )
229 {
230 List subscribedChannels = getSubscribedChannels();
231 subscribedChannels.add( c );
232 fireIntervalAdded( subscribedChannels.size() - 1, subscribedChannels.size() - 1 );
233 }
234 }
235
236 public void removeChannel( Channel c )
237 {
238 int pos = getSubscribedChannels().indexOf( c );
239 if ( pos >= 0 )
240 {
241 getSubscribedChannels().remove( pos );
242 fireIntervalRemoved( pos, pos );
243 }
244 else
245 {
246
247 pos = getUnsubscribedChannels().indexOf( c );
248 if ( pos >= 0 )
249 {
250 getUnsubscribedChannels().remove( pos );
251 }
252 }
253 }
254
255 public void setChannelSubscribed( Channel channel, boolean isSubscribed )
256 {
257 List sourceList = isSubscribed ? getUnsubscribedChannels() :
258 getSubscribedChannels();
259
260 int sourceIndex = sourceList.indexOf( channel );
261 if ( sourceIndex >= 0 )
262 {
263 List destList = isSubscribed ? getSubscribedChannels() :
264 getUnsubscribedChannels();
265 destList.add( sourceList.get( sourceIndex ) );
266 sourceList.remove( sourceIndex );
267
268
269
270 if ( isSubscribed )
271 {
272
273 fireIntervalAdded(
274 destList.size() - 1, destList.size() -1 );
275 }
276 else
277 {
278
279 fireIntervalRemoved(
280 sourceIndex, sourceIndex );
281 }
282 }
283 }
284
285 public boolean isChannelSubscribed( Channel channel )
286 {
287 return getSubscribedChannels().contains( channel );
288 }
289
290
291
292
293
294 public Object copyTo(Object target)
295 {
296 final Channels copy =
297 target != null ? (Channels) target : new Channels();
298
299 copy._channels = new Pair();
300 copy._channels.first = new ArrayList( (Collection)_channels.first );
301 copy._channels.second = new ArrayList( (Collection)_channels.second );
302
303
304 return copy;
305 }
306
307 }