001    /**
002     * Copyright (c) 2000-2013 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.messaging.config;
016    
017    import com.liferay.portal.kernel.log.Log;
018    import com.liferay.portal.kernel.log.LogFactoryUtil;
019    import com.liferay.portal.kernel.messaging.Destination;
020    import com.liferay.portal.kernel.messaging.DestinationEventListener;
021    import com.liferay.portal.kernel.messaging.MessageBus;
022    import com.liferay.portal.kernel.messaging.MessageListener;
023    import com.liferay.portal.kernel.security.pacl.permission.PortalMessageBusPermission;
024    
025    import java.lang.reflect.Method;
026    
027    import java.util.ArrayList;
028    import java.util.HashMap;
029    import java.util.List;
030    import java.util.Map;
031    
032    /**
033     * @author Michael C. Han
034     */
035    public abstract class AbstractMessagingConfigurator
036            implements MessagingConfigurator {
037    
038            public void afterPropertiesSet() {
039                    MessageBus messageBus = getMessageBus();
040    
041                    for (DestinationEventListener destinationEventListener :
042                                    _globalDestinationEventListeners) {
043    
044                            messageBus.addDestinationEventListener(destinationEventListener);
045                    }
046    
047                    for (Destination destination : _destinations) {
048                            messageBus.addDestination(destination);
049                    }
050    
051                    for (Map.Entry<String, List<DestinationEventListener>>
052                                    destinationEventListeners :
053                                            _specificDestinationEventListeners.entrySet()) {
054    
055                            String destinationName = destinationEventListeners.getKey();
056    
057                            for (DestinationEventListener destinationEventListener :
058                                            destinationEventListeners.getValue()) {
059    
060                                    messageBus.addDestinationEventListener(
061                                            destinationName, destinationEventListener);
062                            }
063                    }
064    
065                    for (Destination destination : _replacementDestinations) {
066                            messageBus.replace(destination);
067                    }
068    
069                    Thread currentThread = Thread.currentThread();
070    
071                    ClassLoader contextClassLoader = currentThread.getContextClassLoader();
072    
073                    try {
074                            ClassLoader operatingClassLoader = getOperatingClassloader();
075    
076                            currentThread.setContextClassLoader(operatingClassLoader);
077    
078                            for (Map.Entry<String, List<MessageListener>> messageListeners :
079                                            _messageListeners.entrySet()) {
080    
081                                    String destinationName = messageListeners.getKey();
082    
083                                    for (MessageListener messageListener :
084                                                    messageListeners.getValue()) {
085    
086                                            messageBus.registerMessageListener(
087                                                    destinationName, messageListener);
088                                    }
089                            }
090                    }
091                    finally {
092                            currentThread.setContextClassLoader(contextClassLoader);
093                    }
094            }
095    
096            @Override
097            public void destroy() {
098                    MessageBus messageBus = getMessageBus();
099    
100                    for (Map.Entry<String, List<MessageListener>> messageListeners :
101                                    _messageListeners.entrySet()) {
102    
103                            String destinationName = messageListeners.getKey();
104    
105                            for (MessageListener messageListener :
106                                            messageListeners.getValue()) {
107    
108                                    messageBus.unregisterMessageListener(
109                                            destinationName, messageListener);
110                            }
111                    }
112    
113                    for (Destination destination : _destinations) {
114                            messageBus.removeDestination(destination.getName());
115    
116                            destination.close();
117                    }
118    
119                    for (Map.Entry<String, List<DestinationEventListener>>
120                                    destinationEventListeners :
121                                            _specificDestinationEventListeners.entrySet()) {
122    
123                            String destinationName = destinationEventListeners.getKey();
124    
125                            for (DestinationEventListener destinationEventListener :
126                                            destinationEventListeners.getValue()) {
127    
128                                    messageBus.removeDestinationEventListener(
129                                            destinationName, destinationEventListener);
130                            }
131                    }
132    
133                    for (DestinationEventListener destinationEventListener :
134                                    _globalDestinationEventListeners) {
135    
136                            messageBus.removeDestinationEventListener(destinationEventListener);
137                    }
138            }
139    
140            /**
141             * @deprecated {@link #afterPropertiesSet}
142             */
143            @Override
144            public void init() {
145                    afterPropertiesSet();
146            }
147    
148            @Override
149            public void setDestinations(List<Destination> destinations) {
150                    for (Destination destination : destinations) {
151                            try {
152                                    PortalMessageBusPermission.checkListen(destination.getName());
153                            }
154                            catch (SecurityException se) {
155                                    if (_log.isInfoEnabled()) {
156                                            _log.info("Rejecting destination " + destination.getName());
157                                    }
158    
159                                    continue;
160                            }
161    
162                            _destinations.add(destination);
163                    }
164            }
165    
166            @Override
167            public void setGlobalDestinationEventListeners(
168                    List<DestinationEventListener> globalDestinationEventListeners) {
169    
170                    _globalDestinationEventListeners = globalDestinationEventListeners;
171            }
172    
173            @Override
174            public void setMessageListeners(
175                    Map<String, List<MessageListener>> messageListeners) {
176    
177                    _messageListeners = messageListeners;
178    
179                    for (List<MessageListener> messageListenersList :
180                                    _messageListeners.values()) {
181    
182                            for (MessageListener messageListener : messageListenersList) {
183                                    Class<?> messageListenerClass = messageListener.getClass();
184    
185                                    try {
186                                            Method setMessageBusMethod = messageListenerClass.getMethod(
187                                                    "setMessageBus", MessageBus.class);
188    
189                                            setMessageBusMethod.setAccessible(true);
190    
191                                            setMessageBusMethod.invoke(
192                                                    messageListener, getMessageBus());
193    
194                                            continue;
195                                    }
196                                    catch (Exception e) {
197                                    }
198    
199                                    try {
200                                            Method setMessageBusMethod =
201                                                    messageListenerClass.getDeclaredMethod(
202                                                            "setMessageBus", MessageBus.class);
203    
204                                            setMessageBusMethod.setAccessible(true);
205    
206                                            setMessageBusMethod.invoke(
207                                                    messageListener, getMessageBus());
208                                    }
209                                    catch (Exception e) {
210                                    }
211                            }
212                    }
213            }
214    
215            @Override
216            public void setReplacementDestinations(
217                    List<Destination> replacementDestinations) {
218    
219                    _replacementDestinations = replacementDestinations;
220            }
221    
222            @Override
223            public void setSpecificDestinationEventListener(
224                    Map<String, List<DestinationEventListener>>
225                            specificDestinationEventListeners) {
226    
227                    _specificDestinationEventListeners = specificDestinationEventListeners;
228            }
229    
230            protected abstract MessageBus getMessageBus();
231    
232            protected abstract ClassLoader getOperatingClassloader();
233    
234            private static Log _log = LogFactoryUtil.getLog(
235                    AbstractMessagingConfigurator.class);
236    
237            private List<Destination> _destinations = new ArrayList<Destination>();
238            private List<DestinationEventListener> _globalDestinationEventListeners =
239                    new ArrayList<DestinationEventListener>();
240            private Map<String, List<MessageListener>> _messageListeners =
241                    new HashMap<String, List<MessageListener>>();
242            private List<Destination> _replacementDestinations =
243                    new ArrayList<Destination>();
244            private Map<String, List<DestinationEventListener>>
245                    _specificDestinationEventListeners =
246                            new HashMap<String, List<DestinationEventListener>>();
247    
248    }