| /* |
| * Licensed to the Apache Software Foundation (ASF) under one or more |
| * contributor license agreements. The ASF licenses this file to You |
| * under the Apache License, Version 2.0 (the "License"); you may not |
| * use this file except in compliance with the License. |
| * You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, software |
| * distributed under the License is distributed on an "AS IS" BASIS, |
| * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| * See the License for the specific language governing permissions and |
| * limitations under the License. For additional information regarding |
| * copyright in this work, please see the NOTICE file in the top level |
| * directory of this distribution. |
| */ |
| |
| package org.apache.roller.weblogger.ui.rendering.model; |
| |
| import java.io.IOException; |
| import java.sql.Timestamp; |
| import java.util.Date; |
| import java.util.LinkedList; |
| import java.util.List; |
| import java.util.Map; |
| import java.util.Set; |
| import java.util.TreeSet; |
| import org.apache.commons.text.StringEscapeUtils; |
| |
| import org.apache.commons.lang3.StringUtils; |
| import org.apache.lucene.document.Document; |
| import org.apache.lucene.search.ScoreDoc; |
| import org.apache.lucene.search.TopFieldDocs; |
| import org.apache.roller.weblogger.WebloggerException; |
| import org.apache.roller.weblogger.business.URLStrategy; |
| import org.apache.roller.weblogger.business.WeblogEntryManager; |
| import org.apache.roller.weblogger.business.Weblogger; |
| import org.apache.roller.weblogger.business.WebloggerFactory; |
| import org.apache.roller.weblogger.business.search.FieldConstants; |
| import org.apache.roller.weblogger.business.search.IndexManager; |
| import org.apache.roller.weblogger.business.search.operations.SearchOperation; |
| import org.apache.roller.weblogger.config.WebloggerRuntimeConfig; |
| import org.apache.roller.weblogger.pojos.Weblog; |
| import org.apache.roller.weblogger.pojos.WeblogEntry; |
| import org.apache.roller.weblogger.pojos.wrapper.WeblogCategoryWrapper; |
| import org.apache.roller.weblogger.pojos.wrapper.WeblogEntryWrapper; |
| import org.apache.roller.weblogger.pojos.wrapper.WeblogWrapper; |
| import org.apache.roller.weblogger.ui.rendering.pagers.Pager; |
| import org.apache.roller.weblogger.ui.rendering.pagers.SearchResultsFeedPager; |
| import org.apache.roller.weblogger.ui.rendering.util.WeblogFeedRequest; |
| import org.apache.roller.weblogger.ui.rendering.util.WeblogRequest; |
| import org.apache.roller.weblogger.util.Utilities; |
| |
| /** |
| * Extends normal page renderer model to represent search results for Atom |
| * feeds. |
| * |
| * Also adds some new methods which are specific only to search results. |
| */ |
| public class SearchResultsFeedModel implements Model { |
| |
| private WeblogFeedRequest feedRequest = null; |
| private URLStrategy urlStrategy = null; |
| private Weblog weblog = null; |
| |
| // the pager used by the 3.0+ rendering system |
| private SearchResultsFeedPager pager = null; |
| |
| private List<WeblogEntryWrapper> results = new LinkedList<>(); |
| |
| private Set categories = new TreeSet(); |
| |
| private boolean websiteSpecificSearch = true; |
| |
| private int hits = 0; |
| private int offset = 0; |
| private int limit = 0; |
| |
| private int entryCount = 0; |
| |
| @Override |
| public String getModelName() { |
| return "model"; |
| } |
| |
| @Override |
| public void init(Map initData) throws WebloggerException { |
| |
| // we expect the init data to contain a weblogRequest object |
| WeblogRequest weblogRequest = (WeblogRequest) initData |
| .get("parsedRequest"); |
| if (weblogRequest == null) { |
| throw new WebloggerException( |
| "expected weblogRequest from init data"); |
| } |
| |
| if (weblogRequest instanceof WeblogFeedRequest) { |
| this.feedRequest = (WeblogFeedRequest) weblogRequest; |
| } else { |
| throw new WebloggerException( |
| "weblogRequest is not a WeblogFeedRequest." |
| + " FeedModel only supports feed requests."); |
| } |
| |
| // look for url strategy |
| urlStrategy = (URLStrategy) initData.get("urlStrategy"); |
| if (urlStrategy == null) { |
| urlStrategy = WebloggerFactory.getWeblogger().getUrlStrategy(); |
| } |
| |
| // extract weblog object |
| weblog = feedRequest.getWeblog(); |
| |
| String pagerUrl = urlStrategy.getWeblogFeedURL(weblog, |
| feedRequest.getLocale(), feedRequest.getType(), |
| // cat and term below null but added to URL in pager |
| feedRequest.getFormat(), null, null, |
| null, false, true); |
| |
| // if there is no query, then we are done |
| if (feedRequest.getTerm() == null) { |
| pager = new SearchResultsFeedPager(urlStrategy, pagerUrl, |
| feedRequest.getPage(), feedRequest, results, false); |
| return; |
| } |
| |
| this.entryCount = WebloggerRuntimeConfig |
| .getIntProperty("site.newsfeeds.defaultEntries"); |
| |
| // setup the search |
| IndexManager indexMgr = WebloggerFactory.getWeblogger() |
| .getIndexManager(); |
| |
| SearchOperation search = new SearchOperation(indexMgr); |
| search.setTerm(feedRequest.getTerm()); |
| |
| if (WebloggerRuntimeConfig.isSiteWideWeblog(feedRequest |
| .getWeblogHandle())) { |
| this.websiteSpecificSearch = false; |
| } else { |
| search.setWebsiteHandle(feedRequest.getWeblogHandle()); |
| } |
| |
| if (StringUtils.isNotEmpty(feedRequest.getWeblogCategoryName())) { |
| search.setCategory(feedRequest.getWeblogCategoryName()); |
| } |
| |
| // execute search |
| indexMgr.executeIndexOperationNow(search); |
| |
| if (search.getResultsCount() > -1) { |
| |
| TopFieldDocs docs = search.getResults(); |
| ScoreDoc[] hitsArr = docs.scoreDocs; |
| this.hits = search.getResultsCount(); |
| |
| // Convert the Hits into WeblogEntryData instances. |
| convertHitsToEntries(hitsArr, search); |
| } |
| |
| // search completed, setup pager based on results |
| pager = new SearchResultsFeedPager(urlStrategy, pagerUrl, |
| feedRequest.getPage(), feedRequest, results, |
| (hits > (offset + limit))); |
| } |
| |
| public Pager getSearchResultsPager() { |
| return pager; |
| } |
| |
| /** |
| * Convert hits to entries. |
| * |
| * @param hits |
| * the hits |
| * @param search |
| * the search |
| * @throws WebloggerException |
| * the weblogger exception |
| */ |
| private void convertHitsToEntries(ScoreDoc[] hits, SearchOperation search) |
| throws WebloggerException { |
| |
| // determine offset |
| this.offset = feedRequest.getPage() * this.entryCount; |
| if (this.offset >= hits.length) { |
| this.offset = 0; |
| } |
| |
| // determine limit |
| this.limit = this.entryCount; |
| if (this.offset + this.limit > hits.length) { |
| this.limit = hits.length - this.offset; |
| } |
| |
| try { |
| TreeSet<String> categorySet = new TreeSet<>(); |
| Weblogger roller = WebloggerFactory.getWeblogger(); |
| WeblogEntryManager weblogMgr = roller.getWeblogEntryManager(); |
| |
| WeblogEntry entry; |
| Document doc; |
| String handle; |
| Timestamp now = new Timestamp(new Date().getTime()); |
| for (int i = offset; i < offset + limit; i++) { |
| doc = search.getSearcher().doc(hits[i].doc); |
| handle = doc.getField(FieldConstants.WEBSITE_HANDLE) |
| .stringValue(); |
| |
| entry = weblogMgr.getWeblogEntry(doc.getField( |
| FieldConstants.ID).stringValue()); |
| |
| if (!(websiteSpecificSearch && handle.equals(feedRequest.getWeblogHandle())) |
| && doc.getField(FieldConstants.CATEGORY) != null) { |
| categorySet.add(doc.getField(FieldConstants.CATEGORY).stringValue()); |
| } |
| |
| // maybe null if search result returned inactive user |
| // or entry's user is not the requested user. |
| // but don't return future posts |
| if (entry != null && entry.getPubTime().before(now)) { |
| results.add(WeblogEntryWrapper.wrap(entry, urlStrategy)); |
| } |
| } |
| |
| if (!categorySet.isEmpty()) { |
| this.categories = categorySet; |
| } |
| } catch (IOException e) { |
| throw new WebloggerException(e); |
| } |
| } |
| |
| /** |
| * Get weblog being displayed. |
| */ |
| public WeblogWrapper getWeblog() { |
| return WeblogWrapper.wrap(weblog, urlStrategy); |
| } |
| |
| public String getTerm() { |
| String query =feedRequest.getTerm() ; |
| return (query == null) |
| ? "" : StringEscapeUtils.escapeXml11(Utilities.escapeHTML(query)); |
| } |
| |
| public int getHits() { |
| return hits; |
| } |
| |
| public int getOffset() { |
| return offset; |
| } |
| |
| public int getPage() { |
| return feedRequest.getPage(); |
| } |
| |
| public int getLimit() { |
| return limit; |
| } |
| |
| public List getResults() { |
| return results; |
| } |
| |
| public Set getCategories() { |
| return categories; |
| } |
| |
| public String getCategoryName() { |
| return feedRequest.getWeblogCategoryName(); |
| } |
| |
| public WeblogCategoryWrapper getWeblogCategory() { |
| if (feedRequest.getWeblogCategory() != null) { |
| return WeblogCategoryWrapper.wrap(feedRequest.getWeblogCategory(), |
| urlStrategy); |
| } |
| return null; |
| } |
| } |