1 22 package org.jboss.aspects.versioned; 23 24 import org.jboss.aop.InstanceAdvised; 25 import org.jboss.aop.proxy.ClassProxy; 26 import org.jboss.aop.proxy.ClassProxyFactory; 27 import org.jboss.logging.Logger; 28 import org.jboss.tm.TransactionLocal; 29 import org.jboss.util.id.GUID; 30 31 import javax.naming.InitialContext ; 32 import javax.transaction.Transaction ; 33 import javax.transaction.TransactionManager ; 34 import java.lang.reflect.Method ; 35 import java.util.Collection ; 36 import java.util.HashMap ; 37 import java.util.Iterator ; 38 import java.util.Map ; 39 import java.util.Set ; 40 41 42 47 public class DistributedMapState extends CollectionStateManager implements Map , DistributedState, java.io.Externalizable 48 { 49 private static final long serialVersionUID = -5397547850033533784L; 50 51 private static HashMap mapMethodMap; 52 53 protected static Logger log = Logger.getLogger(DistributedMapState.class); 54 static 55 { 56 try 57 { 58 mapMethodMap = new HashMap (); 59 Method [] methods = Map .class.getDeclaredMethods(); 60 for (int i = 0; i < methods.length; i++) 61 { 62 long hash = org.jboss.aop.util.MethodHashing.methodHash(methods[i]); 63 mapMethodMap.put(new Long (hash), methods[i]); 64 } 65 66 } 67 catch (Exception ignored) 68 { 69 ignored.printStackTrace(); 70 } 71 } 72 73 protected volatile long versionId; 74 protected HashMap updates; 75 protected String classname; 76 transient protected Map base; 77 transient protected TransactionLocal txState = new TransactionLocal(); 78 transient protected TransactionLocal txVersion = new TransactionLocal(); 79 transient protected DistributedVersionManager versionManager; 80 transient protected SynchronizationManager synchManager; 81 transient protected TransactionManager tm; 82 transient protected ClassProxy proxy; 83 84 87 public DistributedMapState() {} 88 89 90 public DistributedMapState(GUID guid, long timeout, ClassProxy proxy, Map obj, DistributedVersionManager versionManager, SynchronizationManager synchManager) 91 throws Exception 92 { 93 super(guid, timeout, mapMethodMap); 94 this.base = obj; 95 this.classname = obj.getClass().getName(); 96 this.versionManager = versionManager; 97 this.synchManager = synchManager; 98 this.proxy = proxy; 99 InitialContext ctx = new InitialContext (); 100 this.tm = (TransactionManager )ctx.lookup("java:/TransactionManager"); 101 this.updates = createMapUpdates(base); 102 } 103 104 public HashMap getMethodMap() 105 { 106 return ClassProxyFactory.getMethodMap(base.getClass().getName()); 107 } 108 109 public InstanceAdvised getObject() { return proxy; } 110 111 113 protected Map getCurrentState(boolean forUpdate) throws Exception 114 { 115 Transaction tx = tm.getTransaction(); 116 if (tx == null) 117 { 118 if (forUpdate) versionId++; 119 return base; 120 } 121 122 Map state = (Map )txState.get(tx); 123 if (state == null && forUpdate) 124 { 125 state = (Map )base.getClass().newInstance(); 126 state.putAll(base); 127 txState.set(tx, state); 128 long newId = versionId + 1; 129 synchManager.registerUpdate(tx, this); 130 txVersion.set(tx, new Long (newId)); 131 return state; 132 } 133 return base; 134 } 135 136 137 protected HashMap createMapUpdates(Map state) 138 { 139 HashMap mapUpdates = new HashMap (); 140 Iterator it = state.entrySet().iterator(); 141 while (it.hasNext()) 142 { 143 Map.Entry entry = (Map.Entry )it.next(); 144 Object obj = entry.getValue(); 145 if (versionManager.isVersioned(obj)) 146 { 147 mapUpdates.put(entry.getKey(), new VersionReference(VersionManager.getGUID((InstanceAdvised)obj))); 148 } 149 else 150 { 151 mapUpdates.put(entry.getKey(), obj); 152 } 153 } 154 return mapUpdates; 155 } 156 157 public DistributedUpdate createTxUpdate(Transaction tx) 158 { 159 Map state = (Map )txState.get(tx); 160 long newId = ((Long )txVersion.get(tx)).longValue(); 161 DistributedMapUpdate update = new DistributedMapUpdate(guid, createMapUpdates(state), newId); 162 return update; 163 } 164 165 public InstanceAdvised buildObject(SynchronizationManager manager, DistributedVersionManager versionManager) 166 throws Exception 167 { 168 log.trace("building a Map"); 169 this.versionManager = versionManager; 170 this.synchManager = manager; 171 log.trace("DistributedMaptState: classname: " + classname); 172 Class clazz = Thread.currentThread().getContextClassLoader().loadClass(classname); 173 base = (Map )clazz.newInstance(); 174 Iterator it = updates.entrySet().iterator(); 175 while (it.hasNext()) 176 { 177 Map.Entry entry = (Map.Entry )it.next(); 178 Object val = entry.getValue(); 179 if (val instanceof VersionReference) 180 { 181 VersionReference ref = (VersionReference)val; 182 val = manager.getObject(ref.getGUID()); 183 if (val == null) 184 { 185 DistributedState fieldVal = manager.getState(ref.getGUID()); 186 val = fieldVal.buildObject(manager, versionManager); 187 ref.set((InstanceAdvised)val); 188 } 189 } 190 base.put(entry.getKey(), val); 191 } 192 proxy = versionManager.addMapVersioning(base, this); 193 return proxy; 194 } 195 196 public void checkOptimisticLock(Transaction tx) 197 { 198 Long version = (Long )txVersion.get(tx); 200 if (version.longValue() <= versionId) 201 throw new OptimisticLockFailure("optimistic lock failure for list"); 202 } 203 204 public void mergeState(Transaction tx) throws Exception 205 { 206 Map current = (Map )txState.get(tx); 208 base = current; 209 Long version = (Long )txVersion.get(tx); 210 versionId = version.longValue(); 211 } 212 213 public void mergeState(DistributedUpdate update) throws Exception 214 { 215 DistributedMapUpdate mapUpdate = (DistributedMapUpdate)update; 216 this.versionId = mapUpdate.versionId; 217 base.clear(); 218 Iterator it = mapUpdate.mapUpdates.entrySet().iterator(); 219 while (it.hasNext()) 220 { 221 Map.Entry entry = (Map.Entry )it.next(); 222 Object val = entry.getValue(); 223 if (val instanceof VersionReference) 224 { 225 VersionReference ref = (VersionReference)val; 226 val = synchManager.getObject(ref.getGUID()); 227 ref.set((InstanceAdvised)val); 228 } 229 base.put(entry.getKey(), val); 230 } 231 updates = mapUpdate.mapUpdates; 232 } 233 234 236 public void clear() 237 { 238 try 239 { 240 lock.readLock().acquire(); 241 try 242 { 243 Map state = getCurrentState(true); 244 state.clear(); 245 } 246 finally 247 { 248 lock.readLock().release(); 249 } 250 } 251 catch (Exception ex) 252 { 253 throw new RuntimeException (ex); 254 } 255 } 256 257 public boolean containsKey(Object o) 258 { 259 try 260 { 261 lock.readLock().acquire(); 262 try 263 { 264 Map state = getCurrentState(false); 265 return state.containsKey(o); 266 } 267 finally 268 { 269 lock.readLock().release(); 270 } 271 } 272 catch (Exception ex) 273 { 274 throw new RuntimeException (ex); 275 } 276 } 277 278 public boolean containsValue(Object o) 279 { 280 try 281 { 282 lock.readLock().acquire(); 283 try 284 { 285 Map state = getCurrentState(false); 286 return state.containsKey(o); 287 } 288 finally 289 { 290 lock.readLock().release(); 291 } 292 } 293 catch (Exception ex) 294 { 295 throw new RuntimeException (ex); 296 } 297 } 298 299 public Set entrySet() 300 { 301 try 302 { 303 lock.readLock().acquire(); 304 try 305 { 306 Map state = getCurrentState(false); 307 return state.entrySet(); 308 } 309 finally 310 { 311 lock.readLock().release(); 312 } 313 } 314 catch (Exception ex) 315 { 316 throw new RuntimeException (ex); 317 } 318 } 319 320 public boolean equals(Object o) 321 { 322 try 323 { 324 lock.readLock().acquire(); 325 try 326 { 327 Map state = getCurrentState(false); 328 return state.equals(o); 329 } 330 finally 331 { 332 lock.readLock().release(); 333 } 334 } 335 catch (Exception ex) 336 { 337 throw new RuntimeException (ex); 338 } 339 } 340 341 public Object get(Object o) 342 { 343 try 344 { 345 lock.readLock().acquire(); 346 try 347 { 348 Map state = getCurrentState(false); 349 return state.get(o); 350 } 351 finally 352 { 353 lock.readLock().release(); 354 } 355 } 356 catch (Exception ex) 357 { 358 throw new RuntimeException (ex); 359 } 360 } 361 362 public int hashCode() 363 { 364 try 365 { 366 lock.readLock().acquire(); 367 try 368 { 369 Map state = getCurrentState(false); 370 return state.hashCode(); 371 } 372 finally 373 { 374 lock.readLock().release(); 375 } 376 } 377 catch (Exception ex) 378 { 379 throw new RuntimeException (ex); 380 } 381 } 382 public boolean isEmpty() 383 { 384 try 385 { 386 lock.readLock().acquire(); 387 try 388 { 389 Map state = getCurrentState(false); 390 return state.isEmpty(); 391 } 392 finally 393 { 394 lock.readLock().release(); 395 } 396 } 397 catch (Exception ex) 398 { 399 throw new RuntimeException (ex); 400 } 401 } 402 403 public Set keySet() 404 { 405 try 406 { 407 lock.readLock().acquire(); 408 try 409 { 410 Map state = getCurrentState(false); 411 return state.keySet(); 412 } 413 finally 414 { 415 lock.readLock().release(); 416 } 417 } 418 catch (Exception ex) 419 { 420 throw new RuntimeException (ex); 421 } 422 } 423 424 public Object put(Object key, Object val) 425 { 426 try 427 { 428 lock.readLock().acquire(); 429 try 430 { 431 val = versionManager.makeVersioned(val); 432 Map state = getCurrentState(true); 433 return state.put(key, val); 434 } 435 finally 436 { 437 lock.readLock().release(); 438 } 439 } 440 catch (Exception ex) 441 { 442 throw new RuntimeException (ex); 443 } 444 } 445 446 public void putAll(Map c) 447 { 448 try 449 { 450 lock.readLock().acquire(); 451 try 452 { 453 Map state = getCurrentState(true); 454 Iterator it = state.entrySet().iterator(); 455 while (it.hasNext()) 456 { 457 Map.Entry entry = (Map.Entry )it.next(); 458 Object val = versionManager.makeVersioned(entry.getValue()); 459 state.put(entry.getKey(), val); 460 } 461 } 462 finally 463 { 464 lock.readLock().release(); 465 } 466 } 467 catch (Exception ex) 468 { 469 throw new RuntimeException (ex); 470 } 471 } 472 public Object remove(Object key) 477 { 478 try 479 { 480 lock.readLock().acquire(); 481 try 482 { 483 Map state = getCurrentState(true); 484 return state.remove(key); 485 } 486 finally 487 { 488 lock.readLock().release(); 489 } 490 } 491 catch (Exception ex) 492 { 493 throw new RuntimeException (ex); 494 } 495 } 496 497 public int size() 498 { 499 try 500 { 501 lock.readLock().acquire(); 502 try 503 { 504 Map state = getCurrentState(false); 505 return state.size(); 506 } 507 finally 508 { 509 lock.readLock().release(); 510 } 511 } 512 catch (Exception ex) 513 { 514 throw new RuntimeException (ex); 515 } 516 } 517 518 public Collection values() 519 { 520 try 521 { 522 lock.readLock().acquire(); 523 try 524 { 525 Map state = getCurrentState(false); 526 return state.values(); 527 } 528 finally 529 { 530 lock.readLock().release(); 531 } 532 } 533 catch (Exception ex) 534 { 535 throw new RuntimeException (ex); 536 } 537 } 538 539 public void writeExternal(java.io.ObjectOutput out) 540 throws java.io.IOException 541 { 542 super.writeExternal(out); 543 out.writeLong(versionId); 544 out.writeObject(updates); 545 out.writeObject(classname); 546 } 547 548 public void readExternal(java.io.ObjectInput in) 549 throws java.io.IOException , ClassNotFoundException 550 { 551 super.readExternal(in); 552 versionId = in.readLong(); 553 this.updates = (HashMap )in.readObject(); 554 this.classname = (String )in.readObject(); 555 try 556 { 557 InitialContext ctx = new InitialContext (); 558 this.tm = (TransactionManager )ctx.lookup("java:/TransactionManager"); 559 } 560 catch (Exception ex) 561 { 562 throw new RuntimeException (ex); 563 } 564 this.txState = new TransactionLocal(); 565 this.txVersion = new TransactionLocal(); 566 this.methodMap = mapMethodMap; 567 } 568 569 } 570 | Popular Tags |