package jde.debugger; import java.util.HashMap; import java.util.Iterator; import jde.debugger.command.CommandHandler; import jde.debugger.command.SessionCommandHandler; /** * The session manager keeps track of which debugging sessions are * currently active and handled by which debuggers. There is also a * special debug command handler thread which is handled by the * SessionManager ({@link #m_handler}). It's a singleton object that * exposes only a set of static interface functions. * *
* Created: Tue Jan 08 13:19:51 2002
*
* @author Petter Måhlén
* @version $Revision: 1.3 $
*/
public class SessionManager implements Protocol {
/**
* The mappings of process ID/debugger that are handled by JDEbug.
* Not synchronized, because it is only accessed from methods defined
* in this file, and these methods are (and must remain) synchronized.
*/
private HashMap m_debuggers;
private SessionCommandHandler m_handler;
private static SessionManager s_theManager = new SessionManager();
private static long s_nextObjectID = 0;
/**
* Creates a new SessionManager
instance and starts
* up the {@link #m_handler} session command handler thread.
*
*/
private SessionManager() {
m_debuggers = new HashMap();
m_handler = new SessionCommandHandler();
m_handler.start();
}
private synchronized CommandHandler p_getCommandHandler(Integer procID)
throws JDEException {
// special hack for the session command handler
if (procID.equals(JDEbug.debuggerID)) {
return m_handler;
}
Debugger debugger = (Debugger) m_debuggers.get(procID);
if (debugger == null) {
throw new JDEException("No process with id " + procID + " found");
}
return debugger.getCommandHandler();
}
private synchronized Debugger p_getDebugger(Integer procID)
throws JDEException {
Debugger debugger = (Debugger) m_debuggers.get(procID);
if (debugger == null) {
throw new JDEException("No debugger for process id " + procID + " found");
}
return debugger;
}
private synchronized void p_registerDebugger(Debugger debugger) throws JDEException {
Integer procID = debugger.getProcID();
if (m_debuggers.containsKey(procID)) {
throw new JDEException("registerDebugger: A process with id " + procID + " already exists!");
}
m_debuggers.put(procID, debugger);
JDE.debug(EVENTS, "registered debugger with procid: " + procID);
}
private synchronized void p_deregisterDebugger(Debugger debugger) throws JDEException {
Integer procID = debugger.getProcID();
if (null != m_debuggers) {
if (!m_debuggers.containsKey(procID)) {
// XXX - sort of doubtful whether I should really throw an exception here,
// but it's generally best to be strict with incorrect usage.
throw new JDEException("deregisterDebugger: No process with id " + procID + " exists!");
}
if (debugger.isValid()) {
throw new JDEException("INTERNAL ERROR: an attempt was made at deregistering a valid debugger. The debugger must be shut down first.");
}
m_debuggers.remove(procID);
}
JDE.debug(EVENTS, "removed debugger with procid: " + procID);
}
private synchronized void p_shutdown() {
if (m_handler != null) {
m_handler.requestStop();
}
if (m_debuggers != null) {
Iterator iter = m_debuggers.values().iterator();
while (iter.hasNext()) {
Debugger dbgr = (Debugger) iter.next();
try {
dbgr.shutdown();
}
catch (JDEException e) {
JDE.signal(dbgr.getProcID(), Protocol.ERROR,
"SessionManager.p_shutdown() caught exception when shutting down debugger: " + e,
QUOTE);
}
}
}
// Invalidate the object
if (null != m_debuggers)
m_debuggers.clear();
m_debuggers = null;
m_handler = null;
}
/*
* PUBLIC, STATIC INTERFACE -----------------------------------------------------
*/
/**
* Returns the command handler for a given process ID. Note that
* it doesn't return the Debugger object, but its command handler.
*
* @param procID an Integer
value
* @return a CommandHandler
value
* @exception JDEException if there is no registered debugger for
* the given process ID
* @see jde.debugger.command.ProcessCommandHandler
* @see Debugger
*/
public static CommandHandler getCommandHandler(Integer procID) throws JDEException {
return s_theManager.p_getCommandHandler(procID);
}
/**
* Returns the Debugger object for a given process ID.
*
* @param procID an Integer
value
* @return a Debugger
value
* @exception JDEException if there is no registered debugger for
* the given process ID
* @see Debugger
*/
public static Debugger getDebugger(Integer procID) throws JDEException {
return s_theManager.p_getDebugger(procID);
}
/**
* Registers the given Debugger as active. When this is done, it
* is possible to retrieve the Debugger and its CommandHandler
* through the {@link #getDebugger} and {@link #getCommandHandler}
* methods.
*
* @param debugger a Debugger
value
* @exception JDEException if there is already a registered
* debugger with the same process ID.
*/
public static void registerDebugger(Debugger debugger) throws JDEException {
s_theManager.p_registerDebugger(debugger);
}
/**
* Deregisters the given debugger.
*
* @param debugger a Debugger
value
* @exception JDEException if the debugger hasn't been registered
* previously, or if the debugger is still valid, as indicated by
* the {@link Debugger#isValid} method.
*/
public static void deregisterDebugger(Debugger debugger) throws JDEException {
s_theManager.p_deregisterDebugger(debugger);
}
/**
* Shuts down the SessionManager, by first shutting down each
* registered Debugger, and then shutting down the session command
* handler. After the shutdown, this object is no longer possible
* to use.
*/
public static void shutdown() {
s_theManager.p_shutdown();
}
/**
* Generates a unique number with each call (unique for each time
* that this class is loaded, not in any wider sense).
*
* @return a Long
value
*/
public static synchronized Long generateObjectID() {
return new Long(s_nextObjectID++);
}
}// SessionManager
/*
* $Log: SessionManager.java,v $
* Revision 1.3 2003/04/29 16:51:57 troy
* Initial version of GUI. Includes display of local variables.
*
* Revision 1.2 2003/01/15 05:50:51 paulk
* Remove CRs.
*
* Revision 1.1 2003/01/08 07:16:45 paulk
* Initial revision.
*
*/