1 27 package ch.ethz.prose.engine; 28 29 import java.lang.reflect.InvocationTargetException ; 31 import java.lang.reflect.Method ; 32 import java.lang.reflect.Field ; 33 34 import java.util.Collection ; 35 import java.util.HashMap ; 36 import java.util.HashSet ; 37 import java.util.Iterator ; 38 import java.util.List ; 39 import java.util.Map ; 40 import java.util.Set ; 41 import java.util.Vector ; 42 43 44 import ch.ethz.jvmai.ExceptionJoinPoint; 45 import ch.ethz.jvmai.ExceptionCatchJoinPoint; 46 import ch.ethz.jvmai.FieldAccessJoinPoint; 47 import ch.ethz.jvmai.FieldModificationJoinPoint; 48 import ch.ethz.jvmai.JVMAspectInterface; 49 import ch.ethz.jvmai.JoinPoint; 50 import ch.ethz.jvmai.JoinPointHook; 51 import ch.ethz.jvmai.MethodEntryJoinPoint; 52 import ch.ethz.jvmai.MethodExitJoinPoint; 53 import ch.ethz.jvmai.MethodRedefineJoinPoint; 54 import ch.ethz.prose.Insertable; 55 import ch.ethz.prose.ProsePermission; 56 import ch.ethz.prose.crosscut.Crosscut; 57 import ch.ethz.inf.util.Logger; 58 59 60 77 public 78 class JoinPointManager extends JoinPointHook implements JoinPointQuery { 79 80 private static ProsePermission permission = new ProsePermission("registerListener"); 81 82 protected final Map req2listener; 84 85 protected final Map listener2req; 87 88 protected final Set classLoadListeners; 90 91 protected boolean isConnected; 93 94 protected boolean enableRevMap; 96 97 98 protected final HashSet enabledJoinPoints = new HashSet (); 99 100 private JVMAspectInterface aspectInterface = null; 101 private Vector loadedClasses; 102 private ClassLoadConsumer classLoaderNotifier; 103 107 public JoinPointManager(boolean isConnected, JVMAspectInterface ai, boolean enableRevMap) 108 { 109 req2listener = new HashMap (); 110 listener2req = new HashMap (); 111 classLoadListeners = new HashSet (); 112 this.isConnected = isConnected; 113 aspectInterface = ai; 114 this.enableRevMap = enableRevMap; 115 loadedClasses = new Vector (); 116 117 if (isConnected) 118 connectToJVMAI(); 119 } 120 121 public static class ClassLoadConsumer extends Thread 122 { 123 public boolean isRunning = true; 124 JoinPointManager jpm; 125 public ClassLoadConsumer(Vector classVector, JoinPointManager j) 126 { 127 jpm=j; 128 } 129 130 { 131 Class c = NoClassDefFoundError .class; 132 } 133 public void run() 134 { 135 while (isRunning) 136 { 137 if (!jpm.loadedClasses.isEmpty()) 138 { 139 Class c=(Class )jpm.loadedClasses.get(0); 140 try { c.getDeclaredMethods(); } 141 catch (NoClassDefFoundError e) 142 { 143 c= null; 144 } 145 146 synchronized(jpm.loadedClasses) 147 { 148 if (!jpm.loadedClasses.isEmpty()) 149 jpm.loadedClasses.remove(0); 150 151 152 } 153 if (c!=null)jpm.notifyClassLoadListeners(c); 154 } 155 else 156 { 157 synchronized(jpm.loadedClasses) 158 { 159 try {jpm.loadedClasses.wait();} catch (java.lang.InterruptedException e){}; 160 } 161 } 162 } 163 164 } 165 } 166 167 168 169 public void connectToJVMAI() 170 { 171 if (aspectInterface == null) 172 throw new RuntimeException ("Cannot have a NULL aspect interface"); 173 loadedClasses = new Vector (); 174 classLoaderNotifier = new ClassLoadConsumer(loadedClasses,this); 175 classLoaderNotifier.start(); 176 aspectInterface.setJoinPointHook(this); 177 } 178 179 public void disconnectFromJVMAI() 180 { 181 if (aspectInterface == null) 182 return; 183 if (isConnected) 184 { 185 aspectInterface.setJoinPointHook(null); 186 classLoaderNotifier.isRunning=false; 187 synchronized(loadedClasses) 188 { 189 loadedClasses.notifyAll(); 190 } 191 } 192 193 listener2req.clear(); 195 req2listener.clear(); 196 } 197 198 public JVMAspectInterface getAspectInterface() 199 { 200 return aspectInterface; 201 } 202 203 204 public boolean isReverseMappingEnabled() 205 { 206 return enableRevMap; 207 } 208 209 public void onFieldAccess(FieldAccessJoinPoint joinPoint) 210 { 211 List caughtExceptions = null; 212 ListenerList listeners = (ListenerList)joinPoint.getAopTag(); 213 for (int i = 0; i < listeners.nrOfListeners; i++) 214 { 215 try 216 { 217 listeners.listenerArray[i].joinPointReached(joinPoint); 218 } 219 catch (Exception e) 220 { 221 if (caughtExceptions == null) 222 caughtExceptions = new Vector (); 223 caughtExceptions.add(handleRuntimeException(e)); 224 } 225 } 226 227 handleExceptions(caughtExceptions,joinPoint); 228 } 229 230 public void onFieldModification(FieldModificationJoinPoint joinPoint) 231 { 232 List caughtExceptions = null; 233 ListenerList listeners = (ListenerList)joinPoint.getAopTag(); 234 for (int i = 0; i < listeners.nrOfListeners; i++) 235 { 236 try 237 { 238 listeners.listenerArray[i].joinPointReached(joinPoint); 239 } 240 catch (Exception e) 241 { 242 if (caughtExceptions == null) 243 caughtExceptions = new Vector (); 244 caughtExceptions.add(handleRuntimeException(e)); 245 } 246 } 247 248 handleExceptions(caughtExceptions,joinPoint); 249 250 } 251 252 public void onMethodEntry(MethodEntryJoinPoint joinPoint) 253 { 254 List caughtExceptions = null; 255 ListenerList listeners = (ListenerList)joinPoint.getAopTag(); 256 for (int i = 0; i < listeners.nrOfListeners; i++) 257 { 258 try 259 { 260 listeners.listenerArray[i].joinPointReached(joinPoint); 261 } 262 catch (Exception e) 263 { 264 if (caughtExceptions == null) 265 caughtExceptions = new Vector (); 266 caughtExceptions.add(handleRuntimeException(e)); 267 } 268 } 269 270 handleExceptions(caughtExceptions,joinPoint); 271 } 272 273 276 public void onMethodExit(MethodExitJoinPoint joinPoint) 277 { 278 List caughtExceptions = null; 279 ListenerList listeners = (ListenerList)joinPoint.getAopTag(); 280 for (int i = 0; i < listeners.nrOfListeners; i++) 281 { 282 try 283 { 284 listeners.listenerArray[i].joinPointReached(joinPoint); 285 } 286 catch (Exception e) 287 { 288 if (caughtExceptions == null) 289 caughtExceptions = new Vector (); 290 caughtExceptions.add(handleRuntimeException(e)); 291 } 292 } 293 294 handleExceptions(caughtExceptions,joinPoint); 295 } 296 297 303 public void onExceptionThrow(ExceptionJoinPoint joinPoint) 304 { 305 List caughtExceptions = null; 307 ListenerList listeners = (ListenerList)joinPoint.getAopTag(); 308 311 for (int i = 0; i < listeners.nrOfListeners; i++) 312 { 313 try 314 { 315 listeners.listenerArray[i].joinPointReached(joinPoint); 316 } 317 catch (Exception e) 318 { 319 if (caughtExceptions == null) 320 caughtExceptions = new Vector (); 321 caughtExceptions.add(handleRuntimeException(e)); 322 } 323 } 324 325 handleExceptions(caughtExceptions,joinPoint); 326 } 327 328 329 335 public void onExceptionCatch(ExceptionCatchJoinPoint joinPoint) 336 { 337 List caughtExceptions = null; 339 ListenerList listeners = (ListenerList)joinPoint.getAopTag(); 340 341 344 for (int i = 0; i < listeners.nrOfListeners; i++) { 345 try { 346 listeners.listenerArray[i].joinPointReached(joinPoint); 347 } 348 catch (Exception e) { 349 if (caughtExceptions == null) 350 caughtExceptions = new Vector (); 351 caughtExceptions.add(handleRuntimeException(e)); 352 } 353 } 354 handleExceptions(caughtExceptions,joinPoint); 355 } 356 357 358 public void onClassLoad(Class cls) 359 { 360 361 365 synchronized(loadedClasses) 366 { 367 loadedClasses.add(cls); 368 loadedClasses.notifyAll(); 369 } 370 } 371 372 373 374 383 public void registerListener(JoinPointListener list, JoinPointRequest req) 384 { 385 388 389 ListenerList listeners = null; 390 synchronized(req2listener) 391 { 392 listeners = (ListenerList)req2listener.get(req); 393 if (listeners == null) 394 { 395 listeners = new ListenerList(); 396 req2listener.put(req,listeners); 397 } 398 if (isConnected) 399 req.enableJoinPoint(listeners); 400 } 401 402 403 listeners.add(list); 408 if (enableRevMap) 409 { 410 Set joinpoints = null; 411 synchronized(listener2req) 412 { 413 joinpoints = (Set )listener2req.get(list); 414 if (joinpoints == null) 415 { 416 joinpoints = new HashSet (); 417 listener2req.put(list, joinpoints); 418 } 419 } 420 joinpoints.add(req); 421 } 422 } 423 424 432 public void unregisterListener(JoinPointListener listener) 433 { 434 436 try 437 { 438 if (listener instanceof Insertable) 439 ((Insertable)listener).withdrawalAction(true); 440 } 441 catch (Throwable e) 442 { 443 e.printStackTrace(); 447 } 448 449 Collection toRemoveKey = new Vector (); 450 synchronized(req2listener) 451 { 452 Iterator i = req2listener.keySet().iterator(); 453 while(i.hasNext()) 454 { 455 JoinPointRequest crtRequest = (JoinPointRequest)i.next(); 456 ListenerList crtListenerList = (ListenerList)req2listener.get(crtRequest); 457 458 crtListenerList.remove(listener); 459 if (crtListenerList.contains(listener)) 460 { 461 throw new Error ("Vector.removeAll works improperly; please reimplement"); 462 } 463 if (crtListenerList.isEmpty()) 464 { 465 if (isConnected) 466 crtRequest.disableJoinPoint(); 467 toRemoveKey.add(crtRequest); 468 } 469 } 470 Iterator oldKeys = toRemoveKey.iterator(); 471 while(oldKeys.hasNext()) 472 { 473 Object key = oldKeys.next(); 474 req2listener.remove(key); 475 } 476 477 } 478 479 if (enableRevMap) 480 listener2req.remove(listener); 481 482 483 try 484 { 485 if (listener instanceof Insertable) 486 ((Insertable)listener).withdrawalAction(true); 487 } 488 catch (Throwable e) 489 { 490 e.printStackTrace(); 494 } 495 } 496 497 498 499 502 public String toString() 503 { 504 String isConnectedString = "(isNotConnected)"; 505 if (isConnected) isConnectedString = "(isConnected)"; 506 StringBuffer result = new StringBuffer (); 507 result.append(" Join Point Manager (" + System.identityHashCode(this) + "State " + isConnectedString + ": \n"); 508 result.append(req2listener.toString()); 509 return result.toString(); 510 } 511 512 513 521 protected Exception handleRuntimeException(Exception e) 522 { 523 525 if (e!= null && e instanceof RuntimeException ) 526 { 527 throw (RuntimeException ) e; 528 } 529 530 if (e instanceof InvocationTargetException ) 532 { 533 InvocationTargetException invokedViaReflection = (InvocationTargetException )e; 534 if (invokedViaReflection.getTargetException() != null && 535 invokedViaReflection.getTargetException() instanceof RuntimeException ) 536 throw (RuntimeException )(invokedViaReflection.getTargetException()); 537 else 538 { 539 Exception realException = (Exception )invokedViaReflection.getTargetException(); 540 if (realException != null) 541 return realException; 542 } 543 } 544 545 return e; 546 } 547 548 549 559 protected void handleExceptions(List exceptionList,JoinPoint crtEvent) 560 { 561 562 if (exceptionList != null) 563 { 564 Iterator it = exceptionList.iterator(); 565 while (it.hasNext()) 566 { 567 Logger.error("Notification failed for " + crtEvent, (Exception ) it.next()); 568 } 569 } 570 } 571 572 580 protected void notifyClassLoadListeners(Class newClass) 581 { 582 synchronized(classLoadListeners) 583 { 584 Iterator i=classLoadListeners.iterator(); 585 while (i.hasNext()) 586 { 587 ClassLoadListener crtListener = (ClassLoadListener)i.next(); 588 crtListener.classLoaded(newClass); 589 } 590 } 591 } 592 593 599 public void registerListener(ClassLoadListener updateGuy) 600 { 601 classLoadListeners.add(updateGuy); 602 } 603 604 608 public void unregisterListener(ClassLoadListener updateGuy) 609 { 610 classLoadListeners.remove(updateGuy); 611 } 612 613 619 public void suspendListenerNotification(Thread t) 620 { 621 aspectInterface.suspendNotification(t); 623 } 624 625 628 public void resumeListenerNotification(Thread t) 629 { 630 aspectInterface.resumeNotification(t); 632 } 633 634 635 638 public List getLoadedClasses() 639 { 640 List result = aspectInterface.getLoadedClasses(); 641 return result; 642 } 643 644 645 648 public Set allJoinpoints() 649 { 650 return req2listener.keySet(); 651 } 652 653 654 657 public Set getCrosscuts(JoinPointRequest jpr) 658 { 659 Set result = new HashSet (); 660 if (jpr == null) return result; 661 662 ListenerList listeners = (ListenerList)req2listener.get(jpr); 663 if (listeners == null) 664 return result; 665 else 666 for (int i=0; i < listeners.nrOfListeners; i++) 667 result.add(listeners.listenerArray[i]); 668 669 return result; 670 } 671 672 673 public JoinPointRequest createJoinPointRequest(String kind,Object o) 674 { 675 if (MethodEntryJoinPoint.KIND.equals(kind)) 676 return new MethodEntryRequest((Method )o, this); 677 if (MethodExitJoinPoint.KIND.equals(kind)) 678 return new MethodExitRequest((Method )o,this); 679 if (MethodRedefineJoinPoint.KIND.equals(kind)) 680 return new MethodRedefineRequest((Method ) o, this); 681 if (FieldAccessJoinPoint.KIND.equals(kind)) 682 return new FieldAccessRequest((Field )o, this); 683 if (FieldModificationJoinPoint.KIND.equals(kind)) 684 return new FieldModificationRequest((Field )o, this); 685 if (ExceptionJoinPoint.KIND.equals(kind)) 686 return new ExceptionThrowRequest((Class )o,this); 687 if (ExceptionCatchJoinPoint.KIND.equals(kind)) 688 return new ExceptionCatchRequest((Class )o,this); 689 throw new RuntimeException ("unknown kind"); 690 } 691 692 695 public Set getJoinpoints(Crosscut cc) 696 { 697 if (cc == null) return (Set )null; 698 699 if (enableRevMap) 700 { 701 Set result = (Set )listener2req.get(cc); 702 if (result == null) 703 return new HashSet (); 704 else 705 return result; 706 } 707 else 708 { 709 return new HashSet (cc.createRequest()); 710 } 711 } 712 713 } 714 715 716 717 | Popular Tags |