001package org.apache.commons.digester3.rss;
002
003/*
004 * Licensed to the Apache Software Foundation (ASF) under one or more
005 * contributor license agreements.  See the NOTICE file distributed with
006 * this work for additional information regarding copyright ownership.
007 * The ASF licenses this file to You under the Apache License, Version 2.0
008 * (the "License"); you may not use this file except in compliance with
009 * the License.  You may obtain a copy of the License at
010 * 
011 *      http://www.apache.org/licenses/LICENSE-2.0
012 * 
013 * Unless required by applicable law or agreed to in writing, software
014 * distributed under the License is distributed on an "AS IS" BASIS,
015 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
016 * See the License for the specific language governing permissions and
017 * limitations under the License.
018 */
019
020import java.io.OutputStream;
021import java.io.OutputStreamWriter;
022import java.io.PrintWriter;
023import java.io.Serializable;
024import java.io.UnsupportedEncodingException;
025import java.io.Writer;
026import java.util.ArrayList;
027
028/**
029 * <p>Implementation object representing a <strong>channel</strong> in the
030 * <em>Rich Site Summary</em> DTD, version 0.91.  This class may be subclassed
031 * to further specialize its behavior.</p>
032 */
033public class Channel
034    implements Serializable
035{
036
037    /**
038     * 
039     */
040    private static final long serialVersionUID = -7358941908590407568L;
041
042    // ----------------------------------------------------- Instance Variables
043
044    /**
045     * The set of items associated with this Channel.
046     */
047    protected ArrayList<Item> items = new ArrayList<Item>();
048
049    /**
050     * The set of skip days for this channel.
051     */
052    protected ArrayList<String> skipDays = new ArrayList<String>();
053
054    /**
055     * The set of skip hours for this channel.
056     */
057    protected ArrayList<String> skipHours = new ArrayList<String>();
058
059    // ------------------------------------------------------------- Properties
060
061    /**
062     * The channel copyright (1-100 characters).
063     */
064    protected String copyright = null;
065
066    public String getCopyright()
067    {
068        return ( this.copyright );
069    }
070
071    public void setCopyright( String copyright )
072    {
073        this.copyright = copyright;
074    }
075
076    /**
077     * The channel description (1-500 characters).
078     */
079    protected String description = null;
080
081    public String getDescription()
082    {
083        return ( this.description );
084    }
085
086    public void setDescription( String description )
087    {
088        this.description = description;
089    }
090
091    /**
092     * The channel description file URL (1-500 characters).
093     */
094    protected String docs = null;
095
096    public String getDocs()
097    {
098        return ( this.docs );
099    }
100
101    public void setDocs( String docs )
102    {
103        this.docs = docs;
104    }
105
106    /**
107     * The image describing this channel.
108     */
109    protected Image image = null;
110
111    public Image getImage()
112    {
113        return ( this.image );
114    }
115
116    public void setImage( Image image )
117    {
118        this.image = image;
119    }
120
121    /**
122     * The channel language (2-5 characters).
123     */
124    protected String language = null;
125
126    public String getLanguage()
127    {
128        return ( this.language );
129    }
130
131    public void setLanguage( String language )
132    {
133        this.language = language;
134    }
135
136    /**
137     * The channel last build date (1-100 characters).
138     */
139    protected String lastBuildDate = null;
140
141    public String getLastBuildDate()
142    {
143        return ( this.lastBuildDate );
144    }
145
146    public void setLastBuildDate( String lastBuildDate )
147    {
148        this.lastBuildDate = lastBuildDate;
149    }
150
151    /**
152     * The channel link (1-500 characters).
153     */
154    protected String link = null;
155
156    public String getLink()
157    {
158        return ( this.link );
159    }
160
161    public void setLink( String link )
162    {
163        this.link = link;
164    }
165
166    /**
167     * The managing editor (1-100 characters).
168     */
169    protected String managingEditor = null;
170
171    public String getManagingEditor()
172    {
173        return ( this.managingEditor );
174    }
175
176    public void setManagingEditor( String managingEditor )
177    {
178        this.managingEditor = managingEditor;
179    }
180
181    /**
182     * The channel publication date (1-100 characters).
183     */
184    protected String pubDate = null;
185
186    public String getPubDate()
187    {
188        return ( this.pubDate );
189    }
190
191    public void setPubDate( String pubDate )
192    {
193        this.pubDate = pubDate;
194    }
195
196    /**
197     * The channel rating (20-500 characters).
198     */
199    protected String rating = null;
200
201    public String getRating()
202    {
203        return ( this.rating );
204    }
205
206    public void setRating( String rating )
207    {
208        this.rating = rating;
209    }
210
211    /**
212     * The text input description for this channel.
213     */
214    protected TextInput textInput = null;
215
216    public TextInput getTextInput()
217    {
218        return ( this.textInput );
219    }
220
221    public void setTextInput( TextInput textInput )
222    {
223        this.textInput = textInput;
224    }
225
226    /**
227     * The channel title (1-100 characters).
228     */
229    protected String title = null;
230
231    public String getTitle()
232    {
233        return ( this.title );
234    }
235
236    public void setTitle( String title )
237    {
238        this.title = title;
239    }
240
241    /**
242     * The RSS specification version number used to create this Channel.
243     */
244    protected double version = 0.91;
245
246    public double getVersion()
247    {
248        return ( this.version );
249    }
250
251    public void setVersion( double version )
252    {
253        this.version = version;
254    }
255
256    /**
257     * The webmaster email address (1-100 characters).
258     */
259    protected String webMaster = null;
260
261    public String getWebMaster()
262    {
263        return ( this.webMaster );
264    }
265
266    public void setWebMaster( String webMaster )
267    {
268        this.webMaster = webMaster;
269    }
270
271    // --------------------------------------------------------- Public Methods
272
273    /**
274     * Add an additional item.
275     *
276     * @param item The item to be added
277     */
278    public void addItem( Item item )
279    {
280        synchronized ( items )
281        {
282            items.add( item );
283        }
284    }
285
286    /**
287     * Add an additional skip day name.
288     *
289     * @param skipDay The skip day to be added
290     */
291    public void addSkipDay( String skipDay )
292    {
293        synchronized ( skipDays )
294        {
295            skipDays.add( skipDay );
296        }
297    }
298
299    /**
300     * Add an additional skip hour name.
301     *
302     * @param skipHour The skip hour to be added
303     */
304    public void addSkipHour( String skipHour )
305    {
306        synchronized ( skipHours )
307        {
308            skipHours.add( skipHour );
309        }
310    }
311
312    /**
313     * Return the items for this channel.
314     */
315    public Item[] findItems()
316    {
317        synchronized ( items )
318        {
319            Item items[] = new Item[this.items.size()];
320            return this.items.toArray( items );
321        }
322    }
323
324    /**
325     * Return the items for this channel.
326     */
327    public Item[] getItems()
328    {
329        return findItems();
330    }
331
332    /**
333     * Return the skip days for this channel.
334     */
335    public String[] findSkipDays()
336    {
337        synchronized ( skipDays )
338        {
339            String skipDays[] = new String[this.skipDays.size()];
340            return this.skipDays.toArray( skipDays );
341        }
342    }
343
344    /**
345     * Return the skip hours for this channel.
346     */
347    public String[] getSkipHours()
348    {
349        return findSkipHours();
350    }
351
352    /**
353     * Return the skip hours for this channel.
354     */
355    public String[] findSkipHours()
356    {
357        synchronized ( skipHours )
358        {
359            String skipHours[] = new String[this.skipHours.size()];
360            return this.skipHours.toArray( skipHours );
361        }
362    }
363
364    /**
365     * Return the skip days for this channel.
366     */
367    public String[] getSkipDays()
368    {
369        return findSkipDays();
370    }
371
372    /**
373     * Remove an item for this channel.
374     *
375     * @param item The item to be removed
376     */
377    public void removeItem( Item item )
378    {
379        synchronized ( items )
380        {
381            items.remove( item );
382        }
383    }
384
385    /**
386     * Remove a skip day for this channel.
387     *
388     * @param skipDay The skip day to be removed
389     */
390    public void removeSkipDay( String skipDay )
391    {
392        synchronized ( skipDays )
393        {
394            skipDays.remove( skipDay );
395        }
396    }
397
398    /**
399     * Remove a skip hour for this channel.
400     *
401     * @param skipHour The skip hour to be removed
402     */
403    public void removeSkipHour( String skipHour )
404    {
405        synchronized ( skipHours )
406        {
407            skipHours.remove( skipHour );
408        }
409    }
410
411    /**
412     * Render this channel as XML conforming to the RSS 0.91 specification,
413     * to the specified output stream, with no indication of character
414     * encoding.
415     *
416     * @param stream The output stream to write to
417     */
418    public void render( OutputStream stream )
419    {
420        try
421        {
422            render( stream, null );
423        }
424        catch ( UnsupportedEncodingException e )
425        {
426            // Can not happen
427        }
428    }
429
430    /**
431     * Render this channel as XML conforming to the RSS 0.91 specification,
432     * to the specified output stream, with the specified character encoding.
433     *
434     * @param stream The output stream to write to
435     * @param encoding The character encoding to declare, or <code>null</code>
436     *  for no declaration
437     *
438     * @exception UnsupportedEncodingException if the named encoding
439     *  is not supported
440     */
441    public void render( OutputStream stream, String encoding )
442        throws UnsupportedEncodingException
443    {
444        PrintWriter pw = null;
445        if ( encoding == null )
446        {
447            pw = new PrintWriter( stream );
448        }
449        else
450        {
451            pw = new PrintWriter( new OutputStreamWriter( stream, encoding ) );
452        }
453        render( pw, encoding );
454        pw.flush();
455    }
456
457    /**
458     * Render this channel as XML conforming to the RSS 0.91 specification,
459     * to the specified writer, with no indication of character encoding.
460     *
461     * @param writer The writer to render output to
462     */
463    public void render( Writer writer )
464    {
465        render( writer, null );
466    }
467
468    /**
469     * Render this channel as XML conforming to the RSS 0.91 specification,
470     * to the specified writer, indicating the specified character encoding.
471     *
472     * @param writer The writer to render output to
473     * @param encoding The character encoding to declare, or <code>null</code>
474     *  for no declaration
475     */
476    public void render( Writer writer, String encoding )
477    {
478        PrintWriter pw = new PrintWriter( writer );
479        render( pw, encoding );
480        pw.flush();
481    }
482
483    /**
484     * Render this channel as XML conforming to the RSS 0.91 specification,
485     * to the specified writer, with no indication of character encoding.
486     *
487     * @param writer The writer to render output to
488     */
489    public void render( PrintWriter writer )
490    {
491        render( writer, null );
492    }
493
494    /**
495     * Render this channel as XML conforming to the RSS 0.91 specification,
496     * to the specified writer, indicating the specified character encoding.
497     *
498     * @param writer The writer to render output to
499     * @param encoding The character encoding to declare, or <code>null</code>
500     *  for no declaration
501     */
502    public void render( PrintWriter writer, String encoding )
503    {
504        writer.print( "<?xml version=\"1.0\"" );
505        if ( encoding != null )
506        {
507            writer.print( " encoding=\"" );
508            writer.print( encoding );
509            writer.print( "\"" );
510        }
511        writer.println( "?>" );
512        writer.println();
513
514        writer.println( "<rss version=\"0.91\">" );
515        writer.println();
516
517        writer.println( "  <channel>" );
518        writer.println();
519
520        writer.print( "    <title>" );
521        writer.print( title );
522        writer.println( "</title>" );
523
524        writer.print( "    <description>" );
525        writer.print( description );
526        writer.println( "</description>" );
527
528        writer.print( "    <link>" );
529        writer.print( link );
530        writer.println( "</link>" );
531
532        writer.print( "    <language>" );
533        writer.print( language );
534        writer.println( "</language>" );
535
536        if ( rating != null )
537        {
538            writer.print( "    <rating>" );
539            writer.print( rating );
540            writer.println( "</rating>" );
541        }
542
543        if ( copyright != null )
544        {
545            writer.print( "    <copyright>" );
546            writer.print( copyright );
547            writer.print( "</copyright>" );
548        }
549
550        if ( pubDate != null )
551        {
552            writer.print( "    <pubDate>" );
553            writer.print( pubDate );
554            writer.println( "</pubDate>" );
555        }
556
557        if ( lastBuildDate != null )
558        {
559            writer.print( "    <lastBuildDate>" );
560            writer.print( lastBuildDate );
561            writer.println( "</lastBuildDate>" );
562        }
563
564        if ( docs != null )
565        {
566            writer.print( "    <docs>" );
567            writer.print( docs );
568            writer.println( "</docs>" );
569        }
570
571        if ( managingEditor != null )
572        {
573            writer.print( "    <managingEditor>" );
574            writer.print( managingEditor );
575            writer.println( "</managingEditor>" );
576        }
577
578        if ( webMaster != null )
579        {
580            writer.print( "    <webMaster>" );
581            writer.print( webMaster );
582            writer.println( "</webMaster>" );
583        }
584
585        writer.println();
586
587        if ( image != null )
588        {
589            image.render( writer );
590            writer.println();
591        }
592
593        if ( textInput != null )
594        {
595            textInput.render( writer );
596            writer.println();
597        }
598
599        String skipDays[] = findSkipDays();
600        if ( skipDays.length > 0 )
601        {
602            writer.println( "    <skipDays>" );
603            for ( int i = 0; i < skipDays.length; i++ )
604            {
605                writer.print( "      <skipDay>" );
606                writer.print( skipDays[i] );
607                writer.println( "</skipDay>" );
608            }
609            writer.println( "    </skipDays>" );
610        }
611
612        String skipHours[] = findSkipHours();
613        if ( skipHours.length > 0 )
614        {
615            writer.println( "    <skipHours>" );
616            for ( int i = 0; i < skipHours.length; i++ )
617            {
618                writer.print( "      <skipHour>" );
619                writer.print( skipHours[i] );
620                writer.println( "</skipHour>" );
621            }
622            writer.println( "    </skipHours>" );
623            writer.println();
624        }
625
626        Item items[] = findItems();
627        for ( int i = 0; i < items.length; i++ )
628        {
629            items[i].render( writer );
630            writer.println();
631        }
632
633        writer.println( "  </channel>" );
634        writer.println();
635
636        writer.println( "</rss>" );
637    }
638
639}