001/* 002 * Copyright 2012 Anyware Services 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 */ 016package org.ametys.plugins.newsletter.userpref; 017 018import java.util.ArrayList; 019import java.util.Date; 020import java.util.HashMap; 021import java.util.HashSet; 022import java.util.List; 023import java.util.Map; 024import java.util.Set; 025import java.util.UUID; 026 027import org.apache.avalon.framework.component.Component; 028import org.apache.avalon.framework.logger.AbstractLogEnabled; 029import org.apache.avalon.framework.service.ServiceException; 030import org.apache.avalon.framework.service.ServiceManager; 031import org.apache.avalon.framework.service.Serviceable; 032 033import org.ametys.core.user.User; 034import org.ametys.core.user.UserIdentity; 035import org.ametys.core.user.UserManager; 036import org.ametys.core.userpref.UserPreferencesException; 037import org.ametys.core.userpref.UserPreferencesStorage; 038import org.ametys.plugins.newsletter.category.CategoryProviderExtensionPoint; 039import org.ametys.plugins.newsletter.daos.Subscriber; 040import org.ametys.plugins.newsletter.daos.SubscribersDAO; 041import org.ametys.web.userpref.FOUserPreferencesConstants; 042 043/** 044 * Retrieves and stores newsletter user preferences values as subscriptions. 045 */ 046public class NewsletterUserPreferencesStorage extends AbstractLogEnabled implements UserPreferencesStorage, Component, Serviceable 047{ 048 049 /** The front-office users manager. */ 050 protected UserManager _foUserManager; 051 052 /** The category provider extension point. */ 053 protected CategoryProviderExtensionPoint _categoryEP; 054 055 /** The subscribers DAO. */ 056 protected SubscribersDAO _subscribersDao; 057 058 @Override 059 public void service(ServiceManager serviceManager) throws ServiceException 060 { 061 _foUserManager = (UserManager) serviceManager.lookup(UserManager.ROLE); 062 _categoryEP = (CategoryProviderExtensionPoint) serviceManager.lookup(CategoryProviderExtensionPoint.ROLE); 063 _subscribersDao = (SubscribersDAO) serviceManager.lookup(SubscribersDAO.ROLE); 064 } 065 066 @Override 067 public Map<String, String> getUnTypedUserPrefs(UserIdentity userIdentity, String storageContext, Map<String, String> contextVars) throws UserPreferencesException 068 { 069 try 070 { 071 Map<String, String> preferenceValues = new HashMap<>(); 072 073 User user = _foUserManager.getUser(userIdentity.getPopulationId(), userIdentity.getLogin()); 074 String siteName = contextVars.get(FOUserPreferencesConstants.CONTEXT_VAR_SITENAME); 075 076 if (user != null && siteName != null) 077 { 078 List<Subscriber> subscriptions = _subscribersDao.getSubscriptions(user.getEmail(), siteName); 079 for (Subscriber subscription : subscriptions) 080 { 081 preferenceValues.put(subscription.getCategoryId(), "true"); 082 } 083 } 084 085 return preferenceValues; 086 } 087 catch (Exception e) 088 { 089 String message = "Error getting newsletter user preferences for login " + userIdentity + " and context " + storageContext; 090 getLogger().error(message, e); 091 throw new UserPreferencesException(message, e); 092 } 093 } 094 095 @Override 096 public void setUserPreferences(UserIdentity userIdentity, String storageContext, Map<String, String> contextVars, Map<String, String> preferences) throws UserPreferencesException 097 { 098 try 099 { 100 User user = _foUserManager.getUser(userIdentity.getPopulationId(), userIdentity.getLogin()); 101 String siteName = contextVars.get(FOUserPreferencesConstants.CONTEXT_VAR_SITENAME); 102 103 if (user != null && siteName != null) 104 { 105 List<Subscriber> newSubscribers = new ArrayList<>(); 106 Set<String> removeTokens = new HashSet<>(); 107 108 Map<String, String> existingCategoryIds = getExistingCategoryIds(user.getEmail(), siteName); 109 110 for (String categoryId : preferences.keySet()) 111 { 112 String value = preferences.get(categoryId); 113 114 if (value.equals("true") && _categoryEP.hasCategory(categoryId) && !existingCategoryIds.containsKey(categoryId)) 115 { 116 Subscriber subscriber = getSubscription(siteName, user, categoryId); 117 newSubscribers.add(subscriber); 118 } 119 else if (!value.equals("true") && _categoryEP.hasCategory(categoryId) && existingCategoryIds.containsKey(categoryId)) 120 { 121 String token = existingCategoryIds.get(categoryId); 122 removeTokens.add(token); 123 } 124 } 125 126 // Modify the subscriptions. 127 _subscribersDao.modifySubscriptions(newSubscribers, removeTokens); 128 } 129 } 130 catch (Exception e) 131 { 132 String message = "Error setting newsletter user preferences for login " + userIdentity + " and context " + storageContext; 133 getLogger().error(message, e); 134 throw new UserPreferencesException(message, e); 135 } 136 } 137 138 @Override 139 public void removeUserPreferences(UserIdentity userIdentity, String storageContext, Map<String, String> contextVars) throws UserPreferencesException 140 { 141 try 142 { 143 User user = _foUserManager.getUser(userIdentity.getPopulationId(), userIdentity.getLogin()); 144 String siteName = contextVars.get(FOUserPreferencesConstants.CONTEXT_VAR_SITENAME); 145 146 if (user != null && siteName != null) 147 { 148 // Remove the subscriptions. 149 _subscribersDao.unsubscribe(user.getEmail(), storageContext); 150 } 151 } 152 catch (Exception e) 153 { 154 String message = "Error removing newsletter subscriptions for login " + userIdentity + " and context " + storageContext; 155 getLogger().error(message, e); 156 throw new UserPreferencesException(message, e); 157 } 158 } 159 160 @Override 161 public String getUserPreferenceAsString(UserIdentity userIdentity, String storageContext, Map<String, String> contextVars, String id) throws UserPreferencesException 162 { 163 String value = null; 164 165 Boolean booleanValue = getUserPreferenceAsBoolean(userIdentity, storageContext, contextVars, id); 166 167 if (booleanValue != null) 168 { 169 value = booleanValue.toString(); 170 } 171 172 return value; 173 } 174 175 @Override 176 public Long getUserPreferenceAsLong(UserIdentity userIdentity, String storageContext, Map<String, String> contextVars, String id) throws UserPreferencesException 177 { 178 return null; 179 } 180 181 @Override 182 public Date getUserPreferenceAsDate(UserIdentity userIdentity, String storageContext, Map<String, String> contextVars, String id) throws UserPreferencesException 183 { 184 return null; 185 } 186 187 @Override 188 public Boolean getUserPreferenceAsBoolean(UserIdentity userIdentity, String storageContext, Map<String, String> contextVars, String id) throws UserPreferencesException 189 { 190 try 191 { 192 Boolean value = null; 193 194 User user = _foUserManager.getUser(userIdentity.getPopulationId(), userIdentity.getLogin()); 195 String siteName = contextVars.get(FOUserPreferencesConstants.CONTEXT_VAR_SITENAME); 196 197 if (user != null && siteName != null) 198 { 199 Subscriber subscriber = _subscribersDao.getSubscriber(user.getEmail(), siteName, id); 200 201 value = Boolean.valueOf(subscriber != null); 202 } 203 204 return value; 205 } 206 catch (Exception e) 207 { 208 throw new UserPreferencesException("Error getting newsletter user preferences for login " + userIdentity + " and context " + storageContext, e); 209 } 210 } 211 212 @Override 213 public Double getUserPreferenceAsDouble(UserIdentity userIdentity, String storageContext, Map<String, String> contextVars, String id) throws UserPreferencesException 214 { 215 return null; 216 } 217 218 /** 219 * Create a subscriber object from the given input. 220 * @param siteName the site name. 221 * @param user the user. 222 * @param categoryId the category ID. 223 * @return the Subscriber object. 224 */ 225 protected Subscriber getSubscription(String siteName, User user, String categoryId) 226 { 227 return getSubscription(siteName, user, categoryId, true); 228 } 229 230 /** 231 * Create a subscriber object from the given input. 232 * @param siteName the site name. 233 * @param user the user. 234 * @param categoryId the category ID. 235 * @param generateDateAndToken true to generate a token and set the subscription date, false otherwise. 236 * @return the Subscriber object. 237 */ 238 protected Subscriber getSubscription(String siteName, User user, String categoryId, boolean generateDateAndToken) 239 { 240 Subscriber subscriber = new Subscriber(); 241 subscriber.setEmail(user.getEmail()); 242 subscriber.setSiteName(siteName); 243 subscriber.setCategoryId(categoryId); 244 245 if (generateDateAndToken) 246 { 247 subscriber.setSubscribedAt(new Date()); 248 249 // Generate unique token. 250 String token = UUID.randomUUID().toString(); 251 subscriber.setToken(token); 252 } 253 254 return subscriber; 255 } 256 257 /** 258 * Get the existing subscriptions for a user in a given site. 259 * @param email the user e-mail address. 260 * @param siteName the site name. 261 * @return a Set of category IDs, to which user has subscribed. 262 */ 263 protected Map<String, String> getExistingCategoryIds(String email, String siteName) 264 { 265 Map<String, String> existingCategoryIds = new HashMap<>(); 266 267 List<Subscriber> existingSubscriptions = _subscribersDao.getSubscriptions(email, siteName); 268 for (Subscriber subscription : existingSubscriptions) 269 { 270 existingCategoryIds.put(subscription.getCategoryId(), subscription.getToken()); 271 } 272 273 return existingCategoryIds; 274 } 275}