Coverage Report - org.apache.commons.feedparser.RSSFeedParser
 
Classes in this File Line Coverage Branch Coverage Complexity
RSSFeedParser
0%
0/101
0%
0/36
5.2
 
 1  
 /*
 2  
  * Copyright 1999,2004 The Apache Software Foundation.
 3  
  * 
 4  
  * Licensed under the Apache License, Version 2.0 (the "License");
 5  
  * you may not use this file except in compliance with the License.
 6  
  * You may obtain a copy of the License at
 7  
  * 
 8  
  *      http://www.apache.org/licenses/LICENSE-2.0
 9  
  * 
 10  
  * Unless required by applicable law or agreed to in writing, software
 11  
  * distributed under the License is distributed on an "AS IS" BASIS,
 12  
  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 13  
  * See the License for the specific language governing permissions and
 14  
  * limitations under the License.
 15  
  */
 16  
 
 17  
 package org.apache.commons.feedparser;
 18  
 
 19  
 import java.util.Iterator;
 20  
 import java.util.List;
 21  
 
 22  
 import org.jaxen.jdom.JDOMXPath;
 23  
 import org.jdom.Attribute;
 24  
 import org.jdom.Element;
 25  
 
 26  
 /**
 27  
  * Handles parsing RSS .
 28  
  *
 29  
  * @author <a href="mailto:burton@apache.org">Kevin A. Burton (burtonator)</a>
 30  
  * @version $Id: RSSFeedParser.java 373614 2006-01-30 22:31:21Z mvdb $
 31  
  */
 32  0
 public class RSSFeedParser extends BaseParser {
 33  
 
 34  
     /**
 35  
      * Parse the given document as an OPML document.
 36  
      *
 37  
      * 
 38  
      */
 39  
     public static void parse( FeedParserListener listener,
 40  
                               org.jdom.Document doc ) throws Exception {
 41  
 
 42  0
         FeedParserState state = new FeedParserState( listener );
 43  
 
 44  0
         FeedVersion v = new FeedVersion();
 45  
 
 46  0
         v.isRSS = true;
 47  0
         v.version = doc.getRootElement().getAttributeValue( "version" );
 48  
         
 49  0
         listener.onFeedVersion( v );
 50  
 
 51  0
         listener.init();
 52  
 
 53  
         //*** now process the channel. ***
 54  0
         JDOMXPath xpath = new JDOMXPath( "/descendant::*[local-name() = 'channel']" );
 55  0
         Element channel = (Element)xpath.selectSingleNode( doc );
 56  0
         state.current = channel;
 57  
 
 58  0
         doLocale( state, listener, channel );
 59  0
         doChannel( listener, state );
 60  0
         doLocaleEnd( state, listener, channel );
 61  
 
 62  
         //*** now process the image. ***
 63  0
         xpath = new JDOMXPath( "/descendant::*[local-name() = 'image']" );
 64  0
         List images = xpath.selectNodes( doc );
 65  0
         Iterator i = images.iterator();
 66  
         //update items.
 67  0
         while ( i.hasNext() ) {
 68  
 
 69  0
             Element child = (Element)i.next();
 70  0
             state.current = child;
 71  0
             doParseImage( listener, state );
 72  
 
 73  0
         }
 74  
 
 75  
         //*** now process all items. ***
 76  0
         xpath = new JDOMXPath( "/descendant::*[local-name() = 'item']" );
 77  
 
 78  0
         List items = xpath.selectNodes( doc );
 79  
 
 80  0
         i = items.iterator();
 81  
             
 82  
         //update items.
 83  0
         while ( i.hasNext() ) {
 84  
 
 85  0
             Element item = (Element)i.next();
 86  
 
 87  0
             state.current = item;
 88  
                 
 89  0
             doLocale( state, listener, item );
 90  0
             doItem( listener, state );
 91  0
             doLocaleEnd( state, listener, item );
 92  
 
 93  0
         }
 94  
 
 95  0
         listener.finished();
 96  
 
 97  0
     }
 98  
     
 99  
     /**
 100  
      * Parse the given channel 
 101  
      *
 102  
      * 
 103  
      */
 104  
     private static void doChannel( FeedParserListener listener,
 105  
                                    FeedParserState state ) throws Exception {
 106  
 
 107  0
         String link = getChildElementTextByName( state, "link" );
 108  
 
 109  0
         if ( link != null )
 110  0
             link = link.trim();
 111  
         
 112  0
         listener.onChannel( state, 
 113  
                             getChildElementTextByName( state, "title" ),
 114  
                             link,
 115  
                             getChildElementTextByName( state, "description" ) );
 116  
 
 117  0
         listener.onChannelEnd();
 118  
 
 119  0
     }
 120  
 
 121  
     /**
 122  
      * Parse the given channel 
 123  
      *
 124  
      * 
 125  
      */
 126  
     private static void doParseImage( FeedParserListener listener,
 127  
                                       FeedParserState state ) throws Exception {
 128  
 
 129  0
         String title = getChildElementTextByName( state, "title" );
 130  0
         String link = getChildElementTextByName( state, "link" );
 131  0
         String url = getChildElementTextByName( state, "url" );
 132  
 
 133  0
         if ( url != null ) {
 134  0
             listener.onImage( state, title, link, url );
 135  0
             listener.onImageEnd();
 136  
 
 137  
         } 
 138  
 
 139  0
     }
 140  
 
 141  
     /**
 142  
      * 
 143  
      *
 144  
      * 
 145  
      */
 146  
     private static void doItem( FeedParserListener listener,
 147  
                                 FeedParserState state ) throws Exception {
 148  
 
 149  0
         String resource = null;
 150  
 
 151  
         //FIXME: migrate this to XPath
 152  
 
 153  0
         JDOMXPath xpath = new JDOMXPath( "@rdf:resource|guid|descendant::*[local-name() = 'link']" );
 154  0
         xpath.addNamespace( NS.RDF.getPrefix(), NS.RDF.getURI() );
 155  0
         Object node = xpath.selectSingleNode( state.current );
 156  
 
 157  
         //FIXME: if this is a GUID and isPermalink=false don't use it as the
 158  
         //permalink.
 159  
 
 160  0
         if ( node instanceof Element ) {
 161  
 
 162  0
             Element element = (Element)node;
 163  0
             resource = element.getText();
 164  
 
 165  0
             if ( "guid".equals( element.getName() ) ) {
 166  
 
 167  0
                 boolean isPermaLink =
 168  
                     "true".equals( element.getAttributeValue( "isPermaLink" ) );
 169  
 
 170  0
                 if ( isPermaLink == false ) {
 171  
                     //resort to the 'link'
 172  
 
 173  0
                     Element link = state.current.getChild( "link" );
 174  
 
 175  0
                     if ( link != null ) {
 176  0
                         resource = link.getText();
 177  
                     }
 178  
                     
 179  
                 }
 180  
                 
 181  
             }
 182  
 
 183  0
         } else if ( node instanceof Attribute ) {
 184  0
             resource = ((Attribute)node).getValue();
 185  
         }
 186  
 
 187  0
         if ( resource == null )
 188  0
             return;
 189  
 
 190  
         //title, link, description
 191  
 
 192  0
         listener.onItem( state,
 193  
                          getChildElementTextByName( state, "title" ),
 194  
                          getChildElementTextByName( state, "link" ),
 195  
                          getChildElementTextByName( state, "description" ),
 196  
                          resource );
 197  
 
 198  
         //see if we have content encoded and if we need to report these events.
 199  
 
 200  0
         if ( listener instanceof ModContentFeedParserListener ) {
 201  
 
 202  0
             ModContentFeedParserListener mcpl = (ModContentFeedParserListener)listener;
 203  
 
 204  0
             Element encoded = state.current.getChild( "encoded", NS.CONTENT );
 205  
 
 206  0
             if ( encoded != null ) {
 207  
 
 208  
                 //FIXME: move to the onContent API defined within the
 209  
                 //AtomFeedParser and deprecated this body handling.
 210  
 
 211  0
                 mcpl.onContentEncoded( new FeedParserState( encoded ),
 212  
                                        encoded.getText() );
 213  
 
 214  0
                 mcpl.onContentEncodedEnd();
 215  
 
 216  
             } else {
 217  
 
 218  0
                 Element items = state.current.getChild( "items", NS.CONTENT );
 219  
 
 220  0
                 if ( items != null ) {
 221  
 
 222  
                     //FIXME: with malformed XML this could throw an NPE. Luckly
 223  
                     //this format is rare now.
 224  0
                     Element value =
 225  
                         items.getChild( "Bag", NS.RDF )
 226  
                             .getChild( "li", NS.RDF )
 227  
                                 .getChild( "item", NS.CONTENT )
 228  
                                     .getChild( "value", NS.RDF );
 229  
 
 230  
                     //FIXME: move to the onContent API defined within the
 231  
                     //AtomFeedParser and deprecated this body handling.
 232  
 
 233  0
                     mcpl.onContentItem( new FeedParserState( value ),
 234  
                                         null,
 235  
                                         null,
 236  
                                         value );
 237  
 
 238  0
                     mcpl.onContentItemEnd();
 239  
 
 240  
                 }
 241  
                     
 242  
             }
 243  
 
 244  
         } 
 245  
 
 246  
         //process xhtml:body
 247  
 
 248  0
         if ( listener instanceof XHTMLFeedParserListener ) {
 249  
 
 250  0
             XHTMLFeedParserListener xfp = (XHTMLFeedParserListener)listener;
 251  
 
 252  0
             Element body = state.current.getChild( "body", NS.XHTML );
 253  
 
 254  
             //FIXME: move to the onContent API defined within the AtomFeedParser
 255  
             //and deprecated this body handling.
 256  
             
 257  0
             if ( body != null ) {
 258  0
                 xfp.onXHTMLBody( new FeedParserState( body ),
 259  
                                  body );
 260  0
                 xfp.onXHTMLBodyEnd();
 261  
             } 
 262  
 
 263  
         }
 264  
 
 265  0
         MetaFeedParser.parse( listener, state );
 266  0
         TagFeedParser.parse( listener, state );
 267  
 
 268  0
         doEnclosures( listener, state );
 269  
         
 270  0
         listener.onItemEnd();
 271  
         
 272  0
     }
 273  
 
 274  
     private static void doEnclosures( FeedParserListener listener,
 275  
                                       FeedParserState state ) throws Exception {
 276  
 
 277  0
         if ( listener instanceof LinkFeedParserListener == false )
 278  0
             return;
 279  
 
 280  0
         Element element = state.current.getChild( "enclosure" );
 281  
 
 282  0
         if ( element == null )
 283  0
             return;
 284  
 
 285  0
         LinkFeedParserListener linkFeedParserListener = (LinkFeedParserListener)listener;
 286  
 
 287  0
         String rel = null;
 288  0
         String type = element.getAttributeValue( "type" );
 289  0
         String href = element.getAttributeValue( "url" );
 290  0
         String title = null;
 291  0
         long length = 0;
 292  0
         if (element.getAttributeValue("length") != null)
 293  0
                 length = Integer.parseInt( element.getAttributeValue( "length" ) );
 294  
 
 295  0
         linkFeedParserListener.onLink( state,
 296  
                                        rel,
 297  
                                        type,
 298  
                                        href,
 299  
                                        title,
 300  
                                        length );
 301  
         
 302  0
     }
 303  
     
 304  
 }