/**
* Copyright (c) 2000-present Liferay, Inc. All rights reserved.
*
* This library is free software; you can redistribute it and/or modify it under
* the terms of the GNU Lesser General Public License as published by the Free
* Software Foundation; either version 2.1 of the License, or (at your option)
* any later version.
*
* This library is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
* FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
* details.
*/
package com.liferay.portlet.asset.util;
import com.liferay.asset.kernel.model.AssetCategory;
import com.liferay.asset.kernel.service.AssetCategoryLocalServiceUtil;
import com.liferay.asset.kernel.service.persistence.AssetEntryQuery;
import com.liferay.portal.kernel.search.BaseSearcher;
import com.liferay.portal.kernel.search.BooleanClauseOccur;
import com.liferay.portal.kernel.search.BooleanQuery;
import com.liferay.portal.kernel.search.DocumentImpl;
import com.liferay.portal.kernel.search.Field;
import com.liferay.portal.kernel.search.Indexer;
import com.liferay.portal.kernel.search.Query;
import com.liferay.portal.kernel.search.SearchContext;
import com.liferay.portal.kernel.search.filter.BooleanFilter;
import com.liferay.portal.kernel.search.filter.TermsFilter;
import com.liferay.portal.kernel.security.permission.PermissionChecker;
import com.liferay.portal.kernel.security.permission.PermissionThreadLocal;
import com.liferay.portal.kernel.util.ArrayUtil;
import com.liferay.portal.kernel.util.GetterUtil;
import com.liferay.portal.kernel.util.PortalUtil;
import com.liferay.portal.kernel.util.Validator;
import com.liferay.portal.util.PropsValues;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Map;
/**
* @author Eudaldo Alonso
*/
public class AssetSearcher extends BaseSearcher {
public static Indexer<?> getInstance() {
return new AssetSearcher();
}
public AssetSearcher() {
setDefaultSelectedFieldNames(
Field.ENTRY_CLASS_NAME, Field.ENTRY_CLASS_PK, Field.UID);
setFilterSearch(true);
setPermissionAware(true);
}
@Override
public String[] getSearchClassNames() {
long[] classNameIds = _assetEntryQuery.getClassNameIds();
String[] classNames = new String[classNameIds.length];
for (int i = 0; i < classNames.length; i++) {
long classNameId = classNameIds[i];
classNames[i] = PortalUtil.getClassName(classNameId);
}
return classNames;
}
public void setAssetEntryQuery(AssetEntryQuery assetEntryQuery) {
_assetEntryQuery = assetEntryQuery;
}
protected void addImpossibleTerm(
BooleanFilter queryBooleanFilter, String field)
throws Exception {
queryBooleanFilter.addTerm(field, "-1", BooleanClauseOccur.MUST);
}
protected void addSearchAllCategories(BooleanFilter queryBooleanFilter)
throws Exception {
PermissionChecker permissionChecker =
PermissionThreadLocal.getPermissionChecker();
long[] allCategoryIds = _assetEntryQuery.getAllCategoryIds();
if (allCategoryIds.length == 0) {
return;
}
long[] filteredAllCategoryIds = AssetUtil.filterCategoryIds(
permissionChecker, allCategoryIds);
if (allCategoryIds.length != filteredAllCategoryIds.length) {
addImpossibleTerm(queryBooleanFilter, Field.ASSET_CATEGORY_IDS);
return;
}
BooleanFilter categoryIdsBooleanFilter = new BooleanFilter();
for (long allCategoryId : filteredAllCategoryIds) {
AssetCategory assetCategory =
AssetCategoryLocalServiceUtil.fetchAssetCategory(allCategoryId);
if (assetCategory == null) {
continue;
}
List<Long> categoryIds = new ArrayList<>();
if (PropsValues.ASSET_CATEGORIES_SEARCH_HIERARCHICAL) {
categoryIds.addAll(
AssetCategoryLocalServiceUtil.getSubcategoryIds(
allCategoryId));
}
if (categoryIds.isEmpty()) {
categoryIds.add(allCategoryId);
}
TermsFilter categoryIdTermsFilter = new TermsFilter(
Field.ASSET_CATEGORY_IDS);
categoryIdTermsFilter.addValues(
ArrayUtil.toStringArray(
categoryIds.toArray(new Long[categoryIds.size()])));
categoryIdsBooleanFilter.add(
categoryIdTermsFilter, BooleanClauseOccur.MUST);
}
queryBooleanFilter.add(
categoryIdsBooleanFilter, BooleanClauseOccur.MUST);
}
protected void addSearchAllTags(BooleanFilter queryBooleanFilter)
throws Exception {
long[][] allTagIdsArray = _assetEntryQuery.getAllTagIdsArray();
if (allTagIdsArray.length == 0) {
return;
}
BooleanFilter tagIdsArrayBooleanFilter = new BooleanFilter();
for (long[] allTagIds : allTagIdsArray) {
if (allTagIds.length == 0) {
continue;
}
TermsFilter tagIdsTermsFilter = new TermsFilter(
Field.ASSET_TAG_IDS);
tagIdsTermsFilter.addValues(ArrayUtil.toStringArray(allTagIds));
tagIdsArrayBooleanFilter.add(
tagIdsTermsFilter, BooleanClauseOccur.MUST);
}
queryBooleanFilter.add(
tagIdsArrayBooleanFilter, BooleanClauseOccur.MUST);
}
protected void addSearchAnyCategories(BooleanFilter queryBooleanFilter)
throws Exception {
PermissionChecker permissionChecker =
PermissionThreadLocal.getPermissionChecker();
long[] anyCategoryIds = _assetEntryQuery.getAnyCategoryIds();
if (anyCategoryIds.length == 0) {
return;
}
long[] filteredAnyCategoryIds = AssetUtil.filterCategoryIds(
permissionChecker, anyCategoryIds);
if (filteredAnyCategoryIds.length == 0) {
addImpossibleTerm(queryBooleanFilter, Field.ASSET_CATEGORY_IDS);
return;
}
TermsFilter categoryIdsTermsFilter = new TermsFilter(
Field.ASSET_CATEGORY_IDS);
for (long anyCategoryId : filteredAnyCategoryIds) {
AssetCategory assetCategory =
AssetCategoryLocalServiceUtil.fetchAssetCategory(anyCategoryId);
if (assetCategory == null) {
continue;
}
List<Long> categoryIds = new ArrayList<>();
if (PropsValues.ASSET_CATEGORIES_SEARCH_HIERARCHICAL) {
categoryIds.addAll(
AssetCategoryLocalServiceUtil.getSubcategoryIds(
anyCategoryId));
}
if (categoryIds.isEmpty()) {
categoryIds.add(anyCategoryId);
}
categoryIdsTermsFilter.addValues(
ArrayUtil.toStringArray(
categoryIds.toArray(new Long[categoryIds.size()])));
}
queryBooleanFilter.add(categoryIdsTermsFilter, BooleanClauseOccur.MUST);
}
protected void addSearchAnyTags(BooleanFilter queryBooleanFilter)
throws Exception {
long[] anyTagIds = _assetEntryQuery.getAnyTagIds();
if (anyTagIds.length == 0) {
return;
}
TermsFilter tagIdsTermsFilter = new TermsFilter(Field.ASSET_TAG_IDS);
tagIdsTermsFilter.addValues(ArrayUtil.toStringArray(anyTagIds));
queryBooleanFilter.add(tagIdsTermsFilter, BooleanClauseOccur.MUST);
}
@Override
protected void addSearchAssetCategoryIds(
BooleanFilter queryBooleanFilter, SearchContext searchContext)
throws Exception {
addSearchAllCategories(queryBooleanFilter);
addSearchAnyCategories(queryBooleanFilter);
addSearchNotAnyCategories(queryBooleanFilter);
addSearchNotAllCategories(queryBooleanFilter);
}
@Override
protected void addSearchAssetTagNames(
BooleanFilter queryBooleanFilter, SearchContext searchContext)
throws Exception {
addSearchAllTags(queryBooleanFilter);
addSearchAnyTags(queryBooleanFilter);
addSearchNotAllTags(queryBooleanFilter);
addSearchNotAnyTags(queryBooleanFilter);
}
@Override
protected Map<String, Query> addSearchKeywords(
BooleanQuery searchQuery, SearchContext searchContext)
throws Exception {
String keywords = searchContext.getKeywords();
if (Validator.isNull(keywords)) {
return Collections.emptyMap();
}
Map<String, Query> queries = super.addSearchKeywords(
searchQuery, searchContext);
String field = DocumentImpl.getLocalizedName(
searchContext.getLocale(), "localized_title");
Query query = searchQuery.addTerm(field, keywords, true);
queries.put(field, query);
return queries;
}
@Override
protected void addSearchLayout(
BooleanFilter queryBooleanFilter, SearchContext searchContext)
throws Exception {
String layoutUuid = (String)searchContext.getAttribute(
Field.LAYOUT_UUID);
if (Validator.isNotNull(layoutUuid)) {
queryBooleanFilter.addRequiredTerm(Field.LAYOUT_UUID, layoutUuid);
}
}
protected void addSearchNotAllCategories(BooleanFilter queryBooleanFilter)
throws Exception {
long[] notAllCategoryIds = _assetEntryQuery.getNotAllCategoryIds();
if (notAllCategoryIds.length == 0) {
return;
}
BooleanFilter categoryIdsBooleanFilter = new BooleanFilter();
for (long notAllCategoryId : notAllCategoryIds) {
AssetCategory assetCategory =
AssetCategoryLocalServiceUtil.fetchAssetCategory(
notAllCategoryId);
if (assetCategory == null) {
continue;
}
List<Long> categoryIds = new ArrayList<>();
if (PropsValues.ASSET_CATEGORIES_SEARCH_HIERARCHICAL) {
categoryIds.addAll(
AssetCategoryLocalServiceUtil.getSubcategoryIds(
notAllCategoryId));
}
if (categoryIds.isEmpty()) {
categoryIds.add(notAllCategoryId);
}
TermsFilter categoryIdTermsFilter = new TermsFilter(
Field.ASSET_CATEGORY_IDS);
categoryIdTermsFilter.addValues(
ArrayUtil.toStringArray(
categoryIds.toArray(new Long[categoryIds.size()])));
categoryIdsBooleanFilter.add(
categoryIdTermsFilter, BooleanClauseOccur.MUST);
}
queryBooleanFilter.add(
categoryIdsBooleanFilter, BooleanClauseOccur.MUST_NOT);
}
protected void addSearchNotAllTags(BooleanFilter queryBooleanFilter)
throws Exception {
long[][] notAllTagIdsArray = _assetEntryQuery.getNotAllTagIdsArray();
if (notAllTagIdsArray.length == 0) {
return;
}
BooleanFilter tagIdsArrayBooleanFilter = new BooleanFilter();
for (long[] notAllTagIds : notAllTagIdsArray) {
if (notAllTagIds.length == 0) {
continue;
}
TermsFilter tagIdsTermsFilter = new TermsFilter(
Field.ASSET_TAG_IDS);
tagIdsTermsFilter.addValues(ArrayUtil.toStringArray(notAllTagIds));
tagIdsArrayBooleanFilter.add(
tagIdsTermsFilter, BooleanClauseOccur.MUST);
}
queryBooleanFilter.add(
tagIdsArrayBooleanFilter, BooleanClauseOccur.MUST_NOT);
}
protected void addSearchNotAnyCategories(BooleanFilter queryBooleanFilter)
throws Exception {
long[] notAnyCategoryIds = _assetEntryQuery.getNotAnyCategoryIds();
if (notAnyCategoryIds.length == 0) {
return;
}
TermsFilter categoryIdsTermsFilter = new TermsFilter(
Field.ASSET_CATEGORY_IDS);
for (long notAnyCategoryId : notAnyCategoryIds) {
AssetCategory assetCategory =
AssetCategoryLocalServiceUtil.fetchAssetCategory(
notAnyCategoryId);
if (assetCategory == null) {
continue;
}
List<Long> categoryIds = new ArrayList<>();
if (PropsValues.ASSET_CATEGORIES_SEARCH_HIERARCHICAL) {
categoryIds.addAll(
AssetCategoryLocalServiceUtil.getSubcategoryIds(
notAnyCategoryId));
}
if (categoryIds.isEmpty()) {
categoryIds.add(notAnyCategoryId);
}
categoryIdsTermsFilter.addValues(
ArrayUtil.toStringArray(
categoryIds.toArray(new Long[categoryIds.size()])));
}
queryBooleanFilter.add(
categoryIdsTermsFilter, BooleanClauseOccur.MUST_NOT);
}
protected void addSearchNotAnyTags(BooleanFilter queryBooleanFilter)
throws Exception {
long[] notAnyTagIds = _assetEntryQuery.getNotAnyTagIds();
if (notAnyTagIds.length == 0) {
return;
}
TermsFilter tagIgsTermsFilter = new TermsFilter(Field.ASSET_TAG_IDS);
tagIgsTermsFilter.addValues(ArrayUtil.toStringArray(notAnyTagIds));
queryBooleanFilter.add(tagIgsTermsFilter, BooleanClauseOccur.MUST_NOT);
}
@Override
protected void postProcessFullQuery(
BooleanQuery fullQuery, SearchContext searchContext)
throws Exception {
boolean showInvisible = GetterUtil.getBoolean(
_assetEntryQuery.getAttribute("showInvisible"));
if (showInvisible) {
return;
}
BooleanFilter booleanFilter = fullQuery.getPreBooleanFilter();
if (booleanFilter == null) {
booleanFilter = new BooleanFilter();
}
booleanFilter.addRequiredTerm("visible", true);
if (booleanFilter.hasClauses() && !showInvisible) {
fullQuery.setPreBooleanFilter(booleanFilter);
}
}
private AssetEntryQuery _assetEntryQuery;
}