001: /*
002: JSPWiki - a JSP-based WikiWiki clone.
003:
004: Copyright (C) 2001-2004 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.xmlrpc;
021:
022: import java.io.*;
023: import com.ecyrd.jspwiki.*;
024: import com.ecyrd.jspwiki.attachment.Attachment;
025: import com.ecyrd.jspwiki.attachment.AttachmentManager;
026: import com.ecyrd.jspwiki.plugin.WeblogEntryPlugin;
027: import com.ecyrd.jspwiki.plugin.WeblogPlugin;
028: import com.ecyrd.jspwiki.providers.ProviderException;
029: import java.util.*;
030:
031: import org.apache.log4j.Logger;
032: import org.apache.xmlrpc.XmlRpcException;
033:
034: /**
035: * Provides handlers for all RPC routines of the MetaWeblog API.
036: * <P>
037: * JSPWiki does not support categories, and therefore we always return
038: * an empty list for getCategories(). Note also that this API is not
039: * suitable for general Wiki editing, since JSPWiki formats the entries
040: * in a wiki-compatible manner. And you cannot choose your page names
041: * either. Since 2.1.94 the entire MetaWeblog API is supported.
042: *
043: * @author Janne Jalkanen
044: * @since 2.1.7
045: */
046:
047: public class MetaWeblogHandler implements WikiRPCHandler {
048: Logger log = Logger.getLogger(MetaWeblogHandler.class);
049:
050: private WikiEngine m_engine;
051:
052: public void initialize(WikiContext context) {
053: m_engine = context.getEngine();
054: }
055:
056: /**
057: * Does a quick check against the current user
058: * and does he have permissions to do the stuff
059: * that he really wants to.
060: * <p>
061: * If there is no authentication enabled, returns normally.
062: *
063: * @throw XmlRpcException with the correct error message, if auth fails.
064: */
065: private void checkPermissions(WikiPage page, String username,
066: String password, String permission) throws XmlRpcException {
067: return;
068: /*
069: AuthorizationManager mgr = m_engine.getAuthorizationManager();
070: UserProfile currentUser = m_engine.getUserManager().getUserProfile( username );
071: currentUser.setPassword( password );
072:
073: WikiAuthenticator auth = m_engine.getUserManager().getAuthenticator();
074:
075: if( auth != null )
076: {
077: boolean isValid = auth.authenticate( currentUser );
078:
079: if( isValid )
080: {
081: if( !mgr.checkPermission( page,
082: currentUser,
083: permission ) )
084: {
085: return;
086: }
087: else
088: {
089: String msg = "Insufficient permissions to do "+permission+" on "+page.getName();
090: log.error( msg );
091: throw new XmlRpcException(0, msg );
092: }
093: }
094: else
095: {
096: log.error( "Username '"+username+"' or password not valid." );
097: throw new XmlRpcException(0, "Password or username not valid.");
098: }
099: }
100: */
101: }
102:
103: /**
104: * JSPWiki does not support categories, therefore JSPWiki
105: * always returns an empty list for categories.
106: */
107: public Hashtable getCategories(String blogid, String username,
108: String password) throws XmlRpcException {
109: WikiPage page = m_engine.getPage(blogid);
110:
111: checkPermissions(page, username, password, "view");
112:
113: Hashtable ht = new Hashtable();
114:
115: return ht;
116: }
117:
118: private String getURL(String page) {
119: return m_engine.getURL(WikiContext.VIEW, page, null, true); // Force absolute urls
120: }
121:
122: /**
123: * Takes a wiki page, and creates a metaWeblog struct
124: * out of it.
125: * @param page The actual entry page
126: * @return A metaWeblog entry struct.
127: */
128: private Hashtable makeEntry(WikiPage page) {
129: Hashtable ht = new Hashtable();
130:
131: WikiPage firstVersion = m_engine.getPage(page.getName(), 1);
132:
133: ht.put("dateCreated", firstVersion.getLastModified());
134: ht.put("link", getURL(page.getName()));
135: ht.put("permaLink", getURL(page.getName()));
136: ht.put("postid", page.getName());
137: ht.put("userid", page.getAuthor());
138:
139: String pageText = m_engine.getText(page.getName());
140: String title = "";
141: int firstLine = pageText.indexOf('\n');
142:
143: if (firstLine > 0) {
144: title = pageText.substring(0, firstLine);
145: }
146:
147: if (title.trim().length() == 0)
148: title = page.getName();
149:
150: // Remove wiki formatting
151: while (title.startsWith("!"))
152: title = title.substring(1);
153:
154: ht.put("title", title);
155: ht.put("description", pageText);
156:
157: return ht;
158: }
159:
160: /**
161: * Returns a list of the recent posts to this weblog.
162: */
163:
164: // FIXME: The implementation is suboptimal, as it
165: // goes through all of the blog entries.
166: public Hashtable getRecentPosts(String blogid, String username,
167: String password, int numberOfPosts) throws XmlRpcException {
168: Hashtable result = new Hashtable();
169:
170: log.info("metaWeblog.getRecentPosts() called");
171:
172: WikiPage page = m_engine.getPage(blogid);
173:
174: checkPermissions(page, username, password, "view");
175:
176: try {
177: WeblogPlugin plugin = new WeblogPlugin();
178:
179: List changed = plugin
180: .findBlogEntries(m_engine.getPageManager(), blogid,
181: new Date(0L), new Date());
182:
183: Collections.sort(changed, new PageTimeComparator());
184:
185: int items = 0;
186: for (Iterator i = changed.iterator(); i.hasNext()
187: && items < numberOfPosts; items++) {
188: WikiPage p = (WikiPage) i.next();
189:
190: result.put("entry", makeEntry(p));
191: }
192:
193: } catch (ProviderException e) {
194: log.error("Failed to list recent posts", e);
195:
196: throw new XmlRpcException(0, e.getMessage());
197: }
198:
199: return result;
200: }
201:
202: /**
203: * Adds a new post to the blog.
204: * @param publish This parameter is ignored for JSPWiki.
205: */
206: public String newPost(String blogid, String username,
207: String password, Hashtable content, boolean publish)
208: throws XmlRpcException {
209: log.info("metaWeblog.newPost() called");
210:
211: WikiPage page = m_engine.getPage(blogid);
212: checkPermissions(page, username, password, "create");
213:
214: try {
215: WeblogEntryPlugin plugin = new WeblogEntryPlugin();
216:
217: String pageName = plugin.getNewEntryPage(m_engine, blogid);
218:
219: WikiPage entryPage = new WikiPage(m_engine, pageName);
220: entryPage.setAuthor(username);
221:
222: WikiContext context = new WikiContext(m_engine, entryPage);
223:
224: StringBuffer text = new StringBuffer();
225: text.append("!" + content.get("title"));
226: text.append("\n\n");
227: text.append(content.get("description"));
228:
229: log.debug("Writing entry: " + text);
230:
231: m_engine.saveText(context, text.toString());
232: } catch (Exception e) {
233: log.error("Failed to create weblog entry", e);
234: throw new XmlRpcException(0,
235: "Failed to create weblog entry: " + e.getMessage());
236: }
237:
238: return ""; // FIXME:
239: }
240:
241: /**
242: * Creates an attachment and adds it to the blog. The attachment
243: * is created into the main blog page, not the actual post page,
244: * because we do not know it at this point.
245: */
246: public Hashtable newMediaObject(String blogid, String username,
247: String password, Hashtable content) throws XmlRpcException {
248: String url = "";
249:
250: log.info("metaWeblog.newMediaObject() called");
251:
252: WikiPage page = m_engine.getPage(blogid);
253: checkPermissions(page, username, password, "upload");
254:
255: String name = (String) content.get("name");
256: byte[] data = (byte[]) content.get("bits");
257:
258: AttachmentManager attmgr = m_engine.getAttachmentManager();
259:
260: try {
261: Attachment att = new Attachment(m_engine, blogid, name);
262: att.setAuthor(username);
263: attmgr.storeAttachment(att, new ByteArrayInputStream(data));
264:
265: url = m_engine.getURL(WikiContext.ATTACH, att.getName(),
266: null, true);
267: } catch (Exception e) {
268: log.error("Failed to upload attachment", e);
269: throw new XmlRpcException(0,
270: "Failed to upload media object: " + e.getMessage());
271: }
272:
273: Hashtable result = new Hashtable();
274: result.put("url", url);
275:
276: return result;
277: }
278:
279: /**
280: * Allows the user to edit a post. It does not allow general
281: * editability of wiki pages, because of the limitations of the
282: * metaWeblog API.
283: */
284: boolean editPost(String postid, String username, String password,
285: Hashtable content, boolean publish) throws XmlRpcException {
286: log.info("metaWeblog.editPost(" + postid + ") called");
287:
288: // FIXME: Is postid correct? Should we determine it from the page name?
289: WikiPage page = m_engine.getPage(postid);
290: checkPermissions(page, username, password, "edit");
291:
292: try {
293: WikiPage entryPage = (WikiPage) page.clone();
294: entryPage.setAuthor(username);
295:
296: WikiContext context = new WikiContext(m_engine, entryPage);
297:
298: StringBuffer text = new StringBuffer();
299: text.append("!" + content.get("title"));
300: text.append("\n\n");
301: text.append(content.get("description"));
302:
303: log.debug("Updating entry: " + text);
304:
305: m_engine.saveText(context, text.toString());
306: } catch (Exception e) {
307: log.error("Failed to create weblog entry", e);
308: throw new XmlRpcException(0,
309: "Failed to update weblog entry: " + e.getMessage());
310: }
311:
312: return true;
313: }
314:
315: /**
316: * Gets the text of any page. The title of the page is parsed
317: * (if any is provided).
318: */
319: Hashtable getPost(String postid, String username, String password)
320: throws XmlRpcException {
321: String wikiname = "FIXME";
322:
323: WikiPage page = m_engine.getPage(wikiname);
324:
325: checkPermissions(page, username, password, "view");
326:
327: return makeEntry(page);
328: }
329: }
|