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.Date;
7 import java.util.HashMap;
8 import java.util.HashSet;
9 import java.util.List;
10 import java.util.Locale;
11 import java.util.Map;
12 import java.util.Set;
13
14 import javax.xml.namespace.QName;
15 import javax.xml.parsers.ParserConfigurationException;
16
17 import org.apache.commons.lang.ArrayUtils;
18 import org.apache.commons.logging.Log;
19 import org.apache.commons.logging.LogFactory;
20 import org.w3c.dom.Element;
21 import org.xml.sax.SAXException;
22
23 import yarfraw.utils.XMLUtils;
24
25 /***
26 *
27 * A channel may contain any number of {@link ItemEntry}s.
28 * An item may represent a "story" -- much like a story in a newspaper or magazine;
29 * if so its description is a synopsis of the story, and the link points to the full story.
30 * An item may also be complete in itself, if so, the description contains the text
31 * (entity-encoded HTML is allowed; see examples),
32 * and the link and title may be omitted.
33 * All elements of an item are optional, however at least one of title or description must be present.
34 * <p/>
35 * for Atom 1.0 format, the field also mapps to <entry> element.
36 * <br/>
37 * @author jliang
38 *
39 */
40 public class ItemEntry extends AbstractBaseObject{
41 private static final long serialVersionUID = 20070927L;
42 private static final Log LOG = LogFactory.getLog(ItemEntry.class);
43 private Text _title;
44 private List<Link> _links;
45 private Text _descriptionOrSummary;
46 private List<Person> _authorOrCreator;
47 private List<Person> _contributors;
48 private Set<CategorySubject> _categorySubjects;
49 private String _comments;
50 private Enclosure _enclosure;
51 private Id _uid;
52 private String _pubDate;
53 private String _updatedDate;
54 private Source _source;
55 private Text _rights;
56 private Content _content;
57
58 public ItemEntry(){}
59
60 /***
61 * <li>Rss 1.0 - The item's title.
62 * </li>
63 * <li>Rss 2.0 - The title of the item.
64 * </li>
65 * <li>Atom 1.0 -
66 * The "atom:title" element is a Text construct that conveys a human-readable title for an entry or feed.
67 * </li>
68 * @return
69 */
70 public Text getTitle() {
71 return _title;
72 }
73
74 /***
75 * <li>Rss 1.0 - The item's title.
76 * </li>
77 * <li>Rss 2.0 - The title of the item.
78 * </li>
79 * <li>Atom 1.0 -
80 * The "atom:title" element is a Text construct that conveys a human-readable title for an entry or feed.
81 * </li>
82 * @param title
83 * @return
84 */
85 public ItemEntry setTitle(Text title) {
86 _title = title;
87 return this;
88 }
89
90 /***
91 * <li>Rss 1.0 - The item's title.
92 * </li>
93 * <li>Rss 2.0 - The title of the item.
94 * </li>
95 * <li>Atom 1.0 -
96 * The "atom:title" element is a Text construct that conveys a human-readable title for an entry or feed.
97 * </li>
98 * <br/>
99 * This method creates a new {@link Text} object using the input string and sets title to this object.
100 * @param title
101 * @return
102 */
103 public ItemEntry setTitle(String title) {
104 return setTitle(new Text(title));
105 }
106
107 /***
108 * <li>Rss 1.0 - The item's title.
109 * </li>
110 * <li>Rss 2.0 - The title of the item.
111 * </li>
112 * <li>Atom 1.0 -
113 * The "atom:title" element is a Text construct that conveys a human-readable title for an entry or feed.
114 * </li>
115 * <br/>
116 * Gets the text content of the title element.
117 * @return
118 */
119 public String getTitleText(){
120 return _title == null?null:_title.getText();
121 }
122
123 /***
124 * <li>Rss 1.0 - The item's URL.
125 * </li>
126 * <li>Rss 2.0 - The URL of the item.
127 * </li>
128 * <li>Atom 1.0 - The "atom:link" element defines a reference from an entry or
129 * feed to a Web resource. This specification assigns no meaning to the content (if any) of this element.
130 * </li>
131 *
132 * <br/>
133 * <b>Only Atom 1.0 supports multiple link elements. Both Rss 1.0 and Rss 2.0 will only use the FIRST link in the list
134 * as the link element</b>
135 * @return
136 */
137 public List<Link> getLinks() {
138 return _links;
139 }
140 /***
141 * <li>Rss 1.0 - The item's URL.
142 * </li>
143 * <li>Rss 2.0 - The URL of the item.
144 * </li>
145 * <li>Atom 1.0 - The "atom:link" element defines a reference from an entry or
146 * feed to a Web resource. This specification assigns no meaning to the content (if any) of this element.
147 * </li>
148 *
149 * <br/>
150 * <b>Only Atom 1.0 supports multiple link elements. Both Rss 1.0 and Rss 2.0 will only use the FIRST link in the list
151 * as the link element</b>
152 * @param links
153 * @return
154 */
155 public ItemEntry setLinks(List<Link> links) {
156 _links = links;
157 return this;
158 }
159
160 /***
161 * <li>Rss 1.0 - The item's URL.
162 * </li>
163 * <li>Rss 2.0 - The URL of the item.
164 * </li>
165 * <li>Atom 1.0 - The "atom:link" element defines a reference from an entry or
166 * feed to a Web resource. This specification assigns no meaning to the content (if any) of this element.
167 * </li>
168 *
169 * <br/>
170 * This method creates new {@link Link} objects and adds them to the END of the links list.
171 * <br/>
172 * <b>Only Atom 1.0 supports multiple link elements. Both Rss 1.0 and Rss 2.0 will only use the FIRST link in the list
173 * as the link element</b>
174 * @param href
175 * @return
176 */
177 public ItemEntry addLink(String... href) {
178 if(ArrayUtils.isEmpty(href)){
179 LOG.warn("Empty href array is ignored");
180 return this;
181 }
182 if(_links == null){
183 _links = new ArrayList<Link>();
184 }
185 for (String s:href){
186 _links.add(new Link(s));
187 }
188 return this;
189 }
190
191 /***
192 * <li>Rss 1.0 - The item's URL.
193 * </li>
194 * <li>Rss 2.0 - The URL of the item.
195 * </li>
196 * <li>Atom 1.0 - The "atom:link" element defines a reference from an entry or
197 * feed to a Web resource. This specification assigns no meaning to the content (if any) of this element.
198 * </li>
199 *
200 * <br/>
201 * This method adds input {@link Link} to the END of the links list.
202 * <br/>
203 * <b>Only Atom 1.0 supports multiple link elements. Both Rss 1.0 and Rss 2.0 will only use the FIRST link in the list
204 * as the link element</b>
205 * @param link
206 * @return
207 */
208 public ItemEntry addLink(Link... link) {
209 if(ArrayUtils.isEmpty(link)){
210 LOG.warn("Empty link array is ignored");
211 return this;
212 }
213 if(_links == null){
214 _links = new ArrayList<Link>();
215 }
216 for(Link l : link){
217 _links.add(l);
218 }
219 return this;
220 }
221 /***
222 * <li>Rss 1.0 - A brief description/abstract of the item.
223 * </li>
224 * <li>Rss 2.0 - The item synopsis.
225 * </li>
226 * <li>Atom 1.0 - The "atom:summary" element is a Text construct that conveys a short summary, abstract, or excerpt of an entry.
227 * </li>
228 *
229 * <br/>
230 * Note: for Rss 1.0, this is mapped to the <description> element, not the <dc:description> element.
231 * @return
232 */
233 public Text getDescriptionOrSummary() {
234 return _descriptionOrSummary;
235 }
236
237 /***
238 * <li>Rss 1.0 - A brief description/abstract of the item.
239 * </li>
240 * <li>Rss 2.0 - The item synopsis.
241 * </li>
242 * <li>Atom 1.0 - The "atom:summary" element is a Text construct that conveys a short summary, abstract, or excerpt of an entry.
243 * </li>
244 *
245 * @param descriptionOrSummary
246 * @return
247 */
248 public ItemEntry setDescriptionOrSummary(Text descriptionOrSummary) {
249 _descriptionOrSummary = descriptionOrSummary;
250 return this;
251 }
252
253 /***
254 * <li>Rss 1.0 - A brief description/abstract of the item.
255 * </li>
256 * <li>Rss 2.0 - The item synopsis.
257 * </li>
258 * <li>Atom 1.0 - The "atom:summary" element is a Text construct that conveys a short summary, abstract, or excerpt of an entry.
259 * </li>
260 *
261 * <br/>
262 * This method creates a new {@link Text} object of type 'text' with the input string as its text content.
263 * @param descriptionOrSummary
264 * @return
265 */
266 public ItemEntry setDescriptionOrSummary(String descriptionOrSummary) {
267 if(descriptionOrSummary == null){
268 _descriptionOrSummary = null;
269 return this;
270 }
271 return setDescriptionOrSummary(new Text(descriptionOrSummary));
272 }
273
274 /***
275 * <li>Rss 1.0 - A brief description/abstract of the item.
276 * </li>
277 * <li>Rss 2.0 - The item synopsis.
278 * </li>
279 * <li>Atom 1.0 - The "atom:summary" element is a Text construct that conveys a short summary, abstract, or excerpt of an entry.
280 * </li>
281 *
282 * <br/>
283 * This methods gets the text content of the <code>descriptionOrSummary</code> field on the current instance.
284 * @return
285 */
286 public String getDescriptionOrSummaryText() {
287 return _descriptionOrSummary == null?null:_descriptionOrSummary.getText();
288 }
289
290 /***
291 * <li>Rss 1.0 - <dc:creator> An entity primarily responsible for making the content of
292 the resource.
293 * </li>
294 * <li>Rss 2.0 - Email address of the author of the item.
295 * </li>
296 * <li>Atom 1.0 - The "atom:author" element is a Person construct that indicates the author of the entry or feed.
297 * </li>
298 * <br/>
299 * Note: only Rss 1.0 and Rss 2.0 only uses the email field of a {@link Person} object, all the other fields are ignored.
300 *
301 * @return
302 */
303 public List<Person> getAuthorOrCreator() {
304 return _authorOrCreator;
305 }
306
307 /***
308 * <li>Rss 1.0 - <dc:creator> An entity primarily responsible for making the content of
309 the resource.
310 * </li>
311 * <li>Rss 2.0 - Email address of the author of the item.
312 * </li>
313 * <li>Atom 1.0 - The "atom:author" element is a Person construct that indicates the author of the entry or feed.
314 * </li>
315 * <br/>
316 * Note: only Rss 1.0 and Rss 2.0 only uses the email field of a {@link Person} object, all the other fields are ignored.
317 * @param author
318 * @return
319 */
320 public ItemEntry setAuthorOrCreator(List<Person> authorOrCreator) {
321 _authorOrCreator = authorOrCreator;
322 return this;
323 }
324
325 /***
326 * <li>Rss 1.0 - <dc:creator> An entity primarily responsible for making the content of
327 the resource.
328 * </li>
329 * <li>Rss 2.0 - Email address of the author of the item.
330 * </li>
331 * <li>Atom 1.0 - The "atom:author" element is a Person construct that indicates the author of the entry or feed.
332 * </li>
333 * <br/>
334 * This method constructs a new {@link Person} object using only the email address and
335 * adds them to the END of the <code>authorOrCreator</code> list.
336 * <br/>
337 * Note: only Rss 1.0 and Rss 2.0 only uses the email field of a {@link Person} object, all the other fields are ignored.
338 * @param email
339 * @return
340 */
341 public ItemEntry addAuthorOrCreator(String... email) {
342 if(ArrayUtils.isEmpty(email)){
343 LOG.warn("Empty email array is ignored");
344 return this;
345 }
346
347 if(_authorOrCreator == null){
348 _authorOrCreator = new ArrayList<Person>();
349 }
350 for(String e : email){
351 _authorOrCreator.add(new Person(e));
352 }
353 return this;
354 }
355 /***
356 * <li>Rss 1.0 - <dc:creator> An entity primarily responsible for making the content of
357 the resource.
358 * </li>
359 * <li>Rss 2.0 - Email address of the author of the item.
360 * </li>
361 * <li>Atom 1.0 - The "atom:author" element is a Person construct that indicates the author of the entry or feed.
362 * </li>
363 * <br/>
364 * This method constructs a new {@link Person} object using only the email address and
365 * adds them to the END of the <code>authorOrCreator</code> list.
366 * <br/>
367 * Note: only Rss 1.0 and Rss 2.0 only uses the email field of a {@link Person} object, all the other fields are ignored.
368 * @param authorOrCreator
369 * @return
370 */
371 public ItemEntry addAuthorOrCreator(Person... authorOrCreator) {
372 if(ArrayUtils.isEmpty(authorOrCreator)){
373 LOG.warn("Empty author array is ignored");
374 return this;
375 }
376
377 if(_authorOrCreator == null){
378 _authorOrCreator = new ArrayList<Person>();
379 }
380 for(Person p : authorOrCreator){
381 _authorOrCreator.add(p);
382 }
383 return this;
384 }
385
386
387 /***
388 * <li>Rss 1.0 - <dc:contributor> An entity responsible for making contributions to the content of the resource.
389 * <br/><b>When this element is map to contributor in Rss 1.0, only the email address is used, other fields are ignored.</b>
390 * </li>
391 * <li>Rss 2.0 - Not supported, this list is ignored.
392 * </li>
393 * <li>Atom 1.0 - The "atom:contributor" element is a Person construct that indicates a person or other entity who contributed to the entry or feed.
394 * </li>
395 * @return
396 */
397 public List<Person> getContributors() {
398 return _contributors;
399 }
400
401 /***
402 * <li>Rss 1.0 - <dc:contributor> An entity responsible for making contributions to the content of the resource.
403 * <br/><b>When this element is map to contributor in Rss 1.0, only the email address is used, other fields are ignored.</b>
404 * </li>
405 * <li>Rss 2.0 - Not supported, this list is ignored.
406 * </li>
407 * <li>Atom 1.0 - The "atom:contributor" element is a Person construct that indicates a person or other entity who contributed to the entry or feed.
408 * </li>
409 * @param contributors
410 * @return
411 */
412 public ItemEntry setContributors(List<Person> contributors) {
413 _contributors = contributors;
414 return this;
415 }
416
417 /***
418 * <li>Rss 1.0 - <dc:contributor> An entity responsible for making contributions to the content of the resource.
419 * <br/><b>When this element is map to contributor in Rss 1.0, only the email address is used, other fields are ignored.</b>
420 * </li>
421 * <li>Rss 2.0 - Not supported, this list is ignored.
422 * </li>
423 * <li>Atom 1.0 - The "atom:contributor" element is a Person construct that indicates a person or other entity who contributed to the entry or feed.
424 * </li>
425 *
426 * <br/>
427 * This method adds the input contributor to the END of the contributors list.
428 * @param contributor
429 * @return
430 */
431 public ItemEntry addContributor(Person... contributor){
432 if(ArrayUtils.isEmpty(contributor)){
433 LOG.warn("Empty contributor array is ignored");
434 return this;
435 }
436
437 if(_contributors == null){
438 _contributors = new ArrayList<Person>();
439 }
440 for(Person p : contributor){
441 _contributors.add(p);
442 }
443 return this;
444 }
445
446 /***
447 * <li>Rss 1.0 - <dc:contributor> An entity responsible for making contributions to the content of the resource.
448 * <br/><b>When this element is map to contributor in Rss 1.0, only the email address is used, other fields are ignored.</b>
449 * </li>
450 * <li>Rss 2.0 - Not supported, this list is ignored.
451 * </li>
452 * <li>Atom 1.0 - The "atom:contributor" element is a Person construct that indicates a person or other entity who contributed to the entry or feed.
453 * </li>
454 *
455 * <br/>
456 * This method adds the input contributor to the END of the contributors list.
457 * @param contributor
458 * @return
459 */
460 public ItemEntry addContributor(String... contributor){
461 if(ArrayUtils.isEmpty(contributor)){
462 LOG.warn("Empty contributor array is ignored");
463 return this;
464 }
465
466 if(_contributors == null){
467 _contributors = new ArrayList<Person>();
468 }
469 for(String c : contributor){
470 _contributors.add(new Person(c));
471 }
472 return this;
473 }
474 /***
475 * <li>Rss 1.0 - <dc:subject> The topic of the content of the resource.
476 * </li>
477 * <li>Rss 2.0 - Includes the item in one or more categories.
478 * </li>
479 * <li>Atom 1.0 - The "atom:category" element conveys information about a category
480 * associated with an entry or feed. This specification assigns no meaning to the content (if any) of this element.
481 * </li>
482 * @return
483 */
484 public Set<CategorySubject> getCategorySubjects() {
485 return _categorySubjects;
486 }
487
488
489 /***
490 * <li>Rss 1.0 - <dc:subject> The topic of the content of the resource.
491 * </li>
492 * <li>Rss 2.0 - Includes the item in one or more categories.
493 * </li>
494 * <li>Atom 1.0 - The "atom:category" element conveys information about a category
495 * associated with an entry or feed. This specification assigns no meaning to the content (if any) of this element.
496 * </li>
497 * @param categorySubjects
498 * @return
499 */
500 public ItemEntry setCategorySubjects(Set<CategorySubject> categorySubjects) {
501 _categorySubjects = categorySubjects;
502 return this;
503 }
504
505 /***
506 * <li>Rss 1.0 - <dc:subject> The topic of the content of the resource.
507 * </li>
508 * <li>Rss 2.0 - Includes the item in one or more categories.
509 * </li>
510 * <li>Atom 1.0 - The "atom:category" element conveys information about a category
511 * associated with an entry or feed. This specification assigns no meaning to the content (if any) of this element.
512 * </li>
513 *
514 * <br/>
515 * This method creates new {@link CategorySubject} objects using the input strings and add them to the category set.
516 * @param categorySubjectOrTerm
517 * @return
518 */
519 public ItemEntry addCategorySubject(String... categorySubjectOrTerm) {
520 if(ArrayUtils.isEmpty(categorySubjectOrTerm)){
521 LOG.warn("Empty category array is ignored");
522 return this;
523 }
524 if(_categorySubjects == null){
525 _categorySubjects = new HashSet<CategorySubject>();
526 }
527 for(String c : categorySubjectOrTerm){
528 _categorySubjects.add(new CategorySubject(c));
529 }
530
531 return this;
532 }
533
534 /***
535 * <li>Rss 1.0 - <dc:subject> The topic of the content of the resource.
536 * </li>
537 * <li>Rss 2.0 - Includes the item in one or more categories.
538 * </li>
539 * <li>Atom 1.0 - The "atom:category" element conveys information about a category
540 * associated with an entry or feed. This specification assigns no meaning to the content (if any) of this element.
541 * </li>
542 *
543 * <br/>
544 * This method adds the input {@link CategorySubject} objects to the category set.
545 * @param categorySubject
546 * @return
547 */
548 public ItemEntry addCategorySubject(CategorySubject... categorySubject) {
549 if(ArrayUtils.isEmpty(categorySubject)){
550 LOG.warn("Empty category array is ignored");
551 return this;
552 }
553
554 if(_categorySubjects == null){
555 _categorySubjects = new HashSet<CategorySubject>();
556 }
557 for(CategorySubject s : categorySubject){
558 _categorySubjects.add(s);
559 }
560 return this;
561 }
562
563 /***
564 * <li>Rss 1.0 - Not supported, this field is ignored.
565 * </li>
566 * <li>Rss 2.0 - URL of a page for comments relating to the item.
567 * </li>
568 * <li>Atom 1.0 - Not supported, this is field is ignored.
569 * </li>
570 * @return
571 */
572 public String getComments() {
573 return _comments;
574 }
575
576 /***
577 * <li>Rss 1.0 - Not supported, this field is ignored.
578 * </li>
579 * <li>Rss 2.0 - URL of a page for comments relating to the item.
580 * </li>
581 * <li>Atom 1.0 - Not supported, this is field is ignored.
582 * </li>
583 * @param comments
584 * @return
585 */
586 public ItemEntry setComments(String comments) {
587 _comments = comments;
588 return this;
589 }
590
591 /***
592 * <li>Rss 1.0 - Not supported, this field is ignored.
593 * </li>
594 * <li>Rss 2.0 - Describes a media object that is attached to the item.
595 * </li>
596 * <li>Atom 1.0 - Not supported, this field is ignored.
597 * </li>
598 * @return
599 */
600 public Enclosure getEnclosure() {
601 return _enclosure;
602 }
603
604 /***
605 * <li>Rss 1.0 - Not supported, this field is ignored.
606 * </li>
607 * <li>Rss 2.0 - Describes a media object that is attached to the item.
608 * </li>
609 * <li>Atom 1.0 - Not supported, this field is ignored.
610 * </li>
611 * @param enclosure
612 * @return
613 */
614 public ItemEntry setEnclosure(Enclosure enclosure) {
615 _enclosure = enclosure;
616 return this;
617 }
618
619 /***
620 * <li>Rss 1.0 - Not supported, this field is ignored.
621 * </li>
622 * <li>Rss 2.0 - <guid> A string that uniquely identifies the item.
623 * </li>
624 * <li>Atom 1.0 - The "atom:id" element conveys a permanent, universally unique identifier for an entry or feed.
625 * </li>
626 * @return
627 */
628 public Id getUid() {
629 return _uid;
630 }
631
632 /***
633 * <li>Rss 1.0 - Not supported, this field is ignored.
634 * </li>
635 * <li>Rss 2.0 - <guid> A string that uniquely identifies the item.
636 * </li>
637 * <li>Atom 1.0 - The "atom:id" element conveys a permanent, universally unique identifier for an entry or feed.
638 * </li>
639 * @param uid
640 * @return
641 */
642 public ItemEntry setUid(Id uid) {
643 _uid = uid;
644 return this;
645 }
646
647 /***
648 * <li>Rss 1.0 - Not supported, this field is ignored.
649 * </li>
650 * <li>Rss 2.0 - <guid> A string that uniquely identifies the item.
651 * </li>
652 * <li>Atom 1.0 - The "atom:id" element conveys a permanent, universally unique identifier for an entry or feed.
653 * </li>
654 * <br/>
655 * This method constructs a new {@link Id} object and sets the <code>uid</code> field to this object.
656 * @param uid
657 * @return
658 */
659 public ItemEntry setUid(String uid){
660 if(uid == null){
661 _uid = null;
662 return this;
663 }
664 return setUid(new Id(uid));
665 }
666
667
668 /***
669 * <li>Rss 1.0 - <dc:date> A date associated with an event in the life cycle of the resource.
670 * </li>
671 * <li>Rss 2.0 - <pubDate> Indicates when the item was published.
672 * </li>
673 * <li>Atom 1.0 - <published> The "atom:published" element is a Date construct indicating an instant in time
674 * associated with an event early in the life cycle of the entry.
675 * </li>
676 * @return
677 */
678 public String getPubDate() {
679 return _pubDate;
680 }
681
682
683 /***
684 * <li>Rss 1.0 - <dc:date> A date associated with an event in the life cycle of the resource.
685 * </li>
686 * <li>Rss 2.0 - <pubDate> Indicates when the item was published.
687 * </li>
688 * <li>Atom 1.0 - <published> The "atom:published" element is a Date construct indicating an instant in time
689 * associated with an event early in the life cycle of the entry.
690 * </li>
691 * @param pubDate
692 * @return
693 */
694 public ItemEntry setPubDate(String pubDate) {
695 _pubDate = pubDate;
696 return this;
697 }
698
699 /***
700 * <li>Rss 1.0 - <dc:date> A date associated with an event in the life cycle of the resource.
701 * </li>
702 * <li>Rss 2.0 - <pubDate> Indicates when the item was published.
703 * </li>
704 * <li>Atom 1.0 - <published> The "atom:published" element is a Date construct indicating an instant in time
705 * associated with an event early in the life cycle of the entry.
706 * </li>
707 *
708 * <br/>
709 * This method uses the input {@link SimpleDateFormat} object to format the date into a string.
710 * @param pubDate
711 * @param format
712 * @return
713 */
714 public ItemEntry setPubDate(Date pubDate, SimpleDateFormat format){
715 return setPubDate(format.format(pubDate));
716 }
717
718 /***
719 * <li>Rss 1.0 - Not supported, this field is ignored.
720 * </li>
721 * <li>Rss 2.0 - Not supported, this field is ignored.
722 * </li>
723 * <li>Atom 1.0 - <updated> The "atom:updated" element is a Date construct indicating the most recent
724 * instant in time when an entry or feed was modified in a way the publisher considers significant.
725 * Therefore, not all modifications necessarily result in a changed atom:updated value.
726 * </li>
727 * @return
728 */
729 public String getUpdatedDate() {
730 return _updatedDate;
731 }
732
733 /***
734 * <li>Rss 1.0 - Not supported, this field is ignored.
735 * </li>
736 * <li>Rss 2.0 - Not supported, this field is ignored.
737 * </li>
738 * <li>Atom 1.0 - <updated> The "atom:updated" element is a Date construct indicating the most recent
739 * instant in time when an entry or feed was modified in a way the publisher considers significant.
740 * Therefore, not all modifications necessarily result in a changed atom:updated value.
741 * </li>
742 * @param updatedDate
743 * @return
744 */
745 public ItemEntry setUpdatedDate(String updatedDate) {
746 _updatedDate = updatedDate;
747 return this;
748 }
749
750
751 /***
752 * <li>Rss 1.0 - Not supported, this field is ignored.
753 * </li>
754 * <li>Rss 2.0 - Not supported, this field is ignored.
755 * </li>
756 * <li>Atom 1.0 - <updated> The "atom:updated" element is a Date construct indicating the most recent
757 * instant in time when an entry or feed was modified in a way the publisher considers significant.
758 * Therefore, not all modifications necessarily result in a changed atom:updated value.
759 * </li>
760 *
761 * <br/>
762 * This method uses the input {@link SimpleDateFormat} object to format the date into a string.
763 * @param date
764 * @param format
765 * @return
766 */
767 public ItemEntry setUpdatedDate(Date date, SimpleDateFormat format) {
768 return setUpdatedDate(format.format(date));
769 }
770
771
772 /***
773 * <li>Rss 1.0 - Not supported, this field is ignored.
774 * </li>
775 * <li>Rss 2.0 - The RSS channel that the item came from.
776 * </li>
777 * <li>Atom 1.0 - Not supported, this field is ignored.
778 * </li>
779 * @return
780 */
781 public Source getSource() {
782 return _source;
783 }
784
785 /***
786 * <li>Rss 1.0 - Not supported, this field is ignored.
787 * </li>
788 * <li>Rss 2.0 - <source> The RSS channel that the item came from.
789 * </li>
790 * <li>Atom 1.0 - Not supported, this field is ignored.
791 * </li>
792 * @param source
793 * @return
794 */
795 public ItemEntry setSource(Source source) {
796 _source = source;
797 return this;
798 }
799
800
801 /***
802 * <li>Rss 1.0 - <dc:rights> Information about rights held in and over the resource.
803 * </li>
804 * <li>Rss 2.0 - Not supported, this field is ignored.
805 * </li>
806 * <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.
807 * </li>
808 * @return
809 */
810 public Text getRights() {
811 return _rights;
812 }
813 /***
814 * <li>Rss 1.0 - <dc:rights> Information about rights held in and over the resource.
815 * </li>
816 * <li>Rss 2.0 - Not supported, this field is ignored.
817 * </li>
818 * <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.
819 * </li>
820 *
821 * @return the text content of the <code>rights</code> field.
822 */
823 public String getRightsText() {
824 return _rights == null ? null:_rights.getText();
825 }
826
827 /***
828 * <li>Rss 1.0 - <dc:rights> Information about rights held in and over the resource.
829 * </li>
830 * <li>Rss 2.0 - Not supported, this field is ignored.
831 * </li>
832 * <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.
833 * </li>
834 * @param rights
835 * @return
836 */
837 public ItemEntry setRights(Text rights) {
838 _rights = rights;
839 return this;
840 }
841
842 /***
843 * <li>Rss 1.0 - <dc:rights> Information about rights held in and over the resource.
844 * </li>
845 * <li>Rss 2.0 - Not supported, this field is ignored.
846 * </li>
847 * <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.
848 * </li>
849 * <br/>
850 * This method creates a new {@link Text} object using the input string as its content and sets <code>rights</code> field to this object.
851 * @param rights
852 * @return
853 */
854 public ItemEntry setRights(String rights) {
855 if(rights == null){
856 _rights = null;
857 return this;
858 }
859 return setRights(new Text(rights));
860 }
861
862 /***
863 * <li>Rss 2.0 -
864 * This is not officially supported, but if there's a <content:encoded /> element under <Item>,
865 * the content of the encoded element will be mapped to this class. The type will always be 'text' in this case.
866 * </li>
867 * <li>Rss 1.0 -
868 * This is not officially supported, but if there's a <content:encoded /> element under <Item>,
869 * the content of the encoded element will be mapped to this class. The type will always be 'text' in this case.
870 * </li>
871 * <li>Atom 1.0 - <content>
872 * The "atom:content" element either contains or links to the content of the entry. The content of atom:content is Language-Sensitive.
873 * </li>
874 * @return
875 */
876 public Content getContent() {
877 return _content;
878 }
879
880 /***
881 * <li>Rss 2.0 -
882 * This is not officially supported, but if there's a <content:encoded /> element under <Item>,
883 * the content of the encoded element will be mapped to this class. The type will always be 'text' in this case.
884 * </li>
885 * <li>Rss 1.0 -
886 * This is not officially supported, but if there's a <content:encoded /> element under <Item>,
887 * the content of the encoded element will be mapped to this class. The type will always be 'text' in this case.
888 * </li>
889 * <li>Atom 1.0 - <content>
890 * The "atom:content" element either contains or links to the content of the entry. The content of atom:content is Language-Sensitive.
891 * </li>
892 * @param content
893 * @return
894 */
895 public ItemEntry setContent(Content content) {
896 _content = content;
897 return this;
898 }
899
900
901 /***
902 * <li>Rss 2.0 -
903 * This is not officially supported, but if there's a <content:encoded /> element under <Item>,
904 * the content of the encoded element will be mapped to this class. The type will always be 'text' in this case.
905 * </li>
906 * <li>Rss 1.0 -
907 * This is not officially supported, but if there's a <content:encoded /> element under <Item>,
908 * the content of the encoded element will be mapped to this class. The type will always be 'text' in this case.
909 * </li>
910 * <li>Atom 1.0 - <content>
911 * The "atom:content" element either contains or links to the content of the entry. The content of atom:content is Language-Sensitive.
912 * </li>
913 * <br/>
914 * This method constructs a new {@link Content} object of type 'text' and uses the input string as its text content.
915 * @param contentText
916 * @return
917 */
918 public ItemEntry setContent(String contentText) {
919 if(_content == null){
920 _content = null;
921 return this;
922 }
923 setContent(new Content(contentText));
924 return this;
925 }
926
927
928 /***
929 * Any other attribute that is not in the RSS 2.0 specs.
930 */
931 public ItemEntry setOtherAttributes(Map<QName, String> otherAttributes) {
932 _otherAttributes = otherAttributes;
933 return this;
934 }
935 /***
936 * Add an attribute that is not in the RSS 2.0 specs.
937 */
938 public ItemEntry addOtherAttributes(QName namespace, String attribute) {
939 if(_otherAttributes == null){
940 _otherAttributes = new HashMap<QName, String>();
941 }
942 _otherAttributes.put(namespace, attribute);
943 return this;
944 }
945
946 /***
947 * Other additional elements that are not in the Rss specs.<br/>
948 * **Note** The element should not have an empty namespace to avoid collision with the specs elements.
949 */
950 public ItemEntry setOtherElements(List<Element> otherElements) {
951 _otherElements = otherElements;
952 return this;
953 }
954 /***
955 * Add an element that is not specified in the Rss specs.<br/>
956 * **Note** The element should not have an empty namespace to avoid collision with the specs elements.
957 * @param element - any element
958 */
959 public ItemEntry addOtherElement(Element element){
960 if(_otherElements == null){
961 _otherElements = new ArrayList<Element>();
962 }
963 _otherElements.add(element);
964 return this;
965 }
966
967 /***
968 * Add an element that is not specified in the Rss specs.<br/>
969 * **Note** The element should not have an empty namespace to avoid collision with the specs elements.
970 *
971 * @param xmlString - any element
972 * @throws ParserConfigurationException
973 * @throws IOException
974 * @throws SAXException
975 */
976 public ItemEntry addOtherElement(String xmlString) throws SAXException, IOException, ParserConfigurationException{
977 return addOtherElement(XMLUtils.parseXml(xmlString, false, false).getDocumentElement());
978 }
979
980
981 /***
982 * <b>Atom 1.0 only</b><br/>
983 * Any element defined by this specification MAY have an xml:base attribute
984 * [W3C.REC-xmlbase-20010627]. When xml:base is used in an Atom Document,
985 * it serves the function described in section 5.1.1 of [RFC3986], establishing
986 * the base URI (or IRI) for resolving any relative references found within the
987 * effective scope of the xml:base attribute.
988 * @param base
989 * @return
990 */
991 public ItemEntry setBase(String base) {
992 _base = base;
993 return this;
994 }
995 /***
996 * <li>Rss 2.0 - <language> element.
997 * The language the channel is written in. This allows aggregators to group
998 * all Italian language sites, for example, on a single page. A list of allowable
999 * values for this element, as provided by Netscape, is here. You may also use values
1000 * defined by the W3C.
1001 * Only <channel> support this element.</li>
1002 * <li>Rss 1.0 - <dc:language> element. A language of the intellectual content of the resource.
1003 * Only <channel> and <item> support this element. </li>
1004 * <li>Atom 1.0 - 'lang' attribute</li>
1005 * <br/>
1006 * Note: for Rss 2.0 and Rss 1.0, only <channel> and <item>
1007 * @param lang
1008 * @return
1009 */
1010 public ItemEntry setLang(String lang) {
1011 _lang = lang;
1012 return this;
1013 }
1014 /***
1015 * <li>Rss 2.0 - <language> element.
1016 * The language the channel is written in. This allows aggregators to group
1017 * all Italian language sites, for example, on a single page. A list of allowable
1018 * values for this element, as provided by Netscape, is here. You may also use values
1019 * defined by the W3C.
1020 * Only <channel> support this element.</li>
1021 * <li>Rss 1.0 - <dc:language> element. A language of the intellectual content of the resource.
1022 * Only <channel> and <item> support this element. </li>
1023 * <li>Atom 1.0 - 'lang' attribute</li>
1024 * <br/>
1025 * Note: for Rss 2.0 and Rss 1.0, only <channel> and <item>
1026 * @param lang
1027 * @return
1028 */
1029 public ItemEntry setLang(Locale lang) {
1030 _lang = lang.getLanguage();
1031 return this;
1032 }
1033 /***
1034 * <b>Rss 1.0 only</b><br/>
1035 * @param resource
1036 * @return
1037 */
1038 public ItemEntry setResource(String resource) {
1039 _resource = resource;
1040 return this;
1041 }
1042 /***
1043 * <b>Rss 1.0 only</b><br/>
1044 * @param about
1045 * @return
1046 */
1047 public ItemEntry setAbout(String about) {
1048 _about = about;
1049 return this;
1050 }
1051
1052
1053 @Override
1054 public void validate(FeedFormat format) throws ValidationException {
1055
1056 if(_title == null && _descriptionOrSummary == null){
1057 throw new ValidationException("Item: At least one of title or description must be present.");
1058 }
1059 if(_categorySubjects != null){
1060 for(CategorySubject c: _categorySubjects){
1061 c.validate(format);
1062 }
1063 }
1064 if(_enclosure != null){
1065 _enclosure.validate(format);
1066 }
1067 if(_uid != null){
1068 _uid.validate(format);
1069 }
1070 if(_source != null){
1071 _source.validate(format);
1072 }
1073
1074 if(_links != null){
1075 for(Link link : _links){
1076 if(link != null){
1077 link.validate(format);
1078 }
1079 }
1080 }
1081
1082 }
1083
1084 }