package br.ufrgs.inf.dsmoura.repository.controller.search;
import java.io.Serializable;
import java.text.NumberFormat;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Collections;
import java.util.List;
import javax.faces.model.SelectItem;
import org.ajax4jsf.model.KeepAlive;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.solr.common.SolrDocumentList;
import br.ufrgs.inf.dsmoura.repository.controller.solr.SearchOrder;
import br.ufrgs.inf.dsmoura.repository.controller.solr.SolrConversionUtil;
import br.ufrgs.inf.dsmoura.repository.controller.solr.SolrServerUtil;
import br.ufrgs.inf.dsmoura.repository.controller.util.JSFUtil;
import br.ufrgs.inf.dsmoura.repository.model.dao.GenericDAO;
import br.ufrgs.inf.dsmoura.repository.model.dao.TypesDAO;
import br.ufrgs.inf.dsmoura.repository.model.entity.Asset;
import br.ufrgs.inf.dsmoura.repository.model.entity.AssetSolrDTO;
import br.ufrgs.inf.dsmoura.repository.model.entity.RelatedAsset;
import br.ufrgs.inf.dsmoura.repository.model.entity.UserQueryLogDTO;
@KeepAlive
public class SearchMB implements Serializable {
private static final long serialVersionUID = 1L;
private static final int NUMBER_ASSETS_LIST = 10;
final Log logger = LogFactory.getLog(getClass());
protected long searchTime;
/* pagination */
protected final Integer pageSize = 15;
protected Integer indexCurrentStart;
protected Long numFound;
protected Float maxScore;
protected SearchOrder searchOrder;
protected List<AssetSolrDTO> assetResultList = new ArrayList<AssetSolrDTO>();
private List<AssetSolrDTO> suggestedAssetsList;
private List<AssetSolrDTO> bestScoredAssetsList;
private List<AssetSolrDTO> mostReusedAssetsList;
private List<AssetSolrDTO> lastCertifiedAssetsList;
private List<AssetSolrDTO> lastPublishedAssetsList;
private Long publishedAssetsNumber;
{
reinitSearch();
}
protected void reinitSearch() {
this.indexCurrentStart = 0;
this.assetResultList = new ArrayList<AssetSolrDTO>();
this.searchOrder = SearchOrder.BY_RELEVANCE;
}
public List<SelectItem> getSearchOrderList() {
List<SelectItem> selectItemList = new ArrayList<SelectItem>();
selectItemList.add(new SelectItem(SearchOrder.BY_RELEVANCE));
selectItemList.add(new SelectItem(SearchOrder.BY_NAME));
selectItemList.add(new SelectItem(SearchOrder.BY_LAST_PUBLISHED));
selectItemList.add(new SelectItem(SearchOrder.BY_MOST_REUSED));
selectItemList.add(new SelectItem(SearchOrder.BY_BEST_RATED));
return selectItemList;
}
public List<AssetSolrDTO> searchAnotherVersions(Asset asset) {
Asset assetWithID = new Asset();
assetWithID.setId( asset.getId() );
List<AssetSolrDTO> anotherVersionsAssetList = advancedSearchQuery(assetWithID);
/* remove the same version */
for (int i = anotherVersionsAssetList.size()-1; i >= 0; i--) {
if (anotherVersionsAssetList.get(i).getVersion().equalsIgnoreCase(asset.getVersion())) {
anotherVersionsAssetList.remove(i);
}
}
Collections.sort(anotherVersionsAssetList);
return anotherVersionsAssetList;
}
public void searchSuggestedAssets(Asset asset, int rowsSize) {
String suggestedQuery = SolrConversionUtil.fromAssetToTextQuery(asset);
suggestedAssetsList = this.queryDismax(suggestedQuery, 0, rowsSize);
/* remove the same asset (id+version) */
for (int i = suggestedAssetsList.size()-1; i >= 0; i--) {
if ((asset.getAssetPk() != null) &&
(suggestedAssetsList.get(i).getAssetPk().equalsIgnoreCase(asset.getAssetPk().toString()))) {
suggestedAssetsList.remove(i);
logger.info("same asset pk was removed with pk: " + asset.getAssetPk() +
" and id: " + asset.getId() +
" and version: " + asset.getVersion());
break;
}
if ((suggestedAssetsList.get(i).getId().equalsIgnoreCase(asset.getId())) &&
(suggestedAssetsList.get(i).getVersion().equalsIgnoreCase(asset.getVersion()))) {
suggestedAssetsList.remove(i);
logger.info("same asset was removed with id: " + asset.getId() +
" and version: " + asset.getVersion());
break;
}
}
/* remove all suggested assets already inserted (id+version) */
for (int i = suggestedAssetsList.size()-1; i >= 0; i--) {
for (RelatedAsset relatedAsset : asset.getRelatedAssets()) {
if ((suggestedAssetsList.get(i).getId().equalsIgnoreCase(relatedAsset.getId())) &&
(suggestedAssetsList.get(i).getVersion().equalsIgnoreCase(relatedAsset.getVersion()))) {
suggestedAssetsList.remove(i);
logger.info("already inserted asset was removed with id: " + relatedAsset.getId() +
" and version: " + relatedAsset.getVersion());
break;
}
}
}
}
public void clearSuggestedAssetsList() {
suggestedAssetsList = new ArrayList<AssetSolrDTO>();
}
private List<AssetSolrDTO> advancedSearchQuery(Asset asset) {
return advancedSearchQuery(asset, 0, SolrServerUtil.DEFAULT_ROWS_SIZE);
}
/** @throws IllegalArgumentException */
private List<AssetSolrDTO> advancedSearchQuery(Asset asset, int startRow, int rowsSize) {
String advancedQuery = SolrConversionUtil.fromAssetToQuery(asset);
if (advancedQuery.trim().isEmpty()) {
throw new IllegalArgumentException("There are not search terms.");
}
searchTime = System.currentTimeMillis();
List<AssetSolrDTO> assetSolrList = this.queryDismax(advancedQuery, startRow, rowsSize);
searchTime = System.currentTimeMillis() - searchTime;
return assetSolrList;
}
public synchronized Long getPublishedAssetsNumber() {
if (publishedAssetsNumber == null) {
refreshPublishedAssetsNumber();
}
return publishedAssetsNumber;
}
public void refreshPublishedAssetsNumber() {
SolrDocumentList sdl = SolrServerUtil.getInstance().queryDismax("*", 0, SearchOrder.NO_ORDER);
this.publishedAssetsNumber = sdl.getNumFound();
}
public synchronized List<AssetSolrDTO> getBestScoredAssetsList() {
if (bestScoredAssetsList == null) {
this.refreshBestScoredAssetsList();
}
return bestScoredAssetsList;
}
public void refreshBestScoredAssetsList() {
SolrDocumentList sdl = SolrServerUtil.getInstance().queryDismax("*", NUMBER_ASSETS_LIST, SearchOrder.BY_BEST_RATED);
bestScoredAssetsList = SolrConversionUtil.fromSolrDocumentListToAsset(sdl);
/* remove invalid values */
for (int i = bestScoredAssetsList.size()-1; i >=0 ; i--) {
if (bestScoredAssetsList.get(i).getAverageScore() == null ||
bestScoredAssetsList.get(i).getAverageScore() <= 0) {
bestScoredAssetsList.remove(i);
}
}
logger.info("refreshBestScoredAssetsList()");
}
public synchronized List<AssetSolrDTO> getMostReusedAssetsList() {
if (mostReusedAssetsList == null) {
this.refreshMostReusedAssetsList();
}
return mostReusedAssetsList;
}
public void refreshMostReusedAssetsList() {
SolrDocumentList sdl = SolrServerUtil.getInstance().queryDismax("*", NUMBER_ASSETS_LIST, SearchOrder.BY_MOST_REUSED);
mostReusedAssetsList = SolrConversionUtil.fromSolrDocumentListToAsset(sdl);
/* remove invalid values */
for (int i = mostReusedAssetsList.size()-1; i >=0 ; i--) {
if (mostReusedAssetsList.get(i).getReuseCounter() == null ||
mostReusedAssetsList.get(i).getReuseCounter() <= 0) {
mostReusedAssetsList.remove(i);
}
}
logger.info("refreshMostReusedAssetsList()");
}
public synchronized List<AssetSolrDTO> getLastCertifiedAssetsList() {
if (lastCertifiedAssetsList == null) {
this.refreshLastCertifiedAssetsList();
}
return lastCertifiedAssetsList;
}
public void refreshLastCertifiedAssetsList() {
Asset asset = new Asset();
asset.setState(TypesDAO.getInstance().getCertifiedAssetStateType());
String certifiedAssetsQuery = SolrConversionUtil.fromAssetToQuery(asset);
SolrDocumentList sdl = SolrServerUtil.getInstance().queryDismax(certifiedAssetsQuery, NUMBER_ASSETS_LIST, SearchOrder.BY_LAST_CERTIFIED);
lastCertifiedAssetsList = SolrConversionUtil.fromSolrDocumentListToAsset(sdl);
logger.info("refreshLastCertifiedAssetsList()");
}
public synchronized List<AssetSolrDTO> getLastPublishedAssetsList() {
if (lastPublishedAssetsList == null) {
this.refreshLastPublishedAssetsList();
}
return lastPublishedAssetsList;
}
public void refreshLastPublishedAssetsList() {
SolrDocumentList sdl = SolrServerUtil.getInstance().queryDismax("*", NUMBER_ASSETS_LIST, SearchOrder.BY_LAST_PUBLISHED);
lastPublishedAssetsList = SolrConversionUtil.fromSolrDocumentListToAsset(sdl);
logger.info("refreshLastPublishedAssetsList()");
}
protected String clearResults() {
this.assetResultList = new ArrayList<AssetSolrDTO>();
return "";
}
protected List<AssetSolrDTO> queryDismax(String q, int startRow, int rowsSize) {
SolrDocumentList sdl = SolrServerUtil.getInstance().queryDismax(q, startRow, rowsSize, this.searchOrder);
this.numFound = sdl.getNumFound();
if (startRow == 0) {
/* Store the maxScore for the another pages starring */
this.maxScore = sdl.getMaxScore();
}
return SolrConversionUtil.fromSolrDocumentListToAsset(sdl, this.maxScore);
}
public String getSearchTime() {
NumberFormat nFBR = NumberFormat.getInstance();
nFBR.setMinimumFractionDigits(3);
nFBR.setMaximumFractionDigits(3);
return nFBR.format(this.searchTime / 1000d);
}
/* PAGINATION */
public Boolean getCanNextPage() {
return (this.indexCurrentStart + this.pageSize ) < this.numFound;
}
public Boolean getCanPreviousPage() {
return this.indexCurrentStart > 0;
}
public String getPageResultsMessage() {
if (assetResultList.isEmpty()) {
return "Your search did not match any results.";
} else {
int currentPage = (this.indexCurrentStart / this.pageSize) + 1;
return "Page " + currentPage + " of " +
this.numFound + " results (" +
getSearchTime() + " seconds)";
}
}
public String getResultsMessage() {
if (assetResultList.isEmpty()) {
return "Your search did not match any results.";
} else {
return assetResultList.size() + " results (" + getSearchTime() + " seconds)";
}
}
public void saveUserQuery(String userQuery) {
UserQueryLogDTO userQueryDTO = new UserQueryLogDTO();
userQueryDTO.setQueryText(userQuery);
userQueryDTO.setIp(JSFUtil.getCurrentIP());
userQueryDTO.setDate(Calendar.getInstance());
if (JSFUtil.isLoggedUser()) {
userQueryDTO.setUsername(JSFUtil.getLoggedUserDTO().getUsername());
}
GenericDAO.getInstance().insert(userQueryDTO);
}
public List<AssetSolrDTO> getAssetResultList() {
return assetResultList;
}
public void setAssetResultList(List<AssetSolrDTO> assetResultList) {
this.assetResultList = assetResultList;
}
public List<AssetSolrDTO> getSuggestedAssetsList() {
return suggestedAssetsList;
}
public void setSuggestedAssetsList(List<AssetSolrDTO> suggestedAssetsList) {
this.suggestedAssetsList = suggestedAssetsList;
}
public SearchOrder getSearchOrder() {
return searchOrder;
}
public void setSearchOrder(SearchOrder searchOrder) {
this.searchOrder = searchOrder;
}
}