1/*
2 * CDDL HEADER START
3 *
4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License (the "License").
6 * You may not use this file except in compliance with the License.
7 *
8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 * or http://www.opensolaris.org/os/licensing.
10 * See the License for the specific language governing permissions
11 * and limitations under the License.
12 *
13 * When distributing Covered Code, include this CDDL HEADER in each
14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 * If applicable, add the following below this CDDL HEADER, with the
16 * fields enclosed by brackets "[]" replaced with your own identifying
17 * information: Portions Copyright [yyyy] [name of copyright owner]
18 *
19 * CDDL HEADER END
20 */
21/*
22 * Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
23 * Use is subject to license terms.
24 */
25package com.sun.dhcpmgr.client;
26
27import java.awt.*;
28import java.awt.event.*;
29import java.util.*;
30import java.text.MessageFormat;
31import java.net.*;
32
33import javax.swing.*;
34import javax.swing.table.*;
35import javax.swing.event.*;
36import javax.swing.border.*;
37
38import com.sun.dhcpmgr.ui.*;
39import com.sun.dhcpmgr.data.*;
40import com.sun.dhcpmgr.server.*;
41import com.sun.dhcpmgr.bridge.BridgeException;
42import com.sun.dhcpmgr.bridge.ExistsException;
43
44/**
45 * This wizard configures the DHCP service.  It also has a mode switch so
46 * that it is also usable for just adding a single network, so that in
47 * the tool it actually performs the Network Wizard function as well.
48 */
49public class ConfigWizard extends DSWizard {
50    private boolean fullConfig;
51    private DhcpServiceMgr server;
52    private int leaseLength = 3600*24;
53    private boolean leaseNegotiable = true;
54    private String dnsDomain;
55    private Vector dnsServs;
56    private Network network;
57    private boolean isLan = true;
58    private boolean routerDiscovery = true;
59    private IPAddress router = null;
60    private String nisDomain;
61    private Vector nisServs;
62    private static final String [] unitChoices = {
63	ResourceStrings.getString("cfg_wiz_hours"),
64	ResourceStrings.getString("cfg_wiz_days"),
65	ResourceStrings.getString("cfg_wiz_weeks") };
66    private static final int [] unitMultiples = { 60*60, 24*60*60, 7*24*60*60 };
67    private HostResource hostResource = null;
68
69    /**
70     * This class defines a host resource component.
71     */
72    private class HostResource extends Box {
73
74	/**
75	 * The host resource(eg., files, dns).
76	 */
77	private String resource = null;
78
79	/**
80	 * The description of the resource.
81	 */
82	private String description = null;
83
84	/**
85	 * The button for the resource.
86	 */
87	private HostButton hostButton = null;
88
89	/**
90	 * The domain field for the resource (if any)
91	 */
92	private NoSpaceField domainField = null;
93
94	/**
95	 * The constructor.
96	 * @param resource the resource value for the config file
97	 * @param description description of the resource
98	 * @param defaultdomain default domain (if any) for the resource
99	 * @param enabled determines whether resource is selectable
100	 */
101	public HostResource(String resource, String description,
102	    String defaultDomain, String domainDescription, boolean enabled) {
103
104	    super(BoxLayout.X_AXIS);
105
106	    this.resource = resource;
107	    this.description = description;
108
109	    // Every host resource needs a button even if the resource
110	    // isn't one that will be selectable.
111	    //
112	    hostButton = new HostButton(this, false);
113	    hostButton.setAlignmentX(Component.LEFT_ALIGNMENT);
114	    add(hostButton);
115	    if (!enabled) {
116		hostButton.setEnabled(false);
117		defaultDomain = new String();
118	    }
119
120	    // If the defaultDomain is null, then the host resource
121	    // does not require a domain. Otherwise, the resource
122	    // must have a text field so that the user can supply
123	    // a domain.
124	    //
125	    if (defaultDomain != null) {
126		add(Box.createHorizontalStrut(20));
127
128		Box domainBox = Box.createHorizontalBox();
129
130		JLabel label = new JLabel(domainDescription);
131		label.setForeground(Color.black);
132		domainBox.add(label);
133
134		domainField = new NoSpaceField(defaultDomain, 10);
135		domainField.setEnabled(false);
136		domainField.setMaximumSize(domainField.getPreferredSize());
137
138		label.setLabelFor(domainField);
139		domainBox.add(domainField);
140		label.setToolTipText(description);
141
142		add(domainBox);
143
144		if (!enabled) {
145		    domainField.setEditable(false);
146		    label.setEnabled(false);
147		} else {
148		    // Disable the forward button if domain empty.
149		    DocumentListener listener = new DocumentListener() {
150			public void insertUpdate(DocumentEvent e) {
151			    setForwardEnabled(
152				domainField.getText().length() != 0);
153			}
154			public void changedUpdate(DocumentEvent e) {
155			    insertUpdate(e);
156			}
157			public void removeUpdate(DocumentEvent e) {
158			    insertUpdate(e);
159			}
160		    };
161		    domainField.getDocument().addDocumentListener(listener);
162		}
163
164	    }
165
166	} // constructor
167
168	/**
169	 * Sets or unsets the host resource.
170	 * @param isSelected if true, sets the resource, else unsets it
171	 */
172	public void setSelected(boolean isSelected) {
173	    if (isSelected) {
174		setHostResource(this);
175		if (!hostButton.isSelected()) {
176		    hostButton.setSelected(true);
177		}
178		if (domainField != null) {
179		    domainField.setEnabled(true);
180		    setForwardEnabled(domainField.getText().length() != 0);
181		} else {
182		    setForwardEnabled(true);
183		}
184	    } else {
185		if (domainField != null) {
186		    domainField.setEnabled(false);
187		}
188	    }
189	} // setSelected
190
191	/**
192	 * Returns the host resource.
193	 * @return the host resource.
194	 */
195	public String getResource() {
196	    return resource;
197	} // getResource
198
199	/**
200	 * Returns the resource description.
201	 * @return the resource description.
202	 */
203	public String getDescription() {
204	    return description;
205	} // getDescription
206
207	/**
208	 * Returns the domain for this component.
209	 * @return the domain for this component.
210	 */
211	public String getDomain() {
212	    if (domainField == null) {
213		return null;
214	    } else {
215		return domainField.getText();
216	    }
217	} // getDomain
218
219	/**
220	 * Returns the HostButton contained in this component.
221	 * @return the HostButton contained in this component.
222	 */
223	public HostButton getHostButton() {
224	    return hostButton;
225	} // getHostButton
226
227    } // hostResource
228
229    /**
230     * This class maps a radio button to its HostResource
231     */
232    private class HostButton extends JRadioButton {
233
234	/**
235	 * The HostResource to link to the radio button.
236	 */
237	private HostResource hostResource = null;
238
239	/**
240	 * Constructs a HostButton from a HostResource and determines
241	 * whether the button should be selected using the boolean argument.
242	 * @param hostResource the HostResource to map to the radio button.
243	 * @param selected select the radio button?
244	 */
245	public HostButton(HostResource hostResource, boolean selected) {
246	    super(hostResource.getDescription(), selected);
247	    this.hostResource = hostResource;
248	} // constructor
249
250	/**
251	 * Returns the HostResource mapped to the radio button.
252	 * @return the HostResource mapped to the radio button.
253	 */
254	public HostResource getHostResource() {
255	    return hostResource;
256	} // getHostResource
257
258    } // HostButton
259
260    // Select where host data will be stored.
261    class HostDataStep implements WizardStep {
262
263	/**
264	 * The component provided to the wizard.
265	 */
266	private Box stepBox;
267
268	/**
269	 * The basic constructor for the wizard step.
270	 */
271	public HostDataStep() {
272
273	    stepBox = Box.createVerticalBox();
274
275	    // Explanatory step text
276	    //
277	    JComponent c = Wizard.createTextArea(
278		ResourceStrings.getString("cfg_wiz_host_explain"), 2, 45);
279	    c.setAlignmentX(Component.LEFT_ALIGNMENT);
280	    stepBox.add(c);
281	    stepBox.add(Box.createVerticalStrut(5));
282
283	    // Create button listener, that will set the selected
284	    // host resource when the button is selected.
285	    //
286	    ChangeListener buttonListener = new ChangeListener() {
287		public void stateChanged(ChangeEvent e) {
288		    HostButton button = (HostButton)e.getSource();
289		    HostResource hostResource = button.getHostResource();
290		    hostResource.setSelected(button.isSelected());
291		}
292	    };
293
294	    // Create panel that will contain the buttons.
295	    //
296	    JPanel boxPanel = new JPanel();
297	    boxPanel.setAlignmentX(Component.LEFT_ALIGNMENT);
298	    boxPanel.setLayout(new GridLayout(4, 1));
299
300	    // List the host resource choices.
301	    //
302	    ButtonGroup buttonGroup = new ButtonGroup();
303
304	    // The "do not manage hosts" option.
305	    //
306	    String hostDescription =
307		ResourceStrings.getString("cfg_wiz_no_host_management");
308	    HostResource hostResource = new HostResource(null,
309		hostDescription, null, null, true);
310	    HostButton hbMgt = hostResource.getHostButton();
311            hbMgt.setToolTipText(hostDescription);
312	    hostResource.setSelected(true);
313	    hostResource.getHostButton().addChangeListener(buttonListener);
314	    buttonGroup.add(hostResource.getHostButton());
315	    boxPanel.add(hostResource);
316
317	    // The "files" option.
318	    //
319	    hostDescription =
320		ResourceStrings.getString("cfg_wiz_files");
321	    hostResource = new HostResource(DhcpConfigOpts.DSVC_CV_FILES,
322		hostDescription, null, null, true);
323	    HostButton hb = hostResource.getHostButton();
324	    hb.setToolTipText(hostDescription);
325	    hostResource.getHostButton().addChangeListener(buttonListener);
326	    buttonGroup.add(hostResource.getHostButton());
327	    boxPanel.add(hostResource);
328
329	    // The "dns" option. Only enabled if it can be managed
330	    // from the selected server.
331	    //
332	    String domainDefault = null;
333	    boolean enabled = false;
334	    String domainDescription =
335		ResourceStrings.getString("cfg_wiz_domain") + " ";
336	    try {
337		domainDefault =
338		    server.getStringOption(StandardOptions.CD_DNSDOMAIN, "");
339	    } catch (Throwable e) {
340		domainDefault = new String();
341	    }
342
343	    try {
344		enabled =
345		    server.isHostsValid(DhcpConfigOpts.DSVC_CV_DNS, "");
346	    } catch (Throwable e) {
347		enabled = false;
348	    }
349
350	    hostDescription =
351		ResourceStrings.getString("cfg_wiz_dns");
352
353	    hostResource = new HostResource(DhcpConfigOpts.DSVC_CV_DNS,
354		hostDescription, domainDefault, domainDescription, enabled);
355	    HostButton hbDNS = hostResource.getHostButton();
356            hbDNS.setToolTipText(hostDescription);
357	    hostResource.getHostButton().addChangeListener(buttonListener);
358	    buttonGroup.add(hostResource.getHostButton());
359	    boxPanel.add(hostResource);
360
361	    // Add the panel to the stepBox component.
362	    //
363	    stepBox.add(boxPanel);
364	    stepBox.add(Box.createVerticalStrut(10));
365	    stepBox.add(Box.createVerticalGlue());
366
367	} // constructor
368
369	public String getDescription() {
370	    return ResourceStrings.getString("cfg_wiz_hostdata_desc");
371	} // getDescription
372
373	public Component getComponent() {
374	    return stepBox;
375	} // getComponent
376
377	public void setActive(int direction) {
378	    setForwardEnabled(true);
379	} // setActive
380
381	public boolean setInactive(int direction) {
382
383	    // If moving forward, validate that the host resource/domain
384	    // input by the user is manageable from the selected server.
385	    //
386	    boolean valid = true;
387	    if (direction == FORWARD) {
388		String resource = getHostResource().getResource();
389		String domain = getHostResource().getDomain();
390		if (resource != null) {
391		    try {
392			valid = server.isHostsValid(resource, domain);
393		    } catch (Throwable e) {
394			valid = false;
395		    }
396		}
397		if (!valid) {
398		    JOptionPane.showMessageDialog(ConfigWizard.this,
399			ResourceStrings.getString("cfg_wiz_invalid_host"),
400			ResourceStrings.getString("input_error"),
401			JOptionPane.ERROR_MESSAGE);
402		}
403	    }
404	    return (valid);
405	} // setInactive
406
407    } // HostDataStep
408
409    // This step specifies lease length and renewal policies for the server
410    class LeaseStep implements WizardStep {
411	private IntegerField length;
412	private JComboBox units;
413	private JCheckBox negotiable;
414	private Box stepBox;
415
416	public LeaseStep() {
417	    stepBox = Box.createVerticalBox();
418
419	    // Explanatory text
420	    stepBox.add(Wizard.createTextArea(
421		ResourceStrings.getString("cfg_wiz_lease_explain"), 3, 45));
422
423	    // Need to input a number together with units
424	    JPanel flowPanel = new JPanel();
425
426	    Mnemonic mnLease =
427                new Mnemonic(ResourceStrings.getString("cfg_wiz_lease_length"));
428            JLabel lblLeaseLen = new JLabel(
429                mnLease.getString());
430
431	    flowPanel.add(lblLeaseLen);
432
433	    // Use a box for the value and units to keep together in layout
434	    Box leaseBox = Box.createHorizontalBox();
435	    length = new IntegerField();
436	    leaseBox.add(length);
437	    leaseBox.add(Box.createHorizontalStrut(5));
438
439	    lblLeaseLen.setLabelFor(length);
440	    lblLeaseLen.setToolTipText(mnLease.getString());
441	    lblLeaseLen.setDisplayedMnemonic(mnLease.getMnemonic());
442
443	    units = new JComboBox(unitChoices);
444	    leaseBox.add(units);
445	    flowPanel.add(leaseBox);
446	    stepBox.add(flowPanel);
447	    stepBox.add(Box.createVerticalStrut(10));
448
449	    // Explain negotiable, provide selection for it
450	    stepBox.add(Wizard.createTextArea(
451		ResourceStrings.getString("cfg_wiz_negotiable_explain"), 6,
452		45));
453
454	    negotiable = new JCheckBox(
455		ResourceStrings.getString("cfg_wiz_negotiable"), true);
456	    negotiable.setToolTipText(
457		ResourceStrings.getString("cfg_wiz_negotiable"));
458	    negotiable.setAlignmentX(Component.CENTER_ALIGNMENT);
459	    stepBox.add(negotiable);
460	    stepBox.add(Box.createVerticalGlue());
461	}
462
463	public String getDescription() {
464	    return ResourceStrings.getString("cfg_wiz_lease_desc");
465	}
466
467	public Component getComponent() {
468	    return stepBox;
469	}
470
471	public void setActive(int direction) {
472	    setForwardEnabled(true);
473	    // Set the units field to the maximum unit this value expresses
474	    int lengthVal = 0;
475	    int i;
476	    for (i = unitMultiples.length - 1; i >= 0; --i) {
477		lengthVal = leaseLength / unitMultiples[i];
478		if (lengthVal != 0) {
479		    if (leaseLength % unitMultiples[i] == 0) {
480			break;
481		    }
482		}
483	    }
484	    if (i == -1) {
485		i = 0;
486	    }
487	    units.setSelectedIndex(i);
488	    length.setValue(lengthVal);
489	    negotiable.setSelected(leaseNegotiable);
490	}
491
492	public boolean setInactive(int direction) {
493	    // Leases cannot be zero length
494	    long lease = (long)length.getValue();
495	    if (lease == 0) {
496		JOptionPane.showMessageDialog(ConfigWizard.this,
497		    ResourceStrings.getString("cfg_wiz_zero_lease"),
498		    ResourceStrings.getString("input_error"),
499		    JOptionPane.ERROR_MESSAGE);
500		return false;
501	    }
502	    int multiplier = unitMultiples[units.getSelectedIndex()];
503	    lease *= multiplier;
504	    if (lease > Integer.MAX_VALUE) {
505		// Value is too large
506		MessageFormat form = new MessageFormat(
507		    ResourceStrings.getString("cfg_wiz_lease_overflow"));
508		Object args = new Object[] {
509		    new Integer(Integer.MAX_VALUE / multiplier),
510		    units.getSelectedItem()
511		};
512		JOptionPane.showMessageDialog(ConfigWizard.this,
513		    form.format(args), ResourceStrings.getString("input_error"),
514		    JOptionPane.ERROR_MESSAGE);
515		return false;
516	    }
517	    leaseLength = (int)lease;
518	    leaseNegotiable = negotiable.isSelected();
519	    return true;
520	}
521    }
522
523    // Step to configure DNS
524    class DnsStep implements WizardStep {
525	private NoSpaceField domain;
526	private IPAddressList serverList;
527	private Box stepBox;
528	private boolean firstActive = true;
529
530	public DnsStep() {
531	    stepBox = Box.createVerticalBox();
532
533	    // Explanatory text
534	    stepBox.add(Wizard.createTextArea(
535		ResourceStrings.getString("cfg_wiz_dns_explain"), 5, 45));
536	    stepBox.add(Box.createVerticalStrut(10));
537
538	    // Domain first
539	    JPanel fieldPanel = new JPanel(new FieldLayout());
540
541	    Mnemonic mnDNS =
542                new Mnemonic(ResourceStrings.getString("cfg_wiz_dns_domain"));
543            JLabel jlDNSDomain = new JLabel(mnDNS.getString());
544            fieldPanel.add(FieldLayout.LABEL, jlDNSDomain);
545
546	    domain = new NoSpaceField();
547	    jlDNSDomain.setLabelFor(domain);
548	    jlDNSDomain.setToolTipText(mnDNS.getString());
549	    jlDNSDomain.setDisplayedMnemonic(mnDNS.getMnemonic());
550	    fieldPanel.add(FieldLayout.FIELD, domain);
551	    stepBox.add(fieldPanel);
552
553	    serverList = new IPAddressList();
554	    Border tb = BorderFactory.createTitledBorder(
555		BorderFactory.createLineBorder(Color.black),
556		ResourceStrings.getString("cfg_wiz_dns_servers"));
557	    serverList.setBorder(BorderFactory.createCompoundBorder(tb,
558		BorderFactory.createEmptyBorder(5, 5, 5, 5)));
559	    stepBox.add(serverList);
560	}
561
562	public String getDescription() {
563	    return ResourceStrings.getString("cfg_wiz_dns_desc");
564	}
565
566	public Component getComponent() {
567	    return stepBox;
568	}
569
570	public void setActive(int direction) {
571	    setForwardEnabled(true);
572
573	    // First time through, ask the server for the defaults
574	    if (firstActive) {
575		firstActive = false;
576		try {
577		    domain.setText(
578			server.getStringOption(StandardOptions.CD_DNSDOMAIN,
579			""));
580		    serverList.setAddressList(
581			server.getIPOption(StandardOptions.CD_DNSSERV, ""));
582		} catch (Throwable e) {
583		    // Ignore errors, we're just supplying defaults
584		}
585	    }
586	}
587
588	public boolean setInactive(int direction) {
589	    if (direction == FORWARD) {
590		/*
591		 * Either must supply both a domain and a list of servers, or
592		 * neither
593		 */
594		if ((domain.getText().length() == 0)
595			!= (serverList.getListSize() == 0)) {
596		    JOptionPane.showMessageDialog(ConfigWizard.this,
597			ResourceStrings.getString("cfg_wiz_dns_both"),
598			ResourceStrings.getString("input_error"),
599			JOptionPane.ERROR_MESSAGE);
600		    return false;
601		}
602	    }
603	    dnsDomain = domain.getText();
604	    dnsServs = serverList.getAddressList();
605	    return true;
606	}
607    }
608
609    // Select the network to configure
610    class NetworkStep implements WizardStep {
611	private JComboBox networkBox;
612	private NetworkListModel networkListModel;
613	private IPAddressField mask;
614	private Box stepBox;
615	private boolean firstActive = true;
616	private Hashtable maskTable;
617
618	// Model for the list of networks
619	class NetworkListModel extends AbstractListModel
620		implements ComboBoxModel {
621	    private Object currentValue;
622	    private String [] data = null;
623
624	    public int getSize() {
625		if (data == null) {
626		    return 0;
627		} else {
628		    return data.length;
629		}
630	    }
631
632	    public Object getElementAt(int index) {
633		if (data == null) {
634		    return null;
635		} else {
636		    return data[index];
637		}
638	    }
639
640	    public void setSelectedItem(Object anItem) {
641		currentValue = anItem;
642		fireContentsChanged(this, -1, -1);
643	    }
644
645	    public Object getSelectedItem() {
646		return currentValue;
647	    }
648
649	    public void setData(Vector addrs) {
650		data = new String[addrs.size()];
651		addrs.copyInto(data);
652		fireContentsChanged(this, 0, data.length);
653	    }
654	}
655
656	/*
657	 * Editor for the Network combo box, ensures that a valid IP address
658	 * is entered. This implementation cribbed from Swing's
659	 * BasicComboBoxEditor in plaf/basic
660	 */
661	class NetworkComboBoxEditor implements ComboBoxEditor, FocusListener {
662	    private IPAddressField editor;
663
664	    public NetworkComboBoxEditor() {
665		editor = new IPAddressField();
666		editor.addFocusListener(this);
667	    }
668
669	    public Component getEditorComponent() {
670		return editor;
671	    }
672
673	    public void setItem(Object obj) {
674		if (obj != null) {
675		    editor.setText((String)obj);
676		} else {
677		    editor.setText("");
678		}
679	    }
680
681	    public Object getItem() {
682		return editor.getText();
683	    }
684
685	    public void selectAll() {
686		editor.selectAll();
687		editor.requestFocus();
688	    }
689
690	    public void focusGained(FocusEvent e) {
691	    }
692
693	    public void focusLost(FocusEvent e) {
694	    }
695
696	    public void addActionListener(ActionListener l) {
697		editor.addActionListener(l);
698	    }
699
700	    public void removeActionListener(ActionListener l) {
701		editor.removeActionListener(l);
702	    }
703	}
704
705	public NetworkStep() {
706	    stepBox = Box.createVerticalBox();
707
708	    // Start with intro text, depending on mode.
709	    if (fullConfig) {
710		stepBox.add(Wizard.createTextArea(
711		    ResourceStrings.getString("cfg_wiz_network_explain"), 4,
712		    45));
713	    } else {
714		stepBox.add(Wizard.createTextArea(
715		    ResourceStrings.getString("net_wiz_net_explain"), 6, 45));
716	    }
717	    stepBox.add(Box.createVerticalStrut(10));
718
719            JPanel panel = new JPanel(new FieldLayout());
720	    Mnemonic mnAddr =
721                new Mnemonic(ResourceStrings.getString("cfg_wiz_network"));
722	    JLabel jlNetworkAddr = new JLabel(mnAddr.getString());
723            panel.add(FieldLayout.LABEL, jlNetworkAddr);
724            networkListModel = new NetworkListModel();
725            networkBox = new JComboBox(networkListModel);
726            networkBox.setEditable(true);
727            networkBox.setEditor(new NetworkComboBoxEditor());
728            panel.add(FieldLayout.FIELD, networkBox);
729	    jlNetworkAddr.setLabelFor(networkBox);
730            jlNetworkAddr.setToolTipText(mnAddr.getString());
731	    jlNetworkAddr.setDisplayedMnemonic(mnAddr.getMnemonic());
732
733	    // Label and text field for subnet mask
734	    Mnemonic mnMask =
735            new Mnemonic(ResourceStrings.getString("cfg_wiz_mask"));
736	    JLabel addrLbl =
737                new JLabel(mnMask.getString());
738            addrLbl.setToolTipText(mnMask.getString());
739            panel.add(FieldLayout.LABEL, addrLbl);
740            mask = new IPAddressField();
741            addrLbl.setLabelFor(mask);
742	    addrLbl.setDisplayedMnemonic(mnMask.getMnemonic());
743
744	    panel.add(FieldLayout.FIELD, mask);
745	    stepBox.add(panel);
746
747	    stepBox.add(Box.createVerticalStrut(10));
748
749	    if (fullConfig) {
750		stepBox.add(Wizard.createTextArea(
751		    ResourceStrings.getString("cfg_wiz_network_explainmore"), 4,
752		    45));
753	    }
754	    stepBox.add(Box.createVerticalGlue());
755
756	    /*
757	     * Listen to selection changes on the network box and change the
758	     * netmask accordingly.
759	     */
760	    networkBox.addItemListener(new ItemListener() {
761		public void itemStateChanged(ItemEvent e) {
762		    if (e.getStateChange() == ItemEvent.SELECTED) {
763			String s = (String)e.getItem();
764			IPAddress a = (IPAddress)maskTable.get(s);
765			if (a != null) {
766			    // We know the correct value, so set it
767			    mask.setValue(a);
768			}
769		    }
770		}
771	    });
772	}
773
774	public String getDescription() {
775	    return ResourceStrings.getString("cfg_wiz_network_desc");
776	}
777
778	public Component getComponent() {
779	    return stepBox;
780	}
781
782	public void setActive(int direction) {
783	    setForwardEnabled(true);
784	    if (firstActive) {
785		firstActive = false;
786		maskTable = new Hashtable();
787		try {
788		    /*
789		     * Initialize list to all networks directly attached to
790		     * the server
791		     */
792		    IPInterface[] ifs = new IPInterface[0];
793		    try {
794			ifs = server.getInterfaces();
795		    } catch (BridgeException e) {
796			// we're not configured yet, apparently
797			ifs = null;
798		    }
799		    Vector addrs = new Vector();
800
801		    // Get list of already-configured networks
802		    Network [] nets = new Network[0];
803		    try {
804			nets = DataManager.get().getNetworks(true);
805		    } catch (BridgeException e) {
806			// Ignore; we're not configured yet, apparently
807		    }
808		    /*
809		     * Now filter the list so only unconfigured networks
810		     * show up in the selection list.
811		     */
812		    if (ifs != null) {
813		    for (int i = 0; i < ifs.length; ++i) {
814			boolean alreadyConfigured = false;
815			for (int j = 0; j < nets.length; ++j) {
816			    if (ifs[i].getNetwork().equals(nets[j])) {
817				alreadyConfigured = true;
818				break;
819			    }
820			}
821			if (!alreadyConfigured) {
822			    // Add to list
823			    String s = ifs[i].getNetwork().
824				getNetworkNumber().getHostAddress();
825			    addrs.addElement(s);
826			    // Save netmask for retrieval later
827			    maskTable.put(s, ifs[i].getNetwork().getMask());
828			}
829		    }
830		    }
831		    networkListModel.setData(addrs);
832		    if (networkBox.getItemCount() > 0) {
833			networkBox.setSelectedIndex(0);
834		    }
835		} catch (Throwable e) {
836		    // Do nothing, we're just setting defaults
837		    e.printStackTrace();
838		}
839	    }
840	}
841
842	public boolean setInactive(int direction) {
843	    if (direction == FORWARD) {
844		try {
845		    network = new Network((String)networkBox.getSelectedItem());
846		    if (mask.getValue() == null) {
847			/*
848			 * Check for empty, in which case we just let the
849			 * default happen
850			 */
851			if (mask.getText().length() != 0) {
852			    // Not a valid subnet mask
853			    MessageFormat form = new MessageFormat(
854				ResourceStrings.getString("cfg_wiz_bad_mask"));
855			    Object [] args = new Object[1];
856			    args[0] = mask.getText();
857			    JOptionPane.showMessageDialog(ConfigWizard.this,
858				form.format(args),
859				ResourceStrings.getString("input_error"),
860				JOptionPane.ERROR_MESSAGE);
861			    return false;
862			}
863		    } else {
864			network.setMask(mask.getValue());
865		    }
866
867		    // Check for network already configured, error if so
868		    Network [] nets = new Network[0];
869		    try {
870			nets = DataManager.get().getNetworks(false);
871		    } catch (BridgeException e) {
872			// Ignore; must not be configured yet
873		    }
874		    for (int i = 0; i < nets.length; ++i) {
875			if (network.equals(nets[i])) {
876			    MessageFormat form = new MessageFormat(
877				ResourceStrings.getString(
878				"cfg_wiz_network_configured"));
879			    Object [] args = new Object[1];
880			    args[0] = network.getAddress().getHostAddress();
881			    JOptionPane.showMessageDialog(ConfigWizard.this,
882				form.format(args),
883				ResourceStrings.getString("input_error"),
884				JOptionPane.ERROR_MESSAGE);
885			    return false;
886			}
887		    }
888		} catch (ValidationException e) {
889		    // Not a valid IP address
890		    MessageFormat form = new MessageFormat(
891			ResourceStrings.getString("cfg_wiz_bad_network"));
892		    Object [] args = new Object[1];
893		    args[0] = (String)networkBox.getSelectedItem();
894		    if (args[0] == null) {
895			args[0] = "";
896		    }
897		    JOptionPane.showMessageDialog(ConfigWizard.this,
898			form.format(args),
899			ResourceStrings.getString("input_error"),
900			JOptionPane.ERROR_MESSAGE);
901		    return false;
902		} catch (Throwable e) {
903		    e.printStackTrace();
904		    // Ignore other exceptions
905		}
906	    }
907	    return true;
908	}
909    }
910
911    // Get the type of network and routing policy
912    class NetTypeStep implements WizardStep {
913	private JRadioButton lan, ptp;
914	private ButtonGroup typeGroup, routingGroup;
915	private JRadioButton discover, specify;
916	private IPAddressField address;
917	private Box stepBox;
918	private boolean firstTime = true;
919
920	public NetTypeStep() {
921	    stepBox = Box.createVerticalBox();
922
923	    // Explanatory text at the top
924	    stepBox.add(Wizard.createTextArea(
925		ResourceStrings.getString("cfg_wiz_nettype_explain"), 2, 45));
926	    stepBox.add(Box.createVerticalStrut(10));
927
928	    // Label and radio buttons for type of network
929	    JPanel panel = new JPanel(new GridLayout(2, 1));
930	    /*
931	     * Create a compound border with empty space on the outside and
932	     * a line border on the inside, then title it amd put a space
933	     * around the outside.
934	     */
935	    Border b = BorderFactory.createCompoundBorder(
936		BorderFactory.createEmptyBorder(0, 5, 0, 5),
937		BorderFactory.createLineBorder(Color.black));
938	    Border tb = BorderFactory.createTitledBorder(b,
939		ResourceStrings.getString("cfg_wiz_nettype_label"));
940	    panel.setBorder(BorderFactory.createCompoundBorder(tb,
941		BorderFactory.createEmptyBorder(0, 5, 0, 5)));
942
943            lan = new JRadioButton(ResourceStrings.getString("cfg_wiz_lan"),
944                true);
945            lan.setToolTipText(ResourceStrings.getString("cfg_wiz_lan"));
946            typeGroup = new ButtonGroup();
947            typeGroup.add(lan);
948            panel.add(lan);
949            ptp = new JRadioButton(ResourceStrings.getString("cfg_wiz_point"),
950                false);
951            ptp.setToolTipText(ResourceStrings.getString("cfg_wiz_point"));
952            typeGroup.add(ptp);
953            panel.add(ptp);
954            stepBox.add(panel);
955            stepBox.add(Box.createVerticalStrut(20));
956
957	    // Routing policy
958	    panel = new JPanel(new GridLayout(2, 1));
959	    tb = BorderFactory.createTitledBorder(b,
960		ResourceStrings.getString("cfg_wiz_routing_label"));
961	    panel.setBorder(BorderFactory.createCompoundBorder(tb,
962		BorderFactory.createEmptyBorder(0, 5, 0, 5)));
963
964	    discover = new JRadioButton(
965		ResourceStrings.getString("cfg_wiz_router_discovery"), true);
966	    discover.setToolTipText(ResourceStrings.getString(
967		"cfg_wiz_router_discovery"));
968	    routingGroup = new ButtonGroup();
969	    routingGroup.add(discover);
970	    panel.add(discover);
971
972	    Box routerBox = Box.createHorizontalBox();
973	    specify = new JRadioButton(
974		ResourceStrings.getString("cfg_wiz_router_specify"), false);
975	    specify.setToolTipText(ResourceStrings.getString(
976		"cfg_wiz_router_specify"));
977	    routingGroup.add(specify);
978	    routerBox.add(specify);
979	    routerBox.add(Box.createHorizontalStrut(2));
980	    address = new IPAddressField();
981	    address.setEnabled(false); // Start off disabled
982	    address.setMaximumSize(address.getPreferredSize());
983
984	    // Box is sensitive to alignment, make sure they all agree
985	    address.setAlignmentY(specify.getAlignmentY());
986
987	    routerBox.add(address);
988	    panel.add(routerBox);
989	    stepBox.add(panel);
990
991	    stepBox.add(Box.createVerticalStrut(10));
992	    stepBox.add(Box.createVerticalGlue());
993
994	    /*
995	     * Enable forward if router discovery, or if specifying router and
996	     * address is not empty.
997	     */
998	    specify.addChangeListener(new ChangeListener() {
999		public void stateChanged(ChangeEvent e) {
1000		    address.setEnabled(specify.isSelected());
1001		    setForwardEnabled(!specify.isSelected()
1002			|| (address.getText().length() != 0));
1003		}
1004	    });
1005
1006	    // Enable forward when address is not empty.
1007	    address.getDocument().addDocumentListener(new DocumentListener() {
1008		public void insertUpdate(DocumentEvent e) {
1009		    setForwardEnabled(address.getText().length() != 0);
1010		}
1011		public void changedUpdate(DocumentEvent e) {
1012		    insertUpdate(e);
1013		}
1014		public void removeUpdate(DocumentEvent e) {
1015		    insertUpdate(e);
1016		}
1017	    });
1018	}
1019
1020	public String getDescription() {
1021	    return ResourceStrings.getString("cfg_wiz_nettype_desc");
1022	}
1023
1024	public Component getComponent() {
1025	    return stepBox;
1026	}
1027
1028	public void setActive(int direction) {
1029	    setForwardEnabled(true);
1030	    lan.setSelected(isLan);
1031	    discover.setSelected(routerDiscovery);
1032	    address.setValue(router);
1033	}
1034
1035	public boolean setInactive(int direction) {
1036	    isLan = lan.isSelected();
1037	    if (direction == FORWARD) {
1038		routerDiscovery = discover.isSelected();
1039		if (!routerDiscovery) {
1040		    IPAddress addr = address.getValue();
1041		    if (addr == null) {
1042			// Invalid IP address
1043			MessageFormat form = new MessageFormat(
1044			    ResourceStrings.getString(
1045			    "cfg_wiz_router_addr_err"));
1046			Object [] args = new Object[1];
1047			args[0] = address.getText();
1048			JOptionPane.showMessageDialog(ConfigWizard.this,
1049				form.format(args),
1050				ResourceStrings.getString("input_error"),
1051				JOptionPane.ERROR_MESSAGE);
1052			return false;
1053		    } else if (!network.containsAddress(addr)) {
1054			// Router is not on the network we're configuring
1055			MessageFormat form = new MessageFormat(
1056			    ResourceStrings.getString(
1057			    "cfg_wiz_router_net_err"));
1058			Object [] args = new Object[2];
1059			args[0] = address.getText();
1060			args[1] = network.toString();
1061			JOptionPane.showMessageDialog(ConfigWizard.this,
1062			    form.format(args),
1063			    ResourceStrings.getString("input_error"),
1064			    JOptionPane.ERROR_MESSAGE);
1065			return false;
1066		    }
1067		    router = addr;
1068		}
1069	    }
1070	    return true;
1071	}
1072    }
1073
1074    // Get the NIS configuration
1075    class NisStep implements WizardStep {
1076	private NoSpaceField domain;
1077	private Box stepBox;
1078	private IPAddressField address;
1079	private JButton add, delete, moveUp, moveDown;
1080	private IPAddressList serverList;
1081	boolean firstActive = true;
1082
1083	public NisStep() {
1084	    stepBox = Box.createVerticalBox();
1085
1086	    stepBox.add(Wizard.createTextArea(
1087		ResourceStrings.getString("cfg_wiz_nis_explain"), 6, 45));
1088	    stepBox.add(Box.createVerticalStrut(10));
1089
1090            JPanel fieldPanel = new JPanel(new FieldLayout());
1091	    Mnemonic mnNis =
1092		new Mnemonic(ResourceStrings.getString("cfg_wiz_nis_domain"));
1093            JLabel jlNISDomain =
1094		new JLabel(mnNis.getString());
1095	    fieldPanel.add(FieldLayout.LABEL, jlNISDomain);
1096	    domain = new NoSpaceField();
1097	    jlNISDomain.setLabelFor(domain);
1098	    jlNISDomain.setToolTipText(mnNis.getString());
1099	    jlNISDomain.setDisplayedMnemonic(mnNis.getMnemonic());
1100	    fieldPanel.add(FieldLayout.FIELD, domain);
1101            stepBox.add(fieldPanel);
1102
1103	    serverList = new IPAddressList();
1104	    Border tb = BorderFactory.createTitledBorder(
1105		BorderFactory.createLineBorder(Color.black),
1106		ResourceStrings.getString("cfg_wiz_nis_servers"));
1107	    serverList.setBorder(BorderFactory.createCompoundBorder(tb,
1108		BorderFactory.createEmptyBorder(5, 5, 5, 5)));
1109	    stepBox.add(serverList);
1110	}
1111
1112	public String getDescription() {
1113	    return ResourceStrings.getString("cfg_wiz_nis_desc");
1114	}
1115
1116	public Component getComponent() {
1117	    return stepBox;
1118	}
1119
1120	public void setActive(int direction) {
1121	    setForwardEnabled(true);
1122	    if (firstActive) {
1123		firstActive = false;
1124		try {
1125		    /*
1126		     * Order here is important; do the servers first because if
1127		     * there's an error, we don't retrieve a domain name, which
1128		     * appears to never fail.
1129		     */
1130		    serverList.setAddressList(
1131			server.getIPOption(StandardOptions.CD_NIS_SERV, ""));
1132		    domain.setText(
1133			server.getStringOption(StandardOptions.CD_NIS_DOMAIN,
1134			""));
1135		} catch (Throwable e) {
1136		    // Do nothing, just setting defaults
1137		}
1138	    }
1139	}
1140
1141	public boolean setInactive(int direction) {
1142	    if (direction == FORWARD) {
1143		/*
1144		 * Either must supply both a domain and a list of servers, or
1145		 * neither
1146		 */
1147		if ((domain.getText().length() == 0)
1148			!= (serverList.getListSize() == 0)) {
1149		    JOptionPane.showMessageDialog(ConfigWizard.this,
1150			ResourceStrings.getString("cfg_wiz_nis_both"),
1151			ResourceStrings.getString("input_error"),
1152			JOptionPane.ERROR_MESSAGE);
1153		    return false;
1154		}
1155	    }
1156	    nisDomain = domain.getText();
1157	    nisServs = serverList.getAddressList();
1158	    return true;
1159	}
1160    }
1161
1162    class ReviewStep implements WizardStep {
1163	private JLabel storeLabel;
1164	private JLabel hostLabel;
1165	private JLabel leaseLabel;
1166	private JLabel networkLabel;
1167	private JLabel netTypeLabel;
1168	private JLabel netmaskLabel;
1169	private JLabel routerLabel;
1170	private JLabel dnsLabel;
1171	private JLabel dnsServLabel;
1172	private JLabel nisLabel;
1173	private JLabel nisServLabel;
1174	private JPanel panel;
1175	private JScrollPane scrollPane;
1176
1177	public ReviewStep() {
1178	    Box stepBox = Box.createVerticalBox();
1179	    if (fullConfig) {
1180		stepBox.add(Wizard.createTextArea(
1181		    ResourceStrings.getString("cfg_wiz_review_explain"), 3,
1182		    45));
1183	    } else {
1184		stepBox.add(Wizard.createTextArea(
1185		    ResourceStrings.getString("net_wiz_review_explain"), 3,
1186		    45));
1187	    }
1188
1189	    panel = new JPanel(new FieldLayout());
1190	    JLabel jlTmp;
1191
1192	    if (fullConfig) {
1193		addLabel("cfg_wiz_datastore");
1194		storeLabel = addField("uninitialized");
1195
1196		addLabel("cfg_wiz_hosts_resource");
1197		hostLabel = addField("uninitialized");
1198
1199		jlTmp = addLabelMnemonic("cfg_wiz_lease_length");
1200		leaseLabel = addField("1 day");
1201
1202		jlTmp = addLabelMnemonic("cfg_wiz_dns_domain");
1203		dnsLabel = addField("Bar.Sun.COM");
1204
1205		addLabel("cfg_wiz_dns_servers");
1206		dnsServLabel = addField("109.151.1.15, 109.148.144.2");
1207	    }
1208
1209	    jlTmp = addLabelMnemonic("cfg_wiz_network");
1210	    networkLabel = addField("109.148.21.0");
1211	    jlTmp.setLabelFor(networkLabel);
1212
1213	    jlTmp = addLabelMnemonic("cfg_wiz_mask");
1214	    netmaskLabel = addField("255.255.255.0");
1215	    jlTmp.setLabelFor(netmaskLabel);
1216
1217	    addLabel("cfg_wiz_nettype");
1218	    netTypeLabel = addField(ResourceStrings.getString("cfg_wiz_lan"));
1219
1220	    addLabel("cfg_wiz_router");
1221	    routerLabel = addField(
1222		ResourceStrings.getString("cfg_wiz_router_discovery"));
1223
1224	    jlTmp = addLabelMnemonic("cfg_wiz_nis_domain");
1225	    nisLabel = addField("Foo.Bar.Sun.COM");
1226	    jlTmp.setLabelFor(nisLabel);
1227
1228	    addLabel("cfg_wiz_nis_servers");
1229	    nisServLabel = addField("109.148.21.21, 109.148.21.44");
1230
1231	    stepBox.add(panel);
1232	    stepBox.add(Box.createVerticalGlue());
1233
1234	    scrollPane = new JScrollPane(stepBox,
1235		JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED,
1236		JScrollPane.HORIZONTAL_SCROLLBAR_NEVER);
1237	}
1238
1239	private void addLabel(String s) {
1240	    JLabel jl;
1241	    jl = new JLabel(ResourceStrings.getString(s));
1242	    panel.add(FieldLayout.LABEL, jl);
1243	    jl.setLabelFor(panel);
1244	    jl.setToolTipText(ResourceStrings.getString(s));
1245	}
1246
1247	private JLabel addLabelMnemonic(String s) {
1248	    JLabel jl;
1249	    Mnemonic mnStr =
1250                new Mnemonic(ResourceStrings.getString(s));
1251	    jl = new JLabel(mnStr.getString());
1252	    panel.add(FieldLayout.LABEL, jl);
1253            jl.setToolTipText(mnStr.getString());
1254	    return jl;
1255        }
1256
1257	private JLabel addField(String s) {
1258	    JLabel l = new JLabel(s);
1259	    l.setForeground(Color.black);
1260	    panel.add(FieldLayout.FIELD, l);
1261	    l.setLabelFor(panel);
1262	    l.setToolTipText(s);
1263	    return l;
1264	}
1265
1266	public String getDescription() {
1267	    return ResourceStrings.getString("cfg_wiz_review_desc");
1268	}
1269
1270	public Component getComponent() {
1271	    return scrollPane;
1272	}
1273
1274	public void setActive(int direction) {
1275	    StringBuffer b = new StringBuffer();
1276	    setFinishEnabled(true);
1277	    if (fullConfig) {
1278		storeLabel.setText(getDsconf().getModule().getDescription());
1279		hostLabel.setText(getHostResource().getDescription());
1280
1281		// Display lease length, reducing to largest units possible
1282		int lengthVal = 0;
1283		int i;
1284		for (i = unitMultiples.length - 1; i >= 0; --i) {
1285		    lengthVal = leaseLength / unitMultiples[i];
1286		    if ((lengthVal != 0)
1287			    && (leaseLength % unitMultiples[i] == 0)) {
1288			break;
1289		    }
1290		}
1291		if (i == -1) {
1292		    i = 0;
1293		}
1294		Object [] objs = new Object[3];
1295		objs[0] = new Integer(lengthVal);
1296		objs[1] = unitChoices[i];
1297		if (leaseNegotiable) {
1298		    objs[2] = ResourceStrings.getString("cfg_wiz_renewable");
1299		} else {
1300		    objs[2] = ResourceStrings.getString("cfg_wiz_nonrenewable");
1301		}
1302		leaseLabel.setText(MessageFormat.format(
1303		    ResourceStrings.getString("cfg_wiz_lease_fmt"), objs));
1304
1305		// Set DNS info
1306		dnsLabel.setText(dnsDomain);
1307		b.setLength(0);
1308		Enumeration en = dnsServs.elements();
1309		while (en.hasMoreElements()) {
1310		    IPAddress a = (IPAddress)en.nextElement();
1311		    if (b.length() != 0) {
1312			b.append(", ");
1313		    }
1314		    b.append(a.getHostAddress());
1315		}
1316		dnsServLabel.setText(b.toString());
1317	    }
1318
1319	    // Set network address
1320	    networkLabel.setText(network.toString());
1321	    // Set subnet mask
1322	    netmaskLabel.setText(network.getMask().getHostAddress());
1323
1324	    // Set network type
1325	    if (isLan) {
1326		netTypeLabel.setText(ResourceStrings.getString("cfg_wiz_lan"));
1327	    } else {
1328		netTypeLabel.setText(
1329		    ResourceStrings.getString("cfg_wiz_point"));
1330	    }
1331
1332	    // Set router
1333	    if (routerDiscovery) {
1334		routerLabel.setText(
1335		    ResourceStrings.getString("cfg_wiz_router_discovery"));
1336	    } else {
1337		routerLabel.setText(router.getHostAddress());
1338	    }
1339
1340	    // Set NIS info
1341	    nisLabel.setText(nisDomain);
1342	    b.setLength(0);
1343	    Enumeration en = nisServs.elements();
1344	    while (en.hasMoreElements()) {
1345		IPAddress a = (IPAddress)en.nextElement();
1346		if (b.length() != 0) {
1347		    b.append(", ");
1348		}
1349		b.append(a.getHostAddress());
1350	    }
1351	    nisServLabel.setText(b.toString());
1352	}
1353
1354	public boolean setInactive(int direction) {
1355	    return true;
1356	}
1357    }
1358
1359    public ConfigWizard(Frame owner, String title, boolean fullConfig) {
1360	super(owner, title);
1361
1362	try {
1363	    server = DataManager.get().getDhcpServiceMgr();
1364	    if (fullConfig) {
1365		dsconfList = new DSConfList();
1366		dsconfList.init(server);
1367	    }
1368	} catch (Throwable e) {
1369	    e.printStackTrace(); // XXX Need to do something to handle this...
1370	    return;
1371	}
1372
1373	this.fullConfig = fullConfig;
1374
1375	// If running as Config Wizard, put in the initial steps.
1376	if (fullConfig) {
1377	    addStep(new DatastoreStep(
1378		ResourceStrings.getString("cfg_wiz_explain"),
1379		ResourceStrings.getString("cfg_wiz_store_explain")));
1380	    addStep(new DatastoreModuleStep());
1381	    addStep(new HostDataStep());
1382	    addStep(new LeaseStep());
1383	    addStep(new DnsStep());
1384	}
1385	// Now the steps that are common to both wizards.
1386	addStep(new NetworkStep());
1387	addStep(new NetTypeStep());
1388	addStep(new NisStep());
1389	addStep(new ReviewStep());
1390	showFirstStep();
1391    }
1392
1393    public void doFinish() {
1394	/*
1395	 * To activate the server, we have to do the following items:
1396	 * 1. Create the location/path if necessary.
1397	 * 2. Create the defaults file.
1398	 * 3. Create the dhcptab; ignore errors if it already exists
1399	 *    (as in NIS+ case)
1400	 * 4. Create the Locale macro; ignore the error if it already exists
1401	 * 5. Create the server macro; if it exists we just overwrite it
1402	 * 6. Create the network macro;
1403	 * 7. Create the network table
1404	 * 8. Start the service
1405	 */
1406	if (fullConfig) {
1407	    getDsconf().setConfig();
1408	    getDsconf().setLocation();
1409	    // Create the location/path.
1410	    try {
1411		server.makeLocation(getDsconf().getDS());
1412	    } catch (ExistsException e) {
1413		// this is o.k.
1414	    } catch (Throwable e) {
1415		MessageFormat form = new MessageFormat(
1416		    ResourceStrings.getString("create_location_error"));
1417		Object [] args = new Object[1];
1418		args[0] = getDsconf().getDS().getLocation();
1419		String msg = form.format(args);
1420		JOptionPane.showMessageDialog(ConfigWizard.this,
1421		    msg,
1422		    ResourceStrings.getString("server_error_title"),
1423		    JOptionPane.ERROR_MESSAGE);
1424		return;
1425	    }
1426
1427	    // Create the defaults file.
1428	    DhcpdOptions options = new DhcpdOptions();
1429	    options.setDaemonEnabled(true);
1430	    options.setDhcpDatastore(getDsconf().getDS());
1431	    if (getHostResource().getResource() != null) {
1432		options.setHostsResource(getHostResource().getResource());
1433	    }
1434	    if (getHostResource().getDomain() != null) {
1435		options.setHostsDomain(getHostResource().getDomain());
1436	    }
1437	    try {
1438		server.writeDefaults(options);
1439	    } catch (Throwable e) {
1440		e.printStackTrace();
1441		return;
1442	    }
1443
1444	    // Create the dhcptab
1445	    try {
1446		DataManager.get().getDhcptabMgr().createDhcptab();
1447	    } catch (Throwable e) {
1448		// Not an error; some data stores are shared by multiple servers
1449	    }
1450	}
1451
1452	if (fullConfig) {
1453	    try {
1454		DataManager.get().getDhcptabMgr().createLocaleMacro();
1455	    } catch (Throwable e) {
1456		/*
1457		 * Ignore this error, if one's already there we'll assume
1458		 * it's correct
1459		 */
1460	    }
1461
1462	    // Create the Server macro
1463	    try {
1464		String svrName =
1465		    DataManager.get().getDhcpServiceMgr().getShortServerName();
1466		InetAddress svrAddress =
1467		    DataManager.get().getDhcpServiceMgr().getServerAddress();
1468		DataManager.get().getDhcptabMgr().createServerMacro(svrName,
1469		    svrAddress, leaseLength, leaseNegotiable, dnsDomain,
1470		    dnsServs);
1471	    } catch (Throwable e) {
1472		// Couldn't create it; inform user because this is serious
1473		Object [] args = new Object[2];
1474		MessageFormat form = new MessageFormat(
1475		    ResourceStrings.getString("create_macro_error"));
1476		args[0] = DataManager.get().getShortServerName();
1477		args[1] = e.getMessage();
1478		JOptionPane.showMessageDialog(this, form.format(args),
1479		    ResourceStrings.getString("server_error_title"),
1480		    JOptionPane.ERROR_MESSAGE);
1481		return;
1482	    }
1483	}
1484
1485	// Create the network macro
1486	IPAddress [] routers = null;
1487	if (router != null) {
1488	    routers = new IPAddress[] { router };
1489	}
1490	try {
1491	    DataManager.get().getDhcptabMgr().createNetworkMacro(network,
1492		routers, isLan, nisDomain, nisServs);
1493	} catch (Throwable e) {
1494	    // Ignore this error? dhcpconfig gives a merge option
1495	}
1496
1497	// Create the network table
1498	try {
1499	    DataManager.get().getDhcpNetMgr().createNetwork(network.toString());
1500	} catch (BridgeException e) {
1501	    // This indicates table existed; no error
1502	} catch (Throwable e) {
1503	    Object [] args = new Object[2];
1504	    MessageFormat form = new MessageFormat(
1505		ResourceStrings.getString("create_network_table_error"));
1506	    args[0] = network.toString();
1507	    args[1] = e.getMessage();
1508	    JOptionPane.showMessageDialog(this, form.format(args),
1509		ResourceStrings.getString("server_error_title"),
1510		JOptionPane.ERROR_MESSAGE);
1511	    return;
1512	}
1513
1514	// Start the server in the initial configuration case
1515	if (fullConfig) {
1516	    try {
1517		DataManager.get().getDhcpServiceMgr().startup();
1518	    } catch (Throwable e) {
1519		// Just warn user; this isn't disastrous
1520		Object [] args = new Object[1];
1521		MessageFormat form = new MessageFormat(
1522		    ResourceStrings.getString("startup_server_error"));
1523		args[0] = e.getMessage();
1524		JOptionPane.showMessageDialog(this, form.format(args),
1525		    ResourceStrings.getString("server_error_title"),
1526		    JOptionPane.WARNING_MESSAGE);
1527	    }
1528	}
1529
1530	super.doFinish();
1531    }
1532
1533    public void doHelp() {
1534	if (fullConfig) {
1535	    DhcpmgrApplet.showHelp("config_wizard");
1536	} else {
1537	    DhcpmgrApplet.showHelp("network_wizard");
1538	}
1539    }
1540
1541    /**
1542     * Sets hostResource.
1543     * @param hostResource the host resource value.
1544     */
1545    public void setHostResource(HostResource hostResource) {
1546	this.hostResource = hostResource;
1547    } // setHostResource
1548
1549    /**
1550     * Returns the hostResource.
1551     * @return the hostResource.
1552     */
1553    public HostResource getHostResource() {
1554	return hostResource;
1555    } // getHostResource
1556
1557}
1558