1
0
Fork 0
mirror of https://github.com/eclipse-cdt/cdt synced 2025-08-08 08:45:44 +02:00

[288656] Add tracing for DsfSession

This commit is contained in:
John Cortell 2009-09-04 19:42:17 +00:00
parent 5df35e00b1
commit 7e8ee4c873
4 changed files with 124 additions and 2 deletions

View file

@ -40,7 +40,7 @@ Export-Package: org.eclipse.cdt.core,
org.eclipse.cdt.core.templateengine, org.eclipse.cdt.core.templateengine,
org.eclipse.cdt.core.templateengine.process, org.eclipse.cdt.core.templateengine.process,
org.eclipse.cdt.core.templateengine.process.processes, org.eclipse.cdt.core.templateengine.process.processes,
org.eclipse.cdt.internal.core;x-friends:="org.eclipse.cdt.ui,org.eclipse.cdt.debug.core", org.eclipse.cdt.internal.core;x-friends:="org.eclipse.cdt.ui,org.eclipse.cdt.debug.core,org.eclipse.cdt.dsf",
org.eclipse.cdt.internal.core.browser;x-friends:="org.eclipse.cdt.ui", org.eclipse.cdt.internal.core.browser;x-friends:="org.eclipse.cdt.ui",
org.eclipse.cdt.internal.core.cdtvariables;x-internal:=true, org.eclipse.cdt.internal.core.cdtvariables;x-internal:=true,
org.eclipse.cdt.internal.core.dom;x-friends:="org.eclipse.cdt.ui", org.eclipse.cdt.internal.core.dom;x-friends:="org.eclipse.cdt.ui",

View file

@ -0,0 +1,46 @@
/*******************************************************************************
* Copyright (c) 2009 Freescale Semiconductor, Inc. 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:
* Freescale Semiconductor - initial API and implementation
*******************************************************************************/
package org.eclipse.cdt.internal.core;
/**
* Some general purpose functions that can be useful for logging/tracing activities.
*
* @since 5.2
*/
public class LoggingUtils {
/**
* Return a string that uniquely identifies a Java object reference, in the form "classname@id", where
* 'classname' is the simple (unqualified) name of the object's class, and 'id' is the hash code. If the
* object is of an anonymous class, classname will be "<anonymous-class>".
*
* Why not just use obj.toString()? That method is often overriden, and so cannot be relied on for a
* representation that uniquely identifies the object in the VM space.
*
* @param obj
* the object reference to stringify
* @return the stringified representation of the object reference
*/
public static String toString(Object obj) {
if (obj == null) {
return "null"; //$NON-NLS-1$
}
String className = obj.getClass().getSimpleName();
if (className == null) {
className = "<anonymous-class>"; //$NON-NLS-1$
}
String id = Integer.toHexString(System.identityHashCode(obj));
return className + "@" + id; //$NON-NLS-1$
}
}

View file

@ -2,3 +2,6 @@ org.eclipse.cdt.dsf/debug = false
org.eclipse.cdt.dsf/debug/executor = false org.eclipse.cdt.dsf/debug/executor = false
org.eclipse.cdt.dsf/debug/executorName = org.eclipse.cdt.dsf/debug/executorName =
org.eclipse.cdt.dsf/debugCache = false org.eclipse.cdt.dsf/debugCache = false
org.eclipse.cdt.dsf/debug/session = false
org.eclipse.cdt.dsf/debug/session/listeners = false
org.eclipse.cdt.dsf/debug/session/dispatches = false

View file

@ -16,6 +16,7 @@ import java.util.ArrayList;
import java.util.Collections; import java.util.Collections;
import java.util.Comparator; import java.util.Comparator;
import java.util.Dictionary; import java.util.Dictionary;
import java.util.Formatter;
import java.util.HashMap; import java.util.HashMap;
import java.util.HashSet; import java.util.HashSet;
import java.util.List; import java.util.List;
@ -29,7 +30,9 @@ import org.eclipse.cdt.dsf.concurrent.DsfExecutor;
import org.eclipse.cdt.dsf.concurrent.DsfRunnable; import org.eclipse.cdt.dsf.concurrent.DsfRunnable;
import org.eclipse.cdt.dsf.concurrent.ThreadSafe; import org.eclipse.cdt.dsf.concurrent.ThreadSafe;
import org.eclipse.cdt.dsf.internal.DsfPlugin; import org.eclipse.cdt.dsf.internal.DsfPlugin;
import org.eclipse.cdt.internal.core.LoggingUtils;
import org.eclipse.core.runtime.IStatus; import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.Platform;
import org.eclipse.core.runtime.Status; import org.eclipse.core.runtime.Status;
import org.osgi.framework.Filter; import org.osgi.framework.Filter;
@ -54,6 +57,39 @@ import org.osgi.framework.Filter;
@ConfinedToDsfExecutor("getExecutor") @ConfinedToDsfExecutor("getExecutor")
public class DsfSession public class DsfSession
{ {
/**
* Has the "debug/session" tracing option been turned on? Requires "debug"
* to also be turned on.
*
* @since 2.1
*/
protected static final boolean DEBUG_SESSION;
/**
* Has the "debug/session/listeners" tracing option been turned on? Requires
* "debug/session" to also be turned on.
*
* @since 2.1
*/
protected static final boolean DEBUG_SESSION_LISTENERS;
/**
* Has the "debug/session/dispatches" tracing option been turned on? Requires
* "debug/session" to also be turned on.
*
* @since 2.1
*/
protected static final boolean DEBUG_SESSION_DISPATCHES;
static {
DEBUG_SESSION = DsfPlugin.DEBUG && "true".equals( //$NON-NLS-1$
Platform.getDebugOption("org.eclipse.cdt.dsf/debug/session")); //$NON-NLS-1$
DEBUG_SESSION_LISTENERS = DEBUG_SESSION && "true".equals( //$NON-NLS-1$
Platform.getDebugOption("org.eclipse.cdt.dsf/debug/session/listeners")); //$NON-NLS-1$
DEBUG_SESSION_DISPATCHES = DEBUG_SESSION && "true".equals( //$NON-NLS-1$
Platform.getDebugOption("org.eclipse.cdt.dsf/debug/session/dispatches")); //$NON-NLS-1$
}
/** /**
* Listener for session started events. This listener is always going to be * Listener for session started events. This listener is always going to be
* called in the dispatch thread of the session's executor. * called in the dispatch thread of the session's executor.
@ -248,6 +284,15 @@ public class DsfSession
public void addServiceEventListener(Object listener, Filter filter) { public void addServiceEventListener(Object listener, Filter filter) {
ListenerEntry entry = new ListenerEntry(listener, filter); ListenerEntry entry = new ListenerEntry(listener, filter);
assert !fListeners.containsKey(entry); assert !fListeners.containsKey(entry);
if (DEBUG_SESSION_LISTENERS) {
String msg = new Formatter().format(
"%s added as a service listener to %s (id=%s)", //$NON-NLS-1$
LoggingUtils.toString(listener),
LoggingUtils.toString(this),
getId()
).toString();
DsfPlugin.debug(msg);
}
fListeners.put(entry, getEventHandlerMethods(listener)); fListeners.put(entry, getEventHandlerMethods(listener));
} }
@ -258,6 +303,15 @@ public class DsfSession
public void removeServiceEventListener(Object listener) { public void removeServiceEventListener(Object listener) {
ListenerEntry entry = new ListenerEntry(listener, null); ListenerEntry entry = new ListenerEntry(listener, null);
assert fListeners.containsKey(entry); assert fListeners.containsKey(entry);
if (DEBUG_SESSION_LISTENERS) {
String msg = new Formatter().format(
"%s removed as a service listener to %s (id=%s)", //$NON-NLS-1$
LoggingUtils.toString(listener),
LoggingUtils.toString(this),
getId()
).toString();
DsfPlugin.debug(msg);
}
fListeners.remove(entry); fListeners.remove(entry);
} }
@ -374,6 +428,9 @@ public class DsfSession
for (Map.Entry<ListenerEntry,List<Method>> entry : listeners.entrySet()) { for (Map.Entry<ListenerEntry,List<Method>> entry : listeners.entrySet()) {
for (Method method : entry.getValue()) { for (Method method : entry.getValue()) {
try { try {
if (DEBUG_SESSION_DISPATCHES) {
DsfPlugin.debug("Listener " + LoggingUtils.toString(entry.getKey().fListener) + " invoked with event " + LoggingUtils.toString(event)); //$NON-NLS-1$ //$NON-NLS-2$
}
method.invoke(entry.getKey().fListener, new Object[] { event } ); method.invoke(entry.getKey().fListener, new Object[] { event } );
} }
catch (IllegalAccessException e) { catch (IllegalAccessException e) {
@ -390,6 +447,22 @@ public class DsfSession
} }
} }
/**
* DSF event handlers don't implement any particular interfaces. They
* declare one or more methods that are annotated with
* '@DsfServiceEventHandler', and which take a single event parameter. The
* type of the parameter indicates what events the handler is interested in.
* Any event that can be cast to that type (and which meets the optional
* filter provided when the listener is registered) will be sent to it.
*
* This method returns the methods annotated as handlers. Each method is
* checked to ensure it takes a single parameter; an
* {@link IllegalArgumentException} is thrown otherwise.
*
* @param listener
* an object which should contain handler methods
* @return the collection of handler methods
*/
private Method[] getEventHandlerMethods(Object listener) private Method[] getEventHandlerMethods(Object listener)
{ {
List<Method> retVal = new ArrayList<Method>(); List<Method> retVal = new ArrayList<Method>();