KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > netbeans > modules > debugger > jpda > ui > ConnectPanel


1 /*
2  * The contents of this file are subject to the terms of the Common Development
3  * and Distribution License (the License). You may not use this file except in
4  * compliance with the License.
5  *
6  * You can obtain a copy of the License at http://www.netbeans.org/cddl.html
7  * or http://www.netbeans.org/cddl.txt.
8  *
9  * When distributing Covered Code, include this CDDL Header Notice in each file
10  * and include the License file at http://www.netbeans.org/cddl.txt.
11  * If applicable, add the following below the CDDL Header, with the fields
12  * enclosed by brackets [] replaced by your own identifying information:
13  * "Portions Copyrighted [year] [name of copyright owner]"
14  *
15  * The Original Software is NetBeans. The Initial Developer of the Original
16  * Software is Sun Microsystems, Inc. Portions Copyright 1997-2007 Sun
17  * Microsystems, Inc. All Rights Reserved.
18  */

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 JavaDoc;
29 import java.awt.Dimension JavaDoc;
30 import java.awt.GridBagConstraints JavaDoc;
31 import java.awt.GridBagLayout JavaDoc;
32 import java.awt.Insets JavaDoc;
33 import java.awt.Window JavaDoc;
34 import java.awt.event.ActionEvent JavaDoc;
35 import java.awt.event.ActionListener JavaDoc;
36 import java.awt.event.FocusAdapter JavaDoc;
37 import java.awt.event.FocusEvent JavaDoc;
38 import java.io.IOException JavaDoc;
39 import java.text.MessageFormat JavaDoc;
40 import java.util.ArrayList JavaDoc;
41 import java.util.HashMap JavaDoc;
42 import java.util.Iterator JavaDoc;
43 import java.util.List JavaDoc;
44 import java.util.ListIterator JavaDoc;
45 import java.util.Map JavaDoc;
46 import java.util.MissingResourceException JavaDoc;
47 import java.util.TreeSet JavaDoc;
48 import javax.swing.JComboBox JavaDoc;
49 import javax.swing.JLabel JavaDoc;
50 import javax.swing.JPanel JavaDoc;
51 import javax.swing.JTextField JavaDoc;
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 /**
75  * Panel for entering parameters of attaching to a remote VM.
76  * If the debugger offers more
77  * <A HREF="http://java.sun.com/j2se/1.3/docs/guide/jpda/jdi/com/sun/jdi/connect/connector.html">connectors</A>
78  * then the panel contains also a combo-box for selecting a connector.
79  *
80  * @author Jan Jancura
81  */

82 public class ConnectPanel extends JPanel JavaDoc implements
83 Controller, ActionListener JavaDoc {
84
85     /** List of all AttachingConnectors.*/
86     private List JavaDoc connectors;
87     /** Combo with list of all AttachingConnector names.*/
88     private JComboBox JavaDoc cbConnectors;
89     /** List of JTextFields containing all parameters of curentConnector. */
90     private JTextField JavaDoc[] tfParams;
91
92
93     public ConnectPanel () {
94         VirtualMachineManager vmm = Bootstrap.virtualMachineManager ();
95         connectors = new ArrayList JavaDoc ();
96         connectors.addAll (vmm.attachingConnectors ());
97         connectors.addAll (vmm.listeningConnectors ());
98            
99         // We temporary do not support these three connectors
100
// use --cp:a ${JDK_HOME}/lib/sa-jdi.jar to activate them if you uncomment this
101
for (Iterator JavaDoc ci = connectors.iterator(); ci.hasNext(); ) {
102             String JavaDoc 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             // no attaching connectors available => print message only
115
add (new JLabel JavaDoc (
116                 NbBundle.getMessage (ConnectPanel.class, "CTL_No_Connector")
117             ));
118             return;
119         }
120         int defaultIndex = 0;
121         if (connectors.size () > 1) {
122             // more than one attaching connector available =>
123
// init cbConnectors & selext default connector
124

125             cbConnectors = new JComboBox JavaDoc ();
126             cbConnectors.getAccessibleContext ().setAccessibleDescription (
127                 NbBundle.getMessage (ConnectPanel.class, "ACSD_CTL_Connector")
128             );
129             String JavaDoc 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 JavaDoc 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     /**
153      * Adds options for a selected connector type to this panel.
154      */

155     private void refresh (int index) {
156         removeAll();
157         
158         Connector connector = (Connector) connectors.get (index);
159
160         GridBagConstraints JavaDoc c;
161         GridBagLayout JavaDoc layout = new GridBagLayout JavaDoc ();
162         setLayout (layout);
163         
164         if (cbConnectors != null) {
165             // more than oneconnection => first line contains connector
166
// selector
167
c = new GridBagConstraints JavaDoc ();
168                 c.insets = new Insets JavaDoc (0, 0, 3, 3);
169                 c.anchor = c.WEST;
170                 JLabel JavaDoc lblConnectors = new JLabel JavaDoc();
171                 Mnemonics.setLocalizedText(
172                         lblConnectors,
173                         NbBundle.getMessage (ConnectPanel.class, "CTL_Connector") // NOI18N
174
);
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 JavaDoc (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         // second line => transport
190
c = new GridBagConstraints JavaDoc ();
191             c.insets = new Insets JavaDoc (3, 0, 0, 6);
192             c.anchor = c.WEST;
193             JLabel JavaDoc lblTransport = new JLabel JavaDoc();
194             Mnemonics.setLocalizedText(
195                     lblTransport,
196                     NbBundle.getMessage (ConnectPanel.class, "CTL_Transport") // NOI18N
197
);
198             lblTransport.getAccessibleContext ().setAccessibleDescription (
199                 NbBundle.getMessage (ConnectPanel.class, "ACSD_CTL_Transport")
200             );
201             layout.setConstraints (lblTransport, c);
202         add (lblTransport);
203             final JTextField JavaDoc tfTransport = new JTextField JavaDoc ();
204             tfTransport.setEditable (false);
205             lblTransport.setLabelFor (tfTransport);
206             c.gridwidth = GridBagConstraints.REMAINDER;
207             c.insets = new Insets JavaDoc (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 JavaDoc () {
217                 public void focusGained (FocusEvent JavaDoc evt) {
218                     tfTransport.selectAll ();
219                 }
220             });
221         add (tfTransport);
222         
223         // other lines
224
Map JavaDoc args = getSavedArgs (connector);
225         tfParams = new JTextField JavaDoc [args.size ()];
226         Iterator JavaDoc it = new TreeSet JavaDoc (args.keySet ()).iterator ();
227         int i = 0;
228         while (it.hasNext ()) {
229             String JavaDoc name = (String JavaDoc) it.next ();
230             Argument a = (Argument) args.get (name);
231             String JavaDoc label = translate (a.name());
232             if (label == null) {
233                 label = "&"+a.label();
234             }
235                 c = new GridBagConstraints JavaDoc ();
236                 c.insets = new Insets JavaDoc (6, 0, 0, 3);
237                 c.anchor = GridBagConstraints.WEST;
238                 JLabel JavaDoc iLabel = new JLabel JavaDoc();// (label);
239
Mnemonics.setLocalizedText(iLabel, label);
240                 iLabel.setToolTipText (a.description ());
241             add (iLabel, c);
242                 JTextField JavaDoc tfParam = new JTextField JavaDoc (a.value ());
243                 iLabel.setLabelFor (tfParam);
244                 tfParam.setName (name);
245                 tfParam.getAccessibleContext ().setAccessibleDescription (
246                     new MessageFormat JavaDoc (NbBundle.getMessage (
247                         ConnectPanel.class, "ACSD_CTL_Argument"
248                     )).format (new Object JavaDoc[] { label })
249                 );
250                 tfParam.setToolTipText (a.description ());
251                 c = new GridBagConstraints JavaDoc ();
252                 c.gridwidth = GridBagConstraints.REMAINDER;
253                 c.insets = new Insets JavaDoc (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         //
261
// Create an empty panel that resizes vertically so that
262
// other elements have fix height:
263
c = new GridBagConstraints JavaDoc ();
264             c.weighty = 1.0;
265             JPanel JavaDoc p = new JPanel JavaDoc ();
266             p.setPreferredSize (new Dimension JavaDoc (1, 1));
267         add (p, c);
268     }
269
270     /**
271      * Refreshes panel with options corresponding to the selected connector type.
272      * This method is called when a user selects new connector type.
273      */

274     public void actionPerformed (ActionEvent JavaDoc e) {
275         refresh (((JComboBox JavaDoc) e.getSource ()).getSelectedIndex ());
276         Component JavaDoc w = getParent ();
277         while ( (w != null) &&
278                 !(w instanceof Window JavaDoc))
279             w = w.getParent ();
280         if (w != null) ((Window JavaDoc) w).pack (); // ugly hack...
281
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 JavaDoc args = getEditedArgs (tfParams, connector);
292         if (args == null) return true; // CANCEL
293
saveArgs (args, connector);
294         
295         // Take the start off the AWT EQ:
296
final RequestProcessor.Task[] startTaskPtr = new RequestProcessor.Task[1];
297         startTaskPtr[0] = RequestProcessor.getDefault().post(new Runnable JavaDoc() {
298             public void run() {
299                 final Thread JavaDoc 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                     //System.out.println("Before progress.start()");
310
progress.start();
311                     //System.out.println("After progress.start()");
312
DebuggerEngine[] es = null;
313                     if (connector instanceof AttachingConnector)
314                         es = DebuggerManager.getDebuggerManager ().startDebugging (
315                             DebuggerInfo.create (
316                                 AttachingDICookie.ID,
317                                 new Object JavaDoc [] {
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 JavaDoc [] {
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                                 // workaround for #64227
345
if (d.getState() != d.STATE_RUNNING)
346                                     d.waitRunning ();
347                             } catch (DebuggerStartException dsex) {
348                                 //ErrorManager.getDefault().notify(ErrorManager.USER, dsex);
349
// Not necessary to notify - message written to debugger console.
350
}
351                         }
352                     }
353                 } finally {
354                     //System.out.println("Before progress.finish()");
355
progress.finish();
356                     //System.out.println("After progress.finish()");
357
}
358             }
359         });
360         //System.out.println("Before return from ConnectPanel.ok()");
361
return true;
362     }
363     
364     /**
365      * Return <code>true</code> whether value of this customizer
366      * is valid (and OK button can be enabled).
367      *
368      * @return <code>true</code> whether value of this customizer
369      * is valid
370      */

371     public boolean isValid () {
372         return true;
373     }
374     
375     
376     // private helper methods ..................................................
377

378     /**
379      * Is hostname unknown? This method resolves if the specified
380      * string means &quot;hostname&nbsp;unknown&quot;.
381      * Hostname is considered unknown if:
382      * <UL>
383      * <LI>the hostname is <TT>null</TT>
384      * <LI>the hostname is an empty string
385      * <LI>the hostname starts with &quot;<I>x</I><TT>none</TT><I>x</I>&quot;
386      * or &quot;<I>x</I><TT>unknown</TT><I>x</I>&quot;, where <I>x</I>
387      * is any character except <TT>'a'-'z'</TT>, <TT>'A'-'Z'</TT>,
388      * <TT>'-'</TT>.
389      * </UL>
390      *
391      * @param hostname hostname to be resolved
392      * @return <TT>true</TT> if the hostname is considered as unknown,
393      * <TT>false</TT> otherwise
394      */

395     private static boolean isUnknownHost (String JavaDoc 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"); //NOI18N
416
}
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"); //NOI18N
423
}
424         return false;
425     }
426
427 // private static String getLastAttachingConnectorName () {
428
// JPDADebuggerProjectSettings settings = (JPDADebuggerProjectSettings)
429
// JPDADebuggerProjectSettings.findObject (
430
// JPDADebuggerProjectSettings.class,
431
// true
432
// );
433
// return settings.getLastConnector ();
434
// }
435

436     private static Map JavaDoc getSavedArgs (Connector connector) {
437         // 1) get default set of args
438
Map JavaDoc args = connector.defaultArguments ();
439
440         // 2) load saved version of args
441
Map JavaDoc savedArgs = Properties.getDefault ().getProperties ("debugger").
442                 getMap ("connection_settings", new HashMap JavaDoc ());
443         savedArgs = (Map JavaDoc) savedArgs.get (connector.name ());
444         if (savedArgs == null) return args;
445         
446         // 3) refres default args about saved values
447
Iterator JavaDoc i = args.keySet ().iterator ();
448         while (i.hasNext()) {
449             String JavaDoc argName = (String JavaDoc) i.next ();
450             String JavaDoc savedValue = (String JavaDoc) savedArgs.get (argName);
451             if (savedValue != null)
452                 ((Argument) args.get (argName)).setValue (savedValue);
453         }
454         return args;
455     }
456
457     private static Map JavaDoc getEditedArgs (
458         JTextField JavaDoc[] tfParams,
459         Connector connector
460     ) {
461         // 1) get default set of args
462
Map JavaDoc args = connector.defaultArguments ();
463
464         // 2) update values from text fields
465
int i, k = tfParams.length;
466         for (i = 0; i < k; i++) {
467             JTextField JavaDoc tf = tfParams [i];
468             String JavaDoc paramName = tf.getName ();
469             String JavaDoc 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 JavaDoc 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 JavaDoc args,
513         Connector connector
514     ) {
515         Map JavaDoc defaultValues = connector.defaultArguments ();
516         Map JavaDoc argsToSave = new HashMap JavaDoc ();
517         Iterator JavaDoc i = args.keySet ().iterator ();
518         while (i.hasNext()) {
519             String JavaDoc argName = (String JavaDoc) 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 JavaDoc m = Properties.getDefault ().getProperties ("debugger").
530             getMap ("connection_settings", new HashMap JavaDoc ());
531         String JavaDoc 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 JavaDoc translate (String JavaDoc str) {
540         try {
541             return NbBundle.getMessage(ConnectPanel.class, "CTL_CA_"+str);
542         } catch (MissingResourceException JavaDoc 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