View Javadoc

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      // Must always copy listener lists.
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      // Must always copy listener lists.
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     // Must always copy listener lists.
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     // Only allow a channel to be added if it's not already subscribed or 
226     // unsubscribed.
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       // See if it's an unsubscribed one.
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       // We need to fire an event to indicate what happened to the subscribed
269       // list only.
270       if ( isSubscribed )
271       {
272         // If isSubscribed, a channel was added to the subscribed list
273         fireIntervalAdded(  
274           destList.size() - 1, destList.size() -1 );
275       }
276       else
277       {
278         // Else, a channel was removed.
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 // Copyable interface
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 }