File Source: searchapihandler.java

     1  
     2  package net.sourceforge.pebble.webservice;
     3  
     4  import java.util.Hashtable;
     5  import java.util.Iterator;
     6  import java.util.List;
     7  import java.util.Map;
     8  import java.util.Vector;
     9  
    10  import net.sourceforge.pebble.domain.Blog;
    11  import net.sourceforge.pebble.domain.BlogEntry;
    12  import net.sourceforge.pebble.domain.BlogService;
    13  import net.sourceforge.pebble.domain.Category;
    14  import net.sourceforge.pebble.search.SearchHit;
    15  import net.sourceforge.pebble.search.SearchResults;
    16  import net.sourceforge.pebble.util.Pageable;
    17  
    18  import org.apache.commons.logging.Log;
    19  import org.apache.commons.logging.LogFactory;
    20  
    21  
    22  /**
    23   * Extension to allow search and query of Blog posting via XML-RPC.
    24   *
    25   * @author tcp@favoritemedium.com
    26   */
         /* 
    P/P   *  Method: void net.sourceforge.pebble.webservice.SearchAPIHandler()
          */
    27  public class SearchAPIHandler extends AbstractAPIHandler {
    28  
    29      static final String URL = "url";
    30      static final String BLOG_ID = "blogid";
    31      static final String BLOG_NAME = "blogName";
    32      static final String DATE_CREATED = "dateCreated";
    33      static final String USER_ID = "userId";
    34      static final String POST_ID = "postid";
    35      static final String CONTENT = "content";
    36  
    37      static final String TITLE_START_DELIMITER = "<title>";
    38      static final String TITLE_END_DELIMITER = "</title>";
    39      static final String CATEGORY_START_DELIMITER = "<category>";
    40      static final String CATEGORY_END_DELIMITER = "</category>";
    41      static final char BLOG_ID_SEPARATOR = '/';
    42  
    43      static final int PAGE_SIZE = 20;
    44  
    45  
    46      /** the log used by this class */
             /* 
    P/P       *  Method: net.sourceforge.pebble.webservice.SearchAPIHandler__static_init
              * 
              *  Postconditions:
              *    init'ed(log)
              */
    47      private static Log log = LogFactory.getLog(SearchAPIHandler.class);
    48  
    49  
    50      /**
    51       * Search blog for specific string.
    52       * 
    53       * @param blogid    the ID of the blog (ignored)
    54       * @param username  the username used for logging in via XML-RPC
    55       * @param password  the password used for logging in via XML-RPC
    56       */
    57      public Vector search(String blogid, String username, String password, 
    58                          String searchString, String sortBy) {
    59          log.debug("search.search(" +
    60              blogid + ", " +
    61              username + ", xxxxxx, \"" +
    62              searchString + "," + 
    63              sortBy + "\")");
    64  
    65          Vector posts = new Vector();
    66          try {
    67  
                     /* 
    P/P               *  Method: Vector search(String, String, String, String, String)
                      * 
                      *  Preconditions:
                      *    log != null
                      * 
                      *  Presumptions:
                      *    java.util.Iterator:next(...)@80 != null
                      *    net.sourceforge.pebble.domain.Blog:getSearchIndex(...)@69 != null
                      *    net.sourceforge.pebble.domain.BlogService:getBlogEntry(...)@81 != null
                      *    net.sourceforge.pebble.index.SearchIndex:search(...)@69 != null
                      *    net.sourceforge.pebble.search.SearchResults:getHits(...)@77 != null
                      * 
                      *  Postconditions:
                      *    return_value == &new Vector(search#2)
                      *    new Vector(search#2) num objects == 1
                      * 
                      *  Test Vectors:
                      *    sortBy: Addr_Set{null}, Inverse{null}
                      *    java.lang.String:equalsIgnoreCase(...)@71: {0}, {1}
                      *    java.util.Iterator:hasNext(...)@80: {1}, {0}
                      */
    68              Blog blog = getBlogWithBlogId(blogid);
    69              SearchResults result = blog.getSearchIndex().search( searchString );
    70  
    71              if ( sortBy != null && sortBy.equalsIgnoreCase("date") ) {
    72                  result.sortByDateDescending();
    73              } else {
    74                  result.sortByScoreDescending();
    75              }
    76  
    77              List<SearchHit> hits = result.getHits();
    78              BlogService service = new BlogService();
    79  
    80              for (SearchHit hit : hits) {
    81                  BlogEntry entry = service.getBlogEntry(hit.getBlog(), hit.getId());
    82                  adaptBlogEntry(entry);
    83                  posts.add(adaptBlogEntry(entry));
    84              }
    85              posts.add( searchResultSummary(hits, sortBy, searchString, 0, 0) );
    86  
    87          } catch (Exception ex) {
    88              log.error(ex);
    89          }
    90          return posts;
    91      }
    92  
    93      /**
    94       * Search blog for specific string with pagable parameters
    95       * 
    96       * @param blogid    the ID of the blog (ignored)
    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       */
   100      public Vector search(String blogid, String username, String password, 
   101                          String searchString, String sortBy, int pageSize, int offset) {
   102          log.debug("search.search(" +
   103              blogid + ", " +
   104              username + ", xxxxxx, \"" +
   105              searchString + "," + 
   106              sortBy + "\")");
   107  
   108  
   109          Vector posts = new Vector();
   110          try {
   111  
                     /* 
    P/P               *  Method: Vector search(String, String, String, String, String, int, int)
                      * 
                      *  Preconditions:
                      *    log != null
                      * 
                      *  Presumptions:
                      *    java.util.Iterator:next(...)@132 != null
                      *    net.sourceforge.pebble.domain.Blog:getSearchIndex(...)@113 != null
                      *    net.sourceforge.pebble.domain.BlogService:getBlogEntry(...)@133 != null
                      *    net.sourceforge.pebble.index.SearchIndex:search(...)@113 != null
                      *    net.sourceforge.pebble.util.Pageable:getListForPage(...)@128 != null
                      * 
                      *  Postconditions:
                      *    return_value == &new Vector(search#2)
                      *    new Vector(search#2) num objects == 1
                      * 
                      *  Test Vectors:
                      *    pageSize: {1..232-1}, {-231..0}
                      *    sortBy: Addr_Set{null}, Inverse{null}
                      *    java.lang.String:equalsIgnoreCase(...)@115: {0}, {1}
                      *    java.util.Iterator:hasNext(...)@132: {1}, {0}
                      */
   112              Blog blog = getBlogWithBlogId(blogid);
   113              SearchResults result = blog.getSearchIndex().search( searchString );
   114              
   115              if ( sortBy != null && sortBy.equalsIgnoreCase("date") ) {
   116                  result.sortByDateDescending();
   117              } else {
   118                  result.sortByScoreDescending();
   119              }
   120  
   121              if ( pageSize <= 0 ) 
   122                  pageSize = PAGE_SIZE;
   123  
   124              List<SearchHit> hits = result.getHits();
   125              Pageable pageable = new Pageable(hits);
   126              pageable.setPageSize(pageSize);
   127              pageable.setPage(offset);
   128              List<SearchHit> subList = pageable.getListForPage();
   129  
   130              BlogService service = new BlogService();
   131  
   132              for (SearchHit hit : subList ) {
   133                  BlogEntry entry = service.getBlogEntry(hit.getBlog(), hit.getId());
   134                  adaptBlogEntry(entry);
   135                  posts.add(adaptBlogEntry(entry));
   136              }
   137              posts.add( searchResultSummary(subList, sortBy, searchString, pageSize, offset) );
   138  
   139          } catch (Exception ex) {
   140              log.error(ex);
   141          }
   142          return posts;
   143      }
   144  
   145      /**
   146       * Helper method to adapt a blog entry into an XML-RPC compatible struct.
   147       * Since the Blogger API doesn't support titles, the title is wrapped in
   148       * <title></title> tags.
   149       *
   150       * @param entry   the BlogEntry to adapt
   151       * @return  a Hashtable representing the major properties of the entry
   152       */
   153      private Hashtable adaptBlogEntry(BlogEntry entry) {
                 /* 
    P/P           *  Method: Hashtable adaptBlogEntry(BlogEntry)
                  * 
                  *  Preconditions:
                  *    entry != null
                  * 
                  *  Presumptions:
                  *    java.util.Iterator:next(...)@158 != null
                  *    net.sourceforge.pebble.domain.BlogEntry:getBlog(...)@166 != null
                  *    net.sourceforge.pebble.domain.BlogEntry:getCategories(...)@156 != null
                  * 
                  *  Postconditions:
                  *    return_value == &new Hashtable(adaptBlogEntry#1)
                  *    new Hashtable(adaptBlogEntry#1) num objects == 1
                  * 
                  *  Test Vectors:
                  *    java.util.Iterator:hasNext(...)@157: {1}, {0}
                  *    java.util.Iterator:hasNext(...)@160: {0}, {1}
                  */
   154          Hashtable post = new Hashtable();
   155          String categories = "";
   156          Iterator it = entry.getCategories().iterator();
   157          while (it.hasNext()) {
   158              Category category = (Category)it.next();
   159              categories += category.getId();
   160              if (it.hasNext()) {
   161                  categories += ",";
   162              }
   163          }
   164          post.put(DATE_CREATED, entry.getDate());
   165          post.put(USER_ID, entry.getAuthor());
   166          post.put(POST_ID, formatPostId(entry.getBlog().getId(), entry.getId()));
   167          post.put(CONTENT, TITLE_START_DELIMITER + entry.getTitle() + TITLE_END_DELIMITER
   168                  + CATEGORY_START_DELIMITER + categories + CATEGORY_END_DELIMITER + entry.getBody());
   169  
   170          return post;
   171      }
   172  
   173      /**
   174       * Auto create a Map of search result summary.
   175       * @param result of the search hits.
   176       */
   177      private Map searchResultSummary(List<SearchHit> result, String sortBy,
   178                                          String query, int pageIndex, int offset) {
                 /* 
    P/P           *  Method: Map searchResultSummary(List, String, String, int, int)
                  * 
                  *  Preconditions:
                  *    result != null
                  * 
                  *  Postconditions:
                  *    return_value == &new Hashtable(searchResultSummary#1)
                  *    new Hashtable(searchResultSummary#1) num objects == 1
                  */
   179          Map data = new Hashtable();
   180          data.put("size", result.size() );
   181          data.put("sortBy", sortBy);
   182          data.put("index", pageIndex);
   183          data.put("offset", offset);
   184          data.put("query", query);
   185  
   186          return data;
   187      }
   188  
   189  }








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