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.impl;
18  
19  import java.util.ArrayList;
20  import java.util.Date;
21  import java.util.Iterator;
22  import java.util.List;
23  
24  import com.sun.syndication.feed.WireFeed;
25  import com.sun.syndication.feed.atom.Category;
26  import com.sun.syndication.feed.atom.Content;
27  import com.sun.syndication.feed.atom.Entry;
28  import com.sun.syndication.feed.atom.Feed;
29  import com.sun.syndication.feed.atom.Link;
30  import com.sun.syndication.feed.atom.Person;
31  import com.sun.syndication.feed.module.impl.ModuleUtils;
32  import com.sun.syndication.feed.synd.Converter;
33  import com.sun.syndication.feed.synd.SyndCategory;
34  import com.sun.syndication.feed.synd.SyndCategoryImpl;
35  import com.sun.syndication.feed.synd.SyndContent;
36  import com.sun.syndication.feed.synd.SyndContentImpl;
37  import com.sun.syndication.feed.synd.SyndEntry;
38  import com.sun.syndication.feed.synd.SyndEntryImpl;
39  import com.sun.syndication.feed.synd.SyndFeed;
40  import com.sun.syndication.feed.synd.SyndFeedImpl;
41  import com.sun.syndication.feed.synd.SyndLink;
42  import com.sun.syndication.feed.synd.SyndLinkImpl;
43  import com.sun.syndication.feed.synd.SyndPerson;
44  import com.sun.syndication.feed.synd.SyndEnclosure;
45  import com.sun.syndication.feed.synd.SyndEnclosureImpl;
46  
47  
48  /***
49   */
50  public class ConverterForAtom10 implements Converter {
51      private String _type;
52  
53      public ConverterForAtom10() {
54          this("atom_1.0");
55      }
56  
57      protected ConverterForAtom10(String type) {
58          _type = type;
59      }
60  
61      public String getType() {
62          return _type;
63      }
64  
65      public void copyInto(WireFeed feed, SyndFeed syndFeed) {
66          Feed aFeed = (Feed) feed;
67  
68          syndFeed.setModules(ModuleUtils.cloneModules(aFeed.getModules()));
69          
70          if (((List)feed.getForeignMarkup()).size() > 0) {
71              syndFeed.setForeignMarkup((List)feed.getForeignMarkup());
72          }
73  
74          syndFeed.setEncoding(aFeed.getEncoding());
75  
76          syndFeed.setUri(aFeed.getId());
77  
78          Content aTitle = aFeed.getTitleEx();
79          if (aTitle != null) {
80              SyndContent c = new SyndContentImpl();
81              c.setType(aTitle.getType());
82              c.setValue(aTitle.getValue());
83              syndFeed.setTitleEx(c);
84          }
85  
86          Content aSubtitle = aFeed.getSubtitle();
87          if (aSubtitle!=null) {
88              SyndContent c = new SyndContentImpl();
89              c.setType(aSubtitle.getType());
90              c.setValue(aSubtitle.getValue());
91              syndFeed.setDescriptionEx(c);
92          }
93  
94          // use first alternate links as THE link
95          if (aFeed.getAlternateLinks() != null 
96                  && aFeed.getAlternateLinks().size() > 0) {
97              Link theLink = (Link)aFeed.getAlternateLinks().get(0);
98              syndFeed.setLink(theLink.getHrefResolved());
99          }
100         // lump alternate and other links together
101         List syndLinks = new ArrayList();
102         if (aFeed.getAlternateLinks() != null 
103                 && aFeed.getAlternateLinks().size() > 0) {
104             syndLinks.addAll(createSyndLinks(aFeed.getAlternateLinks()));
105         }
106         if (aFeed.getOtherLinks() != null 
107                 && aFeed.getOtherLinks().size() > 0) {
108             syndLinks.addAll(createSyndLinks(aFeed.getOtherLinks()));
109         }
110         syndFeed.setLinks(syndLinks);
111             
112         List aEntries = aFeed.getEntries();
113         if (aEntries!=null) {
114             syndFeed.setEntries(createSyndEntries(aFeed, aEntries));
115         }
116 
117         // Core Atom language/author/copyright/modified elements have precedence
118         // over DC equivalent info.
119 
120         List authors = aFeed.getAuthors();
121         if (authors!=null && authors.size() > 0) {
122             syndFeed.setAuthors(ConverterForAtom03.createSyndPersons(authors));
123         }
124 
125         String rights = aFeed.getRights();
126         if (rights!=null) {
127             syndFeed.setCopyright(rights);
128         }
129 
130         Date date = aFeed.getUpdated();
131         if (date!=null) {
132             syndFeed.setPublishedDate(date);
133         }
134         
135     }
136 
137     protected List createSyndLinks(List aLinks) {
138         ArrayList sLinks = new ArrayList();
139         for (Iterator iter = aLinks.iterator(); iter.hasNext();) {
140             Link link = (Link)iter.next();
141             SyndLink sLink = createSyndLink(link);
142             sLinks.add(sLink);
143         }
144         return sLinks;
145     }
146     
147     protected List createSyndEntries(Feed feed, List atomEntries) {
148         List syndEntries = new ArrayList();
149         for (int i=0;i<atomEntries.size();i++) {
150             syndEntries.add(createSyndEntry(feed, (Entry) atomEntries.get(i)));
151         }
152         return syndEntries;
153     }
154 
155     protected SyndEntry createSyndEntry(Feed feed, Entry entry) {
156         SyndEntry syndEntry = new SyndEntryImpl();
157         syndEntry.setModules(ModuleUtils.cloneModules(entry.getModules()));
158         
159         if (((List)entry.getForeignMarkup()).size() >  0) {
160             syndEntry.setForeignMarkup((List)entry.getForeignMarkup());
161         }
162 
163         Content eTitle = entry.getTitleEx();
164         if (eTitle != null) {
165             syndEntry.setTitleEx(createSyndContent(eTitle));
166         }
167         
168         Content summary = entry.getSummary();
169         if (summary!=null) {
170             syndEntry.setDescription(createSyndContent(summary));
171         }
172 
173         List contents = entry.getContents();
174         if (contents != null && contents.size() > 0) {
175             List sContents = new ArrayList();
176             for (Iterator iter=contents.iterator(); iter.hasNext();) {
177                 Content content = (Content)iter.next();
178                 sContents.add(createSyndContent(content));
179             }
180             syndEntry.setContents(sContents);
181         }
182 
183         List authors = entry.getAuthors();
184         if (authors!=null && authors.size() > 0) {
185             syndEntry.setAuthors(ConverterForAtom03.createSyndPersons(authors));
186             SyndPerson person0 = (SyndPerson)syndEntry.getAuthors().get(0);
187             syndEntry.setAuthor(person0.getName());
188         }
189 
190         Date date = entry.getPublished();
191         if (date!=null) {
192             syndEntry.setPublishedDate(date);
193         }
194 
195         date = entry.getUpdated();
196         if (date!=null) {
197             syndEntry.setUpdatedDate(date);
198         }
199         
200         List categories = entry.getCategories();
201         if (categories!=null) {
202             List syndCategories = new ArrayList();
203             for (Iterator iter=categories.iterator(); iter.hasNext();) {
204                 Category c = (Category)iter.next();
205                 SyndCategory syndCategory = new SyndCategoryImpl();
206                 syndCategory.setName(c.getTerm()); 
207                 syndCategory.setTaxonomyUri(c.getSchemeResolved());
208                 // TODO: categories MAY have labels 
209                 //       syndCategory.setLabel(c.getLabel());
210                 syndCategories.add(syndCategory);
211             }
212             syndEntry.setCategories(syndCategories);
213         }
214                 
215         // use first alternate link as THE link
216         if (entry.getAlternateLinks() != null
217 				&& entry.getAlternateLinks().size() > 0) {
218             Link theLink = (Link)entry.getAlternateLinks().get(0);
219             syndEntry.setLink(theLink.getHrefResolved());
220         }
221 
222         // Create synd enclosures from enclosure links
223         List syndEnclosures = new ArrayList();
224         if (entry.getOtherLinks() != null && entry.getOtherLinks().size() > 0) {
225             List oLinks = entry.getOtherLinks();
226             for (Iterator iter = oLinks.iterator(); iter.hasNext(); ) {
227                 Link thisLink = (Link)iter.next();
228                 if ("enclosure".equals(thisLink.getRel()))
229                     syndEnclosures.add(
230                             createSyndEnclosure(feed, entry, thisLink));
231             }
232         }
233         syndEntry.setEnclosures(syndEnclosures);
234 
235         // lump alternate and other links together
236         List syndLinks = new ArrayList();
237         if (entry.getAlternateLinks() != null 
238                 && entry.getAlternateLinks().size() > 0) {
239             syndLinks.addAll(createSyndLinks(entry.getAlternateLinks()));
240         }
241         if (entry.getOtherLinks() != null 
242                 && entry.getOtherLinks().size() > 0) {
243             syndLinks.addAll(createSyndLinks(entry.getOtherLinks()));
244         }
245         syndEntry.setLinks(syndLinks);
246 
247         String id = entry.getId();
248         if (id!=null) {
249             syndEntry.setUri(entry.getId());
250         }
251         else {
252             syndEntry.setUri(syndEntry.getLink());
253         }
254 
255         // Convert source element Feed into SyndFeed and assign as SyndEntry
256         // source
257         Feed source = entry.getSource();
258         if (source != null) {
259         	SyndFeed syndSource = new SyndFeedImpl(source);
260         	syndEntry.setSource(syndSource);
261         }
262 
263         return syndEntry;
264     }
265 
266     public SyndEnclosure createSyndEnclosure(Feed feed, Entry entry,
267             Link link) {
268         SyndEnclosure syndEncl = new SyndEnclosureImpl();
269         syndEncl.setUrl(link.getHrefResolved());
270         syndEncl.setType(link.getType());
271         syndEncl.setLength(link.getLength());
272         return syndEncl;
273     }
274     
275     public Link createAtomEnclosure(SyndEnclosure syndEnclosure) {
276       Link link = new Link();
277       link.setRel(     "enclosure");
278       link.setType(    syndEnclosure.getType());
279       link.setHref(    syndEnclosure.getUrl());
280       link.setLength(  syndEnclosure.getLength());
281       return link;
282     }
283 
284     public SyndLink createSyndLink(Link link) {
285         SyndLink syndLink = new SyndLinkImpl(); 
286         syndLink.setRel(     link.getRel());
287         syndLink.setType(    link.getType());
288         syndLink.setHref(    link.getHrefResolved());
289         syndLink.setHreflang(link.getHreflang());
290         syndLink.setLength(  link.getLength());
291         syndLink.setTitle(   link.getTitle());
292         return syndLink;
293     }
294     
295     public Link createAtomLink(SyndLink syndLink) {
296         Link link = new Link(); 
297         link.setRel(     syndLink.getRel());
298         link.setType(    syndLink.getType());
299         link.setHref(    syndLink.getHref());
300         link.setHreflang(syndLink.getHreflang());
301         link.setLength(  syndLink.getLength());
302         link.setTitle(   syndLink.getTitle());
303         return link;
304     }
305     
306     public WireFeed createRealFeed(SyndFeed syndFeed) {
307         Feed aFeed = new Feed(getType());
308         aFeed.setModules(ModuleUtils.cloneModules(syndFeed.getModules()));
309 
310         aFeed.setEncoding(syndFeed.getEncoding());
311 
312         aFeed.setId(syndFeed.getUri());
313 
314         SyndContent sTitle = syndFeed.getTitleEx();
315         if (sTitle != null) {
316             Content title = new Content();
317             title.setType(sTitle.getType());
318             title.setValue(sTitle.getValue());
319             aFeed.setTitleEx(title);
320         }
321         
322         SyndContent sDesc = syndFeed.getDescriptionEx();
323         if (sDesc != null) {
324             Content subtitle = new Content();
325             subtitle.setType(sDesc.getType());
326             subtitle.setValue(sDesc.getValue());
327             aFeed.setSubtitle(subtitle);
328         }
329 
330         // separate SyndEntry's links collection into alternate and other links
331         List alternateLinks = new ArrayList();
332         List otherLinks = new ArrayList();
333         List slinks = syndFeed.getLinks();
334         if (slinks != null) {
335             for (Iterator iter=slinks.iterator(); iter.hasNext();) {       
336                 SyndLink syndLink = (SyndLink)iter.next();                
337                 Link link = createAtomLink(syndLink);              
338                 if (link.getRel() == null ||
339                         "".equals(link.getRel().trim()) ||
340                         "alternate".equals(link.getRel())) {
341                     alternateLinks.add(link);
342                 } else {
343                     otherLinks.add(link);
344                 }
345             }
346         }
347         // no alternate link? then use THE link if there is one
348         if (alternateLinks.size() == 0 && syndFeed.getLink() != null) {
349             Link link = new Link();
350             link.setRel("alternate");
351             link.setHref(syndFeed.getLink());
352             alternateLinks.add(link);
353         }
354         if (alternateLinks.size() > 0) aFeed.setAlternateLinks(alternateLinks);
355         if (otherLinks.size() > 0) aFeed.setOtherLinks(otherLinks);
356         
357         List sCats = syndFeed.getCategories();
358         List aCats = new ArrayList();
359         if (sCats != null) {
360             for (Iterator iter=sCats.iterator(); iter.hasNext();) { 
361                 SyndCategory sCat = (SyndCategory)iter.next();
362                 Category aCat = new Category();
363                 aCat.setTerm(sCat.getName());
364                 // TODO: aCat.setLabel(sCat.getLabel());
365                 aCat.setScheme(sCat.getTaxonomyUri());
366                 aCats.add(aCat);
367             }
368         }
369         if (aCats.size() > 0) aFeed.setCategories(aCats);
370 
371         List authors = syndFeed.getAuthors();
372         if (authors!=null && authors.size() > 0) {
373             aFeed.setAuthors(ConverterForAtom03.createAtomPersons(authors));
374         }
375 
376         aFeed.setRights(syndFeed.getCopyright());
377 
378         aFeed.setUpdated(syndFeed.getPublishedDate());
379 
380         List sEntries = syndFeed.getEntries();
381         if (sEntries!=null) {
382             aFeed.setEntries(createAtomEntries(sEntries));
383         }
384 
385         if (((List)syndFeed.getForeignMarkup()).size() > 0) {
386             aFeed.setForeignMarkup(syndFeed.getForeignMarkup());
387         }
388         return aFeed;
389     }
390 
391     protected SyndContent createSyndContent(Content content) {
392         SyndContent sContent = new SyndContentImpl();
393         sContent.setType(content.getType());
394         sContent.setValue(content.getValue());
395         return sContent;
396     }
397 
398     protected List createAtomEntries(List syndEntries) {
399         List atomEntries = new ArrayList();
400         for (int i=0;i<syndEntries.size();i++) {
401             atomEntries.add(createAtomEntry((SyndEntry)syndEntries.get(i)));
402         }
403         return atomEntries;
404     }
405 
406     protected Content createAtomContent(SyndContent sContent) {
407         Content content = new Content();
408         content.setType(sContent.getType());
409         content.setValue(sContent.getValue());
410         return content;
411     }
412 
413     protected List createAtomContents(List syndContents) {
414         List atomContents = new ArrayList();
415         for (int i=0;i<syndContents.size();i++) {
416             atomContents.add(createAtomContent((SyndContent)syndContents.get(i)));
417         }
418         return atomContents;
419     }
420 
421     protected Entry createAtomEntry(SyndEntry sEntry) {
422         Entry aEntry = new Entry();
423         aEntry.setModules(ModuleUtils.cloneModules(sEntry.getModules()));
424 
425         aEntry.setId(sEntry.getUri());
426 
427         SyndContent sTitle = sEntry.getTitleEx();
428         if (sTitle!=null) {
429             Content title = new Content();
430             title.setType(sTitle.getType());
431             title.setValue(sTitle.getValue());
432             aEntry.setTitleEx(title);
433         }
434         
435         SyndContent sDescription = sEntry.getDescription();
436         if (sDescription!=null) {
437             Content summary = new Content();
438             summary.setType(sDescription.getType());
439             summary.setValue(sDescription.getValue());
440             aEntry.setSummary(summary);
441         }
442 
443         // separate SyndEntry's links collection into alternate and other links
444         List alternateLinks = new ArrayList();
445         List otherLinks = new ArrayList();
446         List slinks = sEntry.getLinks();
447         List enclosures = sEntry.getEnclosures();
448         boolean linkRelEnclosureExists = false;
449         if (slinks != null) {
450             for (Iterator iter=slinks.iterator(); iter.hasNext();) {       
451                 SyndLink syndLink = (SyndLink)iter.next();                
452                 Link link = createAtomLink(syndLink);
453                 // Set this flag if there's a link of rel = enclosure so that
454                 // enclosures won't be duplicated when pulled from
455                 // SyndEntry.getEnclosures()
456                 if (syndLink.getRel() != null &&
457                         "enclosure".equals(syndLink.getRel())) {
458                     linkRelEnclosureExists = true;
459                 }
460                 if (link.getRel() == null ||
461                         "".equals(link.getRel().trim()) ||
462                         "alternate".equals(syndLink.getRel())) {
463                     alternateLinks.add(link);
464                 } else {
465                     otherLinks.add(link);
466                 }
467             }
468         }
469         // no alternate link? then use THE link if there is one
470         if (alternateLinks.size() == 0 && sEntry.getLink() != null) {
471             Link link = new Link();
472             link.setRel("alternate");
473             link.setHref(sEntry.getLink());
474             alternateLinks.add(link);
475         }
476         // add SyndEnclosures as links with rel="enclosure" ONLY if
477         // there are no SyndEntry.getLinks() with rel="enclosure"
478         if (enclosures != null && linkRelEnclosureExists == false) {
479             for (Iterator iter=enclosures.iterator(); iter.hasNext();) {
480                 SyndEnclosure syndEncl = (SyndEnclosure)iter.next();
481                 Link link = createAtomEnclosure(syndEncl);
482                 otherLinks.add(link);
483             }
484         }
485         if (alternateLinks.size() > 0) aEntry.setAlternateLinks(alternateLinks);
486         if (otherLinks.size() > 0) aEntry.setOtherLinks(otherLinks);
487        
488         List sCats = sEntry.getCategories();
489         List aCats = new ArrayList();
490         if (sCats != null) {
491             for (Iterator iter=sCats.iterator(); iter.hasNext();) { 
492                 SyndCategory sCat = (SyndCategory)iter.next();
493                 Category aCat = new Category();
494                 aCat.setTerm(sCat.getName());
495                 // TODO: aCat.setLabel(sCat.getLabel());
496                 aCat.setScheme(sCat.getTaxonomyUri());
497                 aCats.add(aCat);
498             }
499         }
500         if (aCats.size() > 0) aEntry.setCategories(aCats);
501         
502         List syndContents = sEntry.getContents();
503         aEntry.setContents(createAtomContents(syndContents));
504 
505         List authors = sEntry.getAuthors();
506         if (authors!=null && authors.size() > 0) {
507             aEntry.setAuthors(ConverterForAtom03.createAtomPersons(authors));
508         } else if (sEntry.getAuthor() != null) {
509             Person person = new Person();
510             person.setName(sEntry.getAuthor()); 
511             authors = new ArrayList();
512             authors.add(person);
513             aEntry.setAuthors(authors);
514         }
515 
516         aEntry.setPublished(sEntry.getPublishedDate());
517 
518         // Fix for issue #41 "Use updated instead of published"
519         // And issue #42 "Atom 1.0 Date (Updated or Published) Not Set"
520         // Atom requires an updated date, if it's missing use the published date
521         if (sEntry.getUpdatedDate() != null) {
522             aEntry.setUpdated(sEntry.getUpdatedDate());         
523         } else {
524             aEntry.setUpdated(sEntry.getPublishedDate());
525         }
526 
527         if (((List)sEntry.getForeignMarkup()).size() > 0) {
528             aEntry.setForeignMarkup((List)sEntry.getForeignMarkup());
529         }
530         
531         SyndFeed sSource = sEntry.getSource();
532         if (sSource != null) {
533         	Feed aSource = (Feed) sSource.createWireFeed(getType());
534         	aEntry.setSource(aSource);
535         }
536         return aEntry;
537     }
538 
539 }