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