package com.multysite.search;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.logging.Logger;
import javax.cache.Cache;
import javax.cache.CacheException;
import javax.cache.CacheManager;
import com.google.appengine.api.search.GetRequest;
import com.google.appengine.api.search.Index;
import com.google.appengine.api.search.IndexSpec;
import com.google.appengine.api.search.Query;
import com.google.appengine.api.search.QueryOptions;
import com.google.appengine.api.search.Results;
import com.google.appengine.api.search.ScoredDocument;
import com.google.appengine.api.search.SearchServiceFactory;
import com.google.appengine.api.search.SortExpression;
import com.google.appengine.api.search.SortOptions;
import com.multysite.entity.News;
public class NewsSearchModel {
private static Index INDEX = SearchServiceFactory.getSearchService()
.getIndex(IndexSpec.newBuilder().setName("news"));
private static final Logger log = Logger.getLogger(NewsSearchModel.class
.getName());
private int limit = 10;
private int page = 1;
private int totalResult = 0;
private int totalReturn = 0;
private int totalPage = 1;
private static Cache cache = null;
private static String cachePrefix = "newsSearch_";
private static boolean isRegisted = false;
private List<News> listResult = new ArrayList<News>();
public int getTotalPage() {
totalPage = totalResult / limit;
if ((totalResult % limit) > 0) {
totalPage += 1;
}
return totalPage;
}
public int getLimit() {
return limit;
}
public void setLimit(int limit) {
this.limit = limit;
}
public boolean isHasNextPage() {
if (totalResult != 0) {
return totalResult > (page * limit);
} else {
return false;
}
}
public boolean isHasPreviousPage() {
return page > 1;
}
public int getTotalResult() {
return totalResult;
}
public int getTotalReturn() {
return totalReturn;
}
public int getPage() {
return page;
}
public void setPage(int page) {
this.page = page;
}
public List<News> getListResult() {
return listResult;
}
public void setListResult(List<News> listResult) {
this.listResult = listResult;
}
public static void initCache() {
if (!isRegisted) {
isRegisted = true;
try {
cache = CacheManager.getInstance().getCacheFactory()
.createCache(Collections.emptyMap());
} catch (CacheException e) {
log.warning(e.toString());
e.printStackTrace();
isRegisted = false;
}
}
}
@SuppressWarnings("unchecked")
public void search(String keyword) {
try {
String prefix = cachePrefix + "search_" + keyword + "_page_" + page;
String totalResultPrefix = cachePrefix + "search_" + keyword
+ "TotalResult";
String limitPrefix = cachePrefix + "search_" + keyword + "Limit";
boolean cached = false;
try {
listResult = (ArrayList<News>) cache.get(prefix);
totalResult = (Integer) cache.get(totalResultPrefix);
limit = (Integer) cache.get(limitPrefix);
if (listResult != null) {
cached = true;
}
} catch (Exception e) {
cached = false;
}
if (!cached) {
StringBuilder queryString = new StringBuilder();
if (keyword != null && !keyword.isEmpty()) {
queryString.append(keyword);
}
listResult = new ArrayList<News>();
QueryOptions options = QueryOptions.newBuilder()
.setNumberFoundAccuracy(1000).build();
Query query = Query.newBuilder().setOptions(options)
.build(queryString.toString());
Results<ScoredDocument> docResult = INDEX.search(query);
totalResult = (int) docResult.getNumberFound();
SortOptions sortOptions = SortOptions
.newBuilder()
.addSortExpression(
SortExpression
.newBuilder()
.setExpression("date")
.setDirection(
SortExpression.SortDirection.DESCENDING)
.setDefaultValueNumeric(1)).build();
options = QueryOptions.newBuilder().setSortOptions(sortOptions)
.setNumberFoundAccuracy(1000).setLimit(limit)
.setOffset(limit * (page - 1)).build();
query = Query.newBuilder().setOptions(options)
.build(queryString.toString());
docResult = INDEX.search(query);
totalReturn = (int) docResult.getNumberReturned();
if (docResult.getNumberFound() > 0) {
News obj = new News();
for (ScoredDocument scoredDocument : docResult) {
obj = NewsSearchEngine
.documentToObjectByReflection(scoredDocument);
listResult.add(obj);
}
}
}
} catch (Exception e) {
log.warning(e.toString());
e.printStackTrace();
listResult = new ArrayList<News>();
}
}
public void countTotal() {
GetRequest request = GetRequest.newBuilder()
.setReturningIdsOnly(true).build();
totalResult = (int) INDEX.getRange(request).getResults().size();
}
}