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