View Javadoc

1   package org.robsite.extension.rss.model;
2   
3   import java.io.IOException;
4   import java.io.InputStream;
5   
6   import java.util.Collections;
7   import java.util.HashSet;
8   import java.util.Iterator;
9   import java.util.Set;
10  
11  import javax.xml.parsers.ParserConfigurationException;
12  import javax.xml.parsers.SAXParser;
13  import javax.xml.parsers.SAXParserFactory;
14  
15  import org.xml.sax.Attributes;
16  import org.xml.sax.InputSource;
17  import org.xml.sax.SAXException;
18  import org.xml.sax.XMLReader;
19  import org.xml.sax.helpers.DefaultHandler;
20  
21  /***
22   * DirectoryParser scans the newsdirectory.xml file and determines which 
23   * channels are available.
24   * 
25   * @author brian_duff@users.sourceforge.net
26   * @version $Revision: 1.1.1.1 $
27   */
28  public class DirectoryParser 
29  {
30    private final static String URI =  
31      "http://xmlns.oracle.com/jdeveloper/905/newsdir";
32  
33    /***
34     * Parse the directory xml file from the specified stream and update the
35     * channels
36     * 
37     * @param directoryXML
38     * @param channels
39     */
40    public void parse( InputStream inStream, Channels channels )
41      throws SAXException, IOException, ParserConfigurationException
42    {
43      InputSource inputSource = new InputSource( inStream );
44      
45      SAXParserFactory factory = SAXParserFactory.newInstance();
46      SAXParser parser = factory.newSAXParser();
47      XMLReader reader = parser.getXMLReader();
48      DirectoryHandler handler = new DirectoryHandler();
49      
50      reader.setContentHandler( handler );
51      reader.setErrorHandler( handler );
52      reader.parse( inputSource );
53      
54      Set simpleChannels = handler.getSimpleChannels();
55      if ( simpleChannels == null )
56      {
57        simpleChannels = Collections.EMPTY_SET;
58      }
59      
60      // We make a pass through channels. Any channel which is not
61      // in the set of simpleChannels is removed from channels. If it's in both,
62      // it's removed from simpleChannels. The channels that remain in 
63      // simpleChannels after this loop are new channels that need to be added.
64      
65      for ( Iterator i = channels.getAllChannels().iterator(); i.hasNext(); )
66      {
67        Channel thisChannel = (Channel) i.next();
68        
69        if ( !containsChannel( simpleChannels, thisChannel ) )
70        {
71          // The channel is a target for removal, because it's not on the 
72          // directory. But we allow user-defined channels to remain.
73          if ( !thisChannel.isUserChannel() )
74          {
75            channels.removeChannel( thisChannel );
76          }
77        }
78      }    
79      
80      // Now we have a set of SimpleChannels that need to be added as new
81      // channels.
82      for ( Iterator i = simpleChannels.iterator(); i.hasNext(); )
83      {
84        SimpleChannel simpleChannel = (SimpleChannel) i.next();
85        Channel channel = new Channel();
86        channel.setTitle( simpleChannel.title );
87        channel.setURL( simpleChannel.url );
88        
89        channels.addChannel( channel );
90      }
91    }
92    
93    private boolean containsChannel( Set simpleChannels, Channel channel )
94    {
95      for ( Iterator i = simpleChannels.iterator(); i.hasNext(); )
96      {
97        SimpleChannel simple = (SimpleChannel) i.next();
98        if ( simple.url.equals( channel.getURL() ) )
99        {
100         i.remove();
101         return true;
102       }
103     }
104     
105     return false;
106   }
107   
108   private class DirectoryHandler extends DefaultHandler
109   {
110     private Set m_channels = null;
111     private SimpleChannel m_currentChannel = null;
112     private StringBuffer m_text = null;
113   
114     public Set getSimpleChannels()
115     {
116       return m_channels;
117     }
118   
119     public void startElement( String uri, String name, String qName, 
120       Attributes attributes )
121     {
122       if ( URI.equals( uri ) )
123       {
124         if ( "directory".equals( name ) )
125         {
126           m_channels = new HashSet();
127         }
128         else if ( "channel".equals( name ) )
129         {
130           m_currentChannel = new SimpleChannel();
131         }
132         else if ( "url".equals( name ) || "title".equals( name ) )
133         {
134           m_text = new StringBuffer();
135         }
136       }
137     }
138     
139     public void endElement( String uri, String name, String qName )
140     {
141       if ( URI.equals( uri ) )
142       {
143         if ( "channel".equals( name ) )
144         {
145           m_channels.add( m_currentChannel );
146           m_currentChannel = null;
147         }
148         else if ( "url".equals( name ) )
149         {
150           m_currentChannel.url = m_text.toString().trim();
151         }
152         else if ( "title".equals( name ) )
153         {
154           m_currentChannel.title = m_text.toString().trim();
155         }
156       }
157     }
158     
159     public void characters( char[] chars, int start, int length )
160     {
161       if ( m_text != null )
162       {
163         m_text.append( chars, start, length );
164       }
165     }
166   }
167   
168   private class SimpleChannel
169   {
170     private String url;
171     private String title;
172   }
173 }