File Source: metaweblogapihandler.java
/*
P/P * Method: net.sourceforge.pebble.webservice.MetaWeblogAPIHandler__static_init
*
* Postconditions:
* init'ed(log)
*/
1 /*
2 * Copyright (c) 2003-2006, Simon Brown
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are met:
7 *
8 * - Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 *
11 * - Redistributions in binary form must reproduce the above copyright
12 * notice, this list of conditions and the following disclaimer in
13 * the documentation and/or other materials provided with the
14 * distribution.
15 *
16 * - Neither the name of Pebble nor the names of its contributors may
17 * be used to endorse or promote products derived from this software
18 * without specific prior written permission.
19 *
20 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
21 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
22 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
23 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
24 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
25 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
26 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
27 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
28 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
29 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
30 * POSSIBILITY OF SUCH DAMAGE.
31 */
32 package net.sourceforge.pebble.webservice;
33
34 import java.io.IOException;
35 import java.util.Collection;
36 import java.util.Date;
37 import java.util.Hashtable;
38 import java.util.Iterator;
39 import java.util.Vector;
40
41 import net.sourceforge.pebble.PebbleContext;
42 import net.sourceforge.pebble.domain.Blog;
43 import net.sourceforge.pebble.domain.BlogEntry;
44 import net.sourceforge.pebble.domain.BlogService;
45 import net.sourceforge.pebble.domain.BlogServiceException;
46 import net.sourceforge.pebble.domain.Category;
47 import net.sourceforge.pebble.domain.Comment;
48 import net.sourceforge.pebble.domain.FileManager;
49 import net.sourceforge.pebble.domain.FileMetaData;
50 import net.sourceforge.pebble.domain.IllegalFileAccessException;
51 import net.sourceforge.pebble.domain.Tag;
52
53 import org.apache.commons.logging.Log;
54 import org.apache.commons.logging.LogFactory;
/*
P/P * Method: void net.sourceforge.pebble.webservice.MetaWeblogAPIHandler()
*/
55 import org.apache.xmlrpc.XmlRpcException;
56
57 /**
58 * A handler for the MetaWeblog API (accessed via XML-RPC).
59 *
60 * @author Simon Brown
61 */
62 @SuppressWarnings("unchecked")
63 public class MetaWeblogAPIHandler extends AbstractAPIHandler {
64
65 static final String BODY = "body";
66 static final String AUTHOR = "author";
67 static final String EMAIL = "email";
68 static final String DATE = "date";
69 static final String WEBSITE = "website";
70 static final String IP_ADDRESS = "ipAddress";
71 static final String URL = "url";
72 static final String BLOG_ID = "blogid";
73 static final String BLOG_NAME = "blogName";
74 static final String DATE_CREATED = "dateCreated";
75 static final String USER_ID = "userId";
76 static final String POST_ID = "postid";
77 static final String TITLE = "title";
78 static final String DESCRIPTION = "description";
79 static final String PERMALINK = "permaLink";
80 static final String PUB_DATE = "pubDate";
81 static final String CATEGORIES = "categories";
82 static final String TAGS = "tags";
83 static final String NAME = "name";
84 static final String TYPE = "type";
85 static final String BITS = "bits";
86 static final String HTML_URL = "htmlUrl";
87 static final String RSS_URL = "rssUrl";
88 static final String COMMENTS = "comments";
89
90 /** the log used by this class */
91 private static Log log = LogFactory.getLog(MetaWeblogAPIHandler.class);
92
93 /**
94 * Creates a new media object on the server.
95 *
96 * @param blogid the ID of the blog
97 * @param username the username used for logging in via XML-RPC
98 * @param password the password used for logging in via XML-RPC
99 * @return a Hashtable (structs) containing information about the object
100 * @throws org.apache.xmlrpc.XmlRpcException if something goes wrong, including an authentication error
101 */
/*
P/P * Method: Hashtable newMediaObject(String, String, String, Hashtable)
*
* Preconditions:
* log != null
* struct != null
* this.authenticationManager != null
*
* Presumptions:
* bytes.length@130 <= 18_889_465_931_478_580_854_783
* java.util.Hashtable:get(...)@115 != null
* java.util.Hashtable:get(...)@130 != null
* net.sourceforge.pebble.domain.FileManager:hasEnoughSpace(...)@132 == 1
* net.sourceforge.pebble.domain.FileManager:saveFile(...)@133 != null
*
* Postconditions:
* return_value == &new Hashtable(newMediaObject#4)
* new Hashtable(newMediaObject#4) num objects == 1
*
* Test Vectors:
* java.lang.String:startsWith(...)@117: {0}, {1}
* java.lang.String:startsWith(...)@120: {0}, {1}
*/
102 public Hashtable newMediaObject(String blogid, String username, String password, Hashtable struct) throws XmlRpcException {
103 log.debug("metaWeblog.newMediaObject(" +
104 blogid + ", " +
105 username + ", " +
106 "********)");
107 log.debug(" name = " + struct.get(NAME));
108 log.debug(" type = " + struct.get(TYPE));
109
110 Blog blog = getBlogWithBlogId(blogid);
111 authenticate(blog, username, password);
112
113 Hashtable ht = new Hashtable();
114
115 String name = (String)struct.get(NAME);
116 FileManager manager;
117 if (name.startsWith("files/")) {
118 manager = new FileManager(blog, FileMetaData.BLOG_FILE);
119 name = name.substring(name.indexOf("/"));
120 } else if (name.startsWith("images/")) {
121 manager = new FileManager(blog, FileMetaData.BLOG_IMAGE);
122 name = name.substring(name.indexOf("/"));
123 } else {
124 manager = new FileManager(blog, FileMetaData.BLOG_IMAGE);
125 // name is as specified
126 }
127
128 log.debug("Saving to " + name);
129 try {
130 byte bytes[] = (byte[])struct.get(BITS);
131 long itemSize = bytes.length/1024; // number of bytes / 1024
132 if (FileManager.hasEnoughSpace(blog, itemSize)) {
133 FileMetaData file = manager.saveFile(name, bytes);
134 ht.put(URL, file.getUrl());
135 } else {
136 throw new XmlRpcException(0, "You do not have enough free space - please free some space by removing unused files or asking your system administrator to increase your quota from " + PebbleContext.getInstance().getConfiguration().getFileUploadQuota() + " KB.");
137 }
138 } catch (IOException e) {
139 e.printStackTrace();
140 throw new XmlRpcException(0, "IOException");
141 } catch (IllegalFileAccessException e) {
142 e.printStackTrace();
143 throw new XmlRpcException(0, "Access forbidden");
144 }
145
146 return ht;
147 }
148
149 /**
150 * Gets a list of categories.
151 *
152 * @param blogid the ID of the blog (ignored)
153 * @param username the username used for logging in via XML-RPC
154 * @param password the password used for logging in via XML-RPC
155 * @return a Hashtable of Hashtables (a struct of structs) representing categories
156 * @throws org.apache.xmlrpc.XmlRpcException if something goes wrong, including an authentication error
157 */
/*
P/P * Method: Hashtable getCategories(String, String, String)
*
* Preconditions:
* log != null
* this.authenticationManager != null
*
* Presumptions:
* java.util.Iterator:next(...)@171 != null
* net.sourceforge.pebble.domain.Blog:getCategories(...)@168 != null
*
* Postconditions:
* return_value == &new Hashtable(getCategories#2)
* new Hashtable(getCategories#2) num objects == 1
*
* Test Vectors:
* java.util.Iterator:hasNext(...)@170: {1}, {0}
* net.sourceforge.pebble.domain.Category:isRootCategory(...)@172: {1}, {0}
*/
158 public Hashtable getCategories(String blogid, String username, String password) throws XmlRpcException {
159 log.debug("metaWeblog.getCategories(" +
160 blogid + ", " +
161 username + ", " +
162 "********)");
163
164 Blog blog = getBlogWithBlogId(blogid);
165 authenticate(blog, username, password);
166
167 Hashtable categories = new Hashtable();
168 Iterator it = blog.getCategories().iterator();
169 Category category;
170 while (it.hasNext()) {
171 category = (Category)it.next();
172 if (!category.isRootCategory()) {
173 Hashtable struct = new Hashtable();
174 struct.put(DESCRIPTION, category.getId());
175 struct.put(HTML_URL, category.getPermalink());
176 struct.put(RSS_URL, blog.getUrl() + "rss.xml?category=" + category.getId());
177 categories.put(category.getId(), struct);
178 }
179 }
180
181 return categories;
182 }
183
184 /**
185 * Gets a list of the recent blog entries.
186 *
187 * @param blogid the ID of the blog (ignored)
188 * @param username the username used for logging in via XML-RPC
189 * @param password the password used for logging in via XML-RPC
190 * @param numberOfPosts the number of posts to get
191 * @return a Vector of Hashtables (an array of structs) representing blog entries
192 * @throws org.apache.xmlrpc.XmlRpcException if something goes wrong, including an authentication error
193 */
/*
P/P * Method: Vector getRecentPosts(String, String, String, int)
*
* Preconditions:
* log != null
* this.authenticationManager != null
*
* Presumptions:
* java.util.Iterator:next(...)@209 != null
* net.sourceforge.pebble.domain.Blog:getRecentBlogEntries(...)@204 != null
*
* Postconditions:
* return_value == &new Vector(getRecentPosts#2)
* new Vector(getRecentPosts#2) num objects == 1
*
* Test Vectors:
* java.util.Iterator:hasNext(...)@208: {1}, {0}
*/
194 public Vector getRecentPosts(String blogid, String username, String password, int numberOfPosts) throws XmlRpcException {
195 log.debug("metaWeblog.getRecentPosts(" +
196 blogid + ", " +
197 username + ", " +
198 "********)");
199
200 Blog blog = getBlogWithBlogId(blogid);
201 authenticate(blog, username, password);
202
203 Vector posts = new Vector();
204 Collection coll = blog.getRecentBlogEntries(numberOfPosts);
205
206 Iterator it = coll.iterator();
207 BlogEntry entry;
208 while (it.hasNext()) {
209 entry = (BlogEntry)it.next();
210 posts.add(adaptBlogEntry(entry));
211 }
212
213 return posts;
214 }
215
216 /**
217 * Gets an individual blog entry.
218 *
219 * @param postid the ID of the blog (ignored)
220 * @param username the username used for logging in via XML-RPC
221 * @param password the password used for logging in via XML-RPC
222 * @return a Hashtable representing a blog entry
223 * @throws org.apache.xmlrpc.XmlRpcException if something goes wrong, including an authentication error
224 */
/*
P/P * Method: Hashtable getPost(String, String, String)
*
* Preconditions:
* log != null
* postid != null
* this.authenticationManager != null
*
* Presumptions:
* net.sourceforge.pebble.domain.BlogService:getBlogEntry(...)@237 != null
*
* Postconditions:
* return_value == &new Hashtable(adaptBlogEntry#1)
* new Hashtable(adaptBlogEntry#1) num objects == 1
*/
225 public Hashtable getPost(String postid, String username, String password) throws XmlRpcException {
226 log.debug("metaWeblog.getPost(" +
227 postid + ", " +
228 username + ", " +
229 "********)");
230
231 Blog blog = getBlogWithPostId(postid);
232 postid = getPostId(postid);
233 authenticate(blog, username, password);
234 BlogService service = new BlogService();
235 BlogEntry entry = null;
236 try {
237 entry = service.getBlogEntry(blog, postid);
238 } catch (BlogServiceException e) {
239 throw new XmlRpcException(0, "Blog entry with ID of " + postid + " could not be loaded");
240 }
241
242 if (entry != null) {
243 return adaptBlogEntry(entry);
244 } else {
245 throw new XmlRpcException(0, "Blog entry with ID of " + postid + " was not found.");
246 }
247 }
248
249 /**
250 * Creates a new blog entry.
251 *
252 * @param blogid the ID of the blog (ignored)
253 * @param username the username used for logging in via XML-RPC
254 * @param password the password used for logging in via XML-RPC
255 * @param struct the struct containing the new blog entry
256 * @param publish a flag to indicate whether the entry should be published
257 * @return a String representing the ID of the new blog entry
258 * @throws org.apache.xmlrpc.XmlRpcException if something goes wrong, including an authentication error
259 */
/*
P/P * Method: String newPost(String, String, String, Hashtable, bool)
*
* Preconditions:
* log != null
* struct != null
* this.authenticationManager != null
*
* Postconditions:
* return_value != null
*
* Test Vectors:
* java.util.Hashtable:containsKey(...)@274: {0}, {1}
*/
260 public String newPost(String blogid, String username, String password, Hashtable struct, boolean publish) throws XmlRpcException {
261 log.debug("metaWeblog.newPost(" +
262 blogid + ", " +
263 username + ", " +
264 "********, " +
265 struct + ", " +
266 publish + ")");
267
268 try {
269 Blog blog = getBlogWithBlogId(blogid);
270 authenticate(blog, username, password);
271
272 BlogEntry entry = new BlogEntry(blog);
273
274 if (struct.containsKey(PUB_DATE)) {
275 Date date = (Date)struct.get(PUB_DATE);
276 entry.setDate(date);
277 }
278
279 populateEntry(entry, struct, username);
280 entry.setPublished(publish);
281
282 BlogService service = new BlogService();
283 service.putBlogEntry(entry);
284
285 return formatPostId(blogid, entry.getId());
286 } catch (BlogServiceException be) {
287 throw new XmlRpcException(0, be.getMessage());
288 }
289 }
290
291 /**
292 * Edits an existing blog entry.
293 *
294 * @param postid the ID of the blog entry to be edited
295 * @param username the username used for logging in via XML-RPC
296 * @param password the password used for logging in via XML-RPC
297 * @param struct the new content of the new blog entry
298 * @param publish a flag to indicate whether the entry should be published
299 * @return a boolean true value to signal success
300 * @throws org.apache.xmlrpc.XmlRpcException if something goes wrong, including an authentication error
301 */
/*
P/P * Method: bool editPost(String, String, String, Hashtable, bool)
*
* Preconditions:
* log != null
* postid != null
* struct != null
* this.authenticationManager != null
*
* Presumptions:
* net.sourceforge.pebble.domain.BlogService:getBlogEntry(...)@315 != null
*
* Postconditions:
* return_value == 1
*/
302 public boolean editPost(String postid, String username, String password, Hashtable struct, boolean publish) throws XmlRpcException {
303 log.debug("BloggerAPI.editPost(" +
304 postid + ", " +
305 username + ", " +
306 "********, " +
307 struct + ", " +
308 publish + ")");
309
310 try {
311 Blog blog = getBlogWithPostId(postid);
312 postid = getPostId(postid);
313 authenticate(blog, username, password);
314 BlogService service = new BlogService();
315 BlogEntry entry = service.getBlogEntry(blog, postid);
316
317 if (entry != null) {
318 populateEntry(entry, struct, username);
319 entry.setPublished(publish);
320
321 service.putBlogEntry(entry);
322 } else {
323 throw new XmlRpcException(0, "Blog entry with ID of " + postid + " was not found.");
324 }
325
326 return true;
327 } catch (BlogServiceException be) {
328 throw new XmlRpcException(0, be.getMessage());
329 }
330 }
331
332 /**
333 * Helper method to adapt a blog entry into an XML-RPC compatible struct.
334 *
335 * @param entry the BlogEntry to adapt
336 * @return a Hashtable representing the major properties of the entry
337 */
/*
P/P * Method: Hashtable adaptBlogEntry(BlogEntry)
*
* Preconditions:
* entry != null
*
* Presumptions:
* java.util.Iterator:next(...)@352 != null
* java.util.Iterator:next(...)@359 != null
* java.util.Iterator:next(...)@366 != null
* net.sourceforge.pebble.domain.BlogEntry:getAllTags(...)@359 != null
* net.sourceforge.pebble.domain.BlogEntry:getBlog(...)@347 != null
* ...
*
* Postconditions:
* return_value == &new Hashtable(adaptBlogEntry#1)
* new Hashtable(adaptBlogEntry#1) num objects == 1
*
* Test Vectors:
* java.util.Iterator:hasNext(...)@351: {1}, {0}
* java.util.Iterator:hasNext(...)@359: {1}, {0}
* java.util.Iterator:hasNext(...)@366: {1}, {0}
*/
338 private Hashtable adaptBlogEntry(BlogEntry entry) {
339 Hashtable post = new Hashtable();
340 post.put(TITLE, entry.getTitle());
341 post.put(PERMALINK, entry.getPermalink());
342 post.put(TITLE, entry.getTitle());
343 post.put(DESCRIPTION, entry.getBody());
344 post.put(DATE_CREATED, entry.getDate());
345 post.put(PUB_DATE, entry.getDate());
346 post.put(USER_ID, entry.getAuthor());
347 post.put(POST_ID, formatPostId(entry.getBlog().getId(), entry.getId()));
348
349 Vector categories = new Vector();
350 Iterator it = entry.getCategories().iterator();
351 while (it.hasNext()) {
352 Category cat = (Category)it.next();
353 categories.add(cat.getId());
354 }
355 post.put(CATEGORIES, categories);
356
357 //Get Tags
358 Vector tags = new Vector();
359 for (Tag tag : entry.getAllTags()) {
360 tags.add(tag.getName());
361 }
362 post.put(TAGS, tags);
363
364 //Get comments
365 Vector comments = new Vector();
366 for (Comment comment : entry.getComments()) {
367 comments.add(adaptBlogEntryComment(comment));
368 }
369 post.put(COMMENTS, comments);
370
371 return post;
372 }
373
374 /**
375 * help method to adapt a blog entry comments into an XML-RPC compatible struct.
376 *
377 * @param entry the BlogEntry to adapt
378 * @return a Hashtable representing the major properties of the entry
379 */
/*
P/P * Method: Hashtable adaptBlogEntryComment(Comment)
*
* Preconditions:
* comment != null
*
* Postconditions:
* return_value == &new Hashtable(adaptBlogEntryComment#1)
* new Hashtable(adaptBlogEntryComment#1) num objects == 1
*
* Test Vectors:
* net.sourceforge.pebble.domain.Comment:getEmail(...)@385: Addr_Set{null}, Inverse{null}
* net.sourceforge.pebble.domain.Comment:getWebsite(...)@389: Addr_Set{null}, Inverse{null}
*/
380 private Hashtable adaptBlogEntryComment(Comment comment) {
381 Hashtable cmnt = new Hashtable();
382
383 cmnt.put(BODY, comment.getBody());
384 cmnt.put(AUTHOR, comment.getAuthor());
385 String email = comment.getEmail();
386 if (email != null) cmnt.put(EMAIL, email);
387 cmnt.put(DATE, comment.getDate());
388 cmnt.put(PERMALINK, comment.getPermalink());
389 String website = comment.getWebsite();
390 if (website != null) cmnt.put(WEBSITE, website);
391 cmnt.put(IP_ADDRESS, comment.getIpAddress());
392
393 return cmnt;
394 }
395
396 /**
397 * Populates a given BlogEntry.
398 *
399 * @param entry the BlogEntry to populate
400 * @param struct a Hashtable containing the blog entry details
401 * @param username the author
402 */
/*
P/P * Method: void populateEntry(BlogEntry, Hashtable, String)
*
* Preconditions:
* entry != null
* struct != null
*
* Presumptions:
* net.sourceforge.pebble.domain.BlogEntry:getBlog(...)@412 != null
*
* Test Vectors:
* java.util.Hashtable:get(...)@409: Addr_Set{null}, Inverse{null}
* net.sourceforge.pebble.domain.Blog:getCategory(...)@412: Addr_Set{null}, Inverse{null}
*/
403 private void populateEntry(BlogEntry entry, Hashtable struct, String username) {
404 assert entry != null;
405 entry.setTitle((String)struct.get(TITLE));
406 entry.setBody((String)struct.get(DESCRIPTION));
407 entry.setAuthor(username);
408
409 Vector categories = (Vector)struct.get(CATEGORIES);
410 if (categories != null) {
411 for (int i = 0; i < categories.size(); i++) {
412 Category c = entry.getBlog().getCategory((String)categories.get(i));
413 if (c != null)
414 entry.addCategory(c);
415 }
416 }
417
418 String taglist = (String)struct.get(TAGS);
419 entry.setTags( taglist );
420 }
421
422 }
SofCheck Inspector Build Version : 2.22510
| metaweblogapihandler.java |
2010-Jun-25 19:40:32 |
| metaweblogapihandler.class |
2010-Jul-19 20:23:38 |