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