001: /*
002: *
003: *
004: * Copyright 1990-2007 Sun Microsystems, Inc. All Rights Reserved.
005: * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER
006: *
007: * This program is free software; you can redistribute it and/or
008: * modify it under the terms of the GNU General Public License version
009: * 2 only, as published by the Free Software Foundation.
010: *
011: * This program is distributed in the hope that it will be useful, but
012: * WITHOUT ANY WARRANTY; without even the implied warranty of
013: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
014: * General Public License version 2 for more details (a copy is
015: * included at /legal/license.txt).
016: *
017: * You should have received a copy of the GNU General Public License
018: * version 2 along with this work; if not, write to the Free Software
019: * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
020: * 02110-1301 USA
021: *
022: * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa
023: * Clara, CA 95054 or visit www.sun.com if you need additional
024: * information or have any questions.
025: */
026:
027: package view;
028:
029: import com.sun.cldchi.tools.memoryprofiler.data.*;
030: import com.sun.cldchi.tools.memoryprofiler.jdwp.VMConnection;
031: import com.sun.cldchi.tools.memoryprofiler.jdwp.VMConnectionFactory;
032: import java.io.*;
033: import java.net.*;
034: import java.awt.*;
035: import java.awt.event.*;
036: import java.awt.datatransfer.*;
037: import javax.swing.*;
038: import javax.swing.tree.*;
039: import javax.swing.table.*;
040: import javax.swing.event.*;
041: import java.util.Arrays;
042: import java.nio.channels.*;
043: import java.nio.*;
044: import javax.swing.border.LineBorder;
045:
046: public class Client {
047: private MPDataProvider _data_provider;
048: private JList _classes_list;
049: private JList _object_list;
050: private JFrame _frame;
051: private ViewMemoryPanel _memory_access_panel;
052: private ViewObjectsPanel _view_objects_panel;
053: private JButton _vm_controller;
054: private JButton _connection_controller;
055: private JButton _statistics_btn;
056: private boolean isConnected = false;
057: private static String hostName = "localhost";
058: private static int port = 5000;
059:
060: public static void main(String args[]) {
061: //Parse arguments
062: try {
063: if (parseArgs(args) < 0) {
064: System.exit(1);
065: }
066: } catch (CommandLineException e) {
067: System.err.println(e);
068: System.exit(1);
069: }
070: (new Client()).initUI();
071: }
072:
073: /************Connectivity SECTION****************************/
074: private void initConnection() throws java.net.ConnectException,
075: java.net.SocketException {
076: _data_provider.connect(hostName, port);
077: }
078:
079: /************UI SECTION****************************/
080: private void initUI() {
081: _data_provider = MPDataProviderFactory
082: .getMPDataProvider(VMConnectionFactory
083: .getVMConnectionImpl());
084: _frame = new JFrame("Java Heap Memory Observe Tool");
085: _frame.pack();
086: _frame.setLocation(0, 0);
087: _frame.setSize(1000, 650);
088: _frame.setVisible(true);
089: _frame.setResizable(false);
090: _frame.getContentPane().setLayout(new GridBagLayout());
091: _frame.addWindowListener(new WindowAdapter() {
092: public void windowClosing(WindowEvent e) {
093: _data_provider.closeConnections();
094: System.exit(0);
095: }
096: });
097:
098: /* memory access panel*/
099: _classes_list = new JList();
100: _memory_access_panel = new ViewMemoryPanel(_data_provider);
101: _memory_access_panel.setSize(1000, 300);
102: _memory_access_panel.update();
103:
104: _frame.getContentPane().add(
105: _memory_access_panel,
106: new GridBagConstraints(0, 0, 3, 1, 1, 1,
107: GridBagConstraints.NORTHWEST,
108: GridBagConstraints.HORIZONTAL, new Insets(2, 2,
109: 2, 2), 0, 0));
110:
111: JPanel lists_panel = new JPanel();
112: JScrollPane pane = new JScrollPane() {
113: public Dimension getPreferredSize() {
114: return new Dimension(350, 250);
115: }
116: };
117: _classes_list
118: .setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
119: _classes_list
120: .addListSelectionListener(new ClassesListSelectionListener());
121: pane.getViewport().setView(_classes_list);
122: lists_panel.add(pane);
123: _frame.getContentPane().add(
124: lists_panel,
125: new GridBagConstraints(0, 1, 2, 1, 1, 1,
126: GridBagConstraints.NORTHWEST,
127: GridBagConstraints.NONE,
128: new Insets(2, 2, 2, 2), 0, 0));
129:
130: _view_objects_panel = new ViewObjectsPanel(_data_provider);
131: _view_objects_panel.initUI(true);
132: _frame.getContentPane().add(
133: _view_objects_panel,
134: new GridBagConstraints(2, 1, 1, 1, 1, 1,
135: GridBagConstraints.NORTHWEST,
136: GridBagConstraints.BOTH,
137: new Insets(2, 2, 2, 2), 0, 0));
138:
139: JPanel button_panel = new JPanel();
140: _statistics_btn = new JButton("Statistics");
141: _statistics_btn.addActionListener(new ActionListener() {
142: public void actionPerformed(ActionEvent e) {
143: StatisticsDialog.showDialog(_frame, _data_provider
144: .calculateStatistics());
145: }
146: });
147: button_panel.add(_statistics_btn);
148: _vm_controller = new JButton("Resume");
149: _vm_controller.addActionListener(new VMActionListener());
150: button_panel.add(_vm_controller);
151: _connection_controller = new JButton("Connect");
152: _connection_controller
153: .addActionListener(new ConnectionActionListener());
154: button_panel.add(_connection_controller);
155:
156: _frame.getContentPane().add(
157: button_panel,
158: new GridBagConstraints(2, 2, 1, 1, 1, 1,
159: GridBagConstraints.SOUTHEAST,
160: GridBagConstraints.NONE,
161: new Insets(2, 2, 2, 2), 0, 0));
162:
163: setDisconnected();
164: _frame.invalidate();
165: _frame.validate();
166: _frame.repaint();
167:
168: }
169:
170: private void update() {
171: try {
172: _classes_list.setListData(_data_provider.getClassList());
173: _memory_access_panel.update();
174: } catch (SocketException e) {
175: setDisconnected();
176: }
177: }
178:
179: /******HANDLERS**************************************/
180: private void onClassesSelectionChanged() {
181: JavaClass item = (JavaClass) _classes_list.getSelectedValue();
182: if (item != null) {
183: _memory_access_panel.set_selected_class_id(item);
184: Object[] objects = _data_provider.getObjectsOfClass(item);
185: _view_objects_panel.setObjects(objects);
186: } else {
187: _view_objects_panel.setObjects(new Object[0]);
188: }
189: _frame.invalidate();
190: _frame.validate();
191: _frame.repaint();
192: }
193:
194: private void onObjectSelectionChanged() {
195: _frame.invalidate();
196: _frame.validate();
197: _frame.repaint();
198: }
199:
200: /******PARSE ARGS SECTION****************************/
201: private static int parseArgs(String[] args)
202: throws CommandLineException {
203:
204: //Parse command line parameteres
205: boolean portDefined = false;
206: boolean hostDefined = false;
207: for (int i = 0; i < args.length - 1; i++) {
208:
209: //-port
210: if (args[i].equals("-port")) {
211: if (portDefined) {
212: throw new CommandLineException(
213: "Port already defined");
214: }
215:
216: portDefined = true;
217: try {
218: port = Integer.valueOf(args[++i]).intValue();
219: } catch (NumberFormatException e) {
220: throw new CommandLineException(
221: "Invalid port number");
222: }
223:
224: //-host
225: } else if (args[i].equals("-host")) {
226: if (hostDefined) {
227: throw new CommandLineException(
228: "Host already defined");
229: }
230: hostDefined = true;
231: hostName = args[++i];
232:
233: //Invalid switch
234: } else {
235: throw new CommandLineException("Unknown switch "
236: + args[i]);
237: }
238: }
239:
240: return 0;
241: }
242:
243: private static void usage() {
244: System.err.println("Usage:\n"
245: + "java view.Client -host <hostname> -port <portname>");
246: }
247:
248: class ClassesListSelectionListener implements ListSelectionListener {
249: public void valueChanged(ListSelectionEvent e) {
250: onClassesSelectionChanged();
251: }
252: }
253:
254: class ConnectionActionListener implements ActionListener {
255: public void actionPerformed(ActionEvent event) {
256: if (!isConnected) {
257: try {
258: initConnection();
259: update();
260: setConnected();
261: } catch (java.net.ConnectException e) {
262: JOptionPane.showMessageDialog(null,
263: "Could not connect to the VM! Check parameters! Host:"
264: + hostName + " port:" + port,
265: "Connection Error",
266: JOptionPane.ERROR_MESSAGE);
267: System.out.println("");
268: } catch (java.net.SocketException e) {
269: JOptionPane
270: .showMessageDialog(
271: null,
272: "VM connection was broken during initial update!",
273: "Connection Error",
274: JOptionPane.ERROR_MESSAGE);
275: }
276: } else { //isConnected
277: _data_provider.closeConnections();
278: setDisconnected();
279: }
280: };
281: }
282:
283: class VMActionListener implements ActionListener {
284: boolean vm_run = false;
285:
286: public void actionPerformed(ActionEvent e) {
287: try {
288: if (!vm_run) {
289: _data_provider.resumeVM();
290: } else {
291: _data_provider.pauseVM();
292: }
293: vm_run = !vm_run;
294: } catch (SocketException e2) {
295: vm_run = false;
296: setDisconnected();
297: }
298: if (vm_run) {
299: _vm_controller.setText("Pause");
300: } else {
301: _vm_controller.setText("Resume");
302: }
303: if (!vm_run) {
304: update();
305: }
306:
307: }
308: }
309:
310: private void setDisconnected() {
311: isConnected = false;
312: _classes_list.setListData(new Object[0]);
313: _memory_access_panel.update();
314: _vm_controller.setEnabled(false);
315: _statistics_btn.setEnabled(false);
316: _connection_controller.setText("Connect");
317: }
318:
319: private void setConnected() {
320: isConnected = true;
321: _vm_controller.setEnabled(true);
322: _statistics_btn.setEnabled(true);
323: _connection_controller.setText("Disconnect");
324: }
325: }
326:
327: class CommandLineException extends Exception {
328: public CommandLineException() {
329: super ();
330: }
331:
332: public CommandLineException(String s) {
333: super(s);
334: }
335: }
|