001: /*
002: JSPWiki - a JSP-based WikiWiki clone.
003:
004: Copyright (C) 2001-2007 Janne Jalkanen (Janne.Jalkanen@iki.fi)
005:
006: This program is free software; you can redistribute it and/or modify
007: it under the terms of the GNU Lesser General Public License as published by
008: the Free Software Foundation; either version 2.1 of the License, or
009: (at your option) any later version.
010:
011: This program is distributed in the hope that it will be useful,
012: but WITHOUT ANY WARRANTY; without even the implied warranty of
013: MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
014: GNU Lesser General Public License for more details.
015:
016: You should have received a copy of the GNU Lesser General Public License
017: along with this program; if not, write to the Free Software
018: Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
019: */
020: package com.ecyrd.jspwiki.rss;
021:
022: import java.io.IOException;
023: import java.io.StringWriter;
024: import java.util.ArrayList;
025: import java.util.Collection;
026: import java.util.Date;
027: import java.util.Iterator;
028:
029: import javax.servlet.ServletContext;
030:
031: import org.apache.commons.lang.time.DateFormatUtils;
032: import org.jdom.Element;
033: import org.jdom.Namespace;
034: import org.jdom.output.Format;
035: import org.jdom.output.XMLOutputter;
036:
037: import com.ecyrd.jspwiki.Release;
038: import com.ecyrd.jspwiki.WikiContext;
039: import com.ecyrd.jspwiki.WikiEngine;
040: import com.ecyrd.jspwiki.WikiPage;
041: import com.ecyrd.jspwiki.attachment.Attachment;
042: import com.ecyrd.jspwiki.providers.ProviderException;
043:
044: /**
045: * Provides an Atom 1.0 standard feed, with enclosures.
046: *
047: * @author jalkanen
048: *
049: */
050: public class AtomFeed extends Feed {
051: private Namespace m_atomNameSpace = Namespace
052: .getNamespace("http://www.w3.org/2005/Atom");
053:
054: public static final String RFC3339FORMAT = "yyyy-MM-dd'T'HH:mm:ssZZ";
055:
056: public AtomFeed(WikiContext c) {
057: super (c);
058: }
059:
060: /**
061: * This is a bit complicated right now, as there is no proper metadata
062: * store in JSPWiki.
063: *
064: * @return
065: */
066: private String getFeedID() {
067: return m_wikiContext.getEngine().getBaseURL(); // FIXME: This is not a feed id
068: }
069:
070: private String getEntryID(Entry e) {
071: return e.getURL(); // FIXME: Not really a feed id!
072: }
073:
074: private Collection getItems() {
075: ArrayList list = new ArrayList();
076:
077: WikiEngine engine = m_wikiContext.getEngine();
078: ServletContext servletContext = null;
079:
080: if (m_wikiContext.getHttpRequest() != null)
081: servletContext = m_wikiContext.getHttpRequest()
082: .getSession().getServletContext();
083:
084: for (Iterator i = m_entries.iterator(); i.hasNext();) {
085: Entry e = (Entry) i.next();
086:
087: WikiPage p = e.getPage();
088:
089: Element entryEl = getElement("entry");
090:
091: //
092: // Mandatory elements
093: //
094:
095: entryEl.addContent(getElement("id").setText(getEntryID(e)));
096: entryEl.addContent(getElement("title").setAttribute("type",
097: "html").setText(e.getTitle()));
098: entryEl.addContent(getElement("updated").setText(
099: DateFormatUtils.formatUTC(p.getLastModified(),
100: RFC3339FORMAT)));
101: //
102: // Optional elements
103: //
104:
105: entryEl.addContent(getElement("author").addContent(
106: getElement("name").setText(e.getAuthor())));
107: entryEl.addContent(getElement("link").setAttribute("rel",
108: "alternate").setAttribute("href", e.getURL()));
109: entryEl.addContent(getElement("content").setAttribute(
110: "type", "html").setText(e.getContent()));
111:
112: //
113: // Check for enclosures
114: //
115:
116: if (engine.getAttachmentManager().hasAttachments(p)
117: && servletContext != null) {
118: try {
119: Collection c = engine.getAttachmentManager()
120: .listAttachments(p);
121:
122: for (Iterator a = c.iterator(); a.hasNext();) {
123: Attachment att = (Attachment) a.next();
124:
125: Element attEl = getElement("link");
126: attEl.setAttribute("rel", "enclosure");
127: attEl.setAttribute("href", engine.getURL(
128: WikiContext.ATTACH, att.getName(),
129: null, true));
130: attEl.setAttribute("length", Long.toString(att
131: .getSize()));
132: attEl.setAttribute("type", getMimeType(
133: servletContext, att.getFileName()));
134:
135: entryEl.addContent(attEl);
136: }
137: } catch (ProviderException ex) {
138: // FIXME: log.info("Can't get attachment data",ex);
139: }
140: }
141:
142: list.add(entryEl);
143: }
144:
145: return list;
146: }
147:
148: public String getString() {
149: Element root = getElement("feed");
150: WikiEngine engine = m_wikiContext.getEngine();
151:
152: Date lastModified = new Date(0L);
153:
154: for (Iterator i = m_entries.iterator(); i.hasNext();) {
155: Entry e = (Entry) i.next();
156:
157: if (e.getPage().getLastModified().after(lastModified))
158: lastModified = e.getPage().getLastModified();
159: }
160:
161: //
162: // Mandatory parts
163: //
164: root.addContent(getElement("title").setText(getChannelTitle()));
165: root.addContent(getElement("id").setText(getFeedID()));
166: root
167: .addContent(getElement("updated").setText(
168: DateFormatUtils.formatUTC(lastModified,
169: RFC3339FORMAT)));
170:
171: //
172: // Optional
173: //
174: // root.addContent( getElement("author").addContent(getElement("name").setText(format())))
175: root.addContent(getElement("link").setAttribute("href",
176: engine.getBaseURL()));
177: root.addContent(getElement("generator").setText(
178: "JSPWiki " + Release.VERSTR));
179:
180: String rssFeedURL = engine.getURL(WikiContext.NONE, "rss.jsp",
181: "page="
182: + engine.encodeName(m_wikiContext.getPage()
183: .getName()) + "&mode=" + m_mode
184: + "&type=atom", true);
185: Element self = getElement("link").setAttribute("rel", "self");
186: self.setAttribute("href", rssFeedURL);
187: root.addContent(self);
188:
189: //
190: // Items
191: //
192:
193: root.addContent(getItems());
194:
195: //
196: // aaand output
197: //
198: XMLOutputter output = new XMLOutputter();
199:
200: output.setFormat(Format.getPrettyFormat());
201:
202: try {
203: StringWriter res = new StringWriter();
204: output.output(root, res);
205:
206: return res.toString();
207: } catch (IOException e) {
208: return null;
209: }
210: }
211:
212: private final Element getElement(String name) {
213: return new Element(name, m_atomNameSpace);
214: }
215: }
|