|
|
@@ -12,20 +12,24 @@ |
|
|
|
package org.aspectj.weaver; |
|
|
|
|
|
|
|
import java.io.File; |
|
|
|
import java.io.FileNotFoundException; |
|
|
|
import java.io.FileOutputStream; |
|
|
|
import java.io.PrintStream; |
|
|
|
import java.net.URL; |
|
|
|
import java.text.SimpleDateFormat; |
|
|
|
import java.util.Date; |
|
|
|
import java.util.HashMap; |
|
|
|
import java.util.Iterator; |
|
|
|
import java.util.List; |
|
|
|
import java.util.Map; |
|
|
|
import java.util.Properties; |
|
|
|
import java.util.Set; |
|
|
|
import java.util.WeakHashMap; |
|
|
|
|
|
|
|
import org.aspectj.bridge.IMessage; |
|
|
|
import org.aspectj.bridge.IMessageHolder; |
|
|
|
import org.aspectj.bridge.Version; |
|
|
|
import org.aspectj.weaver.tools.Trace; |
|
|
|
import org.aspectj.weaver.tools.TraceFactory; |
|
|
|
import org.aspectj.weaver.tools.Traceable; |
|
|
|
|
|
|
|
/** |
|
|
|
* @author websterm |
|
|
@@ -35,6 +39,9 @@ import org.aspectj.bridge.Version; |
|
|
|
*/ |
|
|
|
public class Dump { |
|
|
|
|
|
|
|
public final static String DUMP_CONDITION_PROPERTY = "org.aspectj.weaver.Dump.condition"; |
|
|
|
public final static String DUMP_DIRECTORY_PROPERTY = "org.aspectj.dump.directory"; |
|
|
|
|
|
|
|
/* Format for unique filename based on date & time */ |
|
|
|
private static final String FILENAME_PREFIX = "ajcore"; |
|
|
|
// private static final DateFormat dateFormat = new SimpleDateFormat("yyyyMMdd"); |
|
|
@@ -47,6 +54,7 @@ public class Dump { |
|
|
|
|
|
|
|
private static Class exceptionClass; |
|
|
|
private static IMessage.Kind conditionKind = IMessage.ABORT; |
|
|
|
private static File directory = new File("."); |
|
|
|
|
|
|
|
private String reason; |
|
|
|
private String fileName; |
|
|
@@ -56,11 +64,13 @@ public class Dump { |
|
|
|
private static List savedFullClasspath; |
|
|
|
private static IMessageHolder savedMessageHolder; |
|
|
|
|
|
|
|
private static Map nodes = new HashMap(); |
|
|
|
private static Map nodes = new WeakHashMap(); |
|
|
|
private static String lastDumpFileName = UNKNOWN_FILENAME; |
|
|
|
|
|
|
|
private static boolean preserveOnNextReset = false; |
|
|
|
|
|
|
|
private static Trace trace = TraceFactory.getTraceFactory().getTrace(Dump.class); |
|
|
|
|
|
|
|
/** |
|
|
|
* for testing only, so that we can verify dump contents |
|
|
|
* after compilation has completely finished |
|
|
@@ -75,8 +85,8 @@ public class Dump { |
|
|
|
return; |
|
|
|
} |
|
|
|
else { |
|
|
|
Dump.nodes = new HashMap(); |
|
|
|
Dump.savedMessageHolder = null; |
|
|
|
nodes.clear(); |
|
|
|
savedMessageHolder = null; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
@@ -99,37 +109,63 @@ public class Dump { |
|
|
|
} |
|
|
|
|
|
|
|
public static String dumpWithException (Throwable th) { |
|
|
|
return dumpWithException(savedMessageHolder,th); |
|
|
|
} |
|
|
|
|
|
|
|
public static String dumpWithException (IMessageHolder messageHolder, Throwable th) { |
|
|
|
if (trace.isTraceEnabled()) trace.enter("dumpWithException",null,new Object[] {messageHolder, th}); |
|
|
|
|
|
|
|
String fileName = UNKNOWN_FILENAME; |
|
|
|
Dump dump = null; |
|
|
|
try { |
|
|
|
dump = new Dump(th.getClass().getName()); |
|
|
|
fileName = dump.getFileName(); |
|
|
|
dump.dumpException(th); |
|
|
|
dump.dumpException(messageHolder,th); |
|
|
|
} |
|
|
|
finally { |
|
|
|
if (dump != null) dump.close(); |
|
|
|
} |
|
|
|
|
|
|
|
if (trace.isTraceEnabled()) trace.exit("dumpWithException",fileName); |
|
|
|
return fileName; |
|
|
|
} |
|
|
|
|
|
|
|
public static String dumpOnExit () { |
|
|
|
if (!shouldDumpOnExit()) return DUMP_EXCLUDED; |
|
|
|
|
|
|
|
return dumpOnExit(savedMessageHolder, false); |
|
|
|
} |
|
|
|
|
|
|
|
public static String dumpOnExit (IMessageHolder messageHolder, boolean reset) { |
|
|
|
if (trace.isTraceEnabled()) trace.enter("dumpOnExit",null,messageHolder); |
|
|
|
String fileName = UNKNOWN_FILENAME; |
|
|
|
Dump dump = null; |
|
|
|
try { |
|
|
|
dump = new Dump(conditionKind.toString()); |
|
|
|
fileName = dump.getFileName(); |
|
|
|
dump.dumpDefault(); |
|
|
|
|
|
|
|
if (!shouldDumpOnExit(messageHolder)) { |
|
|
|
fileName = DUMP_EXCLUDED; |
|
|
|
} |
|
|
|
finally { |
|
|
|
if (dump != null) dump.close(); |
|
|
|
else { |
|
|
|
Dump dump = null; |
|
|
|
try { |
|
|
|
dump = new Dump(conditionKind.toString()); |
|
|
|
fileName = dump.getFileName(); |
|
|
|
dump.dumpDefault(messageHolder); |
|
|
|
} |
|
|
|
finally { |
|
|
|
if (dump != null) dump.close(); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
if (reset) messageHolder.clearMessages(); |
|
|
|
|
|
|
|
if (trace.isTraceEnabled()) trace.exit("dumpOnExit",fileName); |
|
|
|
return fileName; |
|
|
|
} |
|
|
|
|
|
|
|
private static boolean shouldDumpOnExit () { |
|
|
|
return (savedMessageHolder == null) || savedMessageHolder.hasAnyMessage(conditionKind,true); |
|
|
|
private static boolean shouldDumpOnExit (IMessageHolder messageHolder) { |
|
|
|
if (trace.isTraceEnabled()) trace.enter("shouldDumpOnExit",null,messageHolder); |
|
|
|
if (trace.isTraceEnabled()) trace.event("shouldDumpOnExit",null,conditionKind); |
|
|
|
boolean result = (messageHolder == null) || messageHolder.hasAnyMessage(conditionKind,true); |
|
|
|
|
|
|
|
if (trace.isTraceEnabled()) trace.exit("shouldDumpOnExit",result); |
|
|
|
return result; |
|
|
|
} |
|
|
|
|
|
|
|
/* |
|
|
@@ -144,11 +180,28 @@ public class Dump { |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
public static boolean setDumpDirectory (String directoryName) { |
|
|
|
if (trace.isTraceEnabled()) trace.enter("setDumpDirectory",null,directoryName); |
|
|
|
boolean success = false; |
|
|
|
|
|
|
|
File newDirectory = new File(directoryName); |
|
|
|
if (newDirectory.exists()) { |
|
|
|
directory = newDirectory; |
|
|
|
success = true; |
|
|
|
} |
|
|
|
|
|
|
|
if (trace.isTraceEnabled()) trace.exit("setDumpDirectory",success); |
|
|
|
return success; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
public static boolean getDumpOnException () { |
|
|
|
return (exceptionClass != null); |
|
|
|
} |
|
|
|
|
|
|
|
public static boolean setDumpOnExit (IMessage.Kind condition) { |
|
|
|
if (trace.isTraceEnabled()) trace.event("setDumpOnExit",null,condition); |
|
|
|
|
|
|
|
conditionKind = condition; |
|
|
|
return true; |
|
|
|
} |
|
|
@@ -188,18 +241,26 @@ public class Dump { |
|
|
|
} |
|
|
|
|
|
|
|
public static void registerNode (Class module, INode newNode) { |
|
|
|
nodes.put(module,newNode); |
|
|
|
if (trace.isTraceEnabled()) trace.enter("registerNode",null,new Object[] { module, newNode} ); |
|
|
|
|
|
|
|
nodes.put(newNode,newNode); |
|
|
|
|
|
|
|
if (trace.isTraceEnabled()) trace.exit("registerNode",nodes.size()); |
|
|
|
} |
|
|
|
|
|
|
|
/* |
|
|
|
* Dump methods |
|
|
|
*/ |
|
|
|
private Dump (String reason) { |
|
|
|
if (trace.isTraceEnabled()) trace.enter("<init>",this,reason); |
|
|
|
|
|
|
|
this.reason = reason; |
|
|
|
|
|
|
|
openDump(); |
|
|
|
dumpAspectJProperties(); |
|
|
|
dumpDumpConfiguration(); |
|
|
|
|
|
|
|
if (trace.isTraceEnabled()) trace.exit("<init>",this); |
|
|
|
} |
|
|
|
|
|
|
|
public String getFileName() { |
|
|
@@ -207,41 +268,51 @@ public class Dump { |
|
|
|
} |
|
|
|
|
|
|
|
private void dumpDefault () { |
|
|
|
dumpDefault(savedMessageHolder); |
|
|
|
} |
|
|
|
|
|
|
|
private void dumpDefault (IMessageHolder holder) { |
|
|
|
dumpSytemProperties(); |
|
|
|
dumpCommandLine(); |
|
|
|
dumpFullClasspath(); |
|
|
|
dumpCompilerMessages(); |
|
|
|
dumpCompilerMessages(holder); |
|
|
|
|
|
|
|
dumpNodes(); |
|
|
|
} |
|
|
|
|
|
|
|
private void dumpNodes() { |
|
|
|
|
|
|
|
/* |
|
|
|
* Dump registered nodes |
|
|
|
*/ |
|
|
|
IVisitor dumpVisitor = new IVisitor() { |
|
|
|
|
|
|
|
public void visitString (String s) { |
|
|
|
println(s); |
|
|
|
public void visitObject (Object obj) { |
|
|
|
println(formatObj(obj)); |
|
|
|
} |
|
|
|
|
|
|
|
public void visitList (List list) { |
|
|
|
println(list); |
|
|
|
} |
|
|
|
}; |
|
|
|
for (Iterator i = nodes.keySet().iterator(); i.hasNext();) { |
|
|
|
Class module = (Class)i.next(); |
|
|
|
println("---- " + module.getName() + " ----"); |
|
|
|
Set keys = nodes.keySet(); |
|
|
|
for (Iterator i = keys.iterator(); i.hasNext();) { |
|
|
|
Object module = i.next(); |
|
|
|
INode dumpNode = (INode)nodes.get(module); |
|
|
|
println("---- " + formatObj(dumpNode) + " ----"); |
|
|
|
try { |
|
|
|
dumpNode.accept(dumpVisitor); |
|
|
|
} |
|
|
|
catch (Exception ex) { |
|
|
|
println(ex.toString()); |
|
|
|
trace.error(formatObj(dumpNode).toString(),ex); |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
private void dumpException (Throwable th) { |
|
|
|
private void dumpException (IMessageHolder messageHolder, Throwable th) { |
|
|
|
println("---- Exception Information ---"); |
|
|
|
println(th); |
|
|
|
dumpDefault(); |
|
|
|
dumpDefault(messageHolder); |
|
|
|
} |
|
|
|
|
|
|
|
private void dumpAspectJProperties () { |
|
|
@@ -282,9 +353,9 @@ public class Dump { |
|
|
|
println(savedCommandLine); |
|
|
|
} |
|
|
|
|
|
|
|
private void dumpCompilerMessages () { |
|
|
|
private void dumpCompilerMessages (IMessageHolder messageHolder) { |
|
|
|
println("---- Compiler Messages ---"); |
|
|
|
if (savedMessageHolder != null) for (Iterator i = savedMessageHolder.getUnmodifiableListView().iterator(); i.hasNext(); ) { |
|
|
|
if (messageHolder != null) for (Iterator i = messageHolder.getUnmodifiableListView().iterator(); i.hasNext(); ) { |
|
|
|
IMessage message = (IMessage)i.next(); |
|
|
|
println(message.toString()); |
|
|
|
} |
|
|
@@ -305,12 +376,13 @@ public class Dump { |
|
|
|
+ new SimpleDateFormat("HHmmss.SSS").format(now) + "." |
|
|
|
+ FILENAME_SUFFIX; |
|
|
|
try { |
|
|
|
print = new PrintStream(new FileOutputStream(fileName),true); |
|
|
|
// System.out.println("Dumping to " + fileName); |
|
|
|
File file = new File(directory,fileName); |
|
|
|
print = new PrintStream(new FileOutputStream(file),true); |
|
|
|
trace.info("Dumping to " + file.getAbsolutePath()); |
|
|
|
} |
|
|
|
catch (FileNotFoundException ex) { |
|
|
|
catch (Exception ex) { |
|
|
|
print = System.err; |
|
|
|
System.out.println("Dumping to stderr"); |
|
|
|
trace.info("Dumping to stderr"); |
|
|
|
fileName = UNKNOWN_FILENAME; |
|
|
|
} |
|
|
|
|
|
|
@@ -321,8 +393,8 @@ public class Dump { |
|
|
|
print.close(); |
|
|
|
} |
|
|
|
|
|
|
|
private void println (String s) { |
|
|
|
print.println(s); |
|
|
|
private void println (Object obj) { |
|
|
|
print.println(obj); |
|
|
|
} |
|
|
|
|
|
|
|
private void println (Object[] array) { |
|
|
@@ -375,12 +447,46 @@ public class Dump { |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
private static 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 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.toHexString(System.identityHashCode(obj)); |
|
|
|
|
|
|
|
/* Object.hashCode() can be override and may thow an exception */ |
|
|
|
} catch (Exception ex) { |
|
|
|
return obj.getClass().getName() + "@FFFFFFFF"; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
static { |
|
|
|
String exceptionName = System.getProperty("org.aspectj.weaver.Dump.exception","true"); |
|
|
|
if (!exceptionName.equals("false")) setDumpOnException(true); |
|
|
|
|
|
|
|
String conditionName = System.getProperty("org.aspectj.weaver.Dump.condition","true"); |
|
|
|
setDumpOnExit(conditionName); |
|
|
|
String conditionName = System.getProperty(DUMP_CONDITION_PROPERTY); |
|
|
|
if (conditionName != null) setDumpOnExit(conditionName); |
|
|
|
|
|
|
|
String directoryName = System.getProperty(DUMP_DIRECTORY_PROPERTY); |
|
|
|
if (directoryName != null) setDumpDirectory(directoryName); |
|
|
|
} |
|
|
|
|
|
|
|
public interface INode { |
|
|
@@ -391,7 +497,7 @@ public class Dump { |
|
|
|
|
|
|
|
public interface IVisitor { |
|
|
|
|
|
|
|
public void visitString (String s); |
|
|
|
public void visitObject (Object s); |
|
|
|
public void visitList (List list); |
|
|
|
} |
|
|
|
|