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.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.Locale;
028    import java.util.Map;
029    import java.util.Set;
030    
031    import javax.portlet.PortletURL;
032    
033    /**
034     * @author Raymond Aug??
035     */
036    public class FacetedSearcher extends BaseIndexer {
037    
038            public static Indexer getInstance() {
039                    return new FacetedSearcher();
040            }
041    
042            @Override
043            public String[] getClassNames() {
044                    return null;
045            }
046    
047            @Override
048            public IndexerPostProcessor[] getIndexerPostProcessors() {
049                    throw new UnsupportedOperationException();
050            }
051    
052            @Override
053            public String getPortletId() {
054                    return null;
055            }
056    
057            @Override
058            public void registerIndexerPostProcessor(
059                    IndexerPostProcessor indexerPostProcessor) {
060    
061                    throw new UnsupportedOperationException();
062            }
063    
064            @Override
065            public void unregisterIndexerPostProcessor(
066                    IndexerPostProcessor indexerPostProcessor) {
067    
068                    throw new UnsupportedOperationException();
069            }
070    
071            protected void addSearchExpandoKeywords(
072                            BooleanQuery searchQuery, SearchContext searchContext,
073                            String keywords, String className)
074                    throws Exception {
075    
076                    ExpandoBridge expandoBridge = ExpandoBridgeFactoryUtil.getExpandoBridge(
077                            searchContext.getCompanyId(), className);
078    
079                    Set<String> attributeNames = SetUtil.fromEnumeration(
080                            expandoBridge.getAttributeNames());
081    
082                    for (String attributeName : attributeNames) {
083                            UnicodeProperties properties = expandoBridge.getAttributeProperties(
084                                    attributeName);
085    
086                            int indexType = GetterUtil.getInteger(
087                                    properties.getProperty(ExpandoColumnConstants.INDEX_TYPE));
088    
089                            if (indexType != ExpandoColumnConstants.INDEX_TYPE_NONE) {
090                                    String fieldName = ExpandoBridgeIndexerUtil.encodeFieldName(
091                                            attributeName);
092    
093                                    if (searchContext.isAndSearch()) {
094                                            searchQuery.addRequiredTerm(fieldName, keywords);
095                                    }
096                                    else {
097                                            searchQuery.addTerm(fieldName, keywords);
098                                    }
099                            }
100                    }
101            }
102    
103            @Override
104            protected BooleanQuery createFullQuery(
105                            BooleanQuery contextQuery, SearchContext searchContext)
106                    throws Exception {
107    
108                    BooleanQuery searchQuery = BooleanQueryFactoryUtil.create(
109                            searchContext);
110    
111                    String keywords = searchContext.getKeywords();
112    
113                    if (Validator.isNotNull(keywords)) {
114                            addSearchLocalizedTerm(
115                                    searchQuery, searchContext, Field.ASSET_CATEGORY_TITLES, false);
116    
117                            searchQuery.addExactTerm(Field.ASSET_TAG_NAMES, keywords);
118                            searchQuery.addTerms(Field.KEYWORDS, keywords);
119    
120                            int groupId = GetterUtil.getInteger(
121                                    searchContext.getAttribute(Field.GROUP_ID));
122    
123                            if (groupId == 0) {
124                                    searchQuery.addTerm(
125                                            Field.STAGING_GROUP, "true", false,
126                                            BooleanClauseOccur.MUST_NOT);
127                            }
128                    }
129    
130                    for (String entryClassName : searchContext.getEntryClassNames()) {
131                            Indexer indexer = IndexerRegistryUtil.getIndexer(entryClassName);
132    
133                            if (indexer == null) {
134                                    continue;
135                            }
136    
137                            String searchEngineId = searchContext.getSearchEngineId();
138    
139                            if (!searchEngineId.equals(indexer.getSearchEngineId())) {
140                                    continue;
141                            }
142    
143                            if (Validator.isNotNull(keywords)) {
144                                    addSearchExpandoKeywords(
145                                            searchQuery, searchContext, keywords, entryClassName);
146                            }
147    
148                            indexer.postProcessSearchQuery(searchQuery, searchContext);
149    
150                            for (IndexerPostProcessor indexerPostProcessor :
151                                            indexer.getIndexerPostProcessors()) {
152    
153                                    indexerPostProcessor.postProcessSearchQuery(
154                                            searchQuery, searchContext);
155                            }
156                    }
157    
158                    Map<String, Facet> facets = searchContext.getFacets();
159    
160                    for (Facet facet : facets.values()) {
161                            BooleanClause facetClause = facet.getFacetClause();
162    
163                            if (facetClause != null) {
164                                    contextQuery.add(
165                                            facetClause.getQuery(),
166                                            facetClause.getBooleanClauseOccur());
167                            }
168                    }
169    
170                    BooleanQuery fullQuery = BooleanQueryFactoryUtil.create(searchContext);
171    
172                    fullQuery.add(contextQuery, BooleanClauseOccur.MUST);
173    
174                    if (searchQuery.hasClauses()) {
175                            fullQuery.add(searchQuery, BooleanClauseOccur.MUST);
176                    }
177    
178                    BooleanClause[] booleanClauses = searchContext.getBooleanClauses();
179    
180                    if (booleanClauses != null) {
181                            for (BooleanClause booleanClause : booleanClauses) {
182                                    fullQuery.add(
183                                            booleanClause.getQuery(),
184                                            booleanClause.getBooleanClauseOccur());
185                            }
186                    }
187    
188                    for (String entryClassName : searchContext.getEntryClassNames()) {
189                            Indexer indexer = IndexerRegistryUtil.getIndexer(entryClassName);
190    
191                            if (indexer == null) {
192                                    continue;
193                            }
194    
195                            String searchEngineId = searchContext.getSearchEngineId();
196    
197                            if (!searchEngineId.equals(indexer.getSearchEngineId())) {
198                                    continue;
199                            }
200    
201                            for (IndexerPostProcessor indexerPostProcessor :
202                                            indexer.getIndexerPostProcessors()) {
203    
204                                    indexerPostProcessor.postProcessFullQuery(
205                                            fullQuery, searchContext);
206                            }
207                    }
208    
209                    return fullQuery;
210            }
211    
212            @Override
213            protected void doDelete(Object obj) throws Exception {
214                    throw new UnsupportedOperationException();
215            }
216    
217            @Override
218            protected Document doGetDocument(Object obj) throws Exception {
219                    throw new UnsupportedOperationException();
220            }
221    
222            @Override
223            protected Summary doGetSummary(
224                            Document document, Locale locale, String snippet,
225                            PortletURL portletURL)
226                    throws Exception {
227    
228                    throw new UnsupportedOperationException();
229            }
230    
231            @Override
232            protected void doReindex(Object obj) throws Exception {
233                    throw new UnsupportedOperationException();
234            }
235    
236            @Override
237            protected void doReindex(String className, long classPK) throws Exception {
238                    throw new UnsupportedOperationException();
239            }
240    
241            @Override
242            protected void doReindex(String[] ids) throws Exception {
243                    throw new UnsupportedOperationException();
244            }
245    
246            @Override
247            protected Hits doSearch(SearchContext searchContext)
248                    throws SearchException {
249    
250                    try {
251                            searchContext.setSearchEngineId(getSearchEngineId());
252    
253                            BooleanQuery contextQuery = BooleanQueryFactoryUtil.create(
254                                    searchContext);
255    
256                            contextQuery.addRequiredTerm(
257                                    Field.COMPANY_ID, searchContext.getCompanyId());
258    
259                            BooleanQuery fullQuery = createFullQuery(
260                                    contextQuery, searchContext);
261    
262                            QueryConfig queryConfig = searchContext.getQueryConfig();
263    
264                            fullQuery.setQueryConfig(queryConfig);
265    
266                            return SearchEngineUtil.search(searchContext, fullQuery);
267                    }
268                    catch (Exception e) {
269                            throw new SearchException(e);
270                    }
271            }
272    
273            @Override
274            protected String getPortletId(SearchContext searchContext) {
275                    return null;
276            }
277    
278            /**
279             * @deprecated As of 6.2.0, replaced by {@link
280             *             #isUseSearchResultPermissionFilter(SearchContext)}
281             */
282            protected boolean isFilterSearch(SearchContext searchContext) {
283                    return isUseSearchResultPermissionFilter(searchContext);
284            }
285    
286            @Override
287            protected boolean isUseSearchResultPermissionFilter(
288                    SearchContext searchContext) {
289    
290                    if (searchContext.getEntryClassNames() == null) {
291                            return super.isFilterSearch();
292                    }
293    
294                    for (String entryClassName : searchContext.getEntryClassNames()) {
295                            Indexer indexer = IndexerRegistryUtil.getIndexer(entryClassName);
296    
297                            if (indexer == null) {
298                                    continue;
299                            }
300    
301                            if (indexer.isFilterSearch()) {
302                                    return true;
303                            }
304                    }
305    
306                    return super.isFilterSearch();
307            }
308    
309    }