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