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.webapp.notification; 023 024import java.io.Serializable; 025import java.util.ArrayList; 026import java.util.Collections; 027import java.util.List; 028 029import javax.faces.context.FacesContext; 030 031import org.apache.commons.logging.Log; 032import org.apache.commons.logging.LogFactory; 033import org.jboss.seam.ScopeType; 034import org.jboss.seam.annotations.Factory; 035import org.jboss.seam.annotations.In; 036import org.jboss.seam.annotations.Name; 037import org.jboss.seam.annotations.Observer; 038import org.jboss.seam.annotations.Scope; 039import org.jboss.seam.annotations.datamodel.DataModel; 040import org.jboss.seam.annotations.datamodel.DataModelSelection; 041import org.jboss.seam.annotations.intercept.BypassInterceptors; 042import org.jboss.seam.faces.FacesMessages; 043import org.jboss.seam.international.StatusMessage; 044import org.nuxeo.ecm.core.api.CoreSession; 045import org.nuxeo.ecm.core.api.DocumentModel; 046import org.nuxeo.ecm.core.api.NuxeoPrincipal; 047import org.nuxeo.ecm.platform.ec.notification.NotificationConstants; 048import org.nuxeo.ecm.platform.notification.api.Notification; 049import org.nuxeo.ecm.platform.notification.api.NotificationManager; 050import org.nuxeo.ecm.platform.ui.web.api.NavigationContext; 051import org.nuxeo.ecm.webapp.base.InputController; 052import org.nuxeo.ecm.webapp.helpers.EventNames; 053import org.nuxeo.ecm.webapp.helpers.ResourcesAccessor; 054 055/** 056 * Handles the subscriptions page. 057 * 058 * @author <a href="mailto:npaslaru@nuxeo.com">Narcis Paslaru</a> 059 */ 060@Name("subscriptionAction") 061@Scope(ScopeType.PAGE) 062public class SubscriptionsAction extends InputController implements Serializable { 063 064 private static final long serialVersionUID = -2440187703248677446L; 065 066 private static final Log log = LogFactory.getLog(SubscriptionsAction.class); 067 068 @In 069 protected transient NavigationContext navigationContext; 070 071 @In(create = true, required = false) 072 protected transient CoreSession documentManager; 073 074 @DataModel("notificationList") 075 protected List<SelectableSubscription> notificationList; 076 077 @DataModel("inheritedNotifications") 078 private List<Notification> inheritedNotifications; 079 080 @DataModelSelection(value = "notificationList") 081 private SelectableSubscription currentSubscription; 082 083 @In(create = true) 084 protected transient NotificationManager notificationManager; 085 086 @In(create = true, required = false) 087 protected transient FacesMessages facesMessages; 088 089 @In(create = true) 090 protected ResourcesAccessor resourcesAccessor; 091 092 public static final String CONFIRM_FOLLOW = "label.subscriptions.follow.confirm"; 093 094 public static final String CONFIRM_UNFOLLOW = "label.subscriptions.unfollow.confirm"; 095 096 /** 097 * Gets all the notifications the user may subscribe to. 098 */ 099 @Factory("notificationList") 100 public void getNotificationsList() { 101 log.debug("Factory for notifications list"); 102 103 DocumentModel currentDocument = navigationContext.getCurrentDocument(); 104 String superParentType = documentManager.getSuperParentType(currentDocument); 105 106 List<Notification> notifs = notificationManager.getNotificationsForSubscriptions(superParentType); 107 108 List<String> subscriptions = getSelectedNotifications(); 109 log.debug("Selected notifications : " + subscriptions); 110 111 List<SelectableSubscription> notifsResult = new ArrayList<SelectableSubscription>(); 112 for (Notification notification : notifs) { 113 String notifName = notification.getName(); 114 if (subscriptions.contains(notifName)) { 115 notifsResult.add(new SelectableSubscription(true, notification)); 116 } else { 117 notifsResult.add(new SelectableSubscription(false, notification)); 118 } 119 } 120 notificationList = notifsResult; 121 } 122 123 /** 124 * Gets all the notifications the user may subscribe to. 125 */ 126 @Factory("inheritedNotifications") 127 public void loadInheritedNotifications() throws ClassNotFoundException { 128 inheritedNotifications = new ArrayList<Notification>(); 129 DocumentModel currentDoc = navigationContext.getCurrentDocument(); 130 NuxeoPrincipal principal = (NuxeoPrincipal) FacesContext.getCurrentInstance().getExternalContext().getUserPrincipal(); 131 for (String group : principal.getAllGroups()) { 132 List<String> notifs = notificationManager.getSubscriptionsForUserOnDocument("group:" + group, 133 currentDoc); 134 for (String inheritedNotification : notifs) { 135 Notification notif = notificationManager.getNotificationByName(inheritedNotification); 136 inheritedNotifications.add(notif); 137 } 138 } 139 } 140 141 /** 142 * Registers the user's choices. 143 */ 144 public void updateSubscriptions() { 145 146 NuxeoPrincipal principal = (NuxeoPrincipal) FacesContext.getCurrentInstance().getExternalContext().getUserPrincipal(); 147 DocumentModel currentDoc = navigationContext.getCurrentDocument(); 148 if (currentSubscription.isSelected()) { 149 notificationManager.removeSubscription("user:" + principal.getName(), 150 currentSubscription.getNotification().getName(), currentDoc); 151 } else { 152 notificationManager.addSubscription(NotificationConstants.USER_PREFIX + principal.getName(), 153 currentSubscription.getNotification().getName(), currentDoc, false, principal, ""); 154 } 155 getNotificationsList(); 156 } 157 158 /** 159 * Manage (un)subscription to all notifications 160 */ 161 public void updateAllSubscriptions() { 162 NuxeoPrincipal principal = (NuxeoPrincipal) FacesContext.getCurrentInstance().getExternalContext().getUserPrincipal(); 163 DocumentModel currentDoc = navigationContext.getCurrentDocument(); 164 List<String> userSubscriptions = notificationManager.getSubscriptionsForUserOnDocument( 165 NotificationConstants.USER_PREFIX + principal.getName(), currentDoc); 166 if (userSubscriptions.size() == 0) { 167 notificationManager.addSubscriptions(NotificationConstants.USER_PREFIX + principal.getName(), currentDoc, 168 false, principal); 169 facesMessages.add(StatusMessage.Severity.INFO, resourcesAccessor.getMessages().get(CONFIRM_FOLLOW)); 170 } else { 171 notificationManager.removeSubscriptions(NotificationConstants.USER_PREFIX + principal.getName(), 172 userSubscriptions, currentDoc); 173 facesMessages.add(StatusMessage.Severity.INFO, resourcesAccessor.getMessages().get(CONFIRM_UNFOLLOW)); 174 } 175 getNotificationsList(); 176 } 177 178 @Observer(value = EventNames.DOCUMENT_SELECTION_CHANGED, create = false) 179 @BypassInterceptors 180 public void invalidateNotificationsSelection() { 181 log.debug("Invalidate archive records................."); 182 notificationList = null; 183 currentSubscription = null; 184 inheritedNotifications = null; 185 } 186 187 /** 188 * @return the previously selected notifications. 189 */ 190 public List<String> getSelectedNotifications() { 191 return getSubscriptionsForCurrentUser(); 192 } 193 194 /** 195 * Returns the notifications that the user already subscribed for. 196 */ 197 private List<String> getSubscriptionsForCurrentUser() { 198 199 DocumentModel currentDoc = navigationContext.getCurrentDocument(); 200 if (currentDoc == null) { 201 return Collections.emptyList(); 202 } 203 NuxeoPrincipal principal = (NuxeoPrincipal) FacesContext.getCurrentInstance().getExternalContext().getUserPrincipal(); 204 List<String> subscriptions = notificationManager.getSubscriptionsForUserOnDocument( 205 "user:" + principal.getName(), currentDoc); 206 return subscriptions; 207 } 208 209 public SelectableSubscription getCurrentSubscription() { 210 return currentSubscription; 211 } 212 213 public void setCurrentSubscription(SelectableSubscription currentSubscription) { 214 this.currentSubscription = currentSubscription; 215 } 216 217 public List<SelectableSubscription> getNotificationList() { 218 return notificationList; 219 } 220 221 public void setNotificationList(List<SelectableSubscription> notificationList) { 222 this.notificationList = notificationList; 223 } 224 225 public List<Notification> getInheritedNotifications() { 226 return inheritedNotifications; 227 } 228 229 public void setInheritedNotifications(List<Notification> inheritedNotifications) { 230 this.inheritedNotifications = inheritedNotifications; 231 } 232 233 /** 234 * @since 9.2 235 */ 236 public boolean canFollow() { 237 return !navigationContext.getCurrentDocument().isProxy(); 238 } 239 240}