View Javadoc

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