001    /**
002     * Copyright (c) 2000-present 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.notifications;
016    
017    import com.liferay.portal.kernel.exception.PortalException;
018    import com.liferay.portal.kernel.log.Log;
019    import com.liferay.portal.kernel.log.LogFactoryUtil;
020    import com.liferay.portal.kernel.util.StringPool;
021    import com.liferay.portal.model.UserNotificationDeliveryConstants;
022    import com.liferay.portal.model.UserNotificationEvent;
023    import com.liferay.portal.service.ServiceContext;
024    import com.liferay.registry.Registry;
025    import com.liferay.registry.RegistryUtil;
026    import com.liferay.registry.ServiceReference;
027    import com.liferay.registry.ServiceRegistration;
028    import com.liferay.registry.ServiceTracker;
029    import com.liferay.registry.ServiceTrackerCustomizer;
030    import com.liferay.registry.collections.ServiceRegistrationMap;
031    import com.liferay.registry.collections.StringServiceRegistrationMap;
032    
033    import java.util.ArrayList;
034    import java.util.Collections;
035    import java.util.HashMap;
036    import java.util.List;
037    import java.util.Map;
038    import java.util.concurrent.ConcurrentHashMap;
039    
040    /**
041     * @author Jonathan Lee
042     */
043    public class UserNotificationManagerUtil {
044    
045            public static void addUserNotificationDefinition(
046                    String portletId,
047                    UserNotificationDefinition userNotificationDefinition) {
048    
049                    _instance._addUserNotificationDefinition(
050                            portletId, userNotificationDefinition);
051            }
052    
053            public static void addUserNotificationHandler(
054                    UserNotificationHandler userNotificationHandler) {
055    
056                    _instance._addUserNotificationHandler(userNotificationHandler);
057            }
058    
059            public static void deleteUserNotificationDefinitions(String portletId) {
060                    _instance._deleteUserNotificationDefinitions(portletId);
061            }
062    
063            public static void deleteUserNotificationHandler(
064                    UserNotificationHandler userNotificationHandler) {
065    
066                    _instance._deleteUserNotificationHandler(userNotificationHandler);
067            }
068    
069            public static UserNotificationDefinition fetchUserNotificationDefinition(
070                    String portletId, long classNameId, int notificationType) {
071    
072                    return _instance._fetchUserNotificationDefinition(
073                            portletId, classNameId, notificationType);
074            }
075    
076            public static Map<String, List<UserNotificationDefinition>>
077                    getUserNotificationDefinitions() {
078    
079                    return Collections.unmodifiableMap(
080                            _instance._userNotificationDefinitions);
081            }
082    
083            public static Map<String, Map<String, UserNotificationHandler>>
084                    getUserNotificationHandlers() {
085    
086                    return Collections.unmodifiableMap(_instance._userNotificationHandlers);
087            }
088    
089            public static UserNotificationFeedEntry interpret(
090                            String selector, UserNotificationEvent userNotificationEvent,
091                            ServiceContext serviceContext)
092                    throws PortalException {
093    
094                    return _instance._interpret(
095                            selector, userNotificationEvent, serviceContext);
096            }
097    
098            public static boolean isDeliver(
099                            long userId, String portletId, long classNameId,
100                            int notificationType, int deliveryType)
101                    throws PortalException {
102    
103                    return _instance._isDeliver(
104                            userId, StringPool.BLANK, portletId, classNameId, notificationType,
105                            deliveryType, null);
106            }
107    
108            public static boolean isDeliver(
109                            long userId, String selector, String portletId, long classNameId,
110                            int notificationType, int deliveryType,
111                            ServiceContext serviceContext)
112                    throws PortalException {
113    
114                    return _instance._isDeliver(
115                            userId, selector, portletId, classNameId, notificationType,
116                            deliveryType, serviceContext);
117            }
118    
119            private UserNotificationManagerUtil() {
120                    Registry registry = RegistryUtil.getRegistry();
121    
122                    _userNotificationDefinitionServiceTracker = registry.trackServices(
123                            UserNotificationDefinition.class,
124                            new UserNotificationDefinitionServiceTrackerCustomizer());
125    
126                    _userNotificationDefinitionServiceTracker.open();
127    
128                    _userNotificationHandlerServiceTracker = registry.trackServices(
129                            UserNotificationHandler.class,
130                            new UserNotificationHandlerServiceTrackerCustomizer());
131    
132                    _userNotificationHandlerServiceTracker.open();
133            }
134    
135            private void _addUserNotificationDefinition(
136                    String portletId,
137                    UserNotificationDefinition userNotificationDefinition) {
138    
139                    Registry registry = RegistryUtil.getRegistry();
140    
141                    Map<String, Object> properties = new HashMap<String, Object>();
142    
143                    properties.put("javax.portlet.name", portletId);
144    
145                    ServiceRegistration<UserNotificationDefinition> serviceRegistration =
146                            registry.registerService(
147                                    UserNotificationDefinition.class, userNotificationDefinition,
148                                    properties);
149    
150                    _userNotificationDefinitionServiceRegistrations.put(
151                            portletId, serviceRegistration);
152            }
153    
154            private void _addUserNotificationHandler(
155                    UserNotificationHandler userNotificationHandler) {
156    
157                    Registry registry = RegistryUtil.getRegistry();
158    
159                    ServiceRegistration<UserNotificationHandler> serviceRegistration =
160                            registry.registerService(
161                                    UserNotificationHandler.class, userNotificationHandler);
162    
163                    _userNotificationHandlerServiceRegistrations.put(
164                            userNotificationHandler, serviceRegistration);
165            }
166    
167            private void _deleteUserNotificationDefinitions(String portletId) {
168                    ServiceRegistration<UserNotificationDefinition> serviceRegistration =
169                            _userNotificationDefinitionServiceRegistrations.get(portletId);
170    
171                    if (serviceRegistration != null) {
172                            serviceRegistration.unregister();
173                    }
174            }
175    
176            private void _deleteUserNotificationHandler(
177                    UserNotificationHandler userNotificationHandler) {
178    
179                    ServiceRegistration<UserNotificationHandler> serviceRegistration =
180                            _userNotificationHandlerServiceRegistrations.get(
181                                    userNotificationHandler);
182    
183                    if (serviceRegistration != null) {
184                            serviceRegistration.unregister();
185                    }
186            }
187    
188            private UserNotificationDefinition _fetchUserNotificationDefinition(
189                    String portletId, long classNameId, int notificationType) {
190    
191                    List<UserNotificationDefinition> userNotificationDefinitions =
192                            _userNotificationDefinitions.get(portletId);
193    
194                    if (userNotificationDefinitions == null) {
195                            return null;
196                    }
197    
198                    for (UserNotificationDefinition userNotificationDefinition :
199                                    userNotificationDefinitions) {
200    
201                            if ((userNotificationDefinition.getClassNameId() == classNameId) &&
202                                    (userNotificationDefinition.getNotificationType() ==
203                                            notificationType)) {
204    
205                                    return userNotificationDefinition;
206                            }
207                    }
208    
209                    return null;
210            }
211    
212            private UserNotificationFeedEntry _interpret(
213                            String selector, UserNotificationEvent userNotificationEvent,
214                            ServiceContext serviceContext)
215                    throws PortalException {
216    
217                    Map<String, UserNotificationHandler> userNotificationHandlers =
218                            _userNotificationHandlers.get(selector);
219    
220                    if (userNotificationHandlers == null) {
221                            return null;
222                    }
223    
224                    UserNotificationHandler userNotificationHandler =
225                            userNotificationHandlers.get(userNotificationEvent.getType());
226    
227                    if (userNotificationHandler == null) {
228                            if (_log.isWarnEnabled()) {
229                                    _log.warn("No interpreter found for " + userNotificationEvent);
230                            }
231    
232                            return null;
233                    }
234    
235                    return userNotificationHandler.interpret(
236                            userNotificationEvent, serviceContext);
237            }
238    
239            private boolean _isDeliver(
240                            long userId, String selector, String portletId, long classNameId,
241                            int notificationType, int deliveryType,
242                            ServiceContext serviceContext)
243                    throws PortalException {
244    
245                    Map<String, UserNotificationHandler> userNotificationHandlers =
246                            _userNotificationHandlers.get(selector);
247    
248                    if (userNotificationHandlers == null) {
249                            return false;
250                    }
251    
252                    UserNotificationHandler userNotificationHandler =
253                            userNotificationHandlers.get(portletId);
254    
255                    if (userNotificationHandler == null) {
256                            if (deliveryType == UserNotificationDeliveryConstants.TYPE_EMAIL) {
257                                    return true;
258                            }
259    
260                            return false;
261                    }
262    
263                    return userNotificationHandler.isDeliver(
264                            userId, classNameId, notificationType, deliveryType,
265                            serviceContext);
266            }
267    
268            private static final Log _log = LogFactoryUtil.getLog(
269                    UserNotificationManagerUtil.class);
270    
271            private static final UserNotificationManagerUtil _instance =
272                    new UserNotificationManagerUtil();
273    
274            private final Map<String, List<UserNotificationDefinition>>
275                    _userNotificationDefinitions =
276                            new ConcurrentHashMap<String, List<UserNotificationDefinition>>();
277            private final StringServiceRegistrationMap<UserNotificationDefinition>
278                    _userNotificationDefinitionServiceRegistrations =
279                            new StringServiceRegistrationMap<UserNotificationDefinition>();
280            private final ServiceTracker
281                    <UserNotificationDefinition, UserNotificationDefinition>
282                            _userNotificationDefinitionServiceTracker;
283            private final Map<String, Map<String, UserNotificationHandler>>
284                    _userNotificationHandlers = new ConcurrentHashMap
285                            <String, Map<String, UserNotificationHandler>>();
286            private final ServiceRegistrationMap<UserNotificationHandler>
287                    _userNotificationHandlerServiceRegistrations =
288                            new ServiceRegistrationMap<UserNotificationHandler>();
289            private final
290                    ServiceTracker<UserNotificationHandler, UserNotificationHandler>
291                            _userNotificationHandlerServiceTracker;
292    
293            private class UserNotificationDefinitionServiceTrackerCustomizer
294                    implements ServiceTrackerCustomizer
295                            <UserNotificationDefinition, UserNotificationDefinition> {
296    
297                    @Override
298                    public UserNotificationDefinition addingService(
299                            ServiceReference<UserNotificationDefinition> serviceReference) {
300    
301                            Registry registry = RegistryUtil.getRegistry();
302    
303                            String portletId = (String)serviceReference.getProperty(
304                                    "javax.portlet.name");
305    
306                            UserNotificationDefinition userNotificationDefinition =
307                                    registry.getService(serviceReference);
308    
309                            List<UserNotificationDefinition> userNotificationDefinitions =
310                                    _userNotificationDefinitions.get(portletId);
311    
312                            if (userNotificationDefinitions == null) {
313                                    userNotificationDefinitions =
314                                            new ArrayList<UserNotificationDefinition>();
315    
316                                    _userNotificationDefinitions.put(
317                                            portletId, userNotificationDefinitions);
318                            }
319    
320                            userNotificationDefinitions.add(userNotificationDefinition);
321    
322                            return userNotificationDefinition;
323                    }
324    
325                    @Override
326                    public void modifiedService(
327                            ServiceReference<UserNotificationDefinition> serviceReference,
328                            UserNotificationDefinition userNotificationHandler) {
329                    }
330    
331                    @Override
332                    public void removedService(
333                            ServiceReference<UserNotificationDefinition> serviceReference,
334                            UserNotificationDefinition userNotificationHandler) {
335    
336                            Registry registry = RegistryUtil.getRegistry();
337    
338                            registry.ungetService(serviceReference);
339    
340                            String portletId = (String)serviceReference.getProperty(
341                                    "javax.portlet.name");
342    
343                            List<UserNotificationDefinition> userNotificationDefinitions =
344                                    _userNotificationDefinitions.get(portletId);
345    
346                            if (userNotificationDefinitions != null) {
347                                    userNotificationDefinitions.remove(userNotificationHandler);
348    
349                                    if (userNotificationDefinitions.isEmpty()) {
350                                            _userNotificationDefinitions.remove(portletId);
351                                    }
352                            }
353                    }
354    
355            }
356    
357            private class UserNotificationHandlerServiceTrackerCustomizer
358                    implements ServiceTrackerCustomizer
359                            <UserNotificationHandler, UserNotificationHandler> {
360    
361                    @Override
362                    public UserNotificationHandler addingService(
363                            ServiceReference<UserNotificationHandler> serviceReference) {
364    
365                            Registry registry = RegistryUtil.getRegistry();
366    
367                            UserNotificationHandler userNotificationHandler =
368                                    registry.getService(serviceReference);
369    
370                            String selector = userNotificationHandler.getSelector();
371    
372                            Map<String, UserNotificationHandler> userNotificationHandlers =
373                                    _userNotificationHandlers.get(selector);
374    
375                            if (userNotificationHandlers == null) {
376                                    userNotificationHandlers =
377                                            new HashMap<String, UserNotificationHandler>();
378    
379                                    _userNotificationHandlers.put(
380                                            selector, userNotificationHandlers);
381                            }
382    
383                            userNotificationHandlers.put(
384                                    userNotificationHandler.getPortletId(),
385                                    userNotificationHandler);
386    
387                            return userNotificationHandler;
388                    }
389    
390                    @Override
391                    public void modifiedService(
392                            ServiceReference<UserNotificationHandler> serviceReference,
393                            UserNotificationHandler userNotificationHandler) {
394                    }
395    
396                    @Override
397                    public void removedService(
398                            ServiceReference<UserNotificationHandler> serviceReference,
399                            UserNotificationHandler userNotificationHandler) {
400    
401                            Registry registry = RegistryUtil.getRegistry();
402    
403                            registry.ungetService(serviceReference);
404    
405                            Map<String, UserNotificationHandler> userNotificationHandlers =
406                                    _userNotificationHandlers.get(
407                                            userNotificationHandler.getSelector());
408    
409                            if (userNotificationHandlers == null) {
410                                    return;
411                            }
412    
413                            userNotificationHandlers.remove(
414                                    userNotificationHandler.getPortletId());
415                    }
416    
417            }
418    
419    }