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