File Source: SearchResultsFeedModel.java

     1  /*
     2   * Licensed to the Apache Software Foundation (ASF) under one or more
     3   *  contributor license agreements.  The ASF licenses this file to You
     4   * under the Apache License, Version 2.0 (the "License"); you may not
     5   * use this file except in compliance with the License.
     6   * You may obtain a copy of the License at
     7   *
     8   *     http://www.apache.org/licenses/LICENSE-2.0
     9   *
    10   * Unless required by applicable law or agreed to in writing, software
    11   * distributed under the License is distributed on an "AS IS" BASIS,
    12   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    13   * See the License for the specific language governing permissions and
    14   * limitations under the License.  For additional information regarding
    15   * copyright in this work, please see the NOTICE file in the top level
    16   * directory of this distribution.
    17   */
    18  
    19  package org.apache.roller.weblogger.ui.rendering.model;
    20  
    21  import java.io.IOException;
    22  import java.sql.Timestamp;
    23  import java.util.Date;
    24  import java.util.LinkedList;
    25  import java.util.List;
    26  import java.util.Map;
    27  import java.util.Set;
    28  import java.util.TreeSet;
    29  
    30  import org.apache.commons.lang.StringUtils;
    31  import org.apache.commons.logging.Log;
    32  import org.apache.commons.logging.LogFactory;
    33  import org.apache.lucene.document.Document;
    34  import org.apache.lucene.search.Hits;
    35  import org.apache.roller.weblogger.WebloggerException;
    36  import org.apache.roller.weblogger.business.URLStrategy;
    37  import org.apache.roller.weblogger.business.Weblogger;
    38  import org.apache.roller.weblogger.business.WebloggerFactory;
    39  import org.apache.roller.weblogger.business.WeblogManager;
    40  import org.apache.roller.weblogger.business.search.FieldConstants;
    41  import org.apache.roller.weblogger.business.search.IndexManager;
    42  import org.apache.roller.weblogger.business.search.operations.SearchOperation;
    43  import org.apache.roller.weblogger.config.WebloggerRuntimeConfig;
    44  import org.apache.roller.weblogger.pojos.WeblogEntry;
    45  import org.apache.roller.weblogger.pojos.Weblog;
    46  import org.apache.roller.weblogger.pojos.wrapper.WeblogCategoryWrapper;
    47  import org.apache.roller.weblogger.pojos.wrapper.WeblogEntryWrapper;
    48  import org.apache.roller.weblogger.pojos.wrapper.WeblogWrapper;
    49  import org.apache.roller.weblogger.ui.rendering.pagers.Pager;
    50  import org.apache.roller.weblogger.ui.rendering.pagers.SearchResultsFeedPager;
    51  import org.apache.roller.weblogger.ui.rendering.util.WeblogFeedRequest;
    52  import org.apache.roller.weblogger.ui.rendering.util.WeblogRequest;
    53  
    54  
    55  /**
    56   * Extends normal page renderer model to represent search results for Atom feeds.
    57   *
    58   * Also adds some new methods which are specific only to search results.
    59   */
         /* 
    P/P   *  Method: void org.apache.roller.weblogger.ui.rendering.model.SearchResultsFeedModel()
          * 
          *  Postconditions:
          *    this.categories == &new TreeSet(SearchResultsFeedModel#2)
          *    this.entryCount == 0
          *    this.hits == 0
          *    this.limit == 0
          *    this.offset == 0
          *    this.feedRequest == null
          *    this.pager == null
          *    this.urlStrategy == null
          *    this.weblog == null
          *    this.results == &new LinkedList(SearchResultsFeedModel#1)
          *    ...
          */
    60  public class SearchResultsFeedModel implements Model {
    61  
             /* 
    P/P       *  Method: org.apache.roller.weblogger.ui.rendering.model.SearchResultsFeedModel__static_init
              * 
              *  Postconditions:
              *    init'ed(log)
              */
    62      private static Log log = LogFactory.getLog(SearchResultsFeedModel.class);
    63      
    64      private WeblogFeedRequest feedRequest = null;
    65      private URLStrategy urlStrategy = null;
    66      private Weblog weblog = null;
    67          
    68      // the pager used by the 3.0+ rendering system
    69      private SearchResultsFeedPager pager = null;
    70      
    71      private List results = new LinkedList();
    72      
    73      private Set categories = new TreeSet();
    74  
    75      private boolean websiteSpecificSearch = true;
    76  
    77      private int hits = 0;
    78      private int offset = 0;
    79      private int limit = 0;
    80      
    81      private int entryCount = 0;
    82  
    83  
    84      public String getModelName() {
                 /* 
    P/P           *  Method: String getModelName()
                  * 
                  *  Postconditions:
                  *    return_value == &"model"
                  */
    85          return "model";
    86      }
    87  
    88      
    89      public void init(Map initData) throws WebloggerException {
    90          
    91          // we expect the init data to contain a weblogRequest object
                 /* 
    P/P           *  Method: void init(Map)
                  * 
                  *  Preconditions:
                  *    initData != null
                  *    org/apache/roller/weblogger/util/I18nMessages.messagesMap != null
                  *    (soft) init'ed(this.hits)
                  *    (soft) init'ed(this.limit)
                  *    (soft) init'ed(this.offset)
                  *    (soft) init'ed(this.websiteSpecificSearch)
                  *    (soft) this.results != null
                  * 
                  *  Presumptions:
                  *    java.util.Map:get(...)@92 != null
                  *    org.apache.roller.weblogger.business.Weblogger:getIndexManager(...)@128 != null
                  *    org.apache.roller.weblogger.business.Weblogger:getUrlStrategy(...)@107 != null
                  *    org.apache.roller.weblogger.business.WebloggerFactory:getWeblogger(...)@107 != null
                  *    org.apache.roller.weblogger.business.WebloggerFactory:getWeblogger(...)@128 != null
                  *    ...
                  * 
                  *  Postconditions:
                  *    this.categories == One-of{old this.categories, &new TreeSet(convertHitsToEntries#1)}
                  *    possibly_updated(this.entryCount)
                  *    (soft) this.feedRequest != null
                  *    (soft) init'ed(this.hits)
                  *    (soft) init'ed(this.limit)
                  *    (soft) init'ed(this.offset)
                  *    this.pager in Addr_Set{&new SearchResultsFeedPager(init#3),&new SearchResultsFeedPager(init#1)}
                  *    this.urlStrategy != null
                  *    init'ed(this.weblog)
                  *    (soft) init'ed(this.websiteSpecificSearch)
                  *    ...
                  * 
                  *  Test Vectors:
                  *    java.util.Map:get(...)@105: Inverse{null}, Addr_Set{null}
                  *    org.apache.commons.lang.StringUtils:isNotEmpty(...)@139: {0}, {1}
                  *    org.apache.roller.weblogger.business.search.operations.SearchOperation:getResultsCount(...)@146: {-231..-1}, {0..232-1}
                  *    org.apache.roller.weblogger.config.WebloggerRuntimeConfig:isSiteWideWeblog(...)@133: {0}, {1}
                  *    org.apache.roller.weblogger.ui.rendering.util.WeblogFeedRequest:getTerm(...)@119: Inverse{null}, Addr_Set{null}
                  */
    92          WeblogRequest weblogRequest = (WeblogRequest) initData.get("parsedRequest");
    93          if(weblogRequest == null) {
    94              throw new WebloggerException("expected weblogRequest from init data");
    95          }
    96          
    97          if(weblogRequest instanceof WeblogFeedRequest) {
    98              this.feedRequest = (WeblogFeedRequest) weblogRequest;
    99          } else {
   100              throw new WebloggerException("weblogRequest is not a WeblogFeedRequest."+
   101                      "  FeedModel only supports feed requests.");
   102          }
   103          
   104          // look for url strategy
   105          urlStrategy = (URLStrategy) initData.get("urlStrategy");
   106          if(urlStrategy == null) {
   107              urlStrategy = WebloggerFactory.getWeblogger().getUrlStrategy();
   108          }
   109          
   110          // extract weblog object
   111          weblog = feedRequest.getWeblog();
   112          
   113          String  pagerUrl = urlStrategy.getWeblogFeedURL(weblog, 
   114                  feedRequest.getLocale(), feedRequest.getType(),
   115                  feedRequest.getFormat(), null, null, /* cat and term are null but added to the url in the pager */
   116                  null, false, true);
   117          
   118          // if there is no query, then we are done
   119          if(feedRequest.getTerm() == null) {
   120              pager = new SearchResultsFeedPager(urlStrategy, pagerUrl, feedRequest.getPage(),
   121                      feedRequest, results, false);
   122              return;
   123          }
   124          
   125          this.entryCount = WebloggerRuntimeConfig.getIntProperty("site.newsfeeds.defaultEntries");
   126          
   127          // setup the search
   128          IndexManager indexMgr = WebloggerFactory.getWeblogger().getIndexManager();
   129          
   130          SearchOperation search = new SearchOperation(indexMgr);
   131          search.setTerm(feedRequest.getTerm());
   132          
   133          if(WebloggerRuntimeConfig.isSiteWideWeblog(feedRequest.getWeblogHandle())) {
   134              this.websiteSpecificSearch  = false;
   135          } else {
   136              search.setWebsiteHandle(feedRequest.getWeblogHandle());
   137          }
   138          
   139          if(StringUtils.isNotEmpty(feedRequest.getWeblogCategoryName())) {
   140              search.setCategory(feedRequest.getWeblogCategoryName());
   141          }
   142          
   143          // execute search
   144          indexMgr.executeIndexOperationNow(search);
   145          
   146          if (search.getResultsCount() > -1) {
   147              Hits hits = search.getResults();
   148              this.hits = search.getResultsCount();
   149              
   150              // Convert the Hits into WeblogEntryData instances.
   151              convertHitsToEntries(hits);
   152          }
   153          
   154          // search completed, setup pager based on results
   155          pager = new SearchResultsFeedPager(urlStrategy, pagerUrl, feedRequest.getPage(),
   156                  feedRequest, results, (hits > (offset+limit)));
   157      }
   158      
   159      public Pager getSearchResultsPager() {
                 /* 
    P/P           *  Method: Pager getSearchResultsPager()
                  * 
                  *  Preconditions:
                  *    init'ed(this.pager)
                  * 
                  *  Postconditions:
                  *    return_value == this.pager
                  *    init'ed(return_value)
                  */
   160          return pager;
   161      }
   162      
   163      private void convertHitsToEntries(Hits hits) throws WebloggerException {
   164          
   165          // determine offset
                 /* 
    P/P           *  Method: void convertHitsToEntries(Hits)
                  * 
                  *  Preconditions:
                  *    hits != null
                  *    init'ed(this.entryCount)
                  *    this.feedRequest != null
                  *    (soft) this.results != null
                  *    (soft) init'ed(this.websiteSpecificSearch)
                  * 
                  *  Presumptions:
                  *    org.apache.lucene.document.Document:getField(...)@191 != null
                  *    org.apache.lucene.document.Document:getField(...)@196 != null
                  *    org.apache.lucene.document.Document:getField(...)@200 != null
                  *    org.apache.lucene.document.Document:getField(...)@204 != null
                  *    org.apache.lucene.document.Field:stringValue(...)@191 != null
                  *    ...
                  * 
                  *  Postconditions:
                  *    this.categories == One-of{old this.categories, &new TreeSet(convertHitsToEntries#1)}
                  *    init'ed(this.limit)
                  *    this.offset <= 232-2
                  *    new TreeSet(convertHitsToEntries#1) num objects == 1
                  *    this.offset + this.limit in -232..232-1
                  * 
                  *  Test Vectors:
                  *    this.websiteSpecificSearch: {0}, {1}
                  *    java.lang.String:equals(...)@193: {0}, {1}
                  *    java.sql.Timestamp:before(...)@212: {0}, {1}
                  *    java.util.TreeSet:size(...)@217: {-231..0}, {1..232-1}
                  *    org.apache.lucene.document.Document:getField(...)@203: Addr_Set{null}, Inverse{null}
                  */
   166          this.offset = feedRequest.getPage() * this.entryCount;
   167          if(this.offset >= hits.length()) {
   168              this.offset = 0;
   169          }
   170          
   171          // determine limit
   172          this.limit = this.entryCount;
   173          if(this.offset + this.limit > hits.length()) {
   174              this.limit = hits.length() - this.offset;
   175          }
   176          
   177          try {
   178              TreeSet categories = new TreeSet();
   179              Weblogger roller = WebloggerFactory.getWeblogger();
   180              WeblogManager weblogMgr = roller.getWeblogManager();
   181              
   182              WeblogEntry entry = null;
   183              Document doc = null;
   184              String handle = null;
   185              Timestamp now = new Timestamp(new Date().getTime());
   186              for(int i = offset; i < offset+limit; i++) {
   187                  
   188                  entry = null; // reset for each iteration
   189                  
   190                  doc = hits.doc(i);
   191                  handle = doc.getField(FieldConstants.WEBSITE_HANDLE).stringValue();
   192                  
   193                  if(websiteSpecificSearch &&
   194                          handle.equals(feedRequest.getWeblogHandle())) {
   195                      
   196                      entry = weblogMgr.getWeblogEntry(
   197                              doc.getField(FieldConstants.ID).stringValue());
   198                  } else {
   199                      
   200                      entry = weblogMgr.getWeblogEntry(
   201                              doc.getField(FieldConstants.ID).stringValue());
   202                      
   203                      if (doc.getField(FieldConstants.CATEGORY) != null) {
   204                          categories.add(
   205                                  doc.getField(FieldConstants.CATEGORY).stringValue());
   206                      }
   207                  }
   208                  
   209                  // maybe null if search result returned inactive user
   210                  // or entry's user is not the requested user.
   211                  // but don't return future posts
   212                  if (entry != null && entry.getPubTime().before(now)) {
   213                      results.add(WeblogEntryWrapper.wrap(entry, urlStrategy));
   214                  }
   215              }
   216              
   217              if(categories.size() > 0) {
   218                  this.categories = categories;
   219              }
   220          } catch(IOException e) {
   221              throw new WebloggerException(e);
   222          }
   223      }
   224      
   225      /**
   226       * Get weblog being displayed.
   227       */
   228      public WeblogWrapper getWeblog() {
                 /* 
    P/P           *  Method: WeblogWrapper getWeblog()
                  * 
                  *  Preconditions:
                  *    init'ed(this.urlStrategy)
                  *    this.weblog != null
                  * 
                  *  Postconditions:
                  *    return_value == &new WeblogWrapper(wrap#1)
                  *    new WeblogWrapper(wrap#1) num objects == 1
                  *    new WeblogWrapper(wrap#1).pojo == this.weblog
                  *    new WeblogWrapper(wrap#1).pojo != null
                  *    new WeblogWrapper(wrap#1).urlStrategy == this.urlStrategy
                  *    init'ed(new WeblogWrapper(wrap#1).urlStrategy)
                  */
   229          return WeblogWrapper.wrap(weblog, urlStrategy);
   230      }
   231      
   232      public String getTerm() {
                 /* 
    P/P           *  Method: String getTerm()
                  * 
                  *  Preconditions:
                  *    this.feedRequest != null
                  * 
                  *  Postconditions:
                  *    init'ed(return_value)
                  */
   233          return (feedRequest.getTerm() == null) ? "" : feedRequest.getTerm();
   234      }
   235  
   236      public int getHits() {
                 /* 
    P/P           *  Method: int getHits()
                  * 
                  *  Preconditions:
                  *    init'ed(this.hits)
                  * 
                  *  Postconditions:
                  *    return_value == this.hits
                  *    init'ed(return_value)
                  */
   237          return hits;
   238      }
   239  
   240      public int getOffset() {
                 /* 
    P/P           *  Method: int getOffset()
                  * 
                  *  Preconditions:
                  *    init'ed(this.offset)
                  * 
                  *  Postconditions:
                  *    return_value == this.offset
                  *    init'ed(return_value)
                  */
   241          return offset;
   242      }
   243      
   244      public int getPage() {
                 /* 
    P/P           *  Method: int getPage()
                  * 
                  *  Preconditions:
                  *    this.feedRequest != null
                  * 
                  *  Postconditions:
                  *    init'ed(return_value)
                  */
   245          return feedRequest.getPage();
   246      }
   247  
   248      public int getLimit() {
                 /* 
    P/P           *  Method: int getLimit()
                  * 
                  *  Preconditions:
                  *    init'ed(this.limit)
                  * 
                  *  Postconditions:
                  *    return_value == this.limit
                  *    init'ed(return_value)
                  */
   249          return limit;
   250      }
   251  
   252      public List getResults() {
                 /* 
    P/P           *  Method: List getResults()
                  * 
                  *  Preconditions:
                  *    init'ed(this.results)
                  * 
                  *  Postconditions:
                  *    return_value == this.results
                  *    init'ed(return_value)
                  */
   253          return results;
   254      }
   255  
   256      public Set getCategories() {
                 /* 
    P/P           *  Method: Set getCategories()
                  * 
                  *  Preconditions:
                  *    init'ed(this.categories)
                  * 
                  *  Postconditions:
                  *    return_value == this.categories
                  *    init'ed(return_value)
                  */
   257          return categories;
   258      }
   259  
   260      public boolean isWebsiteSpecificSearch() {
                 /* 
    P/P           *  Method: bool isWebsiteSpecificSearch()
                  * 
                  *  Preconditions:
                  *    init'ed(this.websiteSpecificSearch)
                  * 
                  *  Postconditions:
                  *    return_value == this.websiteSpecificSearch
                  *    init'ed(return_value)
                  */
   261          return websiteSpecificSearch;
   262      }   
   263      
   264      public String getCategoryPath() {
                 /* 
    P/P           *  Method: String getCategoryPath()
                  * 
                  *  Preconditions:
                  *    this.feedRequest != null
                  * 
                  *  Postconditions:
                  *    init'ed(return_value)
                  */
   265          return feedRequest.getWeblogCategoryName();
   266      }
   267      
   268      public WeblogCategoryWrapper getWeblogCategory() {
                 /* 
    P/P           *  Method: WeblogCategoryWrapper getWeblogCategory()
                  * 
                  *  Preconditions:
                  *    this.feedRequest != null
                  * 
                  *  Postconditions:
                  *    return_value == One-of{&new WeblogCategoryWrapper(wrap#1), null}
                  *    return_value in Addr_Set{null,&new WeblogCategoryWrapper(wrap#1)}
                  *    new WeblogCategoryWrapper(wrap#1) num objects <= 1
                  *    new WeblogCategoryWrapper(wrap#1).pojo != null
                  *    new WeblogCategoryWrapper(wrap#1).urlStrategy == this.urlStrategy
                  *    init'ed(new WeblogCategoryWrapper(wrap#1).urlStrategy)
                  * 
                  *  Test Vectors:
                  *    org.apache.roller.weblogger.ui.rendering.util.WeblogFeedRequest:getWeblogCategory(...)@269: Addr_Set{null}, Inverse{null}
                  */
   269          if(feedRequest.getWeblogCategory() != null) {
   270              return WeblogCategoryWrapper.wrap(feedRequest.getWeblogCategory(), urlStrategy);
   271          }
   272          return null;
   273      }    
   274  }








SofCheck Inspector Build Version : 2.18479
SearchResultsFeedModel.java 2009-Jan-02 14:25:28
SearchResultsFeedModel.class 2009-Sep-04 03:12:44