blob: f4612dabf686147463465b0dce213d7a54fe868b [file] [log] [blame]
/****************************************************************************
* Copyright (c) 2004 Composent, Inc. and others.
*
* This program and the accompanying materials are made
* available under the terms of the Eclipse Public License 2.0
* which is available at https://www.eclipse.org/legal/epl-2.0/
*
* Contributors: Composent, Inc. - initial API and implementation
*
* SPDX-License-Identifier: EPL-2.0
*****************************************************************************/
package org.eclipse.ecf.core.util;
import java.text.SimpleDateFormat;
import java.util.*;
import org.eclipse.ecf.internal.core.identity.Activator;
import org.eclipse.osgi.service.debug.DebugOptions;
/**
* A utility for tracing debug information. Provides a simple interface for
* filtering and generating trace output.
*
*/
public class Trace {
private static final boolean TRACEALL = Boolean
.getBoolean(System.getProperty("org.eclipse.ecf.core.util.traceAll", "false"));
private static final List<String> TRACE_BUNDLES = new ArrayList<String>();
static {
if (!TRACEALL) {
String tracePlugins = System.getProperty("org.eclipse.ecf.core.util.traceBundles");
if (tracePlugins != null)
try {
String[] plugins = tracePlugins.split(",");
TRACE_BUNDLES.addAll(Arrays.asList(plugins));
} catch (Exception e) {
System.err.println("Unexpected exception in Trace class static initializer");
e.printStackTrace(System.err);
}
}
}
/**
* private constructor for the static class.
*/
private Trace() {
super();
}
/**
* String containing an open parenthesis.
*
*/
protected static final String PARENTHESIS_OPEN = "("; //$NON-NLS-1$
/**
* String containing a close parenthesis.
*
*/
protected static final String PARENTHESIS_CLOSE = ")"; //$NON-NLS-1$
/**
* String containing TRACE
*
*/
protected static final String TRACE_STR = "TRACE"; //$NON-NLS-1$
/**
* Prefix for tracing the changing of values.
*
*/
protected static final String PREFIX_TRACING = "TRACING "; //$NON-NLS-1$
/**
* Prefix for tracing the changing of values.
*
*/
protected static final String PREFIX_CHANGING = "CHANGING "; //$NON-NLS-1$
/**
* Prefix for tracing the catching of throwables.
*
*/
protected static final String PREFIX_CATCHING = "CAUGHT "; //$NON-NLS-1$
/**
* Prefix for tracing the throwing of throwables.
*
*/
protected static final String PREFIX_THROWING = "THROWN "; //$NON-NLS-1$
/**
* Prefix for tracing the entering of methods.
*
*/
protected static final String PREFIX_ENTERING = "ENTERING "; //$NON-NLS-1$
/**
* Prefix for tracing the exiting of methods.
*
*/
protected static final String PREFIX_EXITING = "EXITING "; //$NON-NLS-1$
/**
* Separator for methods.
*
*/
protected static final String SEPARATOR_METHOD = "#"; //$NON-NLS-1$
/**
* Separator for parameters.
*
*/
protected static final String SEPARATOR_PARAMETER = ", "; //$NON-NLS-1$
/**
* Separator for return values.
*
*/
protected static final String SEPARATOR_RETURN = ":"; //$NON-NLS-1$
/**
* Separator containing a space.
*
*/
protected static final String SEPARATOR_SPACE = " "; //$NON-NLS-1$
/**
* Label indicating old value.
*
*/
protected static final String LABEL_OLD_VALUE = "old="; //$NON-NLS-1$
/**
* Label indicating new value.
*
*/
protected static final String LABEL_NEW_VALUE = "new="; //$NON-NLS-1$
/**
* The cached debug options (for optimization).
*/
private static final Map<String, Boolean> cachedOptions = new HashMap<String, Boolean>();
/**
* Retrieves a Boolean value indicating whether tracing is enabled for the
* specified plug-in.
*
* @return Whether tracing is enabled for the plug-in.
* @param pluginId The symbolic plugin id for which to determine trace
* enablement.
*
*/
protected static boolean shouldTrace(String pluginId) {
return shouldTrace0(pluginId + "/debug"); //$NON-NLS-1$
}
protected static boolean shouldTrace0(String option) {
if (option == null)
return false;
Activator activator = Activator.getDefault();
if (activator == null)
return false;
DebugOptions debugOptions = activator.getDebugOptions();
if (debugOptions == null)
return false;
String result = debugOptions.getOption(option);
return (result == null) ? false : result.equalsIgnoreCase("true"); //$NON-NLS-1$
}
/**
* Retrieves a Boolean value indicating whether tracing is enabled for the
* specified debug option of the specified plug-in.
*
* @return Whether tracing is enabled for the debug option of the plug-in.
* @param pluginId The plug-in for which to determine trace enablement.
* @param option The debug option for which to determine trace enablement.
*
*/
public static boolean shouldTrace(String pluginId, String option) {
if (pluginId == null)
return false;
if (TRACEALL || TRACE_BUNDLES.contains(pluginId))
return true;
if (shouldTrace(pluginId)) {
Boolean value = null;
synchronized (cachedOptions) {
value = cachedOptions.get(option);
if (null == value) {
value = shouldTrace0(option);
cachedOptions.put(option, value);
}
}
return value.booleanValue();
}
return false;
}
/**
* Retrieves a textual representation of the specified argument.
*
* @return A textual representation of the specified argument.
* @param argument The argument for which to retrieve a textual
* representation.
*
*/
public static String getArgumentString(Object argument) {
if (argument == null)
return "null"; //$NON-NLS-1$
if (argument instanceof byte[])
return getStringFromByteArray((byte[]) argument);
if (argument.getClass().isArray())
return getArgumentsString((Object[]) argument);
return String.valueOf(argument);
}
private static String getStringFromByteArray(byte[] bytes) {
StringBuilder buf = new StringBuilder("["); //$NON-NLS-1$
for (int i = 0; i < bytes.length; i++) {
buf.append(bytes[i]);
if (i == (bytes.length - 1))
buf.append("]"); //$NON-NLS-1$
else
buf.append(","); //$NON-NLS-1$
}
return buf.toString();
}
/**
* Retrieves a textual representation of the specified arguments.
*
* @return A textual representation of the specified arguments.
* @param arguments The arguments for which to retrieve a textual
* representation.
*
*/
public static String getArgumentsString(Object[] arguments) {
if (arguments == null)
return "[]"; //$NON-NLS-1$
StringBuilder buffer = new StringBuilder("["); //$NON-NLS-1$
for (int i = 0; i < arguments.length; i++) {
buffer.append(getArgumentString(arguments[i]));
if (i < arguments.length - 1)
buffer.append(SEPARATOR_PARAMETER);
}
buffer.append("]"); //$NON-NLS-1$
return buffer.toString();
}
/**
* Traces the specified message.
*
* @param message The message to be traced.
*
*/
protected static void trace(String message) {
StringBuilder buf = new StringBuilder(PARENTHESIS_OPEN);
buf.append(TRACE_STR).append(PARENTHESIS_CLOSE).append(getTimeString()).append(message).append(SEPARATOR_SPACE);
System.out.println(buf.toString());
}
/**
* Get date and time string
*
* @return String with current date and time
*/
protected static String getTimeString() {
Date d = new Date();
SimpleDateFormat df = new SimpleDateFormat("[MM/dd/yy;HH:mm:ss:SSS]"); //$NON-NLS-1$
return df.format(d);
}
/**
* Traces the specified message from the specified plug-in.
*
* @param pluginId The plug-in from which to trace.
* @param message The message to be traced.
*
*/
public static void trace(String pluginId, String message) {
if (shouldTrace(pluginId))
trace(message);
}
/**
* Traces the specified message from the specified plug-in for the specified
* debug option.
*
* @param pluginId The plug-in from which to trace.
* @param option The debug option for which to trace.
* @param message The message to be traced.
*
*/
public static void trace(String pluginId, String option, String message) {
if (shouldTrace(pluginId, option))
trace(message);
}
/**
* Traces the specified message from the specified plug-in for the specified
* debug option.
*
* @param pluginId The plug-in from which to trace.
* @param option The debug option for which to trace.
* @param clazz The class whose method is being entered.
* @param methodName The name of method that is being entered.
* @param message The message to be traced.
*
*/
public static void trace(String pluginId, String option, @SuppressWarnings("rawtypes") Class clazz,
String methodName, String message) {
if (shouldTrace(pluginId, option)) {
StringBuffer buf = new StringBuffer(PREFIX_TRACING).append(clazz.getName());
buf.append(SEPARATOR_METHOD).append(methodName);
buf.append(PARENTHESIS_OPEN).append(message).append(PARENTHESIS_CLOSE);
trace(buf.toString());
}
}
/**
* Traces the changing of a value.
*
* @param pluginId The plug-in from which to trace.
* @param option The debug option for which to trace.
* @param valueDescription The description of the value which is changing.
* @param oldValue The old value.
* @param newValue The new value.
*/
public static void changing(String pluginId, String option, String valueDescription, Object oldValue,
Object newValue) {
if (shouldTrace(pluginId, option)) {
StringBuilder buf = new StringBuilder(PREFIX_CHANGING);
buf.append(valueDescription).append(SEPARATOR_SPACE).append(LABEL_OLD_VALUE)
.append(getArgumentString(oldValue));
buf.append(SEPARATOR_PARAMETER).append(LABEL_NEW_VALUE).append(getArgumentString(newValue));
trace(buf.toString());
}
}
/**
*
* @param pluginId The plug-in from which to trace.
* @param option The debug option for which to trace.
* @param clazz The class in which the value is changing.
* @param methodName The name of the method in which the value is changing.
* @param valueDescription The description of the value which is changing.
* @param oldValue The old value.
* @param newValue The new value.
*/
public static void changing(String pluginId, String option, @SuppressWarnings("rawtypes") Class clazz,
String methodName, String valueDescription, Object oldValue, Object newValue) {
if (shouldTrace(pluginId, option)) {
StringBuilder buf = new StringBuilder(PREFIX_CHANGING);
buf.append(valueDescription).append(SEPARATOR_SPACE).append(LABEL_OLD_VALUE)
.append(getArgumentString(oldValue));
buf.append(SEPARATOR_PARAMETER).append(LABEL_NEW_VALUE).append(getArgumentString(newValue));
buf.append(SEPARATOR_SPACE).append(PARENTHESIS_OPEN).append(clazz.getName()).append(SEPARATOR_METHOD);
buf.append(methodName).append(PARENTHESIS_CLOSE);
trace(buf.toString());
}
}
/**
* Traces the catching of the specified throwable in the specified method of
* the specified class.
*
* @param pluginId The plug-in from which to trace.
* @param option The debug option for which to trace.
* @param clazz The class in which the throwable is being caught.
* @param methodName The name of the method in which the throwable is being
* caught.
* @param throwable The throwable that is being caught.
*
*/
public static void catching(String pluginId, String option, @SuppressWarnings("rawtypes") Class clazz,
String methodName, Throwable throwable) {
if (shouldTrace(pluginId, option)) {
StringBuilder buf = new StringBuilder(PREFIX_CATCHING);
if (throwable != null) {
String message = throwable.getMessage();
if (message != null)
buf.append(message).append(SEPARATOR_SPACE);
}
buf.append(PARENTHESIS_OPEN).append(clazz.getName()).append(SEPARATOR_METHOD);
buf.append(methodName).append(PARENTHESIS_CLOSE);
trace(buf.toString());
if (throwable != null) {
throwable.printStackTrace(System.err);
}
}
}
/**
* Traces the throwing of the specified throwable from the specified method
* of the specified class.
*
* @param pluginId The plug-in from which to trace.
* @param option The debug option for which to trace.
* @param clazz The class from which the throwable is being thrown.
* @param methodName The name of the method from which the throwable is
* being thrown.
* @param throwable The throwable that is being thrown.
*
*/
public static void throwing(String pluginId, String option, @SuppressWarnings("rawtypes") Class clazz,
String methodName, Throwable throwable) {
if (shouldTrace(pluginId, option)) {
StringBuilder buf = new StringBuilder(PREFIX_THROWING);
if (throwable != null) {
String message = throwable.getMessage();
if (message != null)
buf.append(message).append(SEPARATOR_SPACE);
}
buf.append(PARENTHESIS_OPEN).append(clazz.getName()).append(SEPARATOR_METHOD);
buf.append(methodName).append(PARENTHESIS_CLOSE);
trace(buf.toString());
throwable.printStackTrace(System.err);
}
}
/**
* Traces the entering into the specified method of the specified class.
*
* @param pluginId The plug-in from which to trace.
* @param option The debug option for which to trace.
* @param clazz The class whose method is being entered.
* @param methodName The name of method that is being entered.
*
*/
public static void entering(String pluginId, String option, @SuppressWarnings("rawtypes") Class clazz,
String methodName) {
if (shouldTrace(pluginId, option)) {
StringBuffer buf = new StringBuffer(PREFIX_ENTERING).append(clazz.getName());
buf.append(SEPARATOR_METHOD).append(methodName).append(PARENTHESIS_OPEN).append(PARENTHESIS_CLOSE);
trace(buf.toString());
}
}
/**
* Traces the entering into the specified method of the specified class,
* with the specified parameter.
*
* @param pluginId The plug-in from which to trace.
* @param option The debug option for which to trace.
* @param clazz The class whose method is being entered.
* @param methodName The name of method that is being entered.
* @param parameter The parameter to the method being entered.
*
*/
public static void entering(String pluginId, String option, @SuppressWarnings("rawtypes") Class clazz,
String methodName, Object parameter) {
if (shouldTrace(pluginId, option)) {
StringBuffer buf = new StringBuffer(PREFIX_ENTERING).append(clazz.getName());
buf.append(SEPARATOR_METHOD).append(methodName);
buf.append(PARENTHESIS_OPEN).append(getArgumentString(parameter)).append(PARENTHESIS_CLOSE);
trace(buf.toString());
}
}
/**
* Traces the entering into the specified method of the specified class,
* with the specified parameters.
*
* @param pluginId The plug-in from which to trace.
* @param option The debug option for which to trace.
* @param clazz The class whose method is being entered.
* @param methodName The name of method that is being entered.
* @param parameters The parameters to the method being entered.
*
*/
public static void entering(String pluginId, String option, @SuppressWarnings("rawtypes") Class clazz,
String methodName, Object[] parameters) {
if (shouldTrace(pluginId, option)) {
StringBuffer buf = new StringBuffer(PREFIX_ENTERING).append(clazz.getName());
buf.append(SEPARATOR_METHOD).append(methodName);
buf.append(PARENTHESIS_OPEN).append(getArgumentString(parameters)).append(PARENTHESIS_CLOSE);
trace(buf.toString());
}
}
/**
* Traces the exiting from the specified method of the specified class.
*
* @param pluginId The plug-in from which to trace.
* @param option The debug option for which to trace.
* @param clazz The class whose method is being exited.
* @param methodName The name of method that is being exited.
*
*/
public static void exiting(String pluginId, String option, @SuppressWarnings("rawtypes") Class clazz,
String methodName) {
if (shouldTrace(pluginId, option)) {
StringBuffer buf = new StringBuffer(PREFIX_EXITING).append(clazz.getName());
buf.append(SEPARATOR_METHOD).append(methodName);
trace(buf.toString());
}
}
/**
* Traces the exiting from the specified method of the specified class, with
* the specified return value.
*
* @param pluginId The plug-in from which to trace.
* @param option The debug option for which to trace.
* @param clazz The class whose method is being exited.
* @param methodName The name of method that is being exited.
* @param returnValue The return value of the method being exited.
*
*/
public static void exiting(String pluginId, String option, @SuppressWarnings("rawtypes") Class clazz,
String methodName, Object returnValue) {
if (shouldTrace(pluginId, option)) {
StringBuffer buf = new StringBuffer(PREFIX_EXITING).append(clazz.getName());
buf.append(SEPARATOR_METHOD).append(methodName);
buf.append(PARENTHESIS_OPEN).append(getArgumentString(returnValue)).append(PARENTHESIS_CLOSE);
trace(buf.toString());
}
}
}