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