001: /*
002: * Copyright 2004 Sun Microsystems, Inc.
003: *
004: * Licensed under the Apache License, Version 2.0 (the "License");
005: * you may not use this file except in compliance with the License.
006: * You may obtain a copy of the License at
007: *
008: * http://www.apache.org/licenses/LICENSE-2.0
009: *
010: * Unless required by applicable law or agreed to in writing, software
011: * distributed under the License is distributed on an "AS IS" BASIS,
012: * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
013: * See the License for the specific language governing permissions and
014: * limitations under the License.
015: *
016: */
017: package com.sun.syndication.io.impl;
018:
019: import com.sun.syndication.feed.WireFeed;
020: import com.sun.syndication.feed.atom.*;
021: import com.sun.syndication.io.FeedException;
022: import org.jdom.Document;
023: import org.jdom.Element;
024: import org.jdom.Namespace;
025: import org.jdom.output.XMLOutputter;
026:
027: import java.util.*;
028:
029: /**
030: */
031: public class Atom03Parser extends BaseWireFeedParser {
032: private static final String ATOM_03_URI = "http://purl.org/atom/ns#";
033:
034: public Atom03Parser() {
035: this ("atom_0.3");
036: }
037:
038: protected Atom03Parser(String type) {
039: super (type);
040: }
041:
042: protected Namespace getAtomNamespace() {
043: return Namespace.getNamespace(ATOM_03_URI);
044: }
045:
046: public boolean isMyType(Document document) {
047: Element rssRoot = document.getRootElement();
048: Namespace defaultNS = rssRoot.getNamespace();
049: return (defaultNS != null)
050: && defaultNS.equals(getAtomNamespace());
051: }
052:
053: public WireFeed parse(Document document, boolean validate)
054: throws IllegalArgumentException, FeedException {
055: if (validate) {
056: validateFeed(document);
057: }
058: Element rssRoot = document.getRootElement();
059: return parseFeed(rssRoot);
060: }
061:
062: protected void validateFeed(Document document) throws FeedException {
063: // TBD
064: // here we have to validate the Feed against a schema or whatever
065: // not sure how to do it
066: // one posibility would be to produce an ouput and attempt to parse it again
067: // with validation turned on.
068: // otherwise will have to check the document elements by hand.
069: }
070:
071: protected WireFeed parseFeed(Element eFeed) {
072:
073: com.sun.syndication.feed.atom.Feed feed = new com.sun.syndication.feed.atom.Feed(
074: getType());
075:
076: Element e = eFeed.getChild("title", getAtomNamespace());
077: if (e != null) {
078: feed.setTitle(e.getText());
079: }
080:
081: List eList = eFeed.getChildren("link", getAtomNamespace());
082: feed.setAlternateLinks(parseAlternateLinks(eList));
083: feed.setOtherLinks(parseOtherLinks(eList));
084:
085: e = eFeed.getChild("author", getAtomNamespace());
086: if (e != null) {
087: List authors = new ArrayList();
088: authors.add(parsePerson(e));
089: feed.setAuthors(authors);
090: }
091:
092: eList = eFeed.getChildren("contributor", getAtomNamespace());
093: if (eList.size() > 0) {
094: feed.setContributors(parsePersons(eList));
095: }
096:
097: e = eFeed.getChild("tagline", getAtomNamespace());
098: if (e != null) {
099: feed.setTagline(parseContent(e));
100: }
101:
102: e = eFeed.getChild("id", getAtomNamespace());
103: if (e != null) {
104: feed.setId(e.getText());
105: }
106:
107: e = eFeed.getChild("generator", getAtomNamespace());
108: if (e != null) {
109: Generator gen = new Generator();
110: gen.setValue(e.getText());
111: String att = e.getAttributeValue("url");//getAtomNamespace()); DONT KNOW WHY DOESN'T WORK
112: if (att != null) {
113: gen.setUrl(att);
114: }
115: att = e.getAttributeValue("version");//getAtomNamespace()); DONT KNOW WHY DOESN'T WORK
116: if (att != null) {
117: gen.setVersion(att);
118: }
119: feed.setGenerator(gen);
120: }
121:
122: e = eFeed.getChild("copyright", getAtomNamespace());
123: if (e != null) {
124: feed.setCopyright(e.getText());
125: }
126:
127: e = eFeed.getChild("info", getAtomNamespace());
128: if (e != null) {
129: feed.setInfo(parseContent(e));
130: }
131:
132: e = eFeed.getChild("modified", getAtomNamespace());
133: if (e != null) {
134: feed.setModified(DateParser.parseDate(e.getText()));
135: }
136:
137: feed.setModules(parseFeedModules(eFeed));
138:
139: eList = eFeed.getChildren("entry", getAtomNamespace());
140: if (eList.size() > 0) {
141: feed.setEntries(parseEntries(eList));
142: }
143:
144: List foreignMarkup = extractForeignMarkup(eFeed, feed,
145: getAtomNamespace());
146: if (foreignMarkup.size() > 0) {
147: feed.setForeignMarkup(foreignMarkup);
148: }
149: return feed;
150: }
151:
152: private Link parseLink(Element eLink) {
153: Link link = new Link();
154: String att = eLink.getAttributeValue("rel");//getAtomNamespace()); DONT KNOW WHY DOESN'T WORK
155: if (att != null) {
156: link.setRel(att);
157: }
158: att = eLink.getAttributeValue("type");//getAtomNamespace()); DONT KNOW WHY DOESN'T WORK
159: if (att != null) {
160: link.setType(att);
161: }
162: att = eLink.getAttributeValue("href");//getAtomNamespace()); DONT KNOW WHY DOESN'T WORK
163: if (att != null) {
164: link.setHref(att);
165: }
166: return link;
167: }
168:
169: // List(Elements) -> List(Link)
170: private List parseLinks(List eLinks, boolean alternate) {
171: List links = new ArrayList();
172: for (int i = 0; i < eLinks.size(); i++) {
173: Element eLink = (Element) eLinks.get(i);
174: //Namespace ns = getAtomNamespace();
175: String rel = eLink.getAttributeValue("rel");//getAtomNamespace()); DONT KNOW WHY DOESN'T WORK
176: if (alternate) {
177: if ("alternate".equals(rel)) {
178: links.add(parseLink(eLink));
179: }
180: } else {
181: if (!("alternate".equals(rel))) {
182: links.add(parseLink(eLink));
183: }
184: }
185: }
186: return (links.size() > 0) ? links : null;
187: }
188:
189: // List(Elements) -> List(Link)
190: private List parseAlternateLinks(List eLinks) {
191: return parseLinks(eLinks, true);
192: }
193:
194: // List(Elements) -> List(Link)
195: private List parseOtherLinks(List eLinks) {
196: return parseLinks(eLinks, false);
197: }
198:
199: private Person parsePerson(Element ePerson) {
200: Person person = new Person();
201: Element e = ePerson.getChild("name", getAtomNamespace());
202: if (e != null) {
203: person.setName(e.getText());
204: }
205: e = ePerson.getChild("url", getAtomNamespace());
206: if (e != null) {
207: person.setUrl(e.getText());
208: }
209: e = ePerson.getChild("email", getAtomNamespace());
210: if (e != null) {
211: person.setEmail(e.getText());
212: }
213: return person;
214: }
215:
216: // List(Elements) -> List(Persons)
217: private List parsePersons(List ePersons) {
218: List persons = new ArrayList();
219: for (int i = 0; i < ePersons.size(); i++) {
220: persons.add(parsePerson((Element) ePersons.get(i)));
221: }
222: return (persons.size() > 0) ? persons : null;
223: }
224:
225: private Content parseContent(Element e) {
226: String value = null;
227: String type = e.getAttributeValue("type");//getAtomNamespace()); DONT KNOW WHY DOESN'T WORK
228: type = (type != null) ? type : "text/plain";
229: String mode = e.getAttributeValue("mode");//getAtomNamespace())); DONT KNOW WHY DOESN'T WORK
230: if (mode == null) {
231: mode = Content.XML; // default to xml content
232: }
233: if (mode.equals(Content.ESCAPED)) {
234: // do nothing XML Parser took care of this
235: value = e.getText();
236: } else if (mode.equals(Content.BASE64)) {
237: value = Base64.decode(e.getText());
238: } else if (mode.equals(Content.XML)) {
239: XMLOutputter outputter = new XMLOutputter();
240: List eContent = e.getContent();
241: Iterator i = eContent.iterator();
242: while (i.hasNext()) {
243: org.jdom.Content c = (org.jdom.Content) i.next();
244: if (c instanceof Element) {
245: Element eC = (Element) c;
246: if (eC.getNamespace().equals(getAtomNamespace())) {
247: ((Element) c)
248: .setNamespace(Namespace.NO_NAMESPACE);
249: }
250: }
251: }
252: value = outputter.outputString(eContent);
253: }
254:
255: Content content = new Content();
256: content.setType(type);
257: content.setMode(mode);
258: content.setValue(value);
259: return content;
260: }
261:
262: // List(Elements) -> List(Entries)
263: private List parseEntries(List eEntries) {
264: List entries = new ArrayList();
265: for (int i = 0; i < eEntries.size(); i++) {
266: entries.add(parseEntry((Element) eEntries.get(i)));
267: }
268: return (entries.size() > 0) ? entries : null;
269: }
270:
271: private Entry parseEntry(Element eEntry) {
272: Entry entry = new Entry();
273:
274: Element e = eEntry.getChild("title", getAtomNamespace());
275: if (e != null) {
276: entry.setTitle(e.getText());
277: }
278:
279: List eList = eEntry.getChildren("link", getAtomNamespace());
280: entry.setAlternateLinks(parseAlternateLinks(eList));
281: entry.setOtherLinks(parseOtherLinks(eList));
282:
283: e = eEntry.getChild("author", getAtomNamespace());
284: if (e != null) {
285: List authors = new ArrayList();
286: authors.add(parsePerson(e));
287: entry.setAuthors(authors);
288: }
289:
290: eList = eEntry.getChildren("contributor", getAtomNamespace());
291: if (eList.size() > 0) {
292: entry.setContributors(parsePersons(eList));
293: }
294:
295: e = eEntry.getChild("id", getAtomNamespace());
296: if (e != null) {
297: entry.setId(e.getText());
298: }
299:
300: e = eEntry.getChild("modified", getAtomNamespace());
301: if (e != null) {
302: entry.setModified(DateParser.parseDate(e.getText()));
303: }
304:
305: e = eEntry.getChild("issued", getAtomNamespace());
306: if (e != null) {
307: entry.setIssued(DateParser.parseDate(e.getText()));
308: }
309:
310: e = eEntry.getChild("created", getAtomNamespace());
311: if (e != null) {
312: entry.setCreated(DateParser.parseDate(e.getText()));
313: }
314:
315: e = eEntry.getChild("summary", getAtomNamespace());
316: if (e != null) {
317: entry.setSummary(parseContent(e));
318: }
319:
320: eList = eEntry.getChildren("content", getAtomNamespace());
321: if (eList.size() > 0) {
322: List content = new ArrayList();
323: for (int i = 0; i < eList.size(); i++) {
324: content.add(parseContent((Element) eList.get(i)));
325: }
326: entry.setContents(content);
327: }
328:
329: entry.setModules(parseItemModules(eEntry));
330:
331: List foreignMarkup = extractForeignMarkup(eEntry, entry,
332: getAtomNamespace());
333: if (foreignMarkup.size() > 0) {
334: entry.setForeignMarkup(foreignMarkup);
335: }
336: return entry;
337: }
338:
339: }
|