File Source: bloggerapihandler.java

         /* 
    P/P   *  Method: net.sourceforge.pebble.webservice.BloggerAPIHandler__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 net.sourceforge.pebble.domain.*;
    35  import org.apache.commons.logging.Log;
    36  import org.apache.commons.logging.LogFactory;
         /* 
    P/P   *  Method: void net.sourceforge.pebble.webservice.BloggerAPIHandler()
          */
    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  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    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     */
           /* 
    P/P     *  Method: Hashtable getUserInfo(String, String, String)
            * 
            *  Preconditions:
            *    log != null
            *    this.authenticationManager != null
            * 
            *  Postconditions:
            *    return_value == &new Hashtable(getUserInfo#2)
            *    new Hashtable(getUserInfo#2) num objects == 1
            */
    74    public Hashtable getUserInfo(String appkey, String username, String password) throws XmlRpcException {
    75      log.debug("BloggerAPI.getUserInfo(" +
    76          appkey + ", " +
    77          username + ", " +
    78          "********)");
    79  
    80      authenticate((Blog)null, username, password);
    81      Hashtable ht = new Hashtable();
    82      ht.put("userid", username);
    83  
    84      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     */
           /* 
    P/P     *  Method: Vector getUsersBlogs(String, String, String)
            * 
            *  Preconditions:
            *    log != null
            *    (soft) this.authenticationManager != null
            * 
            *  Presumptions:
            *    java.util.Iterator:next(...)@106 != null
            *    net.sourceforge.pebble.domain.BlogManager:getBlogs(...)@103 != null
            *    net.sourceforge.pebble.domain.BlogManager:getInstance(...)@103 != null
            * 
            *  Postconditions:
            *    return_value == &new Vector(getUsersBlogs#2)
            *    new Vector(getUsersBlogs#2) num objects == 1
            * 
            *  Test Vectors:
            *    java.util.Iterator:hasNext(...)@106: {1}, {0}
            */
    97    public Vector getUsersBlogs(String appkey, String username, String password) throws XmlRpcException {
    98      log.debug("BloggerAPI.getUsersBlogs(" +
    99          appkey + ", " +
   100          username + ", " +
   101          "********)");
   102  
   103      Collection<Blog> blogs = BlogManager.getInstance().getBlogs();
   104      Vector usersBlogs = new Vector();
   105  
   106      for (Blog blog : blogs) {
   107        try {
   108          authenticate(blog, username, password);
   109          Hashtable blogInfo = new Hashtable();
   110          blogInfo.put(URL, blog.getUrl());
   111          blogInfo.put(BLOG_ID, blog.getId());
   112          blogInfo.put(BLOG_NAME, blog.getName());
   113  
   114          usersBlogs.add(blogInfo);
   115        } catch (XmlRpcAuthenticationException xmlrpcae) {
   116          // do nothing - means that they didn't authenticate against the blog
   117        }
   118      }
   119  
   120      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     */
           /* 
    P/P     *  Method: Vector getRecentPosts(String, String, String, String, int)
            * 
            *  Preconditions:
            *    log != null
            *    this.authenticationManager != null
            * 
            *  Presumptions:
            *    java.util.Iterator:next(...)@150 != null
            *    net.sourceforge.pebble.domain.Blog:getRecentBlogEntries(...)@145 != null
            * 
            *  Postconditions:
            *    return_value == &new Vector(getRecentPosts#2)
            *    new Vector(getRecentPosts#2) num objects == 1
            * 
            *  Test Vectors:
            *    java.util.Iterator:hasNext(...)@149: {1}, {0}
            */
   134    public Vector getRecentPosts(String appkey, String blogid, String username, String password, int numberOfPosts) throws XmlRpcException {
   135      log.debug("BloggerAPI.getRecentPosts(" +
   136          appkey + ", " +
   137          blogid + ", " +
   138          username + ", " +
   139          "********)");
   140  
   141      Blog blog = getBlogWithBlogId(blogid);
   142      authenticate(blog, username, password);
   143  
   144      Vector posts = new Vector();
   145      Collection coll = blog.getRecentBlogEntries(numberOfPosts);
   146  
   147      Iterator it = coll.iterator();
   148      BlogEntry entry;
   149      while (it.hasNext()) {
   150        entry = (BlogEntry)it.next();
   151        posts.add(adaptBlogEntry(entry));
   152      }
   153  
   154      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     */
           /* 
    P/P     *  Method: Hashtable getPost(String, String, String, String)
            * 
            *  Preconditions:
            *    log != null
            *    postid != null
            *    this.authenticationManager != null
            * 
            *  Presumptions:
            *    net.sourceforge.pebble.domain.BlogService:getBlogEntry(...)@180 != null
            * 
            *  Postconditions:
            *    return_value == &new Hashtable(adaptBlogEntry#1)
            *    new Hashtable(adaptBlogEntry#1) num objects == 1
            */
   167    public Hashtable getPost(String appkey, String postid, String username, String password) throws XmlRpcException {
   168      log.debug("BloggerAPI.getPost(" +
   169          appkey + ", " +
   170          postid + ", " +
   171          username + ", " +
   172          "********)");
   173  
   174      Blog blog = getBlogWithPostId(postid);
   175      postid = getPostId(postid);
   176      authenticate(blog, username, password);
   177      BlogService service = new BlogService();
   178      BlogEntry entry = null;
   179      try {
   180        entry = service.getBlogEntry(blog, postid);
   181      } catch (BlogServiceException e) {
   182        throw new XmlRpcException(0, "Blog entry with ID of " + postid + " was not found.");
   183      }
   184  
   185      if (entry != null) {
   186        return adaptBlogEntry(entry);
   187      } else {
   188        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     */
           /* 
    P/P     *  Method: String newPost(String, String, String, String, String, bool)
            * 
            *  Preconditions:
            *    content != null
            *    log != null
            *    this.authenticationManager != null
            * 
            *  Postconditions:
            *    return_value != null
            */
   204    public String newPost(String appkey, String blogid, String username, String password, String content, boolean publish) throws XmlRpcException {
   205      log.debug("BloggerAPI.newPost(" +
   206          appkey + ", " +
   207          blogid + ", " +
   208          username + ", " +
   209          "********, " +
   210          content + ", " +
   211          publish + ")");
   212  
   213      try {
   214        Blog blog = getBlogWithBlogId(blogid);
   215        authenticate(blog, username, password);
   216  
   217        BlogEntry blogEntry = new BlogEntry(blog);
   218        populateEntry(blogEntry, content, username);
   219        blogEntry.setPublished(publish);
   220  
   221        BlogService service = new BlogService();
   222        service.putBlogEntry(blogEntry);
   223  
   224        return formatPostId(blogid, blogEntry.getId());
   225      } catch (BlogServiceException be) {
   226        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     */
           /* 
    P/P     *  Method: bool editPost(String, String, String, String, String, bool)
            * 
            *  Preconditions:
            *    content != null
            *    log != null
            *    postid != null
            *    this.authenticationManager != null
            * 
            *  Presumptions:
            *    net.sourceforge.pebble.domain.BlogService:getBlogEntry(...)@257 != null
            * 
            *  Postconditions:
            *    return_value == 1
            */
   243    public boolean editPost(String appkey, String postid, String username, String password, String content, boolean publish) throws XmlRpcException {
   244      log.debug("BloggerAPI.editPost(" +
   245          appkey + ", " +
   246          postid + ", " +
   247          username + ", " +
   248          "********, " +
   249          content + ", " +
   250          publish + ")");
   251  
   252      try {
   253        Blog blog = getBlogWithPostId(postid);
   254        postid = getPostId(postid);
   255        authenticate(blog, username, password);
   256        BlogService service = new BlogService();
   257        BlogEntry entry = service.getBlogEntry(blog, postid);
   258  
   259        if (entry != null) {
   260          populateEntry(entry, content, username);
   261          entry.setPublished(publish);
   262          service.putBlogEntry(entry);
   263        } else {
   264          throw new XmlRpcException(0, "Blog entry with ID of " + postid + " was not found.");
   265        }
   266  
   267        return true;
   268      } catch (BlogServiceException be) {
   269        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     */
           /* 
    P/P     *  Method: bool deletePost(String, String, String, String, bool)
            * 
            *  Preconditions:
            *    log != null
            *    postid != null
            *    this.authenticationManager != null
            * 
            *  Presumptions:
            *    net.sourceforge.pebble.domain.BlogService:getBlogEntry(...)@298 != null
            * 
            *  Postconditions:
            *    return_value == 1
            */
   285    public boolean deletePost(String appkey, String postid, String username, String password, boolean publish) throws XmlRpcException {
   286      log.debug("BloggerAPI.deletePost(" +
   287          appkey + ", " +
   288          postid + ", " +
   289          username + ", " +
   290          "********, " +
   291          publish + ")");
   292  
   293      try {
   294        Blog blog = getBlogWithPostId(postid);
   295        postid = getPostId(postid);
   296        authenticate(blog, username, password);
   297        BlogService service = new BlogService();
   298        BlogEntry blogEntry = service.getBlogEntry(blog, postid);
   299  
   300        if (blogEntry != null) {
   301          service.removeBlogEntry(blogEntry);
   302          return true;
   303        } else {
   304          throw new XmlRpcException(0, "Blog entry with ID of " + postid + " was not found.");
   305        }
   306      } catch (BlogServiceException be) {
   307        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     * <title></title> tags.
   315     *
   316     * @param entry   the BlogEntry to adapt
   317     * @return  a Hashtable representing the major properties of the entry
   318     */
           /* 
    P/P     *  Method: Hashtable adaptBlogEntry(BlogEntry)
            * 
            *  Preconditions:
            *    entry != null
            * 
            *  Presumptions:
            *    java.util.Iterator:next(...)@324 != null
            *    net.sourceforge.pebble.domain.BlogEntry:getBlog(...)@332 != null
            *    net.sourceforge.pebble.domain.BlogEntry:getCategories(...)@322 != null
            * 
            *  Postconditions:
            *    return_value == &new Hashtable(adaptBlogEntry#1)
            *    new Hashtable(adaptBlogEntry#1) num objects == 1
            * 
            *  Test Vectors:
            *    java.util.Iterator:hasNext(...)@323: {1}, {0}
            *    java.util.Iterator:hasNext(...)@326: {0}, {1}
            */
   319    private Hashtable adaptBlogEntry(BlogEntry entry) {
   320      Hashtable post = new Hashtable();
   321      String categories = "";
   322      Iterator it = entry.getCategories().iterator();
   323      while (it.hasNext()) {
   324        Category category = (Category)it.next();
   325        categories += category.getId();
   326        if (it.hasNext()) {
   327          categories += ",";
   328        }
   329      }
   330      post.put(DATE_CREATED, entry.getDate());
   331      post.put(USER_ID, entry.getAuthor());
   332      post.put(POST_ID, formatPostId(entry.getBlog().getId(), entry.getId()));
   333      post.put(CONTENT, TITLE_START_DELIMITER + entry.getTitle() + TITLE_END_DELIMITER
   334          + CATEGORY_START_DELIMITER + categories + CATEGORY_END_DELIMITER + entry.getBody());
   335  
   336      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     */
           /* 
    P/P     *  Method: void populateEntry(BlogEntry, String, String)
            * 
            *  Preconditions:
            *    content != null
            *    entry != null
            * 
            *  Presumptions:
            *    categories.length@371 <= 232-1
            *    categories[i]@371 != null
            *    net.sourceforge.pebble.domain.BlogEntry:getBlog(...)@373 != null
            * 
            *  Test Vectors:
            *    java.lang.String:equals(...)@370: {1}, {0}
            *    java.lang.String:indexOf(...)@350: {-231..-1}, {0..232-1}
            *    java.lang.String:indexOf(...)@358: {-231..-1}, {0..232-1}
            *    net.sourceforge.pebble.domain.Blog:getCategory(...)@373: Addr_Set{null}, Inverse{null}
            */
   346    private void populateEntry(BlogEntry entry, String content, String username) {
   347      String title = "";
   348      String category = "";
   349  
   350      if (content.indexOf(TITLE_START_DELIMITER) > -1 && content.indexOf(TITLE_END_DELIMITER) > -1) {
   351        content = content.substring(TITLE_START_DELIMITER.length());
   352        int index = content.indexOf(TITLE_END_DELIMITER);
   353        title = content.substring(0, index);
   354        content = content.substring(index);
   355        content = content.substring(TITLE_END_DELIMITER.length());
   356      }
   357  
   358      if (content.indexOf(CATEGORY_START_DELIMITER) > -1 && content.indexOf(CATEGORY_END_DELIMITER) > -1) {
   359        content = content.substring(CATEGORY_START_DELIMITER.length());
   360        int index = content.indexOf(CATEGORY_END_DELIMITER);
   361        category = content.substring(0, index);
   362        content = content.substring(index);
   363        content = content.substring(CATEGORY_END_DELIMITER.length());
   364      }
   365  
   366      entry.setTitle(title);
   367      entry.setBody(content);
   368      entry.setAuthor(username);
   369  
+  370      if (category != null && !category.trim().equals("")) {
   371        String[] categories = category.split(",");
   372        for (int i = 0; i < categories.length; i++) {
   373          Category c = entry.getBlog().getCategory(categories[i].trim());
   374           if (c != null) {
   375             entry.addCategory(c);
   376           }
   377        }
   378      }
   379    }
   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     */
           /* 
    P/P     *  Method: String getTemplate(String, String, String, String, String)
            *    getTemplate fails for all possible inputs
            */
   392    public String getTemplate(String appkey, String blogid, String username, String password, String templateType) throws XmlRpcException {
+  393      log.debug("BloggerAPI.getTemplate(" +
   394          appkey + ", " +
   395          blogid + ", " +
   396          username + ", " +
   397          "********, " +
   398          templateType + ")");
   399  
   400      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     */
           /* 
    P/P     *  Method: bool setTemplate(String, String, String, String, String, String)
            *    setTemplate fails for all possible inputs
            */
   415    public boolean setTemplate(String appkey, String blogid, String username, String password, String template, String templateType) throws XmlRpcException {
+  416      log.debug("BloggerAPI.setTemplate(" +
   417          appkey + ", " +
   418          blogid + ", " +
   419          username + ", " +
   420          "********, " +
   421          template + ", " +
   422          templateType + ")");
   423  
   424      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     */
           /* 
    P/P     *  Method: bool addCategory(String, String, String, String, String)
            * 
            *  Preconditions:
            *    log != null
            *    postid != null
            *    this.authenticationManager != null
            * 
            *  Presumptions:
            *    net.sourceforge.pebble.domain.BlogEntry:getBlog(...)@454 != null
            *    net.sourceforge.pebble.domain.BlogService:getBlogEntry(...)@451 != null
            * 
            *  Postconditions:
            *    init'ed(return_value)
            * 
            *  Test Vectors:
            *    net.sourceforge.pebble.domain.Blog:getCategory(...)@454: Addr_Set{null}, Inverse{null}
            */
   438    public boolean addCategory(String appkey, String postid, String username, String password, String category) throws XmlRpcException {
   439      log.debug("BloggerAPI.addCategory(" +
   440          appkey + ", " +
   441          postid + ", " +
   442          username + ", " +
   443          "********, " +
   444          category + ")");
   445  
   446      try {
   447        Blog blog = getBlogWithPostId(postid);
   448        postid = getPostId(postid);
   449        authenticate(blog, username, password);
   450        BlogService service = new BlogService();
   451        BlogEntry entry = service.getBlogEntry(blog, postid);
   452  
   453        if (entry != null) {
   454          Category c = entry.getBlog().getCategory(category);
   455          if (c != null) {
   456            entry.addCategory(c);
   457            service.putBlogEntry(entry);
   458  
   459            return true;
   460          }
   461        } else {
   462          throw new XmlRpcException(0, "Blog entry with ID of " + postid + " was not found.");
   463        }
   464  
   465        return false;
   466      } catch (BlogServiceException be) {
   467        throw new XmlRpcException(0, be.getMessage());
   468      }
   469    }
   470  
   471  }








SofCheck Inspector Build Version : 2.22510
bloggerapihandler.java 2010-Jun-25 19:40:32
bloggerapihandler.class 2010-Jul-19 20:23:38