001/* 002 * Copyright 2015 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.sms.dao; 017 018import java.util.ArrayList; 019import java.util.Date; 020import java.util.HashMap; 021import java.util.LinkedList; 022import java.util.List; 023import java.util.Map; 024 025import org.apache.commons.lang3.StringUtils; 026import org.apache.ibatis.session.ResultContext; 027import org.apache.ibatis.session.ResultHandler; 028import org.apache.ibatis.session.RowBounds; 029import org.apache.ibatis.session.SqlSession; 030 031import org.ametys.core.datasource.AbstractMyBatisDAO; 032import org.ametys.core.ui.Callable; 033import org.ametys.plugins.sms.SMSHelper; 034 035/** 036 * DAO for manipulating SMS subscribers. 037 * 038 */ 039public class SubscriberDAO extends AbstractMyBatisDAO 040{ 041 /** The Avalon role */ 042 public static final String ROLE = SubscriberDAO.class.getName(); 043 044 /** 045 * Get all the phone numbers in the database form the list 046 * @param list the id of the phone number list 047 * @return A map, where keys are phone number and value are date object. 048 */ 049 public Map<String, Date> getPhoneNumbersFromList(String list) 050 { 051 Map<String, Object> params = new HashMap<>(); 052 params.put("list", list); 053 054 Map<String, Date> phoneNumbers = new HashMap<>(); 055 try (SqlSession session = getSession()) 056 { 057 List<Map<String, Object>> results = session.selectList("SmsSubscribers.getPhoneNumbers", params); 058 for (Map<String, Object> result : results) 059 { 060 phoneNumbers.put((String) result.get("PhoneNumber"), (Date) result.get("Date")); 061 } 062 } 063 064 return phoneNumbers; 065 } 066 067 /** 068 * Insert the phoneNumber in the database 069 * @param phoneNumber the phone number 070 * @param list the id of the phone number list 071 */ 072 public void insertNumber(String phoneNumber, String list) 073 { 074 try (SqlSession sqlSession = getSession()) 075 { 076 String stmtId = "SmsSubscribers.insertNumber"; 077 078 Map<String, Object> params = new HashMap<>(); 079 params.put("phoneNumber", phoneNumber); 080 params.put("list", list); 081 params.put("date", new Date()); 082 083 // Insert the session object and get the generated ID. 084 sqlSession.insert(stmtId, params); 085 086 // Commit the transaction. 087 sqlSession.commit(); 088 } 089 } 090 091 /** 092 * Check if the phoneNumber exists in the database 093 * @param phoneNumber the phone number 094 * @param list the id of the list 095 * @return true if exist 096 */ 097 public boolean numberAlreadyExists(String phoneNumber, String list) 098 { 099 String stmtId = "SmsSubscribers.getPhoneNumbers"; 100 101 try (SqlSession session = getSession()) 102 { 103 Map<String, Object> params = new HashMap<>(); 104 params.put("phoneNumber", phoneNumber); 105 params.put("list", list); 106 107 List<Map> selectList = session.selectList(stmtId, params, new RowBounds(RowBounds.NO_ROW_OFFSET, 1)); 108 return selectList.size() > 0; 109 } 110 } 111 112 /** 113 * Creates a SMS subscriber. 114 * @param listId The id of the SMS list to subscribe to. 115 * @param phoneNumber The phone number to add 116 * @return The list id and the phone number of the added subscriber, or an error 117 */ 118 @Callable 119 public Map<String, String> createSubscriber(String listId, String phoneNumber) 120 { 121 Map<String, String> result = new HashMap<>(); 122 123 try 124 { 125 String realPhoneNumber = phoneNumber.trim(); 126 realPhoneNumber = SMSHelper.transformPhoneNumber(realPhoneNumber); 127 if (!SMSHelper.checkPhoneNumber(realPhoneNumber) || !SMSHelper.PHONE_NUMBER_INTERNATIONAL_VALIDATOR.matcher(realPhoneNumber).matches()) 128 { 129 result.put("error", "wrong-format"); 130 } 131 else if (numberAlreadyExists(realPhoneNumber, listId)) 132 { 133 result.put("error", "already-exists"); 134 } 135 else 136 { 137 insertNumber(realPhoneNumber, listId); 138 result.put("phoneNumber", realPhoneNumber); 139 result.put("smsListId", listId); 140 } 141 } 142 catch (Exception e) 143 { 144 getLogger().error("Unable to add a new subscriber", e); 145 result.put("error", "exception"); 146 } 147 148 return result; 149 } 150 151 /** 152 * Delete the phoneNumber in the database 153 * @param phoneNumber the phone number 154 * @param list the id of the phone number list 155 */ 156 public void deleteNumber(String phoneNumber, String list) 157 { 158 try (SqlSession sqlSession = getSession()) 159 { 160 String stmtId = "SmsSubscribers.deleteNumber"; 161 162 Map<String, Object> params = new HashMap<>(); 163 if (StringUtils.isNotEmpty(phoneNumber)) 164 { 165 params.put("phoneNumber", phoneNumber); 166 } 167 if (StringUtils.isNotEmpty(list)) 168 { 169 params.put("list", list); 170 } 171 172 // Insert the session object and get the generated ID. 173 sqlSession.delete(stmtId, params); 174 175 // Commit the transaction. 176 sqlSession.commit(); 177 } 178 } 179 180 /** 181 * Delete every phone number of a list 182 * @param list the id of the phone number list 183 */ 184 public void deleteAllNumbers(String list) 185 { 186 deleteNumber(null, list); 187 } 188 189 /** 190 * Deletes the given subscribers. 191 * @param listId The The id of the SMS list. 192 * @param phoneNumbers The phone numbers to delete 193 * @return The list id, the numbers deleted, the numbers not deleted and/or an error. 194 */ 195 @Callable 196 public Map<String, Object> deleteSubscribers(String listId, ArrayList<String> phoneNumbers) 197 { 198 Map<String, Object> result = new HashMap<>(); 199 List<String> numbersDeleted = new LinkedList<>(); 200 List<String> numbersNotDeleted = new LinkedList<>(); 201 202 for (String phoneNumber : phoneNumbers) 203 { 204 try 205 { 206 deleteNumber(phoneNumber, listId); 207 numbersDeleted.add(phoneNumber); 208 } 209 catch (Exception e) 210 { 211 getLogger().error("Unable to delete the subscriber " + phoneNumber, e); 212 numbersNotDeleted.add(phoneNumber); 213 result.put("error", "exception"); 214 } 215 } 216 217 result.put("listId", listId); 218 result.put("numbersDeleted", numbersDeleted); 219 result.put("numbersNotDeleted", numbersNotDeleted); 220 221 return result; 222 } 223 224 /** 225 * Get the number of user in a list 226 * @return the number of user for each sms list 227 */ 228 public Map<String, Number> getNbUserFromList() 229 { 230 Map<String, Number> userCounts = new HashMap<>(); 231 try (SqlSession session = getSession()) 232 { 233 session.select("SmsSubscribers.getUserCounts", new ResultHandler<Map<String, Object>>() 234 { 235 @Override 236 public void handleResult(ResultContext<? extends Map<String, Object>> context) 237 { 238 final Map<String, Object> map = context.getResultObject(); 239 userCounts.put((String) map.get("ListId"), (Number) map.get("nb")); 240 } 241 }); 242 } 243 244 return userCounts; 245 } 246}