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.io.impl;
18  
19  import com.sun.syndication.feed.WireFeed;
20  import com.sun.syndication.feed.atom.*;
21  import com.sun.syndication.io.FeedException;
22  import org.jdom.Document;
23  import org.jdom.Element;
24  import org.jdom.Namespace;
25  import org.jdom.output.XMLOutputter;
26  
27  import java.util.*;
28  
29  /***
30   */
31  public class Atom03Parser extends BaseWireFeedParser {
32      private static final String ATOM_03_URI = "http://purl.org/atom/ns#";
33      private static final Namespace ATOM_03_NS = Namespace.getNamespace(ATOM_03_URI);
34  
35      public Atom03Parser() {
36          this("atom_0.3", ATOM_03_NS);
37      }
38  
39      protected Atom03Parser(String type, Namespace ns) {
40          super(type, ns);
41      }
42  
43      protected Namespace getAtomNamespace() {
44          return ATOM_03_NS;
45      }
46  
47      public boolean isMyType(Document document) {
48          Element rssRoot = document.getRootElement();
49          Namespace defaultNS = rssRoot.getNamespace();
50          return (defaultNS!=null) && defaultNS.equals(getAtomNamespace());
51      }
52  
53      public WireFeed parse(Document document, boolean validate) throws IllegalArgumentException,FeedException {
54          if (validate) {
55              validateFeed(document);
56          }
57          Element rssRoot = document.getRootElement();
58          return parseFeed(rssRoot);
59      }
60  
61      protected void validateFeed(Document document) throws FeedException {
62          // TBD
63          // here we have to validate the Feed against a schema or whatever
64          // not sure how to do it
65          // one posibility would be to produce an ouput and attempt to parse it again
66          // with validation turned on.
67          // otherwise will have to check the document elements by hand.
68      }
69  
70      protected WireFeed parseFeed(Element eFeed) {
71  
72          com.sun.syndication.feed.atom.Feed feed = new com.sun.syndication.feed.atom.Feed(getType());
73  
74          Element e = eFeed.getChild("title",getAtomNamespace());
75          if (e!=null) {
76              feed.setTitleEx(parseContent(e));
77          }
78  
79          List eList = eFeed.getChildren("link",getAtomNamespace());
80          feed.setAlternateLinks(parseAlternateLinks(eList));
81          feed.setOtherLinks(parseOtherLinks(eList));
82  
83          e = eFeed.getChild("author",getAtomNamespace());
84          if (e!=null) {
85              List authors = new ArrayList();
86              authors.add(parsePerson(e));
87              feed.setAuthors(authors);
88          }
89  
90          eList = eFeed.getChildren("contributor",getAtomNamespace());
91          if (eList.size()>0) {
92              feed.setContributors(parsePersons(eList));
93          }
94  
95          e = eFeed.getChild("tagline",getAtomNamespace());
96          if (e!=null) {
97              feed.setTagline(parseContent(e));
98          }
99  
100         e = eFeed.getChild("id",getAtomNamespace());
101         if (e!=null) {
102             feed.setId(e.getText());
103         }
104 
105         e = eFeed.getChild("generator",getAtomNamespace());
106         if (e!=null) {
107             Generator gen = new Generator();
108             gen.setValue(e.getText());
109             String att = getAttributeValue(e, "url");
110             if (att!=null) {
111                 gen.setUrl(att);
112             }
113             att = getAttributeValue(e, "version");
114             if (att!=null) {
115                 gen.setVersion(att);
116             }
117             feed.setGenerator(gen);
118         }
119 
120         e = eFeed.getChild("copyright",getAtomNamespace());
121         if (e!=null) {
122             feed.setCopyright(e.getText());
123         }
124 
125         e = eFeed.getChild("info",getAtomNamespace());
126         if (e!=null) {
127             feed.setInfo(parseContent(e));
128         }
129 
130         e = eFeed.getChild("modified",getAtomNamespace());
131         if (e!=null) {
132             feed.setModified(DateParser.parseDate(e.getText()));
133         }
134 
135         feed.setModules(parseFeedModules(eFeed));
136         
137         eList = eFeed.getChildren("entry",getAtomNamespace());
138         if (eList.size()>0) {
139             feed.setEntries(parseEntries(eList));
140         }
141 
142         List foreignMarkup = 
143             extractForeignMarkup(eFeed, feed, getAtomNamespace());
144         if (foreignMarkup.size() > 0) {
145             feed.setForeignMarkup(foreignMarkup);
146         } 
147         return feed;
148     }
149 
150     private Link parseLink(Element eLink) {
151         Link link = new Link();
152         String att = getAttributeValue(eLink, "rel");
153         if (att!=null) {
154             link.setRel(att);
155         }
156         att = getAttributeValue(eLink, "type");
157         if (att!=null) {
158             link.setType(att);
159         }
160         att = getAttributeValue(eLink, "href");
161         if (att!=null) {
162             link.setHref(att);
163         }
164         return link;
165     }
166 
167     // List(Elements) -> List(Link)
168     private List parseLinks(List eLinks,boolean alternate) {
169         List links = new ArrayList();
170         for (int i=0;i<eLinks.size();i++) {
171             Element eLink = (Element) eLinks.get(i);
172             String rel = getAttributeValue(eLink, "rel");
173             if (alternate) {
174                 if ("alternate".equals(rel)) {
175                     links.add(parseLink(eLink));
176                 }
177             }
178             else {
179                 if (!("alternate".equals(rel))) {
180                     links.add(parseLink(eLink));
181                 }
182             }
183         }
184         return (links.size()>0) ? links : null;
185     }
186 
187     // List(Elements) -> List(Link)
188     private List parseAlternateLinks(List eLinks) {
189         return parseLinks(eLinks,true);
190     }
191 
192     // List(Elements) -> List(Link)
193     private List parseOtherLinks(List eLinks) {
194         return parseLinks(eLinks,false);
195     }
196 
197     private Person parsePerson(Element ePerson) {
198         Person person = new Person();
199         Element e = ePerson.getChild("name",getAtomNamespace());
200         if (e!=null) {
201             person.setName(e.getText());
202         }
203         e = ePerson.getChild("url",getAtomNamespace());
204         if (e!=null) {
205             person.setUrl(e.getText());
206         }
207         e = ePerson.getChild("email",getAtomNamespace());
208         if (e!=null) {
209             person.setEmail(e.getText());
210         }
211         return person;
212     }
213 
214     // List(Elements) -> List(Persons)
215     private List parsePersons(List ePersons) {
216         List persons = new ArrayList();
217         for (int i=0;i<ePersons.size();i++) {
218             persons.add(parsePerson((Element)ePersons.get(i)));
219         }
220         return (persons.size()>0) ? persons : null;
221     }
222 
223     private Content parseContent(Element e) {
224         String value = null;
225         String type = getAttributeValue(e, "type");
226         type = (type!=null) ? type : "text/plain";
227         String mode = getAttributeValue(e, "mode");
228         if (mode == null) {
229             mode = Content.XML; // default to xml content
230         }
231         if (mode.equals(Content.ESCAPED)) {
232             // do nothing XML Parser took care of this
233             value = e.getText();
234         }
235         else
236         if (mode.equals(Content.BASE64)) {
237                 value = Base64.decode(e.getText());
238         }
239         else
240         if (mode.equals(Content.XML)) {
241             XMLOutputter outputter = new XMLOutputter();
242             List eContent = e.getContent();
243             Iterator i = eContent.iterator();
244             while (i.hasNext()) {
245                 org.jdom.Content c = (org.jdom.Content) i.next();
246                 if (c instanceof Element) {
247                     Element eC = (Element) c;
248                     if (eC.getNamespace().equals(getAtomNamespace())) {
249                         ((Element)c).setNamespace(Namespace.NO_NAMESPACE);
250                     }
251                 }
252             }
253             value = outputter.outputString(eContent);
254         }
255 
256         Content content = new Content();
257         content.setType(type);
258         content.setMode(mode);
259         content.setValue(value);
260         return content;
261     }
262 
263     // List(Elements) -> List(Entries)
264     private List parseEntries(List eEntries) {
265         List entries = new ArrayList();
266         for (int i=0;i<eEntries.size();i++) {
267             entries.add(parseEntry((Element)eEntries.get(i)));
268         }
269         return (entries.size()>0) ? entries : null;
270     }
271 
272     private Entry parseEntry(Element eEntry) {
273         Entry entry = new Entry();
274 
275         Element e = eEntry.getChild("title",getAtomNamespace());
276         if (e!=null) {
277             entry.setTitleEx(parseContent(e));
278         }
279 
280         List eList = eEntry.getChildren("link",getAtomNamespace());
281         entry.setAlternateLinks(parseAlternateLinks(eList));
282         entry.setOtherLinks(parseOtherLinks(eList));
283 
284         e = eEntry.getChild("author",getAtomNamespace());
285         if (e!=null) {
286             List authors = new ArrayList();
287             authors.add(parsePerson(e));
288             entry.setAuthors(authors);
289         }
290 
291         eList = eEntry.getChildren("contributor",getAtomNamespace());
292         if (eList.size()>0) {
293             entry.setContributors(parsePersons(eList));
294         }
295 
296         e = eEntry.getChild("id",getAtomNamespace());
297         if (e!=null) {
298             entry.setId(e.getText());
299         }
300 
301         e = eEntry.getChild("modified",getAtomNamespace());
302         if (e!=null) {
303             entry.setModified(DateParser.parseDate(e.getText()));
304         }
305 
306         e = eEntry.getChild("issued",getAtomNamespace());
307         if (e!=null) {
308             entry.setIssued(DateParser.parseDate(e.getText()));
309         }
310 
311         e = eEntry.getChild("created",getAtomNamespace());
312         if (e!=null) {
313             entry.setCreated(DateParser.parseDate(e.getText()));
314         }
315 
316         e = eEntry.getChild("summary",getAtomNamespace());
317         if (e!=null) {
318             entry.setSummary(parseContent(e));
319         }
320 
321         eList = eEntry.getChildren("content",getAtomNamespace());
322         if (eList.size()>0) {
323             List content = new ArrayList();
324             for (int i=0;i<eList.size();i++) {
325                 content.add(parseContent((Element)eList.get(i)));
326             }
327             entry.setContents(content);
328         }
329 
330         entry.setModules(parseItemModules(eEntry));
331 
332         List foreignMarkup = 
333             extractForeignMarkup(eEntry, entry, getAtomNamespace());
334         if (foreignMarkup.size() > 0) {
335             entry.setForeignMarkup(foreignMarkup);
336         } 
337         return entry;
338     }
339 
340 
341 }