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