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