Coverage Report - net.sourceforge.pebble.webservice.MetaWeblogAPIHandler
 
Classes in this File Line Coverage Branch Coverage Complexity
MetaWeblogAPIHandler
66%
99/148
63%
24/38
4.667
 
 1  
 /*
 2  
  * Copyright (c) 2003-2011, 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;
 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  4
 @SuppressWarnings("unchecked")
 63  112
 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  4
   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  
    */
 102  
   public Hashtable newMediaObject(String blogid, String username, String password, Hashtable struct) throws XmlRpcException {
 103  0
     log.debug("metaWeblog.newMediaObject(" +
 104  
         blogid + ", " +
 105  
         username + ", " +
 106  
         "********)");
 107  0
     log.debug(" name = " + struct.get(NAME));
 108  0
     log.debug(" type = " + struct.get(TYPE));
 109  
 
 110  0
     Blog blog = getBlogWithBlogId(blogid);
 111  0
     authenticate(blog, username, password);
 112  
 
 113  0
     Hashtable ht = new Hashtable();
 114  
 
 115  0
     String name = (String)struct.get(NAME);
 116  
     FileManager manager;
 117  0
     if (name.startsWith("files/")) {
 118  0
       manager = new FileManager(blog, FileMetaData.BLOG_FILE);
 119  0
       name = name.substring(name.indexOf("/"));
 120  0
     } else if (name.startsWith("images/")) {
 121  0
       manager = new FileManager(blog, FileMetaData.BLOG_IMAGE);
 122  0
       name = name.substring(name.indexOf("/"));
 123  
     } else {
 124  0
       manager = new FileManager(blog, FileMetaData.BLOG_IMAGE);
 125  
       // name is as specified
 126  
     }
 127  
 
 128  0
     log.debug("Saving to " + name);
 129  
     try {
 130  0
       byte bytes[] = (byte[])struct.get(BITS);
 131  0
       long itemSize = bytes.length/1024; // number of bytes / 1024
 132  0
       if (FileManager.hasEnoughSpace(blog, itemSize)) {
 133  0
         FileMetaData file = manager.saveFile(name, bytes);
 134  0
         ht.put(URL, file.getUrl());
 135  0
       } else {
 136  0
         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  0
     } catch (IOException e) {
 139  0
       e.printStackTrace();
 140  0
       throw new XmlRpcException(0, "IOException");
 141  0
     } catch (IllegalFileAccessException e) {
 142  0
       e.printStackTrace();
 143  0
       throw new XmlRpcException(0, "Access forbidden");
 144  0
     }
 145  
 
 146  0
     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  
    */
 158  
   public Hashtable getCategories(String blogid, String username, String password) throws XmlRpcException {
 159  32
     log.debug("metaWeblog.getCategories(" +
 160  
         blogid + ", " +
 161  
         username + ", " +
 162  
         "********)");
 163  
 
 164  32
     Blog blog = getBlogWithBlogId(blogid);
 165  20
     authenticate(blog, username, password);
 166  
 
 167  16
     Hashtable categories = new Hashtable();
 168  16
     Iterator it = blog.getCategories().iterator();
 169  
     Category category;
 170  48
     while (it.hasNext()) {
 171  32
       category = (Category)it.next();
 172  32
       if (!category.isRootCategory()) {
 173  16
         Hashtable struct = new Hashtable();
 174  16
         struct.put(DESCRIPTION, category.getId());
 175  16
         struct.put(HTML_URL, category.getPermalink());
 176  16
         struct.put(RSS_URL, blog.getUrl() + "rss.xml?category=" + category.getId());
 177  16
         categories.put(category.getId(), struct);
 178  16
       }
 179  
     }
 180  
 
 181  16
     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  
    */
 194  
   public Vector getRecentPosts(String blogid, String username, String password, int numberOfPosts) throws XmlRpcException {
 195  32
     log.debug("metaWeblog.getRecentPosts(" +
 196  
         blogid + ", " +
 197  
         username + ", " +
 198  
         "********)");
 199  
 
 200  32
     Blog blog = getBlogWithBlogId(blogid);
 201  32
     authenticate(blog, username, password);
 202  
 
 203  24
     Vector posts = new Vector();
 204  24
     Collection coll = blog.getRecentBlogEntries(numberOfPosts);
 205  
 
 206  24
     Iterator it = coll.iterator();
 207  
     BlogEntry entry;
 208  48
     while (it.hasNext()) {
 209  24
       entry = (BlogEntry)it.next();
 210  24
       posts.add(adaptBlogEntry(entry));
 211  
     }
 212  
 
 213  24
     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  
    */
 225  
   public Hashtable getPost(String postid, String username, String password) throws XmlRpcException {
 226  40
     log.debug("metaWeblog.getPost(" +
 227  
         postid + ", " +
 228  
         username + ", " +
 229  
         "********)");
 230  
 
 231  40
     Blog blog = getBlogWithPostId(postid);
 232  32
     postid = getPostId(postid);
 233  32
     authenticate(blog, username, password);
 234  24
     BlogService service = new BlogService();
 235  24
     BlogEntry entry = null;
 236  
     try {
 237  24
       entry = service.getBlogEntry(blog, postid);
 238  0
     } catch (BlogServiceException e) {
 239  0
       throw new XmlRpcException(0, "Blog entry with ID of " + postid + " could not be loaded");
 240  24
     }
 241  
 
 242  24
     if (entry != null) {
 243  8
       return adaptBlogEntry(entry);
 244  
     } else {
 245  16
       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  
    */
 260  
   public String newPost(String blogid, String username, String password, Hashtable struct, boolean publish) throws XmlRpcException {
 261  36
     log.debug("metaWeblog.newPost(" +
 262  
         blogid + ", " +
 263  
         username + ", " +
 264  
         "********, " +
 265  
         struct + ", " +
 266  
         publish + ")");
 267  
 
 268  
     try {
 269  36
       Blog blog = getBlogWithBlogId(blogid);
 270  36
       authenticate(blog, username, password);
 271  
 
 272  28
       BlogEntry entry = new BlogEntry(blog);
 273  
 
 274  28
       if (struct.containsKey(PUB_DATE)) {
 275  4
         Date date = (Date)struct.get(PUB_DATE);
 276  4
         entry.setDate(date);
 277  
       }
 278  
 
 279  28
       populateEntry(entry, struct, username);
 280  28
       entry.setPublished(publish);
 281  
 
 282  28
       BlogService service = new BlogService();
 283  28
       service.putBlogEntry(entry);
 284  
 
 285  28
       return formatPostId(blogid, entry.getId());
 286  0
     } catch (BlogServiceException be) {
 287  0
       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  
    */
 302  
   public boolean editPost(String postid, String username, String password, Hashtable struct, boolean publish) throws XmlRpcException {
 303  40
     log.debug("BloggerAPI.editPost(" +
 304  
         postid + ", " +
 305  
         username + ", " +
 306  
         "********, " +
 307  
         struct + ", " +
 308  
         publish + ")");
 309  
 
 310  
     try {
 311  40
       Blog blog = getBlogWithPostId(postid);
 312  32
       postid = getPostId(postid);
 313  32
       authenticate(blog, username, password);
 314  24
       BlogService service = new BlogService();
 315  24
       BlogEntry entry = service.getBlogEntry(blog, postid);
 316  
 
 317  24
       if (entry != null) {
 318  8
         populateEntry(entry, struct, username);
 319  8
         entry.setPublished(publish);
 320  
 
 321  8
         service.putBlogEntry(entry);
 322  
       } else {
 323  16
         throw new XmlRpcException(0, "Blog entry with ID of " + postid + " was not found.");
 324  
       }
 325  
 
 326  8
       return true;
 327  0
     } catch (BlogServiceException be) {
 328  0
       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  
    */
 338  
   private Hashtable adaptBlogEntry(BlogEntry entry) {
 339  32
     Hashtable post = new Hashtable();
 340  32
     post.put(TITLE, entry.getTitle());
 341  32
     post.put(PERMALINK, entry.getPermalink());
 342  32
     post.put(TITLE, entry.getTitle());
 343  32
     post.put(DESCRIPTION, entry.getBody());
 344  32
     post.put(DATE_CREATED, entry.getDate());
 345  32
     post.put(PUB_DATE, entry.getDate());
 346  32
     post.put(USER_ID, entry.getAuthor());
 347  32
     post.put(POST_ID, formatPostId(entry.getBlog().getId(), entry.getId()));
 348  
 
 349  32
     Vector categories = new Vector();
 350  32
     Iterator it = entry.getCategories().iterator();
 351  40
     while (it.hasNext()) {
 352  8
       Category cat = (Category)it.next();
 353  8
       categories.add(cat.getId());
 354  8
     }
 355  32
     post.put(CATEGORIES, categories);
 356  
 
 357  
     //Get Tags
 358  32
     Vector tags = new Vector();
 359  32
     for (Tag tag : entry.getAllTags()) {
 360  0
         tags.add(tag.getName());
 361  
     }
 362  32
     post.put(TAGS, tags);
 363  
 
 364  
     //Get comments
 365  32
     Vector comments = new Vector();
 366  32
     for (Comment comment : entry.getComments()) {
 367  0
         comments.add(adaptBlogEntryComment(comment));
 368  
     }
 369  32
     post.put(COMMENTS, comments);
 370  
 
 371  32
     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  
    */
 380  
   private Hashtable adaptBlogEntryComment(Comment comment) {
 381  0
       Hashtable cmnt = new Hashtable();
 382  
         
 383  0
       cmnt.put(BODY, comment.getBody());
 384  0
       cmnt.put(AUTHOR, comment.getAuthor());
 385  0
       String email = comment.getEmail();
 386  0
       if (email != null) cmnt.put(EMAIL, email);
 387  0
       cmnt.put(DATE, comment.getDate());
 388  0
       cmnt.put(PERMALINK, comment.getPermalink());
 389  0
       String website = comment.getWebsite();
 390  0
       if (website != null) cmnt.put(WEBSITE, website);
 391  0
       cmnt.put(IP_ADDRESS, comment.getIpAddress());
 392  
 
 393  0
       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  
    */
 403  
   private void populateEntry(BlogEntry entry, Hashtable struct, String username) {
 404  36
       assert entry != null;
 405  36
       entry.setTitle((String)struct.get(TITLE));
 406  36
       entry.setBody((String)struct.get(DESCRIPTION));
 407  36
       entry.setAuthor(username);
 408  
 
 409  36
       Vector categories = (Vector)struct.get(CATEGORIES);
 410  36
       if (categories != null) {
 411  40
           for (int i = 0; i < categories.size(); i++) {
 412  20
               Category c = entry.getBlog().getCategory((String)categories.get(i));
 413  20
               if (c != null)
 414  12
                   entry.addCategory(c);
 415  
           }
 416  
       }
 417  
 
 418  36
       String taglist = (String)struct.get(TAGS);
 419  36
       entry.setTags( taglist );
 420  36
   }
 421  
 
 422  
 }