]> sjero.net Git - linphone/blob - p2pproxy/dependencies-src/jxse-src-2.5/impl/src/net/jxta/impl/peergroup/ConfigDialog.java
285e3a848300ea7058fc83360902b95016dc62cc
[linphone] / p2pproxy / dependencies-src / jxse-src-2.5 / impl / src / net / jxta / impl / peergroup / ConfigDialog.java
1 /*
2  * Copyright (c) 2001-2007 Sun Microsystems, Inc.  All rights reserved.
3  *  
4  *  The Sun Project JXTA(TM) Software License
5  *  
6  *  Redistribution and use in source and binary forms, with or without 
7  *  modification, are permitted provided that the following conditions are met:
8  *  
9  *  1. Redistributions of source code must retain the above copyright notice,
10  *     this list of conditions and the following disclaimer.
11  *  
12  *  2. Redistributions in binary form must reproduce the above copyright notice, 
13  *     this list of conditions and the following disclaimer in the documentation 
14  *     and/or other materials provided with the distribution.
15  *  
16  *  3. The end-user documentation included with the redistribution, if any, must 
17  *     include the following acknowledgment: "This product includes software 
18  *     developed by Sun Microsystems, Inc. for JXTA(TM) technology." 
19  *     Alternately, this acknowledgment may appear in the software itself, if 
20  *     and wherever such third-party acknowledgments normally appear.
21  *  
22  *  4. The names "Sun", "Sun Microsystems, Inc.", "JXTA" and "Project JXTA" must 
23  *     not be used to endorse or promote products derived from this software 
24  *     without prior written permission. For written permission, please contact 
25  *     Project JXTA at http://www.jxta.org.
26  *  
27  *  5. Products derived from this software may not be called "JXTA", nor may 
28  *     "JXTA" appear in their name, without prior written permission of Sun.
29  *  
30  *  THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES,
31  *  INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND 
32  *  FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL SUN 
33  *  MICROSYSTEMS OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, 
34  *  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 
35  *  LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, 
36  *  OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF 
37  *  LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 
38  *  NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, 
39  *  EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
40  *  
41  *  JXTA is a registered trademark of Sun Microsystems, Inc. in the United 
42  *  States and other countries.
43  *  
44  *  Please see the license information page at :
45  *  <http://www.jxta.org/project/www/license.html> for instructions on use of 
46  *  the license in source files.
47  *  
48  *  ====================================================================
49  *  
50  *  This software consists of voluntary contributions made by many individuals 
51  *  on behalf of Project JXTA. For more information on Project JXTA, please see 
52  *  http://www.jxta.org.
53  *  
54  *  This license is based on the BSD license adopted by the Apache Foundation. 
55  */
56 package net.jxta.impl.peergroup;
57
58 import java.awt.BorderLayout;
59 import java.awt.Button;
60 import java.awt.CardLayout;
61 import java.awt.Checkbox;
62 import java.awt.Choice;
63 import java.awt.Color;
64 import java.awt.Dimension;
65 import java.awt.FlowLayout;
66 import java.awt.Font;
67 import java.awt.FontMetrics;
68 import java.awt.Frame;
69 import java.awt.Graphics;
70 import java.awt.GridBagConstraints;
71 import java.awt.GridBagLayout;
72 import java.awt.GridLayout;
73 import java.awt.Insets;
74 import java.awt.Label;
75 import java.awt.Panel;
76 import java.awt.TextField;
77 import java.awt.event.ActionEvent;
78 import java.awt.event.ActionListener;
79 import java.awt.event.ItemEvent;
80 import java.awt.event.ItemListener;
81 import java.awt.event.MouseAdapter;
82 import java.awt.event.MouseEvent;
83 import java.awt.event.WindowAdapter;
84 import java.awt.event.WindowEvent;
85 import java.net.InetAddress;
86 import java.net.URI;
87 import java.net.URISyntaxException;
88 import java.util.ArrayList;
89 import java.util.Arrays;
90 import java.util.Enumeration;
91 import java.util.Iterator;
92 import java.util.List;
93 import java.util.NoSuchElementException;
94
95 import net.jxta.document.Advertisement;
96 import net.jxta.document.AdvertisementFactory;
97 import net.jxta.document.MimeMediaType;
98 import net.jxta.document.StructuredDocumentFactory;
99 import net.jxta.document.StructuredDocumentUtils;
100 import net.jxta.document.XMLDocument;
101 import net.jxta.document.XMLElement;
102 import net.jxta.endpoint.EndpointAddress;
103 import net.jxta.peergroup.PeerGroup;
104 import net.jxta.protocol.TransportAdvertisement;
105
106 import net.jxta.exception.JxtaError;
107 import net.jxta.exception.ConfiguratorException;
108
109 import net.jxta.impl.endpoint.IPUtils;
110 import net.jxta.impl.membership.pse.PSEUtils;
111 import net.jxta.impl.protocol.HTTPAdv;
112 import net.jxta.impl.protocol.PSEConfigAdv;
113 import net.jxta.impl.protocol.PlatformConfig;
114 import net.jxta.impl.protocol.RdvConfigAdv;
115 import net.jxta.impl.protocol.RdvConfigAdv.RendezVousConfiguration;
116 import net.jxta.impl.protocol.RelayConfigAdv;
117 import net.jxta.impl.protocol.TCPAdv;
118
119 /**
120  * The standard and much loved AWT Configuration dialog
121  */
122 @SuppressWarnings("serial")
123 public class ConfigDialog extends Frame {
124
125     static final GridBagConstraints stdConstr;
126     static final GridBagConstraints centerConstr;
127     static final GridBagConstraints centerLastConstr;
128     static final GridBagConstraints fillConstr;
129     static final GridBagConstraints fillInsetConstr;
130
131     static {
132         stdConstr = new GridBagConstraints();
133         stdConstr.gridwidth = GridBagConstraints.REMAINDER;
134         stdConstr.gridheight = 1;
135         stdConstr.gridx = 0;
136         stdConstr.gridy = GridBagConstraints.RELATIVE;
137         stdConstr.fill = GridBagConstraints.NONE;
138         stdConstr.weightx = 1;
139         stdConstr.anchor = GridBagConstraints.NORTHWEST;
140         stdConstr.insets = new Insets(0, 0, 0, 0);
141
142         fillConstr = (GridBagConstraints) stdConstr.clone();
143         fillConstr.fill = GridBagConstraints.HORIZONTAL;
144
145         centerConstr = (GridBagConstraints) stdConstr.clone();
146         centerConstr.anchor = GridBagConstraints.NORTH;
147
148         centerLastConstr = (GridBagConstraints) centerConstr.clone();
149         centerLastConstr.weighty = 1;
150
151         fillInsetConstr = (GridBagConstraints) fillConstr.clone();
152
153         fillInsetConstr.insets = new Insets(5, 5, 5, 5);
154     }
155
156     // A few widgets.
157
158     /**
159      * Grid Bag layout panel
160      */
161     static class PanelGBL extends Panel {
162
163         protected Insets insets = new Insets(0, 0, 0, 0);
164
165         GridBagLayout lay = new GridBagLayout();
166
167         private static final GridBagConstraints constrLabel = new GridBagConstraints();
168
169         static {
170             constrLabel.gridwidth = GridBagConstraints.REMAINDER;
171             constrLabel.gridheight = 1;
172             constrLabel.gridy = GridBagConstraints.RELATIVE;
173             constrLabel.weightx = 1;
174             constrLabel.weighty = 1;
175             constrLabel.anchor = GridBagConstraints.FIRST_LINE_START;
176             constrLabel.fill = GridBagConstraints.HORIZONTAL;
177         }
178
179         public PanelGBL(String label) {
180             this();
181             add(new Label(label, Label.LEFT), constrLabel);
182         }
183
184         public PanelGBL() {
185             super();
186             setLayout(lay);
187         }
188
189         /**
190          * {@inheritDoc}
191          */
192         @Override
193         public Insets getInsets() {
194             return insets;
195         }
196     }
197
198
199     /**
200      * A Grid Bag Panel with a border
201      */
202     static class BorderPanelGBL extends PanelGBL {
203
204         public static final int NONE = 0;
205         public static final int RAISED = 1;
206         public static final int LOWERED = 2;
207         public static final int GROOVE = 3;
208         public static final int BUMP = 4;
209
210         int style = GROOVE;
211         String title;
212         int ascent = 0;
213         int descent = 0;
214         int leading = 0;
215         int titleWidth = 0;
216
217         public BorderPanelGBL(String title) {
218             super();
219             this.title = title;
220         }
221
222         public BorderPanelGBL(String title, String advice) {
223             super(advice);
224             this.title = title;
225         }
226
227         public BorderPanelGBL(String title, String advice, int s) {
228             super(advice);
229             this.title = title;
230             if ((s < NONE) && (s > BUMP)) {
231                 return;
232             }
233             if ((s == RAISED) || (s == LOWERED)) {
234                 this.title = null;
235             }
236             style = s;
237         }
238
239         private void checkMetrics() {
240             Font font = getFont();
241
242             if ((title == null) || (font == null)) {
243                 ascent = 2;
244             } else {
245                 FontMetrics fmetrics = getFontMetrics(font);
246
247                 ascent = fmetrics.getAscent();
248                 descent = fmetrics.getDescent();
249                 leading = fmetrics.getLeading();
250                 titleWidth = fmetrics.stringWidth(title);
251             }
252             insets = new Insets(descent + ascent + leading + 2, 7, 7, 7);
253         }
254
255         /**
256          * {@inheritDoc}
257          */
258         @Override
259         public Insets getInsets() {
260             checkMetrics();
261             return insets;
262         }
263
264         private void paintLowered(Graphics g) {
265             checkMetrics();
266             if (ascent == 0) {
267                 return;
268             }
269
270             Dimension d = getSize();
271
272             g.setColor(Color.black);
273             g.drawRect(1, ascent - 2, d.width - 4, d.height - ascent);
274             g.setColor(Color.white);
275             g.drawRect(2, ascent - 1, d.width - 4, d.height - ascent);
276             g.setColor(getBackground());
277             g.drawRect(2, ascent - 1, d.width - 5, d.height - ascent - 1);
278         }
279
280         private void paintRaised(Graphics g) {
281             checkMetrics();
282             if (ascent == 0) {
283                 return;
284             }
285
286             Dimension d = getSize();
287
288             g.setColor(Color.white);
289             g.drawRect(1, ascent - 2, d.width - 4, d.height - ascent);
290             g.setColor(Color.black);
291             g.drawRect(2, ascent - 1, d.width - 4, d.height - ascent);
292             g.setColor(getBackground());
293             g.drawRect(2, ascent - 1, d.width - 5, d.height - ascent - 1);
294         }
295
296         private void paintGroove(Graphics g) {
297             checkMetrics();
298             if (ascent == 0) {
299                 return;
300             }
301
302             Dimension d = getSize();
303
304             g.setColor(Color.black);
305             g.drawRect(1, ascent - 2, d.width - 4, d.height - ascent);
306             g.setColor(Color.white);
307             g.drawRect(2, ascent - 1, d.width - 4, d.height - ascent);
308
309             g.setColor(Color.white);
310             g.clearRect(10, 0, titleWidth + 6, descent + ascent + leading + 1);
311             g.drawString(title, 12, ascent + 1);
312             g.setColor(Color.black);
313             g.drawString(title, 13, ascent + 2);
314
315             // Work around a bug of at least the awt implem I'm using.
316             // A few wild pixels appear on that line during drawstring.
317             g.clearRect(0, 0, d.width, 1);
318         }
319
320         private void paintBump(Graphics g) {
321             checkMetrics();
322             if (ascent == 0) {
323                 return;
324             }
325
326             Dimension d = getSize();
327
328             g.setColor(Color.white);
329             g.drawRect(1, ascent - 2, d.width - 4, d.height - ascent);
330             g.setColor(Color.black);
331             g.drawRect(2, ascent - 1, d.width - 4, d.height - ascent);
332
333             g.setColor(Color.white);
334             g.clearRect(10, 0, titleWidth + 6, descent + ascent + leading + 1);
335             g.drawString(title, 12, ascent + 1);
336             g.setColor(Color.black);
337             g.drawString(title, 13, ascent + 2);
338
339             // Work around a bug of at least the awt implem I'm using.
340             // A few wild pixels appear on that line during drawstring.
341             g.clearRect(0, 0, d.width, 1);
342         }
343
344         /**
345          * {@inheritDoc}
346          */
347         @Override
348         public void paint(Graphics g) {
349             switch (style) {
350                 case GROOVE:
351                     paintGroove(g);
352                     break;
353
354                 case BUMP:
355                     paintBump(g);
356                     break;
357
358                 case RAISED:
359                     paintRaised(g);
360                     break;
361
362                 case LOWERED:
363                     paintLowered(g);
364                     break;
365
366                 default:
367             }
368             super.paint(g);
369         }
370     }
371
372
373     /**
374      * Panel implementing paged tabs.
375      */
376     static class PagesPanel extends Panel implements ActionListener {
377         private final CardLayout layout;
378         private final Panel pages;
379         private final Panel buttons;
380
381         public PagesPanel() {
382             super(new BorderLayout());
383             layout = new CardLayout();
384             pages = new Panel(layout);
385             buttons = new Panel(new FlowLayout(FlowLayout.LEFT, 0, 0));
386
387             add(pages, BorderLayout.CENTER);
388             add(buttons, BorderLayout.NORTH);
389         }
390
391         /**
392          * {@inheritDoc}
393          */
394         public void actionPerformed(ActionEvent e) {
395             layout.show(pages, e.getActionCommand());
396         }
397
398         public PanelGBL addPage(String buttonName, String comment) {
399             BorderPanelGBL p = new BorderPanelGBL(buttonName, comment, BorderPanelGBL.RAISED);
400
401             pages.add(p, buttonName);
402             Button b = new Button(buttonName);
403
404             buttons.add(b);
405             b.addActionListener(this);
406             return p;
407         }
408
409         public void showPage(String pageName) {
410             layout.show(pages, pageName);
411         }
412     }
413
414
415     /**
416      * Allows for entry of a host address and port number. Besides the host
417      * address and port number text fields there are two optional features:
418      * <p/>
419      * <p/><ul>
420      * <li>A checkbox with annotation to enable/disable the control.</li>
421      * <li>A label for the address.</li>
422      * </ul>
423      */
424     static class HostPortPanel extends Panel implements ItemListener {
425
426         private final Checkbox useMe;
427
428         private Label addressLabel = null;
429
430         private final TextField host;
431         private final TextField port;
432
433         HostPortPanel(String checkLabel, String addrLabel, String defaultHost, String defaultPort, boolean defaultState) {
434
435             super(new GridBagLayout());
436
437             useMe = new Checkbox(checkLabel, defaultState);
438             host = new TextField(defaultHost, 25);
439             port = new TextField(defaultPort, 6);
440
441             GridBagConstraints constraints = new GridBagConstraints();
442
443             constraints.weightx = 1.0;
444             constraints.weighty = 1.0;
445
446             constraints.gridx = 0;
447             constraints.gridy = 0;
448             constraints.gridwidth = (null == addrLabel) ? 2 : 3;
449             constraints.anchor = GridBagConstraints.FIRST_LINE_START;
450
451             if (null != checkLabel) {
452                 add(useMe, constraints);
453                 // if check label and addr label then use 2 lines.
454                 if (null != addrLabel) {
455                     constraints.gridy++;
456                     constraints.gridx = 0;
457                     constraints.anchor = GridBagConstraints.LAST_LINE_START;
458                 } else {
459                     constraints.gridx++;
460                     constraints.gridx = GridBagConstraints.RELATIVE;
461                 }
462             }
463
464             if (null != addrLabel) {
465                 constraints.gridwidth = 1;
466                 addressLabel = new Label(addrLabel, Label.RIGHT);
467                 add(addressLabel, constraints);
468             }
469
470             constraints.gridx = GridBagConstraints.RELATIVE;
471
472             add(host, constraints);
473             add(port, constraints);
474
475             setState(defaultState);
476             useMe.addItemListener(this);
477         }
478
479         /**
480          * {@inheritDoc}
481          */
482         public void itemStateChanged(ItemEvent e) {
483             setState(useMe.getState());
484         }
485
486         /**
487          * {@inheritDoc}
488          */
489         public boolean getState() {
490             return useMe.getState() && isEnabled();
491         }
492
493         /**
494          * {@inheritDoc}
495          */
496         @Override
497         public void setEnabled(boolean enabling) {
498             super.setEnabled(enabling);
499
500             useMe.setEnabled(enabling);
501
502             if (null != addressLabel) {
503                 addressLabel.setEnabled(useMe.getState());
504             }
505
506             host.setEnabled(useMe.getState());
507             port.setEnabled(useMe.getState());
508         }
509
510         /**
511          * {@inheritDoc}
512          */
513         public void setState(boolean state) {
514             useMe.setState(state); // sometimes redundant but not always.
515
516             if (null != addressLabel) {
517                 addressLabel.setEnabled(state);
518             }
519
520             host.setEnabled(state);
521             port.setEnabled(state);
522         }
523
524         /**
525          * Returns the value of the host field
526          *
527          * @return the value of the hot field
528          */
529         public String getHost() {
530             return host.getText().trim();
531         }
532
533         /**
534          * Returns the value of the port field
535          *
536          * @return the value of the port field
537          */
538         public String getPort() {
539             return port.getText().trim();
540         }
541     }
542
543
544     /**
545      * A list of URIs
546      */
547     static class HostListPanel extends Panel implements ActionListener {
548
549         private final String purpose;
550         private final TextField host;
551         private final TextField port;
552         private final java.awt.List list;
553         private final Label listLabel;
554
555         private final Button insert;
556         private final Button remove;
557
558         public HostListPanel(String purpose, String lstLabel, boolean defaultState, boolean showPort) {
559
560             super(new GridBagLayout());
561             this.purpose = purpose;
562
563             host = new TextField("", showPort ? 25 : 30);
564             if (showPort) {
565                 port = new TextField("", 5);
566             } else {
567                 port = null;
568             }
569             insert = new Button("+");
570             remove = new Button("-");
571
572             list = new java.awt.List(2, true);
573             listLabel = new Label(lstLabel);
574
575             GridBagConstraints c1 = new GridBagConstraints();
576
577             c1.gridx = 0;
578             c1.gridy = 0;
579             c1.anchor = GridBagConstraints.FIRST_LINE_START;
580             c1.fill = GridBagConstraints.NONE;
581             add(listLabel, c1);
582
583             c1.gridx = 0;
584             c1.gridy++;
585             if (!showPort) {
586                 c1.gridwidth = 2;
587             }
588             c1.weightx = 2.0;
589             c1.anchor = GridBagConstraints.LINE_START;
590             c1.fill = GridBagConstraints.HORIZONTAL;
591             add(host, c1);
592
593             if (showPort) {
594                 c1.weightx = 0.0;
595                 c1.gridx = 1;
596                 c1.anchor = GridBagConstraints.LINE_END;
597                 c1.fill = GridBagConstraints.NONE;
598                 add(port, c1);
599             }
600
601             c1.gridx = 0;
602             c1.gridy++;
603             c1.gridwidth = 1;
604             c1.weightx = 2.0;
605             c1.anchor = GridBagConstraints.LAST_LINE_START;
606             c1.fill = GridBagConstraints.HORIZONTAL;
607             add(list, c1);
608
609             Panel p2 = new Panel(new GridLayout(2, 1, 1, 1));
610
611             p2.add(insert);
612             p2.add(remove);
613
614             c1.gridx++;
615             c1.weightx = 0.0;
616             c1.anchor = GridBagConstraints.LAST_LINE_END;
617             c1.fill = GridBagConstraints.NONE;
618             c1.insets = new Insets(0, 4, 0, 1);
619             add(p2, c1);
620
621             host.addActionListener(this);
622             insert.addActionListener(this);
623             remove.addActionListener(this);
624             list.addActionListener(this);
625
626             setEnabled(defaultState);
627         }
628
629         /**
630          * {@inheritDoc}
631          */
632         @Override
633         public void setEnabled(boolean state) {
634             super.setEnabled(state);
635
636             listLabel.setEnabled(state);
637             host.setEnabled(state);
638             if (null != port) {
639                 port.setEnabled(state);
640             }
641             list.setEnabled(state);
642             insert.setEnabled(state);
643             remove.setEnabled(state);
644         }
645
646         /**
647          * {@inheritDoc}
648          */
649         @Override
650         public boolean isEnabled() {
651             return listLabel.isEnabled();
652         }
653
654         /**
655          * {@inheritDoc}
656          */
657         public void actionPerformed(ActionEvent e) {
658             if ((insert == e.getSource()) || (host == e.getSource())) {
659                 StringBuilder addHost = new StringBuilder(host.getText());
660
661                 if (null != port) {
662                     String portText = port.getText().trim();
663
664                     if (portText.length() > 0) {
665                         // if( !verifyPort( "Host port", portText, false ) ) {
666                         // return;
667                         // }
668                         addHost.append(':');
669                         addHost.append(portText);
670                     }
671                 }
672                 if (addItem(addHost.toString())) {
673                     host.setText("");
674                     host.setCaretPosition(0);
675                     if (null != port) {
676                         port.setText("");
677                         port.setCaretPosition(0);
678                     }
679                 }
680                 return;
681             }
682
683             if (e.getSource() == remove) {
684                 int[] sel = list.getSelectedIndexes();
685                 int i = sel.length;
686
687                 while (i-- > 0) {
688                     list.remove(sel[i]);
689                 }
690
691                 return;
692             }
693
694             // double click on a host in the list
695             if (e.getSource() == list) {
696                 String cmd = e.getActionCommand();
697
698                 if (null != port) {
699                     int colonAt = cmd.lastIndexOf(':');
700                     String newHost = cmd.substring(0, colonAt);
701                     String newPort = cmd.substring(colonAt + 1);
702
703                     host.setText(newHost);
704                     host.setCaretPosition(newHost.length());
705                     port.setText(newPort);
706                     port.setCaretPosition(newHost.length());
707                 } else {
708                     host.setText(cmd);
709                     host.setCaretPosition(cmd.length());
710                 }
711             }
712         }
713
714         public boolean addItem(String item) {
715             String hostURI = item.trim();
716
717             if (0 == hostURI.trim().length()) {
718                 return false;
719             }
720
721             // See if it is "really" a URI.
722             try {
723                 new URI(hostURI);
724             } catch (URISyntaxException failed) {
725                 return false;
726             }
727
728             try {
729                 while (true) {
730                     try {
731                         list.remove(hostURI);
732                     } catch (IllegalArgumentException notThere) {
733                         break;
734                     }
735                 }
736
737                 list.add(hostURI);
738             } catch (Exception e) {
739                 return false;
740             }
741
742             return true;
743         }
744
745         public String getPurpose() {
746             return purpose;
747         }
748
749         public String[] getItems() {
750             return list.getItems();
751         }
752     }
753
754
755     /**
756      * An interface and port selection panel.
757      */
758     static class IfAddrPanel extends Panel implements ItemListener {
759         private final Checkbox manual;
760
761         private final CardLayout addrLayout;
762
763         private final Panel addrPanel;
764         private final TextField interfaceAddr;
765         private final TextField localPort;
766
767         private final Choice ips;
768
769         public IfAddrPanel(String defaultInterfaceAddr, String defaultPort) {
770
771             super(new FlowLayout(FlowLayout.LEADING, 0, 0));
772
773             ips = new Choice();
774             boolean modeManual = false;
775
776             ips.add("Any/All Local Addresses");
777
778             try {
779                 Iterator<InetAddress> allIntf = IPUtils.getAllLocalAddresses();
780                 boolean sawValid = false;
781
782                 while (allIntf.hasNext()) {
783                     InetAddress anAddr = allIntf.next();
784
785                     if (IPUtils.LOOPBACK.equals(anAddr)) {
786                         continue;
787                     }
788
789                     ips.add(IPUtils.getHostAddress(anAddr));
790                     sawValid = true;
791                 }
792
793                 if (!sawValid) {
794                     modeManual = true;
795                 }
796
797                 // if an address was previously configured, switch to manual
798                 // if we do not find any interface, switch to manual too.
799                 if (defaultInterfaceAddr != null) {
800                     InetAddress defaultIntf = InetAddress.getByName(defaultInterfaceAddr);
801
802                     if (!IPUtils.ANYADDRESS.equals(defaultIntf)) {
803                         modeManual = true;
804
805                         // However, if this address is in the automatic list,
806                         // switch back to automatic and select it.
807                         allIntf = IPUtils.getAllLocalAddresses();
808
809                         while (allIntf.hasNext()) {
810                             InetAddress anAddr = allIntf.next();
811
812                             if (defaultIntf.equals(anAddr)) {
813                                 modeManual = false;
814                                 ips.select(defaultInterfaceAddr);
815                             }
816                         }
817                     }
818                 }
819             } catch (Exception e) {
820                 modeManual = true;
821             }
822
823             manual = new Checkbox("Manual", null, modeManual);
824             add(manual);
825             manual.addItemListener(this);
826
827             addrLayout = new CardLayout();
828             addrPanel = new Panel(addrLayout);
829
830             Panel autoPanel = new Panel(new FlowLayout(FlowLayout.LEADING));
831
832             autoPanel.add(ips);
833
834             Panel manPanel = new Panel(new FlowLayout(FlowLayout.LEADING));
835
836             interfaceAddr = new TextField(defaultInterfaceAddr, 20);
837             manPanel.add(interfaceAddr);
838
839             addrPanel.add(manPanel, "man");
840             addrPanel.add(autoPanel, "auto");
841
842             add(addrPanel);
843
844             localPort = new TextField(defaultPort, 6);
845             add(localPort);
846
847             setManual(modeManual);
848         }
849
850         /**
851          * {@inheritDoc}
852          */
853         private void setManual(boolean manMode) {
854             addrLayout.show(addrPanel, manMode ? "man" : "auto");
855
856             this.validate();
857         }
858
859         /**
860          * {@inheritDoc}
861          */
862         @Override
863         public void setEnabled(boolean enabled) {
864             super.setEnabled(enabled);
865
866             manual.setEnabled(enabled);
867             ips.setEnabled(enabled);
868             interfaceAddr.setEnabled(enabled);
869             localPort.setEnabled(enabled);
870         }
871
872         /**
873          * {@inheritDoc}
874          */
875         public void itemStateChanged(ItemEvent e) {
876             if (e.getSource() == manual) {
877                 setManual(manual.getState());
878             }
879         }
880
881         public String getAddress() {
882             if (manual.getState()) {
883                 return interfaceAddr.getText().trim();
884             } else {
885                 return ips.getSelectedItem().trim();
886             }
887         }
888
889         public String getPort() {
890             return localPort.getText().trim();
891         }
892
893         public String getMode() {
894             return manual.getState() ? "manual" : "auto";
895         }
896
897     }
898
899
900     static final class IPTptPanel extends BorderPanelGBL implements ItemListener {
901
902         enum TransportType {
903             TYPE_HTTP, TYPE_TCP
904         }
905
906
907         ;
908
909         private final Checkbox useMe;
910         private final Checkbox pubAddrOnly;
911         private final Checkbox multicast;
912         private final Checkbox clientEnabled;
913
914         private final IfAddrPanel ifAddr;
915         private final HostPortPanel publicAddr;
916
917         public IPTptPanel(TransportType type, boolean defaultState, String name, String defaultInterfaceAddr, String defaultPort, boolean clientState, boolean serverState, String defaultPublicAddr, String defaultPublicPort, boolean pubAddrOnlyState) {
918             this(type, defaultState, name, defaultInterfaceAddr, defaultPort, clientState, serverState, defaultPublicAddr
919                     ,
920                     defaultPublicPort, pubAddrOnlyState, false);
921         }
922
923         public IPTptPanel(TransportType type, boolean defaultState, String name, String defaultInterfaceAddr, String defaultPort, boolean clientState, boolean serverState, String defaultPublicAddr, String defaultPublicPort, boolean pubAddrOnlyState, boolean multicastState) {
924
925             super(name);
926
927             ifAddr = new IfAddrPanel(defaultInterfaceAddr, defaultPort);
928
929             useMe = new Checkbox("Enabled", null, defaultState);
930
931             if (type == TransportType.TYPE_TCP) {
932                 multicast = new Checkbox("Multicast", null, multicastState);
933             } else {
934                 multicast = null;
935             }
936
937             clientEnabled = new Checkbox("Enable Outgoing connections", null, clientState);
938
939             pubAddrOnly = new Checkbox("Hide private addresses", null, pubAddrOnlyState);
940
941             publicAddr = new HostPortPanel("Enable Incoming Connections", "(Optional) Public address", defaultPublicAddr
942                     ,
943                     defaultPublicPort, serverState);
944
945             GridBagConstraints constraints = new GridBagConstraints();
946
947             constraints.weightx = 1.0;
948             constraints.weighty = 1.0;
949
950             constraints.gridx = 0;
951             constraints.gridy = 1;
952             constraints.anchor = GridBagConstraints.FIRST_LINE_START;
953             add(useMe, constraints);
954
955             if (type == TransportType.TYPE_TCP) {
956                 constraints.anchor = GridBagConstraints.FIRST_LINE_END;
957                 add(multicast, constraints);
958             }
959
960             constraints.gridx = 0;
961             constraints.gridy++;
962             constraints.anchor = GridBagConstraints.LINE_START;
963             add(ifAddr, constraints);
964
965             constraints.gridx = 0;
966             constraints.gridy++;
967
968             constraints.anchor = GridBagConstraints.LINE_START;
969             add(clientEnabled, constraints);
970
971             constraints.anchor = GridBagConstraints.EAST;
972             add(pubAddrOnly, constraints);
973
974             constraints.gridx = 0;
975             constraints.gridy++;
976
977             constraints.anchor = GridBagConstraints.LINE_START;
978             add(publicAddr, constraints);
979             publicAddr.setState(serverState);
980
981             setState(defaultState);
982             useMe.addItemListener(this);
983         }
984
985         /**
986          * {@inheritDoc}
987          */
988         public void setState(boolean state) {
989             useMe.setState(state);
990             ifAddr.setEnabled(state);
991             publicAddr.setEnabled(state);
992             if (multicast != null) {
993                 multicast.setEnabled(state);
994             }
995             clientEnabled.setEnabled(state);
996             pubAddrOnly.setEnabled(state);
997         }
998
999         /**
1000          * {@inheritDoc}
1001          */
1002         public void itemStateChanged(ItemEvent e) {
1003             setState(useMe.getState());
1004         }
1005
1006         public String getInterfaceAddress() {
1007             return ifAddr.getAddress().trim();
1008         }
1009
1010         public String getConfigMode() {
1011             return ifAddr.getMode();
1012         }
1013
1014         public boolean getPubAddrOnly() {
1015             return pubAddrOnly.getState();
1016         }
1017
1018         public void setPubAddrOnly(boolean state) {
1019             pubAddrOnly.setState(state);
1020         }
1021     }
1022
1023
1024     /**
1025      * Manages Peer Identity configuration
1026      */
1027     final class IdPanel extends Panel implements ActionListener {
1028
1029         private final TextField peerName;
1030         private final TextField passwd;
1031         private final TextField vpasswd;
1032
1033         public IdPanel(String defaultPeerName, boolean needSecurityConfig) {
1034
1035             super(new GridBagLayout());
1036
1037             peerName = new TextField(defaultPeerName, 20);
1038
1039             GridBagConstraints constraints = new GridBagConstraints();
1040
1041             constraints.gridx = 0;
1042             constraints.gridy = 0;
1043             constraints.anchor = GridBagConstraints.FIRST_LINE_END;
1044             add(new Label("Peer Name", Label.RIGHT), constraints);
1045
1046             constraints.gridx++;
1047             constraints.anchor = GridBagConstraints.FIRST_LINE_START;
1048             add(peerName, constraints);
1049
1050             if (needSecurityConfig) {
1051                 passwd = new TextField("", 20);
1052                 vpasswd = new TextField("", 20);
1053                 passwd.setEchoChar('*');
1054                 vpasswd.setEchoChar('*');
1055
1056                 constraints.gridx = 0;
1057                 constraints.gridy++;
1058                 constraints.anchor = GridBagConstraints.LINE_END;
1059                 add(new Label("Password", Label.RIGHT), constraints);
1060
1061                 constraints.gridx++;
1062                 constraints.anchor = GridBagConstraints.LINE_START;
1063                 add(passwd, constraints);
1064
1065                 constraints.gridx = 0;
1066                 constraints.gridy++;
1067                 constraints.anchor = GridBagConstraints.LINE_END;
1068                 add(new Label("Verify Password", Label.RIGHT), constraints);
1069
1070                 constraints.gridx++;
1071                 constraints.anchor = GridBagConstraints.LINE_START;
1072                 add(vpasswd, constraints);
1073             } else {
1074                 passwd = null;
1075                 vpasswd = null;
1076             }
1077         }
1078
1079         /**
1080          * {@inheritDoc}
1081          */
1082         @Override
1083         public String getName() {
1084             return peerName.getText().trim();
1085         }
1086
1087         public String getPassword() {
1088             return passwd.getText();
1089         }
1090
1091         public String getVerifyPassword() {
1092             return vpasswd.getText();
1093         }
1094
1095         public void clearPasswords() {
1096             passwd.setText("");
1097             vpasswd.setText("");
1098         }
1099
1100         /**
1101          * {@inheritDoc}
1102          */
1103         public void actionPerformed(ActionEvent e) {
1104         }
1105     }
1106
1107
1108     /**
1109      * Manages Service Enabling
1110      */
1111     final static class EnablingPanel extends BorderPanelGBL {
1112
1113         private final Checkbox isRelay;
1114         private final Checkbox isRendezvous;
1115         private final Checkbox isJxmeProxy;
1116
1117         EnablingPanel(boolean actAsRelay, boolean actAsRendezvous, boolean actAsJxmeProxy) {
1118             super("Services Settings");
1119
1120             isRelay = new Checkbox("Act as a Relay", null, actAsRelay);
1121             isRendezvous = new Checkbox("Act as a Rendezvous", null, actAsRendezvous);
1122             isJxmeProxy = new Checkbox("Act as a JXME proxy", null, actAsJxmeProxy);
1123
1124             add(isRelay, stdConstr);
1125             add(isRendezvous, stdConstr);
1126             add(isJxmeProxy, stdConstr);
1127         }
1128     }
1129
1130
1131     /**
1132      * Manages Rendezvous service options
1133      */
1134     final static class RdvPanel extends BorderPanelGBL implements ItemListener {
1135
1136         private final Checkbox useRdv;
1137         private final Checkbox useOnlySeeds;
1138         private final HostListPanel seeding;
1139         private final HostListPanel seeds;
1140
1141         RdvPanel(boolean useARdv, boolean onlySeeds) {
1142             super("Rendezvous Settings");
1143
1144             useRdv = new Checkbox("Use a rendezvous", null, useARdv);
1145             useOnlySeeds = new Checkbox("Use only configured seeds", null, onlySeeds);
1146             seeds = new HostListPanel("Seeds", "Rendezvous seed peers", true, false);
1147             seeding = new HostListPanel("Seeding", "Rendezvous seeding URIs", true, false);
1148
1149             GridBagConstraints c1 = new GridBagConstraints();
1150
1151             c1.gridx = 0;
1152             c1.gridy = 0;
1153             c1.anchor = GridBagConstraints.LINE_START;
1154             add(useRdv, c1);
1155             useRdv.addItemListener(this);
1156
1157             c1.gridx++;
1158             c1.anchor = GridBagConstraints.LINE_END;
1159             add(useOnlySeeds, c1);
1160
1161             c1.gridx = 0;
1162             c1.gridy++;
1163             c1.gridwidth = 2;
1164             c1.weightx = 1.0;
1165             c1.fill = GridBagConstraints.HORIZONTAL;
1166             c1.anchor = GridBagConstraints.LINE_START;
1167             add(seeding, c1);
1168
1169             c1.gridy++;
1170             add(seeds, c1);
1171         }
1172
1173         /**
1174          * {@inheritDoc}
1175          */
1176         public void itemStateChanged(ItemEvent e) {
1177             seeds.setEnabled(useRdv.getState());
1178             seeding.setEnabled(useRdv.getState());
1179             useOnlySeeds.setEnabled(useRdv.getState());
1180         }
1181     }
1182
1183
1184     /**
1185      * Manages relay service parameters
1186      */
1187     final static class RelayPanel extends BorderPanelGBL implements ItemListener {
1188
1189         private final Checkbox useRelay;
1190         private final Checkbox useOnlySeeds;
1191         private final HostListPanel seeding;
1192         private final HostListPanel seeds;
1193
1194         public RelayPanel(boolean useARelay, boolean onlySeeds) {
1195
1196             super("Relay Settings");
1197
1198             useRelay = new Checkbox("Use a relay", null, useARelay);
1199             useOnlySeeds = new Checkbox("Use only configured seeds", null, onlySeeds);
1200             useOnlySeeds.setEnabled(useARelay);
1201             seeds = new HostListPanel("Seeds", "Relay seed peers", useARelay, false);
1202             seeding = new HostListPanel("Seeding", "Relay seeding URIs", useARelay, false);
1203
1204             GridBagConstraints c1 = new GridBagConstraints();
1205
1206             c1.gridx = 0;
1207             c1.gridy = 0;
1208             c1.anchor = GridBagConstraints.LINE_START;
1209             add(useRelay, c1);
1210             useRelay.addItemListener(this);
1211
1212             c1.gridx++;
1213             c1.anchor = GridBagConstraints.LINE_END;
1214             add(useOnlySeeds, c1);
1215
1216             c1.gridx = 0;
1217             c1.gridy++;
1218             c1.gridwidth = 2;
1219             c1.weightx = 1.0;
1220             c1.fill = GridBagConstraints.HORIZONTAL;
1221             c1.anchor = GridBagConstraints.LINE_START;
1222             add(seeding, c1);
1223
1224             c1.gridy++;
1225             add(seeds, c1);
1226         }
1227
1228         /**
1229          * {@inheritDoc}
1230          */
1231         public void itemStateChanged(ItemEvent e) {
1232             seeds.setEnabled(useRelay.getState());
1233             seeding.setEnabled(useRelay.getState());
1234             useOnlySeeds.setEnabled(useRelay.getState());
1235         }
1236     }
1237
1238     private final PlatformConfig configAdv;
1239
1240     private final Label helpLabel;
1241     private final IdPanel idPanel;
1242     private final EnablingPanel enablingPanel;
1243     private final IPTptPanel tcpPanel;
1244     private final IPTptPanel httpPanel;
1245     private final RdvPanel rdvPanel;
1246     private final RelayPanel relayPanel;
1247
1248     private final Button ok;
1249     private final Button cancel;
1250     private final PagesPanel pages = new PagesPanel();
1251
1252     boolean done = false;
1253     boolean canceled = false;
1254
1255     String tcpMulticastAddr;
1256     int tcpMulticastPort;
1257     int tcpMulticastLength;
1258
1259     public ConfigDialog(PlatformConfig configAdv) throws ConfiguratorException {
1260         super("JXTA Configurator");
1261
1262         this.configAdv = configAdv;
1263
1264         // Identity settings
1265         String peerName = configAdv.getName();
1266
1267         if ((null == peerName) || (0 == peerName.trim().length())) {
1268             peerName = "";
1269         }
1270
1271         // Security settings
1272         boolean needSecurityConfig = true;
1273
1274         // If security is already in place, then the security info is not shown.
1275         XMLElement param = (XMLElement) configAdv.getServiceParam(PeerGroup.membershipClassID);
1276
1277         if (param != null) {
1278             Advertisement adv = null;
1279
1280             try {
1281                 adv = AdvertisementFactory.newAdvertisement(param);
1282             } catch (NoSuchElementException notAnAdv) {
1283                 ; // that's ok.
1284             } catch (IllegalArgumentException badAdv) {
1285                 ; // that's ok.
1286             }
1287
1288             if (adv instanceof PSEConfigAdv) {
1289                 PSEConfigAdv pseConfig = (PSEConfigAdv) adv;
1290
1291                 // no certificate? That means we need to make one.
1292                 needSecurityConfig = (null == pseConfig.getCertificate());
1293             }
1294         }
1295
1296         // JXME Proxy Settings
1297         boolean isJxmeProxy = false;
1298
1299         try {
1300             param = (XMLElement) configAdv.getServiceParam(PeerGroup.proxyClassID);
1301
1302             if (param != null && configAdv.isSvcEnabled(PeerGroup.proxyClassID)) {
1303                 isJxmeProxy = true;
1304             }
1305         } catch (Exception nobigdeal) {
1306             nobigdeal.printStackTrace();
1307         }
1308
1309         int index;
1310
1311         // TCP Settings
1312         boolean tcpEnabled;
1313         boolean clientDefaultT;
1314         boolean serverDefaultT;
1315         String defaultInterfaceAddressT;
1316         String defaultPortT;
1317         String defaultServerNameT;
1318         String defaultServerPortT;
1319         boolean multicastEnabledT;
1320         boolean noPublicAddressesT;
1321
1322         try {
1323             param = (XMLElement) configAdv.getServiceParam(PeerGroup.tcpProtoClassID);
1324
1325             tcpEnabled = configAdv.isSvcEnabled(PeerGroup.tcpProtoClassID);
1326
1327             Enumeration<XMLElement> tcpChilds = param.getChildren(TransportAdvertisement.getAdvertisementType());
1328
1329             // get the TransportAdv from either TransportAdv or tcpAdv
1330             if (tcpChilds.hasMoreElements()) {
1331                 param = tcpChilds.nextElement();
1332             } else {
1333                 throw new IllegalStateException("Missing TCP Advertisment");
1334             }
1335
1336             TCPAdv tcpAdv = (TCPAdv) AdvertisementFactory.newAdvertisement(param);
1337
1338             clientDefaultT = tcpAdv.isClientEnabled();
1339             serverDefaultT = tcpAdv.isServerEnabled();
1340
1341             defaultInterfaceAddressT = tcpAdv.getInterfaceAddress();
1342
1343             if ((null == defaultInterfaceAddressT) || (0 == defaultInterfaceAddressT.trim().length())) {
1344                 defaultInterfaceAddressT = null;
1345             }
1346
1347             defaultPortT = Integer.toString(tcpAdv.getPort());
1348             if ((defaultPortT == null) || (0 == defaultPortT.trim().length())) {
1349                 defaultPortT = "9701";
1350             }
1351
1352             defaultServerNameT = tcpAdv.getServer();
1353
1354             if ((null == defaultServerNameT) || (0 == defaultServerNameT.trim().length())) {
1355                 defaultServerNameT = "";
1356             }
1357
1358             if (defaultServerNameT != null && (index = defaultServerNameT.lastIndexOf(":")) != -1) {
1359                 if ((0 == index) || (index == defaultServerNameT.length())) {
1360                     throw new IllegalArgumentException("Bad TCP server name . Cannot proceed.");
1361                 }
1362                 defaultServerPortT = defaultServerNameT.substring(index + 1);
1363                 defaultServerNameT = defaultServerNameT.substring(0, index);
1364             } else {
1365                 defaultServerNameT = "";
1366                 defaultServerPortT = "9701";
1367             }
1368
1369             noPublicAddressesT = tcpAdv.getPublicAddressOnly();
1370             multicastEnabledT = tcpAdv.getMulticastState();
1371
1372             // we will just pass these to save.
1373             tcpMulticastAddr = tcpAdv.getMulticastAddr();
1374             tcpMulticastPort = tcpAdv.getMulticastPort();
1375             tcpMulticastLength = tcpAdv.getMulticastSize();
1376         } catch (Exception failure) {
1377             throw new ConfiguratorException("Broken Platform Config. Cannot proceed.", failure);
1378         }
1379
1380         // HTTP Settings
1381         boolean httpEnabled;
1382         boolean clientDefaultH;
1383         boolean serverDefaultH;
1384         String defaultInterfaceAddressH;
1385         String defaultPortH;
1386         String defaultServerNameH;
1387         String defaultServerPortH;
1388         boolean noPublicAddressesH;
1389
1390         try {
1391             param = (XMLElement) configAdv.getServiceParam(PeerGroup.httpProtoClassID);
1392
1393             httpEnabled = configAdv.isSvcEnabled(PeerGroup.httpProtoClassID);
1394
1395             Enumeration<XMLElement> httpChilds = param.getChildren(TransportAdvertisement.getAdvertisementType());
1396
1397             // get the TransportAdv from either TransportAdv
1398             if (httpChilds.hasMoreElements()) {
1399                 param = httpChilds.nextElement();
1400             } else {
1401                 throw new IllegalStateException("Missing HTTP Advertisment");
1402             }
1403
1404             // Read-in the adv as it is now.
1405             HTTPAdv httpAdv = (HTTPAdv) AdvertisementFactory.newAdvertisement(param);
1406
1407             clientDefaultH = httpAdv.isClientEnabled();
1408             serverDefaultH = httpAdv.isServerEnabled();
1409
1410             defaultInterfaceAddressH = httpAdv.getInterfaceAddress();
1411
1412             if ((null == defaultInterfaceAddressH) || (0 == defaultInterfaceAddressH.trim().length())) {
1413                 defaultInterfaceAddressH = null;
1414             }
1415
1416             defaultPortH = Integer.toString(httpAdv.getPort());
1417
1418             if ((defaultPortH == null) || (0 == defaultPortH.trim().length())) {
1419                 defaultPortH = "9700";
1420             }
1421
1422             defaultServerNameH = httpAdv.getServer();
1423
1424             if ((null != defaultServerNameH) && (0 == defaultServerNameH.trim().length())) {
1425                 defaultServerNameH = "";
1426             }
1427
1428             defaultServerPortH = "9700";
1429
1430             if (defaultServerNameH != null && (index = defaultServerNameH.lastIndexOf(":")) != -1) {
1431                 if ((0 == index) || (index == defaultServerNameH.length())) {
1432                     throw new IllegalArgumentException("Bad HTTP server name. Cannot proceed.");
1433                 }
1434                 defaultServerPortH = defaultServerNameH.substring(index + 1);
1435                 defaultServerNameH = defaultServerNameH.substring(0, index);
1436             } else {
1437                 defaultServerNameH = "";
1438                 defaultServerPortH = "9700";
1439             }
1440
1441             noPublicAddressesH = httpAdv.getPublicAddressOnly();
1442         } catch (Exception failure) {
1443             throw new ConfiguratorException("Broken Platform Config. Cannot proceed.", failure);
1444         }
1445
1446         // Rendezvous Settings
1447         boolean isRendezvous;
1448         boolean isAdhoc;
1449         boolean onlySeeds;
1450         List<String> seedRdvs = new ArrayList<String>();
1451         List<String> seedingRdvs = new ArrayList<String>();
1452
1453         try {
1454             RdvConfigAdv rdvConfigAdv;
1455
1456             param = (XMLElement) configAdv.getServiceParam(PeerGroup.rendezvousClassID);
1457
1458             rdvConfigAdv = (RdvConfigAdv) AdvertisementFactory.newAdvertisement(param);
1459
1460             isRendezvous = (RendezVousConfiguration.RENDEZVOUS == rdvConfigAdv.getConfiguration());
1461
1462             isAdhoc = (RendezVousConfiguration.AD_HOC == rdvConfigAdv.getConfiguration());
1463
1464             onlySeeds = rdvConfigAdv.getUseOnlySeeds();
1465
1466             for (URI uri : Arrays.asList(rdvConfigAdv.getSeedRendezvous())) {
1467                 seedRdvs.add(uri.toString());
1468             }
1469
1470             for (URI uri1 : Arrays.asList(rdvConfigAdv.getSeedingURIs())) {
1471                 seedingRdvs.add(uri1.toString());
1472             }
1473         } catch (Exception failure) {
1474             throw new ConfiguratorException("Broken Platform Config. Cannot proceed.", failure);
1475         }
1476
1477         // Relay Settings
1478         boolean isRelay;
1479         boolean useRelay;
1480         boolean useOnlySeedRelays;
1481         List<String> seedRelays = new ArrayList<String>();
1482         List<String> seedingRelays = new ArrayList<String>();
1483
1484         try {
1485             param = (XMLElement) configAdv.getServiceParam(PeerGroup.relayProtoClassID);
1486
1487             RelayConfigAdv relayConfig = (RelayConfigAdv) AdvertisementFactory.newAdvertisement(param);
1488
1489             isRelay = relayConfig.isServerEnabled();
1490
1491             useRelay = relayConfig.isClientEnabled();
1492
1493             useOnlySeedRelays = relayConfig.getUseOnlySeeds();
1494
1495             for (EndpointAddress endpointAddress : Arrays.asList(relayConfig.getSeedRelays())) {
1496                 seedRelays.add(endpointAddress.toString());
1497             }
1498
1499             for (URI uri : Arrays.asList(relayConfig.getSeedingURIs())) {
1500                 seedingRelays.add(uri.toString());
1501             }
1502         } catch (Exception failure) {
1503             throw new ConfiguratorException("Broken Platform Config. Cannot proceed.", failure);
1504         }
1505
1506         // BEGIN BUILDING UI
1507
1508         GridBagLayout layout = new GridBagLayout();
1509
1510         setLayout(layout);
1511
1512         addWindowListener(new WindowAdapter() {
1513
1514             @Override
1515             public void windowClosing(WindowEvent e) {
1516                 beCanceled();
1517             }
1518         });
1519
1520         helpLabel = new Label("See \"http://jxta-jxse.dev.java.net/confighelp.html\" for config help", Label.CENTER);
1521         helpLabel.setBackground(new Color(220, 220, 220));
1522         helpLabel.setForeground(Color.black);
1523
1524         helpLabel.addMouseListener(new MouseAdapter() {
1525
1526             @Override
1527             public void mouseClicked(MouseEvent e) {
1528                 helpLabel.setForeground(Color.black);
1529                 helpLabel.setText("See \"http://jxta-jxse.dev.java.net/confighelp.html\" for config help");
1530             }
1531         });
1532
1533         idPanel = new IdPanel(peerName, needSecurityConfig);
1534
1535         enablingPanel = new EnablingPanel(isRelay, isRendezvous, isJxmeProxy);
1536
1537         tcpPanel = new IPTptPanel(IPTptPanel.TransportType.TYPE_TCP, tcpEnabled, "TCP Settings", defaultInterfaceAddressT,
1538                 defaultPortT, clientDefaultT, serverDefaultT, defaultServerNameT, defaultServerPortT, noPublicAddressesT,
1539                 multicastEnabledT);
1540
1541         httpPanel = new IPTptPanel(IPTptPanel.TransportType.TYPE_HTTP, httpEnabled, "HTTP Settings", defaultInterfaceAddressH,
1542                 defaultPortH, clientDefaultH, serverDefaultH, defaultServerNameH, defaultServerPortH, noPublicAddressesH);
1543
1544         rdvPanel = new RdvPanel(!isAdhoc, onlySeeds);
1545
1546         // add the relays
1547
1548         for (Object seedRdv : seedRdvs) {
1549             rdvPanel.seeds.addItem((String) seedRdv);
1550         }
1551
1552         for (Object seedingRdv : seedingRdvs) {
1553             rdvPanel.seeding.addItem((String) seedingRdv);
1554         }
1555
1556         relayPanel = new RelayPanel(useRelay, useOnlySeedRelays);
1557
1558         // add the relays
1559         for (Object seedRelay : seedRelays) {
1560             relayPanel.seeds.addItem((String) seedRelay);
1561         }
1562
1563         for (Object seedingRelay : seedingRelays) {
1564             relayPanel.seeding.addItem((String) seedingRelay);
1565         }
1566
1567         ok = new Button("  OK  ");
1568
1569         ok.addActionListener(new ActionListener() {
1570             public void actionPerformed(ActionEvent e) {
1571                 if (verifyInput()) {
1572                     if (saveValues()) {
1573                         beDone();
1574                     } else {
1575                         beCanceled();
1576                     }
1577                 }
1578             }
1579         });
1580
1581         cancel = new Button("Cancel");
1582         cancel.addActionListener(new ActionListener() {
1583             public void actionPerformed(ActionEvent e) {
1584                 beCanceled();
1585             }
1586         });
1587
1588         Panel okPanel = new Panel();
1589
1590         okPanel.add(ok);
1591         okPanel.add(cancel);
1592
1593         // build basic panel
1594         Panel basicsPanel = pages.addPage("Basic", "Basic settings");
1595
1596         GridBagConstraints centerWConstr = (GridBagConstraints) centerConstr.clone();
1597
1598         centerWConstr.weighty = 1;
1599
1600         basicsPanel.add(idPanel, centerWConstr);
1601
1602         // build Advanced panel
1603         Panel advancedPanel = pages.addPage("Advanced", "Experienced Users Only");
1604
1605         advancedPanel.add(enablingPanel, fillInsetConstr);
1606         advancedPanel.add(tcpPanel, fillInsetConstr);
1607         advancedPanel.add(httpPanel, fillInsetConstr);
1608
1609         Panel proxyRdvRelayPanel = pages.addPage("Rendezvous/Relays", "Experienced Users Only");
1610
1611         proxyRdvRelayPanel.add(rdvPanel, fillInsetConstr);
1612         proxyRdvRelayPanel.add(relayPanel, fillInsetConstr);
1613
1614         add(helpLabel, fillConstr);
1615         add(pages, fillInsetConstr);
1616         add(okPanel, centerLastConstr);
1617
1618         pack();
1619         setVisible(true);
1620     }
1621
1622     public synchronized boolean untilDone() {
1623         try {
1624             while (!done) {
1625                 wait();
1626             }
1627         } catch (InterruptedException e) {
1628             Thread.interrupted();
1629         }
1630
1631         if (canceled) {
1632             throw new JxtaError("Canceled during configuration");
1633         }
1634         return (done);
1635     }
1636
1637     private synchronized boolean beDone() {
1638         done = true;
1639         notify();
1640         dispose();
1641
1642         return canceled;
1643     }
1644
1645     private synchronized boolean beCanceled() {
1646         canceled = true;
1647         done = true;
1648         notify();
1649         dispose();
1650
1651         return canceled;
1652     }
1653
1654     private boolean verifyPort(String portName, String ports, boolean dynamicok) {
1655         int p1;
1656
1657         if ((null == ports) || (0 == ports.trim().length())) {
1658             ports = "0";
1659         }
1660
1661         try {
1662             p1 = Integer.parseInt(ports);
1663         } catch (Exception ex) {
1664             helpLabel.setForeground(Color.red.darker());
1665             helpLabel.setText(portName + " port number must be an integer: " + ports);
1666             return false;
1667         }
1668         if ((p1 > 65535) || (p1 < (dynamicok ? 0 : 1))) {
1669             helpLabel.setForeground(Color.red.darker());
1670             helpLabel.setText(
1671                     portName + " port number must be an integer between " + (dynamicok ? "0" : "1") + " and 65535, found " + p1);
1672             return false;
1673         }
1674         return true;
1675     }
1676
1677     private boolean verifyAddr(String proto, boolean serverOn, String localPort, String publicAddress, String publicPort) {
1678
1679         // if a public name is specified, check its port.
1680         if (serverOn && (publicAddress.length() > 0)) {
1681             if (!verifyPort(proto + " local", localPort, false)) {
1682                 helpLabel.setForeground(Color.red.darker());
1683                 helpLabel.setText("Dynamic tcp port selection not supported when server public address is specified.");
1684                 pages.showPage("Advanced");
1685                 return false;
1686             }
1687
1688             if (!verifyPort(proto + " public", publicPort, false)) {
1689                 pages.showPage("Advanced");
1690                 helpLabel.setForeground(Color.red.darker());
1691                 helpLabel.setText("Dynamic tcp port selection not supported for server public address.");
1692                 return false;
1693             }
1694         } else if (!verifyPort(proto + " local", localPort, true)) {
1695             pages.showPage("Advanced");
1696             return false;
1697         }
1698
1699         return true;
1700     }
1701
1702     private boolean verifyInput() {
1703
1704         if (0 == idPanel.getName().trim().length()) {
1705             helpLabel.setForeground(Color.red.darker());
1706             helpLabel.setText("A peer name is required.");
1707             pages.showPage("Basic");
1708             return false;
1709         }
1710
1711         // Verify security parameters if we are not initialized
1712         // Password and principal
1713         if (null != idPanel.passwd) {
1714             String passwd = idPanel.getPassword();
1715             String vpasswd = idPanel.getVerifyPassword();
1716
1717             // Verify password
1718             // must be at least 8 chars a la unix
1719             if (passwd.length() < 8) {
1720                 // Clear password text boxes
1721                 idPanel.clearPasswords();
1722
1723                 helpLabel.setForeground(Color.red.darker());
1724                 helpLabel.setText("Passwords must be at least 8 characters");
1725                 pages.showPage("Basic");
1726                 return false;
1727             }
1728
1729             // must be identical
1730             if (!passwd.equals(vpasswd)) {
1731                 // Clear password text boxes
1732                 idPanel.clearPasswords();
1733
1734                 helpLabel.setForeground(Color.red.darker());
1735                 helpLabel.setText("Password does not match Verify Password");
1736                 pages.showPage("Basic");
1737                 return false;
1738             }
1739         }
1740
1741         // make sure *some* transport is enabled.
1742         if ((!(httpPanel.useMe.getState())) && (!(tcpPanel.useMe.getState()))) {
1743             helpLabel.setForeground(Color.red.darker());
1744             helpLabel.setText("At least one of TCP or HTTP must be enabled.");
1745             pages.showPage("Advanced");
1746             return false;
1747         }
1748
1749         // http settings
1750         if (httpPanel.useMe.getState()) {
1751             // make sure at least incoming or outgoing enabled.
1752             if (!httpPanel.clientEnabled.getState() && !httpPanel.publicAddr.getState()) {
1753                 helpLabel.setForeground(Color.red.darker());
1754                 helpLabel.setText("Must enable incoming and/or outcoming to enable HTTP");
1755                 pages.showPage("Advanced");
1756                 return false;
1757             }
1758
1759             // Check the http port fields.
1760             boolean valid = verifyAddr("HTTP", httpPanel.publicAddr.getState(), httpPanel.ifAddr.getPort(),
1761                     httpPanel.publicAddr.getHost(), httpPanel.publicAddr.getPort());
1762
1763             if (!valid) {
1764                 return false;
1765             }
1766         }
1767
1768         // tcp settings
1769         if (tcpPanel.useMe.getState()) {
1770             // make sure at least incoming or outgoing enabled.
1771             if (!tcpPanel.clientEnabled.getState() && !tcpPanel.publicAddr.getState() && !tcpPanel.multicast.getState()) {
1772                 helpLabel.setForeground(Color.red.darker());
1773                 helpLabel.setText("Must enable at least one of incoming, outcoming or multicast to enable TCP");
1774                 pages.showPage("Advanced");
1775                 return false;
1776             }
1777
1778             // Check the tcp port fields.
1779             boolean valid = verifyAddr("TCP", tcpPanel.publicAddr.getState(), tcpPanel.ifAddr.getPort(),
1780                     tcpPanel.publicAddr.getHost(), tcpPanel.publicAddr.getPort());
1781
1782             if (!valid) {
1783                 return false;
1784             }
1785         }
1786
1787         if (!relayPanel.useRelay.getState() && (!httpPanel.useMe.getState() || !httpPanel.publicAddr.getState())
1788                 && (!tcpPanel.useMe.getState() || !tcpPanel.publicAddr.getState())) {
1789             helpLabel.setForeground(Color.red.darker());
1790             helpLabel.setText("Must use Relay if incoming not enabled for TCP and/or HTTP");
1791             pages.showPage("Relay/Rendezvous");
1792             return false;
1793         }
1794
1795         if (enablingPanel.isRelay.getState() && (!httpPanel.useMe.getState() || !httpPanel.publicAddr.getState())
1796                 && (!tcpPanel.useMe.getState() || !tcpPanel.publicAddr.getState())) {
1797             helpLabel.setForeground(Color.red.darker());
1798             helpLabel.setText("Must enable incoming for TCP and/or HTTP to enable Relay");
1799             pages.showPage("Advanced");
1800             return false;
1801         }
1802
1803         if (enablingPanel.isRendezvous.getState() && (!httpPanel.useMe.getState() || !httpPanel.publicAddr.getState())
1804                 && (!tcpPanel.useMe.getState() || !tcpPanel.publicAddr.getState())) {
1805             helpLabel.setForeground(Color.red.darker());
1806             helpLabel.setText("Must enable incoming for TCP and/or HTTP to enable Rendezvous");
1807             pages.showPage("Advanced");
1808             return false;
1809         }
1810
1811         // if use only seeds is specified then at least one seed must be
1812         // provided.
1813         if (rdvPanel.useOnlySeeds.getState()) {
1814             String[] rdvAddrs = rdvPanel.seeds.getItems();
1815
1816             String[] rdvSeedAddrs = rdvPanel.seeding.getItems();
1817
1818             if ((rdvAddrs.length == 0) && (rdvSeedAddrs.length == 0)) {
1819                 helpLabel.setForeground(Color.red.darker());
1820                 helpLabel.setText("Must provide at least one seed rendezvous");
1821                 pages.showPage("Rendezvous/Relays");
1822                 return false;
1823             }
1824         }
1825
1826         // if relay is to be used, make sure we have atleast one relay
1827         // addr for the enabled transport(s)
1828         if (relayPanel.useRelay.getState()) {
1829             String[] relayaddrs = relayPanel.seeds.getItems();
1830
1831             String[] relaySeedaddrs = relayPanel.seeding.getItems();
1832
1833             if ((relayaddrs.length == 0) && (relaySeedaddrs.length == 0)) {
1834                 helpLabel.setForeground(Color.red.darker());
1835                 helpLabel.setText("Must provide at least one seed Relay address");
1836                 pages.showPage("Rendezvous/Relays");
1837                 return false;
1838             }
1839         }
1840
1841         return true;
1842     }
1843
1844     /*
1845      * Updates the PlatformConfig Advertisement
1846      */
1847     private boolean saveValues() {
1848         try {
1849             // set the peer name
1850             configAdv.setName(idPanel.getName());
1851
1852             // Save the http config
1853             HTTPAdv httpAdv = (HTTPAdv) AdvertisementFactory.newAdvertisement(HTTPAdv.getAdvertisementType());
1854
1855             httpAdv.setConfigMode(httpPanel.getConfigMode());
1856
1857             String chosenIntf = httpPanel.getInterfaceAddress();
1858
1859             if (chosenIntf.startsWith("A")) {
1860                 httpAdv.setInterfaceAddress(null);
1861             } else {
1862                 httpAdv.setInterfaceAddress(chosenIntf);
1863             }
1864
1865             httpAdv.setPort(Integer.parseInt(httpPanel.ifAddr.getPort()));
1866
1867             httpAdv.setClientEnabled(httpPanel.clientEnabled.getState());
1868
1869             httpAdv.setServerEnabled(httpPanel.publicAddr.getState());
1870
1871             // If there's nothing interesting inthere, do not save it.
1872             if (0 == httpPanel.publicAddr.getHost().trim().length()) {
1873                 httpAdv.setServer(null);
1874             } else {
1875                 httpAdv.setServer(httpPanel.publicAddr.getHost() + ":" + httpPanel.publicAddr.getPort());
1876             }
1877
1878             httpAdv.setPublicAddressOnly(httpPanel.getPubAddrOnly());
1879
1880             configAdv.putServiceParam(PeerGroup.httpProtoClassID, wrapParm(httpAdv, httpPanel.useMe.getState()));
1881
1882             // Save tcp configuration
1883             TCPAdv tcpAdv = (TCPAdv) AdvertisementFactory.newAdvertisement(TCPAdv.getAdvertisementType());
1884
1885             tcpAdv.setConfigMode(tcpPanel.getConfigMode());
1886
1887             chosenIntf = tcpPanel.getInterfaceAddress();
1888             if (chosenIntf.startsWith("A")) {
1889                 tcpAdv.setInterfaceAddress(null);
1890             } else {
1891                 tcpAdv.setInterfaceAddress(chosenIntf);
1892             }
1893
1894             try {
1895                 int theTcpPort = Integer.parseInt(tcpPanel.ifAddr.getPort());
1896
1897                 tcpAdv.setPort(theTcpPort);
1898                 if (0 == theTcpPort) {
1899                     tcpAdv.setStartPort(0);
1900                     tcpAdv.setEndPort(0);
1901                 }
1902             } catch (NumberFormatException ignored) {
1903                 /* verifyInput already checked it */
1904             }
1905
1906             tcpAdv.setClientEnabled(tcpPanel.clientEnabled.getState());
1907
1908             tcpAdv.setServerEnabled(tcpPanel.publicAddr.getState());
1909
1910             if (0 == tcpPanel.publicAddr.getHost().trim().length()) {
1911                 tcpAdv.setServer(null);
1912             } else {
1913                 tcpAdv.setServer(tcpPanel.publicAddr.getHost() + ":" + tcpPanel.publicAddr.getPort());
1914             }
1915
1916             tcpAdv.setMulticastState(tcpPanel.multicast.getState());
1917             tcpAdv.setMulticastAddr(tcpMulticastAddr);
1918             tcpAdv.setMulticastPort(tcpMulticastPort);
1919             tcpAdv.setMulticastSize(tcpMulticastLength);
1920
1921             tcpAdv.setPublicAddressOnly(tcpPanel.getPubAddrOnly());
1922
1923             configAdv.putServiceParam(PeerGroup.tcpProtoClassID, wrapParm(tcpAdv, tcpPanel.useMe.getState()));
1924
1925             // save the proxy service settings
1926             XMLDocument proxy = (XMLDocument) StructuredDocumentFactory.newStructuredDocument(MimeMediaType.XMLUTF8, "Parm");
1927
1928             if (!enablingPanel.isJxmeProxy.getState()) {
1929                 proxy.appendChild(proxy.createElement("isOff"));
1930             }
1931
1932             configAdv.putServiceParam(PeerGroup.proxyClassID, proxy);
1933
1934             // Save the Rendezvous Configuration
1935             RdvConfigAdv rdvConf = (RdvConfigAdv) AdvertisementFactory.newAdvertisement(RdvConfigAdv.getAdvertisementType());
1936
1937             rdvConf.setConfiguration(
1938                     enablingPanel.isRendezvous.getState() ? RendezVousConfiguration.RENDEZVOUS :
1939                             rdvPanel.useRdv.getState() ? RendezVousConfiguration.EDGE : RendezVousConfiguration.AD_HOC);
1940             rdvConf.setUseOnlySeeds(rdvPanel.useOnlySeeds.getState());
1941
1942             for (String s2 : Arrays.asList(rdvPanel.seeds.getItems())) {
1943                 rdvConf.addSeedRendezvous(s2);
1944             }
1945
1946             for (String s3 : Arrays.asList(rdvPanel.seeding.getItems())) {
1947                 rdvConf.addSeedingURI(s3);
1948             }
1949
1950             XMLDocument rdvDoc = (XMLDocument) rdvConf.getDocument(MimeMediaType.XMLUTF8);
1951
1952             configAdv.putServiceParam(PeerGroup.rendezvousClassID, rdvDoc);
1953
1954             // save the relay settings
1955             RelayConfigAdv relayConfig = (RelayConfigAdv) AdvertisementFactory.newAdvertisement(
1956                     RelayConfigAdv.getAdvertisementType());
1957
1958             relayConfig.setServerEnabled(enablingPanel.isRelay.getState());
1959             relayConfig.setClientEnabled(relayPanel.useRelay.getState());
1960
1961             for (String s : Arrays.asList(relayPanel.seeds.getItems())) {
1962                 relayConfig.addSeedRelay(s);
1963             }
1964
1965             for (String s1 : Arrays.asList(relayPanel.seeding.getItems())) {
1966                 relayConfig.addSeedingURI(s1);
1967             }
1968
1969             relayConfig.setUseOnlySeeds(relayPanel.useOnlySeeds.getState());
1970
1971             XMLDocument relayDoc = (XMLDocument) relayConfig.getDocument(MimeMediaType.XMLUTF8);
1972
1973             // check if the relay service should be disabled completely
1974             boolean relayDisabled = (!enablingPanel.isRelay.getState() && !relayPanel.useRelay.getState());
1975
1976             if (relayDisabled) {
1977                 relayDoc.appendChild(relayDoc.createElement("isOff"));
1978             }
1979
1980             configAdv.putServiceParam(PeerGroup.relayProtoClassID, relayDoc);
1981
1982             // Save the security configuration parameters
1983             // If we initialized security
1984             // Otherwise they come from the security login dialog
1985             if (null != idPanel.passwd) {
1986                 PSEConfigAdv pseConf = (PSEConfigAdv) AdvertisementFactory.newAdvertisement(PSEConfigAdv.getAdvertisementType());
1987
1988                 PSEUtils.IssuerInfo info = PSEUtils.genCert(idPanel.getName(), null);
1989
1990                 pseConf.setCertificate(info.cert);
1991                 pseConf.setPrivateKey(info.subjectPkey, idPanel.getPassword().toCharArray());
1992
1993                 XMLDocument pseDoc = (XMLDocument) pseConf.getDocument(MimeMediaType.XMLUTF8);
1994
1995                 configAdv.putServiceParam(PeerGroup.membershipClassID, pseDoc);
1996             }
1997         } catch (Throwable bad) {
1998             bad.printStackTrace();
1999             return false;
2000         }
2001
2002         return true;
2003     }
2004
2005     private XMLDocument wrapParm(Advertisement srcAdv, boolean enabled) {
2006         try {
2007             XMLDocument advDoc = (XMLDocument) srcAdv.getDocument(MimeMediaType.XMLUTF8);
2008
2009             XMLDocument doc = (XMLDocument) StructuredDocumentFactory.newStructuredDocument(MimeMediaType.XMLUTF8, "Parm");
2010
2011             StructuredDocumentUtils.copyElements(doc, doc, advDoc);
2012             if (!enabled) {
2013                 doc.appendChild(doc.createElement("isOff"));
2014             }
2015
2016             return doc;
2017         } catch (Throwable ez1) {
2018             ez1.printStackTrace();
2019             return null;
2020         }
2021     }
2022 }