001/*
002 * (C) Copyright 2011 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 *     Thierry Martins
018 */
019package org.nuxeo.ecm.user.center.notification;
020
021import java.io.Serializable;
022import java.util.ArrayList;
023import java.util.HashMap;
024import java.util.Iterator;
025import java.util.List;
026import java.util.Map;
027import java.util.SortedSet;
028import java.util.TreeSet;
029
030import org.jboss.seam.ScopeType;
031import org.jboss.seam.annotations.Factory;
032import org.jboss.seam.annotations.In;
033import org.jboss.seam.annotations.Name;
034import org.jboss.seam.annotations.Scope;
035import org.nuxeo.ecm.core.api.CoreSession;
036import org.nuxeo.ecm.core.api.DocumentModel;
037import org.nuxeo.ecm.core.api.DocumentRef;
038import org.nuxeo.ecm.core.api.IdRef;
039import org.nuxeo.ecm.core.api.NuxeoGroup;
040import org.nuxeo.ecm.core.api.NuxeoPrincipal;
041import org.nuxeo.ecm.platform.ec.notification.SubscriptionAdapter;
042import org.nuxeo.ecm.platform.notification.api.NotificationManager;
043import org.nuxeo.runtime.api.Framework;
044
045@Name("userNotificationActions")
046@Scope(ScopeType.CONVERSATION)
047public class UserNotificationActions implements Serializable {
048
049    private static final long serialVersionUID = 1L;
050
051    @In(create = true)
052    protected NuxeoPrincipal currentUser;
053
054    @In(create = true)
055    protected CoreSession documentManager;
056
057    @In(create = true)
058    protected transient NotificationManager notificationManager;
059
060    private List<UserSubscription> subscriptions;
061
062    @Factory(value = "userSubscriptions", scope = ScopeType.EVENT)
063    public List<UserSubscription> getUserSubscriptions() {
064
065        List<UserSubscription> result = new ArrayList<>();
066
067        String prefixedUserName = NuxeoPrincipal.PREFIX + currentUser.getName();
068        result.addAll(fetchSubscriptionsFor(prefixedUserName));
069
070        for (String group : currentUser.getAllGroups()) {
071            String prefixedgroupName = NuxeoGroup.PREFIX + group;
072            result.addAll(fetchSubscriptionsFor(prefixedgroupName));
073        }
074
075        reorderSubscriptions(result);
076
077        return subscriptions;
078    }
079
080    private List<UserSubscription> fetchSubscriptionsFor(String prefixedUserName) {
081        List<UserSubscription> result = new ArrayList<>();
082        NotificationManager nm = Framework.getService(NotificationManager.class);
083        List<DocumentModel> subscribedDocs = nm.getSubscribedDocuments(prefixedUserName,
084                documentManager.getRepositoryName());
085        for (DocumentModel doc : subscribedDocs) {
086            // Avoid treating document the current user can't read
087            if (documentManager.exists(doc.getRef())) {
088                SubscriptionAdapter sa = doc.getAdapter(SubscriptionAdapter.class);
089                List<String> notifications = sa.getUserSubscriptions(prefixedUserName);
090                for (String notification : notifications) {
091                    result.add(new UserSubscription(doc.getId(), notification, prefixedUserName));
092                }
093            }
094        }
095        return result;
096    }
097
098    private void reorderSubscriptions(List<UserSubscription> allSubscriptions) {
099        Map<String, List<UserSubscription>> unsortedSubscriptions = new HashMap<String, List<UserSubscription>>();
100        for (Object obj : allSubscriptions) {
101            UserSubscription us = (UserSubscription) obj;
102            DocumentModel doc = getDocument(us.getDocId());
103            String path;
104            if (doc == null) {
105                path = us.getDocId();
106            } else {
107                path = getDocument(us.getDocId()).getPathAsString();
108            }
109            if (!unsortedSubscriptions.containsKey(path)) {
110                unsortedSubscriptions.put(path, new ArrayList<UserSubscription>());
111            }
112            unsortedSubscriptions.get(path).add(us);
113        }
114        SortedSet<String> sortedset = new TreeSet<String>(unsortedSubscriptions.keySet());
115        subscriptions = new ArrayList<UserSubscription>();
116        Iterator<String> it = sortedset.iterator();
117        while (it.hasNext()) {
118            subscriptions.addAll(unsortedSubscriptions.get(it.next()));
119        }
120    }
121
122    public DocumentModel getDocument(String docId) {
123        // test if user has READ right
124        DocumentRef ref = new IdRef(docId);
125        if (documentManager.exists(ref)) {
126            return documentManager.getDocument(ref);
127        }
128        return null;
129    }
130
131    public boolean getCanRemoveNotification(String userId) {
132        // Do not allow removing for group subscription
133        if (userId != null && userId.equals(NuxeoPrincipal.PREFIX + currentUser.getName())) {
134            return true;
135        }
136        return false;
137    }
138
139}