Coverage Report - net.sourceforge.pebble.webservice.BloggerAPIHandler
 
Classes in this File Line Coverage Branch Coverage Complexity
BloggerAPIHandler
92%
128/139
85%
29/34
4.333
 
 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 net.sourceforge.pebble.domain.*;
 35  
 import org.apache.commons.logging.Log;
 36  
 import org.apache.commons.logging.LogFactory;
 37  
 import org.apache.xmlrpc.XmlRpcException;
 38  
 
 39  
 import java.util.*;
 40  
 
 41  
 /**
 42  
  * A handler for the Blogger API (accessed via XML-RPC).
 43  
  *
 44  
  * @author    Simon Brown
 45  
  */
 46  156
 public class BloggerAPIHandler extends AbstractAPIHandler {
 47  
 
 48  
   static final String URL = "url";
 49  
   static final String BLOG_ID = "blogid";
 50  
   static final String BLOG_NAME = "blogName";
 51  
   static final String DATE_CREATED = "dateCreated";
 52  
   static final String USER_ID = "userId";
 53  
   static final String POST_ID = "postid";
 54  
   static final String CONTENT = "content";
 55  
 
 56  
   static final String TITLE_START_DELIMITER = "<title>";
 57  
   static final String TITLE_END_DELIMITER = "</title>";
 58  
   static final String CATEGORY_START_DELIMITER = "<category>";
 59  
   static final String CATEGORY_END_DELIMITER = "</category>";
 60  
   static final char BLOG_ID_SEPARATOR = '/';
 61  
 
 62  
   /** the log used by this class */
 63  4
   private static Log log = LogFactory.getLog(BloggerAPIHandler.class);
 64  
 
 65  
   /**
 66  
    * Gets information about the user logging in.
 67  
    *
 68  
    * @param appkey    the client application key (ignored)
 69  
    * @param username  the username used for logging in via XML-RPC
 70  
    * @param password  the password used for logging in via XML-RPC
 71  
    * @return  a Hashtable containing user information
 72  
    * @throws XmlRpcException    if something goes wrong, including an authentication error
 73  
    */
 74  
   public Hashtable getUserInfo(String appkey, String username, String password) throws XmlRpcException {
 75  12
     log.debug("BloggerAPI.getUserInfo(" +
 76  
         appkey + ", " +
 77  
         username + ", " +
 78  
         "********)");
 79  
 
 80  12
     authenticate((Blog)null, username, password);
 81  8
     Hashtable ht = new Hashtable();
 82  8
     ht.put("userid", username);
 83  
 
 84  8
     return ht;
 85  
   }
 86  
 
 87  
   /**
 88  
    * Gets a list of the blogs that the specified user can edit. Pabble
 89  
    * only has the concept of a single blog.
 90  
    *
 91  
    * @param appkey    the client application key (ignored)
 92  
    * @param username  the username used for logging in via XML-RPC
 93  
    * @param password  the password used for logging in via XML-RPC
 94  
    * @return  a Vector of Hashtables (an array of structs) representing blogs
 95  
    * @throws XmlRpcException    if something goes wrong, including an authentication error
 96  
    */
 97  
   public Vector getUsersBlogs(String appkey, String username, String password) throws XmlRpcException {
 98  12
     log.debug("BloggerAPI.getUsersBlogs(" +
 99  
         appkey + ", " +
 100  
         username + ", " +
 101  
         "********)");
 102  
 
 103  12
     Collection<Blog> blogs = BlogManager.getInstance().getBlogs();
 104  12
     Vector usersBlogs = new Vector();
 105  
 
 106  12
     for (Blog blog : blogs) {
 107  
       try {
 108  16
         authenticate(blog, username, password);
 109  12
         Hashtable blogInfo = new Hashtable();
 110  12
         blogInfo.put(URL, blog.getUrl());
 111  12
         blogInfo.put(BLOG_ID, blog.getId());
 112  12
         blogInfo.put(BLOG_NAME, blog.getName());
 113  
 
 114  12
         usersBlogs.add(blogInfo);
 115  4
       } catch (XmlRpcAuthenticationException xmlrpcae) {
 116  
         // do nothing - means that they didn't authenticate against the blog
 117  28
       }
 118  
     }
 119  
 
 120  12
     return usersBlogs;
 121  
   }
 122  
 
 123  
   /**
 124  
    * Gets a list of the recent blog entries.
 125  
    *
 126  
    * @param appkey    the client application key (ignored)
 127  
    * @param blogid    the ID of the blog (ignored)
 128  
    * @param username  the username used for logging in via XML-RPC
 129  
    * @param password  the password used for logging in via XML-RPC
 130  
    * @param numberOfPosts   the number of posts to get
 131  
    * @return  a Vector of Hashtables (an array of structs) representing blog entries
 132  
    * @throws XmlRpcException    if something goes wrong, including an authentication error
 133  
    */
 134  
   public Vector getRecentPosts(String appkey, String blogid, String username, String password, int numberOfPosts) throws XmlRpcException {
 135  28
     log.debug("BloggerAPI.getRecentPosts(" +
 136  
         appkey + ", " +
 137  
         blogid + ", " +
 138  
         username + ", " +
 139  
         "********)");
 140  
 
 141  28
     Blog blog = getBlogWithBlogId(blogid);
 142  20
     authenticate(blog, username, password);
 143  
 
 144  16
     Vector posts = new Vector();
 145  16
     Collection coll = blog.getRecentBlogEntries(numberOfPosts);
 146  
 
 147  16
     Iterator it = coll.iterator();
 148  
     BlogEntry entry;
 149  40
     while (it.hasNext()) {
 150  24
       entry = (BlogEntry)it.next();
 151  24
       posts.add(adaptBlogEntry(entry));
 152  
     }
 153  
 
 154  16
     return posts;
 155  
   }
 156  
 
 157  
   /**
 158  
    * Gets an individual blog entry.
 159  
    *
 160  
    * @param appkey    the client application key (ignored)
 161  
    * @param postid    the ID of the blog (ignored)
 162  
    * @param username  the username used for logging in via XML-RPC
 163  
    * @param password  the password used for logging in via XML-RPC
 164  
    * @return  a Hashtable representing a blog entry
 165  
    * @throws XmlRpcException    if something goes wrong, including an authentication error
 166  
    */
 167  
   public Hashtable getPost(String appkey, String postid, String username, String password) throws XmlRpcException {
 168  40
     log.debug("BloggerAPI.getPost(" +
 169  
         appkey + ", " +
 170  
         postid + ", " +
 171  
         username + ", " +
 172  
         "********)");
 173  
 
 174  40
     Blog blog = getBlogWithPostId(postid);
 175  28
     postid = getPostId(postid);
 176  28
     authenticate(blog, username, password);
 177  24
     BlogService service = new BlogService();
 178  24
     BlogEntry entry = null;
 179  
     try {
 180  24
       entry = service.getBlogEntry(blog, postid);
 181  0
     } catch (BlogServiceException e) {
 182  0
       throw new XmlRpcException(0, "Blog entry with ID of " + postid + " was not found.");
 183  24
     }
 184  
 
 185  24
     if (entry != null) {
 186  16
       return adaptBlogEntry(entry);
 187  
     } else {
 188  8
       throw new XmlRpcException(0, "Blog entry with ID of " + postid + " was not found.");
 189  
     }
 190  
   }
 191  
 
 192  
   /**
 193  
    * Creates a new blog entry.
 194  
    *
 195  
    * @param appkey    the client application key (ignored)
 196  
    * @param blogid    the ID of the blog (ignored)
 197  
    * @param username  the username used for logging in via XML-RPC
 198  
    * @param password  the password used for logging in via XML-RPC
 199  
    * @param content   the content of the new blog entry
 200  
    * @param publish   a flag to indicate whether the entry should be published
 201  
    * @return  a String representing the ID of the new blog entry
 202  
    * @throws XmlRpcException    if something goes wrong, including an authentication error
 203  
    */
 204  
   public String newPost(String appkey, String blogid, String username, String password, String content, boolean publish) throws XmlRpcException {
 205  20
     log.debug("BloggerAPI.newPost(" +
 206  
         appkey + ", " +
 207  
         blogid + ", " +
 208  
         username + ", " +
 209  
         "********, " +
 210  
         content + ", " +
 211  
         publish + ")");
 212  
 
 213  
     try {
 214  20
       Blog blog = getBlogWithBlogId(blogid);
 215  16
       authenticate(blog, username, password);
 216  
 
 217  12
       BlogEntry blogEntry = new BlogEntry(blog);
 218  12
       populateEntry(blogEntry, content, username);
 219  12
       blogEntry.setPublished(publish);
 220  
 
 221  12
       BlogService service = new BlogService();
 222  12
       service.putBlogEntry(blogEntry);
 223  
 
 224  12
       return formatPostId(blogid, blogEntry.getId());
 225  0
     } catch (BlogServiceException be) {
 226  0
       throw new XmlRpcException(0, be.getMessage());
 227  
     }
 228  
   }
 229  
 
 230  
   /**
 231  
    * Edits an existing blog entry.
 232  
    *
 233  
    * @param appkey    the client application key (ignored)
 234  
    * @param postid    the ID of the blog entry to be edited
 235  
    * @param username  the username used for logging in via XML-RPC
 236  
    * @param password  the password used for logging in via XML-RPC
 237  
    * @param content   the new content of the new blog entry
 238  
    * @param publish   a flag to indicate whether the entry should be published
 239  
    *                  (this is ignored as all new entries are published)
 240  
    * @return  a boolean true value to signal success
 241  
    * @throws XmlRpcException    if something goes wrong, including an authentication error
 242  
    */
 243  
   public boolean editPost(String appkey, String postid, String username, String password, String content, boolean publish) throws XmlRpcException {
 244  20
     log.debug("BloggerAPI.editPost(" +
 245  
         appkey + ", " +
 246  
         postid + ", " +
 247  
         username + ", " +
 248  
         "********, " +
 249  
         content + ", " +
 250  
         publish + ")");
 251  
 
 252  
     try {
 253  20
       Blog blog = getBlogWithPostId(postid);
 254  12
       postid = getPostId(postid);
 255  12
       authenticate(blog, username, password);
 256  8
       BlogService service = new BlogService();
 257  8
       BlogEntry entry = service.getBlogEntry(blog, postid);
 258  
 
 259  8
       if (entry != null) {
 260  4
         populateEntry(entry, content, username);
 261  4
         entry.setPublished(publish);
 262  4
         service.putBlogEntry(entry);
 263  
       } else {
 264  4
         throw new XmlRpcException(0, "Blog entry with ID of " + postid + " was not found.");
 265  
       }
 266  
 
 267  4
       return true;
 268  0
     } catch (BlogServiceException be) {
 269  0
       throw new XmlRpcException(0, be.getMessage());
 270  
     }
 271  
   }
 272  
 
 273  
   /**
 274  
    * Deletes an existing blog entry.
 275  
    *
 276  
    * @param appkey    the client application key (ignored)
 277  
    * @param postid    the ID of the blog entry to be edited
 278  
    * @param username  the username used for logging in via XML-RPC
 279  
    * @param password  the password used for logging in via XML-RPC
 280  
    * @param publish   a flag to indicate whether the entry should be published
 281  
    *                  (this is ignored)
 282  
    * @return  a boolean true value to signal success
 283  
    * @throws XmlRpcException    if something goes wrong, including an authentication error
 284  
    */
 285  
   public boolean deletePost(String appkey, String postid, String username, String password, boolean publish) throws XmlRpcException {
 286  32
     log.debug("BloggerAPI.deletePost(" +
 287  
         appkey + ", " +
 288  
         postid + ", " +
 289  
         username + ", " +
 290  
         "********, " +
 291  
         publish + ")");
 292  
 
 293  
     try {
 294  32
       Blog blog = getBlogWithPostId(postid);
 295  20
       postid = getPostId(postid);
 296  20
       authenticate(blog, username, password);
 297  16
       BlogService service = new BlogService();
 298  16
       BlogEntry blogEntry = service.getBlogEntry(blog, postid);
 299  
 
 300  16
       if (blogEntry != null) {
 301  8
         service.removeBlogEntry(blogEntry);
 302  8
         return true;
 303  
       } else {
 304  8
         throw new XmlRpcException(0, "Blog entry with ID of " + postid + " was not found.");
 305  
       }
 306  0
     } catch (BlogServiceException be) {
 307  0
       throw new XmlRpcException(0, be.getMessage());
 308  
     }
 309  
   }
 310  
 
 311  
   /**
 312  
    * Helper method to adapt a blog entry into an XML-RPC compatible struct.
 313  
    * Since the Blogger API doesn't support titles, the title is wrapped in
 314  
    * &lt;title&gt;&lt;/title&gt; tags.
 315  
    *
 316  
    * @param entry   the BlogEntry to adapt
 317  
    * @return  a Hashtable representing the major properties of the entry
 318  
    */
 319  
   private Hashtable adaptBlogEntry(BlogEntry entry) {
 320  40
     Hashtable post = new Hashtable();
 321  40
     String categories = "";
 322  40
     Iterator it = entry.getCategories().iterator();
 323  48
     while (it.hasNext()) {
 324  8
       Category category = (Category)it.next();
 325  8
       categories += category.getId();
 326  8
       if (it.hasNext()) {
 327  0
         categories += ",";
 328  
       }
 329  8
     }
 330  40
     post.put(DATE_CREATED, entry.getDate());
 331  40
     post.put(USER_ID, entry.getAuthor());
 332  40
     post.put(POST_ID, formatPostId(entry.getBlog().getId(), entry.getId()));
 333  40
     post.put(CONTENT, TITLE_START_DELIMITER + entry.getTitle() + TITLE_END_DELIMITER
 334  
         + CATEGORY_START_DELIMITER + categories + CATEGORY_END_DELIMITER + entry.getBody());
 335  
 
 336  40
     return post;
 337  
   }
 338  
 
 339  
   /**
 340  
    * Populates a given BlogEntry.
 341  
    *
 342  
    * @param entry     the BlogEntry to populate
 343  
    * @param content   the content (including title)
 344  
    * @param username  the author
 345  
    */
 346  
   private void populateEntry(BlogEntry entry, String content, String username) {
 347  16
     String title = "";
 348  16
     String category = "";
 349  
 
 350  16
     if (content.indexOf(TITLE_START_DELIMITER) > -1 && content.indexOf(TITLE_END_DELIMITER) > -1) {
 351  12
       content = content.substring(TITLE_START_DELIMITER.length());
 352  12
       int index = content.indexOf(TITLE_END_DELIMITER);
 353  12
       title = content.substring(0, index);
 354  12
       content = content.substring(index);
 355  12
       content = content.substring(TITLE_END_DELIMITER.length());
 356  
     }
 357  
 
 358  16
     if (content.indexOf(CATEGORY_START_DELIMITER) > -1 && content.indexOf(CATEGORY_END_DELIMITER) > -1) {
 359  8
       content = content.substring(CATEGORY_START_DELIMITER.length());
 360  8
       int index = content.indexOf(CATEGORY_END_DELIMITER);
 361  8
       category = content.substring(0, index);
 362  8
       content = content.substring(index);
 363  8
       content = content.substring(CATEGORY_END_DELIMITER.length());
 364  
     }
 365  
 
 366  16
     entry.setTitle(title);
 367  16
     entry.setBody(content);
 368  16
     entry.setAuthor(username);
 369  
 
 370  16
     if (category != null && !category.trim().equals("")) {
 371  8
       String[] categories = category.split(",");
 372  20
       for (int i = 0; i < categories.length; i++) {
 373  12
         Category c = entry.getBlog().getCategory(categories[i].trim());
 374  12
          if (c != null) {
 375  12
            entry.addCategory(c);
 376  
          }
 377  
       }
 378  
     }
 379  16
   }
 380  
 
 381  
   /**
 382  
    * Gets the specified template type for a blog - not supported by Pebble.
 383  
    *
 384  
    * @param appkey    the client application key (ignored)
 385  
    * @param blogid    the ID of the blog
 386  
    * @param username  the username used for logging in via XML-RPC
 387  
    * @param password  the password used for logging in via XML-RPC
 388  
    * @param templateType  the type of template to retrieve
 389  
    * @return  the text of the specified template
 390  
    * @throws XmlRpcException
 391  
    */
 392  
   public String getTemplate(String appkey, String blogid, String username, String password, String templateType) throws XmlRpcException {
 393  4
     log.debug("BloggerAPI.getTemplate(" +
 394  
         appkey + ", " +
 395  
         blogid + ", " +
 396  
         username + ", " +
 397  
         "********, " +
 398  
         templateType + ")");
 399  
 
 400  4
     throw new XmlRpcException(0, "getTemplate is not supported by Pebble.");
 401  
   }
 402  
 
 403  
   /**
 404  
    * Sets the specified template type for a blog - not supported by Pebble.
 405  
    *
 406  
    * @param appkey    the client application key (ignored)
 407  
    * @param blogid    the ID of the blog
 408  
    * @param username  the username used for logging in via XML-RPC
 409  
    * @param password  the password used for logging in via XML-RPC
 410  
    * @param template  the new text of the template
 411  
    * @param templateType  the type of template to retrieve
 412  
    * @return  true if setting the template was successful, false otherwise
 413  
    * @throws XmlRpcException
 414  
    */
 415  
   public boolean setTemplate(String appkey, String blogid, String username, String password, String template, String templateType) throws XmlRpcException {
 416  4
     log.debug("BloggerAPI.setTemplate(" +
 417  
         appkey + ", " +
 418  
         blogid + ", " +
 419  
         username + ", " +
 420  
         "********, " +
 421  
         template + ", " +
 422  
         templateType + ")");
 423  
 
 424  4
     throw new XmlRpcException(0, "setTemplate is not supported by Pebble.");
 425  
   }
 426  
 
 427  
   /**
 428  
    * Adds a category to a blog entry - this isn't a standard Blogger API method.
 429  
    *
 430  
    * @param appkey    the client application key (ignored)
 431  
    * @param postid    the ID of the blog entry to be edited
 432  
    * @param username  the username used for logging in via XML-RPC
 433  
    * @param password  the password used for logging in via XML-RPC
 434  
    * @param category  the category ID
 435  
    * @return  a boolean true value to signal success
 436  
    * @throws XmlRpcException    if something goes wrong, including an authentication error
 437  
    */
 438  
   public boolean addCategory(String appkey, String postid, String username, String password, String category) throws XmlRpcException {
 439  32
     log.debug("BloggerAPI.addCategory(" +
 440  
         appkey + ", " +
 441  
         postid + ", " +
 442  
         username + ", " +
 443  
         "********, " +
 444  
         category + ")");
 445  
 
 446  
     try {
 447  32
       Blog blog = getBlogWithPostId(postid);
 448  24
       postid = getPostId(postid);
 449  24
       authenticate(blog, username, password);
 450  24
       BlogService service = new BlogService();
 451  24
       BlogEntry entry = service.getBlogEntry(blog, postid);
 452  
 
 453  24
       if (entry != null) {
 454  16
         Category c = entry.getBlog().getCategory(category);
 455  16
         if (c != null) {
 456  8
           entry.addCategory(c);
 457  8
           service.putBlogEntry(entry);
 458  
 
 459  8
           return true;
 460  
         }
 461  8
       } else {
 462  8
         throw new XmlRpcException(0, "Blog entry with ID of " + postid + " was not found.");
 463  
       }
 464  
 
 465  8
       return false;
 466  0
     } catch (BlogServiceException be) {
 467  0
       throw new XmlRpcException(0, be.getMessage());
 468  
     }
 469  
   }
 470  
 
 471  
 }