1 /*
   2  * Copyright (c) 1999, 2011, 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 /*
  27  * This source code is provided to illustrate the usage of a given feature
  28  * or technique and has been deliberately simplified. Additional steps
  29  * required for a production-quality application, such as security checks,
  30  * input validation and proper error handling, might not be present in
  31  * this sample code.
  32  */
  33 
  34 
  35 package com.sun.tools.example.debug.gui;
  36 
  37 import java.util.List;
  38 import java.util.ArrayList;
  39 import java.util.Map;
  40 import java.util.HashMap;
  41 import java.awt.BorderLayout;
  42 import java.awt.Container;
  43 import java.awt.event.ActionEvent;
  44 import java.awt.event.ActionListener;
  45 import javax.swing.*;
  46 import javax.swing.border.Border;
  47 import javax.swing.border.TitledBorder;
  48 
  49 import com.sun.jdi.*;
  50 import com.sun.jdi.connect.*;
  51 
  52 import com.sun.tools.example.debug.bdi.*;
  53 
  54 class LaunchTool {
  55 
  56     private final ExecutionManager runtime;
  57 
  58     private abstract class ArgRep {
  59         final Connector.Argument arg;
  60         final JPanel panel;
  61 
  62         ArgRep(Connector.Argument arg) {
  63             this.arg = arg;
  64             panel = new JPanel();
  65             Border etched = BorderFactory.createEtchedBorder();
  66             Border titled = BorderFactory.createTitledBorder(etched,
  67                                       arg.description(),
  68                                       TitledBorder.LEFT, TitledBorder.TOP);
  69             panel.setBorder(titled);
  70         }
  71 
  72         abstract String getText();
  73 
  74         boolean isValid() {
  75             return arg.isValid(getText());
  76         }
  77 
  78         boolean isSpecified() {
  79             String value = getText();
  80             return (value != null && value.length() > 0) ||
  81                 !arg.mustSpecify();
  82         }
  83 
  84         void install() {
  85             arg.setValue(getText());
  86         }
  87     }
  88 
  89     private class StringArgRep extends ArgRep {
  90         final JTextField textField;
  91 
  92         StringArgRep(Connector.Argument arg, JPanel comp) {
  93             super(arg);
  94             textField = new JTextField(arg.value(), 50 );
  95             textField.setBorder(BorderFactory.createLoweredBevelBorder());
  96 
  97             panel.add(new JLabel(arg.label(), SwingConstants.RIGHT));
  98             panel.add(textField); // , BorderLayout.CENTER);
  99             comp.add(panel);
 100         }
 101 
 102         @Override
 103         String getText() {
 104             return textField.getText();
 105         }
 106     }
 107 
 108     private class BooleanArgRep extends ArgRep {
 109         final JCheckBox check;
 110 
 111         BooleanArgRep(Connector.BooleanArgument barg, JPanel comp) {
 112             super(barg);
 113             check = new JCheckBox(barg.label());
 114             check.setSelected(barg.booleanValue());
 115             panel.add(check);
 116             comp.add(panel);
 117         }
 118 
 119         @Override
 120         String getText() {
 121             return ((Connector.BooleanArgument)arg)
 122                            .stringValueOf(check.getModel().isSelected());
 123         }
 124     }
 125 
 126 
 127     private LaunchTool(ExecutionManager runtime) {
 128         this.runtime = runtime;
 129     }
 130 
 131     private Connector selectConnector() {
 132         final JDialog dialog = new JDialog();
 133         Container content = dialog.getContentPane();
 134         final JPanel radioPanel = new JPanel();
 135         final ButtonGroup radioGroup = new ButtonGroup();
 136         VirtualMachineManager manager = Bootstrap.virtualMachineManager();
 137         List<Connector> all = manager.allConnectors();
 138         Map<ButtonModel, Connector> modelToConnector = new HashMap<ButtonModel, Connector>(all.size(), 0.5f);
 139 
 140         dialog.setModal(true);
 141         dialog.setTitle("Select Connector Type");
 142         radioPanel.setLayout(new BoxLayout(radioPanel, BoxLayout.Y_AXIS));
 143         for (Connector connector : all) {
 144             JRadioButton radio = new JRadioButton(connector.description());
 145             modelToConnector.put(radio.getModel(), connector);
 146             radioPanel.add(radio);
 147             radioGroup.add(radio);
 148         }
 149         content.add(radioPanel);
 150 
 151         final boolean[] oked = {false};
 152         JPanel buttonPanel = okCancel( dialog, new ActionListener() {
 153             @Override
 154             public void actionPerformed(ActionEvent event) {
 155                 if (radioGroup.getSelection() == null) {
 156                     JOptionPane.showMessageDialog(dialog,
 157                                     "Please select a connector type",
 158                                     "No Selection",
 159                                      JOptionPane.ERROR_MESSAGE);
 160                 } else {
 161                     oked[0] = true;
 162                     dialog.setVisible(false);
 163                     dialog.dispose();
 164                 }
 165             }
 166         } );
 167         content.add(BorderLayout.SOUTH, buttonPanel);
 168         dialog.pack();
 169         dialog.setVisible(true);
 170 
 171         return oked[0] ?
 172             modelToConnector.get(radioGroup.getSelection()) :
 173             null;
 174     }
 175 
 176     private void configureAndConnect(final Connector connector) {
 177         final JDialog dialog = new JDialog();
 178         final Map<String, Connector.Argument> args = connector.defaultArguments();
 179 
 180         dialog.setModal(true);
 181         dialog.setTitle("Connector Arguments");
 182         Container content = dialog.getContentPane();
 183         JPanel guts = new JPanel();
 184         Border etched = BorderFactory.createEtchedBorder();
 185         BorderFactory.createTitledBorder(etched,
 186                                 connector.description(),
 187                                 TitledBorder.LEFT, TitledBorder.TOP);
 188         guts.setBorder(etched);
 189         guts.setLayout(new BoxLayout(guts, BoxLayout.Y_AXIS));
 190 
 191         //        guts.add(new JLabel(connector.description()));
 192 
 193         final List<ArgRep> argReps = new ArrayList<ArgRep>(args.size());
 194         for (Connector.Argument arg : args.values()) {
 195             ArgRep ar;
 196             if (arg instanceof Connector.BooleanArgument) {
 197                 ar = new BooleanArgRep((Connector.BooleanArgument)arg, guts);
 198             } else {
 199                 ar = new StringArgRep(arg, guts);
 200             }
 201             argReps.add(ar);
 202         }
 203         content.add(guts);
 204 
 205         JPanel buttonPanel = okCancel( dialog, new ActionListener() {
 206             @Override
 207             public void actionPerformed(ActionEvent event) {
 208                 for (ArgRep ar : argReps) {
 209                     if (!ar.isSpecified()) {
 210                         JOptionPane.showMessageDialog(dialog,
 211                                     ar.arg.label() +
 212                                          ": Argument must be specified",
 213                                     "No argument", JOptionPane.ERROR_MESSAGE);
 214                         return;
 215                     }
 216                     if (!ar.isValid()) {
 217                         JOptionPane.showMessageDialog(dialog,
 218                                     ar.arg.label() +
 219                                          ": Bad argument value: " +
 220                                          ar.getText(),
 221                                     "Bad argument", JOptionPane.ERROR_MESSAGE);
 222                         return;
 223                     }
 224                     ar.install();
 225                 }
 226                 try {
 227                     if (runtime.explictStart(connector, args)) {
 228                         dialog.setVisible(false);
 229                         dialog.dispose();
 230                     } else {
 231                         JOptionPane.showMessageDialog(dialog,
 232                            "Bad arguments values: See diagnostics window.",
 233                            "Bad arguments", JOptionPane.ERROR_MESSAGE);
 234                     }
 235                 } catch (VMLaunchFailureException exc) {
 236                         JOptionPane.showMessageDialog(dialog,
 237                            "Launch Failure: " + exc,
 238                            "Launch Failed",JOptionPane.ERROR_MESSAGE);
 239                 }
 240             }
 241         } );
 242         content.add(BorderLayout.SOUTH, buttonPanel);
 243         dialog.pack();
 244         dialog.setVisible(true);
 245     }
 246 
 247     private JPanel okCancel(final JDialog dialog, ActionListener okListener) {
 248         JPanel buttonPanel = new JPanel();
 249         JButton ok = new JButton("OK");
 250         JButton cancel = new JButton("Cancel");
 251         buttonPanel.add(ok);
 252         buttonPanel.add(cancel);
 253         ok.addActionListener(okListener);
 254         cancel.addActionListener( new ActionListener() {
 255             @Override
 256             public void actionPerformed(ActionEvent event) {
 257                 dialog.setVisible(false);
 258                 dialog.dispose();
 259             }
 260         } );
 261         return buttonPanel;
 262     }
 263 
 264     static void queryAndLaunchVM(ExecutionManager runtime)
 265                                          throws VMLaunchFailureException {
 266         LaunchTool lt = new LaunchTool(runtime);
 267         Connector connector = lt.selectConnector();
 268         if (connector != null) {
 269             lt.configureAndConnect(connector);
 270         }
 271     }
 272 }