001    /**
002     * Copyright (c) 2000-2013 Liferay, Inc. All rights reserved.
003     *
004     * This library is free software; you can redistribute it and/or modify it under
005     * the terms of the GNU Lesser General Public License as published by the Free
006     * Software Foundation; either version 2.1 of the License, or (at your option)
007     * any later version.
008     *
009     * This library is distributed in the hope that it will be useful, but WITHOUT
010     * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
011     * FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
012     * details.
013     */
014    
015    package com.liferay.portlet.assetpublisher.util;
016    
017    import com.liferay.portal.kernel.search.BaseIndexer;
018    import com.liferay.portal.kernel.search.BooleanClauseOccur;
019    import com.liferay.portal.kernel.search.BooleanQuery;
020    import com.liferay.portal.kernel.search.BooleanQueryFactoryUtil;
021    import com.liferay.portal.kernel.search.Document;
022    import com.liferay.portal.kernel.search.DocumentImpl;
023    import com.liferay.portal.kernel.search.Field;
024    import com.liferay.portal.kernel.search.Indexer;
025    import com.liferay.portal.kernel.search.IndexerPostProcessor;
026    import com.liferay.portal.kernel.search.SearchContext;
027    import com.liferay.portal.kernel.search.Summary;
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    import com.liferay.portlet.asset.util.AssetUtil;
037    
038    import java.util.ArrayList;
039    import java.util.List;
040    import java.util.Locale;
041    
042    import javax.portlet.PortletURL;
043    
044    /**
045     * @author Eudaldo Alonso
046     */
047    public class AssetSearcher extends BaseIndexer {
048    
049            public static Indexer getInstance() {
050                    return new AssetSearcher();
051            }
052    
053            public AssetSearcher() {
054                    setFilterSearch(true);
055                    setPermissionAware(true);
056            }
057    
058            @Override
059            public String[] getClassNames() {
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            @Override
074            public IndexerPostProcessor[] getIndexerPostProcessors() {
075                    throw new UnsupportedOperationException();
076            }
077    
078            @Override
079            public String getPortletId() {
080                    return null;
081            }
082    
083            @Override
084            public void registerIndexerPostProcessor(
085                    IndexerPostProcessor indexerPostProcessor) {
086    
087                    throw new UnsupportedOperationException();
088            }
089    
090            public void setAssetEntryQuery(AssetEntryQuery assetEntryQuery) {
091                    _assetEntryQuery = assetEntryQuery;
092            }
093    
094            protected void addSearchAllCategories(
095                            BooleanQuery contextQuery, SearchContext searchContext)
096                    throws Exception {
097    
098                    PermissionChecker permissionChecker =
099                            PermissionThreadLocal.getPermissionChecker();
100    
101                    long[] allCategoryIds = AssetUtil.filterCategoryIds(
102                            permissionChecker, _assetEntryQuery.getAllCategoryIds());
103    
104                    if (allCategoryIds.length == 0) {
105                            return;
106                    }
107    
108                    BooleanQuery categoryIdsQuery = BooleanQueryFactoryUtil.create(
109                            searchContext);
110    
111                    for (long allCategoryId : allCategoryIds) {
112                            AssetCategory assetCategory =
113                                    AssetCategoryLocalServiceUtil.fetchAssetCategory(allCategoryId);
114    
115                            if (assetCategory == null) {
116                                    continue;
117                            }
118    
119                            List<Long> categoryIds = new ArrayList<Long>();
120    
121                            if (PropsValues.ASSET_CATEGORIES_SEARCH_HIERARCHICAL) {
122                                    categoryIds = AssetCategoryLocalServiceUtil.getSubcategoryIds(
123                                            allCategoryId);
124                            }
125    
126                            if (categoryIds.isEmpty()) {
127                                    categoryIds.add(allCategoryId);
128                            }
129    
130                            BooleanQuery categoryIdQuery = BooleanQueryFactoryUtil.create(
131                                    searchContext);
132    
133                            for (long categoryId : categoryIds) {
134                                    categoryIdQuery.addTerm(Field.ASSET_CATEGORY_IDS, categoryId);
135                            }
136    
137                            categoryIdsQuery.add(categoryIdQuery, BooleanClauseOccur.MUST);
138                    }
139    
140                    contextQuery.add(categoryIdsQuery, BooleanClauseOccur.MUST);
141            }
142    
143            protected void addSearchAllTags(
144                            BooleanQuery contextQuery, SearchContext searchContext)
145                    throws Exception {
146    
147                    PermissionChecker permissionChecker =
148                            PermissionThreadLocal.getPermissionChecker();
149    
150                    long[] allTagIds = AssetUtil.filterTagIds(
151                            permissionChecker, _assetEntryQuery.getAllTagIds());
152    
153                    if (allTagIds.length == 0) {
154                            return;
155                    }
156    
157                    BooleanQuery tagIdsQuery = BooleanQueryFactoryUtil.create(
158                            searchContext);
159    
160                    for (long tagId : allTagIds) {
161                            tagIdsQuery.addRequiredTerm(Field.ASSET_TAG_IDS, tagId);
162                    }
163    
164                    contextQuery.add(tagIdsQuery, BooleanClauseOccur.MUST);
165            }
166    
167            protected void addSearchAnyCategories(
168                            BooleanQuery contextQuery, SearchContext searchContext)
169                    throws Exception {
170    
171                    PermissionChecker permissionChecker =
172                            PermissionThreadLocal.getPermissionChecker();
173    
174                    long[] anyCategoryIds = AssetUtil.filterCategoryIds(
175                            permissionChecker, _assetEntryQuery.getAnyCategoryIds());
176    
177                    if (anyCategoryIds.length == 0) {
178                            return;
179                    }
180    
181                    BooleanQuery categoryIdsQuery = BooleanQueryFactoryUtil.create(
182                            searchContext);
183    
184                    for (long anyCategoryId : anyCategoryIds) {
185                            AssetCategory assetCategory =
186                                    AssetCategoryLocalServiceUtil.fetchAssetCategory(anyCategoryId);
187    
188                            if (assetCategory == null) {
189                                    continue;
190                            }
191    
192                            List<Long> categoryIds = new ArrayList<Long>();
193    
194                            if (PropsValues.ASSET_CATEGORIES_SEARCH_HIERARCHICAL) {
195                                    categoryIds = AssetCategoryLocalServiceUtil.getSubcategoryIds(
196                                            anyCategoryId);
197                            }
198    
199                            if (categoryIds.isEmpty()) {
200                                    categoryIds.add(anyCategoryId);
201                            }
202    
203                            for (long categoryId : categoryIds) {
204                                    categoryIdsQuery.addTerm(Field.ASSET_CATEGORY_IDS, categoryId);
205                            }
206                    }
207    
208                    contextQuery.add(categoryIdsQuery, BooleanClauseOccur.MUST);
209            }
210    
211            protected void addSearchAnyTags(
212                            BooleanQuery contextQuery, SearchContext searchContext)
213                    throws Exception {
214    
215                    PermissionChecker permissionChecker =
216                            PermissionThreadLocal.getPermissionChecker();
217    
218                    long[] anyTagIds = AssetUtil.filterTagIds(
219                            permissionChecker, _assetEntryQuery.getAnyTagIds());
220    
221                    if (anyTagIds.length == 0) {
222                            return;
223                    }
224    
225                    BooleanQuery tagIdsQuery = BooleanQueryFactoryUtil.create(
226                            searchContext);
227    
228                    for (long tagId : anyTagIds) {
229                            tagIdsQuery.addTerm(Field.ASSET_TAG_IDS, tagId);
230                    }
231    
232                    contextQuery.add(tagIdsQuery, BooleanClauseOccur.MUST);
233            }
234    
235            @Override
236            protected void addSearchAssetCategoryIds(
237                            BooleanQuery contextQuery, SearchContext searchContext)
238                    throws Exception {
239    
240                    addSearchAllCategories(contextQuery, searchContext);
241                    addSearchAnyCategories(contextQuery, searchContext);
242                    addSearchNotAnyCategories(contextQuery, searchContext);
243                    addSearchNotAllCategories(contextQuery, searchContext);
244            }
245    
246            @Override
247            protected void addSearchAssetTagNames(
248                            BooleanQuery contextQuery, SearchContext searchContext)
249                    throws Exception {
250    
251                    addSearchAllTags(contextQuery, searchContext);
252                    addSearchAnyTags(contextQuery, searchContext);
253                    addSearchNotAllTags(contextQuery, searchContext);
254                    addSearchNotAnyTags(contextQuery, searchContext);
255            }
256    
257            @Override
258            protected void addSearchKeywords(
259                            BooleanQuery searchQuery, SearchContext searchContext)
260                    throws Exception {
261    
262                    String keywords = searchContext.getKeywords();
263    
264                    if (Validator.isNull(keywords)) {
265                            return;
266                    }
267    
268                    super.addSearchKeywords(searchQuery, searchContext);
269    
270                    String field = DocumentImpl.getLocalizedName(
271                            searchContext.getLocale(), "localized_title");
272    
273                    searchQuery.addTerm(field, keywords, true);
274            }
275    
276            @Override
277            protected void addSearchLayout(
278                            BooleanQuery contextQuery, SearchContext searchContext)
279                    throws Exception {
280    
281                    String layoutUuid = (String)searchContext.getAttribute(
282                            Field.LAYOUT_UUID);
283    
284                    if (Validator.isNotNull(layoutUuid)) {
285                            contextQuery.addRequiredTerm(Field.LAYOUT_UUID, layoutUuid);
286                    }
287            }
288    
289            protected void addSearchNotAllCategories(
290                            BooleanQuery contextQuery, SearchContext searchContext)
291                    throws Exception {
292    
293                    long[] notAllCategoryIds = _assetEntryQuery.getNotAllCategoryIds();
294    
295                    if (notAllCategoryIds.length == 0) {
296                            return;
297                    }
298    
299                    BooleanQuery categoryIdsQuery = BooleanQueryFactoryUtil.create(
300                            searchContext);
301    
302                    for (long notAllCategoryId : notAllCategoryIds) {
303                            AssetCategory assetCategory =
304                                    AssetCategoryLocalServiceUtil.fetchAssetCategory(
305                                            notAllCategoryId);
306    
307                            if (assetCategory == null) {
308                                    continue;
309                            }
310    
311                            List<Long> categoryIds = new ArrayList<Long>();
312    
313                            if (PropsValues.ASSET_CATEGORIES_SEARCH_HIERARCHICAL) {
314                                    categoryIds = AssetCategoryLocalServiceUtil.getSubcategoryIds(
315                                            notAllCategoryId);
316                            }
317    
318                            if (categoryIds.isEmpty()) {
319                                    categoryIds.add(notAllCategoryId);
320                            }
321    
322                            BooleanQuery categoryIdQuery = BooleanQueryFactoryUtil.create(
323                                    searchContext);
324    
325                            for (long categoryId : categoryIds) {
326                                    categoryIdQuery.addTerm(Field.ASSET_CATEGORY_IDS, categoryId);
327                            }
328    
329                            categoryIdsQuery.add(categoryIdQuery, BooleanClauseOccur.MUST);
330                    }
331    
332                    contextQuery.add(categoryIdsQuery, BooleanClauseOccur.MUST_NOT);
333            }
334    
335            protected void addSearchNotAllTags(
336                            BooleanQuery contextQuery, SearchContext searchContext)
337                    throws Exception {
338    
339                    long[] notAllTagIds = _assetEntryQuery.getNotAllTagIds();
340    
341                    if (notAllTagIds.length == 0) {
342                            return;
343                    }
344    
345                    BooleanQuery tagIdsQuery = BooleanQueryFactoryUtil.create(
346                            searchContext);
347    
348                    for (long tagId : notAllTagIds) {
349                            tagIdsQuery.addRequiredTerm(Field.ASSET_TAG_IDS, tagId);
350                    }
351    
352                    contextQuery.add(tagIdsQuery, BooleanClauseOccur.MUST_NOT);
353            }
354    
355            protected void addSearchNotAnyCategories(
356                            BooleanQuery contextQuery, SearchContext searchContext)
357                    throws Exception {
358    
359                    long[] notAnyCategoryIds = _assetEntryQuery.getNotAnyCategoryIds();
360    
361                    if (notAnyCategoryIds.length == 0) {
362                            return;
363                    }
364    
365                    BooleanQuery categoryIdsQuery = BooleanQueryFactoryUtil.create(
366                            searchContext);
367    
368                    for (long notAnyCategoryId : notAnyCategoryIds) {
369                            AssetCategory assetCategory =
370                                    AssetCategoryLocalServiceUtil.fetchAssetCategory(
371                                            notAnyCategoryId);
372    
373                            if (assetCategory == null) {
374                                    continue;
375                            }
376    
377                            List<Long> categoryIds = new ArrayList<Long>();
378    
379                            if (PropsValues.ASSET_CATEGORIES_SEARCH_HIERARCHICAL) {
380                                    categoryIds = AssetCategoryLocalServiceUtil.getSubcategoryIds(
381                                            notAnyCategoryId);
382                            }
383    
384                            if (categoryIds.isEmpty()) {
385                                    categoryIds.add(notAnyCategoryId);
386                            }
387    
388                            for (long categoryId : categoryIds) {
389                                    categoryIdsQuery.addTerm(Field.ASSET_CATEGORY_IDS, categoryId);
390                            }
391                    }
392    
393                    contextQuery.add(categoryIdsQuery, BooleanClauseOccur.MUST_NOT);
394            }
395    
396            protected void addSearchNotAnyTags(
397                            BooleanQuery contextQuery, SearchContext searchContext)
398                    throws Exception {
399    
400                    long[] notAnyTagIds = _assetEntryQuery.getNotAnyTagIds();
401    
402                    if (notAnyTagIds.length == 0) {
403                            return;
404                    }
405    
406                    BooleanQuery tagIdsQuery = BooleanQueryFactoryUtil.create(
407                            searchContext);
408    
409                    for (long tagId : _assetEntryQuery.getNotAnyTagIds()) {
410                            tagIdsQuery.addTerm(Field.ASSET_TAG_IDS, tagId);
411                    }
412    
413                    contextQuery.add(tagIdsQuery, BooleanClauseOccur.MUST_NOT);
414            }
415    
416            @Override
417            protected void doDelete(Object obj) throws Exception {
418                    throw new UnsupportedOperationException();
419            }
420    
421            @Override
422            protected Document doGetDocument(Object obj) throws Exception {
423                    throw new UnsupportedOperationException();
424            }
425    
426            @Override
427            protected Summary doGetSummary(
428                            Document document, Locale locale, String snippet,
429                            PortletURL portletURL)
430                    throws Exception {
431    
432                    throw new UnsupportedOperationException();
433            }
434    
435            @Override
436            protected void doReindex(Object obj) throws Exception {
437                    throw new UnsupportedOperationException();
438            }
439    
440            @Override
441            protected void doReindex(String className, long classPK) throws Exception {
442                    throw new UnsupportedOperationException();
443            }
444    
445            @Override
446            protected void doReindex(String[] ids) throws Exception {
447                    throw new UnsupportedOperationException();
448            }
449    
450            @Override
451            protected String getPortletId(SearchContext searchContext) {
452                    return null;
453            }
454    
455            private AssetEntryQuery _assetEntryQuery;
456    
457    }