View Javadoc

1   package org.apache.commons.digester3.rss;
2   
3   /*
4    * Licensed to the Apache Software Foundation (ASF) under one or more
5    * contributor license agreements.  See the NOTICE file distributed with
6    * this work for additional information regarding copyright ownership.
7    * The ASF licenses this file to You under the Apache License, Version 2.0
8    * (the "License"); you may not use this file except in compliance with
9    * the License.  You may obtain a copy of the License at
10   * 
11   *      http://www.apache.org/licenses/LICENSE-2.0
12   * 
13   * Unless required by applicable law or agreed to in writing, software
14   * distributed under the License is distributed on an "AS IS" BASIS,
15   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16   * See the License for the specific language governing permissions and
17   * limitations under the License.
18   */
19  
20  import java.io.File;
21  import java.io.IOException;
22  import java.io.InputStream;
23  
24  import org.apache.commons.digester3.Digester;
25  import org.apache.commons.logging.LogFactory;
26  import org.xml.sax.InputSource;
27  import org.xml.sax.SAXException;
28  
29  
30  /**
31   * <p>Implementation of <strong>org.apache.commons.digester3.Digester</strong>
32   * designed to process input streams that conform to the <em>Rich Site
33   * Summary</em> DTD, version 0.91.  For more information about this format,
34   * see the <a href="http://my.netscape.com/publish/">My Netscape</a> site.</p>
35   *
36   * <p>The default implementation object returned by calling
37   * <code>parse()</code> (an instance of
38   * <code>org.apache.commons.digester3.rss.Channel</code>)
39   * knows how to render itself in XML format via the <code>render()</code>
40   * method.  See the test <code>main()</code> method below for an
41   * example of using these classes.</p>
42   */
43  
44  public class RSSDigester
45      extends Digester
46  {
47  
48      // ----------------------------------------------------------- Constructors
49  
50      // ----------------------------------------------------- Instance Variables
51  
52      /**
53       * Have we been configured yet?
54       */
55      protected boolean configured = false;
56  
57      // ------------------------------------------------------------- Properties
58  
59      /**
60       * The fully qualified class name of the <code>Channel</code>
61       * implementation class.
62       */
63      protected String channelClass = "org.apache.commons.digester3.rss.Channel";
64  
65      public String getChannelClass()
66      {
67          return ( this.channelClass );
68      }
69  
70      public void setChannelClass( String channelClass )
71      {
72          this.channelClass = channelClass;
73      }
74  
75      /**
76       * The fully qualified class name of the <code>Image</code>
77       * implementation class.
78       */
79      protected String imageClass = "org.apache.commons.digester3.rss.Image";
80  
81      public String getImageClass()
82      {
83          return ( this.imageClass );
84      }
85  
86      public void setImageClass( String imageClass )
87      {
88          this.imageClass = imageClass;
89      }
90  
91      /**
92       * The fully qualified class name of the <code>Item</code>
93       * implementation class.
94       */
95      protected String itemClass = "org.apache.commons.digester3.rss.Item";
96  
97      public String getItemClass()
98      {
99          return ( this.itemClass );
100     }
101 
102     public void setItemClass( String itemClass )
103     {
104         this.itemClass = itemClass;
105     }
106 
107     /**
108      * The fully qualified class name of the <code>TextInput</code>
109      * implementation class.
110      */
111     protected String textInputClass = "org.apache.commons.digester3.rss.TextInput";
112 
113     public String getTextInputClass()
114     {
115         return ( this.textInputClass );
116     }
117 
118     public void setTextInputClass( String textInputClass )
119     {
120         this.textInputClass = textInputClass;
121     }
122 
123     // --------------------------------------------------------- Public Methods
124 
125     /**
126      * Parse the content of the specified file using this Digester.  Returns
127      * the root element from the object stack (which will be the Channel).
128      *
129      * @param file File containing the XML data to be parsed
130      *
131      * @exception IOException if an input/output error occurs
132      * @exception SAXException if a parsing exception occurs
133      */
134     @Override
135     public <T> T parse( File file )
136         throws IOException, SAXException
137     {
138         configure();
139         return ( super.<T>parse( file ) );
140     }
141 
142     /**
143      * Parse the content of the specified input source using this Digester.
144      * Returns the root element from the object stack (which will be the
145      * Channel).
146      *
147      * @param input Input source containing the XML data to be parsed
148      *
149      * @exception IOException if an input/output error occurs
150      * @exception SAXException if a parsing exception occurs
151      */
152     @Override
153     public <T> T parse( InputSource input )
154         throws IOException, SAXException
155     {
156         configure();
157         return ( super.<T>parse( input ) );
158     }
159 
160 
161     /**
162      * Parse the content of the specified input stream using this Digester.
163      * Returns the root element from the object stack (which will be
164      * the Channel).
165      *
166      * @param input Input stream containing the XML data to be parsed
167      *
168      * @exception IOException if an input/output error occurs
169      * @exception SAXException if a parsing exception occurs
170      */
171     @Override
172     public <T> T parse( InputStream input )
173         throws IOException, SAXException
174     {
175         configure();
176         return ( super.<T>parse( input ) );
177     }
178 
179     /**
180      * Parse the content of the specified URI using this Digester.
181      * Returns the root element from the object stack (which will be
182      * the Channel).
183      *
184      * @param uri URI containing the XML data to be parsed
185      *
186      * @exception IOException if an input/output error occurs
187      * @exception SAXException if a parsing exception occurs
188      */
189     @Override
190     public <T> T parse( String uri )
191         throws IOException, SAXException
192     {
193         configure();
194         return ( super.<T>parse( uri ) );
195     }
196 
197     // -------------------------------------------------------- Package Methods
198 
199     // ------------------------------------------------------ Protected Methods
200 
201     /**
202      * Configure the parsing rules that will be used to process RSS input.
203      */
204     @Override
205     protected void configure()
206     {
207         if ( configured )
208         {
209             return;
210         }
211 
212         // FIXME - validate the "version" attribute of the rss element?
213 
214         // Add the rules for the Channel object
215         addObjectCreate( "rss/channel", channelClass );
216         addCallMethod( "rss/channel/copyright", "setCopyright", 0 );
217         addCallMethod( "rss/channel/description", "setDescription", 0 );
218         addCallMethod( "rss/channel/docs", "setDocs", 0 );
219         addCallMethod( "rss/channel/language", "setLanguage", 0 );
220         addCallMethod( "rss/channel/lastBuildDate", "setLastBuildDate", 0 );
221         addCallMethod( "rss/channel/link", "setLink", 0 );
222         addCallMethod( "rss/channel/managingEditor", "setManagingEditor", 0 );
223         addCallMethod( "rss/channel/pubDate", "setPubDate", 0 );
224         addCallMethod( "rss/channel/rating", "setRating", 0 );
225         addCallMethod( "rss/channel/skipDays/day", "addSkipDay", 0 );
226         addCallMethod( "rss/channel/skipHours/hour", "addSkipHour", 0 );
227         addCallMethod( "rss/channel/title", "setTitle", 0 );
228         addCallMethod( "rss/channel/webMaster", "setWebMaster", 0 );
229 
230         // Add the rules for the Image object
231         addObjectCreate( "rss/channel/image", imageClass );
232         addSetNext( "rss/channel/image", "setImage", "org.apache.commons.digester3.rss.Image" );
233         addCallMethod( "rss/channel/image/description", "setDescription", 0 );
234         addCallMethod( "rss/channel/image/height", "setHeight", 0, new Class[] { Integer.TYPE } );
235         addCallMethod( "rss/channel/image/link", "setLink", 0 );
236         addCallMethod( "rss/channel/image/title", "setTitle", 0 );
237         addCallMethod( "rss/channel/image/url", "setURL", 0 );
238         addCallMethod( "rss/channel/image/width", "setWidth", 0, new Class[] { Integer.TYPE } );
239 
240         // Add the rules for the Item object
241         addObjectCreate( "rss/channel/item", itemClass );
242         addSetNext( "rss/channel/item", "addItem", "org.apache.commons.digester3.rss.Item" );
243         addCallMethod( "rss/channel/item/description", "setDescription", 0 );
244         addCallMethod( "rss/channel/item/link", "setLink", 0 );
245         addCallMethod( "rss/channel/item/title", "setTitle", 0 );
246 
247         // Add the rules for the TextInput object
248         addObjectCreate( "rss/channel/textinput", textInputClass );
249         addSetNext( "rss/channel/textinput", "setTextInput", "org.apache.commons.digester3.rss.TextInput" );
250         addCallMethod( "rss/channel/textinput/description", "setDescription", 0 );
251         addCallMethod( "rss/channel/textinput/link", "setLink", 0 );
252         addCallMethod( "rss/channel/textinput/name", "setName", 0 );
253         addCallMethod( "rss/channel/textinput/title", "setTitle", 0 );
254 
255         // Mark this digester as having been configured
256         configured = true;
257     }
258 
259     // ------------------------------------------------------ Test Main Program
260 
261     /**
262      * Test main program that parses the channel description included in this
263      * package as a static resource.
264      *
265      * @param args The command line arguments (ignored)
266      */
267     public static void main( String args[] )
268     {
269         try
270         {
271             System.out.println( "RSSDigester Test Program" );
272             System.out.println( "Opening input stream ..." );
273             InputStream is =
274                 RSSDigester.class.getResourceAsStream( "/org/apache/commons/digester3/rss/rss-example.xml" );
275             System.out.println( "Creating new digester ..." );
276             RSSDigester digester = new RSSDigester();
277             if ( ( args.length > 0 ) && ( args[0].equals( "-debug" ) ) )
278             {
279                 digester.setLogger( LogFactory.getLog( "RSSDigester" ) );
280             }
281             System.out.println( "Parsing input stream ..." );
282             Channel channel = (Channel) digester.parse( is );
283             System.out.println( "Closing input stream ..." );
284             is.close();
285             System.out.println( "Dumping channel info ..." );
286             channel.render( System.out );
287         }
288         catch ( Exception e )
289         {
290             System.out.println( "-->Exception" );
291             e.printStackTrace( System.out );
292         }
293     }
294 
295 }