1 11 12 package org.jivesoftware.messenger.group; 13 14 import org.jivesoftware.util.Log; 15 import org.jivesoftware.util.Cacheable; 16 import org.jivesoftware.util.CacheSizes; 17 import org.jivesoftware.database.DbConnectionManager; 18 import org.jivesoftware.messenger.event.GroupEventDispatcher; 19 import org.jivesoftware.messenger.user.UserManager; 20 import org.jivesoftware.stringprep.Stringprep; 21 22 import java.util.*; 23 import java.util.concurrent.ConcurrentHashMap ; 24 import java.sql.Connection ; 25 import java.sql.PreparedStatement ; 26 import java.sql.ResultSet ; 27 import java.sql.SQLException ; 28 29 36 public class Group implements Cacheable { 37 38 private static final String LOAD_PROPERTIES = 39 "SELECT name, propValue FROM jiveGroupProp WHERE groupName=?"; 40 private static final String DELETE_PROPERTY = 41 "DELETE FROM jiveGroupProp WHERE groupName=? AND name=?"; 42 private static final String UPDATE_PROPERTY = 43 "UPDATE jiveGroupProp SET propValue=? WHERE name=? AND groupName=?"; 44 private static final String INSERT_PROPERTY = 45 "INSERT INTO jiveGroupProp (groupName, name, propValue) VALUES (?, ?, ?)"; 46 47 private GroupProvider provider; 48 private GroupManager groupManager; 49 private String name; 50 private String description; 51 private Map <String , String > properties; 52 private Collection<String > members; 53 private Collection<String > administrators; 54 55 66 public Group(GroupProvider provider, String name, String description, 67 Collection<String > members, Collection<String > administrators) 68 { 69 this.provider = provider; 70 this.groupManager = GroupManager.getInstance(); 71 this.name = name; 72 this.description = description; 73 this.members = members; 74 this.administrators = administrators; 75 } 76 77 82 public String getName() { 83 return name; 84 } 85 86 92 public void setName(String name) { 93 try { 94 String originalName = this.name; 95 provider.setName(this.name, name); 96 groupManager.groupCache.remove(this.name); 97 this.name = name; 98 groupManager.groupCache.put(name, this); 99 100 Map <String , Object > params = new HashMap <String , Object >(); 102 params.put("type", "nameModified"); 103 params.put("originalValue", originalName); 104 GroupEventDispatcher.dispatchEvent(this, GroupEventDispatcher.EventType.group_modified, 105 params); 106 } 107 catch (Exception e) { 108 Log.error(e); 109 } 110 } 111 112 118 public String getDescription() { 119 return description; 120 } 121 122 130 public void setDescription(String description) { 131 try { 132 String originalDescription = this.description; 133 provider.setDescription(name, description); 134 this.description = description; 135 Map <String , Object > params = new HashMap <String , Object >(); 137 params.put("type", "descriptionModified"); 138 params.put("originalValue", originalDescription); 139 GroupEventDispatcher.dispatchEvent(this, 140 GroupEventDispatcher.EventType.group_modified, params); 141 } 142 catch (Exception e) { 143 Log.error(e); 144 } 145 } 146 147 153 public Map <String ,String > getProperties() { 154 synchronized (this) { 155 if (properties == null) { 156 properties = new ConcurrentHashMap <String , String >(); 157 loadProperties(); 158 } 159 } 160 return new PropertiesMap(); 162 } 163 164 169 public Collection<String > getAdmins() { 170 return new MemberCollection(administrators, true); 172 } 173 174 179 public Collection<String > getMembers() { 180 return new MemberCollection(members, false); 182 } 183 184 190 public boolean isUser(String username) { 191 return members.contains(username) || administrators.contains(username); 192 } 193 194 public int getCachedSize() { 195 int size = 0; 198 size += CacheSizes.sizeOfObject(); size += CacheSizes.sizeOfString(name); 200 size += CacheSizes.sizeOfString(description); 201 return size; 202 } 203 204 208 private class MemberCollection extends AbstractCollection { 209 210 private Collection<String > users; 211 private boolean adminCollection; 212 213 public MemberCollection(Collection<String > users, boolean adminCollection) { 214 this.users = users; 215 this.adminCollection = adminCollection; 216 } 217 218 public Iterator iterator() { 219 return new Iterator() { 220 221 Iterator iter = users.iterator(); 222 Object current = null; 223 224 public boolean hasNext() { 225 return iter.hasNext(); 226 } 227 228 public Object next() { 229 current = iter.next(); 230 return current; 231 } 232 233 public void remove() { 234 if (current == null) { 235 throw new IllegalStateException (); 236 } 237 String user = (String )current; 238 iter.remove(); 240 provider.deleteMember(name, user); 242 if (adminCollection) { 244 Map <String , String > params = new HashMap <String , String >(); 245 params.put("admin", user); 246 GroupEventDispatcher.dispatchEvent(Group.this, 247 GroupEventDispatcher.EventType.admin_removed, params); 248 } 249 else { 250 Map <String , String > params = new HashMap <String , String >(); 251 params.put("member", user); 252 GroupEventDispatcher.dispatchEvent(Group.this, 253 GroupEventDispatcher.EventType.member_removed, params); 254 } 255 } 256 }; 257 } 258 259 public int size() { 260 return users.size(); 261 } 262 263 public boolean add(Object member) { 264 String username = (String ) member; 265 try { 266 username = Stringprep.nodeprep(username); 267 UserManager.getInstance().getUser(username); 268 } 269 catch (Exception e) { 270 throw new IllegalArgumentException ("Invalid user.", e); 271 } 272 boolean alreadyGroupUser = false; 274 if (adminCollection) { 275 alreadyGroupUser = members.contains(username); 276 } 277 else { 278 alreadyGroupUser = administrators.contains(username); 279 } 280 if (users.add(username)) { 281 if (alreadyGroupUser) { 282 provider.updateMember(name, username, adminCollection); 284 } 285 else { 286 provider.addMember(name, username, adminCollection); 288 } 289 290 if (adminCollection) { 292 Map <String , String > params = new HashMap <String , String >(); 293 params.put("admin", username); 294 if (alreadyGroupUser) { 295 GroupEventDispatcher.dispatchEvent(Group.this, 296 GroupEventDispatcher.EventType.member_removed, params); 297 } 298 GroupEventDispatcher.dispatchEvent(Group.this, 299 GroupEventDispatcher.EventType.admin_added, params); 300 } 301 else { 302 Map <String , String > params = new HashMap <String , String >(); 303 params.put("member", username); 304 if (alreadyGroupUser) { 305 GroupEventDispatcher.dispatchEvent(Group.this, 306 GroupEventDispatcher.EventType.admin_removed, params); 307 } 308 GroupEventDispatcher.dispatchEvent(Group.this, 309 GroupEventDispatcher.EventType.member_added, params); 310 } 311 if (alreadyGroupUser) { 314 if (adminCollection) { 315 if (members.contains(username)) { 316 members.remove(username); 317 } 318 } 319 else { 320 if (administrators.contains(username)) { 321 administrators.remove(username); 322 } 323 } 324 } 325 return true; 326 } 327 return false; 328 } 329 } 330 331 334 private class PropertiesMap extends AbstractMap { 335 336 public Object put(Object key, Object value) { 337 if (key == null || value == null) { 338 throw new NullPointerException (); 339 } 340 Map <String , Object > eventParams = new HashMap <String , Object >(); 341 Object answer; 342 String keyString = (String ) key; 343 synchronized (keyString.intern()) { 344 if (properties.containsKey(keyString)) { 345 String originalValue = properties.get(keyString); 346 answer = properties.put(keyString, (String )value); 347 updateProperty(keyString, (String )value); 348 eventParams.put("type", "propertyModified"); 350 eventParams.put("propertyKey", key); 351 eventParams.put("originalValue", originalValue); 352 } 353 else { 354 answer = properties.put(keyString, (String )value); 355 insertProperty(keyString, (String )value); 356 eventParams.put("type", "propertyAdded"); 358 eventParams.put("propertyKey", key); 359 } 360 } 361 GroupEventDispatcher.dispatchEvent(Group.this, 363 GroupEventDispatcher.EventType.group_modified, eventParams); 364 return answer; 365 } 366 367 public Set <Entry> entrySet() { 368 return new PropertiesEntrySet(); 369 } 370 } 371 372 375 private class PropertiesEntrySet extends AbstractSet { 376 377 public int size() { 378 return properties.entrySet().size(); 379 } 380 381 public Iterator iterator() { 382 return new Iterator() { 383 384 Iterator iter = properties.entrySet().iterator(); 385 Map.Entry current = null; 386 387 public boolean hasNext() { 388 return iter.hasNext(); 389 } 390 391 public Object next() { 392 current = (Map.Entry )iter.next(); 393 return current; 394 } 395 396 public void remove() { 397 if (current == null) { 398 throw new IllegalStateException (); 399 } 400 String key = (String )current.getKey(); 401 deleteProperty(key); 402 iter.remove(); 403 Map <String , Object > params = new HashMap <String , Object >(); 405 params.put("type", "propertyDeleted"); 406 params.put("propertyKey", key); 407 GroupEventDispatcher.dispatchEvent(Group.this, 408 GroupEventDispatcher.EventType.group_modified, params); 409 } 410 }; 411 } 412 } 413 414 private void loadProperties() { 415 Connection con = null; 416 PreparedStatement pstmt = null; 417 try { 418 con = DbConnectionManager.getConnection(); 419 pstmt = con.prepareStatement(LOAD_PROPERTIES); 420 pstmt.setString(1, name); 421 ResultSet rs = pstmt.executeQuery(); 422 while (rs.next()) { 423 properties.put(rs.getString(1), rs.getString(2)); 424 } 425 rs.close(); 426 } 427 catch (SQLException sqle) { 428 Log.error(sqle); 429 } 430 finally { 431 try { if (pstmt != null) pstmt.close(); } 432 catch (Exception e) { Log.error(e); } 433 try { if (con != null) con.close(); } 434 catch (Exception e) { Log.error(e); } 435 } 436 } 437 438 private void insertProperty(String propName, String propValue) { 439 Connection con = null; 440 PreparedStatement pstmt = null; 441 try { 442 con = DbConnectionManager.getConnection(); 443 pstmt = con.prepareStatement(INSERT_PROPERTY); 444 pstmt.setString(1, name); 445 pstmt.setString(2, propName); 446 pstmt.setString(3, propValue); 447 pstmt.executeUpdate(); 448 } 449 catch (SQLException e) { 450 Log.error(e); 451 } 452 finally { 453 try { if (pstmt != null) pstmt.close(); } 454 catch (Exception e) { Log.error(e); } 455 try { if (con != null) con.close(); } 456 catch (Exception e) { Log.error(e); } 457 } 458 } 459 460 private void updateProperty(String propName, String propValue) { 461 Connection con = null; 462 PreparedStatement pstmt = null; 463 try { 464 con = DbConnectionManager.getConnection(); 465 pstmt = con.prepareStatement(UPDATE_PROPERTY); 466 pstmt.setString(1, propValue); 467 pstmt.setString(2, propName); 468 pstmt.setString(3, name); 469 pstmt.executeUpdate(); 470 } 471 catch (SQLException e) { 472 Log.error(e); 473 } 474 finally { 475 try { if (pstmt != null) pstmt.close(); } 476 catch (Exception e) { Log.error(e); } 477 try { if (con != null) con.close(); } 478 catch (Exception e) { Log.error(e); } 479 } 480 } 481 482 private void deleteProperty(String propName) { 483 Connection con = null; 484 PreparedStatement pstmt = null; 485 try { 486 con = DbConnectionManager.getConnection(); 487 pstmt = con.prepareStatement(DELETE_PROPERTY); 488 pstmt.setString(1, name); 489 pstmt.setString(2, propName); 490 pstmt.executeUpdate(); 491 } 492 catch (SQLException e) { 493 Log.error(e); 494 } 495 finally { 496 try { if (pstmt != null) pstmt.close(); } 497 catch (Exception e) { Log.error(e); } 498 try { if (con != null) con.close(); } 499 catch (Exception e) { Log.error(e); } 500 } 501 } 502 } | Popular Tags |