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