KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > ch > ethz > prose > engine > JoinPointManager


1 //
2
// This file is part of the prose package.
3
//
4
// The contents of this file are subject to the Mozilla Public License
5
// Version 1.1 (the "License"); you may not use this file except in
6
// compliance with the License. You may obtain a copy of the License at
7
// http://www.mozilla.org/MPL/
8
//
9
// Software distributed under the License is distributed on an "AS IS" basis,
10
// WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
11
// for the specific language governing rights and limitations under the
12
// License.
13
//
14
// The Original Code is prose.
15
//
16
// The Initial Developer of the Original Code is Andrei Popovici. Portions
17
// created by Andrei Popovici are Copyright (C) 2002 Andrei Popovici.
18
// All Rights Reserved.
19
//
20
// Contributor(s):
21
// $Id: JoinPointManager.java,v 1.3 2004/05/12 09:41:55 anicoara Exp $
22
// =====================================================================
23
//
24
// (history at end)
25
//
26

27 package ch.ethz.prose.engine;
28
29 // used packages
30
import java.lang.reflect.InvocationTargetException JavaDoc;
31 import java.lang.reflect.Method JavaDoc;
32 import java.lang.reflect.Field JavaDoc;
33
34 import java.util.Collection JavaDoc;
35 import java.util.HashMap JavaDoc;
36 import java.util.HashSet JavaDoc;
37 import java.util.Iterator JavaDoc;
38 import java.util.List JavaDoc;
39 import java.util.Map JavaDoc;
40 import java.util.Set JavaDoc;
41 import java.util.Vector JavaDoc;
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 /**
61  * Class JoinPointManagerImpl defines implements two of the basic methods
62  * <code>JoinPointManager</code>. Subclasses of <code>AbstractJoinPointManager</code>
63  * should define only the link between registering event requests and the proper notification.
64  * They should use the <code>notifyListeners</code> method in order to notify the listeners
65  * of an event that this event occured, and invoke <code>handleExceptions</code> to handle
66  * notification exceptions. By providing an implementation of <code>handleExceptions</code>
67  * with a different <code>handleExceptions</code> method, subclasses may change the policy
68  * for exception handling.
69  * <p>
70  * All implementations of <code>AbstractJoinPointManager</code> should also define the
71  * abstract methods <code>suspendListenerNotification</code> and <code>resumeListenerNotification</code>
72  *
73  * @version $Revision: 1.3 $
74  * @author Andrei Popovici
75  * @author Angela Nicoara
76  */

77 public
78 class JoinPointManager extends JoinPointHook implements JoinPointQuery {
79
80   private static ProsePermission permission = new ProsePermission("registerListener");
81
82   // mapping JoinPointRequest -> List(JoinPointListener)
83
protected final Map JavaDoc req2listener;
84
85   // mapping JoinPointListener -> List(JoinPointRequest)
86
protected final Map JavaDoc listener2req;
87
88   // List(ClassLoadListeners)
89
protected final Set JavaDoc classLoadListeners;
90
91   // indicates if this JoinPointManager is connected to the Hook or if it is the test JPM
92
protected boolean isConnected;
93
94   // indicates if the table listener2req is maintained for Reverse Mapping.
95
protected boolean enableRevMap;
96
97
98   protected final HashSet JavaDoc enabledJoinPoints = new HashSet JavaDoc();
99
100   private JVMAspectInterface aspectInterface = null;
101   private Vector JavaDoc loadedClasses;
102   private ClassLoadConsumer classLoaderNotifier;
103   /**
104    * Create an <code>JoinPointManagerImpl</code> with no registered listeners
105    * or events.
106    */

107   public JoinPointManager(boolean isConnected, JVMAspectInterface ai, boolean enableRevMap)
108     {
109       req2listener = new HashMap JavaDoc();
110       listener2req = new HashMap JavaDoc();
111       classLoadListeners = new HashSet JavaDoc();
112       this.isConnected = isConnected;
113       aspectInterface = ai;
114       this.enableRevMap = enableRevMap;
115       loadedClasses = new Vector JavaDoc();
116
117       if (isConnected)
118         connectToJVMAI();
119     }
120
121   public static class ClassLoadConsumer extends Thread JavaDoc
122   {
123     public boolean isRunning = true;
124     JoinPointManager jpm;
125     public ClassLoadConsumer(Vector JavaDoc classVector, JoinPointManager j)
126       {
127     jpm=j;
128       }
129
130       {
131     Class JavaDoc c = NoClassDefFoundError JavaDoc.class;
132       }
133     public void run()
134       {
135     while (isRunning)
136       {
137         if (!jpm.loadedClasses.isEmpty())
138           {
139         Class JavaDoc c=(Class JavaDoc)jpm.loadedClasses.get(0);
140         try { c.getDeclaredMethods(); }
141         catch (NoClassDefFoundError JavaDoc 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 JavaDoc e){};
160           }
161           }
162       }
163
164       }
165   }
166
167
168
169 public void connectToJVMAI()
170     {
171       if (aspectInterface == null)
172           throw new RuntimeException JavaDoc("Cannot have a NULL aspect interface");
173       loadedClasses = new Vector JavaDoc();
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       // this should be part of a teardown procedure
194
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 JavaDoc 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 JavaDoc e)
220             {
221             if (caughtExceptions == null)
222                 caughtExceptions = new Vector JavaDoc();
223             caughtExceptions.add(handleRuntimeException(e));
224             }
225         }
226
227     handleExceptions(caughtExceptions,joinPoint);
228     }
229
230   public void onFieldModification(FieldModificationJoinPoint joinPoint)
231     {
232     List JavaDoc 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 JavaDoc e)
241             {
242             if (caughtExceptions == null)
243                 caughtExceptions = new Vector JavaDoc();
244             caughtExceptions.add(handleRuntimeException(e));
245             }
246         }
247
248     handleExceptions(caughtExceptions,joinPoint);
249
250     }
251
252   public void onMethodEntry(MethodEntryJoinPoint joinPoint)
253     {
254     List JavaDoc 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 JavaDoc e)
263             {
264             if (caughtExceptions == null)
265                 caughtExceptions = new Vector JavaDoc();
266             caughtExceptions.add(handleRuntimeException(e));
267             }
268         }
269
270     handleExceptions(caughtExceptions,joinPoint);
271     }
272
273     /**
274      *
275      */

276     public void onMethodExit(MethodExitJoinPoint joinPoint)
277     {
278     List JavaDoc 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 JavaDoc e)
287             {
288             if (caughtExceptions == null)
289                 caughtExceptions = new Vector JavaDoc();
290             caughtExceptions.add(handleRuntimeException(e));
291             }
292         }
293
294     handleExceptions(caughtExceptions,joinPoint);
295     }
296
297     /**
298      * Hook method to be called whenever an Exception event is reported from
299      * the jvmai-interface.
300      * For every listener registered on an exception throw event it invoces the
301      * corresponding <code>joinPointReached</code>-method.
302      */

303     public void onExceptionThrow(ExceptionJoinPoint joinPoint)
304     {
305     //System.out.println("JoinPointManager -> onExceptionThrow"); //angy test
306
List JavaDoc caughtExceptions = null;
307     ListenerList listeners = (ListenerList)joinPoint.getAopTag();
308     //System.out.println("JoinPointManager onExceptionThrow -> listeners.nrOfListeners = " + listeners.nrOfListeners); //angy test
309
//System.out.println("JoinPointManager onExceptionThrow -> listeners.toString = " + listeners.toString()); //angy test
310

311     for (int i = 0; i < listeners.nrOfListeners; i++)
312         {
313         try
314             {
315             listeners.listenerArray[i].joinPointReached(joinPoint);
316             }
317         catch (Exception JavaDoc e)
318             {
319             if (caughtExceptions == null)
320                 caughtExceptions = new Vector JavaDoc();
321             caughtExceptions.add(handleRuntimeException(e));
322             }
323         }
324
325     handleExceptions(caughtExceptions,joinPoint);
326     }
327
328
329     /**
330       * Hook method to be called whenever an Exception Catch event is reported from
331       * the jvmai-interface.
332       * For every listener registered on an exception catch event it invoces the
333       * corresponding <code>joinPointReached</code>-method.
334       */

335      public void onExceptionCatch(ExceptionCatchJoinPoint joinPoint)
336      {
337          //System.out.println("JoinPointManager -> onExceptionCatch"); //angy test
338
List JavaDoc caughtExceptions = null;
339          ListenerList listeners = (ListenerList)joinPoint.getAopTag();
340
341          //System.out.println("JoinPointManager onExceptionCatch -> listeners.nrOfListeners = " + listeners.nrOfListeners); //angy test
342
//System.out.println("JoinPointManager onExceptionCatch -> listeners.toString = " + listeners.toString()); //angy test
343

344          for (int i = 0; i < listeners.nrOfListeners; i++) {
345              try {
346                  listeners.listenerArray[i].joinPointReached(joinPoint);
347              }
348              catch (Exception JavaDoc e) {
349                  if (caughtExceptions == null)
350                      caughtExceptions = new Vector JavaDoc();
351                  caughtExceptions.add(handleRuntimeException(e));
352              }
353          }
354          handleExceptions(caughtExceptions,joinPoint);
355      }
356
357
358     public void onClassLoad(Class JavaDoc cls)
359     {
360
361       // BIG FIXME: this is because of an error with versions prior to
362
// 1.4!. In addition, at this time (for whatever reason)
363
// I cannot check whether cls is assignable from ..
364

365       synchronized(loadedClasses)
366     {
367       loadedClasses.add(cls);
368       loadedClasses.notifyAll();
369     }
370     }
371
372
373
374   /** Register the listener <code>lsnr</code> for events
375    * requested by <code>jpr</code>. If the request <code>jpr</code>
376    * is the first of its kind, the join corresponding join point
377    * will be enabled. More precise, if no other request with an equal
378    * singature has been previously registered, the join point
379    * will be enabled.
380    *
381    * This method checks for the permission ProsePermission "registerListener" to be present.
382    */

383   public void registerListener(JoinPointListener list, JoinPointRequest req)
384     {
385     // security check
386
//AccessController.checkPermission(permission); // FIXME
387

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       // note the trick: add adds the element at the end of the list.
404
// therefore, during notification, it will be notified last.
405
// therefore, the registration-notification ordering constraint
406
// holds..yeyeyeye
407
listeners.add(list);
408       if (enableRevMap)
409     {
410       Set JavaDoc joinpoints = null;
411       synchronized(listener2req)
412         {
413           joinpoints = (Set JavaDoc)listener2req.get(list);
414           if (joinpoints == null)
415         {
416           joinpoints = new HashSet JavaDoc();
417           listener2req.put(list, joinpoints);
418         }
419         }
420       joinpoints.add(req);
421     }
422     }
423
424   /** Deregister listener <code>lsnr</code> from this JoinPointManager.
425    * As a result of this action, the listener <code>lsnr</code> will
426    * cease being notified of any kind of events. Upon this action,
427    * any 'lonely event' -- one for whom no listener exists will be
428    * disabled. More precisely, if <code>lsnr</code> was the last listener
429    * litening on envents with the signature <em>S</em>,
430    * <em>S.disableJoinPoint</em> will be performed.
431    */

432   public void unregisterListener(JoinPointListener listener)
433       {
434     //iterate through our vectors...
435

436       try
437           {
438           if (listener instanceof Insertable)
439               ((Insertable)listener).withdrawalAction(true);
440           }
441       catch (Throwable JavaDoc e)
442           {
443           // this must be ignored. A malicious crosscut may
444
// want to remain forever inserted. In fact,
445
// the unregistration should be robust.
446
e.printStackTrace();
447           }
448
449     Collection JavaDoc toRemoveKey = new Vector JavaDoc();
450     synchronized(req2listener)
451       {
452         Iterator JavaDoc 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 JavaDoc("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 JavaDoc oldKeys = toRemoveKey.iterator();
471         while(oldKeys.hasNext())
472           {
473         Object JavaDoc 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 JavaDoc e)
489         {
490         // this must be ignored. A malicious crosscut may
491
// want to remain forever inserted. In fact,
492
// the unregistration should be robust.
493
e.printStackTrace();
494           }
495       }
496
497
498
499   /** Return the state of the join-point manager. The registeresd listeners and
500    * the associated requests will be returned.
501    */

502   public String JavaDoc toString()
503       {
504         String JavaDoc isConnectedString = "(isNotConnected)";
505         if (isConnected) isConnectedString = "(isConnected)";
506     StringBuffer JavaDoc result = new StringBuffer JavaDoc();
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     /** This method should be called if a notification fails. If the notification
514      * fails with a Runtime exception, the default implementation of this
515      * method throws the corresponding run-time exception. Otherwise it
516      * returns the exception that caused the failure.
517      *
518      * @param e the exception to be handled
519      * @return a non-runtime exception thrown by the advice
520      */

521     protected Exception JavaDoc handleRuntimeException(Exception JavaDoc e)
522     {
523     // the obvious case
524

525         if (e!= null && e instanceof RuntimeException JavaDoc)
526         {
527         throw (RuntimeException JavaDoc) e;
528         }
529
530     // invoked via reflection
531
if (e instanceof InvocationTargetException JavaDoc)
532         {
533         InvocationTargetException JavaDoc invokedViaReflection = (InvocationTargetException JavaDoc)e;
534         if (invokedViaReflection.getTargetException() != null &&
535             invokedViaReflection.getTargetException() instanceof RuntimeException JavaDoc)
536             throw (RuntimeException JavaDoc)(invokedViaReflection.getTargetException());
537         else
538             {
539             Exception JavaDoc realException = (Exception JavaDoc)invokedViaReflection.getTargetException();
540             if (realException != null)
541                 return realException;
542             }
543         }
544
545     return e;
546     }
547
548
549 /** This method should be called if the notification fails for some of the
550  * listeners. Subclasses are encouraged to override this method in order to
551  * implement their own exception handling policy, e.g., removing the <em>bad</em>
552  * listeners from this <code>JoinPointManager</code>.
553  *
554  * @param exceptionList a list of <code>Exception</code> objects, thrown during the notification
555  * of listeners of <code>crtEvent</code>.
556  * @param crtEvent a <code>JoinPointEvent</code> whose listeners were not properly
557  * notified.
558  */

559   protected void handleExceptions(List JavaDoc exceptionList,JoinPoint crtEvent)
560       {
561
562     if (exceptionList != null)
563       {
564           Iterator JavaDoc it = exceptionList.iterator();
565           while (it.hasNext())
566           {
567               Logger.error("Notification failed for " + crtEvent, (Exception JavaDoc) it.next());
568           }
569       }
570       }
571
572   /** Notify all registered class load listeners that the class
573    * <code>newClass</code> has just been loaded and prepared.
574    * This method should be invoked by implementations of this abstract
575    * immediately after a class of intereest (containing potential join-points)
576    * is loaded and prepared.
577    *
578    * @param newClass the class that is new to the system
579    */

580   protected void notifyClassLoadListeners(Class JavaDoc newClass)
581     {
582       synchronized(classLoadListeners)
583     {
584       Iterator JavaDoc i=classLoadListeners.iterator();
585       while (i.hasNext())
586         {
587           ClassLoadListener crtListener = (ClassLoadListener)i.next();
588           crtListener.classLoaded(newClass);
589         }
590     }
591     }
592
593   /** Register a class load listener event. All class load listeners
594    * will be notified every time a class of interest (containing potential join-points)
595    * has been loaded.
596    *
597    * @param updateGuy the listener of class load events
598    */

599   public void registerListener(ClassLoadListener updateGuy)
600     {
601       classLoadListeners.add(updateGuy);
602     }
603
604   /** Unregister a class load listener.
605    *
606    * @param updateGuy the listener to be removed from the listeners list.
607    */

608   public void unregisterListener(ClassLoadListener updateGuy)
609     {
610       classLoadListeners.remove(updateGuy);
611     }
612
613   /** Suspend notification of all listeners interested in join-points
614    * that occur in the specified thread. This method is idempotent.
615    * Successive calls to this method with the same argument have
616    * the same effect as calling it only once.
617    *
618    */

619   public void suspendListenerNotification(Thread JavaDoc t)
620     {
621 // if (isConnected && aspectInterface != null)
622
aspectInterface.suspendNotification(t);
623     }
624
625   /** Resume the notification of listerners interested in join-points
626    * that occur in the specified thread.
627    */

628   public void resumeListenerNotification(Thread JavaDoc t)
629     {
630 // if (isConnected && aspectInterface != null)
631
aspectInterface.resumeNotification(t);
632     }
633
634
635     /**
636      * Returns all currently loaded classes in the virtual machine.
637      */

638   public List JavaDoc getLoadedClasses()
639     {
640       List JavaDoc result = aspectInterface.getLoadedClasses();
641       return result;
642     }
643
644
645   /**
646    *
647    */

648   public Set JavaDoc allJoinpoints()
649     {
650       return req2listener.keySet();
651     }
652
653
654   /**
655    *
656    */

657   public Set JavaDoc getCrosscuts(JoinPointRequest jpr)
658     {
659       Set JavaDoc result = new HashSet JavaDoc();
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 JavaDoc kind,Object JavaDoc o)
674     {
675       if (MethodEntryJoinPoint.KIND.equals(kind))
676         return new MethodEntryRequest((Method JavaDoc)o, this);
677       if (MethodExitJoinPoint.KIND.equals(kind))
678         return new MethodExitRequest((Method JavaDoc)o,this);
679       if (MethodRedefineJoinPoint.KIND.equals(kind))
680         return new MethodRedefineRequest((Method JavaDoc) o, this);
681       if (FieldAccessJoinPoint.KIND.equals(kind))
682         return new FieldAccessRequest((Field JavaDoc)o, this);
683       if (FieldModificationJoinPoint.KIND.equals(kind))
684         return new FieldModificationRequest((Field JavaDoc)o, this);
685       if (ExceptionJoinPoint.KIND.equals(kind))
686         return new ExceptionThrowRequest((Class JavaDoc)o,this);
687       if (ExceptionCatchJoinPoint.KIND.equals(kind))
688         return new ExceptionCatchRequest((Class JavaDoc)o,this);
689       throw new RuntimeException JavaDoc("unknown kind");
690     }
691
692   /**
693    *
694    */

695   public Set JavaDoc getJoinpoints(Crosscut cc)
696     {
697       if (cc == null) return (Set JavaDoc)null;
698
699       if (enableRevMap)
700         {
701           Set JavaDoc result = (Set JavaDoc)listener2req.get(cc);
702           if (result == null)
703             return new HashSet JavaDoc();
704           else
705             return result;
706     }
707       else
708         {
709           return new HashSet JavaDoc(cc.createRequest());
710     }
711     }
712
713 }
714
715
716
717 //======================================================================
718
//
719
// $Log: JoinPointManager.java,v $
720
// Revision 1.3 2004/05/12 09:41:55 anicoara
721
// Remove the README.RVM file
722
//
723
// Revision 1.2 2003/07/10 15:25:04 apopovic
724
// Bug fix when classes were loaded too early (and getDelclaredMethod) threw
725
// an error
726
//
727
// Revision 1.1.1.1 2003/07/02 15:30:51 apopovic
728
// Imported from ETH Zurich
729
//
730
// Revision 1.5 2003/07/02 12:42:54 anicoara
731
// Added CatchJoinPoint Functionality (Requests, Join-Points, Filters, CatchCuts, Tests)
732
//
733
// Revision 1.4 2003/06/26 09:31:03 popovici
734
// Bugfix: the asyncrhroous loadClassNotification used to load a class while notifying; result: deadlock; fixed
735
//
736
// Revision 1.3 2003/06/25 09:04:11 popovici
737
// Bug fix in synchronizing class producers and consumers; FIXME comment added to AbstractCrosscut
738
//
739
// Revision 1.2 2003/06/23 14:01:21 popovici
740
// Asynchronous aspect insertion on dynamically loaded classes
741
//
742
// Revision 1.1 2003/05/05 13:58:24 popovici
743
// renaming from runes to prose
744
//
745
// Revision 1.21 2003/04/26 18:51:37 popovici
746
// 1 Bug fix which lead to a refactoring step:
747
// 1. the bug: 'JoinPointRequests' used to write to a static list, which survived a startup/teardown;
748
// now this list belongs to the JoinPointManager;
749
// 2. the refactoring: the JoinPointManager now creates (and shares state) with join-points.
750
//
751
// Revision 1.20 2003/04/17 15:15:15 popovici
752
// Extension->Aspect renaming
753
//
754
// Revision 1.19 2003/04/17 12:49:27 popovici
755
// Refactoring of the crosscut package
756
// ExceptionCut renamed to ThrowCut
757
// McutSignature is now SignaturePattern
758
//
759
// Revision 1.18 2003/04/17 08:47:58 popovici
760
// Important functionality additions
761
// - Cflow specializers
762
// - Restructuring of the MethodCut, SetCut, ThrowCut, and GetCut (they are much smaller)
763
// - Transactional capabilities
764
// - Total refactoring of Specializer evaluation, which permits fine-grained distinction
765
// between static and dynamic specializers.
766
// - Functionality pulled up in abstract classes
767
// - Uniformization of advice methods patterns and names
768
//
769
// Revision 1.17 2003/03/04 18:36:05 popovici
770
// Organization of imprts
771
//
772
// Revision 1.16 2003/03/04 11:27:31 popovici
773
// Important refactorization step (march):
774
// - removal of 'JoinPointEvents'; JoinPoints now have the same function as events
775
// - reimplementation of the JVMAIDebuggerAspectInterface (better performance, coding conventions, removal of ProseVM
776
// structures
777
//
778
// Revision 1.15 2003/02/11 14:23:26 popovici
779
// Bug fix: 'insertion' action was performed in the JoinPointManger. This lead
780
//
781
// Revision 1.14 2002/11/26 17:15:17 pschoch
782
// RootComponent now added (replaces RootComponent now added (replaces old ProseSystem)
783
// ProseSystem now owns and starts the Aspect interface.
784
// ProseSystem now containes a 'test' AspectManager
785
// AspectManager now owns the JoinPointManager.
786
// ExtensionManger can be 'connected' to the JVM, or disconnected. The
787
// JoinPointManager of a connected Ext.Mgr enables joinpoints; the
788
// JoinPointManger of a disconnected Ext.Mgr never enables join-points
789
// Documentation updated accordingly.
790
//
791
// Revision 1.13 2002/10/31 18:26:54 pschoch
792
// Capability of crosscutting Exceptions added to prose.
793
//
794
// Revision 1.12 2002/10/25 07:42:38 popovici
795
// Undo Chnages Phillippe
796
//
797
// Revision 1.10 2002/10/17 17:05:54 pschoch
798
// Added throw capabability to JVMAI
799
//
800
// Revision 1.9 2002/10/17 12:23:44 pschoch
801
// Added throw capabability to JVMAI
802
//
803
// Revision 1.8 2002/09/21 14:04:34 popovici
804
// Bug 0000010 fixed. Added 'teardown' procedure
805
// in the JVMAI, Jikes & JDK prose implementation
806
//
807
// Revision 1.7 2002/05/28 15:50:10 popovici
808
// printStackTrace eliminated from the JoinPointManger. Used to give the impresion that
809
// run-time exceptions are true errors
810
//
811
// Revision 1.6 2002/03/28 13:48:49 popovici
812
// Mozilla-ified
813
//
814
// Revision 1.5 2002/03/27 13:56:38 popovici
815
// Legal and realease changes:
816
// added LEGAL & licenses
817
// added profiles/release
818
// added programs/* scripts for installation
819
// modified project/* files for installation
820
//
821
// Revision 1.4 2002/03/11 11:01:32 smarkwal
822
// JVMInfoInterface and JoinPointHook changed to abstract classes
823
//
824
// Revision 1.3 2002/02/21 12:51:43 popovici
825
// Dispatching efficiency issues:
826
// - Hook methods in the join point manager are now inlined (they
827
// do not use any more 'notifyListeners'
828
// - Aop tags are now of type 'ListenerList' which allows efficient
829
// array iteration
830
// - 'setWatch' methods modifiy to accomodate ListenerLists on EventRequests
831
//
832
// Revision 1.2 2002/02/05 10:01:02 smarkwal
833
// JVMDI-specific code replaced by JVMAI. Prose-implementation classes and reflection package removed.
834
//
835
// Revision 1.2 2001/12/07 17:13:02 popovici
836
// attach to local VM did not start jpm. Fixed
837
//
838
// Revision 1.1.1.1 2001/11/29 18:13:13 popovici
839
// Sources from runes
840
//
841
// Revision 1.1.2.11 2001/11/21 11:56:22 popovici
842
//
843
// -The sun.tools.agent and ch.ethz.inf.util.JVMDIUtil functionality
844
// replaced with the iks.jvmdi package. References to this old
845
// functionality replaced throughout the code.
846
// -Partial reimplementation of the ch.ethz.inf.iks.runes classes,
847
// part of their functionality moved to the ch.ethz.prose.reflect
848
// abstract classes. New classes and functionality added to the
849
// ch.ethz.prose.reflect package, partially to reflect the
850
// more stable features taken from the iks.runes packages, partially
851
// to reflect the structure of the VM (constant pool, etc). Functionality in
852
// ch.ethz.prose.crosscut and the junit classes adapted to use the
853
// new form of the ch.ethz.prose.reflect package
854
//
855
// Revision 1.1.2.10 2001/06/05 13:50:35 popovici
856
// method 'post' modified to consider class load events as well.
857
//
858
// Revision 1.1.2.9 2001/03/28 09:20:30 popovici
859
// Methods 'suspendListenerNotification' and 'resumeListenerNotification'
860
// implemented (body used to be commented because of bug in Agent.addSystemThread)
861
//
862
// Revision 1.1.2.8 2001/03/19 10:24:17 popovici
863
// Methods 'suspendListenerNotification' and 'resumeListenerNotification'
864
// implemented (empty body). FIXME: bug in 'Agent.addSystemThread'
865
//
866
// Revision 1.1.2.7 2000/12/01 13:52:47 groos
867
// Upon notification of an unknown event, a java.lang.InternalError is thrown.
868
//
869
// Revision 1.1.2.6 2000/11/21 14:32:10 groos
870
// added support for FieldAccessRequests and FieldModificationRequests:
871
// implements EventTypes,
872
// dispatches Event.FIELD_ACCESS and Event.FIELD_MODIFICATION,
873
// provides createFieldAccessRequest(Field f) and
874
// createFieldModificationRequest(Field f)
875
//
876
// Revision 1.1.2.5 2000/10/30 15:56:42 popovici
877
// Methods 'notifyListeners' 'registerListener' 'unregisterListener' 'hanldeExceptions' moved to AbstractJoinPointManger. Class now extends
878
// EventDispatcher for visibility reasons.
879
//
880
// Revision 1.1.2.4 2000/10/25 09:04:51 popovici
881
// Exception Handler added. Method 'toString' added.
882
//
883
// Revision 1.1.2.3 2000/10/24 17:56:52 popovici
884
// Proprietary event dispatcher specified. Additional method 'attachToLocalVM'
885
// boots the agent and does the setup.
886
//
887
// Revision 1.1.2.2 2000/10/23 19:05:09 popovici
888
// import declaration changed according to refactorization DEVEL_WS0001; some
889
// documentation added.
890
//
891
// Revision 1.1.2.1 2000/10/16 13:04:39 popovici
892
// Initial revision
893
//
894
Popular Tags