/** * Copyright (c) 2000-present Liferay, Inc. All rights reserved. * * This library is free software; you can redistribute it and/or modify it under * the terms of the GNU Lesser General Public License as published by the Free * Software Foundation; either version 2.1 of the License, or (at your option) * any later version. * * This library is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS * FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more * details. */ package com.liferay.portal.kernel.notifications; import com.liferay.portal.kernel.exception.PortalException; import com.liferay.portal.kernel.log.Log; import com.liferay.portal.kernel.log.LogFactoryUtil; import com.liferay.portal.kernel.model.Portlet; import com.liferay.portal.kernel.model.UserNotificationDeliveryConstants; import com.liferay.portal.kernel.model.UserNotificationEvent; import com.liferay.portal.kernel.service.PortletLocalServiceUtil; import com.liferay.portal.kernel.service.ServiceContext; import com.liferay.portal.kernel.util.StringPool; import com.liferay.registry.Registry; import com.liferay.registry.RegistryUtil; import com.liferay.registry.ServiceReference; import com.liferay.registry.ServiceRegistration; import com.liferay.registry.ServiceTracker; import com.liferay.registry.ServiceTrackerCustomizer; import com.liferay.registry.collections.ServiceRegistrationMap; import com.liferay.registry.collections.ServiceRegistrationMapImpl; import com.liferay.registry.collections.ServiceTrackerCollections; import com.liferay.registry.collections.ServiceTrackerMap; import java.util.ArrayList; import java.util.Collections; import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.concurrent.ConcurrentHashMap; /** * @author Jonathan Lee * @author Roberto Díaz */ public class UserNotificationManagerUtil { public static void addUserNotificationDefinition( String portletId, UserNotificationDefinition userNotificationDefinition) { _instance._addUserNotificationDefinition( portletId, userNotificationDefinition); } public static void addUserNotificationHandler( UserNotificationHandler userNotificationHandler) { _instance._addUserNotificationHandler(userNotificationHandler); } public static void deleteUserNotificationDefinitions(String portletId) { _instance._deleteUserNotificationDefinitions(portletId); } public static void deleteUserNotificationHandler( UserNotificationHandler userNotificationHandler) { _instance._deleteUserNotificationHandler(userNotificationHandler); } public static UserNotificationDefinition fetchUserNotificationDefinition( String portletId, long classNameId, int notificationType) { return _instance._fetchUserNotificationDefinition( portletId, classNameId, notificationType); } public static Map<String, List<UserNotificationDefinition>> getActiveUserNotificationDefinitions() { return _instance._getUserNotificationDefinitions(true); } public static Map<String, List<UserNotificationDefinition>> getUserNotificationDefinitions() { return _instance._getUserNotificationDefinitions(false); } public static Map<String, Map<String, UserNotificationHandler>> getUserNotificationHandlers() { return Collections.unmodifiableMap(_instance._userNotificationHandlers); } public static UserNotificationFeedEntry interpret( String selector, UserNotificationEvent userNotificationEvent, ServiceContext serviceContext) throws PortalException { return _instance._interpret( selector, userNotificationEvent, serviceContext); } public static boolean isDeliver( long userId, String portletId, long classNameId, int notificationType, int deliveryType) throws PortalException { return _instance._isDeliver( userId, StringPool.BLANK, portletId, classNameId, notificationType, deliveryType, null); } public static boolean isDeliver( long userId, String selector, String portletId, long classNameId, int notificationType, int deliveryType, ServiceContext serviceContext) throws PortalException { return _instance._isDeliver( userId, selector, portletId, classNameId, notificationType, deliveryType, serviceContext); } private UserNotificationManagerUtil() { Registry registry = RegistryUtil.getRegistry(); _userNotificationHandlerServiceTracker = registry.trackServices( UserNotificationHandler.class, new UserNotificationHandlerServiceTrackerCustomizer()); _userNotificationHandlerServiceTracker.open(); } private void _addUserNotificationDefinition( String portletId, UserNotificationDefinition userNotificationDefinition) { Registry registry = RegistryUtil.getRegistry(); Map<String, Object> properties = new HashMap<>(); properties.put("javax.portlet.name", portletId); ServiceRegistration<UserNotificationDefinition> serviceRegistration = registry.registerService( UserNotificationDefinition.class, userNotificationDefinition, properties); List<ServiceRegistration<UserNotificationDefinition>> serviceRegistrations = new ArrayList<>(); List<ServiceRegistration<UserNotificationDefinition>> userNotificationServiceRegistrations = _userNotificationDefinitionServiceRegistrations.get(portletId); if ((userNotificationServiceRegistrations != null) && !userNotificationServiceRegistrations.isEmpty()) { serviceRegistrations.addAll(userNotificationServiceRegistrations); } serviceRegistrations.add(serviceRegistration); _userNotificationDefinitionServiceRegistrations.put( portletId, serviceRegistrations); } private void _addUserNotificationHandler( UserNotificationHandler userNotificationHandler) { Registry registry = RegistryUtil.getRegistry(); ServiceRegistration<UserNotificationHandler> serviceRegistration = registry.registerService( UserNotificationHandler.class, userNotificationHandler); _userNotificationHandlerServiceRegistrations.put( userNotificationHandler, serviceRegistration); } private void _deleteUserNotificationDefinitions(String portletId) { List<ServiceRegistration<UserNotificationDefinition>> serviceRegistrations = _userNotificationDefinitionServiceRegistrations.get(portletId); for (ServiceRegistration<UserNotificationDefinition> serviceRegistration : serviceRegistrations) { serviceRegistration.unregister(); } } private void _deleteUserNotificationHandler( UserNotificationHandler userNotificationHandler) { ServiceRegistration<UserNotificationHandler> serviceRegistration = _userNotificationHandlerServiceRegistrations.get( userNotificationHandler); if (serviceRegistration != null) { serviceRegistration.unregister(); } } private UserNotificationDefinition _fetchUserNotificationDefinition( String portletId, long classNameId, int notificationType) { List<UserNotificationDefinition> userNotificationDefinitions = _userNotificationDefinitions.getService(portletId); if (userNotificationDefinitions == null) { return null; } for (UserNotificationDefinition userNotificationDefinition : userNotificationDefinitions) { if ((userNotificationDefinition.getClassNameId() == classNameId) && (userNotificationDefinition.getNotificationType() == notificationType)) { return userNotificationDefinition; } } return null; } private Map<String, List<UserNotificationDefinition>> _getUserNotificationDefinitions(boolean active) { Map<String, List<UserNotificationDefinition>> userNotificationDefinitionsMap = new ConcurrentHashMap<>(); ServiceTrackerMap<String, List<UserNotificationDefinition>> userNotificationDefinitionsServiceTrackerMap = _instance._userNotificationDefinitions; for (String portletId : userNotificationDefinitionsServiceTrackerMap.keySet()) { if (active) { Portlet portlet = PortletLocalServiceUtil.getPortletById( portletId); if (portlet == null) { continue; } } userNotificationDefinitionsMap.put( portletId, userNotificationDefinitionsServiceTrackerMap.getService( portletId)); } return Collections.unmodifiableMap(userNotificationDefinitionsMap); } private UserNotificationFeedEntry _interpret( String selector, UserNotificationEvent userNotificationEvent, ServiceContext serviceContext) throws PortalException { Map<String, UserNotificationHandler> userNotificationHandlers = _userNotificationHandlers.get(selector); if (userNotificationHandlers == null) { return null; } UserNotificationHandler userNotificationHandler = userNotificationHandlers.get(userNotificationEvent.getType()); if (userNotificationHandler == null) { if (_log.isWarnEnabled()) { _log.warn("No interpreter found for " + userNotificationEvent); } return null; } return userNotificationHandler.interpret( userNotificationEvent, serviceContext); } private boolean _isDeliver( long userId, String selector, String portletId, long classNameId, int notificationType, int deliveryType, ServiceContext serviceContext) throws PortalException { Map<String, UserNotificationHandler> userNotificationHandlers = _userNotificationHandlers.get(selector); if (userNotificationHandlers == null) { return false; } UserNotificationHandler userNotificationHandler = userNotificationHandlers.get(portletId); if (userNotificationHandler == null) { if (deliveryType == UserNotificationDeliveryConstants.TYPE_EMAIL) { return true; } return false; } return userNotificationHandler.isDeliver( userId, classNameId, notificationType, deliveryType, serviceContext); } private static final Log _log = LogFactoryUtil.getLog( UserNotificationManagerUtil.class); private static final UserNotificationManagerUtil _instance = new UserNotificationManagerUtil(); private final ServiceTrackerMap<String, List<UserNotificationDefinition>> _userNotificationDefinitions = ServiceTrackerCollections.openMultiValueMap( UserNotificationDefinition.class, "javax.portlet.name"); private final ConcurrentHashMap <String, List<ServiceRegistration<UserNotificationDefinition>>> _userNotificationDefinitionServiceRegistrations = new ConcurrentHashMap<>(); private final Map<String, Map<String, UserNotificationHandler>> _userNotificationHandlers = new ConcurrentHashMap<>(); private final ServiceRegistrationMap<UserNotificationHandler> _userNotificationHandlerServiceRegistrations = new ServiceRegistrationMapImpl<>(); private final ServiceTracker<UserNotificationHandler, UserNotificationHandler> _userNotificationHandlerServiceTracker; private class UserNotificationHandlerServiceTrackerCustomizer implements ServiceTrackerCustomizer <UserNotificationHandler, UserNotificationHandler> { @Override public UserNotificationHandler addingService( ServiceReference<UserNotificationHandler> serviceReference) { Registry registry = RegistryUtil.getRegistry(); UserNotificationHandler userNotificationHandler = registry.getService(serviceReference); String selector = userNotificationHandler.getSelector(); Map<String, UserNotificationHandler> userNotificationHandlers = _userNotificationHandlers.get(selector); if (userNotificationHandlers == null) { userNotificationHandlers = new HashMap<>(); _userNotificationHandlers.put( selector, userNotificationHandlers); } userNotificationHandlers.put( userNotificationHandler.getPortletId(), userNotificationHandler); return userNotificationHandler; } @Override public void modifiedService( ServiceReference<UserNotificationHandler> serviceReference, UserNotificationHandler userNotificationHandler) { } @Override public void removedService( ServiceReference<UserNotificationHandler> serviceReference, UserNotificationHandler userNotificationHandler) { Registry registry = RegistryUtil.getRegistry(); registry.ungetService(serviceReference); Map<String, UserNotificationHandler> userNotificationHandlers = _userNotificationHandlers.get( userNotificationHandler.getSelector()); if (userNotificationHandlers == null) { return; } userNotificationHandlers.remove( userNotificationHandler.getPortletId()); } } }