001
014
015 package com.liferay.portal.kernel.search;
016
017 import com.liferay.portal.kernel.log.Log;
018 import com.liferay.portal.kernel.log.LogFactoryUtil;
019 import com.liferay.portal.kernel.messaging.DestinationNames;
020 import com.liferay.portal.kernel.util.GetterUtil;
021 import com.liferay.portal.kernel.util.PropsKeys;
022 import com.liferay.portal.kernel.util.PropsUtil;
023 import com.liferay.portal.kernel.util.StringPool;
024 import com.liferay.portal.security.permission.PermissionThreadLocal;
025
026 import java.util.Collection;
027 import java.util.HashSet;
028 import java.util.List;
029 import java.util.Map;
030 import java.util.Set;
031 import java.util.concurrent.ConcurrentHashMap;
032
033
038 public class SearchEngineUtil {
039
040
044 public static final int ALL_POS = -1;
045
046 public static final String GENERIC_ENGINE_ID = "GENERIC_ENGINE";
047
048 public static final String SYSTEM_ENGINE_ID = "SYSTEM_ENGINE";
049
050 public static void addDocument(long companyId, Document document)
051 throws SearchException {
052
053 addDocument(SYSTEM_ENGINE_ID, companyId, document);
054 }
055
056 public static void addDocument(
057 String searchEngineId, long companyId, Document document)
058 throws SearchException {
059
060 if (isIndexReadOnly()) {
061 return;
062 }
063
064 if (_log.isDebugEnabled()) {
065 _log.debug("Add document " + document.toString());
066 }
067
068 _searchPermissionChecker.addPermissionFields(companyId, document);
069
070 SearchEngine searchEngine = _searchEngines.get(searchEngineId);
071
072 IndexWriter indexWriter = searchEngine.getIndexWriter();
073
074 SearchContext searchContext = new SearchContext();
075
076 searchContext.setCompanyId(companyId);
077 searchContext.setSearchEngineId(searchEngineId);
078
079 indexWriter.addDocument(searchContext, document);
080 }
081
082 public static void addDocuments(
083 long companyId, Collection<Document> documents)
084 throws SearchException {
085
086 addDocuments(SYSTEM_ENGINE_ID, companyId, documents);
087 }
088
089 public static void addDocuments(
090 String searchEngineId, long companyId,
091 Collection<Document> documents)
092 throws SearchException {
093
094 if (isIndexReadOnly() || (documents == null) || documents.isEmpty()) {
095 return;
096 }
097
098 for (Document document : documents) {
099 if (_log.isDebugEnabled()) {
100 _log.debug("Add document " + document.toString());
101 }
102
103 _searchPermissionChecker.addPermissionFields(companyId, document);
104 }
105
106 SearchEngine searchEngine = _searchEngines.get(searchEngineId);
107
108 IndexWriter indexWriter = searchEngine.getIndexWriter();
109
110 SearchContext searchContext = new SearchContext();
111
112 searchContext.setCompanyId(companyId);
113 searchContext.setSearchEngineId(searchEngineId);
114
115 indexWriter.addDocuments(searchContext, documents);
116 }
117
118 public static void addSearchEngine(SearchEngine searchEngine) {
119 _searchEngines.put(searchEngine.getName(), searchEngine);
120 }
121
122 public static void deleteDocument(long companyId, String uid)
123 throws SearchException {
124
125 deleteDocument(SYSTEM_ENGINE_ID, companyId, uid);
126 }
127
128 public static void deleteDocument(
129 String searchEngineId, long companyId, String uid)
130 throws SearchException {
131
132 if (isIndexReadOnly()) {
133 return;
134 }
135
136 SearchEngine searchEngine = _searchEngines.get(searchEngineId);
137
138 IndexWriter indexWriter = searchEngine.getIndexWriter();
139
140 SearchContext searchContext = new SearchContext();
141
142 searchContext.setCompanyId(companyId);
143 searchContext.setSearchEngineId(searchEngineId);
144
145 indexWriter.deleteDocument(searchContext, uid);
146 }
147
148 public static void deleteDocuments(long companyId, Collection<String> uids)
149 throws SearchException {
150
151 deleteDocuments(SYSTEM_ENGINE_ID, companyId, uids);
152 }
153
154 public static void deleteDocuments(
155 String searchEngineId, long companyId, Collection<String> uids)
156 throws SearchException {
157
158 if (isIndexReadOnly() || (uids == null) || uids.isEmpty()) {
159 return;
160 }
161
162 SearchEngine searchEngine = _searchEngines.get(searchEngineId);
163
164 IndexWriter indexWriter = searchEngine.getIndexWriter();
165
166 SearchContext searchContext = new SearchContext();
167
168 searchContext.setCompanyId(companyId);
169 searchContext.setSearchEngineId(searchEngineId);
170
171 indexWriter.deleteDocuments(searchContext, uids);
172 }
173
174 public static void deletePortletDocuments(long companyId, String portletId)
175 throws SearchException {
176
177 deletePortletDocuments(SYSTEM_ENGINE_ID, companyId, portletId);
178 }
179
180 public static void deletePortletDocuments(
181 String searchEngineId, long companyId, String portletId)
182 throws SearchException {
183
184 if (isIndexReadOnly()) {
185 return;
186 }
187
188 SearchEngine searchEngine = _searchEngines.get(searchEngineId);
189
190 if (searchEngine == null) {
191 return;
192 }
193
194 IndexWriter indexWriter = searchEngine.getIndexWriter();
195
196 SearchContext searchContext = new SearchContext();
197
198 searchContext.setCompanyId(companyId);
199 searchContext.setSearchEngineId(searchEngineId);
200
201 indexWriter.deletePortletDocuments(searchContext, portletId);
202 }
203
204 public static String[] getEntryClassNames() {
205 Set<String> assetEntryClassNames = new HashSet<String>();
206
207 for (Indexer indexer : IndexerRegistryUtil.getIndexers()) {
208 for (String className : indexer.getClassNames()) {
209 if (!_excludedEntryClassNames.contains(className)) {
210 assetEntryClassNames.add(className);
211 }
212 }
213 }
214
215 return assetEntryClassNames.toArray(
216 new String[assetEntryClassNames.size()]);
217 }
218
219 public static SearchEngine getSearchEngine() {
220 return getSearchEngine(SYSTEM_ENGINE_ID);
221 }
222
223 public static SearchEngine getSearchEngine(String searchEngineId) {
224 return _searchEngines.get(searchEngineId);
225 }
226
227 public static SearchPermissionChecker getSearchPermissionChecker() {
228 return _searchPermissionChecker;
229 }
230
231 public static String getSearchReaderDestinationName(String searchEngineId) {
232 return DestinationNames.SEARCH_READER.concat(StringPool.SLASH).concat(
233 searchEngineId);
234 }
235
236 public static String getSearchWriterDestinationName(String searchEngineId) {
237 return DestinationNames.SEARCH_WRITER.concat(StringPool.SLASH).concat(
238 searchEngineId);
239 }
240
241 public static boolean isIndexReadOnly() {
242 return _indexReadOnly;
243 }
244
245 public static SearchEngine removeSearchEngine(String searchEngineName) {
246 return _searchEngines.remove(searchEngineName);
247 }
248
249 public static Hits search(
250 long companyId, long[] groupIds, long userId, String className,
251 Query query, int start, int end)
252 throws SearchException {
253
254 SearchContext searchContext = new SearchContext();
255
256 searchContext.setSearchEngineId(SearchEngineUtil.SYSTEM_ENGINE_ID);
257
258 if (userId > 0) {
259 query = _searchPermissionChecker.getPermissionQuery(
260 companyId, groupIds, userId, className, query, searchContext);
261 }
262
263 return search(
264 companyId, query, SortFactoryUtil.getDefaultSorts(), start, end);
265 }
266
267 public static Hits search(
268 long companyId, long[] groupIds, long userId, String className,
269 Query query, Sort sort, int start, int end)
270 throws SearchException {
271
272 SearchContext searchContext = new SearchContext();
273
274 searchContext.setSearchEngineId(SearchEngineUtil.SYSTEM_ENGINE_ID);
275
276 if (userId > 0) {
277 query = _searchPermissionChecker.getPermissionQuery(
278 companyId, groupIds, userId, className, query, searchContext);
279 }
280
281 return search(companyId, query, sort, start, end);
282 }
283
284 public static Hits search(
285 long companyId, long[] groupIds, long userId, String className,
286 Query query, Sort[] sorts, int start, int end)
287 throws SearchException {
288
289 SearchContext searchContext = new SearchContext();
290
291 searchContext.setSearchEngineId(SearchEngineUtil.SYSTEM_ENGINE_ID);
292
293 if (userId > 0) {
294 query = _searchPermissionChecker.getPermissionQuery(
295 companyId, groupIds, userId, className, query, searchContext);
296 }
297
298 return search(companyId, query, sorts, start, end);
299 }
300
301 public static Hits search(long companyId, Query query, int start, int end)
302 throws SearchException {
303
304 return search(SYSTEM_ENGINE_ID, companyId, query, start, end);
305 }
306
307 public static Hits search(
308 long companyId, Query query, Sort sort, int start, int end)
309 throws SearchException {
310
311 return search(SYSTEM_ENGINE_ID, companyId, query, sort, start, end);
312 }
313
314 public static Hits search(
315 long companyId, Query query, Sort[] sorts, int start, int end)
316 throws SearchException {
317
318 return search(SYSTEM_ENGINE_ID, companyId, query, sorts, start, end);
319 }
320
321 public static Hits search(SearchContext searchContext, Query query)
322 throws SearchException {
323
324 if (_log.isDebugEnabled()) {
325 _log.debug("Search query " + query.toString());
326 }
327
328 SearchEngine searchEngine = _searchEngines.get(
329 searchContext.getSearchEngineId());
330
331 IndexSearcher indexSearcher = searchEngine.getIndexSearcher();
332
333 return indexSearcher.search(searchContext, query);
334 }
335
336 public static Hits search(
337 String searchEngineId, long companyId, Query query, int start,
338 int end)
339 throws SearchException {
340
341 if (_log.isDebugEnabled()) {
342 _log.debug("Search query " + query.toString());
343 }
344
345 SearchEngine searchEngine = _searchEngines.get(searchEngineId);
346
347 IndexSearcher indexSearcher = searchEngine.getIndexSearcher();
348
349 return indexSearcher.search(
350 searchEngineId, companyId, query, SortFactoryUtil.getDefaultSorts(),
351 start, end);
352 }
353
354 public static Hits search(
355 String searchEngineId, long companyId, Query query, Sort sort,
356 int start, int end)
357 throws SearchException {
358
359 if (_log.isDebugEnabled()) {
360 _log.debug("Search query " + query.toString());
361 }
362
363 SearchEngine searchEngine = _searchEngines.get(searchEngineId);
364
365 IndexSearcher indexSearcher = searchEngine.getIndexSearcher();
366
367 return indexSearcher.search(
368 searchEngineId, companyId, query, new Sort[] {sort}, start, end);
369 }
370
371 public static Hits search(
372 String searchEngineId, long companyId, Query query, Sort[] sorts,
373 int start, int end)
374 throws SearchException {
375
376 if (_log.isDebugEnabled()) {
377 _log.debug("Search query " + query.toString());
378 }
379
380 SearchEngine searchEngine = _searchEngines.get(searchEngineId);
381
382 IndexSearcher indexSearcher = searchEngine.getIndexSearcher();
383
384 return indexSearcher.search(
385 searchEngineId, companyId, query, sorts, start, end);
386 }
387
388 public static void setIndexReadOnly(boolean indexReadOnly) {
389 _indexReadOnly = indexReadOnly;
390 }
391
392 public static void updateDocument(long companyId, Document document)
393 throws SearchException {
394
395 updateDocument(SYSTEM_ENGINE_ID, companyId, document);
396 }
397
398 public static void updateDocument(
399 String searchEngineId, long companyId, Document document)
400 throws SearchException {
401
402 if (isIndexReadOnly()) {
403 return;
404 }
405
406 if (_log.isDebugEnabled()) {
407 _log.debug("Document " + document.toString());
408 }
409
410 _searchPermissionChecker.addPermissionFields(companyId, document);
411
412 SearchEngine searchEngine = _searchEngines.get(searchEngineId);
413
414 IndexWriter indexWriter = searchEngine.getIndexWriter();
415
416 SearchContext searchContext = new SearchContext();
417
418 searchContext.setCompanyId(companyId);
419 searchContext.setSearchEngineId(searchEngineId);
420
421 indexWriter.updateDocument(searchContext, document);
422 }
423
424 public static void updateDocuments(
425 long companyId, Collection<Document> documents)
426 throws SearchException {
427
428 updateDocuments(SYSTEM_ENGINE_ID, companyId, documents);
429 }
430
431 public static void updateDocuments(
432 String searchEngineId, long companyId,
433 Collection<Document> documents)
434 throws SearchException {
435
436 if (isIndexReadOnly() || (documents == null) || documents.isEmpty()) {
437 return;
438 }
439
440 for (Document document : documents) {
441 if (_log.isDebugEnabled()) {
442 _log.debug("Document " + document.toString());
443 }
444
445 _searchPermissionChecker.addPermissionFields(companyId, document);
446 }
447
448 SearchEngine searchEngine = _searchEngines.get(searchEngineId);
449
450 IndexWriter indexWriter = searchEngine.getIndexWriter();
451
452 SearchContext searchContext = new SearchContext();
453
454 searchContext.setCompanyId(companyId);
455 searchContext.setSearchEngineId(searchEngineId);
456
457 indexWriter.updateDocuments(searchContext, documents);
458 }
459
460 public static void updatePermissionFields(long resourceId) {
461 if (isIndexReadOnly() || !PermissionThreadLocal.isFlushEnabled()) {
462 return;
463 }
464
465 _searchPermissionChecker.updatePermissionFields(resourceId);
466 }
467
468 public static void updatePermissionFields(String name, String primKey) {
469 if (isIndexReadOnly() || !PermissionThreadLocal.isFlushEnabled()) {
470 return;
471 }
472
473 _searchPermissionChecker.updatePermissionFields(name, primKey);
474 }
475
476 public void setExcludedEntryClassNames(
477 List<String> excludedEntryClassNames) {
478
479 _excludedEntryClassNames.addAll(excludedEntryClassNames);
480 }
481
482 public void setSearchEngine(SearchEngine searchEngine) {
483 _searchEngines.put(SYSTEM_ENGINE_ID, searchEngine);
484 }
485
486 public void setSearchEngines(Map<String, SearchEngine> searchEngines) {
487 _searchEngines.putAll(searchEngines);
488 }
489
490 public void setSearchPermissionChecker(
491 SearchPermissionChecker searchPermissionChecker) {
492
493 _searchPermissionChecker = searchPermissionChecker;
494 }
495
496 private static Log _log = LogFactoryUtil.getLog(SearchEngineUtil.class);
497
498 private static Set<String> _excludedEntryClassNames = new HashSet<String>();
499 private static boolean _indexReadOnly = GetterUtil.getBoolean(
500 PropsUtil.get(PropsKeys.INDEX_READ_ONLY));
501 private static Map<String, SearchEngine> _searchEngines =
502 new ConcurrentHashMap<String, SearchEngine>();
503 private static SearchPermissionChecker _searchPermissionChecker;
504
505 }