]> source.dussan.org Git - aspectj.git/commitdiff
First drop of Bug 150487 "Tracing and Logging Framework" (Trace & TraceFactory)
authormwebster <mwebster>
Fri, 14 Jul 2006 17:39:46 +0000 (17:39 +0000)
committermwebster <mwebster>
Fri, 14 Jul 2006 17:39:46 +0000 (17:39 +0000)
20 files changed:
loadtime/src/org/aspectj/weaver/loadtime/Aj.java
loadtime/src/org/aspectj/weaver/loadtime/ClassLoaderWeavingAdaptor.java
loadtime/src/org/aspectj/weaver/loadtime/DefaultWeavingContext.java
loadtime/testsrc/LoadtimeModuleTests.java
weaver/.classpath
weaver/src/org/aspectj/weaver/Lint.java
weaver/src/org/aspectj/weaver/World.java
weaver/src/org/aspectj/weaver/bcel/BcelWeaver.java
weaver/src/org/aspectj/weaver/bcel/ClassPathManager.java
weaver/src/org/aspectj/weaver/tools/AbstractTrace.java [new file with mode: 0644]
weaver/src/org/aspectj/weaver/tools/CommonsTrace.java [new file with mode: 0644]
weaver/src/org/aspectj/weaver/tools/CommonsTraceFactory.java [new file with mode: 0644]
weaver/src/org/aspectj/weaver/tools/DefaultTrace.java [new file with mode: 0644]
weaver/src/org/aspectj/weaver/tools/Trace.java [new file with mode: 0644]
weaver/src/org/aspectj/weaver/tools/TraceFactory.java [new file with mode: 0644]
weaver/src/org/aspectj/weaver/tools/Traceable.java [new file with mode: 0644]
weaver/src/org/aspectj/weaver/tools/WeavingAdaptor.java
weaver5/java5-src/org/aspectj/weaver/tools/Jdk14Trace.java [new file with mode: 0644]
weaver5/java5-src/org/aspectj/weaver/tools/Jdk14TraceFactory.java [new file with mode: 0644]
weaver5/testdata/logging.properties [new file with mode: 0644]

index b0552a0405a8ade293a6952c4cafb80131af6f68..015a245b386dedeba1478c8b76dec66ac159b9d7 100644 (file)
@@ -14,6 +14,8 @@ package org.aspectj.weaver.loadtime;
 import java.util.Map;
 import java.util.WeakHashMap;
 
+import org.aspectj.weaver.tools.Trace;
+import org.aspectj.weaver.tools.TraceFactory;
 import org.aspectj.weaver.tools.WeavingAdaptor;
 
 /**
@@ -26,13 +28,17 @@ public class Aj implements ClassPreProcessor {
 
        private IWeavingContext weavingContext;
        
+       private static Trace trace = TraceFactory.getTraceFactory().getTrace(Aj.class);
+       
        public Aj(){
                this(null);
        }
        
        
        public Aj(IWeavingContext context){
-               weavingContext = context;
+               if (trace.isTraceEnabled()) trace.enter("<init>",this,new Object[] {context});
+               this.weavingContext = context;
+               if (trace.isTraceEnabled()) trace.exit("<init>");
        }
 
     /**
@@ -51,22 +57,28 @@ public class Aj implements ClassPreProcessor {
      * @return weaved bytes
      */
     public byte[] preProcess(String className, byte[] bytes, ClassLoader loader) {
+               if (trace.isTraceEnabled()) trace.enter("preProcess",this,new Object[] {className,bytes,loader});
+       
         //TODO AV needs to doc that
         if (loader == null || className == null) {
             // skip boot loader or null classes (hibernate)
+               if (trace.isTraceEnabled()) trace.exit("preProcess",bytes);
             return bytes;
         }
 
         try {
             WeavingAdaptor weavingAdaptor = WeaverContainer.getWeaver(loader, weavingContext);
             if (weavingAdaptor == null) {
+                       if (trace.isTraceEnabled()) trace.exit("preProcess",bytes);
                return bytes;
             }
             return weavingAdaptor.weaveClass(className, bytes);
         } catch (Exception t) {
+               trace.error("preProcess",t);
             //FIXME AV wondering if we should have the option to fail (throw runtime exception) here
             // would make sense at least in test f.e. see TestHelper.handleMessage()
             t.printStackTrace();
+               if (trace.isTraceEnabled()) trace.exit("preProcess",bytes);
             return bytes;
         }
     }
index 2f02ca67dc34e559ba3ac264eb83530ff37b7369..7f65023613bcd508cfd77f740a7204197dde27c0 100644 (file)
@@ -46,6 +46,8 @@ import org.aspectj.weaver.ltw.LTWWorld;
 import org.aspectj.weaver.patterns.PatternParser;
 import org.aspectj.weaver.patterns.TypePattern;
 import org.aspectj.weaver.tools.GeneratedClassHandler;
+import org.aspectj.weaver.tools.Trace;
+import org.aspectj.weaver.tools.TraceFactory;
 import org.aspectj.weaver.tools.WeavingAdaptor;
 
 /**
@@ -72,10 +74,14 @@ public class ClassLoaderWeavingAdaptor extends WeavingAdaptor {
     private ClassLoader classLoader;
     private IWeavingContext weavingContext;
 
+       private static Trace trace = TraceFactory.getTraceFactory().getTrace(ClassLoaderWeavingAdaptor.class);
+    
     public ClassLoaderWeavingAdaptor(final ClassLoader loader, IWeavingContext wContext) {
        super();
+       if (trace.isTraceEnabled()) trace.enter("<init>",this);
        this.classLoader = loader;
        this.weavingContext = wContext;
+       if (trace.isTraceEnabled()) trace.exit("<init>");
     }
 
     protected void initialize (final ClassLoader deprecatedLoader, IWeavingContext deprecatedContext) {
@@ -334,6 +340,7 @@ public class ClassLoaderWeavingAdaptor extends WeavingAdaptor {
      * @param definitions
      */
     private void registerAspects(final BcelWeaver weaver, final ClassLoader loader, final List definitions) {
+       if (trace.isTraceEnabled()) trace.enter("registerAspects",this, new Object[] { weaver, loader, definitions} );
         //TODO: the exclude aspect allow to exclude aspect defined upper in the CL hierarchy - is it what we want ??
         // if not, review the getResource so that we track which resource is defined by which CL
 
@@ -396,6 +403,8 @@ public class ClassLoaderWeavingAdaptor extends WeavingAdaptor {
                enabled = false;
                info("no aspects registered. Disabling weaver for class loader " + getClassLoaderName(loader));
         }
+
+        if (trace.isTraceEnabled()) trace.exit("registerAspects",enabled);
     }
 
     /**
@@ -647,6 +656,8 @@ public class ClassLoaderWeavingAdaptor extends WeavingAdaptor {
     }
 
        private void defineClass(ClassLoader loader, String name, byte[] bytes) {
+       if (trace.isTraceEnabled()) trace.enter("defineClass",this,new Object[] {loader,name,bytes});
+       Object clazz = null;
                info("generating class '" + name + "'");
                
                try {
@@ -655,7 +666,7 @@ public class ClassLoaderWeavingAdaptor extends WeavingAdaptor {
                                        "defineClass", new Class[] { String.class,
                                                        bytes.getClass(), int.class, int.class });
                        defineClass.setAccessible(true);
-                       defineClass.invoke(loader, new Object[] { name, bytes,
+                       clazz = defineClass.invoke(loader, new Object[] { name, bytes,
                                        new Integer(0), new Integer(bytes.length) });
                } catch (InvocationTargetException e) {
                        if (e.getTargetException() instanceof LinkageError) {
@@ -668,5 +679,7 @@ public class ClassLoaderWeavingAdaptor extends WeavingAdaptor {
                } catch (Exception e) {
                        warn("define generated class failed",e);
                }
+
+               if (trace.isTraceEnabled()) trace.exit("defineClass",clazz);
        }
 }
index e3d7264e8200862e3caae7bddb3d03ee8f11b6ff..2ec0892532c908975bf7be1df0791d529d97f9d7 100644 (file)
@@ -68,7 +68,7 @@ public class DefaultWeavingContext implements IWeavingContext {
         */
        public String getId () {
                if (shortName == null) {
-                       shortName = getClassLoaderName();
+                       shortName = getClassLoaderName().replace('$','.');
                        int index = shortName.lastIndexOf(".");
                        shortName = shortName.substring(index + 1);
                }
index fe0ef33389ef086e204f33206fc1f6c713f5a9f8..342b16f240b355f66809825eef405d3b1b157021 100644 (file)
@@ -15,7 +15,10 @@ import junit.framework.Test;
 import junit.framework.TestSuite;
 import junit.textui.TestRunner;
 
+import org.aspectj.weaver.loadtime.AjTest;
+import org.aspectj.weaver.loadtime.ClassLoaderWeavingAdaptorTest;
 import org.aspectj.weaver.loadtime.JRockitAgentTest;
+import org.aspectj.weaver.loadtime.WeavingContextTest;
 import org.aspectj.weaver.loadtime.WeavingURLClassLoaderTest;
 import org.aspectj.weaver.loadtime.test.DocumentParserTest;
 
@@ -28,8 +31,11 @@ public class LoadtimeModuleTests extends TestCase {
         TestSuite suite = new TestSuite(LoadtimeModuleTests.class.getName());
 
         suite.addTestSuite(DocumentParserTest.class);
-        suite.addTestSuite(WeavingURLClassLoaderTest.class);
+        suite.addTestSuite(AjTest.class);
+        suite.addTestSuite(ClassLoaderWeavingAdaptorTest.class);
         suite.addTestSuite(JRockitAgentTest.class);
+        suite.addTestSuite(WeavingContextTest.class);
+        suite.addTestSuite(WeavingURLClassLoaderTest.class);
         return suite;
     }
 
index ab0c856c457749c5043afb84f96ab9a7e6d4ceae..1cceb2d3a35c79ebbfaacdf480c84a74c6bff4a4 100644 (file)
@@ -12,5 +12,6 @@
        <classpathentry combineaccessrules="false" kind="src" path="/aspectj5rt"/>
        <classpathentry kind="lib" path="/lib/asm/asm-aj.jar"/>
        <classpathentry sourcepath="/lib/bcel/bcel-src.zip" kind="lib" path="/lib/bcel/bcel.jar"/>
+       <classpathentry sourcepath="/lib/commons/commons-src.zip" kind="lib" path="/lib/commons/commons.jar"/>
        <classpathentry kind="output" path="bin"/>
 </classpath>
index 06898f61de4e0b1e05cbab1a7b6180ae61f47aab..739ba02d0940411eb985c8c6516f0c4819a9427e 100644 (file)
@@ -28,6 +28,8 @@ import org.aspectj.bridge.IMessage;
 import org.aspectj.bridge.ISourceLocation;
 import org.aspectj.bridge.Message;
 import org.aspectj.bridge.MessageUtil;
+import org.aspectj.weaver.tools.Trace;
+import org.aspectj.weaver.tools.TraceFactory;
 
 public class Lint {
        /* private */ Map kinds = new HashMap();
@@ -123,14 +125,20 @@ public class Lint {
                new Kind("cantFindType","{0}");
        
        public final Kind cantFindTypeAffectingJoinPointMatch = new Kind("cantFindTypeAffectingJPMatch","{0}");
+
+       private static Trace trace = TraceFactory.getTraceFactory().getTrace(Lint.class);
        
     public Lint(World world) {
+       if (trace.isTraceEnabled()) trace.enter("<init>",this,world);
                this.world = world;
+               if (trace.isTraceEnabled()) trace.exit("<init>");
        }
        
        
        public void setAll(String messageKind) {
+               if (trace.isTraceEnabled()) trace.enter("setAll",this,messageKind);
                setAll(getMessageKind(messageKind));
+               if (trace.isTraceEnabled()) trace.exit("setAll");
        }
        
        private void setAll(IMessage.Kind messageKind) {
@@ -141,6 +149,7 @@ public class Lint {
        }
        
        public void setFromProperties(File file) {
+               if (trace.isTraceEnabled()) trace.enter("setFromProperties",this,file);
                try {
                        InputStream s = new FileInputStream(file);
                        setFromProperties(s);
@@ -148,6 +157,7 @@ public class Lint {
                        MessageUtil.error(world.getMessageHandler(),
                                        WeaverMessages.format(WeaverMessages.XLINT_LOAD_ERROR,file.getPath(),ioe.getMessage()));
                }
+               if (trace.isTraceEnabled()) trace.exit("setFromProperties");
        }
 
        public void loadDefaultProperties() {
index 0051e3106e0a7b350869b651a8f6119bf3269840..8597690b87f410d2f3bfc56a0a34f92216bf5d7e 100644 (file)
@@ -38,6 +38,8 @@ import org.aspectj.weaver.patterns.DeclarePrecedence;
 import org.aspectj.weaver.patterns.PerClause;
 import org.aspectj.weaver.patterns.Pointcut;
 import org.aspectj.weaver.reflect.ReflectionBasedReferenceTypeDelegate;
+import org.aspectj.weaver.tools.Trace;
+import org.aspectj.weaver.tools.TraceFactory;
 
 /**
  * A World is a collection of known types and crosscutting members.
@@ -109,6 +111,7 @@ public abstract class World implements Dump.INode {
        public boolean forDEBUG_structuralChangesCode = false;
        public boolean forDEBUG_bridgingCode = false;
        
+       private static Trace trace = TraceFactory.getTraceFactory().getTrace(World.class);
     
     // Records whether ASM is around ... so we might use it for delegates
     protected static boolean isASMAround;
@@ -138,6 +141,7 @@ public abstract class World implements Dump.INode {
      */
     protected World() {
         super();
+        if (trace.isTraceEnabled()) trace.enter("<init>", this);
         Dump.registerNode(this.getClass(),this);
         typeMap.put("B", ResolvedType.BYTE);
         typeMap.put("S", ResolvedType.SHORT);
@@ -149,6 +153,7 @@ public abstract class World implements Dump.INode {
         typeMap.put("Z", ResolvedType.BOOLEAN);
         typeMap.put("V", ResolvedType.VOID);
         precedenceCalculator = new AspectPrecedenceCalculator(this);
+        if (trace.isTraceEnabled()) trace.exit("<init>");
     }
     
     /**
@@ -305,7 +310,10 @@ public abstract class World implements Dump.INode {
      * Convenience method for finding a type by name and resolving it in one step.
      */
     public ResolvedType resolve(String name) {
-       return resolve(UnresolvedType.forName(name));
+//     trace.enter("resolve", this, new Object[] {name});
+       ResolvedType ret = resolve(UnresolvedType.forName(name));
+//     trace.exit("resolve", ret);
+       return ret;
     }
     
     public ResolvedType resolve(String name,boolean allowMissing) {
@@ -595,6 +603,9 @@ public abstract class World implements Dump.INode {
                        }
                }
 
+       public boolean debug (String message) {
+               return MessageUtil.debug(messageHandler,message);
+       }
 
        public void setCrossReferenceHandler(ICrossReferenceHandler xrefHandler) {
                this.xrefHandler = xrefHandler;
@@ -819,9 +830,13 @@ public abstract class World implements Dump.INode {
                private int collectedTypes = 0;
                private ReferenceQueue rq = new ReferenceQueue();
                
+               private static Trace trace = TraceFactory.getTraceFactory().getTrace(World.TypeMap.class);
+               
                TypeMap(World w) {
+                       if (trace.isTraceEnabled()) trace.enter("<init>",this,w);
                        this.w = w;
                        memoryProfiling = false;// !w.getMessageHandler().isIgnoring(Message.INFO);
+                       if (trace.isTraceEnabled()) trace.exit("<init>");
                }
                
                /** 
index 7ceffdd19eb372a7a7a148a3f3d8ab0b94b9c2d6..b38f470e9c32770cbdc04ac67a7dfc5c6c3a4022 100644 (file)
@@ -95,6 +95,8 @@ import org.aspectj.weaver.patterns.OrPointcut;
 import org.aspectj.weaver.patterns.Pointcut;
 import org.aspectj.weaver.patterns.PointcutRewriter;
 import org.aspectj.weaver.patterns.WithinPointcut;
+import org.aspectj.weaver.tools.Trace;
+import org.aspectj.weaver.tools.TraceFactory;
 
 
 public class BcelWeaver implements IWeaver {
@@ -106,11 +108,15 @@ public class BcelWeaver implements IWeaver {
 
     private boolean inReweavableMode = false;
     
+    private static Trace trace = TraceFactory.getTraceFactory().getTrace(BcelWeaver.class);
+
     public BcelWeaver(BcelWorld world) {
         super();
+        if (trace.isTraceEnabled()) trace.enter("<init>",this,world);
         WeaverMetrics.reset();
         this.world = world;
         this.xcutSet = world.getCrosscuttingMembersSet();
+        if (trace.isTraceEnabled()) trace.exit("<init>");
     }
         
     public BcelWeaver() {
@@ -149,7 +155,9 @@ public class BcelWeaver implements IWeaver {
      * @return aspect
      */
     public ResolvedType addLibraryAspect(String aspectName) {
-        // 1 - resolve as is
+       if (trace.isTraceEnabled()) trace.enter("addLibraryAspect",this,aspectName);
+
+       // 1 - resolve as is
        UnresolvedType unresolvedT = UnresolvedType.forName(aspectName);
        unresolvedT.setNeedsModifiableDelegate(true);
         ResolvedType type = world.resolve(unresolvedT, true);
@@ -185,10 +193,13 @@ public class BcelWeaver implements IWeaver {
             //TODO AV - happens to reach that a lot of time: for each type flagged reweavable X for each aspect in the weaverstate
             //=> mainly for nothing for LTW - pbly for something in incremental build...
                        xcutSet.addOrReplaceAspect(type);
+               if (trace.isTraceEnabled()) trace.exit("addLibraryAspect",type);
             return type;
         } else {
             // FIXME AV - better warning upon no such aspect from aop.xml
-                       throw new RuntimeException("Cannot register non aspect: " + type.getName() + " , " + aspectName);
+                       RuntimeException ex = new RuntimeException("Cannot register non aspect: " + type.getName() + " , " + aspectName);
+               if (trace.isTraceEnabled()) trace.exit("addLibraryAspect",ex);
+                       throw ex;
                }
     }
     
@@ -436,6 +447,7 @@ public class BcelWeaver implements IWeaver {
     }
     
     public void prepareForWeave() {
+       if (trace.isTraceEnabled()) trace.enter("prepareForWeave",this);
        needToReweaveWorld = xcutSet.hasChangedSinceLastReset();
 
        CflowPointcut.clearCaches();
@@ -457,6 +469,7 @@ public class BcelWeaver implements IWeaver {
        }
 
                shadowMungerList = xcutSet.getShadowMungers();
+//             world.debug("shadow mungers=" + shadowMungerList);
                rewritePointcuts(shadowMungerList);
                // Sometimes an error occurs during rewriting pointcuts (for example, if ambiguous bindings
                // are detected) - we ought to fail the prepare when this happens because continuing with
@@ -486,6 +499,8 @@ public class BcelWeaver implements IWeaver {
                                        return (sm2.getSourceLocation().getOffset()-sm1.getSourceLocation().getOffset());
                                }
                        });
+               if (trace.isTraceEnabled()) trace.exit("prepareForWeave");
     }
     
     /*
@@ -991,6 +1006,7 @@ public class BcelWeaver implements IWeaver {
     
     // variation of "weave" that sources class files from an external source.
     public Collection weave(IClassFileProvider input) throws IOException {
+       if (trace.isTraceEnabled()) trace.enter("weave",this,input);
        ContextToken weaveToken = CompilationAndWeavingContext.enteringPhase(CompilationAndWeavingContext.WEAVING, "");
        Collection wovenClassNames = new ArrayList();
        IWeaveRequestor requestor = input.getRequestor();
@@ -1138,6 +1154,7 @@ public class BcelWeaver implements IWeaver {
 
         requestor.weaveCompleted();
         CompilationAndWeavingContext.leavingPhase(weaveToken);
+        if (trace.isTraceEnabled()) trace.exit("weave",wovenClassNames);
        return wovenClassNames;
     }
 
@@ -1693,9 +1710,11 @@ public class BcelWeaver implements IWeaver {
        }
 
        public void setReweavableMode(boolean xNotReweavable) {
+       if (trace.isTraceEnabled()) trace.enter("setReweavableMode",this,xNotReweavable);
                inReweavableMode = !xNotReweavable;
                WeaverStateInfo.setReweavableModeDefaults(!xNotReweavable,false,true);
                BcelClassWeaver.setReweavableMode(!xNotReweavable);
+       if (trace.isTraceEnabled()) trace.exit("setReweavableMode");
        }
 
        public boolean isReweavable() {
@@ -1707,9 +1726,11 @@ public class BcelWeaver implements IWeaver {
     }
 
        public void tidyUp() {
+               if (trace.isTraceEnabled()) trace.enter("tidyUp",this);
            shadowMungerList = null; // setup by prepareForWeave
                typeMungerList = null; // setup by prepareForWeave
            lateTypeMungerList = null; // setup by prepareForWeave
                declareParentsList = null; // setup by prepareForWeave
+               if (trace.isTraceEnabled()) trace.exit("tidyUp");
        }
 }
index 724d0a57a9a7eacc60c37f2384e8acc32076d408..5f06c0e6f17a4477f86d49a486b928b19f6feb68 100644 (file)
@@ -30,6 +30,8 @@ import org.aspectj.bridge.MessageUtil;
 import org.aspectj.weaver.BCException;
 import org.aspectj.weaver.UnresolvedType;
 import org.aspectj.weaver.WeaverMessages;
+import org.aspectj.weaver.tools.Trace;
+import org.aspectj.weaver.tools.TraceFactory;
 
 
 public class ClassPathManager {
@@ -43,6 +45,8 @@ public class ClassPathManager {
        private List openArchives                = new ArrayList();
        private static int maxOpenArchives       = -1;
     private static final int MAXOPEN_DEFAULT = 1000;
+
+    private static Trace trace = TraceFactory.getTraceFactory().getTrace(ClassPathManager.class);
        
        static {
                String openzipsString = getSystemPropertyWithoutSecurityException("org.aspectj.weaver.openarchives",Integer.toString(MAXOPEN_DEFAULT));
@@ -53,11 +57,13 @@ public class ClassPathManager {
        
        
        public ClassPathManager(List classpath, IMessageHandler handler) {
+               if (trace.isTraceEnabled()) trace.enter("<init>",this,new Object[] { classpath, handler });
                entries = new ArrayList();
                for (Iterator i = classpath.iterator(); i.hasNext();) {
                        String name = (String) i.next();
                        addPath(name, handler);
                }
+               if (trace.isTraceEnabled()) trace.exit("<init>");
        }
 
        protected ClassPathManager() {};
diff --git a/weaver/src/org/aspectj/weaver/tools/AbstractTrace.java b/weaver/src/org/aspectj/weaver/tools/AbstractTrace.java
new file mode 100644 (file)
index 0000000..d59eed9
--- /dev/null
@@ -0,0 +1,154 @@
+/*******************************************************************************
+ * 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 org.aspectj.weaver.tools;
+
+import java.io.File;
+
+public abstract class AbstractTrace implements Trace {
+
+       protected Class tracedClass;
+       
+       protected AbstractTrace (Class clazz) {
+               this.tracedClass = clazz;
+       }
+       
+       public abstract void enter (String methodName, Object thiz, Object[] args);
+       
+       public abstract void enter(String methodName, Object thiz);
+
+       public abstract void exit(String methodName, Object ret);
+
+       public abstract void exit(String methodName, Throwable th);
+
+       public void error(String message) {
+               // TODO Auto-generated method stub
+
+       }
+
+       public void error(String message, Throwable th) {
+               // TODO Auto-generated method stub
+
+       }
+
+       public void event(String methodName) {
+               // TODO Auto-generated method stub
+
+       }
+
+       public void event(String methodName, Object thiz, Object[] args) {
+               // TODO Auto-generated method stub
+
+       }
+
+       public void exit(String methodName) {
+               // TODO Auto-generated method stub
+
+       }
+
+       public void info(String message) {
+               // TODO Auto-generated method stub
+
+       }
+
+       public void warn(String message) {
+               // TODO Auto-generated method stub
+
+       }
+
+       public void warn(String message, Throwable th) {
+               // TODO Auto-generated method stub
+
+       }
+       
+       /*
+        * Convenience methods
+        */
+       public void enter (String methodName, Object thiz, Object arg) {
+               enter(methodName,thiz,new Object[] { arg });
+       }
+
+       public void enter (String methodName, Object thiz, boolean z) {
+               enter(methodName,thiz,new Boolean(z));
+       }
+
+       public void exit (String methodName, boolean b) {
+               exit(methodName,new Boolean(b));
+       }
+       
+       public boolean isTraceEnabled () {
+               return true;
+       }
+
+       protected String formatMessage(String className, String methodName, Object thiz, Object[] args) {
+               StringBuffer message = new StringBuffer();
+               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();
+       }
+
+       /**
+        * 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
+                   ) return obj;
+               else try {
+                       
+                       /* Classes can provide an alternative implementation of toString() */
+                       if (obj instanceof Traceable) {
+                               Traceable t = (Traceable)obj;
+                               return t.toTraceString();
+                       }
+                       
+                       /* Use classname@hashcode */
+                       else return obj.getClass().getName() + "@" + Integer.toString(obj.hashCode(),16);
+               
+               /* Object.hashCode() can be override and may thow an exception */       
+               } catch (Exception ex) {
+                       return obj.getClass().getName();
+               }
+       }
+
+       /** 
+        * 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();
+       }
+
+}
diff --git a/weaver/src/org/aspectj/weaver/tools/CommonsTrace.java b/weaver/src/org/aspectj/weaver/tools/CommonsTrace.java
new file mode 100644 (file)
index 0000000..c030141
--- /dev/null
@@ -0,0 +1,57 @@
+/*******************************************************************************
+ * 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 org.aspectj.weaver.tools;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+
+public class CommonsTrace extends AbstractTrace {
+
+       private Log log;
+       private String className;
+       
+       public CommonsTrace (Class clazz) {
+               super(clazz);
+               this.log = LogFactory.getLog(clazz);
+               this.className = tracedClass.getName();
+       }
+       
+       public void enter(String methodName, Object thiz, Object[] args) {
+               if (log.isDebugEnabled()) {
+                       log.debug("> " + formatMessage(className, methodName, thiz, args));
+               }
+       }
+
+       public void enter(String methodName, Object thiz) {
+               if (log.isDebugEnabled()) {
+                       log.debug("> " + formatMessage(className, methodName, thiz, null));
+               }
+       }
+
+       public void exit(String methodName, Object ret) {
+               if (log.isDebugEnabled()) {
+                       log.debug("< " + formatMessage(className, methodName, ret, null));
+               }
+       }
+
+       public void exit(String methodName, Throwable th) {
+               if (log.isDebugEnabled()) {
+                       log.debug("< " + formatMessage(className, methodName, th, null));
+               }
+       }
+
+       public void exit(String methodName) {
+               if (log.isDebugEnabled()) {
+                       log.debug("< " + formatMessage(className, methodName, null, null));
+               }
+       }
+
+}
diff --git a/weaver/src/org/aspectj/weaver/tools/CommonsTraceFactory.java b/weaver/src/org/aspectj/weaver/tools/CommonsTraceFactory.java
new file mode 100644 (file)
index 0000000..296b1fd
--- /dev/null
@@ -0,0 +1,23 @@
+/*******************************************************************************
+ * 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 org.aspectj.weaver.tools;
+
+import org.apache.commons.logging.LogFactory;
+
+public class CommonsTraceFactory extends TraceFactory {
+
+       private LogFactory logFactory = LogFactory.getFactory();
+       
+       public Trace getTrace(Class clazz) {
+               return new CommonsTrace(clazz);
+       }
+
+}
diff --git a/weaver/src/org/aspectj/weaver/tools/DefaultTrace.java b/weaver/src/org/aspectj/weaver/tools/DefaultTrace.java
new file mode 100644 (file)
index 0000000..fdfc5e0
--- /dev/null
@@ -0,0 +1,68 @@
+/*******************************************************************************
+ * 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 org.aspectj.weaver.tools;
+
+public class DefaultTrace extends AbstractTrace {
+       
+       public DefaultTrace (Class clazz) {
+               super(clazz);
+       }
+       
+       public void enter (String methodName, Object thiz, Object[] args) {
+               if (tracingEnabled) {
+//                     println("> " + tracedClass.getName() + "." + methodName + " " + formatObj(thiz) + " " + formatArgs(args));
+                       println("> " + formatMessage(tracedClass.getName(),methodName,thiz,args));
+               }
+       }
+       
+       public void enter (String methodName, Object thiz) {
+               if (tracingEnabled) {
+//                     println("> " + tracedClass.getName() + "." + methodName + " " + formatObj(thiz));
+                       println("> " + formatMessage(tracedClass.getName(),methodName,thiz,null));
+               }
+       }
+
+       public void exit (String methodName, Object ret) {
+               if (tracingEnabled) {
+//                     println("< " + tracedClass.getName() + "." + methodName + " " + formatObj(ret));
+                       println("< " + formatMessage(tracedClass.getName(),methodName,ret,null));
+               }
+       }
+
+       public void exit (String methodName) {
+               if (tracingEnabled) {
+//                     println("< " + tracedClass.getName() + "." + methodName);
+                       println("< " + formatMessage(tracedClass.getName(),methodName,null,null));
+               }
+       }
+
+       public void exit(String methodName, Throwable th) {
+               exit(methodName,th);
+       }
+
+       /**
+        * Template method that allows choice of destination for output
+        * 
+        * @param s message to be traced
+        */
+       protected void println (String s) {
+               System.err.println(s);
+       }
+
+       private static boolean tracingEnabled = getBoolean("org.aspectj.weaver.tools.tracing",false);
+
+       private static boolean getBoolean (String name, boolean def) {
+               String defaultValue = String.valueOf(def);
+               String value = System.getProperty(name,defaultValue);
+               return Boolean.valueOf(value).booleanValue();
+       }
+
+}
diff --git a/weaver/src/org/aspectj/weaver/tools/Trace.java b/weaver/src/org/aspectj/weaver/tools/Trace.java
new file mode 100644 (file)
index 0000000..6337c60
--- /dev/null
@@ -0,0 +1,49 @@
+/*******************************************************************************
+ * 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 org.aspectj.weaver.tools;
+
+public interface Trace {
+
+       public void enter (String methodName, Object thiz, Object[] args);
+
+       public void enter (String methodName, Object thiz);
+
+       public void exit (String methodName, Object ret);
+
+       public void exit (String methodName, Throwable th);
+
+       public void exit (String methodName);
+
+       public void event (String methodName);
+
+       public void event (String methodName, Object thiz, Object[] args);
+       
+       public void info (String message);
+
+       public void warn (String message);
+
+       public void warn (String message, Throwable th);
+
+       public void error (String message);
+
+       public void error (String message, Throwable th);
+       
+       /*
+        * Convenience methods
+        */
+       public void enter (String methodName, Object thiz, Object arg);
+
+       public void enter (String methodName, Object thiz, boolean z);
+
+       public void exit (String methodName, boolean b);
+       
+       public boolean isTraceEnabled ();
+}
diff --git a/weaver/src/org/aspectj/weaver/tools/TraceFactory.java b/weaver/src/org/aspectj/weaver/tools/TraceFactory.java
new file mode 100644 (file)
index 0000000..d77b7e1
--- /dev/null
@@ -0,0 +1,42 @@
+/*******************************************************************************
+ * 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 org.aspectj.weaver.tools;
+
+import org.aspectj.util.LangUtil;
+
+public class TraceFactory {
+    
+    public static TraceFactory instance = new TraceFactory(); 
+    
+    public Trace getTrace (Class clazz) {
+       return new DefaultTrace(clazz);
+    }
+    
+    public static TraceFactory getTraceFactory () {
+       return instance;
+    }
+    
+    static {
+       try {
+                       if (LangUtil.is15VMOrGreater()) {
+                       Class factoryClass = Class.forName("org.aspectj.weaver.tools.Jdk14TraceFactory");
+                       instance = (TraceFactory)factoryClass.newInstance();
+                       } else {
+                       Class factoryClass = Class.forName("org.aspectj.weaver.tools.CommonsTraceFactory");
+                       instance = (TraceFactory)factoryClass.newInstance();
+                       }
+       }
+       catch (Exception ex) {
+       }
+//     System.out.println("TraceFactory.<clinit>() instance=" + instance);
+    }
+
+}
diff --git a/weaver/src/org/aspectj/weaver/tools/Traceable.java b/weaver/src/org/aspectj/weaver/tools/Traceable.java
new file mode 100644 (file)
index 0000000..957786e
--- /dev/null
@@ -0,0 +1,17 @@
+/*******************************************************************************
+ * 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 org.aspectj.weaver.tools;
+
+public interface Traceable {
+
+       public String toTraceString ();
+       
+}
index 1a637cfbc8b6312a4d0b5165abd9b76a477cd196..f62c7305e4f010e314ac518edffd6968c7f7db2b 100644 (file)
@@ -78,6 +78,8 @@ public class WeavingAdaptor {
        protected GeneratedClassHandler generatedClassHandler;
        protected Map generatedClasses = new HashMap(); /* String -> UnwovenClassFile */
 
+       private static Trace trace = TraceFactory.getTraceFactory().getTrace(WeavingAdaptor.class);
+
        protected WeavingAdaptor () {
        }
        
@@ -205,6 +207,7 @@ public class WeavingAdaptor {
         */
        public byte[] weaveClass (String name, byte[] bytes) throws IOException {
                if (enabled) {
+               if (trace.isTraceEnabled()) trace.enter("weaveClass",this,new Object[] {name,bytes});
 
                        if (shouldWeave(name, bytes)) {
                                info("weaving '" + name + "'");
@@ -217,6 +220,8 @@ public class WeavingAdaptor {
                        else {
                                info("not weaving '" + name + "'");
                        }
+
+                       if (trace.isTraceEnabled()) trace.exit("weaveClass",bytes);
                }
 
         return bytes;
diff --git a/weaver5/java5-src/org/aspectj/weaver/tools/Jdk14Trace.java b/weaver5/java5-src/org/aspectj/weaver/tools/Jdk14Trace.java
new file mode 100644 (file)
index 0000000..93d816d
--- /dev/null
@@ -0,0 +1,63 @@
+/*******************************************************************************
+ * 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 org.aspectj.weaver.tools;
+
+import java.util.logging.Level;
+import java.util.logging.Logger;
+
+public class Jdk14Trace extends AbstractTrace {
+
+       private Logger logger;
+       private String name;
+       
+       public Jdk14Trace (Class clazz) {
+               super(clazz);
+               this.name = clazz.getName();
+               this.logger = Logger.getLogger(name);
+       }
+       
+       public void enter(String methodName, Object thiz, Object[] args) {
+               if (logger.isLoggable(Level.FINE)) {
+                       logger.entering(name,methodName,formatObj(thiz));
+                       if (args != null && logger.isLoggable(Level.FINER)) {
+                               logger.entering(name,methodName,args);
+                       }                       
+               }
+       }
+
+       public void enter(String methodName, Object thiz) {
+               enter(methodName,thiz,null);
+       }
+
+       public void exit(String methodName, Object ret) {
+               if (logger.isLoggable(Level.FINE)) {
+                       logger.exiting(name,methodName,ret);
+               }
+       }
+
+       public void exit(String methodName, Throwable th) {
+               if (logger.isLoggable(Level.FINE)) {
+                       logger.exiting(name,methodName,th);
+               }
+       }
+
+       public void exit(String methodName) {
+               if (logger.isLoggable(Level.FINE)) {
+                       logger.exiting(name,methodName);
+               }
+       }
+
+       @Override
+       public boolean isTraceEnabled() {
+               return logger.isLoggable(Level.FINE);
+       }
+       
+}
diff --git a/weaver5/java5-src/org/aspectj/weaver/tools/Jdk14TraceFactory.java b/weaver5/java5-src/org/aspectj/weaver/tools/Jdk14TraceFactory.java
new file mode 100644 (file)
index 0000000..4043d1d
--- /dev/null
@@ -0,0 +1,20 @@
+/*******************************************************************************
+ * 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 org.aspectj.weaver.tools;
+
+public class Jdk14TraceFactory extends TraceFactory {
+
+       @Override
+       public Trace getTrace(Class clazz) {
+               return new Jdk14Trace(clazz);
+       }
+
+}
diff --git a/weaver5/testdata/logging.properties b/weaver5/testdata/logging.properties
new file mode 100644 (file)
index 0000000..fb96358
--- /dev/null
@@ -0,0 +1,59 @@
+############################################################
+#      Default Logging Configuration File
+#
+# You can use a different file by specifying a filename
+# with the java.util.logging.config.file system property.  
+# For example java -Djava.util.logging.config.file=myfile
+############################################################
+
+############################################################
+#      Global properties
+############################################################
+
+# "handlers" specifies a comma separated list of log Handler 
+# classes.  These handlers will be installed during VM startup.
+# Note that these classes must be on the system classpath.
+# By default we only configure a ConsoleHandler, which will only
+# show messages at the INFO and above levels.
+#handlers= java.util.logging.ConsoleHandler
+
+# To also add the FileHandler, use the following line instead.
+#handlers= java.util.logging.FileHandler, java.util.logging.ConsoleHandler
+handlers= java.util.logging.FileHandler
+
+# Default global logging level.
+# This specifies which kinds of events are logged across
+# all loggers.  For any given facility this global level
+# can be overriden by a facility specific level
+# Note that the ConsoleHandler also has a separate level
+# setting to limit messages printed to the console.
+.level= INFO
+
+############################################################
+# Handler specific properties.
+# Describes specific configuration info for Handlers.
+############################################################
+
+# default file output is in user's home directory.
+java.util.logging.FileHandler.pattern = %h/java%u.log
+#java.util.logging.FileHandler.limit = 50000
+java.util.logging.FileHandler.count = 1
+#java.util.logging.FileHandler.formatter = java.util.logging.XMLFormatter
+java.util.logging.FileHandler.formatter = java.util.logging.SimpleFormatter
+java.util.logging.FileHandler.level = FINER
+
+# Limit the message that are printed on the console to INFO and above.
+java.util.logging.ConsoleHandler.level = FINER
+java.util.logging.ConsoleHandler.formatter = java.util.logging.SimpleFormatter
+
+
+############################################################
+# Facility specific properties.
+# Provides extra control for each logger.
+############################################################
+
+# For example, set the com.xyz.foo logger to only log SEVERE
+# messages:
+#com.xyz.foo.level = SEVERE
+org.aspectj.weaver.level = FINER
+org.aspectj.weaver.loadtime.level = FINER