1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 package com.sun.syndication.feed.synd;
18
19 import com.sun.syndication.feed.impl.ObjectBean;
20 import com.sun.syndication.feed.module.*;
21 import com.sun.syndication.feed.module.impl.ModuleUtils;
22 import com.sun.syndication.feed.synd.impl.URINormalizer;
23 import com.sun.syndication.feed.impl.CopyFromHelper;
24
25 import java.util.*;
26 import java.io.Serializable;
27
28 /***
29 * Bean for entries of SyndFeedImpl feeds.
30 * <p>
31 * @author Alejandro Abdelnur
32 *
33 */
34 public class SyndEntryImpl implements Serializable,SyndEntry {
35 private ObjectBean _objBean;
36 private String _uri;
37 private String _link;
38 private Date _updatedDate;
39 private SyndContent _title;
40 private SyndContent _description;
41 private List _links;
42 private List _contents;
43 private List _modules;
44 private List _enclosures;
45 private List _authors;
46 private List _contributors;
47 private SyndFeed _source;
48 private List _foreignMarkup;
49
50
51 private List _categories = new ArrayList();
52
53 private static final Set IGNORE_PROPERTIES = new HashSet();
54
55 /***
56 * Unmodifiable Set containing the convenience properties of this class.
57 * <p>
58 * Convenience properties are mapped to Modules, for cloning the convenience properties
59 * can be ignored as the will be copied as part of the module cloning.
60 */
61 public static final Set CONVENIENCE_PROPERTIES = Collections.unmodifiableSet(IGNORE_PROPERTIES);
62
63 static {
64 IGNORE_PROPERTIES.add("publishedDate");
65 IGNORE_PROPERTIES.add("author");
66 }
67
68 /***
69 * For implementations extending SyndEntryImpl to be able to use the ObjectBean functionality
70 * with extended interfaces.
71 * <p>
72 * @param beanClass
73 * @param convenienceProperties set containing the convenience properties of the SyndEntryImpl
74 * (the are ignored during cloning, check CloneableBean for details).
75 *
76 */
77 protected SyndEntryImpl(Class beanClass,Set convenienceProperties) {
78 _objBean = new ObjectBean(beanClass,this,convenienceProperties);
79 }
80
81 /***
82 * Default constructor. All properties are set to <b>null</b>.
83 * <p>
84 *
85 */
86 public SyndEntryImpl() {
87 this(SyndEntry.class,IGNORE_PROPERTIES);
88 }
89
90 /***
91 * Creates a deep 'bean' clone of the object.
92 * <p>
93 * @return a clone of the object.
94 * @throws CloneNotSupportedException thrown if an element of the object cannot be cloned.
95 *
96 */
97 public Object clone() throws CloneNotSupportedException {
98 return _objBean.clone();
99 }
100
101 /***
102 * Indicates whether some other object is "equal to" this one as defined by the Object equals() method.
103 * <p>
104 * @param other he reference object with which to compare.
105 * @return <b>true</b> if 'this' object is equal to the 'other' object.
106 *
107 */
108 public boolean equals(Object other) {
109 if (other == null) {
110 return false;
111 }
112
113
114 if (!(other instanceof SyndEntryImpl)) {
115 return false;
116 }
117
118 Object fm = getForeignMarkup();
119 setForeignMarkup(((SyndEntryImpl)other).getForeignMarkup());
120 boolean ret = _objBean.equals(other);
121
122 setForeignMarkup(fm);
123 return ret;
124 }
125
126 /***
127 * Returns a hashcode value for the object.
128 * <p>
129 * It follows the contract defined by the Object hashCode() method.
130 * <p>
131 * @return the hashcode of the bean object.
132 *
133 */
134 public int hashCode() {
135 return _objBean.hashCode();
136 }
137
138 /***
139 * Returns the String representation for the object.
140 * <p>
141 * @return String representation for the object.
142 *
143 */
144 public String toString() {
145 return _objBean.toString();
146 }
147
148
149 /***
150 * Returns the entry URI.
151 * <p>
152 * How the entry URI maps to a concrete feed type (RSS or Atom) depends on
153 * the concrete feed type. This is explained in detail in Rome documentation,
154 * <a href="http://wiki.java.net/bin/edit/Javawsxml/Rome04URIMapping">Feed and entry URI mapping</a>.
155 * <p>
156 * The returned URI is a normalized URI as specified in RFC 2396bis.
157 * <p>
158 * @return the entry URI, <b>null</b> if none.
159 *
160 */
161 public String getUri() {
162 return _uri;
163 }
164
165 /***
166 * Sets the entry URI.
167 * <p>
168 * How the entry URI maps to a concrete feed type (RSS or Atom) depends on
169 * the concrete feed type. This is explained in detail in Rome documentation,
170 * <a href="http://wiki.java.net/bin/edit/Javawsxml/Rome04URIMapping">Feed and entry URI mapping</a>.
171 * <p>
172 * @param uri the entry URI to set, <b>null</b> if none.
173 *
174 */
175 public void setUri(String uri) {
176 _uri = URINormalizer.normalize(uri);
177 }
178
179 /***
180 * Returns the entry title.
181 * <p>
182 * @return the entry title, <b>null</b> if none.
183 *
184 */
185 public String getTitle() {
186 if (_title != null) return _title.getValue();
187 return null;
188 }
189
190 /***
191 * Sets the entry title.
192 * <p>
193 * @param title the entry title to set, <b>null</b> if none.
194 *
195 */
196 public void setTitle(String title) {
197 if (_title == null) _title = new SyndContentImpl();
198 _title.setValue(title);
199 }
200
201 /***
202 * Returns the entry title as a text construct.
203 * <p>
204 * @return the entry title, <b>null</b> if none.
205 *
206 */
207 public SyndContent getTitleEx() {
208 return _title;
209 }
210
211 /***
212 * Sets the entry title as a text construct.
213 * <p>
214 * @param title the entry title to set, <b>null</b> if none.
215 *
216 */
217 public void setTitleEx(SyndContent title) {
218 _title = title;
219 }
220
221 /***
222 * Returns the entry link.
223 * <p>
224 * @return the entry link, <b>null</b> if none.
225 *
226 */
227 public String getLink() {
228 return _link;
229 }
230
231 /***
232 * Sets the entry link.
233 * <p>
234 * @param link the entry link to set, <b>null</b> if none.
235 *
236 */
237 public void setLink(String link) {
238 _link = link;
239 }
240
241 /***
242 * Returns the entry description.
243 * <p>
244 * @return the entry description, <b>null</b> if none.
245 *
246 */
247 public SyndContent getDescription() {
248 return _description;
249 }
250
251 /***
252 * Sets the entry description.
253 * <p>
254 * @param description the entry description to set, <b>null</b> if none.
255 *
256 */
257 public void setDescription(SyndContent description) {
258 _description = description;
259 }
260
261 /***
262 * Returns the entry contents.
263 * <p>
264 * @return a list of SyndContentImpl elements with the entry contents,
265 * an empty list if none.
266 *
267 */
268 public List getContents() {
269 return (_contents==null) ? (_contents=new ArrayList()) : _contents;
270 }
271
272 /***
273 * Sets the entry contents.
274 * <p>
275 * @param contents the list of SyndContentImpl elements with the entry contents to set,
276 * an empty list or <b>null</b> if none.
277 *
278 */
279 public void setContents(List contents) {
280 _contents = contents;
281 }
282
283 /***
284 * Returns the entry enclosures.
285 * <p>
286 * @return a list of SyndEnclosure elements with the entry enclosures,
287 * an empty list if none.
288 *
289 */
290 public List getEnclosures() {
291 return (_enclosures==null) ? (_enclosures=new ArrayList()) : _enclosures;
292 }
293
294 /***
295 * Sets the entry enclosures.
296 * <p>
297 * @param enclosures the list of SyndEnclosure elements with the entry enclosures to set,
298 * an empty list or <b>null</b> if none.
299 *
300 */
301 public void setEnclosures(List enclosures) {
302 _enclosures = enclosures;
303 }
304
305
306 /***
307 * Returns the entry published date.
308 * <p>
309 * This method is a convenience method, it maps to the Dublin Core module date.
310 * <p>
311 * @return the entry published date, <b>null</b> if none.
312 *
313 */
314 public Date getPublishedDate() {
315 return getDCModule().getDate();
316 }
317
318 /***
319 * Sets the entry published date.
320 * <p>
321 * This method is a convenience method, it maps to the Dublin Core module date.
322 * <p>
323 * @param publishedDate the entry published date to set, <b>null</b> if none.
324 *
325 */
326 public void setPublishedDate(Date publishedDate) {
327 getDCModule().setDate(publishedDate);
328 }
329
330 /***
331 * Returns the entry categories.
332 * <p>
333 * @return a list of SyndCategoryImpl elements with the entry categories,
334 * an empty list if none.
335 *
336 */
337 public List getCategories() {
338 return _categories;
339 }
340
341 /***
342 * Sets the entry categories.
343 * <p>
344 * This method is a convenience method, it maps to the Dublin Core module subjects.
345 * <p>
346 * @param categories the list of SyndCategoryImpl elements with the entry categories to set,
347 * an empty list or <b>null</b> if none.
348 *
349 */
350 public void setCategories(List categories) {
351 _categories = categories;
352 }
353
354 /***
355 * Returns the entry modules.
356 * <p>
357 * @return a list of ModuleImpl elements with the entry modules,
358 * an empty list if none.
359 *
360 */
361 public List getModules() {
362 if (_modules==null) {
363 _modules=new ArrayList();
364 }
365 if (ModuleUtils.getModule(_modules,DCModule.URI)==null) {
366 _modules.add(new DCModuleImpl());
367 }
368 return _modules;
369 }
370
371 /***
372 * Sets the entry modules.
373 * <p>
374 * @param modules the list of ModuleImpl elements with the entry modules to set,
375 * an empty list or <b>null</b> if none.
376 *
377 */
378 public void setModules(List modules) {
379 _modules = modules;
380 }
381
382 /***
383 * Returns the module identified by a given URI.
384 * <p>
385 * @param uri the URI of the ModuleImpl.
386 * @return The module with the given URI, <b>null</b> if none.
387 */
388 public Module getModule(String uri) {
389 return ModuleUtils.getModule(getModules(),uri);
390 }
391
392 /***
393 * Returns the Dublin Core module of the feed.
394 * @return the DC module, it's never <b>null</b>
395 *
396 */
397 private DCModule getDCModule() {
398 return (DCModule) getModule(DCModule.URI);
399 }
400
401 public Class getInterface() {
402 return SyndEntry.class;
403 }
404
405 public void copyFrom(Object obj) {
406 COPY_FROM_HELPER.copy(this,obj);
407 }
408
409 private static final CopyFromHelper COPY_FROM_HELPER;
410
411 static {
412 Map basePropInterfaceMap = new HashMap();
413 basePropInterfaceMap.put("uri",String.class);
414 basePropInterfaceMap.put("title",String.class);
415 basePropInterfaceMap.put("link",String.class);
416 basePropInterfaceMap.put("uri",String.class);
417 basePropInterfaceMap.put("description",SyndContent.class);
418 basePropInterfaceMap.put("contents",SyndContent.class);
419 basePropInterfaceMap.put("enclosures",SyndEnclosure.class);
420 basePropInterfaceMap.put("modules",Module.class);
421
422 Map basePropClassImplMap = new HashMap();
423 basePropClassImplMap.put(SyndContent.class,SyndContentImpl.class);
424 basePropClassImplMap.put(SyndEnclosure.class,SyndEnclosureImpl.class);
425 basePropClassImplMap.put(DCModule.class,DCModuleImpl.class);
426 basePropClassImplMap.put(SyModule.class,SyModuleImpl.class);
427
428 COPY_FROM_HELPER = new CopyFromHelper(SyndEntry.class,basePropInterfaceMap,basePropClassImplMap);
429 }
430
431 /***
432 * Returns the links
433 * <p>
434 * @return Returns the links.
435 */
436 public List getLinks() {
437 return (_links==null) ? (_links=new ArrayList()) : _links;
438 }
439
440 /***
441 * Set the links
442 * <p>
443 * @param links The links to set.
444 */
445 public void setLinks(List links) {
446 _links = links;
447 }
448
449 /***
450 * Returns the updatedDate
451 * <p>
452 * @return Returns the updatedDate.
453 */
454 public Date getUpdatedDate() {
455 return _updatedDate;
456 }
457
458 /***
459 * Set the updatedDate
460 * <p>
461 * @param updatedDate The updatedDate to set.
462 */
463 public void setUpdatedDate(Date updatedDate) {
464 _updatedDate = updatedDate;
465 }
466
467 public List getAuthors() {
468 return _authors;
469 }
470
471
472
473
474 public void setAuthors(List authors) {
475 _authors = authors;
476 }
477
478 /***
479 * Returns the entry author.
480 * <p>
481 * This method is a convenience method, it maps to the Dublin Core module creator.
482 * <p>
483 * @return the entry author, <b>null</b> if none.
484 *
485 */
486 public String getAuthor() {
487 String author;
488
489
490
491 if ((_authors != null) && (_authors.size() > 0)) {
492 author = ((SyndPerson)_authors.get(0)).getName();
493 } else {
494 author = getDCModule().getCreator();
495 }
496 if (author == null) {
497 author = "";
498 }
499
500 return author;
501 }
502
503 /***
504 * Sets the entry author.
505 * <p>
506 * This method is a convenience method, it maps to the Dublin Core module creator.
507 * <p>
508 * @param author the entry author to set, <b>null</b> if none.
509 *
510 */
511 public void setAuthor(String author) {
512
513
514 DCModule dcModule = getDCModule();
515 String currentValue = dcModule.getCreator();
516
517 if ((currentValue == null) || (currentValue.length() == 0)) {
518 getDCModule().setCreator(author);
519 }
520 }
521
522 public List getContributors() {
523 return _contributors;
524 }
525
526
527
528
529 public void setContributors(List contributors) {
530 _contributors = contributors;
531 }
532
533 public SyndFeed getSource() {
534 return _source;
535 }
536
537 public void setSource(SyndFeed source) {
538 _source = source;
539 }
540
541 /***
542 * Returns foreign markup found at channel level.
543 * <p>
544 * @return list of JDOM nodes containing channel-level foreign markup,
545 * an empty list if none.
546 *
547 */
548 public Object getForeignMarkup() {
549 return (_foreignMarkup==null) ? (_foreignMarkup=new ArrayList()) : _foreignMarkup;
550 }
551
552 /***
553 * Sets foreign markup found at channel level.
554 * <p>
555 * @param foreignMarkup list of JDOM nodes containing channel-level foreign markup,
556 * an empty list if none.
557 *
558 */
559 public void setForeignMarkup(Object foreignMarkup) {
560 _foreignMarkup = (List)foreignMarkup;
561 }
562 }