You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

AbstractTrace.java 5.6KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185
  1. /*
  2. Copyright (c) Xerox Corporation 1998-2002. All rights reserved.
  3. Use and copying of this software and preparation of derivative works based
  4. upon this software are permitted. Any distribution of this software or
  5. derivative works must comply with all applicable United States export control
  6. laws.
  7. This software is made available AS IS, and Xerox Corporation makes no warranty
  8. about the software, its performance or its conformity to any specification.
  9. |<--- this code is formatted to fit into 80 columns --->|
  10. |<--- this code is formatted to fit into 80 columns --->|
  11. |<--- this code is formatted to fit into 80 columns --->|
  12. */
  13. package tracing.lib;
  14. import java.io.PrintStream;
  15. import org.aspectj.lang.JoinPoint;
  16. /**
  17. * This class provides support for printing trace messages into a stream.
  18. * The trace messages consist of the class name, method name (if method)
  19. * and the list of parameter types.<P>
  20. * The class is thread-safe. Different threads may use different output streams
  21. * by simply calling the method initStream(myStream).<P>
  22. * This class should be extended.
  23. * It defines 3 abstract crosscuts for injecting the tracing functionality
  24. * into any constructors and methods of any application classes.<P>
  25. *
  26. * One example of using this class might be
  27. * <PRE>
  28. * import tracing.lib.AbstractTrace;
  29. * aspect TraceMyClasses extends AbstractTrace of eachJVM() {
  30. * pointcut classes(): within(TwoDShape) | within(Circle) | within(Square);
  31. * pointcut constructors(): executions(new(..));
  32. * pointcut methods(): executions(!abstract * *(..))
  33. * }
  34. * </PRE>
  35. * (Make sure .../aspectj/examples is in your classpath)
  36. */
  37. public abstract aspect AbstractTrace {
  38. /**
  39. * Application classes - left unspecified.
  40. * Subclasses should concretize this crosscut with class names.
  41. */
  42. abstract pointcut classes();
  43. /**
  44. * Constructors - left unspecified.
  45. * Subclasses should concretize this crosscut with constructors.
  46. */
  47. abstract pointcut constructors();
  48. /**
  49. * Methods - left unspecified.
  50. * Subclasses should concretize this crosscut with method names.
  51. */
  52. abstract pointcut methods();
  53. before(): classes() && constructors() {
  54. doTraceEntry(thisJoinPoint, true);
  55. }
  56. after(): classes() && constructors() {
  57. doTraceExit(thisJoinPoint, true);
  58. }
  59. before(): classes() && methods() {
  60. doTraceEntry(thisJoinPoint, false);
  61. }
  62. after(): classes() && methods() {
  63. doTraceExit(thisJoinPoint, false);
  64. }
  65. /*
  66. * From here on, it's an ordinary class implementation.
  67. * The static state is thread-safe by using ThreadLocal variables.
  68. */
  69. /**
  70. * This method initializes this thread's trace output stream.
  71. * By default, the output stream is System.err, and it is the same for
  72. * all threads. In multithreaded applications, you may want to define
  73. * different output streams for the different threads. For doing it,
  74. * simply call this method in the beginning of each thread's main loop,
  75. * giving it different output streams.
  76. */
  77. public void initStream(PrintStream _stream) {
  78. setStream(_stream);
  79. }
  80. private ThreadLocal stream = new ThreadLocal() {
  81. protected Object initialValue() {
  82. return System.err;
  83. }
  84. };
  85. private ThreadLocal callDepth = new ThreadLocal() {
  86. protected Object initialValue() {
  87. return new Integer(0);
  88. }
  89. };
  90. private PrintStream getStream() {
  91. return (PrintStream)stream.get();
  92. }
  93. private void setStream(PrintStream s) {
  94. stream.set(s);
  95. }
  96. private int getCallDepth() {
  97. return ((Integer)(callDepth.get())).intValue();
  98. }
  99. private void setCallDepth(int n) {
  100. callDepth.set(new Integer(n));
  101. }
  102. private void doTraceEntry (JoinPoint jp, boolean isConstructor) {
  103. setCallDepth(getCallDepth() + 1);
  104. printEntering(jp, isConstructor);
  105. }
  106. private void doTraceExit (JoinPoint jp, boolean isConstructor) {
  107. printExiting(jp, isConstructor);
  108. setCallDepth(getCallDepth() - 1);
  109. }
  110. private void printEntering (JoinPoint jp, boolean isConstructor) {
  111. printIndent();
  112. getStream().print("--> ");
  113. getStream().print(jp);
  114. // printParameterTypes(jp);
  115. getStream().println();
  116. }
  117. private void printExiting (JoinPoint jp, boolean isConstructor) {
  118. printIndent();
  119. getStream().print("<-- ");
  120. getStream().print(jp);
  121. // printParameterTypes(jp);
  122. getStream().println();
  123. }
  124. // private void printParameterTypes(JoinPoint jp) {
  125. // Class[] ptypes = jp.parameterTypes;
  126. // getStream().print("(");
  127. // for (int i = 0; i < ptypes.length; i++) {
  128. // getStream().print(ptypes[i].getName());
  129. // if (i < ptypes.length - 1) getStream().print(", ");
  130. // }
  131. // getStream().print(")");
  132. // }
  133. private void printIndent() {
  134. for (int i = 0; i < getCallDepth(); i++)
  135. getStream().print(" ");
  136. }
  137. /**
  138. * This method is not being used.
  139. * It's being included solely for illustrating how to access and use
  140. * the information in JoinPoint.
  141. * If you want, you can replace the calls to printParameterTypes (above)
  142. * by calls to this method.
  143. */
  144. // private void printParameters(JoinPoint jp) {
  145. // Class[] ptypes = jp.parameterTypes;
  146. // String[] pnames = jp.parameterNames;
  147. // Object[] params = jp.parameters;
  148. // getStream().print("(");
  149. // for (int i = 0; i < ptypes.length; i++) {
  150. // getStream().print(ptypes[i].getName() + " " +
  151. // pnames[i] + "=" +
  152. // params[i]);
  153. // if (i < ptypes.length - 1) getStream().print(", ");
  154. // }
  155. // getStream().print(")");
  156. // }
  157. }