KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > com > sun > tools > example > debug > gui > ContextManager


1 /*
2  * @(#)ContextManager.java 1.16 05/11/17
3  *
4  * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
5  * SUN PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
6  */

7 /*
8  * Copyright (c) 1997-1999 by Sun Microsystems, Inc. All Rights Reserved.
9  *
10  * Sun grants you ("Licensee") a non-exclusive, royalty free, license to use,
11  * modify and redistribute this software in source and binary code form,
12  * provided that i) this copyright notice and license appear on all copies of
13  * the software; and ii) Licensee does not utilize the software in a manner
14  * which is disparaging to Sun.
15  *
16  * This software is provided "AS IS," without a warranty of any kind. ALL
17  * EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES, INCLUDING ANY
18  * IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE OR
19  * NON-INFRINGEMENT, ARE HEREBY EXCLUDED. SUN AND ITS LICENSORS SHALL NOT BE
20  * LIABLE FOR ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING
21  * OR DISTRIBUTING THE SOFTWARE OR ITS DERIVATIVES. IN NO EVENT WILL SUN OR ITS
22  * LICENSORS BE LIABLE FOR ANY LOST REVENUE, PROFIT OR DATA, OR FOR DIRECT,
23  * INDIRECT, SPECIAL, CONSEQUENTIAL, INCIDENTAL OR PUNITIVE DAMAGES, HOWEVER
24  * CAUSED AND REGARDLESS OF THE THEORY OF LIABILITY, ARISING OUT OF THE USE OF
25  * OR INABILITY TO USE SOFTWARE, EVEN IF SUN HAS BEEN ADVISED OF THE
26  * POSSIBILITY OF SUCH DAMAGES.
27  *
28  * This software is not designed or intended for use in on-line control of
29  * aircraft, air traffic, aircraft navigation or aircraft communications; or in
30  * the design, construction, operation or maintenance of any nuclear
31  * facility. Licensee represents and warrants that it will not use or
32  * redistribute the Software for such purposes.
33  */

34
35 package com.sun.tools.example.debug.gui;
36
37 import java.io.*;
38 import java.util.*;
39
40 import com.sun.jdi.*;
41 import com.sun.tools.example.debug.event.*;
42 import com.sun.tools.example.debug.bdi.*;
43
44 public class ContextManager {
45
46     private ClassManager classManager;
47     private ExecutionManager runtime;
48
49     private String JavaDoc mainClassName;
50     private String JavaDoc vmArguments;
51     private String JavaDoc commandArguments;
52     private String JavaDoc remotePort;
53
54     private ThreadReference currentThread;
55
56     private boolean verbose;
57
58     private Vector contextListeners = new Vector();
59
60     public ContextManager(Environment env) {
61     classManager = env.getClassManager();
62     runtime = env.getExecutionManager();
63     mainClassName = "";
64     vmArguments = "";
65     commandArguments = "";
66     currentThread = null;
67
68     ContextManagerListener listener = new ContextManagerListener();
69     runtime.addJDIListener(listener);
70     runtime.addSessionListener(listener);
71     }
72     
73     // Program execution defaults.
74

75     //### Should there be change listeners for these?
76
//### They would be needed if we expected a dialog to be
77
//### synchronized with command input while it was open.
78

79     public String JavaDoc getMainClassName() {
80     return mainClassName;
81     }
82
83     public void setMainClassName(String JavaDoc mainClassName) {
84     this.mainClassName = mainClassName;
85     }
86
87     public String JavaDoc getVmArguments() {
88     return processClasspathDefaults(vmArguments);
89     }
90
91     public void setVmArguments(String JavaDoc vmArguments) {
92     this.vmArguments = vmArguments;
93     }
94
95     public String JavaDoc getProgramArguments() {
96     return commandArguments;
97     }
98
99     public void setProgramArguments(String JavaDoc commandArguments) {
100     this.commandArguments = commandArguments;
101     }
102
103     public String JavaDoc getRemotePort() {
104     return remotePort;
105     }
106
107     public void setRemotePort(String JavaDoc remotePort) {
108     this.remotePort = remotePort;
109
110     }
111
112
113     // Miscellaneous debugger session preferences.
114

115     public boolean getVerboseFlag() {
116     return verbose;
117     }
118
119     public void setVerboseFlag(boolean verbose) {
120     this.verbose = verbose;
121     }
122
123
124     // Thread focus.
125

126     public ThreadReference getCurrentThread() {
127     return currentThread;
128     }
129
130     public void setCurrentThread(ThreadReference t) {
131     if (t != currentThread) {
132         currentThread = t;
133         notifyCurrentThreadChanged(t);
134     }
135     }
136
137     public void setCurrentThreadInvalidate(ThreadReference t) {
138     currentThread = t;
139         notifyCurrentFrameChanged(runtime.threadInfo(t),
140                                   0, true);
141     }
142
143     public void invalidateCurrentThread() {
144         notifyCurrentFrameChanged(null, 0, true);
145     }
146
147
148     // If a view is displaying the current thread, it may
149
// choose to indicate which frame is current in the
150
// sense of the command-line UI. It may also "warp" the
151
// selection to that frame when changed by an 'up' or 'down'
152
// command. Hence, a notifier is provided.
153

154     /******
155     public int getCurrentFrameIndex() {
156     return getCurrentFrameIndex(currentThreadInfo);
157     }
158     ******/

159
160     public int getCurrentFrameIndex(ThreadReference t) {
161     return getCurrentFrameIndex(runtime.threadInfo(t));
162     }
163
164     //### Used in StackTraceTool.
165
public int getCurrentFrameIndex(ThreadInfo tinfo) {
166         if (tinfo == null) {
167             return 0;
168         }
169     Integer JavaDoc currentFrame = (Integer JavaDoc)tinfo.getUserObject();
170     if (currentFrame == null) {
171         return 0;
172     } else {
173         return currentFrame.intValue();
174     }
175     }
176
177     public int moveCurrentFrameIndex(ThreadReference t, int count) throws VMNotInterruptedException {
178     return setCurrentFrameIndex(t,count, true);
179     }
180
181     public int setCurrentFrameIndex(ThreadReference t, int newIndex) throws VMNotInterruptedException {
182     return setCurrentFrameIndex(t, newIndex, false);
183     }
184
185     public int setCurrentFrameIndex(int newIndex) throws VMNotInterruptedException {
186     if (currentThread == null) {
187             return 0;
188         } else {
189             return setCurrentFrameIndex(currentThread, newIndex, false);
190         }
191     }
192
193     private int setCurrentFrameIndex(ThreadReference t, int x, boolean relative) throws VMNotInterruptedException {
194         boolean sameThread = t.equals(currentThread);
195     ThreadInfo tinfo = runtime.threadInfo(t);
196         if (tinfo == null) {
197             return 0;
198         }
199     int maxIndex = tinfo.getFrameCount()-1;
200     int oldIndex = getCurrentFrameIndex(tinfo);
201         int newIndex = relative? oldIndex + x : x;
202     if (newIndex > maxIndex) {
203         newIndex = maxIndex;
204     } else if (newIndex < 0) {
205         newIndex = 0;
206     }
207         if (!sameThread || newIndex != oldIndex) { // don't recurse
208
setCurrentFrameIndex(tinfo, newIndex);
209         }
210     return newIndex - oldIndex;
211     }
212
213     private void setCurrentFrameIndex(ThreadInfo tinfo, int index) {
214     tinfo.setUserObject(new Integer JavaDoc(index));
215     //### In fact, the value may not have changed at this point.
216
//### We need to signal that the user attempted to change it,
217
//### however, so that the selection can be "warped" to the
218
//### current location.
219
notifyCurrentFrameChanged(tinfo.thread(), index);
220     }
221
222     public StackFrame getCurrentFrame() throws VMNotInterruptedException {
223     return getCurrentFrame(runtime.threadInfo(currentThread));
224     }
225
226     public StackFrame getCurrentFrame(ThreadReference t) throws VMNotInterruptedException {
227     return getCurrentFrame(runtime.threadInfo(t));
228     }
229
230     public StackFrame getCurrentFrame(ThreadInfo tinfo) throws VMNotInterruptedException {
231     int index = getCurrentFrameIndex(tinfo);
232     try {
233         // It is possible, though unlikely, that the VM was interrupted
234
// before the thread created its Java stack.
235
return tinfo.getFrame(index);
236     } catch (FrameIndexOutOfBoundsException e) {
237         return null;
238     }
239     }
240
241     public void addContextListener(ContextListener cl) {
242     contextListeners.add(cl);
243     }
244
245     public void removeContextListener(ContextListener cl) {
246     contextListeners.remove(cl);
247     }
248
249     //### These notifiers are fired only in response to USER-INITIATED changes
250
//### to the current thread and current frame. When the current thread is set automatically
251
//### after a breakpoint hit or step completion, no event is generated. Instead,
252
//### interested parties are expected to listen for the BreakpointHit and StepCompleted
253
//### events. This convention is unclean, and I believe that it reflects a defect in
254
//### in the current architecture. Unfortunately, however, we cannot guarantee the
255
//### order in which various listeners receive a given event, and the handlers for
256
//### the very same events that cause automatic changes to the current thread may also
257
//### need to know the current thread.
258

259     private void notifyCurrentThreadChanged(ThreadReference t) {
260         ThreadInfo tinfo = null;
261         int index = 0;
262         if (t != null) {
263             tinfo = runtime.threadInfo(t);
264             index = getCurrentFrameIndex(tinfo);
265         }
266         notifyCurrentFrameChanged(tinfo, index, false);
267     }
268
269     private void notifyCurrentFrameChanged(ThreadReference t, int index) {
270         notifyCurrentFrameChanged(runtime.threadInfo(t),
271                                   index, false);
272     }
273
274     private void notifyCurrentFrameChanged(ThreadInfo tinfo, int index,
275                                            boolean invalidate) {
276     Vector l = (Vector)contextListeners.clone();
277     CurrentFrameChangedEvent evt =
278         new CurrentFrameChangedEvent(this, tinfo, index, invalidate);
279     for (int i = 0; i < l.size(); i++) {
280         ((ContextListener)l.elementAt(i)).currentFrameChanged(evt);
281     }
282     }
283
284     private class ContextManagerListener extends JDIAdapter
285                implements SessionListener, JDIListener {
286
287         // SessionListener
288

289         public void sessionStart(EventObject e) {
290         invalidateCurrentThread();
291     }
292
293         public void sessionInterrupt(EventObject e) {
294         setCurrentThreadInvalidate(currentThread);
295     }
296
297         public void sessionContinue(EventObject e) {
298         invalidateCurrentThread();
299     }
300
301         // JDIListener
302

303     public void locationTrigger(LocationTriggerEventSet e) {
304         setCurrentThreadInvalidate(e.getThread());
305     }
306
307     public void exception(ExceptionEventSet e) {
308         setCurrentThreadInvalidate(e.getThread());
309     }
310
311         public void vmDisconnect(VMDisconnectEventSet e) {
312         invalidateCurrentThread();
313     }
314
315     }
316
317
318     /**
319      * Add a -classpath argument to the arguments passed to the exec'ed
320      * VM with the contents of CLASSPATH environment variable,
321      * if -classpath was not already specified.
322      *
323      * @param javaArgs the arguments to the VM being exec'd that
324      * potentially has a user specified -classpath argument.
325      * @return a javaArgs whose -classpath option has been added
326      */

327
328     private String JavaDoc processClasspathDefaults(String JavaDoc javaArgs) {
329         if (javaArgs.indexOf("-classpath ") == -1) {
330             StringBuffer JavaDoc munged = new StringBuffer JavaDoc(javaArgs);
331         SearchPath classpath = classManager.getClassPath();
332         if (classpath.isEmpty()) {
333         String JavaDoc envcp = System.getProperty("env.class.path");
334                 if ((envcp != null) && (envcp.length() > 0)) {
335                     munged.append(" -classpath " + envcp);
336                 }
337         } else {
338         munged.append(" -classpath " + classpath.asString());
339         }
340             return munged.toString();
341         } else {
342             return javaArgs;
343         }
344     }
345
346     private String JavaDoc appendPath(String JavaDoc path1, String JavaDoc path2) {
347         if (path1 == null || path1.length() == 0) {
348             return path2 == null ? "." : path2;
349         } else if (path2 == null || path2.length() == 0) {
350             return path1;
351         } else {
352             return path1 + File.pathSeparator + path2;
353         }
354     }
355
356 }
357
Popular Tags