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.cluster.messaging.ClusterBridgeMessageListener;
018    import com.liferay.portal.kernel.messaging.Destination;
019    import com.liferay.portal.kernel.messaging.InvokerMessageListener;
020    import com.liferay.portal.kernel.messaging.MessageBus;
021    import com.liferay.portal.kernel.messaging.MessageListener;
022    import com.liferay.portal.kernel.messaging.ParallelDestination;
023    import com.liferay.portal.kernel.messaging.SynchronousDestination;
024    import com.liferay.portal.kernel.search.messaging.BaseSearchEngineMessageListener;
025    import com.liferay.portal.kernel.search.messaging.SearchReaderMessageListener;
026    import com.liferay.portal.kernel.search.messaging.SearchWriterMessageListener;
027    
028    import java.util.ArrayList;
029    import java.util.List;
030    import java.util.Set;
031    
032    /**
033     * @author Michael C. Han
034     */
035    public abstract class AbstractSearchEngineConfigurator {
036    
037            public void afterPropertiesSet() {
038                    for (SearchEngine searchEngine : _searchEngines) {
039                            initSearchEngine(searchEngine);
040                    }
041    
042                    _searchEngines.clear();
043            }
044    
045            public void destroy() {
046                    for (SearchEngineRegistration searchEngineRegistration :
047                                    _searchEngineRegistrations) {
048    
049                            destroySearchEngine(searchEngineRegistration);
050                    }
051    
052                    _searchEngineRegistrations.clear();
053            }
054    
055            public void setSearchEngines(List<SearchEngine> searchEngines) {
056                    _searchEngines = searchEngines;
057            }
058    
059            protected void createSearchEngineListeners(
060                    SearchEngine searchEngine, Destination searchReaderDestination,
061                    Destination searchWriterDestination) {
062    
063                    registerSearchEngineMessageListener(
064                            searchEngine, searchReaderDestination,
065                            new SearchReaderMessageListener(),
066                            searchEngine.getIndexSearcher());
067    
068                    registerSearchEngineMessageListener(
069                            searchEngine, searchWriterDestination,
070                            new SearchWriterMessageListener(), searchEngine.getIndexWriter());
071    
072                    if (searchEngine.isClusteredWrite()) {
073                            ClusterBridgeMessageListener clusterBridgeMessageListener =
074                                    new ClusterBridgeMessageListener();
075    
076                            clusterBridgeMessageListener.setPriority(
077                                    searchEngine.getClusteredWritePriority());
078    
079                            searchWriterDestination.register(clusterBridgeMessageListener);
080                    }
081            }
082    
083            protected void destroySearchEngine(
084                    SearchEngineRegistration searchEngineRegistration) {
085    
086                    MessageBus messageBus = getMessageBus();
087    
088                    Destination searchReaderDestination = messageBus.removeDestination(
089                            searchEngineRegistration.getSearchReaderDestinationName());
090    
091                    searchReaderDestination.close(true);
092    
093                    Destination searchWriterDestination = messageBus.removeDestination(
094                            searchEngineRegistration.getSearchWriterDestinationName());
095    
096                    searchWriterDestination.close(true);
097    
098                    SearchEngine searchEngine = searchEngineRegistration.getSearchEngine();
099    
100                    SearchEngineUtil.removeSearchEngine(searchEngine.getName());
101    
102                    if (!searchEngineRegistration.isOverride()) {
103                            return;
104                    }
105    
106                    SearchEngineProxyWrapper originalSearchEngineProxy =
107                            searchEngineRegistration.getOriginalSearchEngineProxyWrapper();
108    
109                    SearchEngine originalSearchEngine =
110                            originalSearchEngineProxy.getSearchEngine();
111    
112                    searchReaderDestination = getSearchReaderDestination(
113                            messageBus, originalSearchEngine);
114    
115                    registerInvokerMessageListener(
116                            searchReaderDestination,
117                            searchEngineRegistration.getOriginalSearchReaderMessageListeners());
118    
119                    searchWriterDestination = getSearchWriterDestination(
120                            messageBus, originalSearchEngine);
121    
122                    registerInvokerMessageListener(
123                            searchWriterDestination,
124                            searchEngineRegistration.getOriginalSearchWriterMessageListeners());
125    
126                    SearchEngineUtil.addSearchEngine(originalSearchEngineProxy);
127            }
128    
129            protected abstract IndexSearcher getIndexSearcher();
130    
131            protected abstract IndexWriter getIndexWriter();
132    
133            protected abstract MessageBus getMessageBus();
134    
135            protected abstract ClassLoader getOperatingClassloader();
136    
137            protected Destination getSearchReaderDestination(
138                    MessageBus messageBus, SearchEngine searchEngine) {
139    
140                    String searchReaderDestinationName =
141                            SearchEngineUtil.getSearchReaderDestinationName(
142                                    searchEngine.getName());
143    
144                    Destination searchReaderDestination = messageBus.getDestination(
145                            searchReaderDestinationName);
146    
147                    if (searchReaderDestination == null) {
148                            SynchronousDestination synchronousDestination =
149                                    new SynchronousDestination();
150    
151                            synchronousDestination.setName(searchReaderDestinationName);
152    
153                            synchronousDestination.open();
154    
155                            searchReaderDestination = synchronousDestination;
156    
157                            messageBus.addDestination(searchReaderDestination);
158                    }
159    
160                    return searchReaderDestination;
161            }
162    
163            protected Destination getSearchWriterDestination(
164                    MessageBus messageBus, SearchEngine searchEngine) {
165    
166                    String searchWriterDestinationName =
167                            SearchEngineUtil.getSearchWriterDestinationName(
168                                    searchEngine.getName());
169    
170                    Destination searchWriterDestination = messageBus.getDestination(
171                            searchWriterDestinationName);
172    
173                    if (searchWriterDestination == null) {
174                            ParallelDestination parallelDestination = new ParallelDestination();
175    
176                            parallelDestination.setName(searchWriterDestinationName);
177    
178                            parallelDestination.open();
179    
180                            searchWriterDestination = parallelDestination;
181    
182                            messageBus.addDestination(searchWriterDestination);
183                    }
184    
185                    return searchWriterDestination;
186            }
187    
188            protected void initSearchEngine(SearchEngine searchEngine) {
189                    SearchEngineRegistration searchEngineRegistration =
190                            new SearchEngineRegistration(searchEngine);
191    
192                    _searchEngineRegistrations.add(searchEngineRegistration);
193    
194                    MessageBus messageBus = getMessageBus();
195    
196                    Destination searchReaderDestination = getSearchReaderDestination(
197                            messageBus, searchEngine);
198    
199                    searchEngineRegistration.setSearchReaderDestinationName(
200                            searchReaderDestination.getName());
201    
202                    Destination searchWriterDestination = getSearchWriterDestination(
203                            messageBus, searchEngine);
204    
205                    searchEngineRegistration.setSearchWriterDestinationName(
206                            searchWriterDestination.getName());
207    
208                    SearchEngine originalSearchEngine = SearchEngineUtil.getSearchEngine(
209                            searchEngine.getName());
210    
211                    if (originalSearchEngine != null) {
212                            searchEngineRegistration.setOverride(true);
213    
214                            searchEngineRegistration.setOriginalSearchEngineProxyWrapper(
215                                    (SearchEngineProxyWrapper)originalSearchEngine);
216    
217                            savePreviousSearchEngineListeners(
218                                    searchReaderDestination, searchWriterDestination,
219                                    searchEngineRegistration);
220    
221                            messageBus.removeDestination(searchReaderDestination.getName());
222    
223                            searchReaderDestination = getSearchReaderDestination(
224                                    messageBus, originalSearchEngine);
225    
226                            messageBus.removeDestination(searchWriterDestination.getName());
227    
228                            searchWriterDestination = getSearchWriterDestination(
229                                    messageBus, originalSearchEngine);
230                    }
231    
232                    createSearchEngineListeners(
233                            searchEngine, searchReaderDestination, searchWriterDestination);
234    
235                    SearchEngineProxyWrapper searchEngineProxyWrapper =
236                            new SearchEngineProxyWrapper(
237                                    searchEngine, getIndexSearcher(), getIndexWriter());
238    
239                    SearchEngineUtil.addSearchEngine(searchEngineProxyWrapper);
240            }
241    
242            protected void registerInvokerMessageListener(
243                    Destination destination,
244                    List<InvokerMessageListener> invokerMessageListeners) {
245    
246                    for (InvokerMessageListener invokerMessageListener :
247                                    invokerMessageListeners) {
248    
249                            destination.register(
250                                    invokerMessageListener.getMessageListener(),
251                                    invokerMessageListener.getClassLoader());
252                    }
253            }
254    
255            protected void registerSearchEngineMessageListener(
256                    SearchEngine searchEngine, Destination destination,
257                    BaseSearchEngineMessageListener baseSearchEngineMessageListener,
258                    Object manager) {
259    
260                    baseSearchEngineMessageListener.setManager(manager);
261                    baseSearchEngineMessageListener.setMessageBus(getMessageBus());
262                    baseSearchEngineMessageListener.setSearchEngine(searchEngine);
263    
264                    destination.register(
265                            baseSearchEngineMessageListener, getOperatingClassloader());
266            }
267    
268            protected void savePreviousSearchEngineListeners(
269                    Destination searchReaderDestination,
270                    Destination searchWriterDestination,
271                    SearchEngineRegistration searchEngineRegistration) {
272    
273                    Set<MessageListener> searchReaderMessageListeners =
274                            searchReaderDestination.getMessageListeners();
275    
276                    for (MessageListener searchReaderMessageListener :
277                                    searchReaderMessageListeners) {
278    
279                            InvokerMessageListener invokerMessageListener =
280                                    (InvokerMessageListener)searchReaderMessageListener;
281    
282                            searchEngineRegistration.addOriginalSearchReaderMessageListener(
283                                    invokerMessageListener);
284                    }
285    
286                    Set<MessageListener> searchWriterMessageListeners =
287                            searchWriterDestination.getMessageListeners();
288    
289                    for (MessageListener searchWriterMessageListener :
290                                    searchWriterMessageListeners) {
291    
292                            InvokerMessageListener invokerMessageListener =
293                                    (InvokerMessageListener)searchWriterMessageListener;
294    
295                            searchEngineRegistration.addOriginalSearchWriterMessageListener(
296                                    invokerMessageListener);
297                    }
298            }
299    
300            private List<SearchEngineRegistration> _searchEngineRegistrations =
301                    new ArrayList<SearchEngineRegistration>();
302            private List<SearchEngine> _searchEngines;
303    
304            private class SearchEngineRegistration {
305    
306                    private SearchEngineRegistration(SearchEngine searchEngine) {
307                            _searchEngine = searchEngine;
308                    }
309    
310                    public void addOriginalSearchReaderMessageListener(
311                            InvokerMessageListener messageListener) {
312    
313                            _originalSearchReaderMessageListeners.add(messageListener);
314                    }
315    
316                    public void addOriginalSearchWriterMessageListener(
317                            InvokerMessageListener messageListener) {
318    
319                            _originalSearchWriterMessageListeners.add(messageListener);
320                    }
321    
322                    public SearchEngineProxyWrapper getOriginalSearchEngineProxyWrapper() {
323                            return _originalSearchEngineProxyWrapper;
324                    }
325    
326                    public List<InvokerMessageListener>
327                            getOriginalSearchReaderMessageListeners() {
328    
329                            return _originalSearchReaderMessageListeners;
330                    }
331    
332                    public List<InvokerMessageListener>
333                            getOriginalSearchWriterMessageListeners() {
334    
335                            return _originalSearchWriterMessageListeners;
336                    }
337    
338                    public SearchEngine getSearchEngine() {
339                            return _searchEngine;
340                    }
341    
342                    public String getSearchReaderDestinationName() {
343                            return _searchReaderDestinationName;
344                    }
345    
346                    public String getSearchWriterDestinationName() {
347                            return _searchWriterDestinationName;
348                    }
349    
350                    public boolean isOverride() {
351                            return _override;
352                    }
353    
354                    public void setOriginalSearchEngineProxyWrapper(
355                            SearchEngineProxyWrapper searchEngineProxyWrapper) {
356    
357                            _originalSearchEngineProxyWrapper = searchEngineProxyWrapper;
358                    }
359    
360                    public void setOverride(boolean override) {
361                            _override = override;
362                    }
363    
364                    public void setSearchReaderDestinationName(
365                            String searchReaderDestinationName) {
366    
367                            _searchReaderDestinationName = searchReaderDestinationName;
368                    }
369    
370                    public void setSearchWriterDestinationName(
371                            String searchWriterDestinationName) {
372    
373                            _searchWriterDestinationName = searchWriterDestinationName;
374                    }
375    
376                    private SearchEngineProxyWrapper _originalSearchEngineProxyWrapper;
377                    private List<InvokerMessageListener>
378                            _originalSearchReaderMessageListeners =
379                                    new ArrayList<InvokerMessageListener>();
380                    private List<InvokerMessageListener>
381                            _originalSearchWriterMessageListeners =
382                                    new ArrayList<InvokerMessageListener>();
383                    private boolean _override;
384                    private SearchEngine _searchEngine;
385                    private String _searchReaderDestinationName;
386                    private String _searchWriterDestinationName;
387    
388            }
389    
390    }