Initial Commit
[packages] / xemacs-packages / jde / java / src / jde / debugger / SessionManager.java
1 package jde.debugger;
2
3 import java.util.HashMap;
4 import java.util.Iterator;
5
6 import jde.debugger.command.CommandHandler;
7 import jde.debugger.command.SessionCommandHandler;
8
9
10 /**
11  * The session manager keeps track of which debugging sessions are
12  * currently active and handled by which debuggers. There is also a
13  * special debug command handler thread which is handled by the
14  * SessionManager ({@link #m_handler}). It's a singleton object that
15  * exposes only a set of static interface functions.
16  *
17  * <p>
18  * Created: Tue Jan 08 13:19:51 2002
19  *
20  * @author Petter Måhlén
21  * @version $Revision: 1.3 $
22  */
23
24 public class SessionManager implements Protocol {
25   /**
26    * The mappings of process ID/debugger that are handled by JDEbug.
27    * Not synchronized, because it is only accessed from methods defined
28    * in this file, and these methods are (and must remain) synchronized.
29    */
30   private HashMap               m_debuggers;
31   private SessionCommandHandler m_handler;
32
33   private static SessionManager s_theManager   = new SessionManager();
34   private static long           s_nextObjectID = 0;
35
36   /**
37    * Creates a new <code>SessionManager</code> instance and starts
38    * up the {@link #m_handler} session command handler thread.
39    *
40    */
41   private SessionManager() {
42     m_debuggers = new HashMap();
43     m_handler   = new SessionCommandHandler();
44     m_handler.start();
45   }
46
47   private synchronized CommandHandler p_getCommandHandler(Integer procID)
48     throws JDEException {
49
50     // special hack for the session command handler
51     if (procID.equals(JDEbug.debuggerID)) {
52       return m_handler;
53     }
54
55     Debugger debugger = (Debugger) m_debuggers.get(procID);
56
57     if (debugger == null) {
58       throw new JDEException("No process with id " + procID + " found");
59     }
60
61     return debugger.getCommandHandler();
62   }
63
64   private synchronized Debugger p_getDebugger(Integer procID)
65     throws JDEException {
66
67     Debugger debugger = (Debugger) m_debuggers.get(procID);
68
69     if (debugger == null) {
70       throw new JDEException("No debugger for process id " + procID + " found");
71     }
72
73     return debugger;
74   }
75
76   private synchronized void p_registerDebugger(Debugger debugger) throws JDEException {
77     Integer procID = debugger.getProcID();
78
79     if (m_debuggers.containsKey(procID)) {
80       throw new JDEException("registerDebugger: A process with id " + procID + " already exists!");
81     }
82
83     m_debuggers.put(procID, debugger);
84     JDE.debug(EVENTS, "registered debugger with procid: " + procID);
85   }
86
87
88   private synchronized void p_deregisterDebugger(Debugger debugger) throws JDEException {
89     Integer procID = debugger.getProcID();
90
91     if (null != m_debuggers) {
92       if (!m_debuggers.containsKey(procID)) {
93         // XXX - sort of doubtful whether I should really throw an exception here,
94         // but it's generally best to be strict with incorrect usage.
95         throw new JDEException("deregisterDebugger: No process with id " + procID + " exists!");
96       }
97
98       if (debugger.isValid()) {
99         throw new JDEException("INTERNAL ERROR: an attempt was made at deregistering a valid debugger. The debugger must be shut down first.");
100       }
101
102       m_debuggers.remove(procID);
103     }
104     JDE.debug(EVENTS, "removed debugger with procid: " + procID);
105   }
106
107
108   private synchronized void p_shutdown() {
109     if (m_handler != null) {
110       m_handler.requestStop();
111     }
112
113     if (m_debuggers != null) {
114       Iterator iter = m_debuggers.values().iterator();
115
116       while (iter.hasNext()) {
117         Debugger dbgr = (Debugger) iter.next();
118
119         try {
120           dbgr.shutdown();
121         }
122         catch (JDEException e) {
123           JDE.signal(dbgr.getProcID(), Protocol.ERROR,
124                      "SessionManager.p_shutdown() caught exception when shutting down debugger: " + e,
125                      QUOTE);
126         }
127       }
128     }
129
130     // Invalidate the object
131     if (null != m_debuggers)
132       m_debuggers.clear();
133     m_debuggers = null;
134     m_handler   = null;
135   }
136
137   /*
138    * PUBLIC, STATIC INTERFACE -----------------------------------------------------
139    */
140
141
142   /**
143    * Returns the command handler for a given process ID. Note that
144    * it doesn't return the Debugger object, but its command handler.
145    *
146    * @param procID an <code>Integer</code> value
147    * @return a <code>CommandHandler</code> value
148    * @exception JDEException if there is no registered debugger for
149    * the given process ID
150    * @see jde.debugger.command.ProcessCommandHandler
151    * @see Debugger
152    */
153   public static CommandHandler getCommandHandler(Integer procID) throws JDEException {
154     return s_theManager.p_getCommandHandler(procID);
155   }
156
157   /**
158    * Returns the Debugger object for a given process ID.
159    *
160    * @param procID an <code>Integer</code> value
161    * @return a <code>Debugger</code> value
162    * @exception JDEException if there is no registered debugger for
163    * the given process ID
164    * @see Debugger
165    */
166   public static Debugger getDebugger(Integer procID) throws JDEException {
167     return s_theManager.p_getDebugger(procID);
168   }
169
170   /**
171    * Registers the given Debugger as active. When this is done, it
172    * is possible to retrieve the Debugger and its CommandHandler
173    * through the {@link #getDebugger} and {@link #getCommandHandler}
174    * methods.
175    *
176    * @param debugger a <code>Debugger</code> value
177    * @exception JDEException if there is already a registered
178    * debugger with the same process ID.
179    */
180   public static void registerDebugger(Debugger debugger) throws JDEException {
181     s_theManager.p_registerDebugger(debugger);
182   }
183
184   /**
185    * Deregisters the given debugger.
186    *
187    * @param debugger a <code>Debugger</code> value
188    * @exception JDEException if the debugger hasn't been registered
189    * previously, or if the debugger is still valid, as indicated by
190    * the {@link Debugger#isValid} method.
191    */
192   public static void deregisterDebugger(Debugger debugger) throws JDEException {
193     s_theManager.p_deregisterDebugger(debugger);
194   }
195
196   /**
197    * Shuts down the SessionManager, by first shutting down each
198    * registered Debugger, and then shutting down the session command
199    * handler. After the shutdown, this object is no longer possible
200    * to use.
201    */
202   public static void shutdown() {
203     s_theManager.p_shutdown();
204   }
205
206   /**
207    * Generates a unique number with each call (unique for each time
208    * that this class is loaded, not in any wider sense).
209    *
210    * @return a <code>Long</code> value
211    */
212   public static synchronized Long generateObjectID() {
213     return new Long(s_nextObjectID++);
214   }
215 }// SessionManager
216
217 /*
218  * $Log: SessionManager.java,v $
219  * Revision 1.3  2003/04/29 16:51:57  troy
220  * Initial version of GUI.  Includes display of local variables.
221  *
222  * Revision 1.2  2003/01/15 05:50:51  paulk
223  * Remove CRs.
224  *
225  * Revision 1.1  2003/01/08 07:16:45  paulk
226  * Initial revision.
227  *
228  */
229