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  
34      public Atom03Parser() {
35          this("atom_0.3");
36      }
37  
38      protected Atom03Parser(String type) {
39          super(type);
40      }
41  
42      protected Namespace getAtomNamespace() {
43          return Namespace.getNamespace(ATOM_03_URI);
44      }
45  
46      public boolean isMyType(Document document) {
47          Element rssRoot = document.getRootElement();
48          Namespace defaultNS = rssRoot.getNamespace();
49          return (defaultNS!=null) && defaultNS.equals(getAtomNamespace());
50      }
51  
52      public WireFeed parse(Document document, boolean validate) throws IllegalArgumentException,FeedException {
53          if (validate) {
54              validateFeed(document);
55          }
56          Element rssRoot = document.getRootElement();
57          return parseFeed(rssRoot);
58      }
59  
60      protected void validateFeed(Document document) throws FeedException {
61          // TBD
62          // here we have to validate the Feed against a schema or whatever
63          // not sure how to do it
64          // one posibility would be to produce an ouput and attempt to parse it again
65          // with validation turned on.
66          // otherwise will have to check the document elements by hand.
67      }
68  
69      protected WireFeed parseFeed(Element eFeed) {
70  
71          com.sun.syndication.feed.atom.Feed feed = new com.sun.syndication.feed.atom.Feed(getType());
72  
73          Element e = eFeed.getChild("title",getAtomNamespace());
74          if (e!=null) {
75              feed.setTitle(e.getText());
76          }
77  
78          List eList = eFeed.getChildren("link",getAtomNamespace());
79          feed.setAlternateLinks(parseAlternateLinks(eList));
80          feed.setOtherLinks(parseOtherLinks(eList));
81  
82          e = eFeed.getChild("author",getAtomNamespace());
83          if (e!=null) {
84              List authors = new ArrayList();
85              authors.add(parsePerson(e));
86              feed.setAuthors(authors);
87          }
88  
89          eList = eFeed.getChildren("contributor",getAtomNamespace());
90          if (eList.size()>0) {
91              feed.setContributors(parsePersons(eList));
92          }
93  
94          e = eFeed.getChild("tagline",getAtomNamespace());
95          if (e!=null) {
96              feed.setTagline(parseContent(e));
97          }
98  
99          e = eFeed.getChild("id",getAtomNamespace());
100         if (e!=null) {
101             feed.setId(e.getText());
102         }
103 
104         e = eFeed.getChild("generator",getAtomNamespace());
105         if (e!=null) {
106             Generator gen = new Generator();
107             gen.setValue(e.getText());
108             String att = e.getAttributeValue("url");//getAtomNamespace()); DONT KNOW WHY DOESN'T WORK
109             if (att!=null) {
110                 gen.setUrl(att);
111             }
112             att = e.getAttributeValue("version");//getAtomNamespace()); DONT KNOW WHY DOESN'T WORK
113             if (att!=null) {
114                 gen.setVersion(att);
115             }
116             feed.setGenerator(gen);
117         }
118 
119         e = eFeed.getChild("copyright",getAtomNamespace());
120         if (e!=null) {
121             feed.setCopyright(e.getText());
122         }
123 
124         e = eFeed.getChild("info",getAtomNamespace());
125         if (e!=null) {
126             feed.setInfo(parseContent(e));
127         }
128 
129         e = eFeed.getChild("modified",getAtomNamespace());
130         if (e!=null) {
131             feed.setModified(DateParser.parseDate(e.getText()));
132         }
133 
134         feed.setModules(parseFeedModules(eFeed));
135         
136         eList = eFeed.getChildren("entry",getAtomNamespace());
137         if (eList.size()>0) {
138             feed.setEntries(parseEntries(eList));
139         }
140 
141         List foreignMarkup = 
142             extractForeignMarkup(eFeed, feed, getAtomNamespace());
143         if (foreignMarkup.size() > 0) {
144             feed.setForeignMarkup(foreignMarkup);
145         } 
146         return feed;
147     }
148 
149     private Link parseLink(Element eLink) {
150         Link link = new Link();
151         String att = eLink.getAttributeValue("rel");//getAtomNamespace()); DONT KNOW WHY DOESN'T WORK
152         if (att!=null) {
153             link.setRel(att);
154         }
155         att = eLink.getAttributeValue("type");//getAtomNamespace()); DONT KNOW WHY DOESN'T WORK
156         if (att!=null) {
157             link.setType(att);
158         }
159         att = eLink.getAttributeValue("href");//getAtomNamespace()); DONT KNOW WHY DOESN'T WORK
160         if (att!=null) {
161             link.setHref(att);
162         }
163         return link;
164     }
165 
166     // List(Elements) -> List(Link)
167     private List parseLinks(List eLinks,boolean alternate) {
168         List links = new ArrayList();
169         for (int i=0;i<eLinks.size();i++) {
170             Element eLink = (Element) eLinks.get(i);
171             //Namespace ns = getAtomNamespace();
172             String rel = eLink.getAttributeValue("rel");//getAtomNamespace()); DONT KNOW WHY DOESN'T WORK
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 = e.getAttributeValue("type");//getAtomNamespace()); DONT KNOW WHY DOESN'T WORK
226         type = (type!=null) ? type : "text/plain";
227         String mode = e.getAttributeValue("mode");//getAtomNamespace())); DONT KNOW WHY DOESN'T WORK
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.setTitle(e.getText());
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 }