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        for (DocumentModel doc : subscribedDocs) {
085            //Avoid treating document the current user can't read
086            if (documentManager.exists(doc.getRef())) {
087                SubscriptionAdapter sa = doc.getAdapter(SubscriptionAdapter.class);
088                List<String> notifications = sa.getUserSubscriptions(prefixedUserName);
089                for (String notification : notifications) {
090                    result.add(new UserSubscription(doc.getId(), notification, prefixedUserName));
091                }
092            }
093        }
094        return result;
095    }
096
097    private void reorderSubscriptions(List<UserSubscription> allSubscriptions) {
098        Map<String, List<UserSubscription>> unsortedSubscriptions = new HashMap<String, List<UserSubscription>>();
099        for (Object obj : allSubscriptions) {
100            UserSubscription us = (UserSubscription) obj;
101            DocumentModel doc = getDocument(us.getDocId());
102            String path;
103            if (doc == null) {
104                path = us.getDocId();
105            } else {
106                path = getDocument(us.getDocId()).getPathAsString();
107            }
108            if (!unsortedSubscriptions.containsKey(path)) {
109                unsortedSubscriptions.put(path, new ArrayList<UserSubscription>());
110            }
111            unsortedSubscriptions.get(path).add(us);
112        }
113        SortedSet<String> sortedset = new TreeSet<String>(unsortedSubscriptions.keySet());
114        subscriptions = new ArrayList<UserSubscription>();
115        Iterator<String> it = sortedset.iterator();
116        while (it.hasNext()) {
117            subscriptions.addAll(unsortedSubscriptions.get(it.next()));
118        }
119    }
120
121    public DocumentModel getDocument(String docId) {
122        // test if user has READ right
123        DocumentRef ref = new IdRef(docId);
124        if (documentManager.exists(ref)) {
125            return documentManager.getDocument(ref);
126        }
127        return null;
128    }
129
130    public boolean getCanRemoveNotification(String userId) {
131        // Do not allow removing for group subscription
132        if (userId != null && userId.equals(NuxeoPrincipal.PREFIX + currentUser.getName())) {
133            return true;
134        }
135        return false;
136    }
137
138}