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.ArrayList ; 36 import java.util.Collection ; 37 import java.util.HashMap ; 38 import java.util.Iterator ; 39 import java.util.List ; 40 import java.util.ListIterator ; 41 42 43 48 public class DistributedListState extends CollectionStateManager implements List , DistributedState, java.io.Externalizable 49 { 50 private static final long serialVersionUID = 8318313674571329182L; 51 52 private static HashMap listMethodMap; 53 54 protected static Logger log = Logger.getLogger(DistributedListState.class); 55 static 56 { 57 try 58 { 59 listMethodMap = new HashMap (); 60 Method [] methods = List .class.getDeclaredMethods(); 61 for (int i = 0; i < methods.length; i++) 62 { 63 long hash = org.jboss.aop.util.MethodHashing.methodHash(methods[i]); 64 listMethodMap.put(new Long (hash), methods[i]); 65 } 66 67 } 68 catch (Exception ignored) 69 { 70 ignored.printStackTrace(); 71 } 72 } 73 74 protected volatile long versionId; 75 protected ArrayList updates; 76 protected String classname; 77 transient protected List base; 78 transient protected TransactionLocal txState = new TransactionLocal(); 79 transient protected TransactionLocal txVersion = new TransactionLocal(); 80 transient protected DistributedVersionManager versionManager; 81 transient protected SynchronizationManager synchManager; 82 transient protected TransactionManager tm; 83 transient protected ClassProxy proxy; 84 85 88 public DistributedListState() {} 89 90 91 public DistributedListState(GUID guid, long timeout, ClassProxy proxy, List obj, DistributedVersionManager versionManager, SynchronizationManager synchManager) 92 throws Exception 93 { 94 super(guid, timeout, listMethodMap); 95 this.base = obj; 96 this.classname = obj.getClass().getName(); 97 this.versionManager = versionManager; 98 this.synchManager = synchManager; 99 this.proxy = proxy; 100 InitialContext ctx = new InitialContext (); 101 this.tm = (TransactionManager )ctx.lookup("java:/TransactionManager"); 102 this.updates = createListUpdates(base); 103 } 104 105 public HashMap getMethodMap() 106 { 107 return ClassProxyFactory.getMethodMap(base.getClass().getName()); 108 } 109 110 public InstanceAdvised getObject() { return proxy; } 111 112 114 protected List getCurrentState(boolean forUpdate) throws Exception 115 { 116 Transaction tx = tm.getTransaction(); 117 if (tx == null) 118 { 119 if (forUpdate) versionId++; 120 return base; 121 } 122 123 List state = (List )txState.get(tx); 124 if (state == null && forUpdate) 125 { 126 state = (List )base.getClass().newInstance(); 127 state.addAll(base); 128 txState.set(tx, state); 129 long newId = versionId + 1; 130 synchManager.registerUpdate(tx, this); 131 txVersion.set(tx, new Long (newId)); 132 return state; 133 } 134 return base; 135 } 136 137 138 protected ArrayList createListUpdates(List state) 139 { 140 ArrayList listUpdates = new ArrayList (state.size()); 141 Iterator it = state.iterator(); 142 while (it.hasNext()) 143 { 144 Object obj = it.next(); 145 if (versionManager.isVersioned(obj)) 146 { 147 listUpdates.add(new VersionReference(VersionManager.getGUID((InstanceAdvised)obj))); 148 } 149 else 150 { 151 listUpdates.add(obj); 152 } 153 } 154 return listUpdates; 155 } 156 157 public DistributedUpdate createTxUpdate(Transaction tx) 158 { 159 List state = (List )txState.get(tx); 160 long newId = ((Long )txVersion.get(tx)).longValue(); 161 DistributedListUpdate update = new DistributedListUpdate(guid, createListUpdates(state), newId); 162 return update; 163 } 164 165 public InstanceAdvised buildObject(SynchronizationManager manager, DistributedVersionManager versionManager) 166 throws Exception 167 { 168 log.trace("building a List"); 169 this.versionManager = versionManager; 170 this.synchManager = manager; 171 log.trace("DistributedListState: classname: " + classname); 172 Class clazz = Thread.currentThread().getContextClassLoader().loadClass(classname); 173 base = (List )clazz.newInstance(); 174 Iterator it = updates.iterator(); 175 while (it.hasNext()) 176 { 177 Object val = it.next(); 178 if (val instanceof VersionReference) 179 { 180 VersionReference ref = (VersionReference)val; 181 val = manager.getObject(ref.getGUID()); 182 if (val == null) 183 { 184 DistributedState fieldVal = manager.getState(ref.getGUID()); 185 val = fieldVal.buildObject(manager, versionManager); 186 ref.set((InstanceAdvised)val); 187 } 188 } 189 base.add(val); 190 } 191 proxy = versionManager.addListVersioning(base, this); 192 return proxy; 193 } 194 195 public void checkOptimisticLock(Transaction tx) 196 { 197 Long version = (Long )txVersion.get(tx); 199 if (version.longValue() <= versionId) 200 throw new OptimisticLockFailure("optimistic lock failure for list"); 201 } 202 203 public void mergeState(Transaction tx) throws Exception 204 { 205 List current = (List )txState.get(tx); 207 base = current; 208 Long version = (Long )txVersion.get(tx); 209 versionId = version.longValue(); 210 } 211 212 public void mergeState(DistributedUpdate update) throws Exception 213 { 214 DistributedListUpdate listUpdate = (DistributedListUpdate)update; 215 this.versionId = listUpdate.versionId; 216 base.clear(); 217 Iterator it = listUpdate.listUpdates.iterator(); 218 while (it.hasNext()) 219 { 220 Object val = it.next(); 221 if (val instanceof VersionReference) 222 { 223 VersionReference ref = (VersionReference)val; 224 val = synchManager.getObject(ref.getGUID()); 225 ref.set((InstanceAdvised)val); 226 } 227 base.add(val); 228 } 229 updates = listUpdate.listUpdates; 230 } 231 232 234 public boolean add(Object val) 235 { 236 try 237 { 238 lock.readLock().acquire(); 239 try 240 { 241 val = versionManager.makeVersioned(val); 242 List state = getCurrentState(true); 243 return state.add(val); 244 } 245 finally 246 { 247 lock.readLock().release(); 248 } 249 } 250 catch (Exception ex) 251 { 252 throw new RuntimeException (ex); 253 } 254 } 255 256 public void add(int index, Object val) 257 { 258 try 259 { 260 lock.readLock().acquire(); 261 try 262 { 263 val = versionManager.makeVersioned(val); 264 List state = getCurrentState(true); 265 state.add(index, val); 266 } 267 finally 268 { 269 lock.readLock().release(); 270 } 271 } 272 catch (Exception ex) 273 { 274 throw new RuntimeException (ex); 275 } 276 } 277 278 279 public boolean addAll(Collection c) 280 { 281 try 282 { 283 lock.readLock().acquire(); 284 try 285 { 286 List state = getCurrentState(true); 287 Object [] copy = c.toArray(); 288 for (int i = 0; i < copy.length; i++) 289 { 290 Object item = versionManager.makeVersioned(copy[i]); 291 state.add(item); 292 } 293 return true; 294 } 295 finally 296 { 297 lock.readLock().release(); 298 } 299 } 300 catch (Exception ex) 301 { 302 throw new RuntimeException (ex); 303 } 304 } 305 306 public boolean addAll(int index, Collection c) 307 { 308 try 309 { 310 lock.readLock().acquire(); 311 try 312 { 313 List state = getCurrentState(true); 314 Object [] copy = c.toArray(); 315 for (int i = 0; i < copy.length; i++) 316 { 317 Object item = versionManager.makeVersioned(copy[i]); 318 state.add(index + i, item); 319 } 320 return true; 321 } 322 finally 323 { 324 lock.readLock().release(); 325 } 326 } 327 catch (Exception ex) 328 { 329 throw new RuntimeException (ex); 330 } 331 } 332 333 public void clear() 334 { 335 try 336 { 337 lock.readLock().acquire(); 338 try 339 { 340 List state = getCurrentState(true); 341 state.clear(); 342 } 343 finally 344 { 345 lock.readLock().release(); 346 } 347 } 348 catch (Exception ex) 349 { 350 throw new RuntimeException (ex); 351 } 352 } 353 354 public boolean contains(Object o) 355 { 356 try 357 { 358 lock.readLock().acquire(); 359 try 360 { 361 List state = getCurrentState(false); 362 return state.contains(o); 363 } 364 finally 365 { 366 lock.readLock().release(); 367 } 368 } 369 catch (Exception ex) 370 { 371 throw new RuntimeException (ex); 372 } 373 } 374 public boolean containsAll(Collection c) 375 { 376 try 377 { 378 lock.readLock().acquire(); 379 try 380 { 381 List state = getCurrentState(false); 382 return state.containsAll(c); 383 } 384 finally 385 { 386 lock.readLock().release(); 387 } 388 } 389 catch (Exception ex) 390 { 391 throw new RuntimeException (ex); 392 } 393 } 394 public boolean equals(Object o) 395 { 396 try 397 { 398 lock.readLock().acquire(); 399 try 400 { 401 List state = getCurrentState(false); 402 return state.equals(o); 403 } 404 finally 405 { 406 lock.readLock().release(); 407 } 408 } 409 catch (Exception ex) 410 { 411 throw new RuntimeException (ex); 412 } 413 } 414 public Object get(int i) 415 { 416 try 417 { 418 lock.readLock().acquire(); 419 try 420 { 421 List state = getCurrentState(false); 422 return state.get(i); 423 } 424 finally 425 { 426 lock.readLock().release(); 427 } 428 } 429 catch (Exception ex) 430 { 431 throw new RuntimeException (ex); 432 } 433 } 434 public int hashCode() 435 { 436 try 437 { 438 lock.readLock().acquire(); 439 try 440 { 441 List state = getCurrentState(false); 442 return state.hashCode(); 443 } 444 finally 445 { 446 lock.readLock().release(); 447 } 448 } 449 catch (Exception ex) 450 { 451 throw new RuntimeException (ex); 452 } 453 } 454 public int indexOf(Object o) 455 { 456 try 457 { 458 lock.readLock().acquire(); 459 try 460 { 461 List state = getCurrentState(false); 462 return state.indexOf(o); 463 } 464 finally 465 { 466 lock.readLock().release(); 467 } 468 } 469 catch (Exception ex) 470 { 471 throw new RuntimeException (ex); 472 } 473 } 474 public boolean isEmpty() 475 { 476 try 477 { 478 lock.readLock().acquire(); 479 try 480 { 481 List state = getCurrentState(false); 482 return state.isEmpty(); 483 } 484 finally 485 { 486 lock.readLock().release(); 487 } 488 } 489 catch (Exception ex) 490 { 491 throw new RuntimeException (ex); 492 } 493 } 494 public Iterator iterator() 495 { 496 try 497 { 498 lock.readLock().acquire(); 499 try 500 { 501 List state = getCurrentState(false); 502 return state.iterator(); 503 } 504 finally 505 { 506 lock.readLock().release(); 507 } 508 } 509 catch (Exception ex) 510 { 511 throw new RuntimeException (ex); 512 } 513 } 514 public int lastIndexOf(Object o) 515 { 516 try 517 { 518 lock.readLock().acquire(); 519 try 520 { 521 List state = getCurrentState(false); 522 return state.lastIndexOf(o); 523 } 524 finally 525 { 526 lock.readLock().release(); 527 } 528 } 529 catch (Exception ex) 530 { 531 throw new RuntimeException (ex); 532 } 533 } 534 public ListIterator listIterator() 535 { 536 try 537 { 538 lock.readLock().acquire(); 539 try 540 { 541 List state = getCurrentState(false); 542 return state.listIterator(); 543 } 544 finally 545 { 546 lock.readLock().release(); 547 } 548 } 549 catch (Exception ex) 550 { 551 throw new RuntimeException (ex); 552 } 553 } 554 public ListIterator listIterator(int index) 555 { 556 try 557 { 558 lock.readLock().acquire(); 559 try 560 { 561 List state = getCurrentState(false); 562 return state.listIterator(index); 563 } 564 finally 565 { 566 lock.readLock().release(); 567 } 568 } 569 catch (Exception ex) 570 { 571 throw new RuntimeException (ex); 572 } 573 } 574 575 public Object remove(int index) 580 { 581 try 582 { 583 lock.readLock().acquire(); 584 try 585 { 586 List state = getCurrentState(true); 587 return state.remove(index); 588 } 589 finally 590 { 591 lock.readLock().release(); 592 } 593 } 594 catch (Exception ex) 595 { 596 throw new RuntimeException (ex); 597 } 598 } 599 public boolean remove(Object o) 600 { 601 try 602 { 603 lock.readLock().acquire(); 604 try 605 { 606 List state = getCurrentState(true); 607 return state.remove(o); 608 } 609 finally 610 { 611 lock.readLock().release(); 612 } 613 } 614 catch (Exception ex) 615 { 616 throw new RuntimeException (ex); 617 } 618 } 619 public boolean removeAll(Collection c) 620 { 621 try 622 { 623 lock.readLock().acquire(); 624 try 625 { 626 List state = getCurrentState(true); 627 return state.removeAll(c); 628 } 629 finally 630 { 631 lock.readLock().release(); 632 } 633 } 634 catch (Exception ex) 635 { 636 throw new RuntimeException (ex); 637 } 638 } 639 public boolean retainAll(Collection c) 640 { 641 try 642 { 643 lock.readLock().acquire(); 644 try 645 { 646 List state = getCurrentState(true); 647 return state.retainAll(c); 648 } 649 finally 650 { 651 lock.readLock().release(); 652 } 653 } 654 catch (Exception ex) 655 { 656 throw new RuntimeException (ex); 657 } 658 } 659 public Object set(int index, Object element) 660 { 661 try 662 { 663 lock.readLock().acquire(); 664 try 665 { 666 try 667 { 668 element = versionManager.makeVersioned(element); 669 } 670 catch (Exception ex) 671 { 672 throw new RuntimeException (ex); 673 } 674 List state = getCurrentState(true); 675 return state.set(index, element); 676 } 677 finally 678 { 679 lock.readLock().release(); 680 } 681 } 682 catch (Exception ex) 683 { 684 throw new RuntimeException (ex); 685 } 686 } 687 public int size() 688 { 689 try 690 { 691 lock.readLock().acquire(); 692 try 693 { 694 List state = getCurrentState(false); 695 return state.size(); 696 } 697 finally 698 { 699 lock.readLock().release(); 700 } 701 } 702 catch (Exception ex) 703 { 704 throw new RuntimeException (ex); 705 } 706 } 707 public List subList(int fromIndex, int toIndex) 708 { 709 try 710 { 711 lock.readLock().acquire(); 712 try 713 { 714 List state = getCurrentState(false); 715 return state.subList(fromIndex, toIndex); 716 } 717 finally 718 { 719 lock.readLock().release(); 720 } 721 } 722 catch (Exception ex) 723 { 724 throw new RuntimeException (ex); 725 } 726 } 727 public Object [] toArray() 728 { 729 try 730 { 731 lock.readLock().acquire(); 732 try 733 { 734 List state = getCurrentState(false); 735 return state.toArray(); 736 } 737 finally 738 { 739 lock.readLock().release(); 740 } 741 } 742 catch (Exception ex) 743 { 744 throw new RuntimeException (ex); 745 } 746 } 747 public Object [] toArray(Object [] a) 748 { 749 try 750 { 751 lock.readLock().acquire(); 752 try 753 { 754 List state = getCurrentState(false); 755 return state.toArray(a); 756 } 757 finally 758 { 759 lock.readLock().release(); 760 } 761 } 762 catch (Exception ex) 763 { 764 throw new RuntimeException (ex); 765 } 766 } 767 768 public void writeExternal(java.io.ObjectOutput out) 769 throws java.io.IOException 770 { 771 super.writeExternal(out); 772 out.writeLong(versionId); 773 out.writeObject(updates); 774 out.writeObject(classname); 775 } 776 777 public void readExternal(java.io.ObjectInput in) 778 throws java.io.IOException , ClassNotFoundException 779 { 780 super.readExternal(in); 781 versionId = in.readLong(); 782 this.updates = (ArrayList )in.readObject(); 783 this.classname = (String )in.readObject(); 784 try 785 { 786 InitialContext ctx = new InitialContext (); 787 this.tm = (TransactionManager )ctx.lookup("java:/TransactionManager"); 788 } 789 catch (Exception ex) 790 { 791 throw new RuntimeException (ex); 792 } 793 this.txState = new TransactionLocal(); 794 this.txVersion = new TransactionLocal(); 795 this.methodMap = listMethodMap; 796 } 797 798 } 799 | Popular Tags |