Coverage Report - yarfraw.core.datamodel.ChannelFeed
 
Classes in this File Line Coverage Branch Coverage Complexity
ChannelFeed
74% 
87% 
0
 
 1  
 package yarfraw.core.datamodel;
 2  
 
 3  
 import java.io.IOException;
 4  
 import java.text.SimpleDateFormat;
 5  
 import java.util.ArrayList;
 6  
 import java.util.Arrays;
 7  
 import java.util.Date;
 8  
 import java.util.HashMap;
 9  
 import java.util.HashSet;
 10  
 import java.util.List;
 11  
 import java.util.Locale;
 12  
 import java.util.Map;
 13  
 import java.util.Set;
 14  
 
 15  
 import javax.xml.namespace.QName;
 16  
 import javax.xml.parsers.ParserConfigurationException;
 17  
 
 18  
 import org.apache.commons.collections.CollectionUtils;
 19  
 import org.apache.commons.lang.ArrayUtils;
 20  
 import org.apache.commons.logging.Log;
 21  
 import org.apache.commons.logging.LogFactory;
 22  
 import org.w3c.dom.Element;
 23  
 import org.xml.sax.SAXException;
 24  
 
 25  
 import yarfraw.utils.ValidationUtils;
 26  
 import yarfraw.utils.XMLUtils;
 27  
 /**
 28  
  * 
 29  
  * The name of the channel. It's how people refer to your service. 
 30  
  * If you have an HTML website that contains the same information as your RSS file, 
 31  
  * the title of your channel should be the same as the title of your website.
 32  
  * <p/>
 33  
  * for Atom 1.0 format, the field also maps to &lt;feed> element. 
 34  
  * <br/>
 35  
  * 
 36  
  * <li>Rss 1.0 - &lt;channel> and second level elements  such as &lt;item> elements under &lt;rdf:RDF>
 37  
  * </li>
 38  
  * <li>Rss 2.0 - &lt;channel>
 39  
  * </li>
 40  
  * <li>Atom 1.0 - &lt;feed> The "atom:feed" element is the document (i.e., top-level) element of an Atom Feed Document, 
 41  
  * acting as a container for metadata and data associated with the feed. Its element children consist of metadata 
 42  
  * elements followed by zero or more atom:entry child elements.
 43  
  * </li>
 44  
  * @author jliang
 45  
  *
 46  
  */
 47  2296
 public class ChannelFeed extends AbstractBaseObject{
 48  
   /**
 49  
    * 
 50  
    */
 51  
   private static final long serialVersionUID = 20070927L;
 52  78
   private static final Log LOG = LogFactory.getLog(ChannelFeed.class);
 53  
   private List<ItemEntry> _items;
 54  
   private Text _title;
 55  
   private List<Link> _links;
 56  
   private Text _descriptionOrSubtitle;
 57  
   private Text _rights;
 58  
   private List<Person> _managingEditorOrAuthorOrPublisher;
 59  
   private List<Person> _webMasterOrCreator;
 60  
   private List<Person> _contributors;
 61  
   private Set<CategorySubject> _categorySubjects;
 62  
   private String _pubDate;
 63  
   private String _lastBuildOrUpdatedDate;
 64  
   private Id _uid;
 65  
   private Generator _generator;
 66  
   private String _docs;
 67  
   private Integer _ttl;
 68  
   private Cloud _cloud;
 69  
   private Image _imageOrIcon;
 70  
   private Image _logo;
 71  
   private TextInput _texInput;
 72  
   private Set<Integer> _skipHours;
 73  
   private Set<Day> _skipDays;
 74  
   
 75  
   /**
 76  
    * <li>Rss 1.0 - &lt;item> 
 77  
    * While commonly a news headline, with RSS 1.0's modular extensibility, 
 78  
    * this can be just about anything: discussion posting, job listing, software 
 79  
    * patch -- any object with a URI. There may be a minimum of one item per RSS 
 80  
    * document. While RSS 1.0 does not enforce an upper limit, 
 81  
    * for backward compatibility with RSS 0.9 and 0.91, a maximum of fifteen items is recommended.
 82  
    * </li>
 83  
    * <li>Rss 2.0 - &lt;item> 
 84  
    * A channel may contain any number of <item>s. An item may represent a "story" 
 85  
    * -- much like a story in a newspaper or magazine; if so its description is a 
 86  
    * synopsis of the story, and the link points to the full story. An item may also 
 87  
    * be complete in itself, if so, the description contains the text 
 88  
    * (entity-encoded HTML is allowed; see examples), and the link and title 
 89  
    * may be omitted. All elements of an item are optional, however at least one 
 90  
    * of title or description must be present.
 91  
    * </li>
 92  
    * <li>Atom 1.0 - &lt;entry>
 93  
    * The "atom:entry" element represents an individual entry, acting as a 
 94  
    * container for metadata and data associated with the entry. This element 
 95  
    * can appear as a child of the atom:feed element, or it can appear as the 
 96  
    * document (i.e., top-level) element of a standalone Atom Entry Document.
 97  
    * </li>
 98  
    * @return
 99  
    */
 100  
   public List<ItemEntry> getItems() {
 101  513
     return _items;
 102  
   }
 103  
 
 104  
   /**
 105  
    * <li>Rss 1.0 - &lt;item> 
 106  
    * While commonly a news headline, with RSS 1.0's modular extensibility, 
 107  
    * this can be just about anything: discussion posting, job listing, software 
 108  
    * patch -- any object with a URI. There may be a minimum of one item per RSS 
 109  
    * document. While RSS 1.0 does not enforce an upper limit, 
 110  
    * for backward compatibility with RSS 0.9 and 0.91, a maximum of fifteen items is recommended.
 111  
    * </li>
 112  
    * <li>Rss 2.0 - &lt;item> 
 113  
    * A channel may contain any number of <item>s. An item may represent a "story" 
 114  
    * -- much like a story in a newspaper or magazine; if so its description is a 
 115  
    * synopsis of the story, and the link points to the full story. An item may also 
 116  
    * be complete in itself, if so, the description contains the text 
 117  
    * (entity-encoded HTML is allowed; see examples), and the link and title 
 118  
    * may be omitted. All elements of an item are optional, however at least one 
 119  
    * of title or description must be present.
 120  
    * </li>
 121  
    * <li>Atom 1.0 - &lt;entry>
 122  
    * The "atom:entry" element represents an individual entry, acting as a 
 123  
    * container for metadata and data associated with the entry. This element 
 124  
    * can appear as a child of the atom:feed element, or it can appear as the 
 125  
    * document (i.e., top-level) element of a standalone Atom Entry Document.
 126  
    * </li>
 127  
    * @param items
 128  
    * @return
 129  
    */
 130  
   public ChannelFeed setItems(List<ItemEntry> items) {
 131  54
     _items = items;
 132  54
     return this;
 133  
   }
 134  
 
 135  
   /**
 136  
    * <li>Rss 1.0 - &lt;item> 
 137  
    * While commonly a news headline, with RSS 1.0's modular extensibility, 
 138  
    * this can be just about anything: discussion posting, job listing, software 
 139  
    * patch -- any object with a URI. There may be a minimum of one item per RSS 
 140  
    * document. While RSS 1.0 does not enforce an upper limit, 
 141  
    * for backward compatibility with RSS 0.9 and 0.91, a maximum of fifteen items is recommended.
 142  
    * </li>
 143  
    * <li>Rss 2.0 - &lt;item> 
 144  
    * A channel may contain any number of <item>s. An item may represent a "story" 
 145  
    * -- much like a story in a newspaper or magazine; if so its description is a 
 146  
    * synopsis of the story, and the link points to the full story. An item may also 
 147  
    * be complete in itself, if so, the description contains the text 
 148  
    * (entity-encoded HTML is allowed; see examples), and the link and title 
 149  
    * may be omitted. All elements of an item are optional, however at least one 
 150  
    * of title or description must be present.
 151  
    * </li>
 152  
    * <li>Atom 1.0 - &lt;entry>
 153  
    * The "atom:entry" element represents an individual entry, acting as a 
 154  
    * container for metadata and data associated with the entry. This element 
 155  
    * can appear as a child of the atom:feed element, or it can appear as the 
 156  
    * document (i.e., top-level) element of a standalone Atom Entry Document.
 157  
    * </li>
 158  
    * <br/>
 159  
    * This method adds all the input {@link ItemEntry} to the end of the items list.
 160  
    * @param items
 161  
    * @return
 162  
    */
 163  
   public ChannelFeed addItem(ItemEntry...items){
 164  7342
     if(ArrayUtils.isEmpty(items)){
 165  0
       LOG.warn("Empty items array is ignored");
 166  0
       return this;
 167  
     }
 168  7342
     if(_items == null){
 169  398
       _items = new ArrayList<ItemEntry>();
 170  
     }
 171  14687
     for(ItemEntry item : items){
 172  7345
       _items.add(item);
 173  
     }
 174  7342
     return this;
 175  
   }
 176  
 
 177  
   /**
 178  
    * <li>Rss 1.0 - The channel's title.
 179  
    * </li>
 180  
    * <li>Rss 2.0 - The title of the channel.
 181  
    * </li>
 182  
    * <li>Atom 1.0 - 
 183  
    * The "atom:title" element is a Text construct that conveys a 
 184  
    * human-readable title for an entry or feed.
 185  
    * </li>
 186  
    * <br/>
 187  
    * Note: Rss 1.0 and Rss 2.0 only use the text content of the title field, 
 188  
    * the other fields in the {@link Text} object are ignored.
 189  
    * @return
 190  
    */
 191  
   public Text getTitle() {
 192  340
     return _title;
 193  
   }
 194  
   
 195  
   /**
 196  
    * <li>Rss 1.0 - The channel's title.
 197  
    * </li>
 198  
    * <li>Rss 2.0 - The title of the channel.
 199  
    * </li>
 200  
    * <li>Atom 1.0 - 
 201  
    * The "atom:title" element is a Text construct that conveys a 
 202  
    * human-readable title for an entry or feed.
 203  
    * </li>
 204  
    * <br/>
 205  
    * This method returns the text content of the <code>title</code> field.
 206  
    * @return
 207  
    */
 208  
   public String getTitleText() {
 209  192
     return _title == null ? null :_title.getText();
 210  
   }
 211  
 
 212  
   /**
 213  
    * <li>Rss 1.0 - The channel's title.
 214  
    * </li>
 215  
    * <li>Rss 2.0 - The title of the channel.
 216  
    * </li>
 217  
    * <li>Atom 1.0 - 
 218  
    * The "atom:title" element is a Text construct that conveys a 
 219  
    * human-readable title for an entry or feed.
 220  
    * </li>
 221  
    * <br/>
 222  
    * Note: Rss 1.0 and Rss 2.0 only use the text content of the title field, 
 223  
    * the other fields in the {@link Text} object are ignored.
 224  
    * @param title
 225  
    * @return
 226  
    */
 227  
   public ChannelFeed setTitle(Text title) {
 228  431
     _title = title;
 229  431
     return this;
 230  
   }
 231  
 
 232  
   /**
 233  
    * <li>Rss 1.0 - The channel's title.
 234  
    * </li>
 235  
    * <li>Rss 2.0 - The title of the channel.
 236  
    * </li>
 237  
    * <li>Atom 1.0 - 
 238  
    * The "atom:title" element is a Text construct that conveys a 
 239  
    * human-readable title for an entry or feed.
 240  
    * </li>
 241  
    * <br/>
 242  
    * This method constructs a new {@link Text} object with the input string as its text
 243  
    * content.
 244  
    * <br/>
 245  
    * Note: Rss 1.0 and Rss 2.0 only use the text content of the title field, 
 246  
    * the other fields in the {@link Text} object are ignored.
 247  
    * @param title
 248  
    * @return
 249  
    */
 250  
   public ChannelFeed setTitle(String title){
 251  389
     if(title == null){
 252  0
       _title = null;
 253  0
       return this;
 254  
     }
 255  389
     return setTitle(new Text(title));
 256  
   }
 257  
 
 258  
   /**
 259  
    * <li>Rss 1.0 - The URL to which an HTML rendering of the channel title will link, 
 260  
    * commonly the parent site's home or news page.
 261  
    * </li>
 262  
    * <li>Rss 2.0 - The URL to the HTML website corresponding to the channel.
 263  
    * </li>
 264  
    * <li>Atom 1.0 - 
 265  
    * The "atom:link" element defines a reference from an entry or feed to a Web 
 266  
    * resource. This specification assigns no meaning to the content (if any) of this element.
 267  
    * </li>
 268  
    * 
 269  
    * <br/>
 270  
    * Note: According to the specs, only Atom 1.0 allows multiple links under the {@link ChannelFeed}.
 271  
    * Therefore, for Rss 1.0 and Rss 2.0, only the first link will be interpreted, the rest will be 
 272  
    * ignored.
 273  
    * @return
 274  
    */
 275  
   public List<Link> getLinks() {
 276  141
     return _links;
 277  
   }
 278  
 
 279  
 
 280  
   /**
 281  
    * <li>Rss 1.0 - The URL to which an HTML rendering of the channel title will link, 
 282  
    * commonly the parent site's home or news page.
 283  
    * </li>
 284  
    * <li>Rss 2.0 - The URL to the HTML website corresponding to the channel.
 285  
    * </li>
 286  
    * <li>Atom 1.0 - 
 287  
    * The "atom:link" element defines a reference from an entry or feed to a Web 
 288  
    * resource. This specification assigns no meaning to the content (if any) of this element.
 289  
    * </li>
 290  
    * 
 291  
    * <br/>
 292  
    * Note: According to the specs, only Atom 1.0 allows multiple links under the {@link ChannelFeed}.
 293  
    * Therefore, for Rss 1.0 and Rss 2.0, only the first link will be interpreted, the rest will be 
 294  
    * ignored.
 295  
    * @param links
 296  
    * @return
 297  
    */
 298  
   public ChannelFeed setLinks(List<Link> links) {
 299  0
     _links = links;
 300  0
     return this;
 301  
   }
 302  
 
 303  
 
 304  
   /**
 305  
    * <li>Rss 1.0 - The URL to which an HTML rendering of the channel title will link, 
 306  
    * commonly the parent site's home or news page.
 307  
    * </li>
 308  
    * <li>Rss 2.0 - The URL to the HTML website corresponding to the channel.
 309  
    * </li>
 310  
    * <li>Atom 1.0 - 
 311  
    * The "atom:link" element defines a reference from an entry or feed to a Web 
 312  
    * resource. This specification assigns no meaning to the content (if any) of this element.
 313  
    * </li>
 314  
    * 
 315  
    * <br/>
 316  
    * Note: According to the specs, only Atom 1.0 allows multiple links under the {@link ChannelFeed}.
 317  
    * Therefore, for Rss 1.0 and Rss 2.0, only the first link will be interpreted, the rest will be 
 318  
    * ignored.
 319  
    * <br/>
 320  
    * This method creates new {@link Link} objects and adds them to the END of the links list. 
 321  
    * 
 322  
    * @param href
 323  
    * @return
 324  
    */
 325  
   public ChannelFeed addLink(String... href) {
 326  317
     if(ArrayUtils.isEmpty(href)){
 327  0
       LOG.warn("Empty href array is ignored");
 328  0
       return this;
 329  
     }
 330  317
     if(_links == null){
 331  314
       _links = new ArrayList<Link>();
 332  
     }
 333  634
     for (String s:href){
 334  317
       _links.add(new Link(s));
 335  
     }
 336  317
     return this;
 337  
   }
 338  
 
 339  
   /**
 340  
    * <li>Rss 1.0 - The URL to which an HTML rendering of the channel title will link, 
 341  
    * commonly the parent site's home or news page.
 342  
    * </li>
 343  
    * <li>Rss 2.0 - The URL to the HTML website corresponding to the channel.
 344  
    * </li>
 345  
    * <li>Atom 1.0 - 
 346  
    * The "atom:link" element defines a reference from an entry or feed to a Web 
 347  
    * resource. This specification assigns no meaning to the content (if any) of this element.
 348  
    * </li>
 349  
    * 
 350  
    * <br/>
 351  
    * Note: According to the specs, only Atom 1.0 allows multiple links under the {@link ChannelFeed}.
 352  
    * Therefore, for Rss 1.0 and Rss 2.0, only the first link will be interpreted, the rest will be 
 353  
    * ignored.
 354  
    * <br/>
 355  
    * 
 356  
    * <br/>
 357  
    * This method adds input {@link Link} to the END of the links list. 
 358  
    * 
 359  
    * @param link
 360  
    * @return
 361  
    */
 362  
   public ChannelFeed addLink(Link... link) {
 363  105
     if(ArrayUtils.isEmpty(link)){
 364  0
       LOG.warn("Empty link array is ignored");
 365  0
       return this;
 366  
     }
 367  105
     if(_links == null){
 368  51
       _links = new ArrayList<Link>();
 369  
     }
 370  210
     for(Link l : link){
 371  105
       _links.add(l);
 372  
     }
 373  105
     return this;
 374  
   }
 375  
   
 376  
   /**
 377  
    * <li>Rss 1.0 - &lt;description> 
 378  
    * A brief description of the channel's content, function, source, etc.
 379  
    * </li>
 380  
    * <li>Rss 2.0 - &lt;description> Phrase or sentence describing the channel.
 381  
    * </li>
 382  
    * <li>Atom 1.0 - 
 383  
    * This maps to &lt;subtitle>. 
 384  
    * The "atom:subtitle" element is a Text construct that conveys a human-readable description or subtitle for a feed.
 385  
    * </li>
 386  
    * @return
 387  
    */
 388  
   public Text getDescriptionOrSubtitle() {
 389  30
     return _descriptionOrSubtitle;
 390  
   }
 391  
   
 392  
   /**
 393  
    * <li>Rss 1.0 - &lt;description> 
 394  
    * A brief description of the channel's content, function, source, etc.
 395  
    * </li>
 396  
    * <li>Rss 2.0 - &lt;description> Phrase or sentence describing the channel.
 397  
    * </li>
 398  
    * <li>Atom 1.0 - 
 399  
    * This maps to &lt;subtitle>. 
 400  
    * The "atom:subtitle" element is a Text construct that conveys a human-readable description or subtitle for a feed.
 401  
    * </li>
 402  
    * <br/>
 403  
    * This method returns the text content of the <code>descriptionOrSubtitle</code> field.
 404  
    * @return
 405  
    */
 406  
   public String getDescriptionOrSubtitleText() {
 407  159
     return _descriptionOrSubtitle == null ? null : _descriptionOrSubtitle.getText();
 408  
   }
 409  
 
 410  
   /**
 411  
    * <li>Rss 1.0 - &lt;description> 
 412  
    * A brief description of the channel's content, function, source, etc.
 413  
    * </li>
 414  
    * <li>Rss 2.0 - &lt;description> Phrase or sentence describing the channel.
 415  
    * </li>
 416  
    * <li>Atom 1.0 - 
 417  
    * This maps to &lt;subtitle>. 
 418  
    * The "atom:subtitle" element is a Text construct that conveys a human-readable description or subtitle for a feed.
 419  
    * </li>
 420  
    * @param descriptionOrSubtitle
 421  
    * @return
 422  
    */
 423  
   public ChannelFeed setDescriptionOrSubtitle(Text descriptionOrSubtitle) {
 424  18
     _descriptionOrSubtitle = descriptionOrSubtitle;
 425  18
     return this;
 426  
   }
 427  
 
 428  
   /**
 429  
    * <li>Rss 1.0 - &lt;description> 
 430  
    * A brief description of the channel's content, function, source, etc.
 431  
    * </li>
 432  
    * <li>Rss 2.0 - &lt;description> Phrase or sentence describing the channel.
 433  
    * </li>
 434  
    * <li>Atom 1.0 - 
 435  
    * This maps to &lt;subtitle>. 
 436  
    * The "atom:subtitle" element is a Text construct that conveys a human-readable description or subtitle for a feed.
 437  
    * </li>
 438  
    * 
 439  
    * <br/>
 440  
    * This method constructs a new {@link Text} object with the input string as its text content.
 441  
    * @param descriptionOrSubtitle
 442  
    * @return
 443  
    */
 444  
   public ChannelFeed setDescriptionOrSubtitle(String descriptionOrSubtitle) {
 445  326
     _descriptionOrSubtitle = descriptionOrSubtitle == null? null: new Text(descriptionOrSubtitle);
 446  326
     return this;
 447  
   }
 448  
   
 449  
   /**
 450  
    * <li>Rss 1.0 - &lt;dc:rights> Information about rights held in and over the resource.
 451  
    * </li>
 452  
    * <li>Rss 2.0 - &lt;copyright> Copyright notice for content in the channel.
 453  
    * </li>
 454  
    * <li>Atom 1.0 - &lt;rights> The "atom:rights" element is a Text construct that conveys information about rights held in and over an entry or feed.
 455  
    * </li>
 456  
    * @return
 457  
    */
 458  
   public Text getRights() {
 459  33
     return _rights;
 460  
   }
 461  
   
 462  
 
 463  
   /**
 464  
    * <li>Rss 1.0 - &lt;dc:rights> Information about rights held in and over the resource.
 465  
    * </li>
 466  
    * <li>Rss 2.0 - &lt;copyright> Copyright notice for content in the channel.
 467  
    * </li>
 468  
    * <li>Atom 1.0 - &lt;rights> The "atom:rights" element is a Text construct that conveys information about rights held in and over an entry or feed.
 469  
    * </li>
 470  
    * 
 471  
    * @return the text content of the <code>rights</code> field.
 472  
    */
 473  
   public String getRightsText() {
 474  111
     return _rights == null ? null:_rights.getText();
 475  
   }
 476  
   
 477  
   /**
 478  
    * <li>Rss 1.0 - &lt;dc:rights> Information about rights held in and over the resource.
 479  
    * </li>
 480  
    * <li>Rss 2.0 - &lt;copyright> Copyright notice for content in the channel.
 481  
    * </li>
 482  
    * <li>Atom 1.0 - &lt;rights> The "atom:rights" element is a Text construct that conveys information about rights held in and over an entry or feed.
 483  
    * </li>
 484  
    * @param rights
 485  
    * @return
 486  
    */
 487  
   public ChannelFeed setRights(Text rights) {
 488  140
     _rights = rights;
 489  140
     return this;
 490  
   }
 491  
 
 492  
   /**
 493  
    * <li>Rss 1.0 - &lt;dc:rights> Information about rights held in and over the resource.
 494  
    * </li>
 495  
    * <li>Rss 2.0 - &lt;copyright> Copyright notice for content in the channel.
 496  
    * </li>
 497  
    * <li>Atom 1.0 - &lt;rights> The "atom:rights" element is a Text construct that conveys information about rights held in and over an entry or feed.
 498  
    * </li>
 499  
    * <br/>
 500  
    * This method creates a new {@link Text} object using the input string as its content and sets <code>rights</code> field to this object.
 501  
    * @param rights
 502  
    * @return
 503  
    */
 504  
   public ChannelFeed setRights(String rights) {
 505  119
     if(rights == null){
 506  0
       _rights = null;
 507  0
       return this;
 508  
     }
 509  119
     return setRights(new Text(rights));
 510  
   }
 511  
 
 512  
   /**
 513  
    * <li>Rss 1.0 - &lt;dc:publisher> An entity responsible for making the resource available
 514  
    * </li>
 515  
    * <li>Rss 2.0 - &lt;managingEditor> Email address for person responsible for editorial content.
 516  
    * </li>
 517  
    * <li>Atom 1.0 - &lt;author> 
 518  
    * The "atom:author" element is a Person construct that indicates the author of the entry or feed.
 519  
    * </li>
 520  
    * <br/>
 521  
    * Note: This is a list because Atom 1.0 allows multiple &lt;author>. For Rss 1.0 and Rss 2.0,
 522  
    * only the first {@link Person} is interpreted, the rest are ignored.
 523  
    * @return
 524  
    */
 525  
   public List<Person> getManagingEditorOrAuthorOrPublisher() {
 526  117
     return _managingEditorOrAuthorOrPublisher;
 527  
   }
 528  
 
 529  
   /**
 530  
    * <li>Rss 1.0 - &lt;dc:publisher> An entity responsible for making the resource available
 531  
    * </li>
 532  
    * <li>Rss 2.0 - &lt;managingEditor> Email address for person responsible for editorial content.
 533  
    * </li>
 534  
    * <li>Atom 1.0 - &lt;author> 
 535  
    * The "atom:author" element is a Person construct that indicates the author of the entry or feed.
 536  
    * </li>
 537  
    * <br/>
 538  
    * Note: This is a list because Atom 1.0 allows multiple &lt;author>. For Rss 1.0 and Rss 2.0,
 539  
    * only the first {@link Person} is interpreted, the rest are ignored.
 540  
    * @param managingEditorOrAuthorOrPublisher
 541  
    * @return
 542  
    */
 543  
   public ChannelFeed setManagingEditorOrAuthorOrPublisher(
 544  
       List<Person> managingEditorOrAuthorOrPublisher) {
 545  0
     _managingEditorOrAuthorOrPublisher = managingEditorOrAuthorOrPublisher;
 546  0
     return this;
 547  
   }
 548  
 
 549  
   /**
 550  
    * <li>Rss 1.0 - &lt;dc:publisher> An entity responsible for making the resource available
 551  
    * </li>
 552  
    * <li>Rss 2.0 - &lt;managingEditor> Email address for person responsible for editorial content.
 553  
    * </li>
 554  
    * <li>Atom 1.0 - &lt;author> 
 555  
    * The "atom:author" element is a Person construct that indicates the author of the entry or feed.
 556  
    * </li>
 557  
    * <br/>
 558  
    * Note: This is a list because Atom 1.0 allows multiple &lt;author>. For Rss 1.0 and Rss 2.0,
 559  
    * only the first {@link Person} is interpreted, the rest are ignored.
 560  
    * <br/>
 561  
    * This method constructs a new {@link Person} object with input email as its email and adds it to the end
 562  
    * of the list.
 563  
    * @param managingEditorOrAuthorOrPublisher
 564  
    * @return
 565  
    */
 566  
   public ChannelFeed addManagingEditorOrAuthorOrPublisher(
 567  
       String... emails) {
 568  111
     if(ArrayUtils.isEmpty(emails)){
 569  0
       LOG.warn("Empty email array is ignored");
 570  0
       return this;
 571  
     }
 572  111
     if(_managingEditorOrAuthorOrPublisher == null){
 573  111
       _managingEditorOrAuthorOrPublisher = new ArrayList<Person>();
 574  
     }
 575  222
     for(String s :emails){
 576  111
       _managingEditorOrAuthorOrPublisher.add(new Person(s));
 577  
     }
 578  111
     return this;
 579  
   }
 580  
   
 581  
   /**
 582  
    * <li>Rss 1.0 - &lt;dc:publisher> An entity responsible for making the resource available
 583  
    * </li>
 584  
    * <li>Rss 2.0 - &lt;managingEditor> Email address for person responsible for editorial content.
 585  
    * </li>
 586  
    * <li>Atom 1.0 - &lt;author> 
 587  
    * The "atom:author" element is a Person construct that indicates the author of the entry or feed.
 588  
    * </li>
 589  
    * <br/>
 590  
    * Note: This is a list because Atom 1.0 allows multiple &lt;author>. For Rss 1.0 and Rss 2.0,
 591  
    * only the first {@link Person} is interpreted, the rest are ignored.
 592  
    * <br/>
 593  
    * This method adds all input {@link Person} to the END of the list.
 594  
    * @param managingEditorOrAuthorOrPublisher
 595  
    * @return
 596  
    */
 597  
   public ChannelFeed addManagingEditorOrAuthorOrPublisher(
 598  
       Person... persons) {
 599  18
     if(ArrayUtils.isEmpty(persons)){
 600  0
       LOG.warn("Empty email array is ignored");
 601  0
       return this;
 602  
     }
 603  18
     if(_managingEditorOrAuthorOrPublisher == null){
 604  18
       _managingEditorOrAuthorOrPublisher = new ArrayList<Person>();
 605  
     }
 606  36
     for(Person p : persons){
 607  18
       _managingEditorOrAuthorOrPublisher.add(p);
 608  
     }
 609  18
     return this;
 610  
   }
 611  
   
 612  
   /**
 613  
    * <li>Rss 1.0 - &lt;dc:creator> An entity primarily responsible for making the content of
 614  
    * the resource.
 615  
    * </li>
 616  
    * <li>Rss 2.0 - &lt;webMaster> Email address for person responsible for technical issues relating to channel.
 617  
    * </li>
 618  
    * <li>Atom 1.0 - Not supported, this field is ignored.
 619  
    * </li>
 620  
    * 
 621  
    * <br/>
 622  
    * Notes: according to Rss 2.0 specs, there can be only 1 &lt;webMaster> element under &lt;channel>,
 623  
    * therefore, only the first {@link Person} is interpreted, the rest are ignored.  
 624  
    * @return
 625  
    */
 626  
   public List<Person> getWebMasterOrCreator() {
 627  96
     return _webMasterOrCreator;
 628  
   }
 629  
 
 630  
   /**
 631  
    * <li>Rss 1.0 - &lt;dc:creator> An entity primarily responsible for making the content of
 632  
    * the resource.
 633  
    * </li>
 634  
    * <li>Rss 2.0 - &lt;webMaster> Email address for person responsible for technical issues relating to channel.
 635  
    * </li>
 636  
    * <li>Atom 1.0 - Not supported, this field is ignored.
 637  
    * </li>
 638  
    * 
 639  
    * <br/>
 640  
    * Notes: according to Rss 2.0 specs, there can be only 1 &lt;webMaster> element under &lt;channel>,
 641  
    * therefore, only the first {@link Person} is interpreted, the rest are ignored.
 642  
    * @param webMasterOrCreator
 643  
    * @return
 644  
    */
 645  
   public ChannelFeed setWebMasterOrCreator(List<Person> webMasterOrCreator) {
 646  0
     _webMasterOrCreator = webMasterOrCreator;
 647  0
     return this;
 648  
   }
 649  
 
 650  
 
 651  
   /**
 652  
    * <li>Rss 1.0 - &lt;dc:creator> An entity primarily responsible for making the content of
 653  
    * the resource.
 654  
    * </li>
 655  
    * <li>Rss 2.0 - &lt;webMaster> Email address for person responsible for technical issues relating to channel.
 656  
    * </li>
 657  
    * <li>Atom 1.0 - Not supported, this field is ignored.
 658  
    * </li>
 659  
    * <br/>
 660  
    * This method adds all the input {@link Person} to the END of the list.
 661  
    * <br/>
 662  
    * Notes: according to Rss 2.0 specs, there can be only 1 &lt;webMaster> element under &lt;channel>,
 663  
    * therefore, only the first {@link Person} is interpreted, the rest are ignored.
 664  
    * @param webMasterOrCreator
 665  
    * @return
 666  
    */
 667  
   public ChannelFeed addWebMasterOrCreator(Person... webMasterOrCreator) {
 668  0
     if(ArrayUtils.isEmpty(webMasterOrCreator)){
 669  0
       LOG.warn("empty person array is ignored");
 670  0
       return this;
 671  
     }
 672  0
     if(_webMasterOrCreator == null){
 673  0
       _webMasterOrCreator = new ArrayList<Person>();
 674  
     }
 675  0
     for(Person p : webMasterOrCreator){
 676  0
       _webMasterOrCreator.add(p);
 677  
     }
 678  0
     return this;
 679  
   }
 680  
   
 681  
   /**
 682  
    * <li>Rss 1.0 - &lt;dc:creator> An entity primarily responsible for making the content of
 683  
    * the resource.
 684  
    * </li>
 685  
    * <li>Rss 2.0 - &lt;webMaster> Email address for person responsible for technical issues relating to channel.
 686  
    * </li>
 687  
    * <li>Atom 1.0 - Not supported, this field is ignored.
 688  
    * </li>
 689  
    * <br/>
 690  
    * This method constructs new {@link Person} object and adds them all to the END of the list.
 691  
    * <br/>
 692  
    * Notes: according to Rss 2.0 specs, there can be only 1 &lt;webMaster> element under &lt;channel>,
 693  
    * therefore, only the first {@link Person} is interpreted, the rest are ignored.
 694  
    * @param emailOrText
 695  
    * @return
 696  
    */
 697  
   public ChannelFeed addWebMasterOrCreator(String... emailOrText) {
 698  126
     if(ArrayUtils.isEmpty(emailOrText)){
 699  0
       LOG.warn("empty array is ignored");
 700  0
       return this;
 701  
     }
 702  126
     if(_webMasterOrCreator == null){
 703  126
       _webMasterOrCreator = new ArrayList<Person>();
 704  
     }
 705  252
     for(String e : emailOrText){
 706  126
       _webMasterOrCreator.add(new Person(e));
 707  
     }
 708  126
     return this;
 709  
   }
 710  
   
 711  
   /**
 712  
    * <li>Rss 1.0 - &lt;dc:creator> An entity responsible for making contributions to the content of the resource.
 713  
    * </li>
 714  
    * <li>Rss 2.0 - Not supported, this field is ignored.
 715  
    * </li>
 716  
    * <li>Atom 1.0 - &lt;contributor> 
 717  
    * The "atom:contributor" element is a Person construct that indicates a person or other entity who contributed to the entry or feed.
 718  
    * </li>
 719  
    * 
 720  
    * @return
 721  
    */
 722  
   public List<Person> getContributors() {
 723  33
     return _contributors;
 724  
   }
 725  
 
 726  
 
 727  
   /**
 728  
    * <li>Rss 1.0 - &lt;dc:creator> An entity responsible for making contributions to the content of the resource.
 729  
    * </li>
 730  
    * <li>Rss 2.0 - Not supported, this field is ignored.
 731  
    * </li>
 732  
    * <li>Atom 1.0 - &lt;contributor> 
 733  
    * The "atom:contributor" element is a Person construct that indicates a person or other entity who contributed to the entry or feed.
 734  
    * </li>
 735  
    * @param contributors
 736  
    * @return
 737  
    */
 738  
   public ChannelFeed setContributors(List<Person> contributors) {
 739  0
     _contributors = contributors;
 740  0
     return this;
 741  
   }
 742  
 
 743  
   /**
 744  
    * <li>Rss 1.0 - &lt;dc:creator> An entity responsible for making contributions to the content of the resource.
 745  
    * </li>
 746  
    * <li>Rss 2.0 - Not supported, this field is ignored.
 747  
    * </li>
 748  
    * <li>Atom 1.0 - &lt;contributor> 
 749  
    * The "atom:contributor" element is a Person construct that indicates a person or other entity who contributed to the entry or feed.
 750  
    * </li>
 751  
    * <br/>
 752  
    * This method adds all the input {@link Person} to the END of the list.
 753  
    * 
 754  
    * @param contributor
 755  
    * @return
 756  
    */
 757  
   public ChannelFeed addContributor(Person... contributor) {
 758  0
     if(ArrayUtils.isEmpty(contributor)){
 759  0
       LOG.warn("empty person array is ignored");
 760  0
       return this;
 761  
     }
 762  0
     if(_contributors == null){
 763  0
       _contributors = new ArrayList<Person>();
 764  
     }
 765  0
     for(Person p : contributor){
 766  0
       _contributors.add(p);
 767  
     }
 768  0
     return this;
 769  
   }
 770  
   
 771  
   /**
 772  
    * <li>Rss 1.0 - &lt;dc:creator> An entity responsible for making contributions to the content of the resource.
 773  
    * </li>
 774  
    * <li>Rss 2.0 - Not supported, this field is ignored.
 775  
    * </li>
 776  
    * <li>Atom 1.0 - &lt;contributor> 
 777  
    * The "atom:contributor" element is a Person construct that indicates a person or other entity who contributed to the entry or feed.
 778  
    * </li>
 779  
    * <br/>
 780  
    * This method constructs new {@link Person} object and adds them all to the END of the list.
 781  
    * @return
 782  
    */
 783  
   public ChannelFeed addContributor(String... emailOrText) {
 784  6
     if(ArrayUtils.isEmpty(emailOrText)){
 785  0
       LOG.warn("empty array is ignored");
 786  0
       return this;
 787  
     }
 788  6
     if(_contributors == null){
 789  3
       _contributors = new ArrayList<Person>();
 790  
     }
 791  12
     for(String e : emailOrText){
 792  6
       _contributors.add(new Person(e));
 793  
     }
 794  6
     return this;
 795  
   }
 796  
   
 797  
   /**
 798  
    * <li>Rss 1.0 - &lt;dc:subject> The topic of the content of the resource.
 799  
    * </li>
 800  
    * <li>Rss 2.0 - Includes the item in one or more categories.
 801  
    * </li>
 802  
    * <li>Atom 1.0 - The "atom:category" element conveys information about a category 
 803  
    * associated with an entry or feed. This specification assigns no meaning to the content (if any) of this element.
 804  
    * </li>
 805  
    * @return
 806  
    */
 807  
   public Set<CategorySubject> getCategorySubjects() {
 808  120
     return _categorySubjects;
 809  
   }
 810  
 
 811  
 
 812  
   /**
 813  
    * <li>Rss 1.0 - &lt;dc:subject> The topic of the content of the resource.
 814  
    * </li>
 815  
    * <li>Rss 2.0 - Includes the item in one or more categories.
 816  
    * </li>
 817  
    * <li>Atom 1.0 - The "atom:category" element conveys information about a category 
 818  
    * associated with an entry or feed. This specification assigns no meaning to the content (if any) of this element.
 819  
    * </li>
 820  
    * @param categorySubjects
 821  
    * @return
 822  
    */
 823  
   public ChannelFeed setCategorySubjects(Set<CategorySubject> categorySubjects) {
 824  0
     _categorySubjects = categorySubjects;
 825  0
     return this;
 826  
   }
 827  
 
 828  
   /**
 829  
    * <li>Rss 1.0 - &lt;dc:subject> The topic of the content of the resource.
 830  
    * </li>
 831  
    * <li>Rss 2.0 - Includes the item in one or more categories.
 832  
    * </li>
 833  
    * <li>Atom 1.0 - The "atom:category" element conveys information about a category 
 834  
    * associated with an entry or feed. This specification assigns no meaning to the content (if any) of this element.
 835  
    * </li>
 836  
    * 
 837  
    * <br/>
 838  
    * This method creates new {@link CategorySubject} objects using the input strings and add them to the category set.
 839  
    * @param categorySubjectOrTerm
 840  
    * @return
 841  
    */
 842  
   public ChannelFeed addCategorySubject(String... categorySubjectOrTerm) {
 843  6
     if(ArrayUtils.isEmpty(categorySubjectOrTerm)){
 844  0
       LOG.warn("Empty category array is ignored");
 845  0
       return this;
 846  
     }
 847  6
     if(_categorySubjects == null){
 848  3
       _categorySubjects = new HashSet<CategorySubject>();
 849  
     }
 850  12
     for(String c : categorySubjectOrTerm){
 851  6
       _categorySubjects.add(new CategorySubject(c));
 852  
     }
 853  
     
 854  6
     return this;
 855  
   }
 856  
 
 857  
   /**
 858  
    * <li>Rss 1.0 - &lt;dc:subject> The topic of the content of the resource.
 859  
    * </li>
 860  
    * <li>Rss 2.0 - Includes the item in one or more categories.
 861  
    * </li>
 862  
    * <li>Atom 1.0 - The "atom:category" element conveys information about a category 
 863  
    * associated with an entry or feed. This specification assigns no meaning to the content (if any) of this element.
 864  
    * </li>
 865  
    * 
 866  
    * <br/>
 867  
    * This method adds the input {@link CategorySubject} objects to the category set.
 868  
    * @param categorySubject
 869  
    * @return
 870  
    */
 871  
   public ChannelFeed addCategorySubject(CategorySubject... categorySubject) {
 872  39
     if(ArrayUtils.isEmpty(categorySubject)){
 873  0
       LOG.warn("Empty category array is ignored");
 874  0
       return this;
 875  
     }
 876  
     
 877  39
     if(_categorySubjects == null){
 878  24
       _categorySubjects = new HashSet<CategorySubject>();
 879  
     }
 880  78
     for(CategorySubject s : categorySubject){
 881  39
       _categorySubjects.add(s);
 882  
     }
 883  39
     return this;
 884  
   }
 885  
 
 886  
 
 887  
   /**
 888  
    * <li>Rss 1.0 - &lt;dc:date>  A date associated with an event in the life cycle of the resource.
 889  
    * </li>
 890  
    * <li>Rss 2.0 - &lt;pubDate> Indicates when the item was published. 
 891  
    * </li>
 892  
    * <li>Atom 1.0 - Not supported, this field is ignored.
 893  
    * </li>
 894  
    * @return
 895  
    */
 896  
   public String getPubDate() {
 897  159
     return _pubDate;
 898  
   }
 899  
 
 900  
 
 901  
   /**
 902  
    * <li>Rss 1.0 - &lt;dc:date>  A date associated with an event in the life cycle of the resource.
 903  
    * </li>
 904  
    * <li>Rss 2.0 - &lt;pubDate> Indicates when the item was published. 
 905  
    * </li>
 906  
    * <li>Atom 1.0 - Not supported, this field is ignored.
 907  
    * </li>
 908  
    * @param pubDate
 909  
    * @return
 910  
    */
 911  
   public ChannelFeed setPubDate(String pubDate) {
 912  156
     _pubDate = pubDate;
 913  156
     return this;
 914  
   }
 915  
   
 916  
   /**
 917  
    * <li>Rss 1.0 - &lt;dc:date>  A date associated with an event in the life cycle of the resource.
 918  
    * </li>
 919  
    * <li>Rss 2.0 - &lt;pubDate> Indicates when the item was published. 
 920  
    * </li>
 921  
    * <li>Atom 1.0 - Not supported, this field is ignored.
 922  
    * </li>
 923  
    * 
 924  
    * <br/>
 925  
    * This method uses the input {@link SimpleDateFormat} object to format the date into a string.
 926  
    * @param pubDate
 927  
    * @param format
 928  
    * @return
 929  
    */
 930  
   public ChannelFeed setPubDate(Date pubDate, SimpleDateFormat format){
 931  0
     _pubDate = format.format(pubDate);
 932  0
     return this;
 933  
   }
 934  
 
 935  
 
 936  
   /**
 937  
    * <li>Rss 1.0 - Not supported, this field is ignored.
 938  
    * </li>
 939  
    * <li>Rss 2.0 - &lt;lastBuildDate> The last time the content of the channel changed. 
 940  
    * </li>
 941  
    * <li>Atom 1.0 - &lt;updated> The "atom:updated" element is a Date construct indicating the most recent 
 942  
    * instant in time when an entry or feed was modified in a way the publisher considers significant. 
 943  
    * Therefore, not all modifications necessarily result in a changed atom:updated value.
 944  
    * </li>
 945  
    * 
 946  
    * @return
 947  
    */
 948  
   public String getLastBuildOrUpdatedDate() {
 949  156
     return _lastBuildOrUpdatedDate;
 950  
   }
 951  
 
 952  
 
 953  
   /**
 954  
    * <li>Rss 1.0 - Not supported, this field is ignored.
 955  
    * </li>
 956  
    * <li>Rss 2.0 - &lt;lastBuildDate> The last time the content of the channel changed. 
 957  
    * </li>
 958  
    * <li>Atom 1.0 - &lt;updated> The "atom:updated" element is a Date construct indicating the most recent 
 959  
    * instant in time when an entry or feed was modified in a way the publisher considers significant. 
 960  
    * Therefore, not all modifications necessarily result in a changed atom:updated value.
 961  
    * </li>
 962  
    * 
 963  
    * @param lastBuildOrUpdatedDate
 964  
    * @return
 965  
    */
 966  
   public ChannelFeed setLastBuildOrUpdatedDate(String lastBuildOrUpdatedDate) {
 967  182
     _lastBuildOrUpdatedDate = lastBuildOrUpdatedDate;
 968  182
     return this;
 969  
   }
 970  
 
 971  
   /**
 972  
    * <li>Rss 1.0 - Not supported, this field is ignored.
 973  
    * </li>
 974  
    * <li>Rss 2.0 - &lt;lastBuildDate> The last time the content of the channel changed. 
 975  
    * </li>
 976  
    * <li>Atom 1.0 - &lt;updated> The "atom:updated" element is a Date construct indicating the most recent 
 977  
    * instant in time when an entry or feed was modified in a way the publisher considers significant. 
 978  
    * Therefore, not all modifications necessarily result in a changed atom:updated value.
 979  
    * </li>
 980  
    * <br/>
 981  
    * This method uses the input {@link SimpleDateFormat} object to format the date into a string.
 982  
    * @param lastBuildOrUpdatedDate
 983  
    * @return
 984  
    */
 985  
   public ChannelFeed setLastBuildOrUpdatedDate(Date lastBuildOrUpdatedDate, SimpleDateFormat format) {
 986  0
     return setLastBuildOrUpdatedDate(format.format(lastBuildOrUpdatedDate));
 987  
   }
 988  
   
 989  
   
 990  
   /**
 991  
    * <li>Rss 1.0 - Not supported, this field is ignored.
 992  
    * </li>
 993  
    * <li>Rss 2.0 - Not supported, this field is ignored.
 994  
    * </li>
 995  
    * <li>Atom 1.0 - The "atom:id" element conveys a permanent, universally unique identifier for an entry or feed.
 996  
    * </li>
 997  
    * @return
 998  
    */
 999  
   public Id getUid() {
 1000  60
     return _uid;
 1001  
   }
 1002  
 
 1003  
   /**
 1004  
    * <li>Rss 1.0 - Not supported, this field is ignored.
 1005  
    * </li>
 1006  
    * <li>Rss 2.0 - Not supported, this field is ignored.
 1007  
    * </li>
 1008  
    * <li>Atom 1.0 - The "atom:id" element conveys a permanent, universally unique identifier for an entry or feed.
 1009  
    * </li>
 1010  
    * @param uid
 1011  
    * @return
 1012  
    */
 1013  
   public ChannelFeed setUid(Id uid) {
 1014  57
     _uid = uid;
 1015  57
     return this;
 1016  
   }
 1017  
 
 1018  
   /**
 1019  
    * <li>Rss 1.0 - Not supported, this field is ignored.
 1020  
    * </li>
 1021  
    * <li>Rss 2.0 - Not supported, this field is ignored.
 1022  
    * </li>
 1023  
    * <li>Atom 1.0 - The "atom:id" element conveys a permanent, universally unique identifier for an entry or feed.
 1024  
    * </li>
 1025  
    * <br/>
 1026  
    * This method constructs a new {@link Id} object and sets the <code>uid</code> field to this object.
 1027  
    * @param uid
 1028  
    * @return
 1029  
    */
 1030  
   public ChannelFeed setUid(String uid){
 1031  6
     if(_uid == null){
 1032  6
       _uid = null;
 1033  6
       return this;
 1034  
     }
 1035  0
     _uid = new Id(uid);
 1036  0
     return this;
 1037  
   }
 1038  
 
 1039  
 
 1040  
   /**
 1041  
    * <li>Rss 1.0 - Not supported, this is ignored.</li>
 1042  
    * <li>Rss 2.0 - &lt;generator> A string indicating the program used to generate the channel.  
 1043  
    * </li>
 1044  
    * <li>Atom 1.0 - &lt;generator> 
 1045  
    * The "atom:generator" element's content identifies the agent used to generate a feed, for debugging and other purposes.
 1046  
    * </li>
 1047  
    * @return
 1048  
    */
 1049  
   public Generator getGenerator() {
 1050  150
     return _generator;
 1051  
   }
 1052  
 
 1053  
   /**
 1054  
    * <li>Rss 1.0 - Not supported, this is ignored.</li>
 1055  
    * <li>Rss 2.0 - &lt;generator> A string indicating the program used to generate the channel.  
 1056  
    * </li>
 1057  
    * <li>Atom 1.0 - &lt;generator> 
 1058  
    * The "atom:generator" element's content identifies the agent used to generate a feed, for debugging and other purposes.
 1059  
    * </li>
 1060  
    * @param generator
 1061  
    * @return
 1062  
    */
 1063  
   public ChannelFeed setGenerator(Generator generator) {
 1064  39
     _generator = generator;
 1065  39
     return this;
 1066  
   }
 1067  
 
 1068  
   /**
 1069  
    * <li>Rss 1.0 - Not supported, this is ignored.</li>
 1070  
    * <li>Rss 2.0 - &lt;generator> A string indicating the program used to generate the channel.  
 1071  
    * </li>
 1072  
    * <li>Atom 1.0 - &lt;generator> 
 1073  
    * The "atom:generator" element's content identifies the agent used to generate a feed, for debugging and other purposes.
 1074  
    * </li>
 1075  
    * <br/>
 1076  
    * This method constructs a new {@link Generator} object.
 1077  
    * @param generatorValue
 1078  
    * @return
 1079  
    */
 1080  
   public ChannelFeed setGenerator(String generatorValue) {
 1081  129
     _generator = generatorValue == null?null: new Generator(generatorValue);
 1082  129
     return this;
 1083  
   }
 1084  
   
 1085  
   /**
 1086  
    * <b>Rss 2.0 only</b><br/>
 1087  
    * A URL that points to the documentation for the format used in the RSS file. 
 1088  
    * It's probably a pointer to this page. It's for people who might stumble 
 1089  
    * across an RSS file on a Web server 25 years from now and wonder what it is.
 1090  
    * @return
 1091  
    */
 1092  
   public String getDocs() {
 1093  120
     return _docs;
 1094  
   }
 1095  
 
 1096  
 
 1097  
   /**
 1098  
    * <b>Rss 2.0 only</b><br/>
 1099  
    * A URL that points to the documentation for the format used in the RSS file. 
 1100  
    * It's probably a pointer to this page. It's for people who might stumble 
 1101  
    * across an RSS file on a Web server 25 years from now and wonder what it is.
 1102  
    * @param docs
 1103  
    * @return
 1104  
    */
 1105  
   public ChannelFeed setDocs(String docs) {
 1106  98
     _docs = docs;
 1107  98
     return this;
 1108  
   }
 1109  
 
 1110  
   /**
 1111  
    * <li>Rss 1.0 - This value is parsed from both the 
 1112  
    * &lt;sy:updatePeriod> and  &lt;sy:updateFrequency> <br/>
 1113  
    * for example: updatePeriod:hourly and updateFrequency:2 = ttl: 30 minutes
 1114  
    * </li>
 1115  
    * <li>Rss 2.0 - ttl stands for time to live. It's a number of minutes that 
 1116  
    * indicates how long a channel can be cached before refreshing from the source.
 1117  
    * </li>
 1118  
    * <li>Atom 1.0 - Not supported, this field is ignored.</li>
 1119  
    * @return
 1120  
    */
 1121  
   public Integer getTtl() {
 1122  111
     return _ttl;
 1123  
   }
 1124  
 
 1125  
   /**
 1126  
    * <li>Rss 1.0 - This value is parsed from both the 
 1127  
    * &lt;sy:updatePeriod> and  &lt;sy:updateFrequency> <br/>
 1128  
    * for example: updatePeriod:hourly and updateFrequency:2 = ttl: 30 minutes
 1129  
    * </li>
 1130  
    * <li>Rss 2.0 - ttl stands for time to live. It's a number of minutes that 
 1131  
    * indicates how long a channel can be cached before refreshing from the source.
 1132  
    * </li>
 1133  
    * <li>Atom 1.0 - Not supported, this field is ignored.</li>
 1134  
    * @param ttl
 1135  
    * @return
 1136  
    */
 1137  
   public ChannelFeed setTtl(Integer ttl) {
 1138  95
     _ttl = ttl;
 1139  95
     return this;
 1140  
   }
 1141  
 
 1142  
 
 1143  
   /**
 1144  
    * <b>Rss 2.0 only</b><br/>
 1145  
    * Allows processes to register with a cloud to be notified of updates to the 
 1146  
    * channel, implementing a lightweight publish-subscribe protocol for RSS feeds.
 1147  
    * @return
 1148  
    */
 1149  
   public Cloud getCloud() {
 1150  99
     return _cloud;
 1151  
   }
 1152  
 
 1153  
 
 1154  
   /**
 1155  
    * <b>Rss 2.0 only</b><br/>
 1156  
    * Allows processes to register with a cloud to be notified of updates to the 
 1157  
    * channel, implementing a lightweight publish-subscribe protocol for RSS feeds.
 1158  
    * @param cloud
 1159  
    * @return
 1160  
    */
 1161  
   public ChannelFeed setCloud(Cloud cloud) {
 1162  9
     _cloud = cloud;
 1163  9
     return this;
 1164  
   }
 1165  
 
 1166  
   /**
 1167  
    * <li>Rss 1.0 - &lt;image> 
 1168  
    * Establishes an RDF association between the optional image element [5.4] and this particular RSS channel. The rdf:resource's {image_uri} must be the same as the image element's rdf:about {image_uri}.
 1169  
    * </li>
 1170  
    * <li> Rss 2.0 - &lt;image>
 1171  
    * Specifies a GIF, JPEG or PNG image that can be displayed with the channel. </li>
 1172  
    * <li>Atom 1.0 - &lt;icon>
 1173  
    * The "atom:icon" element's content is an IRI reference [RFC3987] which identifies 
 1174  
    * an image which provides iconic visual identification for a feed.
 1175  
    * </li>
 1176  
    * @return
 1177  
    */
 1178  
   public Image getImageOrIcon() {
 1179  192
     return _imageOrIcon;
 1180  
   }
 1181  
 
 1182  
   /**
 1183  
    * <li>Rss 1.0 - &lt;image> 
 1184  
    * Establishes an RDF association between the optional image element [5.4] and this particular RSS channel. The rdf:resource's {image_uri} must be the same as the image element's rdf:about {image_uri}.
 1185  
    * </li>
 1186  
    * <li> Rss 2.0 - &lt;image>
 1187  
    * Specifies a GIF, JPEG or PNG image that can be displayed with the channel. </li>
 1188  
    * <li>Atom 1.0 - &lt;icon>
 1189  
    * The "atom:icon" element's content is an IRI reference [RFC3987] which identifies 
 1190  
    * an image which provides iconic visual identification for a feed.
 1191  
    * </li>
 1192  
    * @param imageOrIcon
 1193  
    * @return
 1194  
    */
 1195  
   public ChannelFeed setImageOrIcon(Image imageOrIcon) {
 1196  131
     _imageOrIcon = imageOrIcon;
 1197  131
     return this;
 1198  
   }
 1199  
 
 1200  
 
 1201  
   /**
 1202  
    * <b>Atom 1.0 only </b><br/>
 1203  
    * The "atom:logo" element's content is an IRI reference [RFC3987] which identifies an image which provides visual identification for a feed.
 1204  
    * @return
 1205  
    */
 1206  
   public Image getLogo() {
 1207  18
     return _logo;
 1208  
   }
 1209  
 
 1210  
 
 1211  
   /**
 1212  
    * <b>Atom 1.0 only </b><br/>
 1213  
    * The "atom:logo" element's content is an IRI reference [RFC3987] which identifies an image which provides visual identification for a feed.
 1214  
    * @param logo
 1215  
    * @return
 1216  
    */
 1217  
   public ChannelFeed setLogo(Image logo) {
 1218  3
     _logo = logo;
 1219  3
     return this;
 1220  
   }
 1221  
 
 1222  
 
 1223  
   /**
 1224  
    * <b>Rss 1.0 and Rss 2.0 only </b><br/>
 1225  
    * <li>Rss 1.0 - Establishes an RDF association between the optional textinput element [5.6] and this particular RSS channel. The {textinput_uri} rdf:resource must be the same as the textinput element's rdf:about {textinput_uri}.
 1226  
    * </li>
 1227  
    * <li>Rss 2.0 - Specifies a text input box that can be displayed with the channel. </li>
 1228  
    * @return
 1229  
    */
 1230  
   public TextInput getTexInput() {
 1231  156
     return _texInput;
 1232  
   }
 1233  
 
 1234  
 
 1235  
   /**
 1236  
    * <b>Rss 1.0 and Rss 2.0 only </b><br/>
 1237  
    * <li>Rss 1.0 - Establishes an RDF association between the optional textinput element [5.6] and this particular RSS channel. The {textinput_uri} rdf:resource must be the same as the textinput element's rdf:about {textinput_uri}.
 1238  
    * </li>
 1239  
    * <li>Rss 2.0 - Specifies a text input box that can be displayed with the channel. </li>
 1240  
    * @param texInput
 1241  
    * @return
 1242  
    */
 1243  
   public ChannelFeed setTexInput(TextInput texInput) {
 1244  27
     _texInput = texInput;
 1245  27
     return this;
 1246  
   }
 1247  
 
 1248  
    /**
 1249  
     * <b>Rss 2.0 only</b><br/>
 1250  
     * An XML element that contains up to 24 <hour> sub-elements whose value is a number between 0 and 23, representing a time in GMT, when aggregators, if they support the feature, may not read the channel on hours listed in the skipHours element.
 1251  
     * <br/>
 1252  
     * The hour beginning at midnight is hour zero.
 1253  
     */
 1254  
    public Set<Integer> getSkipHours() {
 1255  99
      return _skipHours;
 1256  
    }
 1257  
    /**
 1258  
     * <b>Rss 2.0 only</b><br/>
 1259  
     * An XML element that contains up to 24 <hour> sub-elements whose value is a number between 0 and 23, representing a time in GMT, when aggregators, if they support the feature, may not read the channel on hours listed in the skipHours element.
 1260  
     * <br/>
 1261  
     * The hour beginning at midnight is hour zero.
 1262  
     */
 1263  
    public ChannelFeed setSkipHours(Set<Integer> skipHours) {
 1264  0
      for(Integer i : skipHours){
 1265  0
        if(i == null || i <0 || i >23){
 1266  0
          throw new IllegalArgumentException("all skip hour must be a value that is a number between 0 and 23");
 1267  
        }
 1268  
      }
 1269  0
      _skipHours = skipHours;
 1270  0
      return this;
 1271  
    }
 1272  
  
 1273  
    /**
 1274  
     * <b>Rss 2.0 only</b><br/>
 1275  
     * Add a skip hour to the feed;
 1276  
     * @param hour value is a number between 0 and 23, representing a time in GMT, when aggregators, if they support the feature, may not read the channel on hours listed in the skipHours element.
 1277  
     * <br/>
 1278  
     * The hour beginning at midnight is hour zero.
 1279  
     */
 1280  
    public ChannelFeed addSkipHour(int... hour){
 1281  45
      if(!ArrayUtils.isEmpty(hour)){
 1282  108
        for(int h : hour){
 1283  63
          if(h <0 || h >23){
 1284  0
            throw new IllegalArgumentException("all skip hour must be a value that is a number between 0 and 23");
 1285  
          }
 1286  63
          if(_skipHours == null){
 1287  9
            _skipHours = new HashSet<Integer>();
 1288  
          }
 1289  63
          _skipHours.add(h);
 1290  
        }
 1291  
      }
 1292  45
      return this;
 1293  
    }
 1294  
  
 1295  
    /**
 1296  
     * <b>Rss 2.0 only</b><br/>
 1297  
     * value is Monday, Tuesday, Wednesday, Thursday, Friday, Saturday or Sunday. Aggregators may not read the channel during days listed in the skipDays element.
 1298  
     */
 1299  
    public Set<Day> getSkipDays() {
 1300  99
      return _skipDays;
 1301  
    }
 1302  
    /**
 1303  
     * <b>Rss 2.0 only</b><br/>
 1304  
     * value is Monday, Tuesday, Wednesday, Thursday, Friday, Saturday or Sunday. Aggregators may not read the channel during days listed in the skipDays element.
 1305  
     */
 1306  
    public ChannelFeed setSkipDays(Set<Day> skipDays) {
 1307  0
      _skipDays = skipDays;
 1308  0
      return this;
 1309  
    }
 1310  
  
 1311  
    /**
 1312  
     * <b>Rss 2.0 only</b><br/>
 1313  
     * Add a skip day.
 1314  
     */
 1315  
    public ChannelFeed addSkipDay(Day... day){
 1316  15
      if(!ArrayUtils.isEmpty(day)){
 1317  15
        if(_skipDays == null){
 1318  9
          _skipDays = new HashSet<Day>();
 1319  
        }
 1320  15
        _skipDays.addAll(Arrays.asList(day));
 1321  
      }
 1322  
  
 1323  15
      return this;
 1324  
    }
 1325  
 
 1326  
 
 1327  
   ////////////////////////Common setters///////////////////////
 1328  
    /**
 1329  
     * Any other attribute that is not in the RSS 2.0 specs.
 1330  
     */
 1331  
    public ChannelFeed setOtherAttributes(Map<QName, String> otherAttributes) {
 1332  12
      _otherAttributes = otherAttributes;
 1333  12
      return this;
 1334  
    }
 1335  
    /**
 1336  
     * Add an attribute that is not in the RSS 2.0 specs.
 1337  
     */
 1338  
    public ChannelFeed addOtherAttributes(QName namespace, String attribute) {
 1339  21
      if(_otherAttributes == null){
 1340  6
        _otherAttributes = new HashMap<QName, String>();
 1341  
      }
 1342  21
      _otherAttributes.put(namespace, attribute);
 1343  21
      return this;
 1344  
    }
 1345  
    
 1346  
    /**
 1347  
     * Other additional elements that are not in the Rss specs.<br/>
 1348  
     * **Note** The element should not have an empty namespace to avoid collision with the specs elements.
 1349  
     */
 1350  
    public ChannelFeed setOtherElements(List<Element> otherElements) {
 1351  24
      _otherElements = otherElements;
 1352  24
      return this;
 1353  
    }
 1354  
    /**
 1355  
     * Add an element that is not specified in the Rss specs.<br/>
 1356  
     * **Note** The element should not have an empty namespace to avoid collision with the specs elements.
 1357  
     * @param element - any element
 1358  
     */
 1359  
    public ChannelFeed addOtherElement(Element element){
 1360  33
      if(_otherElements == null){
 1361  6
        _otherElements = new ArrayList<Element>();
 1362  
      }
 1363  33
      _otherElements.add(element);
 1364  33
      return this;
 1365  
    }
 1366  
    
 1367  
    /**
 1368  
     * Add an element that is not specified in the Rss specs.<br/>
 1369  
     * **Note** The element should not have an empty namespace to avoid collision with the specs elements.
 1370  
     * 
 1371  
     * @param xmlString - any element
 1372  
     * @throws ParserConfigurationException 
 1373  
     * @throws IOException 
 1374  
     * @throws SAXException 
 1375  
     */
 1376  
    public ChannelFeed addOtherElement(String xmlString) throws SAXException, IOException, ParserConfigurationException{
 1377  21
      return addOtherElement(XMLUtils.parseXml(xmlString, false, false).getDocumentElement());
 1378  
    }
 1379  
    
 1380  
 
 1381  
    /**
 1382  
     * <b>Atom 1.0 only</b><br/>
 1383  
     * Any element defined by this specification MAY have an xml:base attribute 
 1384  
     * [W3C.REC-xmlbase-20010627]. When xml:base is used in an Atom Document, 
 1385  
     * it serves the function described in section 5.1.1 of [RFC3986], establishing 
 1386  
     * the base URI (or IRI) for resolving any relative references found within the 
 1387  
     * effective scope of the xml:base attribute.
 1388  
     * @param base
 1389  
     * @return
 1390  
     */
 1391  
    public ChannelFeed setBase(String base) {
 1392  42
      _base = base;
 1393  42
      return this;
 1394  
    }
 1395  
    /**
 1396  
     * <li>Rss 2.0 - &lt;language> element. 
 1397  
     * The language the channel is written in. This allows aggregators to group 
 1398  
     * all Italian language sites, for example, on a single page. A list of allowable 
 1399  
     * values for this element, as provided by Netscape, is here. You may also use values 
 1400  
     * defined by the W3C.
 1401  
     * Only &lt;channel> support this element.</li>
 1402  
     * <li>Rss 1.0 - &lt;dc:language> element. A language of the intellectual content of the resource.
 1403  
     * Only &lt;channel> and &lt;item> support this element. </li>
 1404  
     * <li>Atom 1.0 - 'lang' attribute</li>
 1405  
     * <br/>
 1406  
     * Note: for Rss 2.0 and Rss 1.0, only &lt;channel> and &lt;item>
 1407  
     * @param lang
 1408  
     * @return
 1409  
     */
 1410  
    public ChannelFeed setLang(String lang) {
 1411  293
      _lang = lang;
 1412  293
      return this;
 1413  
    }
 1414  
    
 1415  
    /**
 1416  
     * <li>Rss 2.0 - &lt;language> element. 
 1417  
     * The language the channel is written in. This allows aggregators to group 
 1418  
     * all Italian language sites, for example, on a single page. A list of allowable 
 1419  
     * values for this element, as provided by Netscape, is here. You may also use values 
 1420  
     * defined by the W3C.
 1421  
     * Only &lt;channel> support this element.</li>
 1422  
     * <li>Rss 1.0 - &lt;dc:language> element. A language of the intellectual content of the resource.
 1423  
     * Only &lt;channel> and &lt;item> support this element. </li>
 1424  
     * <li>Atom 1.0 - 'lang' attribute</li>
 1425  
     * <br/>
 1426  
     * Note: for Rss 2.0 and Rss 1.0, only &lt;channel> and &lt;item>
 1427  
     * @param lang
 1428  
     * @return
 1429  
     */
 1430  
    public ChannelFeed setLang(Locale lang) {
 1431  18
      _lang = lang.getLanguage();
 1432  18
      return this;
 1433  
    }
 1434  
    /**
 1435  
     * <b>Rss 1.0 only</b><br/>
 1436  
     * @param resource
 1437  
     * @return
 1438  
     */
 1439  
    public ChannelFeed setResource(String resource) {
 1440  33
      _resource = resource;
 1441  33
      return this;
 1442  
    }
 1443  
    /**
 1444  
     * <b>Rss 1.0 only</b><br/>
 1445  
     * @param about
 1446  
     * @return
 1447  
     */
 1448  
    public ChannelFeed setAbout(String about) {
 1449  45
      _about = about;
 1450  45
      return this;
 1451  
    }
 1452  
    ////////////////////////Common setters///////////////////////
 1453  
    
 1454  
   @Override
 1455  
   public void validate(FeedFormat format) throws ValidationException {
 1456  12
     if(CollectionUtils.isEmpty(_items)){
 1457  3
       throw new ValidationException("Channel: You should have at least 1 item");
 1458  
     }
 1459  
     
 1460  9
     for(ItemEntry item : _items){
 1461  21
       ValidationUtils.validateNotNull("Channel: All item should not be null", item);
 1462  21
       item.validate(format);
 1463  
     }
 1464  
     
 1465  6
     ValidationUtils.validateNotNull("Channel: Title, Link and Description should not be null", _title, _links, _descriptionOrSubtitle);
 1466  
   
 1467  6
     _title.validate(format);
 1468  6
     _descriptionOrSubtitle.validate(format);
 1469  
     
 1470  6
     for(Link l : _links){
 1471  9
       l.validate(format);
 1472  
     }
 1473  
     
 1474  6
     if(_categorySubjects != null){
 1475  3
       for(CategorySubject c: _categorySubjects){
 1476  6
         c.validate(format);
 1477  
       }
 1478  
     }
 1479  6
     if(_cloud != null){
 1480  3
       _cloud.validate(format);
 1481  
     }
 1482  6
     if(_imageOrIcon != null){
 1483  3
       _imageOrIcon.validate(format);
 1484  
     }
 1485  6
     if(_logo != null){
 1486  0
       _logo.validate(format);
 1487  
     }
 1488  6
     if(_texInput != null){
 1489  3
       _texInput.validate(format);
 1490  
     }    
 1491  
     
 1492  6
     if(_uid != null){
 1493  0
       _uid.validate(format);
 1494  
     }
 1495  
     
 1496  6
     if(_generator != null){
 1497  6
       _generator.validate(format);
 1498  
     }
 1499  
     
 1500  6
     if(_contributors != null){
 1501  0
       for(Person p : _contributors){
 1502  0
         p.validate(format);
 1503  
       }
 1504  
     }
 1505  
     
 1506  6
     if(_managingEditorOrAuthorOrPublisher != null){
 1507  3
       for(Person p : _managingEditorOrAuthorOrPublisher){
 1508  3
         p.validate(format);
 1509  
       }
 1510  
     }
 1511  
     
 1512  6
     if(_webMasterOrCreator != null){
 1513  3
       for(Person p : _webMasterOrCreator){
 1514  3
         p.validate(format);
 1515  
       }
 1516  
     }
 1517  
     
 1518  6
     if(_rights != null){
 1519  6
       _rights.validate(format);
 1520  
     }
 1521  
     
 1522  6
   }
 1523  
   
 1524  
 }