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 long[][] allTagIdsArray = _assetEntryQuery.getAllTagIdsArray();
146
147 if (allTagIdsArray.length == 0) {
148 return;
149 }
150
151 BooleanFilter tagIdsArrayBooleanFilter = new BooleanFilter();
152
153 for (long[] allTagIds : allTagIdsArray) {
154 if (allTagIds.length == 0) {
155 continue;
156 }
157
158 TermsFilter tagIdsTermsFilter = new TermsFilter(
159 Field.ASSET_TAG_IDS);
160
161 tagIdsTermsFilter.addValues(ArrayUtil.toStringArray(allTagIds));
162
163 tagIdsArrayBooleanFilter.add(
164 tagIdsTermsFilter, BooleanClauseOccur.MUST);
165 }
166
167 queryBooleanFilter.add(
168 tagIdsArrayBooleanFilter, BooleanClauseOccur.MUST);
169 }
170
171 protected void addSearchAnyCategories(BooleanFilter queryBooleanFilter)
172 throws Exception {
173
174 PermissionChecker permissionChecker =
175 PermissionThreadLocal.getPermissionChecker();
176
177 long[] anyCategoryIds = _assetEntryQuery.getAnyCategoryIds();
178
179 if (anyCategoryIds.length == 0) {
180 return;
181 }
182
183 long[] filteredAnyCategoryIds = AssetUtil.filterCategoryIds(
184 permissionChecker, anyCategoryIds);
185
186 if (filteredAnyCategoryIds.length == 0) {
187 addImpossibleTerm(queryBooleanFilter, Field.ASSET_CATEGORY_IDS);
188
189 return;
190 }
191
192 TermsFilter categoryIdsTermsFilter = new TermsFilter(
193 Field.ASSET_CATEGORY_IDS);
194
195 for (long anyCategoryId : filteredAnyCategoryIds) {
196 AssetCategory assetCategory =
197 AssetCategoryLocalServiceUtil.fetchAssetCategory(anyCategoryId);
198
199 if (assetCategory == null) {
200 continue;
201 }
202
203 List<Long> categoryIds = new ArrayList<>();
204
205 if (PropsValues.ASSET_CATEGORIES_SEARCH_HIERARCHICAL) {
206 categoryIds.addAll(
207 AssetCategoryLocalServiceUtil.getSubcategoryIds(
208 anyCategoryId));
209 }
210
211 if (categoryIds.isEmpty()) {
212 categoryIds.add(anyCategoryId);
213 }
214
215 categoryIdsTermsFilter.addValues(
216 ArrayUtil.toStringArray(
217 categoryIds.toArray(new Long[categoryIds.size()])));
218 }
219
220 queryBooleanFilter.add(categoryIdsTermsFilter, BooleanClauseOccur.MUST);
221 }
222
223 protected void addSearchAnyTags(BooleanFilter queryBooleanFilter)
224 throws Exception {
225
226 long[] anyTagIds = _assetEntryQuery.getAnyTagIds();
227
228 if (anyTagIds.length == 0) {
229 return;
230 }
231
232 TermsFilter tagIdsTermsFilter = new TermsFilter(Field.ASSET_TAG_IDS);
233
234 tagIdsTermsFilter.addValues(ArrayUtil.toStringArray(anyTagIds));
235
236 queryBooleanFilter.add(tagIdsTermsFilter, BooleanClauseOccur.MUST);
237 }
238
239 @Override
240 protected void addSearchAssetCategoryIds(
241 BooleanFilter queryBooleanFilter, SearchContext searchContext)
242 throws Exception {
243
244 addSearchAllCategories(queryBooleanFilter);
245 addSearchAnyCategories(queryBooleanFilter);
246 addSearchNotAnyCategories(queryBooleanFilter);
247 addSearchNotAllCategories(queryBooleanFilter);
248 }
249
250 @Override
251 protected void addSearchAssetTagNames(
252 BooleanFilter queryBooleanFilter, SearchContext searchContext)
253 throws Exception {
254
255 addSearchAllTags(queryBooleanFilter);
256 addSearchAnyTags(queryBooleanFilter);
257 addSearchNotAllTags(queryBooleanFilter);
258 addSearchNotAnyTags(queryBooleanFilter);
259 }
260
261 @Override
262 protected Map<String, Query> addSearchKeywords(
263 BooleanQuery searchQuery, SearchContext searchContext)
264 throws Exception {
265
266 String keywords = searchContext.getKeywords();
267
268 if (Validator.isNull(keywords)) {
269 return Collections.emptyMap();
270 }
271
272 Map<String, Query> queries = super.addSearchKeywords(
273 searchQuery, searchContext);
274
275 String field = DocumentImpl.getLocalizedName(
276 searchContext.getLocale(), "localized_title");
277
278 Query query = searchQuery.addTerm(field, keywords, true);
279
280 queries.put(field, query);
281
282 return queries;
283 }
284
285 @Override
286 protected void addSearchLayout(
287 BooleanFilter queryBooleanFilter, SearchContext searchContext)
288 throws Exception {
289
290 String layoutUuid = (String)searchContext.getAttribute(
291 Field.LAYOUT_UUID);
292
293 if (Validator.isNotNull(layoutUuid)) {
294 queryBooleanFilter.addRequiredTerm(Field.LAYOUT_UUID, layoutUuid);
295 }
296 }
297
298 protected void addSearchNotAllCategories(BooleanFilter queryBooleanFilter)
299 throws Exception {
300
301 long[] notAllCategoryIds = _assetEntryQuery.getNotAllCategoryIds();
302
303 if (notAllCategoryIds.length == 0) {
304 return;
305 }
306
307 BooleanFilter categoryIdsBooleanFilter = new BooleanFilter();
308
309 for (long notAllCategoryId : notAllCategoryIds) {
310 AssetCategory assetCategory =
311 AssetCategoryLocalServiceUtil.fetchAssetCategory(
312 notAllCategoryId);
313
314 if (assetCategory == null) {
315 continue;
316 }
317
318 List<Long> categoryIds = new ArrayList<>();
319
320 if (PropsValues.ASSET_CATEGORIES_SEARCH_HIERARCHICAL) {
321 categoryIds.addAll(
322 AssetCategoryLocalServiceUtil.getSubcategoryIds(
323 notAllCategoryId));
324 }
325
326 if (categoryIds.isEmpty()) {
327 categoryIds.add(notAllCategoryId);
328 }
329
330 TermsFilter categoryIdTermsFilter = new TermsFilter(
331 Field.ASSET_CATEGORY_IDS);
332
333 categoryIdTermsFilter.addValues(
334 ArrayUtil.toStringArray(
335 categoryIds.toArray(new Long[categoryIds.size()])));
336
337 categoryIdsBooleanFilter.add(
338 categoryIdTermsFilter, BooleanClauseOccur.MUST);
339 }
340
341 queryBooleanFilter.add(
342 categoryIdsBooleanFilter, BooleanClauseOccur.MUST_NOT);
343 }
344
345 protected void addSearchNotAllTags(BooleanFilter queryBooleanFilter)
346 throws Exception {
347
348 long[][] notAllTagIdsArray = _assetEntryQuery.getNotAllTagIdsArray();
349
350 if (notAllTagIdsArray.length == 0) {
351 return;
352 }
353
354 BooleanFilter tagIdsArrayBooleanFilter = new BooleanFilter();
355
356 for (long[] notAllTagIds : notAllTagIdsArray) {
357 if (notAllTagIds.length == 0) {
358 continue;
359 }
360
361 TermsFilter tagIdsTermsFilter = new TermsFilter(
362 Field.ASSET_TAG_IDS);
363
364 tagIdsTermsFilter.addValues(ArrayUtil.toStringArray(notAllTagIds));
365
366 tagIdsArrayBooleanFilter.add(
367 tagIdsTermsFilter, BooleanClauseOccur.MUST);
368 }
369
370 queryBooleanFilter.add(
371 tagIdsArrayBooleanFilter, BooleanClauseOccur.MUST_NOT);
372 }
373
374 protected void addSearchNotAnyCategories(BooleanFilter queryBooleanFilter)
375 throws Exception {
376
377 long[] notAnyCategoryIds = _assetEntryQuery.getNotAnyCategoryIds();
378
379 if (notAnyCategoryIds.length == 0) {
380 return;
381 }
382
383 TermsFilter categoryIdsTermsFilter = new TermsFilter(
384 Field.ASSET_CATEGORY_IDS);
385
386 for (long notAnyCategoryId : notAnyCategoryIds) {
387 AssetCategory assetCategory =
388 AssetCategoryLocalServiceUtil.fetchAssetCategory(
389 notAnyCategoryId);
390
391 if (assetCategory == null) {
392 continue;
393 }
394
395 List<Long> categoryIds = new ArrayList<>();
396
397 if (PropsValues.ASSET_CATEGORIES_SEARCH_HIERARCHICAL) {
398 categoryIds.addAll(
399 AssetCategoryLocalServiceUtil.getSubcategoryIds(
400 notAnyCategoryId));
401 }
402
403 if (categoryIds.isEmpty()) {
404 categoryIds.add(notAnyCategoryId);
405 }
406
407 categoryIdsTermsFilter.addValues(
408 ArrayUtil.toStringArray(
409 categoryIds.toArray(new Long[categoryIds.size()])));
410 }
411
412 queryBooleanFilter.add(
413 categoryIdsTermsFilter, BooleanClauseOccur.MUST_NOT);
414 }
415
416 protected void addSearchNotAnyTags(BooleanFilter queryBooleanFilter)
417 throws Exception {
418
419 long[] notAnyTagIds = _assetEntryQuery.getNotAnyTagIds();
420
421 if (notAnyTagIds.length == 0) {
422 return;
423 }
424
425 TermsFilter tagIgsTermsFilter = new TermsFilter(Field.ASSET_TAG_IDS);
426
427 tagIgsTermsFilter.addValues(ArrayUtil.toStringArray(notAnyTagIds));
428
429 queryBooleanFilter.add(tagIgsTermsFilter, BooleanClauseOccur.MUST_NOT);
430 }
431
432 @Override
433 protected void postProcessFullQuery(
434 BooleanQuery fullQuery, SearchContext searchContext)
435 throws Exception {
436
437 BooleanFilter booleanFilter = fullQuery.getPreBooleanFilter();
438
439 if (booleanFilter == null) {
440 booleanFilter = new BooleanFilter();
441 }
442
443 booleanFilter.addRequiredTerm("visible", true);
444
445 if (booleanFilter.hasClauses()) {
446 fullQuery.setPreBooleanFilter(booleanFilter);
447 }
448 }
449
450 private AssetEntryQuery _assetEntryQuery;
451
452 }