jTracer  1.03
Stack trace visualization tool
Session.java
Go to the documentation of this file.
1 
7 package org.libcsdbg.jtracer;
8 
9 import java.beans.PropertyChangeListener;
10 
11 import java.util.Hashtable;
12 import java.util.Enumeration;
13 import java.util.Vector;
14 
15 import java.io.IOException;
16 import java.io.InputStreamReader;
17 import java.io.BufferedReader;
18 
19 import java.net.Socket;
20 import java.net.ProtocolException;
21 
22 import java.awt.event.ActionEvent;
23 import java.awt.event.ActionListener;
24 import java.awt.Color;
25 import java.awt.Font;
26 import java.awt.Insets;
27 import java.awt.Dimension;
28 import java.awt.Container;
29 import java.awt.BorderLayout;
30 
31 import javax.swing.event.ChangeEvent;
32 import javax.swing.event.ChangeListener;
33 import javax.swing.JFrame;
34 import javax.swing.JToolBar;
35 import javax.swing.JTabbedPane;
36 import javax.swing.JPanel;
37 import javax.swing.JScrollPane;
38 
44 public class Session extends JFrame implements
45  ActionListener,
46  ChangeListener,
47  Runnable
48 {
50  private static final long serialVersionUID = 0x0400;
51 
53  private JToolBar tools = null;
54 
56  private JTabbedPane tabs = null;
57 
58  private Vector<TracePane> traces = null;
59 
60  private TraceBar details = null;
61 
63  private JFrame owner = null;
64 
66  private Socket link = null;
67 
69  private BufferedReader rx = null;
70 
71  private Thread server = null;
72 
74  private boolean isLocked = false;
75 
76 
84  Session(JFrame f, Socket sock) throws IOException
85  {
86  super("Session");
87  owner = f;
88 
89  Registry conf = Registry.getCurrent();
90  setIconImages(conf.getProjectIcons());
91 
92  link = sock;
93  //link.shutdownOutput();
94  rx = new BufferedReader(new InputStreamReader(link.getInputStream()));
95 
96  /*Integer timeout = (Integer) conf.get("session", "timeout");
97  if (timeout != null)
98  link.setSoTimeout(timeout);*/
99 
100  tools = new JToolBar();
101  tools.add(createTool("Remove trace", (ActionListener) owner));
102  tools.add(createTool("Lock", this));
103  tools.addSeparator();
104 
105  tools.add(createTool("Select previous", (ActionListener) owner));
106  tools.add(createTool("Select next", (ActionListener) owner));
107  tools.add(createTool("Close", (ActionListener) owner));
108  tools.addSeparator();
109 
110  tools.add(createTool("Find", this));
111  add(tools, BorderLayout.NORTH);
112 
113  Button tool = (Button) tools.getComponent(0);
114  tool.addActionListener(this);
115 
116  traces = new Vector<TracePane>();
117  tabs = new JTabbedPane();
118  tabs.addChangeListener(this);
119  tabs.setFont((Font) conf.get("component", "font"));
120  tabs.setForeground((Color) conf.get("component", "fgcolor"));
121  add(tabs, BorderLayout.CENTER);
122 
123  details = new TraceBar();
124  add(details, BorderLayout.SOUTH);
125 
126  setSize((Dimension) conf.get("session", "size"));
127  addPropertyChangeListener("sessionRequest", (PropertyChangeListener) owner);
128  addPropertyChangeListener("traceCount", (PropertyChangeListener) owner);
129 
130  server = new Thread(this);
131  server.start();
132  }
133 
134 
140  public void addTrace(Hashtable<String, String> rqst)
141  {
142  Registry conf = Registry.getCurrent();
143  TracePane pane = new TracePane(rqst);
144  traces.add(pane);
145 
146  /*String token = rqst.get("tstamp");
147  details.setTimestamp(Long.parseLong(token, 16));
148 
149  token = rqst.get("exception");
150  if (token != null)
151  details.setMessage(token);
152  else
153  details.setMessage("Thread stack trace"); */
154 
155  String host = link.getInetAddress().getCanonicalHostName();
156  String addr = link.getInetAddress().getHostAddress();
157  int port = link.getPort();
158  //details.setAddress(host, port);
159 
160  pane.append(rqst.get("trace"));
161  JPanel view = new JPanel(new BorderLayout());
162  view.add(pane);
163  pane.setMargin(new Insets(6, 2, 0, 2));
164 
165  JScrollPane scroll = new JScrollPane(view);
166  scroll.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_ALWAYS);
167  tabs.addTab("Thread " + rqst.get("tid"), conf.loadIcon("new.png"), scroll);
168 
169  String path = rqst.get("path");
170  int pid = Integer.parseInt(rqst.get("pid"), 16);
171  setTitle(path + " (" + pid + "@" + addr + ")");
172 
173  int len = rqst.get("request").length();
174  StringBuffer msg = new StringBuffer();
175  msg.append("Read " + len + " bytes ");
176  msg.append("for " + path + " (" + pid + "@");
177  msg.append(addr + ":" + port + ")");
178  firePropertyChange("sessionRequest", null, msg.toString());
179  firePropertyChange("traceCount", null, tabs.getTabCount());
180 
181  tools.getComponent(0).setEnabled(true);
182  tools.getComponent(7).setEnabled(true);
183  }
184 
185 
191  public boolean isIconified()
192  {
193  return (getExtendedState() & ICONIFIED) != 0;
194  }
195 
196 
204  public int setIconified(boolean how)
205  {
206  int state = getExtendedState();
207  if (how)
208  state |= ICONIFIED;
209  else
210  state &= ~ICONIFIED;
211 
212  setExtendedState(state);
213  return state;
214  }
215 
216 
224  public Hashtable<String, String> getRequest() throws IOException
225  {
226  Hashtable<String, String> retval = new Hashtable<String, String>();
227 
228  int cnt = 0;
229  boolean text = false;
230  StringBuffer buffer = new StringBuffer();
231  StringBuffer trace = new StringBuffer();
232 
233  /* Read a line at a time and parse it */
234  do {
235  String ln = rx.readLine();
236  if (ln == null)
237  throw new IOException("The peer disconnected prematurely");
238 
239  cnt++;
240  buffer.append(ln).append("\n");
241  if (ln.length() == 0) {
242  text = true;
243  continue;
244  }
245 
246  if (text) {
247  trace.append(ln).append("\n");
248  continue;
249  }
250 
251  String hdr[] = ln.split(":");
252  if (hdr.length < 2 || hdr[0].trim().length() == 0) {
253  String msg = "LDP request format error (" + cnt + ": " + ln + ")";
254  throw new ProtocolException(msg);
255  }
256 
257  String field = hdr[1];
258  for (int i = 2; i < hdr.length; i++)
259  field += ":" + hdr[i];
260 
261  retval.put(hdr[0].trim(), field.trim());
262  }
263  while (!buffer.toString().endsWith("}\n\n"));
264 
265  retval.put("trace", trace.toString().trim());
266  retval.put("request", buffer.toString().trim());
267  return retval;
268  }
269 
270 
274  public void quit()
275  {
276  try {
277  link.close();
278  rx.close();
279 
280  /*Thread thr = server;
281  server = null;
282  thr.interrupt();*/
283  }
284 
285  catch (Throwable t) {
286  Registry.debug(t);
287  }
288  }
289 
290 
296  public int getTraceCount()
297  {
298  return tabs.getTabCount();
299  }
300 
301 
311  private Button createTool(String cmd, ActionListener handler)
312  {
313  String nm = cmd.toLowerCase().replace(' ', '_') + "24.png";
314  Button retval = new Button(nm, cmd, handler);
315  retval.setMargin(new Insets(2, 2, 2, 2));
316  return retval;
317  }
318 
319 
320  public void run()
321  {
322  /* Listen for incoming connections */
323  while (server == Thread.currentThread()) {
324  try {
325  Hashtable<String, String> rqst = getRequest();
326  addTrace(rqst);
327  }
328 
329  catch (Throwable t) {
330  //Registry.debug(t);
331  server = null;
332  }
333  }
334  }
335 
336 
342  public void actionPerformed(ActionEvent event)
343  {
344  try {
345  String cmd = event.getActionCommand();
346 
347  if (cmd.equals("Remove trace")) {
348  int i = tabs.getSelectedIndex();
349  if (i < 0)
350  return;
351 
352  traces.remove(i);
353  tabs.remove(i);
354  int cnt = tabs.getTabCount();
355  firePropertyChange("traceCount", null, cnt);
356  if (cnt != 0)
357  return;
358 
359  if (!isLocked) {
360  owner.toFront();
361  dispose();
362  return;
363  }
364 
365  tools.getComponent(0).setEnabled(false);
366  tools.getComponent(7).setEnabled(false);
367  }
368 
369  else if (cmd.equals("Lock")) {
370  isLocked = !isLocked;
371 
372  Registry conf = Registry.getCurrent();
373  Button tool = (Button) tools.getComponent(1);
374 
375  if (isLocked) {
376  tool.setIcon(conf.loadIcon("unlock24.png"));
377  tool.setToolTipText("Unlock");
378  }
379 
380  else {
381  tool.setIcon(conf.loadIcon("lock24.png"));
382  tool.setToolTipText("Lock");
383  }
384  }
385 
386  else if (cmd.equals("Find"))
387  Alert.error(this, "Not implemented yet", false);
388  }
389 
390  catch (Throwable t) {
391  Registry.debug(t);
392  }
393  }
394 
395 
401  public void stateChanged(ChangeEvent event)
402  {
403  try {
404  int i = tabs.getSelectedIndex();
405  if (i < 0) {
406  details.clear();
407  return;
408  }
409 
410  tabs.setIconAt(i, Registry.getCurrent().loadIcon("void.png"));
411 
412  /*for (int j = 0, cnt = traces.size(); j < cnt; j++) {
413  Hashtable<String, String> rqst = traces.get(j);
414 
415  System.out.println("Trace " + j + ": ");
416  Enumeration keys = rqst.keys();
417  while (keys.hasMoreElements()) {
418  String key = (String) keys.nextElement();
419  String field = rqst.get(key);
420 
421  System.out.println("\t" + key + ": " + field);
422  }
423  }*/
424 
425  TracePane pane = traces.get(i);
426  String field = pane.getField("exception");
427  if (field != null)
428  details.setMessage(field);
429  else
430  details.setMessage("Thread stack trace");
431 
432  field = pane.getField("tstamp");
433  details.setTimestamp(Long.parseLong(field, 16));
434 
435  String host = link.getInetAddress().getCanonicalHostName();
436  int port = link.getPort();
437  details.setAddress(host, port);
438  }
439 
440  catch (Throwable t) {
441  Registry.debug(t);
442  }
443  }
444 }
445 
Hashtable< String, String > getRequest()
Read and parse an incoming LDP request.
Definition: Session.java:224
Multitype button with configurable styles and behaviour.
Definition: Button.java:20
Object get(String section, String key)
Get an entry.
Definition: Registry.java:151
Vector< TracePane > traces
Definition: Session.java:58
Configuration registry.
Definition: Registry.java:41
ImageIcon loadIcon(String nm)
Load an icon from the current theme.
Definition: Registry.java:220
Socket link
Client socket.
Definition: Session.java:66
int setIconified(boolean how)
Set frame state.
Definition: Session.java:204
Vector< Image > getProjectIcons()
Get a cross-platform set of project icons.
Definition: Registry.java:305
void stateChanged(ChangeEvent event)
Handler for events fired from the trace enumerator.
Definition: Session.java:401
JToolBar tools
Trace and frame tools.
Definition: Session.java:53
BufferedReader rx
Socket buffered reader.
Definition: Session.java:69
static final long serialVersionUID
Class version.
Definition: Session.java:50
static void error(JFrame owner, String msg, boolean fatal)
Show an error alert and exit if the error is marked as fatal.
Definition: Alert.java:165
int getTraceCount()
Get the number of traces.
Definition: Session.java:296
Button createTool(String cmd, ActionListener handler)
Create a toolbar button.
Definition: Session.java:311
void quit()
Protocol quit.
Definition: Session.java:274
A bar for various trace details (exception message, timestamp e.t.c) with multiple indicators and con...
Definition: TraceBar.java:28
JTabbedPane tabs
Trace enumeration pane.
Definition: Session.java:56
JFrame owner
Main application frame.
Definition: Session.java:63
User alert or simple prompt dialog with configurable styles.
Definition: Alert.java:29
boolean isLocked
Lock state indicator.
Definition: Session.java:74
Rich text pane for trace visualization with syntax highlighting.
Definition: TracePane.java:26
void addTrace(Hashtable< String, String > rqst)
Add a trace to the tab enumerator.
Definition: Session.java:140
void actionPerformed(ActionEvent event)
Handler for events fired from the toolbar of the frame.
Definition: Session.java:342
boolean isIconified()
Check frame state.
Definition: Session.java:191