001    /**
002     * Copyright (c) 2000-2011 Liferay, Inc. All rights reserved.
003     *
004     * The contents of this file are subject to the terms of the Liferay Enterprise
005     * Subscription License ("License"). You may not use this file except in
006     * compliance with the License. You can obtain a copy of the License by
007     * contacting Liferay, Inc. See the License for the specific language governing
008     * permissions and limitations under the License, including but not limited to
009     * distribution rights of the Software.
010     *
011     *
012     *
013     */
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    
025    import java.util.Collection;
026    import java.util.Map;
027    import java.util.concurrent.ConcurrentHashMap;
028    
029    /**
030     * @author Bruno Farache
031     * @author Raymond Augé
032     * @author Michael C. Han
033     */
034    public class SearchEngineUtil {
035    
036            /**
037             * @deprecated Use {@link
038             *             com.liferay.portal.kernel.dao.orm.QueryUtil#ALL_POS}.
039             */
040            public static final int ALL_POS = -1;
041    
042            public static final String SYSTEM_ENGINE_ID = "SYSTEM_ENGINE";
043    
044            public static void addDocument(long companyId, Document document)
045                    throws SearchException {
046    
047                    addDocument(SYSTEM_ENGINE_ID, companyId, document);
048            }
049    
050            public static void addDocument(
051                            String searchEngineId, long companyId, Document document)
052                    throws SearchException {
053    
054                    if (isIndexReadOnly()) {
055                            return;
056                    }
057    
058                    if (_log.isDebugEnabled()) {
059                            _log.debug("Add document " + document.toString());
060                    }
061    
062                    _searchPermissionChecker.addPermissionFields(companyId, document);
063    
064                    SearchEngine searchEngine = _searchEngines.get(searchEngineId);
065    
066                    IndexWriter indexWriter = searchEngine.getIndexWriter();
067    
068                    SearchContext searchContext = new SearchContext();
069    
070                    searchContext.setCompanyId(companyId);
071                    searchContext.setSearchEngineId(searchEngineId);
072    
073                    indexWriter.addDocument(searchContext, document);
074            }
075    
076            public static void addDocuments(
077                            long companyId, Collection<Document> documents)
078                    throws SearchException {
079    
080                    addDocuments(SYSTEM_ENGINE_ID, companyId, documents);
081            }
082    
083            public static void addDocuments(
084                            String searchEngineId, long companyId,
085                            Collection<Document> documents)
086                    throws SearchException {
087    
088                    if (isIndexReadOnly() || (documents == null) || documents.isEmpty()) {
089                            return;
090                    }
091    
092                    for (Document document : documents) {
093                            if (_log.isDebugEnabled()) {
094                                    _log.debug("Add document " + document.toString());
095                            }
096    
097                            _searchPermissionChecker.addPermissionFields(companyId, document);
098                    }
099    
100                    SearchEngine searchEngine = _searchEngines.get(searchEngineId);
101    
102                    IndexWriter indexWriter = searchEngine.getIndexWriter();
103    
104                    SearchContext searchContext = new SearchContext();
105    
106                    searchContext.setCompanyId(companyId);
107                    searchContext.setSearchEngineId(searchEngineId);
108    
109                    indexWriter.addDocuments(searchContext, documents);
110            }
111    
112            public static void addSearchEngine(SearchEngine searchEngine) {
113                    _searchEngines.put(searchEngine.getName(), searchEngine);
114            }
115    
116            public static void deleteDocument(long companyId, String uid)
117                    throws SearchException {
118    
119                    deleteDocument(SYSTEM_ENGINE_ID, companyId, uid);
120            }
121    
122            public static void deleteDocument(
123                            String searchEngineId, long companyId, String uid)
124                    throws SearchException {
125    
126                    if (isIndexReadOnly()) {
127                            return;
128                    }
129    
130                    SearchEngine searchEngine = _searchEngines.get(searchEngineId);
131    
132                    IndexWriter indexWriter = searchEngine.getIndexWriter();
133    
134                    SearchContext searchContext = new SearchContext();
135    
136                    searchContext.setCompanyId(companyId);
137                    searchContext.setSearchEngineId(searchEngineId);
138    
139                    indexWriter.deleteDocument(searchContext, uid);
140            }
141    
142            public static void deleteDocuments(long companyId, Collection<String> uids)
143                    throws SearchException {
144    
145                    deleteDocuments(SYSTEM_ENGINE_ID, companyId, uids);
146            }
147    
148            public static void deleteDocuments(
149                            String searchEngineId, long companyId, Collection<String> uids)
150                    throws SearchException {
151    
152                    if (isIndexReadOnly() || (uids == null) || uids.isEmpty()) {
153                            return;
154                    }
155    
156                    SearchEngine searchEngine = _searchEngines.get(searchEngineId);
157    
158                    IndexWriter indexWriter = searchEngine.getIndexWriter();
159    
160                    SearchContext searchContext = new SearchContext();
161    
162                    searchContext.setCompanyId(companyId);
163                    searchContext.setSearchEngineId(searchEngineId);
164    
165                    indexWriter.deleteDocuments(searchContext, uids);
166            }
167    
168            public static void deletePortletDocuments(
169                            long companyId, String portletId)
170                    throws SearchException {
171    
172                    deletePortletDocuments(SYSTEM_ENGINE_ID, companyId, portletId);
173            }
174    
175            public static void deletePortletDocuments(
176                            String searchEngineId, long companyId, String portletId)
177                    throws SearchException {
178    
179                    if (isIndexReadOnly()) {
180                            return;
181                    }
182    
183                    SearchEngine searchEngine = _searchEngines.get(searchEngineId);
184    
185                    IndexWriter indexWriter = searchEngine.getIndexWriter();
186    
187                    SearchContext searchContext = new SearchContext();
188    
189                    searchContext.setCompanyId(companyId);
190                    searchContext.setSearchEngineId(searchEngineId);
191    
192                    indexWriter.deletePortletDocuments(searchContext, portletId);
193            }
194    
195            public static SearchEngine getSearchEngine() {
196                    return getSearchEngine(SYSTEM_ENGINE_ID);
197            }
198    
199            public static SearchEngine getSearchEngine(String searchEngineId) {
200                    return _searchEngines.get(searchEngineId);
201            }
202    
203            public static SearchPermissionChecker getSearchPermissionChecker() {
204                    return _searchPermissionChecker;
205            }
206    
207            public static String getSearchReaderDestinationName(String searchEngineId) {
208                    return DestinationNames.SEARCH_READER.concat(StringPool.SLASH).concat(
209                            searchEngineId);
210            }
211    
212            public static String getSearchWriterDestinationName(String searchEngineId) {
213                    return DestinationNames.SEARCH_WRITER.concat(StringPool.SLASH).concat(
214                            searchEngineId);
215            }
216    
217            public static boolean isIndexReadOnly() {
218                    return _indexReadOnly;
219            }
220    
221            public static SearchEngine removeSearchEngine(String searchEngineName) {
222                    return _searchEngines.remove(searchEngineName);
223            }
224    
225            public static Hits search(
226                            long companyId, long[] groupIds, long userId, String className,
227                            Query query, int start, int end)
228                    throws SearchException {
229    
230                    SearchContext searchContext = new SearchContext();
231    
232                    searchContext.setSearchEngineId(SearchEngineUtil.SYSTEM_ENGINE_ID);
233    
234                    if (userId > 0) {
235                            query = _searchPermissionChecker.getPermissionQuery(
236                                    companyId, groupIds, userId, className, query, searchContext);
237                    }
238    
239                    return search(
240                            companyId, query, SortFactoryUtil.getDefaultSorts(), start, end);
241            }
242    
243            public static Hits search(
244                            long companyId, long[] groupIds, long userId, String className,
245                            Query query, Sort sort, int start, int end)
246                    throws SearchException {
247    
248                    SearchContext searchContext = new SearchContext();
249    
250                    searchContext.setSearchEngineId(SearchEngineUtil.SYSTEM_ENGINE_ID);
251    
252                    if (userId > 0) {
253                            query = _searchPermissionChecker.getPermissionQuery(
254                                    companyId, groupIds, userId, className, query, searchContext);
255                    }
256    
257                    return search(companyId, query, sort, start, end);
258            }
259    
260            public static Hits search(
261                            long companyId, long[] groupIds, long userId, String className,
262                            Query query, Sort[] sorts, int start, int end)
263                    throws SearchException {
264    
265                    SearchContext searchContext = new SearchContext();
266    
267                    searchContext.setSearchEngineId(SearchEngineUtil.SYSTEM_ENGINE_ID);
268    
269                    if (userId > 0) {
270                            query = _searchPermissionChecker.getPermissionQuery(
271                                    companyId, groupIds, userId, className, query, searchContext);
272                    }
273    
274                    return search(companyId, query, sorts, start, end);
275            }
276    
277            public static Hits search(long companyId, Query query, int start, int end)
278                    throws SearchException {
279    
280                    return search(SYSTEM_ENGINE_ID, companyId, query, start, end);
281            }
282    
283            public static Hits search(
284                            long companyId, Query query, Sort sort, int start, int end)
285                    throws SearchException {
286    
287                    return search(SYSTEM_ENGINE_ID, companyId, query, sort, start, end);
288            }
289    
290            public static Hits search(
291                            long companyId, Query query, Sort[] sorts, int start, int end)
292                    throws SearchException {
293    
294                    return search(SYSTEM_ENGINE_ID, companyId, query, sorts, start, end);
295            }
296    
297            public static Hits search(SearchContext searchContext, Query query)
298                    throws SearchException {
299    
300                    if (_log.isDebugEnabled()) {
301                            _log.debug("Search query " + query.toString());
302                    }
303    
304                    SearchEngine searchEngine = _searchEngines.get(
305                            searchContext.getSearchEngineId());
306    
307                    IndexSearcher indexSearcher = searchEngine.getIndexSearcher();
308    
309                    return indexSearcher.search(searchContext, query);
310            }
311    
312            public static Hits search(
313                            String searchEngineId, long companyId, Query query, int start,
314                            int end)
315                    throws SearchException {
316    
317                    if (_log.isDebugEnabled()) {
318                            _log.debug("Search query " + query.toString());
319                    }
320    
321                    SearchEngine searchEngine = _searchEngines.get(searchEngineId);
322    
323                    IndexSearcher indexSearcher = searchEngine.getIndexSearcher();
324    
325                    return indexSearcher.search(
326                            searchEngineId, companyId, query, SortFactoryUtil.getDefaultSorts(),
327                            start, end);
328            }
329    
330            public static Hits search(
331                            String searchEngineId, long companyId, Query query, Sort sort,
332                            int start, int end)
333                    throws SearchException {
334    
335                    if (_log.isDebugEnabled()) {
336                            _log.debug("Search query " + query.toString());
337                    }
338    
339                    SearchEngine searchEngine = _searchEngines.get(searchEngineId);
340    
341                    IndexSearcher indexSearcher = searchEngine.getIndexSearcher();
342    
343                    return indexSearcher.search(
344                            searchEngineId, companyId, query, new Sort[] {sort}, start, end);
345            }
346    
347            public static Hits search(
348                            String searchEngineId, long companyId, Query query, Sort[] sorts,
349                            int start, int end)
350                    throws SearchException {
351    
352                    if (_log.isDebugEnabled()) {
353                            _log.debug("Search query " + query.toString());
354                    }
355    
356                    SearchEngine searchEngine = _searchEngines.get(searchEngineId);
357    
358                    IndexSearcher indexSearcher = searchEngine.getIndexSearcher();
359    
360                    return indexSearcher.search(
361                            searchEngineId, companyId, query, sorts, start, end);
362            }
363    
364            public static void setIndexReadOnly(boolean indexReadOnly) {
365                    _indexReadOnly = indexReadOnly;
366            }
367    
368            public static void updateDocument(long companyId, Document document)
369                    throws SearchException {
370    
371                    updateDocument(SYSTEM_ENGINE_ID, companyId, document);
372            }
373    
374            public static void updateDocument(
375                            String searchEngineId, long companyId, Document document)
376                    throws SearchException {
377    
378                    if (isIndexReadOnly()) {
379                            return;
380                    }
381    
382                    if (_log.isDebugEnabled()) {
383                            _log.debug("Document " + document.toString());
384                    }
385    
386                    _searchPermissionChecker.addPermissionFields(companyId, document);
387    
388                    SearchEngine searchEngine = _searchEngines.get(searchEngineId);
389    
390                    IndexWriter indexWriter = searchEngine.getIndexWriter();
391    
392                    SearchContext searchContext = new SearchContext();
393    
394                    searchContext.setCompanyId(companyId);
395                    searchContext.setSearchEngineId(searchEngineId);
396    
397                    indexWriter.updateDocument(searchContext, document);
398            }
399    
400            public static void updateDocuments(
401                            long companyId, Collection<Document> documents)
402                    throws SearchException {
403    
404                    updateDocuments(SYSTEM_ENGINE_ID, companyId, documents);
405            }
406    
407            public static void updateDocuments(
408                            String searchEngineId, long companyId,
409                            Collection<Document> documents)
410                    throws SearchException {
411    
412                    if (isIndexReadOnly() || (documents == null) || documents.isEmpty()) {
413                            return;
414                    }
415    
416                    for (Document document : documents) {
417                            if (_log.isDebugEnabled()) {
418                                    _log.debug("Document " + document.toString());
419                            }
420    
421                            _searchPermissionChecker.addPermissionFields(companyId, document);
422                    }
423    
424                    SearchEngine searchEngine = _searchEngines.get(searchEngineId);
425    
426                    IndexWriter indexWriter = searchEngine.getIndexWriter();
427    
428                    SearchContext searchContext = new SearchContext();
429    
430                    searchContext.setCompanyId(companyId);
431                    searchContext.setSearchEngineId(searchEngineId);
432    
433                    indexWriter.updateDocuments(searchContext, documents);
434            }
435    
436            public static void updatePermissionFields(long resourceId) {
437                    if (isIndexReadOnly()) {
438                            return;
439                    }
440    
441                    _searchPermissionChecker.updatePermissionFields(resourceId);
442            }
443    
444            public static void updatePermissionFields(String name, String primKey) {
445                    if (isIndexReadOnly()) {
446                            return;
447                    }
448    
449                    _searchPermissionChecker.updatePermissionFields(name, primKey);
450            }
451    
452            public void setSearchEngine(SearchEngine searchEngine) {
453                    _searchEngines.put(SYSTEM_ENGINE_ID, searchEngine);
454            }
455    
456            public void setSearchEngines(Map<String,SearchEngine> searchEngines) {
457                    _searchEngines.putAll(searchEngines);
458            }
459    
460            public void setSearchPermissionChecker(
461                    SearchPermissionChecker searchPermissionChecker) {
462    
463                    _searchPermissionChecker = searchPermissionChecker;
464            }
465    
466            private static Log _log = LogFactoryUtil.getLog(SearchEngineUtil.class);
467    
468            private static boolean _indexReadOnly = GetterUtil.getBoolean(
469                    PropsUtil.get(PropsKeys.INDEX_READ_ONLY));
470            private static Map<String, SearchEngine> _searchEngines =
471                    new ConcurrentHashMap<String,SearchEngine>();
472            private static SearchPermissionChecker _searchPermissionChecker;
473    
474    }