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