1 19 20 package org.netbeans.modules.debugger.jpda.ui; 21 22 import com.sun.jdi.Bootstrap; 23 import com.sun.jdi.VirtualMachine; 24 import com.sun.jdi.VirtualMachineManager; 25 import com.sun.jdi.connect.Connector.Argument; 26 import com.sun.jdi.connect.*; 27 28 import java.awt.Component ; 29 import java.awt.Dimension ; 30 import java.awt.GridBagConstraints ; 31 import java.awt.GridBagLayout ; 32 import java.awt.Insets ; 33 import java.awt.Window ; 34 import java.awt.event.ActionEvent ; 35 import java.awt.event.ActionListener ; 36 import java.awt.event.FocusAdapter ; 37 import java.awt.event.FocusEvent ; 38 import java.io.IOException ; 39 import java.text.MessageFormat ; 40 import java.util.ArrayList ; 41 import java.util.HashMap ; 42 import java.util.Iterator ; 43 import java.util.List ; 44 import java.util.ListIterator ; 45 import java.util.Map ; 46 import java.util.MissingResourceException ; 47 import java.util.TreeSet ; 48 import javax.swing.JComboBox ; 49 import javax.swing.JLabel ; 50 import javax.swing.JPanel ; 51 import javax.swing.JTextField ; 52 import org.netbeans.api.debugger.DebuggerEngine; 53 54 import org.netbeans.api.debugger.DebuggerManager; 55 import org.netbeans.api.debugger.DebuggerInfo; 56 import org.netbeans.api.debugger.Properties; 57 import org.netbeans.api.debugger.jpda.DebuggerStartException; 58 import org.netbeans.api.debugger.jpda.JPDADebugger; 59 import org.netbeans.api.debugger.jpda.AbstractDICookie; 60 import org.netbeans.api.debugger.jpda.AttachingDICookie; 61 import org.netbeans.api.debugger.jpda.ListeningDICookie; 62 import org.netbeans.api.progress.ProgressHandle; 63 import org.netbeans.api.progress.ProgressHandleFactory; 64 import org.netbeans.spi.debugger.ui.Controller; 65 import org.openide.DialogDisplayer; 66 import org.openide.ErrorManager; 67 import org.openide.NotifyDescriptor; 68 import org.openide.awt.Mnemonics; 69 import org.openide.util.Cancellable; 70 import org.openide.util.NbBundle; 71 import org.openide.util.RequestProcessor; 72 73 74 82 public class ConnectPanel extends JPanel implements 83 Controller, ActionListener { 84 85 86 private List connectors; 87 88 private JComboBox cbConnectors; 89 90 private JTextField [] tfParams; 91 92 93 public ConnectPanel () { 94 VirtualMachineManager vmm = Bootstrap.virtualMachineManager (); 95 connectors = new ArrayList (); 96 connectors.addAll (vmm.attachingConnectors ()); 97 connectors.addAll (vmm.listeningConnectors ()); 98 99 for (Iterator ci = connectors.iterator(); ci.hasNext(); ) { 102 String name = ((Connector)ci.next()).name(); 103 int index = name.lastIndexOf('.'); 104 if (index >= 0) 105 name = name.substring(index + 1); 106 107 if (name.equalsIgnoreCase("SACoreAttachingConnector") || 108 name.equalsIgnoreCase("SAPIDAttachingConnector") || 109 name.equalsIgnoreCase("SADebugServerAttachingConnector")) 110 ci.remove(); 111 } 112 113 if (connectors.size () == 0) { 114 add (new JLabel ( 116 NbBundle.getMessage (ConnectPanel.class, "CTL_No_Connector") 117 )); 118 return; 119 } 120 int defaultIndex = 0; 121 if (connectors.size () > 1) { 122 125 cbConnectors = new JComboBox (); 126 cbConnectors.getAccessibleContext ().setAccessibleDescription ( 127 NbBundle.getMessage (ConnectPanel.class, "ACSD_CTL_Connector") 128 ); 129 String lacn = Properties.getDefault ().getProperties ("debugger"). 130 getString ("last_attaching_connector", ""); 131 int i, k = connectors.size (); 132 for (i = 0; i < k; i++) { 133 Connector connector = (Connector) connectors.get (i); 134 if ((lacn != null) && connector.name ().equals (lacn)) 135 defaultIndex = i; 136 int jj = connector.name ().lastIndexOf ('.'); 137 138 String s = (jj < 0) ? 139 connector.name () : 140 connector.name ().substring (jj + 1); 141 cbConnectors.addItem ( 142 s + " (" + connector.description () + ")" 143 ); 144 } 145 cbConnectors.setActionCommand ("SwitchMe!"); 146 cbConnectors.addActionListener (this); 147 } 148 149 cbConnectors.setSelectedIndex (defaultIndex); 150 } 151 152 155 private void refresh (int index) { 156 removeAll(); 157 158 Connector connector = (Connector) connectors.get (index); 159 160 GridBagConstraints c; 161 GridBagLayout layout = new GridBagLayout (); 162 setLayout (layout); 163 164 if (cbConnectors != null) { 165 c = new GridBagConstraints (); 168 c.insets = new Insets (0, 0, 3, 3); 169 c.anchor = c.WEST; 170 JLabel lblConnectors = new JLabel (); 171 Mnemonics.setLocalizedText( 172 lblConnectors, 173 NbBundle.getMessage (ConnectPanel.class, "CTL_Connector") ); 175 lblConnectors.getAccessibleContext ().setAccessibleDescription ( 176 NbBundle.getMessage (ConnectPanel.class, "ACSD_CTL_Connector") 177 ); 178 lblConnectors.setLabelFor (cbConnectors); 179 layout.setConstraints (lblConnectors, c); 180 add (lblConnectors); 181 c.insets = new Insets (0, 3, 3, 0); 182 c.weightx = 1.0; 183 c.fill = GridBagConstraints.HORIZONTAL; 184 c.gridwidth = GridBagConstraints.REMAINDER; 185 layout.setConstraints (cbConnectors, c); 186 add (cbConnectors); 187 } 188 189 c = new GridBagConstraints (); 191 c.insets = new Insets (3, 0, 0, 6); 192 c.anchor = c.WEST; 193 JLabel lblTransport = new JLabel (); 194 Mnemonics.setLocalizedText( 195 lblTransport, 196 NbBundle.getMessage (ConnectPanel.class, "CTL_Transport") ); 198 lblTransport.getAccessibleContext ().setAccessibleDescription ( 199 NbBundle.getMessage (ConnectPanel.class, "ACSD_CTL_Transport") 200 ); 201 layout.setConstraints (lblTransport, c); 202 add (lblTransport); 203 final JTextField tfTransport = new JTextField (); 204 tfTransport.setEditable (false); 205 lblTransport.setLabelFor (tfTransport); 206 c.gridwidth = GridBagConstraints.REMAINDER; 207 c.insets = new Insets (3, 3, 0, 0); 208 c.fill = GridBagConstraints.HORIZONTAL; 209 c.weightx = 1.0; 210 layout.setConstraints (tfTransport, c); 211 Transport t = connector.transport(); 212 tfTransport.setText (t != null ? t.name() : ""); 213 tfTransport.getAccessibleContext ().setAccessibleDescription ( 214 NbBundle.getMessage (ConnectPanel.class, "ACSD_CTL_Transport") 215 ); 216 tfTransport.addFocusListener (new FocusAdapter () { 217 public void focusGained (FocusEvent evt) { 218 tfTransport.selectAll (); 219 } 220 }); 221 add (tfTransport); 222 223 Map args = getSavedArgs (connector); 225 tfParams = new JTextField [args.size ()]; 226 Iterator it = new TreeSet (args.keySet ()).iterator (); 227 int i = 0; 228 while (it.hasNext ()) { 229 String name = (String ) it.next (); 230 Argument a = (Argument) args.get (name); 231 String label = translate (a.name()); 232 if (label == null) { 233 label = "&"+a.label(); 234 } 235 c = new GridBagConstraints (); 236 c.insets = new Insets (6, 0, 0, 3); 237 c.anchor = GridBagConstraints.WEST; 238 JLabel iLabel = new JLabel (); Mnemonics.setLocalizedText(iLabel, label); 240 iLabel.setToolTipText (a.description ()); 241 add (iLabel, c); 242 JTextField tfParam = new JTextField (a.value ()); 243 iLabel.setLabelFor (tfParam); 244 tfParam.setName (name); 245 tfParam.getAccessibleContext ().setAccessibleDescription ( 246 new MessageFormat (NbBundle.getMessage ( 247 ConnectPanel.class, "ACSD_CTL_Argument" 248 )).format (new Object [] { label }) 249 ); 250 tfParam.setToolTipText (a.description ()); 251 c = new GridBagConstraints (); 252 c.gridwidth = GridBagConstraints.REMAINDER; 253 c.insets = new Insets (6, 3, 0, 0); 254 c.fill = GridBagConstraints.HORIZONTAL; 255 c.weightx = 1.0; 256 add (tfParam, c); 257 tfParams [i ++] = tfParam; 258 } 259 260 c = new GridBagConstraints (); 264 c.weighty = 1.0; 265 JPanel p = new JPanel (); 266 p.setPreferredSize (new Dimension (1, 1)); 267 add (p, c); 268 } 269 270 274 public void actionPerformed (ActionEvent e) { 275 refresh (((JComboBox ) e.getSource ()).getSelectedIndex ()); 276 Component w = getParent (); 277 while ( (w != null) && 278 !(w instanceof Window )) 279 w = w.getParent (); 280 if (w != null) ((Window ) w).pack (); return; 282 } 283 284 public boolean cancel () { 285 return true; 286 } 287 288 public boolean ok () { 289 int index = cbConnectors.getSelectedIndex (); 290 final Connector connector = (Connector) connectors.get (index); 291 final Map args = getEditedArgs (tfParams, connector); 292 if (args == null) return true; saveArgs (args, connector); 294 295 final RequestProcessor.Task[] startTaskPtr = new RequestProcessor.Task[1]; 297 startTaskPtr[0] = RequestProcessor.getDefault().post(new Runnable () { 298 public void run() { 299 final Thread theCurrentThread = Thread.currentThread(); 300 ProgressHandle progress = ProgressHandleFactory.createHandle( 301 NbBundle.getMessage(ConnectPanel.class, "CTL_connectProgress"), 302 new Cancellable() { 303 public boolean cancel() { 304 theCurrentThread.interrupt(); 305 return startTaskPtr[0].isFinished(); 306 } 307 }); 308 try { 309 progress.start(); 311 DebuggerEngine[] es = null; 313 if (connector instanceof AttachingConnector) 314 es = DebuggerManager.getDebuggerManager ().startDebugging ( 315 DebuggerInfo.create ( 316 AttachingDICookie.ID, 317 new Object [] { 318 AttachingDICookie.create ( 319 (AttachingConnector) connector, 320 args 321 ) 322 } 323 ) 324 ); 325 else 326 if (connector instanceof ListeningConnector) 327 es = DebuggerManager.getDebuggerManager ().startDebugging ( 328 DebuggerInfo.create ( 329 ListeningDICookie.ID, 330 new Object [] { 331 ListeningDICookie.create ( 332 (ListeningConnector) connector, 333 args 334 ) 335 } 336 ) 337 ); 338 if (es != null) { 339 for (int i = 0; i < es.length; i++) { 340 JPDADebugger d = (JPDADebugger) es [i].lookupFirst 341 (null, JPDADebugger.class); 342 if (d == null) continue; 343 try { 344 if (d.getState() != d.STATE_RUNNING) 346 d.waitRunning (); 347 } catch (DebuggerStartException dsex) { 348 } 351 } 352 } 353 } finally { 354 progress.finish(); 356 } 358 } 359 }); 360 return true; 362 } 363 364 371 public boolean isValid () { 372 return true; 373 } 374 375 376 378 395 private static boolean isUnknownHost (String hostname) { 396 if (hostname == null) { 397 return true; 398 } 399 int length = hostname.length(); 400 if (length == 0) { 401 return true; 402 } 403 if (length < 6) { 404 return false; 405 } 406 char firstChar = hostname.charAt(0); 407 if (('a' <= firstChar && firstChar <= 'z') 408 || ('A' <= firstChar && firstChar <= 'Z') 409 || (firstChar == '-')) { 410 return false; 411 } 412 char c; 413 c = hostname.charAt(5); 414 if (c == firstChar) { 415 return hostname.substring(1, 5).equalsIgnoreCase("none"); } 417 if (length < 9) { 418 return false; 419 } 420 c = hostname.charAt(8); 421 if (c == firstChar) { 422 return hostname.substring(1, 8).equalsIgnoreCase("unknown"); } 424 return false; 425 } 426 427 436 private static Map getSavedArgs (Connector connector) { 437 Map args = connector.defaultArguments (); 439 440 Map savedArgs = Properties.getDefault ().getProperties ("debugger"). 442 getMap ("connection_settings", new HashMap ()); 443 savedArgs = (Map ) savedArgs.get (connector.name ()); 444 if (savedArgs == null) return args; 445 446 Iterator i = args.keySet ().iterator (); 448 while (i.hasNext()) { 449 String argName = (String ) i.next (); 450 String savedValue = (String ) savedArgs.get (argName); 451 if (savedValue != null) 452 ((Argument) args.get (argName)).setValue (savedValue); 453 } 454 return args; 455 } 456 457 private static Map getEditedArgs ( 458 JTextField [] tfParams, 459 Connector connector 460 ) { 461 Map args = connector.defaultArguments (); 463 464 int i, k = tfParams.length; 466 for (i = 0; i < k; i++) { 467 JTextField tf = tfParams [i]; 468 String paramName = tf.getName (); 469 String paramValue = tf.getText (); 470 Argument a = (Argument) args.get (paramName); 471 while ( ((!a.isValid (paramValue)) && (!"".equals (paramValue))) || 472 ( "".equals (paramValue) && a.mustSpecify () ) 473 ) { 474 NotifyDescriptor.InputLine in = null; 475 String label = translate (a.name()); 476 if (label == null) { 477 label = a.label(); 478 } else { 479 int amp = Mnemonics.findMnemonicAmpersand(label); 480 if (amp >= 0) { 481 label = label.substring(0, amp) + label.substring(amp + 1); 482 } 483 } 484 if ( "".equals (paramValue) && a.mustSpecify ()) 485 in = new NotifyDescriptor.InputLine ( 486 label, 487 NbBundle.getMessage ( 488 ConnectPanel.class, 489 "CTL_Required_value_title" 490 ) 491 ); 492 else 493 in = new NotifyDescriptor.InputLine ( 494 label, 495 NbBundle.getMessage ( 496 ConnectPanel.class, 497 "CTL_Invalid_value_title" 498 ) 499 ); 500 if (DialogDisplayer.getDefault ().notify (in) == 501 NotifyDescriptor.CANCEL_OPTION 502 ) return null; 503 paramValue = in.getInputText (); 504 } 505 a.setValue (paramValue); 506 } 507 508 return args; 509 } 510 511 private static void saveArgs ( 512 Map args, 513 Connector connector 514 ) { 515 Map defaultValues = connector.defaultArguments (); 516 Map argsToSave = new HashMap (); 517 Iterator i = args.keySet ().iterator (); 518 while (i.hasNext()) { 519 String argName = (String ) i.next (); 520 Argument value = (Argument) args.get (argName); 521 Argument defaultValue = (Argument) defaultValues.get (argName); 522 if ( value != null && 523 value != defaultValue && 524 !value.equals (defaultValue) 525 ) 526 argsToSave.put (argName, value.value ()); 527 } 528 529 Map m = Properties.getDefault ().getProperties ("debugger"). 530 getMap ("connection_settings", new HashMap ()); 531 String name = connector.name (); 532 m.put (name, argsToSave); 533 Properties.getDefault ().getProperties ("debugger"). 534 setString ("last_attaching_connector", name); 535 Properties.getDefault ().getProperties ("debugger"). 536 setMap ("connection_settings", m); 537 } 538 539 private static String translate (String str) { 540 try { 541 return NbBundle.getMessage(ConnectPanel.class, "CTL_CA_"+str); 542 } catch (MissingResourceException mrex) { 543 ErrorManager.getDefault().log(ErrorManager.WARNING, "Missing resource "+"CTL_CA_"+str+" from "+ConnectPanel.class.getName()); 544 return null; 545 } 546 } 547 548 } 549 550 | Popular Tags |