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.security.Principal; 026import java.util.ArrayList; 027import java.util.HashMap; 028import java.util.List; 029import java.util.Map; 030 031import javax.faces.context.FacesContext; 032import javax.faces.model.SelectItem; 033 034import org.jboss.seam.ScopeType; 035import org.jboss.seam.annotations.In; 036import org.jboss.seam.annotations.Name; 037import org.jboss.seam.annotations.Out; 038import org.jboss.seam.annotations.Scope; 039import org.jboss.seam.faces.FacesMessages; 040import org.jboss.seam.international.StatusMessage; 041import org.nuxeo.common.utils.i18n.Labeler; 042import org.nuxeo.ecm.core.api.CoreSession; 043import org.nuxeo.ecm.core.api.DocumentModel; 044import org.nuxeo.ecm.core.api.NuxeoPrincipal; 045import org.nuxeo.ecm.platform.ec.notification.NotificationConstants; 046import org.nuxeo.ecm.platform.notification.api.Notification; 047import org.nuxeo.ecm.platform.notification.api.NotificationManager; 048import org.nuxeo.ecm.platform.ui.web.util.ComponentUtils; 049import org.nuxeo.ecm.webapp.base.InputController; 050 051/** 052 * Handles the subscriptions page. 053 * 054 * @author <a href="mailto:npaslaru@nuxeo.com">Narcis Paslaru</a> 055 */ 056@Name("groupsSubscriptionsAction") 057@Scope(ScopeType.PAGE) 058public class GroupsSubscriptionsAction extends InputController implements Serializable { 059 060 private static final long serialVersionUID = -2440187703248677446L; 061 062 private static final Labeler labeler = new Labeler("label.subscriptions"); 063 064 @In(create = true, required = false) 065 protected transient CoreSession documentManager; 066 067 @In(required = false) 068 @Out(required = false) 069 private List<String> selectedNotifications; 070 071 @In(create = true) 072 protected transient NotificationManager notificationManager; 073 074 private String selectedGrant; 075 076 private String selectedNotification; 077 078 private SelectItem[] permissionActionItems; 079 080 protected List<String> selectedEntries; 081 082 /** 083 * Gets all the notifications registered in the system. 084 */ 085 public List<SelectItem> getNotificationList() { 086 String parentType = documentManager.getSuperParentType(navigationContext.getCurrentDocument()); 087 List<Notification> notifs = notificationManager.getNotificationsForSubscriptions(parentType); 088 List<SelectItem> notifsResult = new ArrayList<SelectItem>(); 089 for (Notification notification : notifs) { 090 String notifName = notification.getName(); 091 String notifLabel = notification.getLabel(); 092 notifsResult.add(new SelectItem(notifName, resourcesAccessor.getMessages().get(notifLabel))); 093 } 094 return notifsResult; 095 } 096 097 /** 098 * Registers the user's choices. 099 */ 100 public void updateSubscriptions() { 101 List<String> selectedNotifications = getSelectedNotifications(); 102 List<String> subscriptions = getSubscriptionsForCurrentUser(); 103 104 List<String> newSubscriptions = getDisjunctElements(selectedNotifications, subscriptions); 105 List<String> removedSubscriptions = getDisjunctElements(subscriptions, selectedNotifications); 106 107 NuxeoPrincipal principal = (NuxeoPrincipal) currentUser; 108 DocumentModel currentDoc = navigationContext.getCurrentDocument(); 109 110 // removing the unselected subscriptions 111 if (!removedSubscriptions.isEmpty()) { 112 for (String subscription : removedSubscriptions) { 113 notificationManager.removeSubscription("user:" + principal.getName(), subscription, currentDoc); 114 } 115 } 116 117 // adding the newly selected subscriptions 118 if (!newSubscriptions.isEmpty()) { 119 for (String subscription : newSubscriptions) { 120 notificationManager.addSubscription(NotificationConstants.USER_PREFIX + principal.getName(), 121 subscription, currentDoc, false, principal, ""); 122 } 123 } 124 125 facesMessages.add(StatusMessage.Severity.INFO, 126 resourcesAccessor.getMessages().get("label.notifications.registered")); 127 } 128 129 private static List<String> getDisjunctElements(List<String> array1, List<String> array2) { 130 List<String> result = new ArrayList<String>(); 131 for (String elem1 : array1) { 132 133 if (!array2.contains(elem1)) { 134 result.add(elem1); 135 } 136 } 137 return result; 138 } 139 140 /** 141 * @return the previously selected notifications. 142 */ 143 public List<String> getSelectedNotifications() { 144 if (selectedNotifications == null) { 145 selectedNotifications = getSubscriptionsForCurrentUser(); 146 } 147 return selectedNotifications; 148 } 149 150 /** 151 * Returns the notifications that the user already subscribed for. 152 */ 153 private List<String> getSubscriptionsForCurrentUser() { 154 DocumentModel currentDoc = navigationContext.getCurrentDocument(); 155 NuxeoPrincipal principal = (NuxeoPrincipal) currentUser; 156 List<String> subscriptions = notificationManager.getSubscriptionsForUserOnDocument( 157 "user:" + principal.getName(), currentDoc); 158 return subscriptions; 159 } 160 161 /** 162 * Returns the users that subscribed to a notification. 163 */ 164 public List<String> getSubscribedUsersForNotification(String notification) { 165 DocumentModel currentDoc = navigationContext.getCurrentDocument(); 166 return notificationManager.getUsersSubscribedToNotificationOnDocument(notification, currentDoc); 167 } 168 169 /** 170 * Returns a map that contains all users and groups subscribed to notifications(keys). 171 */ 172 public Map<String, List<String>> getUsersByNotificationsForCurrentDocument() { 173 Map<String, List<String>> result = new HashMap<String, List<String>>(); 174 175 String superParentType = documentManager.getSuperParentType(navigationContext.getCurrentDocument()); 176 List<Notification> notifications = notificationManager.getNotificationsForSubscriptions(superParentType); 177 for (Notification notification : notifications) { 178 result.put(notification.getLabel(), getSubscribedUsersForNotification(notification.getName())); 179 } 180 return result; 181 } 182 183 /** 184 * @param selectedNotifications The selectedNotifications to set. 185 */ 186 public void setSelectedNotifications(List<String> selectedNotifications) { 187 this.selectedNotifications = selectedNotifications; 188 } 189 190 public SelectItem[] getNotificationActionItems() { 191 List<String> permissionActions = new ArrayList<String>(); 192 List<SelectItem> jsfModelList = new ArrayList<SelectItem>(); 193 194 permissionActions.add("Subscribe"); 195 permissionActions.add("Unsubscribe"); 196 197 for (String permissionAction : permissionActions) { 198 String label = labeler.makeLabel(permissionAction); 199 SelectItem it = new SelectItem(permissionAction, resourcesAccessor.getMessages().get(label)); 200 jsfModelList.add(it); 201 } 202 203 permissionActionItems = jsfModelList.toArray(new SelectItem[0]); 204 205 return permissionActionItems; 206 } 207 208 public String getSelectedGrant() { 209 return selectedGrant; 210 } 211 212 public void setSelectedGrant(String selectedPermission) { 213 selectedGrant = selectedPermission; 214 } 215 216 public String getSelectedNotification() { 217 return selectedNotification; 218 } 219 220 public void setSelectedNotification(String selectedNotification) { 221 this.selectedNotification = selectedNotification; 222 } 223 224 public boolean getCanAddSubscriptions() { 225 return documentManager.hasPermission(currentDocument.getRef(), "WriteSecurity"); 226 } 227 228 public String addSubscriptionsAndUpdate() { 229 if (selectedEntries == null || selectedEntries.isEmpty()) { 230 String message = ComponentUtils.translate(FacesContext.getCurrentInstance(), 231 "error.notifManager.noUserSelected"); 232 FacesMessages.instance().add(message); 233 return null; 234 } 235 String notificationName = resourcesAccessor.getMessages().get( 236 notificationManager.getNotificationByName(selectedNotification).getLabel()); 237 boolean subscribe = selectedGrant.equals("Subscribe"); 238 239 DocumentModel currentDoc = navigationContext.getCurrentDocument(); 240 NuxeoPrincipal currentPrincipal = (NuxeoPrincipal) currentUser; 241 242 List<String> registeredNotifications = null; 243 if (subscribe) { 244 registeredNotifications = getSubscribedUsersForNotification(selectedNotification); 245 } 246 247 for (String selectedEntry : selectedEntries) { 248 if (subscribe) { 249 if (registeredNotifications == null || !registeredNotifications.contains(selectedEntry)) { 250 notificationManager.addSubscription(selectedEntry, selectedNotification, currentDoc, true, 251 currentPrincipal, notificationName); 252 } else { 253 facesMessages.add(StatusMessage.Severity.WARN, 254 resourcesAccessor.getMessages().get("label.notifications.alreadyRegistered"), selectedEntry); 255 } 256 } else { 257 notificationManager.removeSubscription(selectedEntry, selectedNotification, currentDoc); 258 } 259 } 260 // reset 261 selectedEntries = null; 262 facesMessages.add(StatusMessage.Severity.INFO, 263 resourcesAccessor.getMessages().get("label.notifications.registered")); 264 return null; 265 } 266 267 public List<String> getSelectedEntries() { 268 if (selectedEntries == null) { 269 selectedEntries = new ArrayList<String>(); 270 } 271 return selectedEntries; 272 } 273 274 public void setSelectedEntries(List<String> selectedEntries) { 275 this.selectedEntries = selectedEntries; 276 } 277 278}