001    /**
002     * Copyright (c) 2000-present 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.portal.kernel.search;
016    
017    import com.liferay.portal.kernel.search.facet.Facet;
018    import com.liferay.portal.kernel.util.GetterUtil;
019    import com.liferay.portal.kernel.util.SetUtil;
020    import com.liferay.portal.kernel.util.UnicodeProperties;
021    import com.liferay.portal.kernel.util.Validator;
022    import com.liferay.portlet.expando.model.ExpandoBridge;
023    import com.liferay.portlet.expando.model.ExpandoColumnConstants;
024    import com.liferay.portlet.expando.util.ExpandoBridgeFactoryUtil;
025    import com.liferay.portlet.expando.util.ExpandoBridgeIndexerUtil;
026    
027    import java.util.Map;
028    import java.util.Set;
029    
030    /**
031     * @author Raymond Aug??
032     */
033    public class FacetedSearcher extends BaseSearcher {
034    
035            public static Indexer getInstance() {
036                    return new FacetedSearcher();
037            }
038    
039            @Override
040            public String[] getClassNames() {
041                    return null;
042            }
043    
044            protected void addSearchExpandoKeywords(
045                            BooleanQuery searchQuery, SearchContext searchContext,
046                            String keywords, String className)
047                    throws Exception {
048    
049                    ExpandoBridge expandoBridge = ExpandoBridgeFactoryUtil.getExpandoBridge(
050                            searchContext.getCompanyId(), className);
051    
052                    Set<String> attributeNames = SetUtil.fromEnumeration(
053                            expandoBridge.getAttributeNames());
054    
055                    for (String attributeName : attributeNames) {
056                            UnicodeProperties properties = expandoBridge.getAttributeProperties(
057                                    attributeName);
058    
059                            int indexType = GetterUtil.getInteger(
060                                    properties.getProperty(ExpandoColumnConstants.INDEX_TYPE));
061    
062                            if (indexType != ExpandoColumnConstants.INDEX_TYPE_NONE) {
063                                    String fieldName = ExpandoBridgeIndexerUtil.encodeFieldName(
064                                            attributeName);
065    
066                                    if (searchContext.isAndSearch()) {
067                                            searchQuery.addRequiredTerm(fieldName, keywords);
068                                    }
069                                    else {
070                                            searchQuery.addTerm(fieldName, keywords);
071                                    }
072                            }
073                    }
074            }
075    
076            @Override
077            protected BooleanQuery createFullQuery(
078                            BooleanQuery contextQuery, SearchContext searchContext)
079                    throws Exception {
080    
081                    BooleanQuery searchQuery = BooleanQueryFactoryUtil.create(
082                            searchContext);
083    
084                    String keywords = searchContext.getKeywords();
085    
086                    if (Validator.isNotNull(keywords)) {
087                            addSearchLocalizedTerm(
088                                    searchQuery, searchContext, Field.ASSET_CATEGORY_TITLES, false);
089    
090                            searchQuery.addExactTerm(Field.ASSET_TAG_NAMES, keywords);
091    
092                            int groupId = GetterUtil.getInteger(
093                                    searchContext.getAttribute(Field.GROUP_ID));
094    
095                            if (groupId == 0) {
096                                    searchQuery.addTerm(
097                                            Field.STAGING_GROUP, "true", false,
098                                            BooleanClauseOccur.MUST_NOT);
099                            }
100    
101                            searchQuery.addTerms(Field.KEYWORDS, keywords);
102                    }
103    
104                    for (String entryClassName : searchContext.getEntryClassNames()) {
105                            Indexer indexer = IndexerRegistryUtil.getIndexer(entryClassName);
106    
107                            if (indexer == null) {
108                                    continue;
109                            }
110    
111                            String searchEngineId = searchContext.getSearchEngineId();
112    
113                            if (!searchEngineId.equals(indexer.getSearchEngineId())) {
114                                    continue;
115                            }
116    
117                            if (Validator.isNotNull(keywords)) {
118                                    addSearchExpandoKeywords(
119                                            searchQuery, searchContext, keywords, entryClassName);
120                            }
121    
122                            indexer.postProcessSearchQuery(searchQuery, searchContext);
123    
124                            for (IndexerPostProcessor indexerPostProcessor :
125                                            indexer.getIndexerPostProcessors()) {
126    
127                                    indexerPostProcessor.postProcessSearchQuery(
128                                            searchQuery, searchContext);
129                            }
130                    }
131    
132                    Map<String, Facet> facets = searchContext.getFacets();
133    
134                    for (Facet facet : facets.values()) {
135                            BooleanClause facetClause = facet.getFacetClause();
136    
137                            if (facetClause != null) {
138                                    contextQuery.add(
139                                            facetClause.getQuery(),
140                                            facetClause.getBooleanClauseOccur());
141                            }
142                    }
143    
144                    BooleanQuery fullQuery = BooleanQueryFactoryUtil.create(searchContext);
145    
146                    fullQuery.add(contextQuery, BooleanClauseOccur.MUST);
147    
148                    if (searchQuery.hasClauses()) {
149                            fullQuery.add(searchQuery, BooleanClauseOccur.MUST);
150                    }
151    
152                    BooleanClause[] booleanClauses = searchContext.getBooleanClauses();
153    
154                    if (booleanClauses != null) {
155                            for (BooleanClause booleanClause : booleanClauses) {
156                                    fullQuery.add(
157                                            booleanClause.getQuery(),
158                                            booleanClause.getBooleanClauseOccur());
159                            }
160                    }
161    
162                    for (String entryClassName : searchContext.getEntryClassNames()) {
163                            Indexer indexer = IndexerRegistryUtil.getIndexer(entryClassName);
164    
165                            if (indexer == null) {
166                                    continue;
167                            }
168    
169                            String searchEngineId = searchContext.getSearchEngineId();
170    
171                            if (!searchEngineId.equals(indexer.getSearchEngineId())) {
172                                    continue;
173                            }
174    
175                            for (IndexerPostProcessor indexerPostProcessor :
176                                            indexer.getIndexerPostProcessors()) {
177    
178                                    indexerPostProcessor.postProcessFullQuery(
179                                            fullQuery, searchContext);
180                            }
181                    }
182    
183                    return fullQuery;
184            }
185    
186            @Override
187            protected Hits doSearch(SearchContext searchContext)
188                    throws SearchException {
189    
190                    try {
191                            searchContext.setSearchEngineId(getSearchEngineId());
192    
193                            BooleanQuery contextQuery = BooleanQueryFactoryUtil.create(
194                                    searchContext);
195    
196                            contextQuery.addRequiredTerm(
197                                    Field.COMPANY_ID, searchContext.getCompanyId());
198    
199                            BooleanQuery fullQuery = createFullQuery(
200                                    contextQuery, searchContext);
201    
202                            QueryConfig queryConfig = searchContext.getQueryConfig();
203    
204                            fullQuery.setQueryConfig(queryConfig);
205    
206                            return SearchEngineUtil.search(searchContext, fullQuery);
207                    }
208                    catch (Exception e) {
209                            throw new SearchException(e);
210                    }
211            }
212    
213            @Override
214            protected boolean isUseSearchResultPermissionFilter(
215                    SearchContext searchContext) {
216    
217                    if (searchContext.getEntryClassNames() == null) {
218                            return super.isFilterSearch();
219                    }
220    
221                    for (String entryClassName : searchContext.getEntryClassNames()) {
222                            Indexer indexer = IndexerRegistryUtil.getIndexer(entryClassName);
223    
224                            if (indexer == null) {
225                                    continue;
226                            }
227    
228                            if (indexer.isFilterSearch()) {
229                                    return true;
230                            }
231                    }
232    
233                    return super.isFilterSearch();
234            }
235    
236    }