/projects/roller-5.0.1/weblogger-web/src/main/java/org/apache/roller/weblogger/webservices/xmlrpc/BloggerAPIHandler.java
Java | 501 lines | 296 code | 77 blank | 128 comment | 26 complexity | 09a12e4386e68a609bc61b718b368118 MD5 | raw file
1/*
2 * Licensed to the Apache Software Foundation (ASF) under one or more
3 * contributor license agreements. The ASF licenses this file to You
4 * under the Apache License, Version 2.0 (the "License"); you may not
5 * 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. For additional information regarding
15 * copyright in this work, please see the NOTICE file in the top level
16 * directory of this distribution.
17 */
18
19package org.apache.roller.weblogger.webservices.xmlrpc;
20
21import java.sql.Timestamp;
22import java.util.ArrayList;
23import java.util.Date;
24import java.util.Hashtable;
25import java.util.Iterator;
26import java.util.List;
27import java.util.Map;
28import java.util.StringTokenizer;
29import java.util.Vector;
30
31
32import org.apache.commons.lang.StringUtils;
33import org.apache.commons.logging.Log;
34import org.apache.commons.logging.LogFactory;
35import org.apache.roller.weblogger.WebloggerException;
36import org.apache.roller.weblogger.config.WebloggerRuntimeConfig;
37import org.apache.roller.weblogger.business.Weblogger;
38import org.apache.roller.weblogger.business.WebloggerFactory;
39import org.apache.roller.weblogger.business.UserManager;
40import org.apache.roller.weblogger.business.WeblogEntryManager;
41import org.apache.roller.weblogger.pojos.User;
42import org.apache.roller.weblogger.pojos.WeblogEntry;
43import org.apache.roller.weblogger.pojos.WeblogTemplate;
44import org.apache.roller.weblogger.pojos.Weblog;
45import org.apache.roller.weblogger.util.Utilities;
46import org.apache.xmlrpc.XmlRpcException;
47
48/**
49 * Weblogger XML-RPC Handler for the Blogger v1 API.
50 *
51 * Blogger API spec can be found at http://plant.blogger.com/api/index.html
52 * See also http://xmlrpc.free-conversant.com/docs/bloggerAPI
53 *
54 * @author David M Johnson
55 */
56public class BloggerAPIHandler extends BaseAPIHandler {
57
58 static final long serialVersionUID = 2398898776655115019L;
59
60 private static Log mLogger = LogFactory.getLog(BloggerAPIHandler.class);
61
62 public BloggerAPIHandler() {
63 super();
64 }
65
66
67 /**
68 * Delete a Post
69 *
70 * @param appkey Unique identifier/passcode of the application sending the post
71 * @param postid Unique identifier of the post to be changed
72 * @param userid Login for a Blogger user who has permission to post to the blog
73 * @param password Password for said username
74 * @param publish Ignored
75 * @throws XmlRpcException
76 * @return
77 */
78 public boolean deletePost(String appkey, String postid, String userid,
79 String password, boolean publish) throws Exception {
80
81 mLogger.debug("deletePost() Called =====[ SUPPORTED ]=====");
82 mLogger.debug(" Appkey: " + appkey);
83 mLogger.debug(" PostId: " + postid);
84 mLogger.debug(" UserId: " + userid);
85
86 Weblogger roller = WebloggerFactory.getWeblogger();
87 WeblogEntryManager weblogMgr = roller.getWeblogEntryManager();
88 WeblogEntry entry = weblogMgr.getWeblogEntry(postid);
89
90 // Return false if entry not found
91 if (entry == null) return false;
92
93 validate(entry.getWebsite().getHandle(), userid, password);
94
95 try {
96 // notify cache
97 flushPageCache(entry.getWebsite());
98
99 // delete the entry
100 weblogMgr.removeWeblogEntry(entry);
101 roller.flush();
102
103
104 } catch (Exception e) {
105 String msg = "ERROR in blogger.deletePost: "+e.getClass().getName();
106 mLogger.error(msg,e);
107 throw new XmlRpcException(UNKNOWN_EXCEPTION, msg);
108 }
109
110 return true;
111 }
112
113
114 /**
115 * Edits the main index template of a given blog. Weblogger only support
116 * updating the main template, the default template of your weblog.
117 *
118 * @param appkey Unique identifier/passcode of the application sending the post
119 * @param blogid Unique identifier of the blog the post will be added to
120 * @param userid Login for a Blogger user who has permission to post to the blog
121 * @param password Password for said username
122 * @param template The text for the new template (usually mostly HTML).
123 * @param templateType Determines which of the blog's templates is to be set.
124 * @return
125 * @throws XmlRpcException
126 */
127 public boolean setTemplate(String appkey, String blogid, String userid,
128 String password, String templateData,
129 String templateType) throws Exception {
130
131 mLogger.debug("setTemplate() Called =====[ SUPPORTED ]=====");
132 mLogger.debug(" Appkey: " + appkey);
133 mLogger.debug(" BlogId: " + blogid);
134 mLogger.debug(" UserId: " + userid);
135 mLogger.debug(" Template: " + templateData);
136 mLogger.debug(" Type: " + templateType);
137
138 validate(blogid, userid, password);
139
140 if (! templateType.equals("main")) {
141 throw new XmlRpcException(
142 UNKNOWN_EXCEPTION, "Roller only supports main template");
143 }
144
145 try {
146 WeblogTemplate page = WebloggerFactory.getWeblogger().getWeblogManager().getPage(templateType);
147 page.setContents(templateData);
148 WebloggerFactory.getWeblogger().getWeblogManager().savePage(page);
149 flushPageCache(page.getWebsite());
150
151 return true;
152 } catch (WebloggerException e) {
153 String msg = "ERROR in BlooggerAPIHander.setTemplate";
154 mLogger.error(msg,e);
155 throw new XmlRpcException(UNKNOWN_EXCEPTION,msg);
156 }
157 }
158
159
160 /**
161 * Returns the main or archive index template of a given blog
162 *
163 * @param appkey Unique identifier/passcode of the application sending the post
164 * @param blogid Unique identifier of the blog the post will be added to
165 * @param userid Login for a Blogger user who has permission to post to the blog
166 * @param password Password for said username
167 * @param templateType Determines which of the blog's templates will be returned. Currently, either "main" or "archiveIndex"
168 * @throws XmlRpcException
169 * @return
170 */
171 public String getTemplate(String appkey, String blogid, String userid,
172 String password, String templateType)
173 throws Exception {
174
175 mLogger.debug("getTemplate() Called =====[ SUPPORTED ]=====");
176 mLogger.debug(" Appkey: " + appkey);
177 mLogger.debug(" BlogId: " + blogid);
178 mLogger.debug(" UserId: " + userid);
179 mLogger.debug(" Type: " + templateType);
180
181 validate(blogid, userid,password);
182
183 try {
184 WeblogTemplate page = WebloggerFactory.getWeblogger().getWeblogManager().getPage(templateType);
185
186 if ( null == page ) {
187 throw new XmlRpcException(UNKNOWN_EXCEPTION,"Template not found");
188 } else {
189 return page.getContents();
190 }
191 } catch (Exception e) {
192 String msg = "ERROR in BlooggerAPIHander.getTemplate";
193 mLogger.error(msg,e);
194 throw new XmlRpcException(UNKNOWN_EXCEPTION,msg);
195 }
196 }
197
198
199 /**
200 * Authenticates a user and returns basic user info (name, email, userid, etc.)
201 *
202 * @param appkey Unique identifier/passcode of the application sending the post
203 * @param userid Login for a Blogger user who has permission to post to the blog
204 * @param password Password for said username
205 * @throws XmlRpcException
206 * @return
207 */
208 public Object getUserInfo(String appkey, String userid, String password)
209 throws Exception {
210
211 mLogger.debug("getUserInfo() Called =====[ SUPPORTED ]=====");
212 mLogger.debug(" Appkey: " + appkey);
213 mLogger.debug(" UserId: " + userid);
214
215 validateUser(userid, password);
216
217 try {
218 Weblogger roller = WebloggerFactory.getWeblogger();
219 UserManager userMgr = roller.getUserManager();
220 User user = userMgr.getUserByUserName(userid);
221
222 // parses full name into two strings, firstname and lastname
223 String firstname = "", lastname = "";
224 StringTokenizer toker = new StringTokenizer(user.getFullName());
225
226 if (toker.hasMoreTokens()) {
227 firstname = toker.nextToken();
228 }
229
230 while (toker.hasMoreTokens()) {
231 if ( !lastname.equals("") ) {
232 lastname += " ";
233 }
234 lastname += toker.nextToken();
235 }
236
237 // TODO: Should screen name be renamed nickname and used here?
238 // populates user information to return as a result
239 Hashtable result = new Hashtable();
240 result.put("nickname", user.getUserName());
241 result.put("userid", user.getUserName());
242 result.put("email", "");
243 result.put("lastname", lastname);
244 result.put("firstname", firstname);
245
246 return result;
247 } catch (WebloggerException e) {
248 String msg = "ERROR in BlooggerAPIHander.getInfo";
249 mLogger.error(msg,e);
250 throw new XmlRpcException(UNKNOWN_EXCEPTION,msg);
251 }
252 }
253
254
255 /**
256 * Returns information on all the blogs a given user is a member of
257 *
258 * @param appkey Unique identifier/passcode of the application sending the post
259 * @param userid Login for a Blogger user who has permission to post to the blog
260 * @param password Password for said username
261 * @throws XmlRpcException
262 * @return
263 */
264 public Object getUsersBlogs(String appkey, String userid, String password)
265 throws Exception {
266
267 mLogger.debug("getUsersBlogs() Called ===[ SUPPORTED ]=======");
268 mLogger.debug(" Appkey: " + appkey);
269 mLogger.debug(" UserId: " + userid);
270
271 Vector result = new Vector();
272 if (validateUser(userid, password)) {
273 try {
274 String contextUrl = WebloggerRuntimeConfig.getAbsoluteContextURL();
275
276 UserManager umgr = WebloggerFactory.getWeblogger().getUserManager();
277 User user = umgr.getUserByUserName(userid);
278
279 // get list of user's enabled websites
280 List websites = WebloggerFactory.getWeblogger().getWeblogManager().getUserWeblogs(user, true);
281 Iterator iter = websites.iterator();
282 while (iter.hasNext()) {
283 Weblog website = (Weblog)iter.next();
284
285 // only include weblog's that have client API support enabled
286 if (Boolean.TRUE.equals(website.getEnableBloggerApi())) {
287 Hashtable blog = new Hashtable(3);
288 blog.put("url", website.getURL());
289 blog.put("blogid", website.getHandle());
290 blog.put("blogName", website.getName());
291 result.add(blog);
292 }
293 }
294 } catch (Exception e) {
295 String msg = "ERROR in BlooggerAPIHander.getUsersBlogs";
296 mLogger.error(msg,e);
297 throw new XmlRpcException(UNKNOWN_EXCEPTION, msg);
298 }
299 }
300 return result;
301 }
302
303
304 /**
305 * Edits a given post. Optionally, will publish the blog after making the edit
306 *
307 * @param appkey Unique identifier/passcode of the application sending the post
308 * @param postid Unique identifier of the post to be changed
309 * @param userid Login for a Blogger user who has permission to post to the blog
310 * @param password Password for said username
311 * @param content Contents of the post
312 * @param publish If true, the blog will be published immediately after the post is made
313 * @throws XmlRpcException
314 * @return
315 */
316 public boolean editPost(String appkey, String postid, String userid,
317 String password, String content, boolean publish)
318 throws Exception {
319
320 mLogger.debug("editPost() Called ========[ SUPPORTED ]=====");
321 mLogger.debug(" Appkey: " + appkey);
322 mLogger.debug(" PostId: " + postid);
323 mLogger.debug(" UserId: " + userid);
324 mLogger.debug(" Publish: " + publish);
325 mLogger.debug(" Content:\n " + content);
326
327 if (validateUser(userid, password)) {
328 try {
329 Timestamp current = new Timestamp(System.currentTimeMillis());
330
331 Weblogger roller = WebloggerFactory.getWeblogger();
332 WeblogEntryManager weblogMgr = roller.getWeblogEntryManager();
333 WeblogEntry entry = weblogMgr.getWeblogEntry(postid);
334 entry.setText(content);
335 entry.setUpdateTime(current);
336 if (Boolean.valueOf(publish).booleanValue()) {
337 entry.setStatus(WeblogEntry.PUBLISHED);
338 } else {
339 entry.setStatus(WeblogEntry.DRAFT);
340 }
341
342 // save the entry
343 weblogMgr.saveWeblogEntry(entry);
344 roller.flush();
345
346 // notify cache
347 flushPageCache(entry.getWebsite());
348
349 return true;
350 } catch (Exception e) {
351 String msg = "ERROR in BlooggerAPIHander.editPost";
352 mLogger.error(msg,e);
353 throw new XmlRpcException(UNKNOWN_EXCEPTION, msg);
354 }
355 }
356 return false;
357 }
358
359
360 /**
361 * Makes a new post to a designated blog. Optionally, will publish the blog after making the post
362 *
363 * @param appkey Unique identifier/passcode of the application sending the post
364 * @param blogid Unique identifier of the blog the post will be added to
365 * @param userid Login for a Blogger user who has permission to post to the blog
366 * @param password Password for said username
367 * @param content Contents of the post
368 * @param publish If true, the blog will be published immediately after the post is made
369 * @throws XmlRpcException
370 * @return
371 */
372 public String newPost(String appkey, String blogid, String userid,
373 String password, String content, boolean publish)
374 throws Exception {
375
376 mLogger.debug("newPost() Called ===========[ SUPPORTED ]=====");
377 mLogger.debug(" Appkey: " + appkey);
378 mLogger.debug(" BlogId: " + blogid);
379 mLogger.debug(" UserId: " + userid);
380 mLogger.debug(" Publish: " + publish);
381 mLogger.debug(" Content:\n " + content);
382
383 Weblog website = validate(blogid, userid, password);
384
385 // extract the title from the content
386 String title = "";
387
388 if (content.indexOf("<title>") != -1) {
389 title =
390 content.substring(content.indexOf("<title>") + 7,
391 content.indexOf("</title>"));
392 content = StringUtils.replace(content, "<title>"+title+"</title>", "");
393 }
394 if (StringUtils.isEmpty(title)) {
395 title = Utilities.truncateNicely(content, 15, 15, "...");
396 }
397
398 try {
399 Weblogger roller = WebloggerFactory.getWeblogger();
400 WeblogEntryManager weblogMgr = roller.getWeblogEntryManager();
401
402 Timestamp current = new Timestamp(System.currentTimeMillis());
403
404 WeblogEntry entry = new WeblogEntry();
405 entry.setTitle(title);
406 entry.setText(content);
407 entry.setLocale(website.getLocale());
408 entry.setPubTime(current);
409 entry.setUpdateTime(current);
410 User user = roller.getUserManager().getUserByUserName(userid);
411 entry.setCreatorUserName(user.getUserName());
412 entry.setWebsite(website);
413 entry.setCategory(website.getBloggerCategory());
414 entry.setCommentDays(new Integer(website.getDefaultCommentDays()));
415 if (Boolean.valueOf(publish).booleanValue()) {
416 entry.setStatus(WeblogEntry.PUBLISHED);
417 } else {
418 entry.setStatus(WeblogEntry.DRAFT);
419 }
420
421 // save the entry
422 weblogMgr.saveWeblogEntry(entry);
423 roller.flush();
424
425 // notify cache
426 flushPageCache(entry.getWebsite());
427
428 return entry.getId();
429 } catch (Exception e) {
430 String msg = "ERROR in BlooggerAPIHander.newPost";
431 mLogger.error(msg,e);
432 throw new XmlRpcException(UNKNOWN_EXCEPTION, msg);
433 }
434 }
435
436
437 /**
438 * This method was added to the Blogger 1.0 API via an Email from Evan
439 * Williams to the Yahoo Group bloggerDev, see the email message for details -
440 * http://groups.yahoo.com/group/bloggerDev/message/225
441 *
442 * @param appkey Unique identifier/passcode of the application sending the post
443 * @param blogid Unique identifier of the blog the post will be added to
444 * @param userid Login for a Blogger user who has permission to post to the blog
445 * @param password Password for said username
446 * @param numposts Number of Posts to Retrieve
447 * @throws XmlRpcException
448 * @return Vector of Hashtables, each containing dateCreated, userid, postid, content
449 */
450 public Object getRecentPosts(String appkey, String blogid, String userid,
451 String password, int numposts)
452 throws Exception {
453
454 mLogger.debug("getRecentPosts() Called ===========[ SUPPORTED ]=====");
455 mLogger.debug(" Appkey: " + appkey);
456 mLogger.debug(" BlogId: " + blogid);
457 mLogger.debug(" UserId: " + userid);
458 mLogger.debug(" Number: " + numposts);
459
460 Weblog website = validate(blogid, userid,password);
461
462 try {
463 Vector results = new Vector();
464
465 Weblogger roller = WebloggerFactory.getWeblogger();
466 WeblogEntryManager weblogMgr = roller.getWeblogEntryManager();
467 if (website != null) {
468 Map entries = weblogMgr.getWeblogEntryObjectMap(
469 website, // website
470 null, // startDate
471 new Date(), // endDate
472 null, // catName
473 null, // tags
474 null, null, 0, -1);
475
476 Iterator iter = entries.values().iterator();
477 while (iter.hasNext()) {
478 ArrayList list = (ArrayList) iter.next();
479 Iterator i = list.iterator();
480 while (i.hasNext()) {
481 WeblogEntry entry = (WeblogEntry) i.next();
482 Hashtable result = new Hashtable();
483 if (entry.getPubTime() != null) {
484 result.put("dateCreated", entry.getPubTime());
485 }
486 result.put("userid", userid);
487 result.put("postid", entry.getId());
488 result.put("content", entry.getText());
489 results.add(result);
490 }
491 }
492 }
493 return results;
494 } catch (Exception e) {
495 String msg = "ERROR in BlooggerAPIHander.getRecentPosts";
496 mLogger.error(msg,e);
497 throw new XmlRpcException(UNKNOWN_EXCEPTION, msg);
498 }
499 }
500
501}