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 <feed> element.
34 * <br/>
35 *
36 * <li>Rss 1.0 - <channel> and second level elements such as <item> elements under <rdf:RDF>
37 * </li>
38 * <li>Rss 2.0 - <channel>
39 * </li>
40 * <li>Atom 1.0 - <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 public class ChannelFeed extends AbstractBaseObject{
48 /***
49 *
50 */
51 private static final long serialVersionUID = 20070927L;
52 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 - <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 - <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 - <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 return _items;
102 }
103
104 /***
105 * <li>Rss 1.0 - <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 - <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 - <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 _items = items;
132 return this;
133 }
134
135 /***
136 * <li>Rss 1.0 - <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 - <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 - <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 if(ArrayUtils.isEmpty(items)){
165 LOG.warn("Empty items array is ignored");
166 return this;
167 }
168 if(_items == null){
169 _items = new ArrayList<ItemEntry>();
170 }
171 for(ItemEntry item : items){
172 _items.add(item);
173 }
174 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 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 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 _title = title;
229 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 if(title == null){
252 _title = null;
253 return this;
254 }
255 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 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 _links = links;
300 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 if(ArrayUtils.isEmpty(href)){
327 LOG.warn("Empty href array is ignored");
328 return this;
329 }
330 if(_links == null){
331 _links = new ArrayList<Link>();
332 }
333 for (String s:href){
334 _links.add(new Link(s));
335 }
336 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 if(ArrayUtils.isEmpty(link)){
364 LOG.warn("Empty link array is ignored");
365 return this;
366 }
367 if(_links == null){
368 _links = new ArrayList<Link>();
369 }
370 for(Link l : link){
371 _links.add(l);
372 }
373 return this;
374 }
375
376 /***
377 * <li>Rss 1.0 - <description>
378 * A brief description of the channel's content, function, source, etc.
379 * </li>
380 * <li>Rss 2.0 - <description> Phrase or sentence describing the channel.
381 * </li>
382 * <li>Atom 1.0 -
383 * This maps to <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 return _descriptionOrSubtitle;
390 }
391
392 /***
393 * <li>Rss 1.0 - <description>
394 * A brief description of the channel's content, function, source, etc.
395 * </li>
396 * <li>Rss 2.0 - <description> Phrase or sentence describing the channel.
397 * </li>
398 * <li>Atom 1.0 -
399 * This maps to <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 return _descriptionOrSubtitle == null ? null : _descriptionOrSubtitle.getText();
408 }
409
410 /***
411 * <li>Rss 1.0 - <description>
412 * A brief description of the channel's content, function, source, etc.
413 * </li>
414 * <li>Rss 2.0 - <description> Phrase or sentence describing the channel.
415 * </li>
416 * <li>Atom 1.0 -
417 * This maps to <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 _descriptionOrSubtitle = descriptionOrSubtitle;
425 return this;
426 }
427
428 /***
429 * <li>Rss 1.0 - <description>
430 * A brief description of the channel's content, function, source, etc.
431 * </li>
432 * <li>Rss 2.0 - <description> Phrase or sentence describing the channel.
433 * </li>
434 * <li>Atom 1.0 -
435 * This maps to <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 _descriptionOrSubtitle = descriptionOrSubtitle == null? null: new Text(descriptionOrSubtitle);
446 return this;
447 }
448
449 /***
450 * <li>Rss 1.0 - <dc:rights> Information about rights held in and over the resource.
451 * </li>
452 * <li>Rss 2.0 - <copyright> Copyright notice for content in the channel.
453 * </li>
454 * <li>Atom 1.0 - <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 return _rights;
460 }
461
462
463 /***
464 * <li>Rss 1.0 - <dc:rights> Information about rights held in and over the resource.
465 * </li>
466 * <li>Rss 2.0 - <copyright> Copyright notice for content in the channel.
467 * </li>
468 * <li>Atom 1.0 - <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 return _rights == null ? null:_rights.getText();
475 }
476
477 /***
478 * <li>Rss 1.0 - <dc:rights> Information about rights held in and over the resource.
479 * </li>
480 * <li>Rss 2.0 - <copyright> Copyright notice for content in the channel.
481 * </li>
482 * <li>Atom 1.0 - <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 _rights = rights;
489 return this;
490 }
491
492 /***
493 * <li>Rss 1.0 - <dc:rights> Information about rights held in and over the resource.
494 * </li>
495 * <li>Rss 2.0 - <copyright> Copyright notice for content in the channel.
496 * </li>
497 * <li>Atom 1.0 - <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 if(rights == null){
506 _rights = null;
507 return this;
508 }
509 return setRights(new Text(rights));
510 }
511
512 /***
513 * <li>Rss 1.0 - <dc:publisher> An entity responsible for making the resource available
514 * </li>
515 * <li>Rss 2.0 - <managingEditor> Email address for person responsible for editorial content.
516 * </li>
517 * <li>Atom 1.0 - <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 <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 return _managingEditorOrAuthorOrPublisher;
527 }
528
529 /***
530 * <li>Rss 1.0 - <dc:publisher> An entity responsible for making the resource available
531 * </li>
532 * <li>Rss 2.0 - <managingEditor> Email address for person responsible for editorial content.
533 * </li>
534 * <li>Atom 1.0 - <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 <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 _managingEditorOrAuthorOrPublisher = managingEditorOrAuthorOrPublisher;
546 return this;
547 }
548
549 /***
550 * <li>Rss 1.0 - <dc:publisher> An entity responsible for making the resource available
551 * </li>
552 * <li>Rss 2.0 - <managingEditor> Email address for person responsible for editorial content.
553 * </li>
554 * <li>Atom 1.0 - <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 <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 if(ArrayUtils.isEmpty(emails)){
569 LOG.warn("Empty email array is ignored");
570 return this;
571 }
572 if(_managingEditorOrAuthorOrPublisher == null){
573 _managingEditorOrAuthorOrPublisher = new ArrayList<Person>();
574 }
575 for(String s :emails){
576 _managingEditorOrAuthorOrPublisher.add(new Person(s));
577 }
578 return this;
579 }
580
581 /***
582 * <li>Rss 1.0 - <dc:publisher> An entity responsible for making the resource available
583 * </li>
584 * <li>Rss 2.0 - <managingEditor> Email address for person responsible for editorial content.
585 * </li>
586 * <li>Atom 1.0 - <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 <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 if(ArrayUtils.isEmpty(persons)){
600 LOG.warn("Empty email array is ignored");
601 return this;
602 }
603 if(_managingEditorOrAuthorOrPublisher == null){
604 _managingEditorOrAuthorOrPublisher = new ArrayList<Person>();
605 }
606 for(Person p : persons){
607 _managingEditorOrAuthorOrPublisher.add(p);
608 }
609 return this;
610 }
611
612 /***
613 * <li>Rss 1.0 - <dc:creator> An entity primarily responsible for making the content of
614 * the resource.
615 * </li>
616 * <li>Rss 2.0 - <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 <webMaster> element under <channel>,
623 * therefore, only the first {@link Person} is interpreted, the rest are ignored.
624 * @return
625 */
626 public List<Person> getWebMasterOrCreator() {
627 return _webMasterOrCreator;
628 }
629
630 /***
631 * <li>Rss 1.0 - <dc:creator> An entity primarily responsible for making the content of
632 * the resource.
633 * </li>
634 * <li>Rss 2.0 - <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 <webMaster> element under <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 _webMasterOrCreator = webMasterOrCreator;
647 return this;
648 }
649
650
651 /***
652 * <li>Rss 1.0 - <dc:creator> An entity primarily responsible for making the content of
653 * the resource.
654 * </li>
655 * <li>Rss 2.0 - <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 <webMaster> element under <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 if(ArrayUtils.isEmpty(webMasterOrCreator)){
669 LOG.warn("empty person array is ignored");
670 return this;
671 }
672 if(_webMasterOrCreator == null){
673 _webMasterOrCreator = new ArrayList<Person>();
674 }
675 for(Person p : webMasterOrCreator){
676 _webMasterOrCreator.add(p);
677 }
678 return this;
679 }
680
681 /***
682 * <li>Rss 1.0 - <dc:creator> An entity primarily responsible for making the content of
683 * the resource.
684 * </li>
685 * <li>Rss 2.0 - <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 <webMaster> element under <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 if(ArrayUtils.isEmpty(emailOrText)){
699 LOG.warn("empty array is ignored");
700 return this;
701 }
702 if(_webMasterOrCreator == null){
703 _webMasterOrCreator = new ArrayList<Person>();
704 }
705 for(String e : emailOrText){
706 _webMasterOrCreator.add(new Person(e));
707 }
708 return this;
709 }
710
711 /***
712 * <li>Rss 1.0 - <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 - <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 return _contributors;
724 }
725
726
727 /***
728 * <li>Rss 1.0 - <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 - <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 _contributors = contributors;
740 return this;
741 }
742
743 /***
744 * <li>Rss 1.0 - <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 - <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 if(ArrayUtils.isEmpty(contributor)){
759 LOG.warn("empty person array is ignored");
760 return this;
761 }
762 if(_contributors == null){
763 _contributors = new ArrayList<Person>();
764 }
765 for(Person p : contributor){
766 _contributors.add(p);
767 }
768 return this;
769 }
770
771 /***
772 * <li>Rss 1.0 - <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 - <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 if(ArrayUtils.isEmpty(emailOrText)){
785 LOG.warn("empty array is ignored");
786 return this;
787 }
788 if(_contributors == null){
789 _contributors = new ArrayList<Person>();
790 }
791 for(String e : emailOrText){
792 _contributors.add(new Person(e));
793 }
794 return this;
795 }
796
797 /***
798 * <li>Rss 1.0 - <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 return _categorySubjects;
809 }
810
811
812 /***
813 * <li>Rss 1.0 - <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 _categorySubjects = categorySubjects;
825 return this;
826 }
827
828 /***
829 * <li>Rss 1.0 - <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 if(ArrayUtils.isEmpty(categorySubjectOrTerm)){
844 LOG.warn("Empty category array is ignored");
845 return this;
846 }
847 if(_categorySubjects == null){
848 _categorySubjects = new HashSet<CategorySubject>();
849 }
850 for(String c : categorySubjectOrTerm){
851 _categorySubjects.add(new CategorySubject(c));
852 }
853
854 return this;
855 }
856
857 /***
858 * <li>Rss 1.0 - <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 if(ArrayUtils.isEmpty(categorySubject)){
873 LOG.warn("Empty category array is ignored");
874 return this;
875 }
876
877 if(_categorySubjects == null){
878 _categorySubjects = new HashSet<CategorySubject>();
879 }
880 for(CategorySubject s : categorySubject){
881 _categorySubjects.add(s);
882 }
883 return this;
884 }
885
886
887 /***
888 * <li>Rss 1.0 - <dc:date> A date associated with an event in the life cycle of the resource.
889 * </li>
890 * <li>Rss 2.0 - <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 return _pubDate;
898 }
899
900
901 /***
902 * <li>Rss 1.0 - <dc:date> A date associated with an event in the life cycle of the resource.
903 * </li>
904 * <li>Rss 2.0 - <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 _pubDate = pubDate;
913 return this;
914 }
915
916 /***
917 * <li>Rss 1.0 - <dc:date> A date associated with an event in the life cycle of the resource.
918 * </li>
919 * <li>Rss 2.0 - <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 _pubDate = format.format(pubDate);
932 return this;
933 }
934
935
936 /***
937 * <li>Rss 1.0 - Not supported, this field is ignored.
938 * </li>
939 * <li>Rss 2.0 - <lastBuildDate> The last time the content of the channel changed.
940 * </li>
941 * <li>Atom 1.0 - <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 return _lastBuildOrUpdatedDate;
950 }
951
952
953 /***
954 * <li>Rss 1.0 - Not supported, this field is ignored.
955 * </li>
956 * <li>Rss 2.0 - <lastBuildDate> The last time the content of the channel changed.
957 * </li>
958 * <li>Atom 1.0 - <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 _lastBuildOrUpdatedDate = lastBuildOrUpdatedDate;
968 return this;
969 }
970
971 /***
972 * <li>Rss 1.0 - Not supported, this field is ignored.
973 * </li>
974 * <li>Rss 2.0 - <lastBuildDate> The last time the content of the channel changed.
975 * </li>
976 * <li>Atom 1.0 - <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 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 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 _uid = uid;
1015 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 if(_uid == null){
1032 _uid = null;
1033 return this;
1034 }
1035 _uid = new Id(uid);
1036 return this;
1037 }
1038
1039
1040 /***
1041 * <li>Rss 1.0 - Not supported, this is ignored.</li>
1042 * <li>Rss 2.0 - <generator> A string indicating the program used to generate the channel.
1043 * </li>
1044 * <li>Atom 1.0 - <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 return _generator;
1051 }
1052
1053 /***
1054 * <li>Rss 1.0 - Not supported, this is ignored.</li>
1055 * <li>Rss 2.0 - <generator> A string indicating the program used to generate the channel.
1056 * </li>
1057 * <li>Atom 1.0 - <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 _generator = generator;
1065 return this;
1066 }
1067
1068 /***
1069 * <li>Rss 1.0 - Not supported, this is ignored.</li>
1070 * <li>Rss 2.0 - <generator> A string indicating the program used to generate the channel.
1071 * </li>
1072 * <li>Atom 1.0 - <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 _generator = generatorValue == null?null: new Generator(generatorValue);
1082 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 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 _docs = docs;
1107 return this;
1108 }
1109
1110 /***
1111 * <li>Rss 1.0 - This value is parsed from both the
1112 * <sy:updatePeriod> and <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 return _ttl;
1123 }
1124
1125 /***
1126 * <li>Rss 1.0 - This value is parsed from both the
1127 * <sy:updatePeriod> and <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 _ttl = ttl;
1139 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 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 _cloud = cloud;
1163 return this;
1164 }
1165
1166 /***
1167 * <li>Rss 1.0 - <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 - <image>
1171 * Specifies a GIF, JPEG or PNG image that can be displayed with the channel. </li>
1172 * <li>Atom 1.0 - <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 return _imageOrIcon;
1180 }
1181
1182 /***
1183 * <li>Rss 1.0 - <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 - <image>
1187 * Specifies a GIF, JPEG or PNG image that can be displayed with the channel. </li>
1188 * <li>Atom 1.0 - <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 _imageOrIcon = imageOrIcon;
1197 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 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 _logo = logo;
1219 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 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 _texInput = texInput;
1245 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 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 for(Integer i : skipHours){
1265 if(i == null || i <0 || i >23){
1266 throw new IllegalArgumentException("all skip hour must be a value that is a number between 0 and 23");
1267 }
1268 }
1269 _skipHours = skipHours;
1270 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 if(!ArrayUtils.isEmpty(hour)){
1282 for(int h : hour){
1283 if(h <0 || h >23){
1284 throw new IllegalArgumentException("all skip hour must be a value that is a number between 0 and 23");
1285 }
1286 if(_skipHours == null){
1287 _skipHours = new HashSet<Integer>();
1288 }
1289 _skipHours.add(h);
1290 }
1291 }
1292 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 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 _skipDays = skipDays;
1308 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 if(!ArrayUtils.isEmpty(day)){
1317 if(_skipDays == null){
1318 _skipDays = new HashSet<Day>();
1319 }
1320 _skipDays.addAll(Arrays.asList(day));
1321 }
1322
1323 return this;
1324 }
1325
1326
1327
1328 /***
1329 * Any other attribute that is not in the RSS 2.0 specs.
1330 */
1331 public ChannelFeed setOtherAttributes(Map<QName, String> otherAttributes) {
1332 _otherAttributes = otherAttributes;
1333 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 if(_otherAttributes == null){
1340 _otherAttributes = new HashMap<QName, String>();
1341 }
1342 _otherAttributes.put(namespace, attribute);
1343 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 _otherElements = otherElements;
1352 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 if(_otherElements == null){
1361 _otherElements = new ArrayList<Element>();
1362 }
1363 _otherElements.add(element);
1364 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 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 _base = base;
1393 return this;
1394 }
1395 /***
1396 * <li>Rss 2.0 - <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 <channel> support this element.</li>
1402 * <li>Rss 1.0 - <dc:language> element. A language of the intellectual content of the resource.
1403 * Only <channel> and <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 <channel> and <item>
1407 * @param lang
1408 * @return
1409 */
1410 public ChannelFeed setLang(String lang) {
1411 _lang = lang;
1412 return this;
1413 }
1414
1415 /***
1416 * <li>Rss 2.0 - <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 <channel> support this element.</li>
1422 * <li>Rss 1.0 - <dc:language> element. A language of the intellectual content of the resource.
1423 * Only <channel> and <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 <channel> and <item>
1427 * @param lang
1428 * @return
1429 */
1430 public ChannelFeed setLang(Locale lang) {
1431 _lang = lang.getLanguage();
1432 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 _resource = resource;
1441 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 _about = about;
1450 return this;
1451 }
1452
1453
1454 @Override
1455 public void validate(FeedFormat format) throws ValidationException {
1456 if(CollectionUtils.isEmpty(_items)){
1457 throw new ValidationException("Channel: You should have at least 1 item");
1458 }
1459
1460 for(ItemEntry item : _items){
1461 ValidationUtils.validateNotNull("Channel: All item should not be null", item);
1462 item.validate(format);
1463 }
1464
1465 ValidationUtils.validateNotNull("Channel: Title, Link and Description should not be null", _title, _links, _descriptionOrSubtitle);
1466
1467 _title.validate(format);
1468 _descriptionOrSubtitle.validate(format);
1469
1470 for(Link l : _links){
1471 l.validate(format);
1472 }
1473
1474 if(_categorySubjects != null){
1475 for(CategorySubject c: _categorySubjects){
1476 c.validate(format);
1477 }
1478 }
1479 if(_cloud != null){
1480 _cloud.validate(format);
1481 }
1482 if(_imageOrIcon != null){
1483 _imageOrIcon.validate(format);
1484 }
1485 if(_logo != null){
1486 _logo.validate(format);
1487 }
1488 if(_texInput != null){
1489 _texInput.validate(format);
1490 }
1491
1492 if(_uid != null){
1493 _uid.validate(format);
1494 }
1495
1496 if(_generator != null){
1497 _generator.validate(format);
1498 }
1499
1500 if(_contributors != null){
1501 for(Person p : _contributors){
1502 p.validate(format);
1503 }
1504 }
1505
1506 if(_managingEditorOrAuthorOrPublisher != null){
1507 for(Person p : _managingEditorOrAuthorOrPublisher){
1508 p.validate(format);
1509 }
1510 }
1511
1512 if(_webMasterOrCreator != null){
1513 for(Person p : _webMasterOrCreator){
1514 p.validate(format);
1515 }
1516 }
1517
1518 if(_rights != null){
1519 _rights.validate(format);
1520 }
1521
1522 }
1523
1524 }