1 11 12 package org.jivesoftware.messenger; 13 14 import org.dom4j.Element; 15 import org.dom4j.io.SAXReader; 16 import org.jivesoftware.database.DbConnectionManager; 17 import org.jivesoftware.database.SequenceManager; 18 import org.jivesoftware.messenger.container.BasicModule; 19 import org.jivesoftware.util.*; 20 import org.xmpp.packet.Message; 21 22 import java.io.StringReader ; 23 import java.sql.Connection ; 24 import java.sql.PreparedStatement ; 25 import java.sql.ResultSet ; 26 import java.text.SimpleDateFormat ; 27 import java.util.*; 28 29 38 public class OfflineMessageStore extends BasicModule { 39 40 private static final String INSERT_OFFLINE = 41 "INSERT INTO jiveOffline (username, messageID, creationDate, messageSize, message) " + 42 "VALUES (?, ?, ?, ?, ?)"; 43 private static final String LOAD_OFFLINE = 44 "SELECT message, creationDate FROM jiveOffline WHERE username=?"; 45 private static final String LOAD_OFFLINE_MESSAGE = 46 "SELECT message FROM jiveOffline WHERE username=? AND creationDate=?"; 47 private static final String SELECT_SIZE_OFFLINE = 48 "SELECT SUM(messageSize) FROM jiveOffline WHERE username=?"; 49 private static final String SELECT_SIZE_ALL_OFFLINE = 50 "SELECT SUM(messageSize) FROM jiveOffline"; 51 private static final String DELETE_OFFLINE = 52 "DELETE FROM jiveOffline WHERE username=?"; 53 private static final String DELETE_OFFLINE_MESSAGE = 54 "DELETE FROM jiveOffline WHERE username=? AND creationDate=?"; 55 56 private Cache sizeCache; 57 private SimpleDateFormat dateFormat; 58 59 64 public static OfflineMessageStore getInstance() { 65 return XMPPServer.getInstance().getOfflineMessageStore(); 66 } 67 68 private SAXReader saxReader = new SAXReader(); 69 70 73 public OfflineMessageStore() { 74 super("Offline Message Store"); 75 dateFormat = new SimpleDateFormat ("yyyyMMdd'T'hh:mm:ss"); 76 dateFormat.setTimeZone(TimeZone.getTimeZone("UTC")); 77 sizeCache = new Cache("Offline Message Size Cache", 1024*100, JiveConstants.HOUR*12); 78 } 79 80 86 public void addMessage(Message message) { 87 if (message == null) { 88 return; 89 } 90 String username = message.getTo().getNode(); 91 if (username == null) { 93 return; 94 } 95 else if (!XMPPServer.getInstance().getServerInfo().getName().equals(message.getTo() 96 .getDomain())) { 97 return; 99 } 100 101 long messageID = SequenceManager.nextID(JiveConstants.OFFLINE); 102 103 String msgXML = message.getElement().asXML(); 105 106 Connection con = null; 107 PreparedStatement pstmt = null; 108 try { 109 con = DbConnectionManager.getConnection(); 110 pstmt = con.prepareStatement(INSERT_OFFLINE); 111 pstmt.setString(1, username); 112 pstmt.setLong(2, messageID); 113 pstmt.setString(3, StringUtils.dateToMillis(new java.util.Date ())); 114 pstmt.setInt(4, msgXML.length()); 115 pstmt.setString(5, msgXML); 116 pstmt.executeUpdate(); 117 } 118 119 catch (Exception e) { 120 Log.error(LocaleUtils.getLocalizedString("admin.error"), e); 121 } 122 finally { 123 try { if (pstmt != null) { pstmt.close(); } } 124 catch (Exception e) { Log.error(e); } 125 try { if (con != null) { con.close(); } } 126 catch (Exception e) { Log.error(e); } 127 } 128 129 if (sizeCache.containsKey(username)) { 131 int size = (Integer )sizeCache.get(username); 132 size += msgXML.length(); 133 sizeCache.put(username, size); 134 } 135 } 136 137 146 public Collection<OfflineMessage> getMessages(String username, boolean delete) { 147 List<OfflineMessage> messages = new ArrayList<OfflineMessage>(); 148 Connection con = null; 149 PreparedStatement pstmt = null; 150 try { 151 con = DbConnectionManager.getConnection(); 152 pstmt = con.prepareStatement(LOAD_OFFLINE); 153 pstmt.setString(1, username); 154 ResultSet rs = pstmt.executeQuery(); 155 while (rs.next()) { 156 String msgXML = rs.getString(1); 157 Date creationDate = new Date(Long.parseLong(rs.getString(2).trim())); 158 OfflineMessage message = new OfflineMessage(creationDate, 159 saxReader.read(new StringReader (msgXML)).getRootElement()); 160 Element delay = message.addChildElement("x", "jabber:x:delay"); 162 delay.addAttribute("from", XMPPServer.getInstance().getServerInfo().getName()); 163 synchronized (dateFormat) { 164 delay.addAttribute("stamp", dateFormat.format(creationDate)); 165 } 166 messages.add(message); 167 } 168 rs.close(); 169 if (delete) { 171 pstmt.close(); 172 173 pstmt = con.prepareStatement(DELETE_OFFLINE); 174 pstmt.setString(1, username); 175 pstmt.executeUpdate(); 176 } 177 } 178 catch (Exception e) { 179 Log.error(LocaleUtils.getLocalizedString("admin.error"), e); 180 } 181 finally { 182 try { if (pstmt != null) { pstmt.close(); } } 183 catch (Exception e) { Log.error(e); } 184 try { if (con != null) { con.close(); } } 185 catch (Exception e) { Log.error(e); } 186 } 187 return messages; 188 } 189 190 198 public OfflineMessage getMessage(String username, Date creationDate) { 199 OfflineMessage message = null; 200 Connection con = null; 201 PreparedStatement pstmt = null; 202 try { 203 con = DbConnectionManager.getConnection(); 204 pstmt = con.prepareStatement(LOAD_OFFLINE_MESSAGE); 205 pstmt.setString(1, username); 206 pstmt.setString(2, StringUtils.dateToMillis(creationDate)); 207 ResultSet rs = pstmt.executeQuery(); 208 while (rs.next()) { 209 String msgXML = rs.getString(1); 210 message = 211 new OfflineMessage(creationDate, 212 saxReader.read(new StringReader (msgXML)).getRootElement()); 213 Element delay = message.addChildElement("x", "jabber:x:delay"); 215 delay.addAttribute("from", XMPPServer.getInstance().getServerInfo().getName()); 216 synchronized (dateFormat) { 217 delay.addAttribute("stamp", dateFormat.format(creationDate)); 218 } 219 } 220 rs.close(); 221 } 222 catch (Exception e) { 223 Log.error(LocaleUtils.getLocalizedString("admin.error"), e); 224 } 225 finally { 226 try { if (pstmt != null) { pstmt.close(); } } 227 catch (Exception e) { Log.error(e); } 228 try { if (con != null) { con.close(); } } 229 catch (Exception e) { Log.error(e); } 230 } 231 return message; 232 } 233 234 239 public void deleteMessages(String username) { 240 Connection con = null; 241 PreparedStatement pstmt = null; 242 try { 243 con = DbConnectionManager.getConnection(); 244 pstmt = con.prepareStatement(DELETE_OFFLINE); 245 pstmt.setString(1, username); 246 pstmt.executeUpdate(); 247 } 248 catch (Exception e) { 249 Log.error(LocaleUtils.getLocalizedString("admin.error"), e); 250 } 251 finally { 252 try { if (pstmt != null) { pstmt.close(); } } 253 catch (Exception e) { Log.error(e); } 254 try { if (con != null) { con.close(); } } 255 catch (Exception e) { Log.error(e); } 256 } 257 } 258 259 266 public void deleteMessage(String username, Date creationDate) { 267 Connection con = null; 268 PreparedStatement pstmt = null; 269 try { 270 con = DbConnectionManager.getConnection(); 271 pstmt = con.prepareStatement(DELETE_OFFLINE_MESSAGE); 272 pstmt.setString(1, username); 273 pstmt.setString(2, StringUtils.dateToMillis(creationDate)); 274 pstmt.executeUpdate(); 275 } 276 catch (Exception e) { 277 Log.error(LocaleUtils.getLocalizedString("admin.error"), e); 278 } 279 finally { 280 try { if (pstmt != null) { pstmt.close(); } } 281 catch (Exception e) { Log.error(e); } 282 try { if (con != null) { con.close(); } } 283 catch (Exception e) { Log.error(e); } 284 } 285 } 286 287 294 public int getSize(String username) { 295 if (sizeCache.containsKey(username)) { 297 return (Integer )sizeCache.get(username); 298 } 299 int size = 0; 300 Connection con = null; 301 PreparedStatement pstmt = null; 302 try { 303 con = DbConnectionManager.getConnection(); 304 pstmt = con.prepareStatement(SELECT_SIZE_OFFLINE); 305 pstmt.setString(1, username); 306 ResultSet rs = pstmt.executeQuery(); 307 if (rs.next()) { 308 size = rs.getInt(1); 309 } 310 rs.close(); 311 sizeCache.put(username, size); 313 } 314 catch (Exception e) { 315 Log.error(LocaleUtils.getLocalizedString("admin.error"), e); 316 } 317 finally { 318 try { if (pstmt != null) { pstmt.close(); } } 319 catch (Exception e) { Log.error(e); } 320 try { if (con != null) { con.close(); } } 321 catch (Exception e) { Log.error(e); } 322 } 323 return size; 324 } 325 326 332 public int getSize() { 333 int size = 0; 334 Connection con = null; 335 PreparedStatement pstmt = null; 336 try { 337 con = DbConnectionManager.getConnection(); 338 pstmt = con.prepareStatement(SELECT_SIZE_ALL_OFFLINE); 339 ResultSet rs = pstmt.executeQuery(); 340 if (rs.next()) { 341 size = rs.getInt(1); 342 } 343 rs.close(); 344 } 345 catch (Exception e) { 346 Log.error(LocaleUtils.getLocalizedString("admin.error"), e); 347 } 348 finally { 349 try { if (pstmt != null) { pstmt.close(); } } 350 catch (Exception e) { Log.error(e); } 351 try { if (con != null) { con.close(); } } 352 catch (Exception e) { Log.error(e); } 353 } 354 return size; 355 } 356 } | Popular Tags |