1 18 19 package org.objectweb.jac.aspects.gui; 20 21 import java.util.Arrays ; 22 import java.util.HashMap ; 23 import java.util.HashSet ; 24 import java.util.Hashtable ; 25 import java.util.Iterator ; 26 import java.util.List ; 27 import java.util.Map ; 28 import java.util.Set ; 29 import java.util.WeakHashMap ; 30 import org.aopalliance.intercept.ConstructorInvocation; 31 import org.aopalliance.intercept.MethodInvocation; 32 import org.apache.log4j.Logger; 33 import org.objectweb.jac.core.AspectComponent; 34 import org.objectweb.jac.core.Interaction; 35 import org.objectweb.jac.core.Wrappee; 36 import org.objectweb.jac.core.Wrapper; 37 import org.objectweb.jac.core.Wrapping; 38 import org.objectweb.jac.core.rtti.CollectionItem; 39 import org.objectweb.jac.core.rtti.FieldItem; 40 import org.objectweb.jac.core.rtti.MemberItem; 41 import org.objectweb.jac.core.rtti.MethodItem; 42 import org.objectweb.jac.util.Strings; 43 44 63 64 public class ViewControlWrapper extends Wrapper { 65 static Logger logger = Logger.getLogger("gui.viewcontrol"); 66 static Logger loggerReg = Logger.getLogger("gui.register"); 67 68 WeakHashMap fieldClients = new WeakHashMap (); 70 WeakHashMap methodClients = new WeakHashMap (); 72 WeakHashMap collectionClients = new WeakHashMap (); 74 WeakHashMap objectClients = new WeakHashMap (); 76 77 static Hashtable allMethodClients = new Hashtable (); 81 86 89 public ViewControlWrapper(AspectComponent ac) { 90 super(ac); 91 } 92 93 102 public void registerField( 103 Wrappee wrappee, 104 FieldItem field, 105 FieldUpdate client, 106 Object param) { 107 Map clients = (Map ) fieldClients.get(field.getName()); 108 if (clients == null) { 109 clients = new HashMap (); 110 fieldClients.put(field.getName(), clients); 111 } 112 clients.put(client, param); 113 loggerReg.debug( 114 "registerField(" + Strings.hex(client) 115 + ") on " + Strings.hex(wrappee) + "." + field.getName()); 116 } 117 118 125 public void unregisterField( 126 Wrappee wrappee, 127 FieldItem field, 128 FieldUpdate client) { 129 Map clients = (Map ) fieldClients.get(field.getName()); 130 if (clients != null) { 131 loggerReg.debug("unregisterField(" 132 + Strings.hex(client) 133 + ") on " 134 + Strings.hex(wrappee) 135 + "." 136 + field.getName()); 137 clients.remove(client); 138 } 139 } 140 141 148 public void registerCollection( 149 Wrappee wrappee, 150 CollectionItem collection, 151 CollectionUpdate client, 152 Object param) { 153 Map clients = (Map ) collectionClients.get(collection.getName()); 154 if (clients == null) { 155 clients = new HashMap (); 156 collectionClients.put(collection.getName(), clients); 157 } 158 clients.put(client, param); 159 loggerReg.debug("registerCollection(" 160 + Strings.hex(client) 161 + ") on " 162 + Strings.hex(wrappee) 163 + "." 164 + collection.getName()); 165 } 166 167 174 175 public void unregisterCollection( 176 Wrappee wrappee, 177 CollectionItem collection, 178 CollectionUpdate client) { 179 Map clients = (Map ) collectionClients.get(collection.getName()); 180 if (clients != null) { 181 loggerReg.debug("unregisterCollection(" 182 + Strings.hex(client) 183 + ") on " 184 + Strings.hex(wrappee) 185 + "." 186 + collection.getName()); 187 clients.remove(client); 188 } 189 } 190 191 200 public void registerMethod( 201 Wrappee wrappee, 202 MethodItem method, 203 MethodUpdate client, 204 Object param) { 205 String key = method.getFullName(); 206 Map clients = (Map ) methodClients.get(key); 207 if (clients == null) { 208 clients = new HashMap (); 209 methodClients.put(key, clients); 210 } 211 clients.put(client, param); 212 213 clients = (Map ) allMethodClients.get(key); 214 if (clients == null) { 215 clients = new HashMap (); 216 allMethodClients.put(key, clients); 217 } 218 clients.put(client, param); 219 220 loggerReg.debug("registerMethod(" 221 + Strings.hex(client) 222 + ") on " 223 + Strings.hex(wrappee) 224 + "." 225 + key); 226 } 227 228 public void unregisterMethod( 229 Wrappee wrappee, 230 MethodItem method, 231 MethodUpdate client) { 232 String key = method.getFullName(); 233 Map clients = (Map ) methodClients.get(key); 234 if (clients != null) { 235 loggerReg.debug("unregisterMethod(" 236 + Strings.hex(client) 237 + ") on " 238 + Strings.hex(wrappee) 239 + "." 240 + method.getName()); 241 clients.remove(client); 242 } 243 clients = (Map ) allMethodClients.get(key); 244 if (clients != null) { 245 clients.remove(client); 246 } 247 } 248 249 256 public void registerObject( 257 Wrappee wrappee, 258 ObjectUpdate client, 259 Object param) { 260 loggerReg.debug( 261 "registerObject " + Strings.hex(client) + 262 " on " + Strings.hex(wrappee)); 263 objectClients.put(client, param); 264 } 265 266 271 public void unregisterObject(Wrappee wrappee, ObjectUpdate client) { 272 loggerReg.debug( 273 "unregisterObject(" + Strings.hex(client) 274 + ") on " + Strings.hex(wrappee)); 275 objectClients.remove(client); 276 } 277 278 283 public void unregister(Wrappee wrappee, Object client) { 284 loggerReg.debug("unregister(" + Strings.hex(client) 285 + ") on " + Strings.hex(wrappee)); 286 objectClients.remove(client); 287 Iterator i; 288 i = fieldClients.values().iterator(); 289 while (i.hasNext()) { 290 Map clients = (Map ) i.next(); 291 clients.remove(client); 292 } 293 294 i = collectionClients.values().iterator(); 295 while (i.hasNext()) { 296 Map clients = (Map ) i.next(); 297 clients.remove(client); 298 } 299 } 300 301 306 307 312 313 327 328 public Object updateView(Interaction interaction) { 329 330 Object ret = proceed(interaction); 331 332 logger.debug(this 333 + " checking view updating for method " 334 + Strings.hex(interaction.wrappee) 335 + "." 336 + interaction.method.getName()); 337 338 MethodItem method = (MethodItem) interaction.method; 339 340 347 348 FieldItem[] writtenFields = method.getWrittenFields(); 350 if (writtenFields != null) { 351 Class cl = interaction.getActualClass(); 352 for (int i = 0; i < writtenFields.length; i++) { 353 if (writtenFields[i].getGetter() == interaction.method) { 354 logger.warn( 355 "Skipping " + interaction.method 356 + " since it's the getter of " + writtenFields[i]); 357 continue; 358 } 359 logger.debug(method.getClassItem() + "." + method.getFullName() 360 + " writes " + writtenFields[i].getLongName()); 361 onFieldWrite(interaction.wrappee,cl,writtenFields[i]); 362 363 } 364 } 365 366 CollectionItem[] addedCollections = method.getAddedCollections(); 368 CollectionItem[] removedCollections = method.getRemovedCollections(); 369 CollectionItem[] modifiedCollections = method.getModifiedCollections(); 370 HashSet clientCollections = new HashSet (); 371 if (addedCollections != null) { 372 clientCollections.addAll(Arrays.asList(addedCollections)); 373 } 374 if (removedCollections != null) { 375 clientCollections.addAll(Arrays.asList(removedCollections)); 376 } 377 if (modifiedCollections != null) { 378 clientCollections.addAll(Arrays.asList(modifiedCollections)); 379 } 380 Iterator i = clientCollections.iterator(); 381 while (i.hasNext()) { 382 CollectionItem collection = (CollectionItem) i.next(); 383 HashMap clients = 384 (HashMap ) collectionClients.get(collection.getName()); 385 if (clients != null) { 386 Iterator it = ((Map ) clients.clone()).keySet().iterator(); 387 Object value = 388 collection.getThroughAccessor(interaction.wrappee); 389 while (it.hasNext()) { 390 CollectionUpdate client = (CollectionUpdate) it.next(); 391 logger.debug("collectionUpdated(" 392 + collection.getLongName() 393 + ") on " 394 + Strings.hex(client)); 395 try { 396 if (method.isAdder()) 397 client.onAdd( 398 interaction.wrappee, 399 collection, 400 value, 401 interaction.args[0], 402 clients.get(client)); 403 else if (method.isRemover()) 404 client.onRemove( 405 interaction.wrappee, 406 collection, 407 value, 408 interaction.args[0], 409 clients.get(client)); 410 else 411 client.onChange( 412 interaction.wrappee, 413 collection, 414 value, 415 clients.get(client)); 416 } catch (Exception e) { 417 logger.error( 418 "Caught exception in collectionUpdated(" 419 + collection.getLongName() 420 + ") on " 421 + Strings.hex(client), 422 e); 423 } 424 } 425 } 426 notifyDependentCollections( 427 collection, 428 interaction.wrappee, 429 method, 430 interaction.args); 431 } 432 433 if (method.isModifier()) { 435 logger.debug(method + " is a modifier"); 436 onObjectModified(interaction.wrappee); 437 } 438 439 return ret; 440 } 441 442 public void onObjectModified(Object substance) { 443 Iterator it = (new HashMap (objectClients)).keySet().iterator(); 444 while (it.hasNext()) { 445 ObjectUpdate client = (ObjectUpdate) it.next(); 446 logger.debug("objectUpdated(" 447 + Strings.hex(substance) 448 + ") on " 449 + Strings.hex(client)); 450 try { 451 client.objectUpdated( 452 substance, 453 objectClients.get(client)); 454 } catch (Exception e) { 455 logger.error( 456 "Caught exception in objectUpdated(" 457 + Strings.hex(substance) 458 + ") on " 459 + Strings.hex(client), 460 e); 461 } 462 } 463 } 464 465 470 public void onFieldWrite(Object substance, Class cl, FieldItem writtenField) { 471 logger.debug("onFieldWrite "+substance+"."+writtenField); 472 473 HashMap clients = 474 (HashMap ) fieldClients.get(writtenField.getName()); 475 if (clients != null) { 476 Iterator it = ((Map ) clients.clone()).entrySet().iterator(); 477 Object value = 478 writtenField.getThroughAccessor(substance); 479 while (it.hasNext()) { 480 Map.Entry entry = (Map.Entry ) it.next(); 481 FieldUpdate client = (FieldUpdate) entry.getKey(); 482 logger.debug(" fieldUpdated(" 483 + writtenField.getLongName() 484 + ") on " 485 + Strings.hex(client)); 486 try { 487 client.fieldUpdated( 488 substance, 489 writtenField, 490 value, 491 entry.getValue()); 492 } catch (Exception e) { 493 logger.error( 494 "Caught exception in fieldUpdated(" 495 + writtenField.getLongName() 496 + ") on " 497 + Strings.hex(client), e); 498 } 499 } 500 } 501 502 FieldItem[] dependentFields = 504 writtenField.getDependentFields(); 505 for (int j = 0; j < dependentFields.length; j++) { 506 if (!dependentFields[j] 507 .getClassItem() 508 .getActualClass() 509 .isAssignableFrom(cl)) { 510 logger.debug(" Skipping dependentField " 511 + dependentFields[j] 512 + " (class=" + cl.getName() + ")"); 513 continue; 514 } 515 516 logger.debug(" dependent field " + dependentFields[j].getLongName()); 517 List depSubstances = (List )dependentFields[j].getSubstances(substance); 518 Iterator sit = depSubstances.iterator(); 519 while(sit.hasNext()) { 520 Wrappee depSubstance = (Wrappee)sit.next(); 521 logger.debug(" iterating on " + depSubstance); 522 if (depSubstance!=null && depSubstance!=substance) { 523 Wrapping.invokeRoleMethod( 524 depSubstance, 525 ViewControlWrapper.class, 526 "onFieldWrite", 527 new Object [] {depSubstance,depSubstance.getClass(),dependentFields[j].getField()} 528 ); 529 Wrapping.invokeRoleMethod( 530 depSubstance, 531 ViewControlWrapper.class, 532 "onObjectModified", 533 new Object [] {depSubstance} 534 ); 535 } 536 } 537 clients = 538 (HashMap ) fieldClients.get( 539 dependentFields[j].getName()); 540 if (clients != null) { 541 Iterator it = 542 ((Map ) clients.clone()).entrySet().iterator(); 543 Object value = 544 dependentFields[j].getThroughAccessor( 545 substance); 546 while (it.hasNext()) { 547 Map.Entry entry = (Map.Entry ) it.next(); 548 FieldUpdate client = (FieldUpdate) entry.getKey(); 549 logger.debug(" fieldUpdated(" 550 + dependentFields[j].getLongName() 551 + ") on " + Strings.hex(client)); 552 try { 553 client.fieldUpdated( 554 substance, 555 dependentFields[j], 556 value, 557 entry.getValue()); 558 } catch (Exception e) { 559 logger.error( 560 "Caught exception in fieldUpdated(" 561 + dependentFields[j].getLongName() 562 + ") on " + Strings.hex(client), 563 e); 564 } 565 } 566 } 567 } 568 569 notifyDependentMethods( 570 methodClients, 571 writtenField, 572 substance, 573 cl, 574 new HashSet ()); 575 576 } 577 578 579 587 void notifyDependentMethods( 588 Map methodClients, 589 MemberItem member, 590 Object wrappee, 591 Class cl, 592 Set alreadyNotified) { 593 logger.debug("notifyDependentMethods for " + member + " / " + wrappee); 594 MethodItem[] dependentMethods = member.getDependentMethods(); 596 for (int i = 0; i < dependentMethods.length; i++) { 597 Class depClass = 599 dependentMethods[i].getClassItem().getActualClass(); 600 if ((cl != null && !depClass.isAssignableFrom(cl)) 601 || alreadyNotified.contains(dependentMethods[i])) { 602 logger.debug(" skipping " + dependentMethods[i].getLongName()); 603 continue; 604 } 605 logger.debug("dependent method " 606 + dependentMethods[i].getClassItem() 607 + "." 608 + dependentMethods[i].getFullName()); 609 alreadyNotified.add(dependentMethods[i]); 610 HashMap clients = 611 (HashMap ) methodClients.get(dependentMethods[i].getFullName()); 612 if (clients != null) { 613 Iterator it = ((Map ) clients.clone()).entrySet().iterator(); 614 while (it.hasNext()) { 615 Map.Entry entry = (Map.Entry ) it.next(); 616 MethodUpdate client = (MethodUpdate) entry.getKey(); 617 logger.debug("MethodUpdated(" 618 + dependentMethods[i].getLongName() 619 + ") on " 620 + Strings.hex(client)); 621 try { 622 client.methodUpdated( 623 wrappee, 624 dependentMethods[i], 625 entry.getValue()); 626 } catch (Exception e) { 627 logger.error( 628 "Caught exception in methodUpdated(" 629 + dependentMethods[i].getLongName() 630 + ") on " + Strings.hex(client), 631 e); 632 } 633 } 634 } 635 if (member != dependentMethods[i]) 636 notifyDependentMethods( 637 allMethodClients, 638 dependentMethods[i], 639 wrappee, 640 null, 641 alreadyNotified); 642 } 643 } 644 645 void notifyDependentCollections( 646 CollectionItem collection, 647 Wrappee wrappee, 648 MethodItem method, 649 Object [] args) { 650 FieldItem[] dependentFields = collection.getDependentFields(); 652 for (int j = 0; j < dependentFields.length; j++) { 653 logger.debug("dependent field " 654 + dependentFields[j].getName() 655 + " for " 656 + collection.getName()); 657 HashMap clients = 658 (HashMap ) collectionClients.get(dependentFields[j].getName()); 659 if (clients != null) { 660 Iterator it2 = ((Map ) clients.clone()).entrySet().iterator(); 661 Object value = dependentFields[j].getThroughAccessor(wrappee); 662 while (it2.hasNext()) { 663 Map.Entry entry = (Map.Entry ) it2.next(); 664 CollectionUpdate client = (CollectionUpdate) entry.getKey(); 665 logger.debug( 666 "collectionUpdated(" + dependentFields[j].getLongName() 667 + ") on " + Strings.hex(client)); 668 try { 669 client.onChange( 670 wrappee, 671 (CollectionItem) dependentFields[j], 672 value, 673 entry.getValue()); 674 } catch (Exception e) { 675 logger.error( 676 "Caught exception in collectionUpdated(" 677 + dependentFields[j].getLongName() 678 + ") on " + Strings.hex(client), 679 e); 680 } 681 } 682 } 683 } 684 } 685 686 public Object invoke(MethodInvocation invocation) throws Throwable { 687 return updateView((Interaction) invocation); 688 } 689 690 public Object construct(ConstructorInvocation invocation) 691 throws Throwable { 692 throw new Exception ("This wrapper does not support constructor wrapping"); 693 } 694 695 } 696 | Popular Tags |