001/*
002 * (C) Copyright 2007 Nuxeo SAS (http://nuxeo.com/) and contributors.
003 *
004 * All rights reserved. This program and the accompanying materials
005 * are made available under the terms of the GNU Lesser General Public License
006 * (LGPL) version 2.1 which accompanies this distribution, and is available at
007 * http://www.gnu.org/licenses/lgpl.html
008 *
009 * This library is distributed in the hope that it will be useful,
010 * but WITHOUT ANY WARRANTY; without even the implied warranty of
011 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
012 * Lesser General Public License for more details.
013 *
014 * Contributors:
015 *     Nuxeo - initial API and implementation
016 *
017 * $Id$
018 */
019
020package org.nuxeo.ecm.webapp.notification;
021
022import java.io.Serializable;
023import java.util.ArrayList;
024import java.util.List;
025
026import javax.faces.context.FacesContext;
027
028import org.apache.commons.logging.Log;
029import org.apache.commons.logging.LogFactory;
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.Observer;
035import org.jboss.seam.annotations.Scope;
036import org.jboss.seam.annotations.datamodel.DataModel;
037import org.jboss.seam.annotations.datamodel.DataModelSelection;
038import org.jboss.seam.annotations.intercept.BypassInterceptors;
039import org.jboss.seam.faces.FacesMessages;
040import org.jboss.seam.international.StatusMessage;
041import org.nuxeo.ecm.core.api.CoreSession;
042import org.nuxeo.ecm.core.api.DocumentModel;
043import org.nuxeo.ecm.core.api.NuxeoPrincipal;
044import org.nuxeo.ecm.platform.ec.notification.NotificationConstants;
045import org.nuxeo.ecm.platform.notification.api.Notification;
046import org.nuxeo.ecm.platform.notification.api.NotificationManager;
047import org.nuxeo.ecm.platform.ui.web.api.NavigationContext;
048import org.nuxeo.ecm.webapp.base.InputController;
049import org.nuxeo.ecm.webapp.helpers.EventNames;
050import org.nuxeo.ecm.webapp.helpers.ResourcesAccessor;
051
052/**
053 * Handles the subscriptions page.
054 *
055 * @author <a href="mailto:npaslaru@nuxeo.com">Narcis Paslaru</a>
056 */
057@Name("subscriptionAction")
058@Scope(ScopeType.PAGE)
059public class SubscriptionsAction extends InputController implements Serializable {
060
061    private static final long serialVersionUID = -2440187703248677446L;
062
063    private static final Log log = LogFactory.getLog(SubscriptionsAction.class);
064
065    @In
066    protected transient NavigationContext navigationContext;
067
068    @In(create = true, required = false)
069    protected transient CoreSession documentManager;
070
071    @DataModel("notificationList")
072    protected List<SelectableSubscription> notificationList;
073
074    @DataModel("inheritedNotifications")
075    private List<Notification> inheritedNotifications;
076
077    @DataModelSelection(value = "notificationList")
078    private SelectableSubscription currentSubscription;
079
080    @In(create = true)
081    protected transient NotificationManager notificationManager;
082
083    @In(create = true, required = false)
084    protected transient FacesMessages facesMessages;
085
086    @In(create = true)
087    protected ResourcesAccessor resourcesAccessor;
088
089    public static final String CONFIRM_FOLLOW = "label.subscriptions.follow.confirm";
090
091    public static final String CONFIRM_UNFOLLOW = "label.subscriptions.unfollow.confirm";
092
093    /**
094     * Gets all the notifications the user may subscribe to.
095     */
096    @Factory("notificationList")
097    public void getNotificationsList() {
098        log.debug("Factory for notifications list");
099
100        DocumentModel currentDocument = navigationContext.getCurrentDocument();
101        String superParentType = documentManager.getSuperParentType(currentDocument);
102
103        List<Notification> notifs = notificationManager.getNotificationsForSubscriptions(superParentType);
104
105        List<String> subscriptions = getSelectedNotifications();
106        log.debug("Selected notifications : " + subscriptions);
107
108        List<SelectableSubscription> notifsResult = new ArrayList<SelectableSubscription>();
109        for (Notification notification : notifs) {
110            String notifName = notification.getName();
111            if (subscriptions.contains(notifName)) {
112                notifsResult.add(new SelectableSubscription(true, notification));
113            } else {
114                notifsResult.add(new SelectableSubscription(false, notification));
115            }
116        }
117        notificationList = notifsResult;
118    }
119
120    /**
121     * Gets all the notifications the user may subscribe to.
122     */
123    @Factory("inheritedNotifications")
124    public void loadInheritedNotifications() throws ClassNotFoundException {
125        inheritedNotifications = new ArrayList<Notification>();
126        DocumentModel currentDoc = navigationContext.getCurrentDocument();
127        NuxeoPrincipal principal = (NuxeoPrincipal) FacesContext.getCurrentInstance().getExternalContext().getUserPrincipal();
128        for (String group : principal.getAllGroups()) {
129            List<String> notifs = notificationManager.getSubscriptionsForUserOnDocument("group:" + group,
130                    currentDoc);
131            for (String inheritedNotification : notifs) {
132                Notification notif = notificationManager.getNotificationByName(inheritedNotification);
133                inheritedNotifications.add(notif);
134            }
135        }
136    }
137
138    /**
139     * Registers the user's choices.
140     */
141    public void updateSubscriptions() {
142
143        NuxeoPrincipal principal = (NuxeoPrincipal) FacesContext.getCurrentInstance().getExternalContext().getUserPrincipal();
144        DocumentModel currentDoc = navigationContext.getCurrentDocument();
145        if (currentSubscription.isSelected()) {
146            notificationManager.removeSubscription("user:" + principal.getName(),
147                    currentSubscription.getNotification().getName(), currentDoc);
148        } else {
149            notificationManager.addSubscription(NotificationConstants.USER_PREFIX + principal.getName(),
150                    currentSubscription.getNotification().getName(), currentDoc, false, principal, "");
151        }
152        getNotificationsList();
153    }
154
155    /**
156     * Manage (un)subscription to all notifications
157     */
158    public void updateAllSubscriptions() {
159        NuxeoPrincipal principal = (NuxeoPrincipal) FacesContext.getCurrentInstance().getExternalContext().getUserPrincipal();
160        DocumentModel currentDoc = navigationContext.getCurrentDocument();
161        List<String> userSubscriptions = notificationManager.getSubscriptionsForUserOnDocument(
162                NotificationConstants.USER_PREFIX + principal.getName(), currentDoc);
163        if (userSubscriptions.size() == 0) {
164            notificationManager.addSubscriptions(NotificationConstants.USER_PREFIX + principal.getName(), currentDoc,
165                    false, principal);
166            facesMessages.add(StatusMessage.Severity.INFO, resourcesAccessor.getMessages().get(CONFIRM_FOLLOW));
167        } else {
168            notificationManager.removeSubscriptions(NotificationConstants.USER_PREFIX + principal.getName(),
169                    userSubscriptions, currentDoc);
170            facesMessages.add(StatusMessage.Severity.INFO, resourcesAccessor.getMessages().get(CONFIRM_UNFOLLOW));
171        }
172        getNotificationsList();
173    }
174
175    @Observer(value = EventNames.DOCUMENT_SELECTION_CHANGED, create = false)
176    @BypassInterceptors
177    public void invalidateNotificationsSelection() {
178        log.debug("Invalidate archive records.................");
179        notificationList = null;
180        currentSubscription = null;
181        inheritedNotifications = null;
182    }
183
184    /**
185     * @return the previously selected notifications.
186     */
187    public List<String> getSelectedNotifications() {
188        return getSubscriptionsForCurrentUser();
189    }
190
191    /**
192     * Returns the notifications that the user already subscribed for.
193     */
194    private List<String> getSubscriptionsForCurrentUser() {
195
196        DocumentModel currentDoc = navigationContext.getCurrentDocument();
197        NuxeoPrincipal principal = (NuxeoPrincipal) FacesContext.getCurrentInstance().getExternalContext().getUserPrincipal();
198        List<String> subscriptions = notificationManager.getSubscriptionsForUserOnDocument(
199                "user:" + principal.getName(), currentDoc);
200        return subscriptions;
201    }
202
203    public SelectableSubscription getCurrentSubscription() {
204        return currentSubscription;
205    }
206
207    public void setCurrentSubscription(SelectableSubscription currentSubscription) {
208        this.currentSubscription = currentSubscription;
209    }
210
211    public List<SelectableSubscription> getNotificationList() {
212        return notificationList;
213    }
214
215    public void setNotificationList(List<SelectableSubscription> notificationList) {
216        this.notificationList = notificationList;
217    }
218
219    public List<Notification> getInheritedNotifications() {
220        return inheritedNotifications;
221    }
222
223    public void setInheritedNotifications(List<Notification> inheritedNotifications) {
224        this.inheritedNotifications = inheritedNotifications;
225    }
226
227}