001
014
015 package com.liferay.portlet.asset.util;
016
017 import com.liferay.asset.kernel.model.AssetCategory;
018 import com.liferay.asset.kernel.service.AssetCategoryLocalServiceUtil;
019 import com.liferay.asset.kernel.service.persistence.AssetEntryQuery;
020 import com.liferay.portal.kernel.search.BaseSearcher;
021 import com.liferay.portal.kernel.search.BooleanClauseOccur;
022 import com.liferay.portal.kernel.search.BooleanQuery;
023 import com.liferay.portal.kernel.search.DocumentImpl;
024 import com.liferay.portal.kernel.search.Field;
025 import com.liferay.portal.kernel.search.Indexer;
026 import com.liferay.portal.kernel.search.Query;
027 import com.liferay.portal.kernel.search.SearchContext;
028 import com.liferay.portal.kernel.search.filter.BooleanFilter;
029 import com.liferay.portal.kernel.search.filter.TermsFilter;
030 import com.liferay.portal.kernel.security.permission.PermissionChecker;
031 import com.liferay.portal.kernel.security.permission.PermissionThreadLocal;
032 import com.liferay.portal.kernel.util.ArrayUtil;
033 import com.liferay.portal.kernel.util.GetterUtil;
034 import com.liferay.portal.kernel.util.PortalUtil;
035 import com.liferay.portal.kernel.util.Validator;
036 import com.liferay.portal.util.PropsValues;
037
038 import java.util.ArrayList;
039 import java.util.Collections;
040 import java.util.List;
041 import java.util.Map;
042
043
046 public class AssetSearcher extends BaseSearcher {
047
048 public static Indexer<?> getInstance() {
049 return new AssetSearcher();
050 }
051
052 public AssetSearcher() {
053 setDefaultSelectedFieldNames(
054 Field.ENTRY_CLASS_NAME, Field.ENTRY_CLASS_PK, Field.UID);
055 setFilterSearch(true);
056 setPermissionAware(true);
057 }
058
059 @Override
060 public String[] getSearchClassNames() {
061 long[] classNameIds = _assetEntryQuery.getClassNameIds();
062
063 String[] classNames = new String[classNameIds.length];
064
065 for (int i = 0; i < classNames.length; i++) {
066 long classNameId = classNameIds[i];
067
068 classNames[i] = PortalUtil.getClassName(classNameId);
069 }
070
071 return classNames;
072 }
073
074 public void setAssetEntryQuery(AssetEntryQuery assetEntryQuery) {
075 _assetEntryQuery = assetEntryQuery;
076 }
077
078 protected void addImpossibleTerm(
079 BooleanFilter queryBooleanFilter, String field)
080 throws Exception {
081
082 queryBooleanFilter.addTerm(field, "-1", BooleanClauseOccur.MUST);
083 }
084
085 protected void addSearchAllCategories(BooleanFilter queryBooleanFilter)
086 throws Exception {
087
088 PermissionChecker permissionChecker =
089 PermissionThreadLocal.getPermissionChecker();
090
091 long[] allCategoryIds = _assetEntryQuery.getAllCategoryIds();
092
093 if (allCategoryIds.length == 0) {
094 return;
095 }
096
097 long[] filteredAllCategoryIds = AssetUtil.filterCategoryIds(
098 permissionChecker, allCategoryIds);
099
100 if (allCategoryIds.length != filteredAllCategoryIds.length) {
101 addImpossibleTerm(queryBooleanFilter, Field.ASSET_CATEGORY_IDS);
102
103 return;
104 }
105
106 BooleanFilter categoryIdsBooleanFilter = new BooleanFilter();
107
108 for (long allCategoryId : filteredAllCategoryIds) {
109 AssetCategory assetCategory =
110 AssetCategoryLocalServiceUtil.fetchAssetCategory(allCategoryId);
111
112 if (assetCategory == null) {
113 continue;
114 }
115
116 List<Long> categoryIds = new ArrayList<>();
117
118 if (PropsValues.ASSET_CATEGORIES_SEARCH_HIERARCHICAL) {
119 categoryIds.addAll(
120 AssetCategoryLocalServiceUtil.getSubcategoryIds(
121 allCategoryId));
122 }
123
124 if (categoryIds.isEmpty()) {
125 categoryIds.add(allCategoryId);
126 }
127
128 TermsFilter categoryIdTermsFilter = new TermsFilter(
129 Field.ASSET_CATEGORY_IDS);
130
131 categoryIdTermsFilter.addValues(
132 ArrayUtil.toStringArray(
133 categoryIds.toArray(new Long[categoryIds.size()])));
134
135 categoryIdsBooleanFilter.add(
136 categoryIdTermsFilter, BooleanClauseOccur.MUST);
137 }
138
139 queryBooleanFilter.add(
140 categoryIdsBooleanFilter, BooleanClauseOccur.MUST);
141 }
142
143 protected void addSearchAllTags(BooleanFilter queryBooleanFilter)
144 throws Exception {
145
146 long[][] allTagIdsArray = _assetEntryQuery.getAllTagIdsArray();
147
148 if (allTagIdsArray.length == 0) {
149 return;
150 }
151
152 BooleanFilter tagIdsArrayBooleanFilter = new BooleanFilter();
153
154 for (long[] allTagIds : allTagIdsArray) {
155 if (allTagIds.length == 0) {
156 continue;
157 }
158
159 TermsFilter tagIdsTermsFilter = new TermsFilter(
160 Field.ASSET_TAG_IDS);
161
162 tagIdsTermsFilter.addValues(ArrayUtil.toStringArray(allTagIds));
163
164 tagIdsArrayBooleanFilter.add(
165 tagIdsTermsFilter, BooleanClauseOccur.MUST);
166 }
167
168 queryBooleanFilter.add(
169 tagIdsArrayBooleanFilter, BooleanClauseOccur.MUST);
170 }
171
172 protected void addSearchAnyCategories(BooleanFilter queryBooleanFilter)
173 throws Exception {
174
175 PermissionChecker permissionChecker =
176 PermissionThreadLocal.getPermissionChecker();
177
178 long[] anyCategoryIds = _assetEntryQuery.getAnyCategoryIds();
179
180 if (anyCategoryIds.length == 0) {
181 return;
182 }
183
184 long[] filteredAnyCategoryIds = AssetUtil.filterCategoryIds(
185 permissionChecker, anyCategoryIds);
186
187 if (filteredAnyCategoryIds.length == 0) {
188 addImpossibleTerm(queryBooleanFilter, Field.ASSET_CATEGORY_IDS);
189
190 return;
191 }
192
193 TermsFilter categoryIdsTermsFilter = new TermsFilter(
194 Field.ASSET_CATEGORY_IDS);
195
196 for (long anyCategoryId : filteredAnyCategoryIds) {
197 AssetCategory assetCategory =
198 AssetCategoryLocalServiceUtil.fetchAssetCategory(anyCategoryId);
199
200 if (assetCategory == null) {
201 continue;
202 }
203
204 List<Long> categoryIds = new ArrayList<>();
205
206 if (PropsValues.ASSET_CATEGORIES_SEARCH_HIERARCHICAL) {
207 categoryIds.addAll(
208 AssetCategoryLocalServiceUtil.getSubcategoryIds(
209 anyCategoryId));
210 }
211
212 if (categoryIds.isEmpty()) {
213 categoryIds.add(anyCategoryId);
214 }
215
216 categoryIdsTermsFilter.addValues(
217 ArrayUtil.toStringArray(
218 categoryIds.toArray(new Long[categoryIds.size()])));
219 }
220
221 queryBooleanFilter.add(categoryIdsTermsFilter, BooleanClauseOccur.MUST);
222 }
223
224 protected void addSearchAnyTags(BooleanFilter queryBooleanFilter)
225 throws Exception {
226
227 long[] anyTagIds = _assetEntryQuery.getAnyTagIds();
228
229 if (anyTagIds.length == 0) {
230 return;
231 }
232
233 TermsFilter tagIdsTermsFilter = new TermsFilter(Field.ASSET_TAG_IDS);
234
235 tagIdsTermsFilter.addValues(ArrayUtil.toStringArray(anyTagIds));
236
237 queryBooleanFilter.add(tagIdsTermsFilter, BooleanClauseOccur.MUST);
238 }
239
240 @Override
241 protected void addSearchAssetCategoryIds(
242 BooleanFilter queryBooleanFilter, SearchContext searchContext)
243 throws Exception {
244
245 addSearchAllCategories(queryBooleanFilter);
246 addSearchAnyCategories(queryBooleanFilter);
247 addSearchNotAnyCategories(queryBooleanFilter);
248 addSearchNotAllCategories(queryBooleanFilter);
249 }
250
251 @Override
252 protected void addSearchAssetTagNames(
253 BooleanFilter queryBooleanFilter, SearchContext searchContext)
254 throws Exception {
255
256 addSearchAllTags(queryBooleanFilter);
257 addSearchAnyTags(queryBooleanFilter);
258 addSearchNotAllTags(queryBooleanFilter);
259 addSearchNotAnyTags(queryBooleanFilter);
260 }
261
262 @Override
263 protected Map<String, Query> addSearchKeywords(
264 BooleanQuery searchQuery, SearchContext searchContext)
265 throws Exception {
266
267 String keywords = searchContext.getKeywords();
268
269 if (Validator.isNull(keywords)) {
270 return Collections.emptyMap();
271 }
272
273 Map<String, Query> queries = super.addSearchKeywords(
274 searchQuery, searchContext);
275
276 String field = DocumentImpl.getLocalizedName(
277 searchContext.getLocale(), "localized_title");
278
279 Query query = searchQuery.addTerm(field, keywords, true);
280
281 queries.put(field, query);
282
283 return queries;
284 }
285
286 @Override
287 protected void addSearchLayout(
288 BooleanFilter queryBooleanFilter, SearchContext searchContext)
289 throws Exception {
290
291 String layoutUuid = (String)searchContext.getAttribute(
292 Field.LAYOUT_UUID);
293
294 if (Validator.isNotNull(layoutUuid)) {
295 queryBooleanFilter.addRequiredTerm(Field.LAYOUT_UUID, layoutUuid);
296 }
297 }
298
299 protected void addSearchNotAllCategories(BooleanFilter queryBooleanFilter)
300 throws Exception {
301
302 long[] notAllCategoryIds = _assetEntryQuery.getNotAllCategoryIds();
303
304 if (notAllCategoryIds.length == 0) {
305 return;
306 }
307
308 BooleanFilter categoryIdsBooleanFilter = new BooleanFilter();
309
310 for (long notAllCategoryId : notAllCategoryIds) {
311 AssetCategory assetCategory =
312 AssetCategoryLocalServiceUtil.fetchAssetCategory(
313 notAllCategoryId);
314
315 if (assetCategory == null) {
316 continue;
317 }
318
319 List<Long> categoryIds = new ArrayList<>();
320
321 if (PropsValues.ASSET_CATEGORIES_SEARCH_HIERARCHICAL) {
322 categoryIds.addAll(
323 AssetCategoryLocalServiceUtil.getSubcategoryIds(
324 notAllCategoryId));
325 }
326
327 if (categoryIds.isEmpty()) {
328 categoryIds.add(notAllCategoryId);
329 }
330
331 TermsFilter categoryIdTermsFilter = new TermsFilter(
332 Field.ASSET_CATEGORY_IDS);
333
334 categoryIdTermsFilter.addValues(
335 ArrayUtil.toStringArray(
336 categoryIds.toArray(new Long[categoryIds.size()])));
337
338 categoryIdsBooleanFilter.add(
339 categoryIdTermsFilter, BooleanClauseOccur.MUST);
340 }
341
342 queryBooleanFilter.add(
343 categoryIdsBooleanFilter, BooleanClauseOccur.MUST_NOT);
344 }
345
346 protected void addSearchNotAllTags(BooleanFilter queryBooleanFilter)
347 throws Exception {
348
349 long[][] notAllTagIdsArray = _assetEntryQuery.getNotAllTagIdsArray();
350
351 if (notAllTagIdsArray.length == 0) {
352 return;
353 }
354
355 BooleanFilter tagIdsArrayBooleanFilter = new BooleanFilter();
356
357 for (long[] notAllTagIds : notAllTagIdsArray) {
358 if (notAllTagIds.length == 0) {
359 continue;
360 }
361
362 TermsFilter tagIdsTermsFilter = new TermsFilter(
363 Field.ASSET_TAG_IDS);
364
365 tagIdsTermsFilter.addValues(ArrayUtil.toStringArray(notAllTagIds));
366
367 tagIdsArrayBooleanFilter.add(
368 tagIdsTermsFilter, BooleanClauseOccur.MUST);
369 }
370
371 queryBooleanFilter.add(
372 tagIdsArrayBooleanFilter, BooleanClauseOccur.MUST_NOT);
373 }
374
375 protected void addSearchNotAnyCategories(BooleanFilter queryBooleanFilter)
376 throws Exception {
377
378 long[] notAnyCategoryIds = _assetEntryQuery.getNotAnyCategoryIds();
379
380 if (notAnyCategoryIds.length == 0) {
381 return;
382 }
383
384 TermsFilter categoryIdsTermsFilter = new TermsFilter(
385 Field.ASSET_CATEGORY_IDS);
386
387 for (long notAnyCategoryId : notAnyCategoryIds) {
388 AssetCategory assetCategory =
389 AssetCategoryLocalServiceUtil.fetchAssetCategory(
390 notAnyCategoryId);
391
392 if (assetCategory == null) {
393 continue;
394 }
395
396 List<Long> categoryIds = new ArrayList<>();
397
398 if (PropsValues.ASSET_CATEGORIES_SEARCH_HIERARCHICAL) {
399 categoryIds.addAll(
400 AssetCategoryLocalServiceUtil.getSubcategoryIds(
401 notAnyCategoryId));
402 }
403
404 if (categoryIds.isEmpty()) {
405 categoryIds.add(notAnyCategoryId);
406 }
407
408 categoryIdsTermsFilter.addValues(
409 ArrayUtil.toStringArray(
410 categoryIds.toArray(new Long[categoryIds.size()])));
411 }
412
413 queryBooleanFilter.add(
414 categoryIdsTermsFilter, BooleanClauseOccur.MUST_NOT);
415 }
416
417 protected void addSearchNotAnyTags(BooleanFilter queryBooleanFilter)
418 throws Exception {
419
420 long[] notAnyTagIds = _assetEntryQuery.getNotAnyTagIds();
421
422 if (notAnyTagIds.length == 0) {
423 return;
424 }
425
426 TermsFilter tagIgsTermsFilter = new TermsFilter(Field.ASSET_TAG_IDS);
427
428 tagIgsTermsFilter.addValues(ArrayUtil.toStringArray(notAnyTagIds));
429
430 queryBooleanFilter.add(tagIgsTermsFilter, BooleanClauseOccur.MUST_NOT);
431 }
432
433 @Override
434 protected void postProcessFullQuery(
435 BooleanQuery fullQuery, SearchContext searchContext)
436 throws Exception {
437
438 boolean showInvisible = GetterUtil.getBoolean(
439 _assetEntryQuery.getAttribute("showInvisible"));
440
441 if (showInvisible) {
442 return;
443 }
444
445 BooleanFilter booleanFilter = fullQuery.getPreBooleanFilter();
446
447 if (booleanFilter == null) {
448 booleanFilter = new BooleanFilter();
449 }
450
451 booleanFilter.addRequiredTerm("visible", true);
452
453 if (booleanFilter.hasClauses() && !showInvisible) {
454 fullQuery.setPreBooleanFilter(booleanFilter);
455 }
456 }
457
458 private AssetEntryQuery _assetEntryQuery;
459
460 }