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