blob: 52217f880dcbcf06eacbeef3da09f94ff8805575 [file] [log] [blame]
/*******************************************************************************
* 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;
import java.lang.reflect.Array;
import java.net.URL;
import java.text.SimpleDateFormat;
import java.util.Collection;
import java.util.Date;
import java.util.regex.Pattern;
import org.aspectj.bridge.IMessage.Kind;
public abstract class AbstractTrace implements Trace {
private static final Pattern packagePrefixPattern = Pattern.compile("([^.])[^.]*(\\.)");
protected Class<?> tracedClass;
private static SimpleDateFormat timeFormat;
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);
/*
* Convenience methods
*/
public void enter (String methodName) {
enter(methodName,null,null);
}
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 void exit (String methodName, int i) {
exit(methodName,new Integer(i));
}
public void event (String methodName, Object thiz, Object arg) {
event(methodName,thiz,new Object[] { arg });
}
public void warn(String message) {
warn(message,null);
}
public void error(String message) {
error(message,null);
}
public void fatal (String message) {
fatal(message,null);
}
/*
* 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(formatClassName(className));
message.append(".").append(methodName);
if (thiz != null) message.append(" ").append(formatObj(thiz));
if (args != null) message.append(" ").append(formatArgs(args));
return message.toString();
}
/**
* @param className full dotted class name
* @return short version of class name with package collapse to initials
*/
private String formatClassName(String className) {
return packagePrefixPattern.matcher(className).replaceAll("$1.");
}
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();
}
private static String formatDate (Date date) {
if (timeFormat == null) {
timeFormat = new SimpleDateFormat("HH:mm:ss.SSS");
}
return timeFormat.format(date);
}
/**
* Format objects safely avoiding toString which can cause recursion,
* NullPointerExceptions or highly verbose results.
*
* @param obj parameter to be formatted
* @return the formatted 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
|| obj instanceof Kind
) return obj;
else if (obj.getClass().isArray()) {
return formatArray(obj);
}
else if (obj instanceof Collection) {
return formatCollection((Collection)obj);
}
else try {
// Classes can provide an alternative implementation of toString()
if (obj instanceof Traceable) {
return ((Traceable)obj).toTraceString();
}
// classname@hashcode
else return formatClassName(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() + ")";
}
/**
* 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();
}
protected Object[] formatObjects(Object[] args) {
for (int i = 0; i < args.length; i++) {
args[i] = formatObj(args[i]);
}
return args;
}
}