001    /**
002     * Copyright (c) 2000-2010 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.servlet;
016    
017    import com.liferay.portal.kernel.log.Log;
018    import com.liferay.portal.kernel.log.LogFactoryUtil;
019    import com.liferay.portal.kernel.scheduler.SchedulerEngineUtil;
020    import com.liferay.portal.kernel.scheduler.SchedulerEntry;
021    import com.liferay.portal.kernel.scheduler.SchedulerEntryImpl;
022    import com.liferay.portal.kernel.scheduler.TimeUnit;
023    import com.liferay.portal.kernel.scheduler.TriggerType;
024    import com.liferay.portal.kernel.util.GetterUtil;
025    import com.liferay.portal.kernel.util.ObjectValuePair;
026    import com.liferay.portal.kernel.util.PortalClassLoaderUtil;
027    import com.liferay.portal.kernel.util.PropsKeys;
028    import com.liferay.portal.search.lucene.LuceneIndexer;
029    import com.liferay.portal.search.lucene.messaging.CleanUpMessageListener;
030    import com.liferay.portal.util.PortalInstances;
031    import com.liferay.portal.util.PropsUtil;
032    import com.liferay.portal.util.PropsValues;
033    
034    import java.util.ArrayList;
035    import java.util.List;
036    
037    import javax.servlet.ServletConfig;
038    import javax.servlet.ServletException;
039    import javax.servlet.http.HttpServlet;
040    
041    /**
042     * @author Brian Wing Shun Chan
043     * @author Jorge Ferrer
044     */
045    public class LuceneServlet extends HttpServlet {
046    
047            public void init(ServletConfig servletConfig) throws ServletException {
048                    super.init(servletConfig);
049    
050                    long[] companyIds = PortalInstances.getCompanyIds();
051    
052                    for (int i = 0; i < companyIds.length; i++) {
053                            long companyId = companyIds[i];
054    
055                            if (GetterUtil.getBoolean(
056                                            PropsUtil.get(PropsKeys.INDEX_ON_STARTUP))) {
057    
058                                    if (_log.isInfoEnabled()) {
059                                            _log.info("Indexing Lucene on startup");
060                                    }
061    
062                                    LuceneIndexer indexer = new LuceneIndexer(companyId);
063                                    Thread indexerThread = null;
064    
065                                    if (GetterUtil.getBoolean(
066                                                    PropsUtil.get(PropsKeys.INDEX_WITH_THREAD))) {
067    
068                                            indexerThread = new Thread(
069                                                    indexer, THREAD_NAME + "." + companyId);
070    
071                                            indexerThread.setPriority(THREAD_PRIORITY);
072    
073                                            indexerThread.start();
074                                    }
075                                    else {
076                                            indexer.reindex();
077                                    }
078    
079                                    _indexers.add(
080                                            new ObjectValuePair<LuceneIndexer, Thread>(
081                                                    indexer, indexerThread));
082                            }
083    
084                            if (PropsValues.LUCENE_STORE_JDBC_AUTO_CLEAN_UP_ENABLED) {
085                                    SchedulerEntry schedulerEntry = new SchedulerEntryImpl();
086    
087                                    schedulerEntry.setEventListenerClass(
088                                            CleanUpMessageListener.class.getName());
089                                    schedulerEntry.setTimeUnit(TimeUnit.MINUTE);
090                                    schedulerEntry.setTriggerType(TriggerType.SIMPLE);
091                                    schedulerEntry.setTriggerValue(
092                                            PropsValues.LUCENE_STORE_JDBC_AUTO_CLEAN_UP_INTERVAL);
093    
094                                    try {
095                                            SchedulerEngineUtil.schedule(
096                                                    schedulerEntry, PortalClassLoaderUtil.getClassLoader());
097                                    }
098                                    catch (Exception e) {
099                                            _log.error(e, e);
100                                    }
101                            }
102                    }
103            }
104    
105            public void destroy() {
106    
107                    // Wait for indexer to be gracefully interrupted
108    
109                    for (int i = 0; i < _indexers.size(); i++) {
110                            ObjectValuePair<LuceneIndexer, Thread> ovp = _indexers.get(i);
111    
112                            LuceneIndexer indexer = ovp.getKey();
113                            Thread indexerThread = ovp.getValue();
114    
115                            if ((indexer != null) && (!indexer.isFinished()) &&
116                                    (indexerThread != null)) {
117    
118                                    if (_log.isWarnEnabled()) {
119                                            _log.warn("Waiting for Lucene indexer to shutdown");
120                                    }
121    
122                                    indexer.halt();
123    
124                                    try {
125                                            indexerThread.join(THREAD_TIMEOUT);
126                                    }
127                                    catch (InterruptedException e) {
128                                            _log.error("Lucene indexer shutdown interrupted", e);
129                                    }
130                            }
131                    }
132    
133                    // Parent
134    
135                    super.destroy();
136            }
137    
138            private static final String THREAD_NAME = LuceneIndexer.class.getName();
139    
140            private static final int THREAD_PRIORITY = Thread.MIN_PRIORITY;
141    
142            private static final int THREAD_TIMEOUT = 60000;
143    
144            private static Log _log = LogFactoryUtil.getLog(LuceneServlet.class);
145    
146            private List<ObjectValuePair<LuceneIndexer, Thread>> _indexers =
147                    new ArrayList<ObjectValuePair<LuceneIndexer, Thread>>();
148    
149    }