1 22 package org.jboss.ha.framework.server; 23 24 25 import java.io.Serializable ; 26 import java.util.ArrayList ; 27 import java.util.Collection ; 28 import java.util.Collections ; 29 import java.util.HashMap ; 30 import java.util.HashSet ; 31 import java.util.Iterator ; 32 import java.util.Map ; 33 import java.util.Set ; 34 35 import org.jboss.cache.AbstractCacheListener; 36 import org.jboss.cache.Cache; 37 import org.jboss.cache.CacheException; 38 import org.jboss.cache.Fqn; 39 import org.jboss.cache.Node; 40 import org.jboss.ha.framework.interfaces.HAPartition; 41 import org.jboss.logging.Logger; 42 import org.jboss.system.ServiceMBeanSupport; 43 44 52 public class DistributedStateImpl 53 extends ServiceMBeanSupport 54 implements DistributedStateImplMBean 55 { 56 58 protected final static String SERVICE_NAME = "DistributedState"; 59 60 protected final static Class [] set_types=new Class []{String .class, Serializable .class, Serializable .class}; 61 protected final static Class [] remove_types=new Class []{String .class, Serializable .class}; 62 63 65 protected HashMap keyListeners = new HashMap (); 66 protected HAPartition partition; 67 protected Logger log; 68 protected String name = null; 70 protected Cache cache; 71 private DSCacheListener cacheListener; 72 73 public static final String ROOT = "__DISTRIBUTED_STATE__"; 74 75 public static final Fqn ROOTFQN = new Fqn(new Object [] { ROOT }); 76 77 public static final int ROOTFQNSIZE = ROOTFQN.size(); 78 79 81 83 public DistributedStateImpl () 84 { 85 super(); 86 this.log = Logger.getLogger (this.getClass ()); 87 this.cacheListener = new DSCacheListener(); 88 } 89 90 92 93 125 protected void createService() throws Exception 126 { 127 super.createService(); 128 } 130 131 public void startService() throws Exception 132 { 133 super.startService(); 134 } 135 136 public void stopService() throws Exception 137 { 138 super.stopService(); 139 } 144 145 public void destroyService() throws Exception 146 { 147 super.destroyService(); 148 cache.removeCacheListener(cacheListener); 149 153 } 154 155 public String listContent () throws Exception 156 { 157 StringBuffer result = new StringBuffer (); 158 Collection cats = this.getAllCategories (); 159 Iterator catsIter = cats.iterator (); 160 while (catsIter.hasNext ()) 161 { 162 String category = (String )catsIter.next (); 163 Iterator keysIter = this.getAllKeys(category).iterator (); 164 165 result.append ("-----------------------------------------------\n"); 166 result.append ("Logger : ").append (category).append ("\n\n"); 167 result.append ("KEY\t:\tVALUE\n"); 168 169 while (keysIter.hasNext ()) 170 { 171 Serializable key = (Serializable ) keysIter.next (); 172 String value = this.get (category, key).toString (); 173 result.append ("'").append(key); 174 result.append ("'\t:\t'"); 175 result.append (value); 176 result.append("'\n"); 177 } 178 result.append ("\n"); 179 } 180 return result.toString (); 181 } 182 183 public String listXmlContent () throws Exception 184 { 185 StringBuffer result = new StringBuffer (); 186 Collection cats = this.getAllCategories (); 187 Iterator catsIter = cats.iterator (); 188 189 result.append ("<DistributedState>\n"); 190 191 while (catsIter.hasNext ()) 192 { 193 String category = (String )catsIter.next (); 194 Iterator keysIter = this.getAllKeys(category).iterator (); 195 196 result.append ("\t<Logger>\n"); 197 result.append ("\t\t<LoggerName>").append (category).append ("</LoggerName>\n"); 198 199 while (keysIter.hasNext ()) 200 { 201 Serializable key = (Serializable ) keysIter.next (); 202 String value = this.get (category, key).toString (); 203 result.append ("\t\t<Entry>\n"); 204 result.append ("\t\t\t<Key>").append (key).append ("</Key>\n"); 205 result.append ("\t\t\t<Value>").append (value).append ("</Value>\n"); 206 result.append ("\t\t</Entry>\n"); 207 } 208 result.append ("\t</Logger>\n"); 209 } 210 result.append ("</DistributedState>\n"); 211 212 return result.toString (); 213 } 214 215 public Cache getClusteredCache() 216 { 217 return cache; 218 } 219 220 public void setClusteredCache(Cache cache) 221 { 222 this.cache = cache; 223 this.cache.addCacheListener(cacheListener); 224 } 225 226 228 234 public void set(String category, Serializable key, Serializable value) 235 throws Exception { 236 cache.put(buildFqn(category), key, value); 237 notifyKeyListeners (category, key, value, true); 238 } 239 240 248 public void set(String category, Serializable key, Serializable value, 249 boolean asynchronousCall) throws Exception { 250 set(category, key, value); 252 } 253 254 261 public Serializable remove(String category, Serializable key) 262 throws Exception { 263 return remove(category, key, true); 264 } 265 266 275 public Serializable remove(String category, Serializable key, 276 boolean asynchronousCall) throws Exception { 277 Serializable retVal = get(category, key); 278 if(retVal != null){ 279 cache.remove(buildFqn(category), key); 280 notifyKeyListenersOfRemove(category, key, retVal, true); 281 } 282 283 return retVal; 284 } 285 286 292 public Serializable get(String category, Serializable key) { 293 try { 294 return (Serializable ) cache.get(buildFqn(category), key); 295 } catch (CacheException ce) { 296 return null; 297 } 298 299 } 300 301 public Collection getAllCategories () 302 { 303 try { 304 Node base = cache.getChild(ROOTFQN); 305 Collection keys = (base == null ? null : base.getChildrenNames()); 306 if(keys != null && keys.size() > 0) { 307 keys = Collections.unmodifiableCollection(keys); 308 } 309 return keys; 310 } 311 catch(CacheException ce) { 312 return null; 313 } 314 } 315 316 322 public Collection getAllKeys(String category) { 323 try { 324 Node nodeLogger = getLogger(category); 325 if (nodeLogger==null) 326 return null; 327 return nodeLogger.getKeys(); 328 } catch (CacheException ce) { 329 return null; 330 } 331 } 332 333 339 public Collection getAllValues(String category) { 340 try { 341 Node categoryNode = getLogger(category); 342 if (categoryNode == null) { 343 return null; 344 } 345 Set childNodes = categoryNode.getKeys(); 346 if (childNodes == null) { 347 return null; 348 } 349 Map entries = categoryNode.getData(); 350 if (entries == null) 351 return null; 352 Collection retVal = new HashSet (entries.values()); 353 return Collections.unmodifiableCollection(retVal); 354 } catch (CacheException ce) { 355 return null; 356 } 357 } 358 359 360 public void registerDSListenerEx (String category, DSListenerEx subscriber) 361 { 362 registerListener(category, subscriber); 363 } 364 public void unregisterDSListenerEx (String category, DSListenerEx subscriber) 365 { 366 unregisterListener(category, subscriber); 367 } 368 public void registerDSListener (String category, DSListener subscriber) 369 { 370 registerListener(category, subscriber); 371 } 372 public void unregisterDSListener (String category, DSListener subscriber) 373 { 374 unregisterListener(category, subscriber); 375 } 376 377 379 381 protected void registerListener (String category, Object subscriber) 382 { 383 synchronized(this.keyListeners) 384 { 385 ArrayList listeners = (ArrayList )keyListeners.get (category); 386 if (listeners == null) 387 { 388 listeners = new ArrayList (); 389 keyListeners.put (category, listeners); 390 } 391 listeners.add (subscriber); 392 } 393 } 394 395 protected void unregisterListener (String category, Object subscriber) 396 { 397 synchronized(this.keyListeners) 398 { 399 ArrayList listeners = (ArrayList )keyListeners.get (category); 400 if (listeners == null) return; 401 402 listeners.remove (subscriber); 403 if (listeners.size () == 0) 404 { 405 keyListeners.remove (category); 406 } 407 } 408 } 409 410 protected void notifyKeyListeners (String category, Serializable key, 411 Serializable value, boolean locallyModified) 412 { 413 synchronized(this.keyListeners) 414 { 415 ArrayList listeners = (ArrayList )keyListeners.get (category); 416 if (listeners == null) 417 return; 418 String strKey = key.toString(); 419 420 for (int i = 0; i < listeners.size (); i++) 421 { 422 Object listener = listeners.get (i); 423 if( listener instanceof DSListener ) 424 { 425 DSListener dslistener = (DSListener) listener; 426 dslistener.valueHasChanged (category, strKey, value, locallyModified); 427 } 428 else 429 { 430 DSListenerEx dslistener = (DSListenerEx) listener; 431 dslistener.valueHasChanged (category, key, value, locallyModified); 432 } 433 } 434 } 435 } 436 437 protected void notifyKeyListenersOfRemove (String category, Serializable key, 438 Serializable oldContent, boolean locallyModified) 439 { 440 synchronized(this.keyListeners) 441 { 442 ArrayList listeners = (ArrayList )keyListeners.get (category); 443 if (listeners == null) 444 return; 445 String strKey = key.toString(); 446 447 for (int i = 0; i < listeners.size (); i++) 448 { 449 Object listener = listeners.get (i); 450 if( listener instanceof DSListener ) 451 { 452 DSListener dslistener = (DSListener) listener; 453 dslistener.keyHasBeenRemoved (category, strKey, oldContent, locallyModified); 454 } 455 else 456 { 457 DSListenerEx dslistener = (DSListenerEx) listener; 458 dslistener.keyHasBeenRemoved (category, key, oldContent, locallyModified); 459 } 460 } 461 } 462 } 463 464 protected void cleanupKeyListeners () 465 { 466 } 468 469 470 471 472 protected Fqn buildFqn(String category) { 474 return new Fqn(ROOTFQN, category); 475 } 476 477 protected Fqn buildFqn(String category, Serializable key) { 478 return new Fqn(new Object [] { ROOT, category, key }); 479 } 480 481 protected Fqn buildFqn(String category, Serializable key, Serializable value) { 482 return new Fqn(new Object [] { ROOT, category, key, value }); 483 } 484 485 protected Node getLogger(String category) throws CacheException { 487 return cache.getChild(buildFqn(category)); 488 } 489 490 492 private class DSCacheListener extends AbstractCacheListener 493 { 494 504 public void nodeEvict(Fqn fqn, boolean pre) {} 505 506 519 public void nodeRemove(Fqn fqn, boolean pre, boolean isLocal) { 520 if (isLocal || pre || !fqn.isChildOf(ROOTFQN)) 523 return; 524 525 543 DistributedStateImpl.this.notifyKeyListenersOfRemove((String )fqn.get(ROOTFQNSIZE), "", "", isLocal); 545 } 546 547 557 public void nodeModify(Fqn fqn, boolean pre, boolean isLocal) { 558 if (isLocal || pre || !fqn.isChildOf(ROOTFQN)) 561 return; 562 563 583 DistributedStateImpl.this.notifyKeyListeners((String )fqn.get(ROOTFQNSIZE), "", "", isLocal); 585 } 586 } 587 588 } 589 | Popular Tags |