diff options
author | aclement <aclement> | 2008-05-05 18:51:46 +0000 |
---|---|---|
committer | aclement <aclement> | 2008-05-05 18:51:46 +0000 |
commit | 41cd95b3fcd154cbe279b2f8ea73b6e3ebf922f0 (patch) | |
tree | 36c9e612f8aa1b2d29645c1072e64ecba8121aa6 /tests/bugs161 | |
parent | e5583b04a2eef87eac84482485b60adc486acd9a (diff) | |
download | aspectj-41cd95b3fcd154cbe279b2f8ea73b6e3ebf922f0.tar.gz aspectj-41cd95b3fcd154cbe279b2f8ea73b6e3ebf922f0.zip |
230134: testcode
Diffstat (limited to 'tests/bugs161')
-rw-r--r-- | tests/bugs161/pr230134/HW.java | 14 | ||||
-rw-r--r-- | tests/bugs161/pr230134/HelloWorldTracing.java | 31 | ||||
-rw-r--r-- | tests/bugs161/pr230134/SimpleTracing.java | 210 | ||||
-rw-r--r-- | tests/bugs161/pr230134/Tracing.java | 226 | ||||
-rw-r--r-- | tests/bugs161/pr230134/aop.xml | 9 |
5 files changed, 490 insertions, 0 deletions
diff --git a/tests/bugs161/pr230134/HW.java b/tests/bugs161/pr230134/HW.java new file mode 100644 index 000000000..01719db99 --- /dev/null +++ b/tests/bugs161/pr230134/HW.java @@ -0,0 +1,14 @@ +package hello; + +public class HW { + public static void main(String[] argv) { + new HW().print("Hello"); + new HW().print(" "); + new HW().print("World"); + new HW().print("\n"); + } + + public void print(String msg) { + System.out.print(msg); + } +} diff --git a/tests/bugs161/pr230134/HelloWorldTracing.java b/tests/bugs161/pr230134/HelloWorldTracing.java new file mode 100644 index 000000000..1115a876d --- /dev/null +++ b/tests/bugs161/pr230134/HelloWorldTracing.java @@ -0,0 +1,31 @@ +/******************************************************************************* + * Copyright (c) 2006 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Matthew Webster initial implementation + *******************************************************************************/ + +package demo.hello.tracing; + +import org.aspectj.lib.tracing.*; + +public aspect HelloWorldTracing extends SimpleTracing { + + protected pointcut tracingScope () : + within(hello.*); + + /** + * Template method that allows choice of destination for output + * + * @param s message to be traced + */ + protected void println (String s) { + System.out.println(s); + } + +} + diff --git a/tests/bugs161/pr230134/SimpleTracing.java b/tests/bugs161/pr230134/SimpleTracing.java new file mode 100644 index 000000000..97f92da8a --- /dev/null +++ b/tests/bugs161/pr230134/SimpleTracing.java @@ -0,0 +1,210 @@ +/******************************************************************************* + * Copyright (c) 2005 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Common Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/cpl-v10.html + * + * Contributors: + * Matthew Webster - initial implementation + * Sian January + *******************************************************************************/ +package org.aspectj.lib.tracing; + +import java.io.File; +import java.lang.reflect.Array; +import java.net.URL; +import java.text.SimpleDateFormat; +import java.util.Collection; +import java.util.Date; + +import org.aspectj.lang.JoinPoint; +import org.aspectj.lang.reflect.CodeSignature; + +/** + * This simple abstract aspect is enabled by default and traces method + * signatures as well as arguments to stderr. An abstract scoping pointcut + * is provided for concrete, user-supplied sub-aspect to determine which + * classes should be traced. + */ +public abstract aspect SimpleTracing extends Tracing { + + /** + * Sub-aspects <b>must</b> implement this pointcut to determine what to trace + */ + protected abstract pointcut tracingScope (); + + private static SimpleDateFormat timeFormat; + + /** + * Enabled or disable tracing + * + * @param enabled + */ + public static void setEnabled (boolean enabled) { + tracingEnabled = enabled; + } + + public static boolean getEnabled () { + return tracingEnabled; + } + + /* + * Tracing pattern 2: Use if() pointcut to efficiently determine when to trace + * + * Tracing pattern 3: Use -XlazyTjp compiler option + */ + protected pointcut shouldTrace () : + if(tracingEnabled) && tracingScope(); + + private static boolean tracingEnabled = getBoolean("org.aspectj.lib.tracing",true); + + private static boolean getBoolean (String name, boolean def) { + String defaultValue = String.valueOf(def); + String value = System.getProperty(name,defaultValue); + return Boolean.valueOf(value).booleanValue(); + } + + /* + * Tracing template methods + */ + protected void enter (JoinPoint jp, Object obj) { + CodeSignature signature = (CodeSignature)jp.getSignature(); + println(signature.getDeclaringType(),formatMessage(">",signature.getDeclaringTypeName(),signature.getName(),obj,jp.getArgs())); +// println("> " + signature.toShortString() + " " + formatParam("obj",obj) + " " + formatArgs(signature.getParameterNames(),jp.getArgs())); + } + + protected void enter (JoinPoint jp) { + CodeSignature signature = (CodeSignature)jp.getSignature(); + println(signature.getDeclaringType(),formatMessage(">",signature.getDeclaringTypeName(),signature.getName(),null,jp.getArgs())); +// println("> " + jp.getSignature().toShortString() + " " + formatArgs(signature.getParameterNames(),jp.getArgs())); + } + + protected void exit (JoinPoint.StaticPart sjp, Object ret) { + CodeSignature signature = (CodeSignature)sjp.getSignature(); + println(signature.getDeclaringType(),formatMessage("<",signature.getDeclaringTypeName(),signature.getName(),ret,null)); +// println("< " + sjp.getSignature().toShortString() + " " + formatParam("ret",ret)); + } + + protected void exit (JoinPoint.StaticPart sjp) { + CodeSignature signature = (CodeSignature)sjp.getSignature(); + println(signature.getDeclaringType(),formatMessage("<",signature.getDeclaringTypeName(),signature.getName(),null,null)); +// println("< " + sjp.getSignature().toShortString()); + } + + protected void exception (JoinPoint.StaticPart sjp, Throwable th) { + CodeSignature signature = (CodeSignature)sjp.getSignature(); + println(signature.getDeclaringType(),formatMessage("E",signature.getName(),th)); +// println("E " + sjp.getSignature().toShortString() + " " + th.toString()); + } + + /* + * Formatting + */ + protected String formatMessage(String kind, String className, String methodName, Object thiz, Object[] args) { + StringBuffer message = new StringBuffer(); + Date now = new Date(); + message.append(formatDate(now)).append(" "); + message.append(Thread.currentThread().getName()).append(" "); + message.append(kind).append(" "); + message.append(className); + message.append(".").append(methodName); + if (thiz != null) message.append(" ").append(formatObj(thiz)); + if (args != null) message.append(" ").append(formatArgs(args)); + return message.toString(); + } + + protected String formatMessage(String kind, String text, Throwable th) { + StringBuffer message = new StringBuffer(); + Date now = new Date(); + message.append(formatDate(now)).append(" "); + message.append(Thread.currentThread().getName()).append(" "); + message.append(kind).append(" "); + message.append(text); + if (th != null) message.append(" ").append(formatObj(th)); + return message.toString(); + } + + /** + * Format arguments into a comma separated list + * + * @param names array of argument names + * @param args array of arguments + * @return the formated list + */ + protected String formatArgs(Object[] args) { + StringBuffer sb = new StringBuffer(); + + for (int i = 0; i < args.length; i++) { + sb.append(formatObj(args[i])); + if (i < args.length-1) sb.append(", "); + } + + return sb.toString(); + } + + /** + * Format objects safely avoiding toString which can cause recursion, + * NullPointerExceptions or highly verbose results. + * + * @param obj parameter to be formatted + * @return the formated parameter + */ + protected Object formatObj(Object obj) { + + /* These classes have a safe implementation of toString() */ + if (obj == null + || obj instanceof String + || obj instanceof Number + || obj instanceof Boolean + || obj instanceof Exception + || obj instanceof Character + || obj instanceof Class + || obj instanceof File + || obj instanceof StringBuffer + || obj instanceof URL + ) return obj; + else if (obj.getClass().isArray()) { + return formatArray(obj); + } + else if (obj instanceof Collection) { + return formatCollection((Collection)obj); + } + else try { + + /* Use classname@hashcode */ + return obj.getClass().getName() + "@" + Integer.toHexString(System.identityHashCode(obj)); + + /* Object.hashCode() can be override and may thow an exception */ + } catch (Exception ex) { + return obj.getClass().getName() + "@FFFFFFFF"; + } + } + + protected String formatArray (Object obj) { + return obj.getClass().getComponentType().getName() + "[" + Array.getLength(obj) + "]"; + } + + protected String formatCollection (Collection c) { + return c.getClass().getName() + "(" + c.size() + ")"; + } + + private static String formatDate (Date date) { + if (timeFormat == null) { + timeFormat = new SimpleDateFormat("HH:mm:ss.SSS"); + } + + return timeFormat.format(date); + } + + /** + * Template method that allows choice of destination for output + * + * @param s message to be traced + */ + protected void println (Class clazz, String s) { + System.err.println(s); + } + +} + diff --git a/tests/bugs161/pr230134/Tracing.java b/tests/bugs161/pr230134/Tracing.java new file mode 100644 index 000000000..2029bc968 --- /dev/null +++ b/tests/bugs161/pr230134/Tracing.java @@ -0,0 +1,226 @@ +/******************************************************************************* + * Copyright (c) 2005 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Common Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/cpl-v10.html + * + * Contributors: + * Matthew Webster - initial implementation + * Sian January + *******************************************************************************/ +package org.aspectj.lib.tracing; + +import org.aspectj.lang.*; + +/** + * This root abstract aspect determines the basic tracing behaviour + * i.e. entry/exit/exception using the method/constructor execution() pointcut + * and before/after returning/after throwing advice. Determining what + * methods and constructors belonging to which classes is delegated to a + * user-supplied concrete aspect using an abstract pointcut. When tracing + * occurs and what is done with the captured data is delegated to an abstract, + * infrastructure-specific sub-aspect through template methods. + */ +public abstract aspect Tracing { + + /** + * Sub-aspects <b>must</b> implement this pointcut to determine what and when to + * trace + */ + protected abstract pointcut shouldTrace (); + + private pointcut staticContext () : !this(Object); + private pointcut nonStaticContext (Object obj) : this(obj); + private pointcut voidMethod () : execution(void *(..)); + + public final static pointcut methodExecution () : execution(* *(..)); + public final static pointcut constructorExecution () : execution(new(..)); + public final static pointcut objectMethod () : execution(* Object.*(..)); + + /** + * Sub-aspects <b>may</b> override this point to determine which methods if any + * are traced. By default include only public methods and those not inherited + * from java.lang.Object e.g. toString(). + */ + protected pointcut includedMethod () : + execution(public * *(..)) + && !objectMethod(); + + + /** + * Sub-aspects <b>may</b> override this point to determine which constructors if any + * are traced. By default include only public constructors. + */ + protected pointcut includedConstructor () : + execution(public new(..)); + + /* + * Exclude methods and constructors in Tracing and sub-aspects as well as + * those in the control flow of Tracing advice or constructors to avoid recursion. + */ + private pointcut excluded () : + within(Tracing+) +// || cflow((adviceexecution() || execution(new(..))) && within(Tracing+)) + || cflow((adviceexecution() && within(Tracing+))) + ; + + /* + * Trace only method execution included by the user but excluded by the aspect e.g. itself + */ + private pointcut tracedMethod () : + methodExecution() + && includedMethod() + && !excluded() + ; + + /* + * Trace only constructor execution included by the user but excluded by the aspect e.g. itself + */ + private pointcut tracedConstructor (Object obj) : + constructorExecution() + && includedConstructor() + && !excluded() + && this(obj) + ; + + /* + * Trace entry to instance methods + * + * Tracing pattern 1: Only use thisJoinPoint in before() + */ + before (Object obj) : tracedMethod() && nonStaticContext(obj) && shouldTrace() { + enter(thisJoinPoint,obj); + } + + /* + * Trace entry to static methods + * + * Tracing pattern 1: Only use thisJoinPoint in before() + */ + before () : tracedMethod() && staticContext() && shouldTrace() { + enter(thisJoinPoint); + } + + /* + * Trace exit from void methods + * + * Tracing pattern 1: Use thisJoinPointStaticPart in after() + */ + after() returning() : tracedMethod() && voidMethod() && shouldTrace() { + exit(thisJoinPointStaticPart); + } + + /* + * Trace exit from non-void methods including return value + * + * Tracing pattern 1: Use thisJoinPointStaticPart in after() + */ + after() returning(Object ret) : tracedMethod() && !voidMethod() && shouldTrace() { + exit(thisJoinPointStaticPart,ret); + } + + /* + * Trace exceptions thrown from methods and constructors + * + * Tracing pattern 1: Use thisJoinPointStaticPart in after() + */ + after() throwing(Throwable th) : (tracedMethod() || tracedConstructor(Object)) && shouldTrace() { + if (shouldTrace(th)) exception(thisJoinPointStaticPart,th); + } + + /* + * Trace entry to constructors + * + * Tracing pattern 1: Only use thisJoinPoint in before() + */ + before () : tracedConstructor(Object) && shouldTrace() { + enter(thisJoinPoint); + } + + /* + * Trace exit from constructors including new object + * + * Tracing pattern 1: Only use thisJoinPoint in before() + */ + after (Object obj) : tracedConstructor(obj) && shouldTrace() { + exit(thisJoinPointStaticPart,obj); + } + + /* + * Template methods to log data implemented by infrastructure-specific sub-aspects + * e.g. java.util.logging.Logger + */ + protected abstract void enter (JoinPoint jp, Object obj); + + protected abstract void enter (JoinPoint jp); + + protected abstract void exit (JoinPoint.StaticPart sjp); + + protected abstract void exit (JoinPoint.StaticPart sjp, Object ret); + + protected abstract void exception (JoinPoint.StaticPart sjp, Throwable th); + + /** + * Format arguments into a comma separated list + * + * @param names array of argument names + * @param args array of arguments + * @return the formated list + */ + protected String formatArgs (String[] names, Object[] args) { + StringBuffer sb = new StringBuffer(); + + for (int i = 0; i < args.length; i++) { + sb.append(formatParam(names[i],args[i])); + if (i < args.length-1) sb.append(", "); + } + + return sb.toString(); + } + + /** + * Format objects safely avoiding toString which can cause recursion, + * NullPointerExceptions or highly verbose results. + * + * @param obj parameter to be formatted + * @return the formated parameter + */ + protected Object formatObj (Object obj) { + if (obj == null + || obj instanceof String + || obj instanceof Number + || obj instanceof Boolean + || obj instanceof Character + || obj instanceof Class + || obj instanceof StringBuffer + ) return obj; + else try { + return obj.getClass().getName() + "@" + Integer.toString(obj.hashCode(),16); + } catch (Exception ex) { + return obj.getClass().getName(); + } + } + + /** + * Format parameter into name=value pair + * + * @param name parameter name + * @param arg parameted to be formatted + * @return the formated parameter + */ + protected String formatParam (String name, Object arg) { + return name + "=" + formatObj(arg); + } + + /** + * By default we do not trace errors e.g. OutOfMemoryError because the + * system my be in an inconsistent state. However users may override this + * + * @param th excpeption or error to be traced + * @return whether it should be traced + */ + protected boolean shouldTrace (Throwable th) { + return !(th instanceof Error); + } +} diff --git a/tests/bugs161/pr230134/aop.xml b/tests/bugs161/pr230134/aop.xml new file mode 100644 index 000000000..c39ae97bb --- /dev/null +++ b/tests/bugs161/pr230134/aop.xml @@ -0,0 +1,9 @@ +<?xml version="1.0"?> +<aspectj> + <weaver options="-verbose -showWeaveInfo"/> + + <aspects> + <aspect name="demo.hello.tracing.HelloWorldTracing"/> + </aspects> +</aspectj> + |