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_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_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              feed.setAuthor(parsePerson(e));
85          }
86  
87          eList = eFeed.getChildren("contributor",getAtomNamespace());
88          if (eList.size()>0) {
89              feed.setContributors(parsePersons(eList));
90          }
91  
92          e = eFeed.getChild("tagline",getAtomNamespace());
93          if (e!=null) {
94              feed.setTagline(parseContent(e));
95          }
96  
97          e = eFeed.getChild("id",getAtomNamespace());
98          if (e!=null) {
99              feed.setId(e.getText());
100         }
101 
102         e = eFeed.getChild("generator",getAtomNamespace());
103         if (e!=null) {
104             Generator gen = new Generator();
105             gen.setValue(e.getText());
106             String att = e.getAttributeValue("url");//getAtomNamespace()); DONT KNOW WHY DOESN'T WORK
107             if (att!=null) {
108                 gen.setUrl(att);
109             }
110             att = e.getAttributeValue("version");//getAtomNamespace()); DONT KNOW WHY DOESN'T WORK
111             if (att!=null) {
112                 gen.setVersion(att);
113             }
114             feed.setGenerator(gen);
115         }
116 
117         e = eFeed.getChild("copyright",getAtomNamespace());
118         if (e!=null) {
119             feed.setCopyright(e.getText());
120         }
121 
122         e = eFeed.getChild("info",getAtomNamespace());
123         if (e!=null) {
124             feed.setInfo(parseContent(e));
125         }
126 
127         e = eFeed.getChild("modified",getAtomNamespace());
128         if (e!=null) {
129             feed.setModified(DateParser.parseW3CDateTime(e.getText()));
130         }
131 
132         eList = eFeed.getChildren("entry",getAtomNamespace());
133         if (eList.size()>0) {
134             feed.setEntries(parseEntries(eList));
135         }
136 
137         feed.setModules(parseFeedModules(eFeed));
138 
139         return feed;
140     }
141 
142     private static final Map RELS = new HashMap();
143 
144     static {
145         RELS.put(Link.ALTERNATE.toString(),Link.ALTERNATE);
146         RELS.put(Link.START.toString(),Link.START);
147         RELS.put(Link.NEXT.toString(),Link.NEXT);
148         RELS.put(Link.PREV.toString(),Link.PREV);
149         RELS.put(Link.SERVICE_EDIT.toString(),Link.SERVICE_EDIT);
150         RELS.put(Link.SERVICE_POST.toString(),Link.SERVICE_POST);
151         RELS.put(Link.SERVICE_FEED.toString(),Link.SERVICE_FEED);
152     }
153 
154     private Link parseLink(Element eLink) {
155         Link link = new Link();
156         String att = eLink.getAttributeValue("rel");//getAtomNamespace()); DONT KNOW WHY DOESN'T WORK
157         if (att!=null) {
158             link.setRel((Link.Rel) RELS.get(att));
159         }
160         att = eLink.getAttributeValue("type");//getAtomNamespace()); DONT KNOW WHY DOESN'T WORK
161         if (att!=null) {
162             link.setType(att);
163         }
164         att = eLink.getAttributeValue("href");//getAtomNamespace()); DONT KNOW WHY DOESN'T WORK
165         if (att!=null) {
166             link.setHref(att);
167         }
168         return link;
169     }
170 
171     // List(Elements) -> List(Link)
172     private List parseLinks(List eLinks,boolean alternate) {
173         List links = new ArrayList();
174         for (int i=0;i<eLinks.size();i++) {
175             Element eLink = (Element) eLinks.get(i);
176             //Namespace ns = getAtomNamespace();
177             String rel = eLink.getAttributeValue("rel");//getAtomNamespace()); DONT KNOW WHY DOESN'T WORK
178             if (alternate) {
179                 if ("alternate".equals(rel)) {
180                     links.add(parseLink(eLink));
181                 }
182             }
183             else {
184                 if (!("alternate".equals(rel))) {
185                     links.add(parseLink(eLink));
186                 }
187             }
188         }
189         return (links.size()>0) ? links : null;
190     }
191 
192     // List(Elements) -> List(Link)
193     private List parseAlternateLinks(List eLinks) {
194         return parseLinks(eLinks,true);
195     }
196 
197     // List(Elements) -> List(Link)
198     private List parseOtherLinks(List eLinks) {
199         return parseLinks(eLinks,false);
200     }
201 
202     private Person parsePerson(Element ePerson) {
203         Person person = new Person();
204         Element e = ePerson.getChild("name",getAtomNamespace());
205         if (e!=null) {
206             person.setName(e.getText());
207         }
208         e = ePerson.getChild("url",getAtomNamespace());
209         if (e!=null) {
210             person.setUrl(e.getText());
211         }
212         e = ePerson.getChild("email",getAtomNamespace());
213         if (e!=null) {
214             person.setEmail(e.getText());
215         }
216         return person;
217     }
218 
219     // List(Elements) -> List(Persons)
220     private List parsePersons(List ePersons) {
221         List persons = new ArrayList();
222         for (int i=0;i<ePersons.size();i++) {
223             persons.add(parsePerson((Element)ePersons.get(i)));
224         }
225         return (persons.size()>0) ? persons : null;
226     }
227 
228     private static final Map MODES = new HashMap();
229 
230     static {
231         MODES.put(Content.XML.toString(),Content.XML);
232         MODES.put(Content.ESCAPED.toString(),Content.ESCAPED);
233         MODES.put(Content.BASE64.toString(),Content.BASE64);
234         MODES.put(null,Content.XML);
235     }
236 
237     private Content parseContent(Element e) {
238         String value = null;
239         String type = e.getAttributeValue("type");//getAtomNamespace()); DONT KNOW WHY DOESN'T WORK
240         type = (type!=null) ? type : "text/plain";
241         Content.Mode mode = (Content.Mode)MODES.get(e.getAttributeValue("mode"));//getAtomNamespace())); DONT KNOW WHY DOESN'T WORK
242         if (mode.equals(Content.ESCAPED)) {
243             // do nothing XML Parser took care of this
244             value = e.getText();
245         }
246         else
247         if (mode.equals(Content.BASE64)) {
248                 value = Base64.decode(e.getText());
249         }
250         else
251         if (mode.equals(Content.XML)) {
252             XMLOutputter outputter = new XMLOutputter();
253             List eContent = e.getContent();
254             Iterator i = eContent.iterator();
255             while (i.hasNext()) {
256                 org.jdom.Content c = (org.jdom.Content) i.next();
257                 if (c instanceof Element) {
258                     Element eC = (Element) c;
259                     if (eC.getNamespace().equals(getAtomNamespace())) {
260                         ((Element)c).setNamespace(Namespace.NO_NAMESPACE);
261                     }
262                 }
263             }
264             value = outputter.outputString(eContent);
265         }
266 
267         Content content = new Content();
268         content.setType(type);
269         content.setMode(mode);
270         content.setValue(value);
271         return content;
272     }
273 
274     // List(Elements) -> List(Entries)
275     private List parseEntries(List eEntries) {
276         List entries = new ArrayList();
277         for (int i=0;i<eEntries.size();i++) {
278             entries.add(parseEntry((Element)eEntries.get(i)));
279         }
280         return (entries.size()>0) ? entries : null;
281     }
282 
283     private Entry parseEntry(Element eEntry) {
284         Entry entry = new Entry();
285 
286         Element e = eEntry.getChild("title",getAtomNamespace());
287         if (e!=null) {
288             entry.setTitle(e.getText());
289         }
290 
291         List eList = eEntry.getChildren("link",getAtomNamespace());
292         entry.setAlternateLinks(parseAlternateLinks(eList));
293         entry.setOtherLinks(parseOtherLinks(eList));
294 
295         e = eEntry.getChild("author",getAtomNamespace());
296         if (e!=null) {
297             entry.setAuthor(parsePerson(e));
298         }
299 
300         eList = eEntry.getChildren("contributor",getAtomNamespace());
301         if (eList.size()>0) {
302             entry.setContributors(parsePersons(eList));
303         }
304 
305         e = eEntry.getChild("id",getAtomNamespace());
306         if (e!=null) {
307             entry.setId(e.getText());
308         }
309 
310         e = eEntry.getChild("modified",getAtomNamespace());
311         if (e!=null) {
312             entry.setModified(DateParser.parseW3CDateTime(e.getText()));
313         }
314 
315         e = eEntry.getChild("issued",getAtomNamespace());
316         if (e!=null) {
317             entry.setIssued(DateParser.parseW3CDateTime(e.getText()));
318         }
319 
320         e = eEntry.getChild("summary",getAtomNamespace());
321         if (e!=null) {
322             entry.setSummary(parseContent(e));
323         }
324 
325         eList = eEntry.getChildren("content",getAtomNamespace());
326         if (eList.size()>0) {
327             List content = new ArrayList();
328             for (int i=0;i<eList.size();i++) {
329                 content.add(parseContent((Element)eList.get(i)));
330             }
331             entry.setContents(content);
332         }
333 
334         entry.setModules(parseItemModules(eEntry));
335 
336         return entry;
337     }
338 
339 
340 }