001/*
002 * (C) Copyright 2007 Nuxeo SA (http://nuxeo.com/) and others.
003 *
004 * Licensed under the Apache License, Version 2.0 (the "License");
005 * you may not use this file except in compliance with the License.
006 * You may obtain a copy of the License at
007 *
008 *     http://www.apache.org/licenses/LICENSE-2.0
009 *
010 * Unless required by applicable law or agreed to in writing, software
011 * distributed under the License is distributed on an "AS IS" BASIS,
012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
013 * See the License for the specific language governing permissions and
014 * limitations under the License.
015 *
016 * Contributors:
017 *     Nuxeo - initial API and implementation
018 *
019 * $Id$
020 */
021
022package org.nuxeo.ecm.platform.ec.notification.service;
023
024import java.util.ArrayList;
025import java.util.Arrays;
026import java.util.HashMap;
027import java.util.HashSet;
028import java.util.List;
029import java.util.Map;
030import java.util.Set;
031
032import org.apache.commons.logging.Log;
033import org.apache.commons.logging.LogFactory;
034import org.nuxeo.ecm.platform.ec.notification.NotificationImpl;
035import org.nuxeo.ecm.platform.notification.api.Notification;
036import org.nuxeo.ecm.platform.notification.api.NotificationRegistry;
037
038/**
039 * @author <a href="mailto:npaslaru@nuxeo.com">Narcis Paslaru</a>
040 * @author <a href="mailto:tmartins@nuxeo.com">Thierry Martins</a>
041 */
042public class NotificationRegistryImpl implements NotificationRegistry {
043
044    private static final long serialVersionUID = 1L;
045
046    private static final Log log = LogFactory.getLog(NotificationRegistryImpl.class);
047
048    // maps EventId to a list of notifications
049    private final Map<String, List<Notification>> notificationRegistry = new HashMap<String, List<Notification>>();
050
051    private final List<Notification> notificationList = new ArrayList<Notification>();
052
053    @Override
054    public void clear() {
055        notificationRegistry.clear();
056    }
057
058    @Override
059    public void registerNotification(Notification notif, List<String> events) {
060        if (notif.getName() == null) {
061            log.error("Notifications contributions must have a name");
062        }
063
064        if (notif.getEnabled()) {
065            NotificationImpl notification = new NotificationImpl(notif.getName(), notif.getTemplate(),
066                    notif.getChannel(), notif.getSubjectTemplate(), notif.getAutoSubscribed(), notif.getSubject(),
067                    notif.getAvailableIn(), notif.getLabel());
068
069            if (notif.getTemplateExpr() != null) {
070                notification.setTemplateExpr(notif.getTemplateExpr());
071            }
072
073            if (notificationList.contains(notification)) {
074                unregisterNotification(notification, events);
075            }
076            notificationList.add(notification);
077
078            if (events != null && !events.isEmpty()) {
079                for (String event : events) {
080                    List<Notification> regNotifs = getNotificationsForEvent(event);
081                    if (!regNotifs.contains(notification)) {
082                        regNotifs.add(notification);
083                    }
084                }
085            }
086        } else {
087            unregisterNotification(notif, events);
088        }
089    }
090
091    @Override
092    @Deprecated
093    /**
094     * Please use unregisterNotification(Notification notif) instead.
095     * Deprecated since 5.7.2
096     */
097    public void unregisterNotification(Notification notif, List<String> events) {
098        unregisterNotification(notif);
099    }
100
101    @Override
102    public void unregisterNotification(Notification notif) {
103        if (notif == null) {
104            log.warn("Try to unregister a null notification, do nothing");
105            return;
106        }
107
108        NotificationImpl notification = new NotificationImpl(notif.getName(), notif.getTemplate(), notif.getChannel(),
109                notif.getSubjectTemplate(), notif.getAutoSubscribed(), notif.getSubject(), notif.getAvailableIn(),
110                notif.getLabel());
111
112        if (notificationList.contains(notification)) {
113            notificationList.remove(notification);
114        }
115
116        for (String event : notificationRegistry.keySet()) {
117            for (int i = notificationRegistry.get(event).size() - 1; i >= 0; i--) {
118                List<Notification> regNotifs = notificationRegistry.get(event);
119                if (regNotifs.contains(notification)) {
120                    regNotifs.remove(notification);
121                }
122            }
123        }
124    }
125
126    @Override
127    public Set<String> getNotificationEventNames() {
128        Set<String> ret = new HashSet<String>();
129        for (String name : notificationRegistry.keySet()) {
130            if (!notificationRegistry.get(name).isEmpty()) {
131                ret.add(name);
132            }
133        }
134        return ret;
135    }
136
137    /**
138     * Gets the list of possible notifications for an event.
139     */
140    @Override
141    public List<Notification> getNotificationsForEvent(String eventId) {
142        if (notificationRegistry.get(eventId) == null) {
143            notificationRegistry.put(eventId, new ArrayList<Notification>());
144        }
145
146        return notificationRegistry.get(eventId);
147    }
148
149    @Override
150    public List<Notification> getNotifications() {
151        return notificationList;
152    }
153
154    public Map<String, List<Notification>> getNotificationRegistry() {
155        return notificationRegistry;
156    }
157
158    @Override
159    public List<Notification> getNotificationsForSubscriptions(String parentType) {
160        List<Notification> result = new ArrayList<Notification>();
161        for (Notification notification : notificationList) {
162            if (notification.getAutoSubscribed()) {
163                continue;
164            }
165            String type = notification.getAvailableIn();
166            if (type == null || "all".equals(type) || "*".equals(type)) {
167                result.add(notification);
168            } else {
169                String[] types = type.replace(",", " ").split(" ");
170                if (Arrays.asList(types).contains(parentType)) {
171                    result.add(notification);
172                }
173            }
174        }
175        return result;
176    }
177
178}