History

My first initial commit with all of mine experimental changes.

Dmitry Kabak (userdima committed 13 years ago

Commit d37b88d1 parent 3f5b46618352 files · +2598093 −-8690Browse files

Showing the changes to java/pkg/sun/tools/jconsole/JConsole.java (1 of 18352 files). Show all

Unified · Split

java/pkg/sun/tools/jconsole/JConsole.java+1112−0
@@ -0,0 +1,1112 @@
1+/*
2+ * Copyright (c) 2004, 2006, Oracle and/or its affiliates. All rights reserved.
3+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4+ *
5+ * This code is free software; you can redistribute it and/or modify it
6+ * under the terms of the GNU General Public License version 2 only, as
7+ * published by the Free Software Foundation. Oracle designates this
8+ * particular file as subject to the "Classpath" exception as provided
9+ * by Oracle in the LICENSE file that accompanied this code.
10+ *
11+ * This code is distributed in the hope that it will be useful, but WITHOUT
12+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14+ * version 2 for more details (a copy is included in the LICENSE file that
15+ * accompanied this code).
16+ *
17+ * You should have received a copy of the GNU General Public License version
18+ * 2 along with this work; if not, write to the Free Software Foundation,
19+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20+ *
21+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22+ * or visit www.oracle.com if you need additional information or have any
23+ * questions.
24+ */
25+
26+package sun.tools.jconsole;
27+
28+import java.awt.*;
29+import java.awt.event.*;
30+import java.beans.*;
31+import java.io.*;
32+import java.lang.reflect.InvocationTargetException;
33+import java.net.*;
34+import java.util.*;
35+import java.util.List;
36+
37+import javax.swing.*;
38+import javax.swing.border.*;
39+import javax.swing.event.*;
40+import javax.swing.plaf.*;
41+import javax.management.remote.JMXServiceURL;
42+import javax.management.remote.JMXConnector;
43+import javax.security.auth.login.FailedLoginException;
44+import javax.net.ssl.SSLHandshakeException;
45+
46+import com.sun.tools.jconsole.JConsolePlugin;
47+
48+import sun.net.util.IPAddressUtil;
49+
50+import static sun.tools.jconsole.Resources.*;
51+import static sun.tools.jconsole.Utilities.*;
52+
53+@SuppressWarnings("serial")
54+public class JConsole extends JFrame
55+ implements ActionListener, InternalFrameListener {
56+
57+ static /*final*/ boolean IS_GTK;
58+ static /*final*/ boolean IS_WIN;
59+
60+ static {
61+ // Apply the system L&F if it is GTK or Windows, and
62+ // the L&F is not specified using a system property.
63+ if (System.getProperty("swing.defaultlaf") == null) {
64+ String systemLaF = UIManager.getSystemLookAndFeelClassName();
65+ if (systemLaF.equals("com.sun.java.swing.plaf.gtk.GTKLookAndFeel") ||
66+ systemLaF.equals("com.sun.java.swing.plaf.windows.WindowsLookAndFeel")) {
67+
68+ try {
69+ UIManager.setLookAndFeel(systemLaF);
70+ } catch (Exception e) {
71+ System.err.println(Resources.getText("JConsole: ", e.getMessage()));
72+ }
73+ }
74+ }
75+
76+ updateLafValues();
77+ }
78+
79+
80+ static void updateLafValues() {
81+ String lafName = UIManager.getLookAndFeel().getClass().getName();
82+ IS_GTK = lafName.equals("com.sun.java.swing.plaf.gtk.GTKLookAndFeel");
83+ IS_WIN = lafName.equals("com.sun.java.swing.plaf.windows.WindowsLookAndFeel");
84+
85+ //BorderedComponent.updateLafValues();
86+ }
87+
88+
89+ private final static String title =
90+ Resources.getText("Java Monitoring & Management Console");
91+ public final static String ROOT_URL =
92+ "service:jmx:";
93+
94+ private static int updateInterval = 4000;
95+ private static String pluginPath = "";
96+
97+ private JMenuBar menuBar;
98+ private JMenuItem hotspotMI, connectMI, exitMI;
99+ private WindowMenu windowMenu;
100+ private JMenuItem tileMI, cascadeMI, minimizeAllMI, restoreAllMI;
101+ private JMenuItem userGuideMI, aboutMI;
102+
103+ private JButton connectButton;
104+ private JDesktopPane desktop;
105+ private ConnectDialog connectDialog;
106+ private CreateMBeanDialog createDialog;
107+
108+ private ArrayList<VMInternalFrame> windows =
109+ new ArrayList<VMInternalFrame>();
110+
111+ private int frameLoc = 5;
112+ static boolean debug;
113+
114+ public JConsole(boolean hotspot) {
115+ super(title);
116+
117+ setRootPane(new FixedJRootPane());
118+ setAccessibleDescription(this,
119+ getText("JConsole.accessibleDescription"));
120+ setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
121+
122+ menuBar = new JMenuBar();
123+ setJMenuBar(menuBar);
124+
125+ // TODO: Use Actions !
126+
127+ JMenu connectionMenu = new JMenu(getText("Connection"));
128+ connectionMenu.setMnemonic(getMnemonicInt("Connection"));
129+ menuBar.add(connectionMenu);
130+ if(hotspot) {
131+ hotspotMI = new JMenuItem(getText("Hotspot MBeans..."));
132+ hotspotMI.setMnemonic(getMnemonicInt("Hotspot MBeans..."));
133+ hotspotMI.setAccelerator(KeyStroke.
134+ getKeyStroke(KeyEvent.VK_H,
135+ InputEvent.CTRL_MASK));
136+ hotspotMI.addActionListener(this);
137+ connectionMenu.add(hotspotMI);
138+
139+ connectionMenu.addSeparator();
140+ }
141+
142+ connectMI = new JMenuItem(Resources.getText("New Connection..."));
143+ connectMI.setMnemonic(getMnemonicInt("New Connection..."));
144+ connectMI.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_N,
145+ InputEvent.CTRL_MASK));
146+ connectMI.addActionListener(this);
147+ connectionMenu.add(connectMI);
148+
149+ connectionMenu.addSeparator();
150+
151+ exitMI = new JMenuItem(Resources.getText("Exit"));
152+ exitMI.setMnemonic(getMnemonicInt("Exit"));
153+ exitMI.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_F4,
154+ InputEvent.ALT_MASK));
155+ exitMI.addActionListener(this);
156+ connectionMenu.add(exitMI);
157+
158+
159+ JMenu helpMenu = new JMenu(getText("HelpMenu.title"));
160+ helpMenu.setMnemonic(getMnemonicInt("HelpMenu.title"));
161+ menuBar.add(helpMenu);
162+
163+ if (AboutDialog.isBrowseSupported()) {
164+ userGuideMI = new JMenuItem(getText("HelpMenu.UserGuide.title"));
165+ userGuideMI.setMnemonic(getMnemonicInt("HelpMenu.UserGuide.title"));
166+ userGuideMI.addActionListener(this);
167+ helpMenu.add(userGuideMI);
168+ helpMenu.addSeparator();
169+ }
170+ aboutMI = new JMenuItem(getText("HelpMenu.About.title"));
171+ aboutMI.setMnemonic(getMnemonicInt("HelpMenu.About.title"));
172+ aboutMI.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_F1, 0));
173+ aboutMI.addActionListener(this);
174+ helpMenu.add(aboutMI);
175+ }
176+
177+ public JDesktopPane getDesktopPane() {
178+ return desktop;
179+ }
180+
181+ public List<VMInternalFrame> getInternalFrames() {
182+ return windows;
183+ }
184+
185+ private void createMDI() {
186+ // Restore title - we now show connection name on internal frames
187+ setTitle(title);
188+
189+ Container cp = getContentPane();
190+ Component oldCenter =
191+ ((BorderLayout)cp.getLayout()).
192+ getLayoutComponent(BorderLayout.CENTER);
193+
194+ windowMenu = new WindowMenu(Resources.getText("Window"));
195+ windowMenu.setMnemonic(getMnemonicInt("Window"));
196+ // Add Window menu before Help menu
197+ menuBar.add(windowMenu, menuBar.getComponentCount() - 1);
198+
199+ desktop = new JDesktopPane();
200+ desktop.setBackground(new Color(235, 245, 255));
201+
202+ cp.add(desktop, BorderLayout.CENTER);
203+
204+ if (oldCenter instanceof VMPanel) {
205+ addFrame((VMPanel)oldCenter);
206+ }
207+ }
208+
209+ private class WindowMenu extends JMenu {
210+ VMInternalFrame[] windowMenuWindows = new VMInternalFrame[0];
211+ int separatorPosition;
212+
213+ // The width value of viewR is used to truncate long menu items.
214+ // The rest are placeholders and are ignored for this purpose.
215+ Rectangle viewR = new Rectangle(0, 0, 400, 20);
216+ Rectangle textR = new Rectangle(0, 0, 0, 0);
217+ Rectangle iconR = new Rectangle(0, 0, 0, 0);
218+
219+ WindowMenu(String text) {
220+ super(text);
221+
222+ cascadeMI = new JMenuItem(Resources.getText("Cascade"));
223+ cascadeMI.setMnemonic(getMnemonicInt("Cascade"));
224+ cascadeMI.addActionListener(JConsole.this);
225+ add(cascadeMI);
226+
227+ tileMI = new JMenuItem(Resources.getText("Tile"));
228+ tileMI.setMnemonic(getMnemonicInt("Tile"));
229+ tileMI.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_T,
230+ InputEvent.CTRL_MASK));
231+ tileMI.addActionListener(JConsole.this);
232+ add(tileMI);
233+
234+ minimizeAllMI = new JMenuItem(Resources.getText("Minimize All"));
235+ minimizeAllMI.setMnemonic(getMnemonicInt("Minimize All"));
236+ minimizeAllMI.addActionListener(JConsole.this);
237+ add(minimizeAllMI);
238+
239+ restoreAllMI = new JMenuItem(Resources.getText("Restore All"));
240+ restoreAllMI.setMnemonic(getMnemonicInt("Restore All"));
241+ restoreAllMI.addActionListener(JConsole.this);
242+ add(restoreAllMI);
243+
244+ separatorPosition = getMenuComponentCount();
245+ }
246+
247+ private void add(VMInternalFrame vmIF) {
248+ if (separatorPosition == getMenuComponentCount()) {
249+ addSeparator();
250+ }
251+
252+ int index = -1;
253+ int position = separatorPosition + 1;
254+ int n = windowMenuWindows.length;
255+
256+ for (int i = 0; i < n; i++) {
257+ if (windowMenuWindows[i] != null) {
258+ // Slot is in use, try next
259+ position++;
260+ } else {
261+ // Found a free slot
262+ index = i;
263+ break;
264+ }
265+ }
266+
267+ if (index == -1) {
268+ // Create a slot at the end
269+ VMInternalFrame[] newArray = new VMInternalFrame[n + 1];
270+ System.arraycopy(windowMenuWindows, 0, newArray, 0, n);
271+ windowMenuWindows = newArray;
272+ index = n;
273+ }
274+
275+ windowMenuWindows[index] = vmIF;
276+
277+ String indexString = "" + (index+1);
278+ String vmName = vmIF.getVMPanel().getDisplayName();
279+ // Maybe truncate menu item string and end with "..."
280+ String text =
281+ SwingUtilities.layoutCompoundLabel(this,
282+ getGraphics().getFontMetrics(getFont()),
283+ indexString + " " + vmName,
284+ null, 0, 0, 0, 0,
285+ viewR, iconR, textR, 0);
286+ JMenuItem mi = new JMenuItem(text);
287+ if (text.endsWith("...")) {
288+ mi.setToolTipText(vmName);
289+ }
290+
291+ // Set mnemonic using last digit of number
292+ int nDigits = indexString.length();
293+ mi.setMnemonic(indexString.charAt(nDigits-1));
294+ mi.setDisplayedMnemonicIndex(nDigits-1);
295+
296+ mi.putClientProperty("JConsole.vmIF", vmIF);
297+ mi.addActionListener(JConsole.this);
298+ vmIF.putClientProperty("JConsole.menuItem", mi);
299+ add(mi, position);
300+ }
301+
302+ private void remove(VMInternalFrame vmIF) {
303+ for (int i = 0; i < windowMenuWindows.length; i++) {
304+ if (windowMenuWindows[i] == vmIF) {
305+ windowMenuWindows[i] = null;
306+ }
307+ }
308+ JMenuItem mi = (JMenuItem)vmIF.getClientProperty("JConsole.menuItem");
309+ remove(mi);
310+ mi.putClientProperty("JConsole.vmIF", null);
311+ vmIF.putClientProperty("JConsole.menuItem", null);
312+
313+ if (separatorPosition == getMenuComponentCount() - 1) {
314+ remove(getMenuComponent(getMenuComponentCount() - 1));
315+ }
316+ }
317+ }
318+
319+ public void actionPerformed(ActionEvent ev) {
320+ Object src = ev.getSource();
321+ if (src == hotspotMI) {
322+ showCreateMBeanDialog();
323+ }
324+
325+ if (src == connectButton || src == connectMI) {
326+ VMPanel vmPanel = null;
327+ JInternalFrame vmIF = desktop.getSelectedFrame();
328+ if (vmIF instanceof VMInternalFrame) {
329+ vmPanel = ((VMInternalFrame)vmIF).getVMPanel();
330+ }
331+ String hostName = "";
332+ String url = "";
333+ if (vmPanel != null) {
334+ hostName = vmPanel.getHostName();
335+ if(vmPanel.getUrl() != null)
336+ url = vmPanel.getUrl();
337+ }
338+ showConnectDialog(url, hostName, 0, null, null, null);
339+ } else if (src == tileMI) {
340+ tileWindows();
341+ } else if (src == cascadeMI) {
342+ cascadeWindows();
343+ } else if (src == minimizeAllMI) {
344+ for (VMInternalFrame vmIF : windows) {
345+ try {
346+ vmIF.setIcon(true);
347+ } catch (PropertyVetoException ex) {
348+ // Ignore
349+ }
350+ }
351+ } else if (src == restoreAllMI) {
352+ for (VMInternalFrame vmIF : windows) {
353+ try {
354+ vmIF.setIcon(false);
355+ } catch (PropertyVetoException ex) {
356+ // Ignore
357+ }
358+ }
359+ } else if (src == exitMI) {
360+ System.exit(0);
361+ } else if (src == userGuideMI) {
362+ AboutDialog.browseUserGuide(this);
363+ } else if (src == aboutMI) {
364+ AboutDialog.showAboutDialog(this);
365+ } else if (src instanceof JMenuItem) {
366+ JMenuItem mi = (JMenuItem)src;
367+ VMInternalFrame vmIF = (VMInternalFrame)mi.
368+ getClientProperty("JConsole.vmIF");
369+ if (vmIF != null) {
370+ try {
371+ vmIF.setIcon(false);
372+ vmIF.setSelected(true);
373+ } catch (PropertyVetoException ex) {
374+ // Ignore
375+ }
376+ vmIF.moveToFront();
377+ }
378+ }
379+ }
380+
381+
382+ public void tileWindows() {
383+ int w = -1;
384+ int h = -1;
385+ int n = 0;
386+ for (VMInternalFrame vmIF : windows) {
387+ if (!vmIF.isIcon()) {
388+ n++;
389+ if (w == -1) {
390+ try {
391+ vmIF.setMaximum(true);
392+ w = vmIF.getWidth();
393+ h = vmIF.getHeight();
394+ } catch (PropertyVetoException ex) {
395+ // Ignore
396+ }
397+ }
398+ }
399+ }
400+ if (n > 0 && w > 0 && h > 0) {
401+ int rows = (int)Math.ceil(Math.sqrt(n));
402+ int cols = n / rows;
403+ if (rows * cols < n) cols++;
404+ int x = 0;
405+ int y = 0;
406+ w /= cols;
407+ h /= rows;
408+ int col = 0;
409+ for (VMInternalFrame vmIF : windows) {
410+ if (!vmIF.isIcon()) {
411+ try {
412+ vmIF.setMaximum(n==1);
413+ } catch (PropertyVetoException ex) {
414+ // Ignore
415+ }
416+ if (n > 1) {
417+ vmIF.setBounds(x, y, w, h);
418+ }
419+ if (col < cols-1) {
420+ col++;
421+ x += w;
422+ } else {
423+ col = 0;
424+ x = 0;
425+ y += h;
426+ }
427+ }
428+ }
429+ }
430+ }
431+
432+ public void cascadeWindows() {
433+ int n = 0;
434+ int w = -1;
435+ int h = -1;
436+ for (VMInternalFrame vmIF : windows) {
437+ if (!vmIF.isIcon()) {
438+ try {
439+ vmIF.setMaximum(false);
440+ } catch (PropertyVetoException ex) {
441+ // Ignore
442+ }
443+ n++;
444+ vmIF.pack();
445+ if (w == -1) {
446+ try {
447+ w = vmIF.getWidth();
448+ h = vmIF.getHeight();
449+ vmIF.setMaximum(true);
450+ w = vmIF.getWidth() - w;
451+ h = vmIF.getHeight() - h;
452+ vmIF.pack();
453+ } catch (PropertyVetoException ex) {
454+ // Ignore
455+ }
456+ }
457+ }
458+ }
459+ int x = 0;
460+ int y = 0;
461+ int dX = (n > 1) ? (w / (n - 1)) : 0;
462+ int dY = (n > 1) ? (h / (n - 1)) : 0;
463+ for (VMInternalFrame vmIF : windows) {
464+ if (!vmIF.isIcon()) {
465+ vmIF.setLocation(x, y);
466+ vmIF.moveToFront();
467+ x += dX;
468+ y += dY;
469+ }
470+ }
471+ }
472+
473+ // Call on EDT
474+ void addHost(String hostName, int port,
475+ String userName, String password) {
476+ addHost(hostName, port, userName, password, false);
477+ }
478+
479+ // Call on EDT
480+ void addVmid(LocalVirtualMachine lvm) {
481+ addVmid(lvm, false);
482+ }
483+
484+ // Call on EDT
485+ void addVmid(final LocalVirtualMachine lvm, final boolean tile) {
486+ new Thread("JConsole.addVmid") {
487+ public void run() {
488+ try {
489+ addProxyClient(ProxyClient.getProxyClient(lvm), tile);
490+ } catch (final SecurityException ex) {
491+ failed(ex, null, null, null);
492+ } catch (final IOException ex) {
493+ failed(ex, null, null, null);
494+ }
495+ }
496+ }.start();
497+ }
498+
499+ // Call on EDT
500+ void addUrl(final String url,
501+ final String userName,
502+ final String password,
503+ final boolean tile) {
504+ new Thread("JConsole.addUrl") {
505+ public void run() {
506+ try {
507+ addProxyClient(ProxyClient.getProxyClient(url, userName, password),
508+ tile);
509+ } catch (final MalformedURLException ex) {
510+ failed(ex, url, userName, password);
511+ } catch (final SecurityException ex) {
512+ failed(ex, url, userName, password);
513+ } catch (final IOException ex) {
514+ failed(ex, url, userName, password);
515+ }
516+ }
517+ }.start();
518+ }
519+
520+
521+ // Call on EDT
522+ void addHost(final String hostName, final int port,
523+ final String userName, final String password,
524+ final boolean tile) {
525+ new Thread("JConsole.addHost") {
526+ public void run() {
527+ try {
528+ addProxyClient(ProxyClient.getProxyClient(hostName, port,
529+ userName, password),
530+ tile);
531+ } catch (final IOException ex) {
532+ dbgStackTrace(ex);
533+ SwingUtilities.invokeLater(new Runnable() {
534+ public void run() {
535+ showConnectDialog(null, hostName, port,
536+ userName, password, errorMessage(ex));
537+ }
538+ });
539+ }
540+ }
541+ }.start();
542+ }
543+
544+
545+ // Call on worker thread
546+ void addProxyClient(final ProxyClient proxyClient, final boolean tile) {
547+ SwingUtilities.invokeLater(new Runnable() {
548+ public void run() {
549+ VMPanel vmPanel = new VMPanel(proxyClient, updateInterval);
550+ addFrame(vmPanel);
551+
552+ if (tile) {
553+ SwingUtilities.invokeLater(new Runnable() {
554+ public void run() {
555+ tileWindows();
556+ }
557+ });
558+ }
559+ vmPanel.connect();
560+ }
561+ });
562+ }
563+
564+
565+ // Call on worker thread
566+ private void failed(final Exception ex,
567+ final String url,
568+ final String userName,
569+ final String password) {
570+ SwingUtilities.invokeLater(new Runnable() {
571+ public void run() {
572+ dbgStackTrace(ex);
573+ showConnectDialog(url,
574+ null,
575+ -1,
576+ userName,
577+ password,
578+ errorMessage(ex));
579+ }
580+ });
581+ }
582+
583+
584+ private VMInternalFrame addFrame(VMPanel vmPanel) {
585+ final VMInternalFrame vmIF = new VMInternalFrame(vmPanel);
586+
587+ for (VMInternalFrame f : windows) {
588+ try {
589+ f.setMaximum(false);
590+ } catch (PropertyVetoException ex) {
591+ // Ignore
592+ }
593+ }
594+ desktop.add(vmIF);
595+
596+ vmIF.setLocation(frameLoc, frameLoc);
597+ frameLoc += 30;
598+ vmIF.setVisible(true);
599+ windows.add(vmIF);
600+ if (windows.size() == 1) {
601+ try {
602+ vmIF.setMaximum(true);
603+ } catch (PropertyVetoException ex) {
604+ // Ignore
605+ }
606+ }
607+ vmIF.addInternalFrameListener(this);
608+ windowMenu.add(vmIF);
609+
610+ return vmIF;
611+ }
612+
613+ private void showConnectDialog(String url,
614+ String hostName,
615+ int port,
616+ String userName,
617+ String password,
618+ String msg) {
619+ if (connectDialog == null) {
620+ connectDialog = new ConnectDialog(this);
621+ }
622+ connectDialog.setConnectionParameters(url,
623+ hostName,
624+ port,
625+ userName,
626+ password,
627+ msg);
628+
629+ connectDialog.refresh();
630+ connectDialog.setVisible(true);
631+ try {
632+ // Bring to front of other dialogs
633+ connectDialog.setSelected(true);
634+ } catch (PropertyVetoException e) {
635+ }
636+ }
637+
638+ private void showCreateMBeanDialog() {
639+ if (createDialog == null) {
640+ createDialog = new CreateMBeanDialog(this);
641+ }
642+ createDialog.setVisible(true);
643+ try {
644+ // Bring to front of other dialogs
645+ createDialog.setSelected(true);
646+ } catch (PropertyVetoException e) {
647+ }
648+ }
649+
650+ private void removeVMInternalFrame(VMInternalFrame vmIF) {
651+ windowMenu.remove(vmIF);
652+ desktop.remove(vmIF);
653+ desktop.repaint();
654+ vmIF.getVMPanel().cleanUp();
655+ vmIF.dispose();
656+ }
657+
658+ private boolean isProxyClientUsed(ProxyClient client) {
659+ for(VMInternalFrame frame : windows) {
660+ ProxyClient cli = frame.getVMPanel().getProxyClient(false);
661+ if(client == cli)
662+ return true;
663+ }
664+ return false;
665+ }
666+
667+ static boolean isValidRemoteString(String txt) {
668+ boolean valid = false;
669+ if (txt != null) {
670+ txt = txt.trim();
671+ if (txt.startsWith(ROOT_URL)) {
672+ if (txt.length() > ROOT_URL.length()) {
673+ valid = true;
674+ }
675+ } else {
676+ //---------------------------------------
677+ // Supported host and port combinations:
678+ // hostname:port
679+ // IPv4Address:port
680+ // [IPv6Address]:port
681+ //---------------------------------------
682+
683+ // Is literal IPv6 address?
684+ //
685+ if (txt.startsWith("[")) {
686+ int index = txt.indexOf("]:");
687+ if (index != -1) {
688+ // Extract literal IPv6 address
689+ //
690+ String address = txt.substring(1, index);
691+ if (IPAddressUtil.isIPv6LiteralAddress(address)) {
692+ // Extract port
693+ //
694+ try {
695+ String portStr = txt.substring(index + 2);
696+ int port = Integer.parseInt(portStr);
697+ if (port >= 0 && port <= 0xFFFF) {
698+ valid = true;
699+ }
700+ } catch (NumberFormatException ex) {
701+ valid = false;
702+ }
703+ }
704+ }
705+ } else {
706+ String[] s = txt.split(":");
707+ if (s.length == 2) {
708+ try {
709+ int port = Integer.parseInt(s[1]);
710+ if (port >= 0 && port <= 0xFFFF) {
711+ valid = true;
712+ }
713+ } catch (NumberFormatException ex) {
714+ valid = false;
715+ }
716+ }
717+ }
718+ }
719+ }
720+ return valid;
721+ }
722+
723+ private String errorMessage(Exception ex) {
724+ String msg = Resources.getText("Connection failed");
725+ if (ex instanceof IOException || ex instanceof SecurityException) {
726+ Throwable cause = null;
727+ Throwable c = ex.getCause();
728+ while (c != null) {
729+ cause = c;
730+ c = c.getCause();
731+ }
732+ if (cause instanceof ConnectException) {
733+ return msg + ": " + cause.getMessage();
734+ } else if (cause instanceof UnknownHostException) {
735+ return Resources.getText("Unknown Host", cause.getMessage());
736+ } else if (cause instanceof NoRouteToHostException) {
737+ return msg + ": " + cause.getMessage();
738+ } else if (cause instanceof FailedLoginException) {
739+ return msg + ": " + cause.getMessage();
740+ } else if (cause instanceof SSLHandshakeException) {
741+ return msg + ": "+ cause.getMessage();
742+ }
743+ } else if (ex instanceof MalformedURLException) {
744+ return Resources.getText("Invalid URL", ex.getMessage());
745+ }
746+ return msg + ": " + ex.getMessage();
747+ }
748+
749+
750+ // InternalFrameListener interface
751+
752+ public void internalFrameClosing(InternalFrameEvent e) {
753+ VMInternalFrame vmIF = (VMInternalFrame)e.getInternalFrame();
754+ removeVMInternalFrame(vmIF);
755+ windows.remove(vmIF);
756+ ProxyClient client = vmIF.getVMPanel().getProxyClient(false);
757+ if(!isProxyClientUsed(client))
758+ client.markAsDead();
759+ if (windows.size() == 0) {
760+ showConnectDialog("", "", 0, null, null, null);
761+ }
762+ }
763+
764+ public void internalFrameOpened(InternalFrameEvent e) {}
765+ public void internalFrameClosed(InternalFrameEvent e) {}
766+ public void internalFrameIconified(InternalFrameEvent e) {}
767+ public void internalFrameDeiconified(InternalFrameEvent e) {}
768+ public void internalFrameActivated(InternalFrameEvent e) {}
769+ public void internalFrameDeactivated(InternalFrameEvent e) {}
770+
771+
772+ private static void usage() {
773+ System.err.println(Resources.getText("zz usage text", "jconsole"));
774+ }
775+
776+ private static void mainInit(final List<String> urls,
777+ final List<String> hostNames,
778+ final List<Integer> ports,
779+ final List<LocalVirtualMachine> vmids,
780+ final ProxyClient proxyClient,
781+ final boolean noTile,
782+ final boolean hotspot) {
783+
784+
785+ // Always create Swing GUI on the Event Dispatching Thread
786+ SwingUtilities.invokeLater(new Runnable() {
787+ public void run() {
788+ JConsole jConsole = new JConsole(hotspot);
789+
790+ // Center the window on screen, taking into account screen
791+ // size and insets.
792+ Toolkit toolkit = Toolkit.getDefaultToolkit();
793+ GraphicsConfiguration gc = jConsole.getGraphicsConfiguration();
794+ Dimension scrSize = toolkit.getScreenSize();
795+ Insets scrInsets = toolkit.getScreenInsets(gc);
796+ Rectangle scrBounds =
797+ new Rectangle(scrInsets.left, scrInsets.top,
798+ scrSize.width - scrInsets.left - scrInsets.right,
799+ scrSize.height - scrInsets.top - scrInsets.bottom);
800+ int w = Math.min(900, scrBounds.width);
801+ int h = Math.min(750, scrBounds.height);
802+ jConsole.setBounds(scrBounds.x + (scrBounds.width - w) / 2,
803+ scrBounds.y + (scrBounds.height - h) / 2,
804+ w, h);
805+
806+ jConsole.setVisible(true);
807+ jConsole.createMDI();
808+
809+ for (int i = 0; i < hostNames.size(); i++) {
810+ jConsole.addHost(hostNames.get(i), ports.get(i),
811+ null, null,
812+ (i == hostNames.size() - 1) ?
813+ !noTile : false);
814+ }
815+
816+ for (int i = 0; i < urls.size(); i++) {
817+ jConsole.addUrl(urls.get(i),
818+ null,
819+ null,
820+ (i == urls.size() - 1) ?
821+ !noTile : false);
822+ }
823+
824+ for (int i = 0; i < vmids.size(); i++) {
825+ jConsole.addVmid(vmids.get(i),
826+ (i == vmids.size() - 1) ?
827+ !noTile : false);
828+ }
829+
830+ if (vmids.size() == 0 &&
831+ hostNames.size() == 0 &&
832+ urls.size() == 0) {
833+ jConsole.showConnectDialog(null,
834+ null,
835+ 0,
836+ null,
837+ null,
838+ null);
839+ }
840+ }
841+ });
842+ }
843+
844+ public static void main(String[] args) {
845+ boolean noTile = false, hotspot = false;
846+ int argIndex = 0;
847+ ProxyClient proxyClient = null;
848+
849+ if (System.getProperty("jconsole.showOutputViewer") != null) {
850+ OutputViewer.init();
851+ }
852+
853+ while (args.length - argIndex > 0 && args[argIndex].startsWith("-")) {
854+ String arg = args[argIndex++];
855+ if (arg.equals("-h") ||
856+ arg.equals("-help") ||
857+ arg.equals("-?")) {
858+
859+ usage();
860+ return;
861+ } else if (arg.startsWith("-interval=")) {
862+ try {
863+ updateInterval = Integer.parseInt(arg.substring(10)) *
864+ 1000;
865+ } catch (NumberFormatException ex) {
866+ usage();
867+ return;
868+ }
869+ } else if (arg.equals("-pluginpath")) {
870+ if (argIndex < args.length && !args[argIndex].startsWith("-")) {
871+ pluginPath = args[argIndex++];
872+ } else {
873+ // Invalid argument
874+ usage();
875+ return;
876+ }
877+ } else if (arg.equals("-notile")) {
878+ noTile = true;
879+ } else if (arg.equals("-version")) {
880+ Version.print(System.err);
881+ return;
882+ } else if (arg.equals("-debug")) {
883+ debug = true;
884+ } else if (arg.equals("-fullversion")) {
885+ Version.printFullVersion(System.err);
886+ return;
887+ } else {
888+ // Unknown switch
889+ usage();
890+ return;
891+ }
892+ }
893+
894+ if (System.getProperty("jconsole.showUnsupported") != null) {
895+ hotspot = true;
896+ }
897+
898+ List<String> urls = new ArrayList<String>();
899+ List<String> hostNames = new ArrayList<String>();
900+ List<Integer> ports = new ArrayList<Integer>();
901+ List<LocalVirtualMachine> vms = new ArrayList<LocalVirtualMachine>();
902+
903+ for (int i = argIndex; i < args.length; i++) {
904+ String arg = args[i];
905+ if (isValidRemoteString(arg)) {
906+ if (arg.startsWith(ROOT_URL)) {
907+ urls.add(arg);
908+ } else if (arg.matches(".*:[0-9]*")) {
909+ int p = arg.lastIndexOf(':');
910+ hostNames.add(arg.substring(0, p));
911+ try {
912+ ports.add(Integer.parseInt(arg.substring(p+1)));
913+ } catch (NumberFormatException ex) {
914+ usage();
915+ return;
916+ }
917+ }
918+ } else {
919+ if (!isLocalAttachAvailable()) {
920+ System.err.println("Local process monitoring is not supported");
921+ return;
922+ }
923+ try {
924+ int vmid = Integer.parseInt(arg);
925+ LocalVirtualMachine lvm =
926+ LocalVirtualMachine.getLocalVirtualMachine(vmid);
927+ if (lvm == null) {
928+ System.err.println("Invalid process id:" + vmid);
929+ return;
930+ }
931+ vms.add(lvm);
932+ } catch (NumberFormatException ex) {
933+ usage();
934+ return;
935+ }
936+ }
937+ }
938+
939+ mainInit(urls, hostNames, ports, vms, proxyClient, noTile, hotspot);
940+ }
941+
942+ public static boolean isDebug() {
943+ return debug;
944+ }
945+
946+ private static void dbgStackTrace(Exception ex) {
947+ if (debug) {
948+ ex.printStackTrace();
949+ }
950+ }
951+
952+ private static final boolean localAttachmentSupported;
953+ static {
954+ boolean supported;
955+ try {
956+ Class.forName("com.sun.tools.attach.VirtualMachine");
957+ Class.forName("sun.management.ConnectorAddressLink");
958+ supported = true;
959+ } catch (NoClassDefFoundError x) {
960+ supported = false;
961+ } catch (ClassNotFoundException x) {
962+ supported = false;
963+ }
964+ localAttachmentSupported = supported;
965+ }
966+
967+ public static boolean isLocalAttachAvailable() {
968+ return localAttachmentSupported;
969+ }
970+
971+
972+ private static ServiceLoader<JConsolePlugin> pluginService = null;
973+
974+ // Return a list of newly instantiated JConsolePlugin objects
975+ static synchronized List<JConsolePlugin> getPlugins() {
976+ if (pluginService == null) {
977+ // First time loading and initializing the plugins
978+ initPluginService(pluginPath);
979+ } else {
980+ // reload the plugin so that new instances will be created
981+ pluginService.reload();
982+ }
983+
984+ List<JConsolePlugin> plugins = new ArrayList<JConsolePlugin>();
985+ for (JConsolePlugin p : pluginService) {
986+ plugins.add(p);
987+ }
988+ return plugins;
989+ }
990+
991+ private static void initPluginService(String pluginPath) {
992+ if (pluginPath.length() > 0) {
993+ try {
994+ ClassLoader pluginCL = new URLClassLoader(pathToURLs(pluginPath));
995+ ServiceLoader<JConsolePlugin> plugins =
996+ ServiceLoader.load(JConsolePlugin.class, pluginCL);
997+ // validate all plugins
998+ for (JConsolePlugin p : plugins) {
999+ if (isDebug()) {
1000+ System.out.println("Plugin " + p.getClass() + " loaded.");
1001+ }
1002+ }
1003+ pluginService = plugins;
1004+ } catch (ServiceConfigurationError e) {
1005+ // Error occurs during initialization of plugin
1006+ System.out.println(Resources.getText("Fail to load plugin",
1007+ e.getMessage()));
1008+ } catch (MalformedURLException e) {
1009+ if (JConsole.isDebug()) {
1010+ e.printStackTrace();
1011+ }
1012+ System.out.println(Resources.getText("Invalid plugin path",
1013+ e.getMessage()));
1014+ }
1015+ }
1016+
1017+ if (pluginService == null) {
1018+ initEmptyPlugin();
1019+ }
1020+ }
1021+
1022+ private static void initEmptyPlugin() {
1023+ ClassLoader pluginCL = new URLClassLoader(new URL[0]);
1024+ pluginService = ServiceLoader.load(JConsolePlugin.class, pluginCL);
1025+ }
1026+
1027+ /**
1028+ * Utility method for converting a search path string to an array
1029+ * of directory and JAR file URLs.
1030+ *
1031+ * @param path the search path string
1032+ * @return the resulting array of directory and JAR file URLs
1033+ */
1034+ private static URL[] pathToURLs(String path) throws MalformedURLException {
1035+ String[] names = path.split(File.pathSeparator);
1036+ URL[] urls = new URL[names.length];
1037+ int count = 0;
1038+ for (String f : names) {
1039+ URL url = fileToURL(new File(f));
1040+ urls[count++] = url;
1041+ }
1042+ return urls;
1043+ }
1044+
1045+ /**
1046+ * Returns the directory or JAR file URL corresponding to the specified
1047+ * local file name.
1048+ *
1049+ * @param file the File object
1050+ * @return the resulting directory or JAR file URL, or null if unknown
1051+ */
1052+ private static URL fileToURL(File file) throws MalformedURLException {
1053+ String name;
1054+ try {
1055+ name = file.getCanonicalPath();
1056+ } catch (IOException e) {
1057+ name = file.getAbsolutePath();
1058+ }
1059+ name = name.replace(File.separatorChar, '/');
1060+ if (!name.startsWith("/")) {
1061+ name = "/" + name;
1062+ }
1063+ // If the file does not exist, then assume that it's a directory
1064+ if (!file.isFile()) {
1065+ name = name + "/";
1066+ }
1067+ return new URL("file", "", name);
1068+ }
1069+
1070+
1071+ private static class FixedJRootPane extends JRootPane {
1072+ public void updateUI() {
1073+ updateLafValues();
1074+ super.updateUI();
1075+ }
1076+
1077+ /**
1078+ * The revalidate method seems to be the only one that gets
1079+ * called whenever there is a change of L&F or change of theme
1080+ * in Windows L&F and GTK L&F.
1081+ */
1082+ @Override
1083+ public void revalidate() {
1084+ // Workaround for Swing bug where the titledborder in both
1085+ // GTK and Windows L&F's use calculated colors instead of
1086+ // the highlight/shadow colors from the theme.
1087+ //
1088+ // Putting null removes any previous override and causes a
1089+ // fallback to the current L&F's value.
1090+ UIManager.put("TitledBorder.border", null);
1091+ Border border = UIManager.getBorder("TitledBorder.border");
1092+ if (border instanceof BorderUIResource.EtchedBorderUIResource) {
1093+ Color highlight = UIManager.getColor("ToolBar.highlight");
1094+ Color shadow = UIManager.getColor("ToolBar.shadow");
1095+ border = new BorderUIResource.EtchedBorderUIResource(highlight,
1096+ shadow);
1097+ UIManager.put("TitledBorder.border", border);
1098+ }
1099+
1100+ if (IS_GTK) {
1101+ // Workaround for Swing bug where the titledborder in
1102+ // GTK L&F use hardcoded color and font for the title
1103+ // instead of getting them from the theme.
1104+ UIManager.put("TitledBorder.titleColor",
1105+ UIManager.getColor("Label.foreground"));
1106+ UIManager.put("TitledBorder.font",
1107+ UIManager.getFont("Label.font"));
1108+ }
1109+ super.revalidate();
1110+ }
1111+ }
1112+}