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}