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, Version 1.0 only
6 * (the "License"). You may not use this file except in compliance
7 * with the License.
8 *
9 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
10 * or http://www.opensolaris.org/os/licensing.
11 * See the License for the specific language governing permissions
12 * and limitations under the License.
13 *
14 * When distributing Covered Code, include this CDDL HEADER in each
15 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
16 * If applicable, add the following below this CDDL HEADER, with the
17 * fields enclosed by brackets "[]" replaced with your own identifying
18 * information: Portions Copyright [yyyy] [name of copyright owner]
19 *
20 * CDDL HEADER END
21 */
22 /*
23 * Copyright 1998-2002 Sun Microsystems, Inc. All rights reserved.
24 * Use is subject to license terms.
25 */
26 package com.sun.dhcpmgr.client;
27
28 import javax.swing.*;
29 import javax.swing.border.*;
30 import javax.swing.event.*;
31
32 import java.awt.*;
33 import java.awt.event.*;
34 import java.text.*;
35 import java.util.*;
36 import java.net.*;
37
38 import com.sun.dhcpmgr.server.*;
39 import com.sun.dhcpmgr.data.*;
40 import com.sun.dhcpmgr.ui.*;
41 import com.sun.dhcpmgr.bridge.ExistsException;
42 import com.sun.dhcpmgr.bridge.NoEntryException;
43 import com.sun.dhcpmgr.bridge.HostExistsException;
44 import com.sun.dhcpmgr.bridge.NoHostsEntryException;
45 import com.sun.dhcpmgr.bridge.NoTableException;
46 import com.sun.dhcpmgr.bridge.BridgeException;
47
48 /**
49 * This dialog is used to create/duplicate/modify a DHCP address record.
50 */
51 public class CreateAddressDialog extends JDialog
52 implements ButtonPanelListener {
53
54 // Model class for the drop-down list of macros user may select from
55 class MacroListModel extends AbstractListModel implements ComboBoxModel {
56 private Object currentValue;
57 private Macro [] data = null;
58 private String noMacro;
59
60 public MacroListModel() {
61 try {
62 noMacro = ResourceStrings.getString("no_macro_item");
63 DhcptabMgr server = DataManager.get().getDhcptabMgr();
64 data = server.getMacros();
65 } catch (NoTableException e) {
66 // can function without table
67 } catch (Throwable e) {
68 e.printStackTrace();
69 }
70 }
71
72 public int getSize() {
73 if (data == null)
74 return 1;
75 else
76 return data.length+1;
77 }
78
79 public Object getElementAt(int index) {
80 if (index == 0) {
81 return noMacro;
82 } else {
83 return data[index-1].getKey();
84 }
85 }
86
87 public void setSelectedItem(Object anItem) {
88 currentValue = anItem;
89 fireContentsChanged(this, -1, -1);
90 }
91
92 public Object getSelectedItem() {
93 return currentValue;
94 }
95 }
96
97 public static final int CREATE = 0;
98 public static final int EDIT = 1;
99 public static final int DUPLICATE = 2;
100
101 private int mode = EDIT;
102 private Network network;
103 private IPAddressField address;
104 private JTextField server;
105 private JComboBox macro;
106 private JTextField clientId;
107 private JTextField comment;
108 private JTextField expirationDate;
109 private JCheckBox unusable;
110 private JCheckBox bootp;
111 private JCheckBox manual;
112 private JRadioButton temporary;
113 private JRadioButton permanent;
114 private ButtonGroup buttonGroup;
115 private ButtonPanel buttonPanel;
116 private DhcpClientRecord client, originalClient;
117 private Vector listeners;
118 private DateFormat dateFormat =
119 DateFormat.getDateTimeInstance(DateFormat.SHORT, DateFormat.SHORT);
120
121 public CreateAddressDialog(Frame f, int mode, DhcpClientRecord rec,
122 Network net) {
123 super(f);
124 setLocationRelativeTo(f);
125
126 listeners = new Vector();
127 this.mode = mode;
128 network = net;
129 switch (mode) {
130 case CREATE:
131 setTitle(ResourceStrings.getString("create_address_title"));
132 break;
133 case EDIT:
134 setTitle(ResourceStrings.getString("edit_address_title"));
135 break;
136 case DUPLICATE:
137 setTitle(ResourceStrings.getString("duplicate_address_title"));
138 break;
139 default:
140 break;
141 }
142
143 getContentPane().setLayout(new BorderLayout());
144
145 JTabbedPane tabbedPane = new JTabbedPane();
146
147 GridBagLayout bag = new GridBagLayout();
148 JPanel mainPanel = new JPanel(bag);
149 GridBagConstraints c = new GridBagConstraints();
150 c.gridx = c.gridy = 0;
151 c.gridwidth = c.gridheight = 1;
152 c.fill = GridBagConstraints.HORIZONTAL;
153 c.insets = new Insets(5, 5, 5, 5);
154 c.weightx = c.weighty = 1.0;
155
156 // Label and text field for address
157 Mnemonic mnIP =
158 new Mnemonic(ResourceStrings.getString("ip_address_label"));
159 JLabel l = new JLabel(mnIP.getString(), SwingConstants.RIGHT);
160 bag.setConstraints(l, c);
161 mainPanel.add(l);
162 address = new IPAddressField();
163 l.setLabelFor(address);
164 l.setToolTipText(mnIP.getString());
165 l.setDisplayedMnemonic(mnIP.getMnemonic());
166
167 if (mode == EDIT) {
168 address.setEditable(false);
169 }
170 ++c.gridx;
171 bag.setConstraints(address, c);
172 mainPanel.add(address);
173
174 // label and field for owning server
175 Mnemonic mnOwn =
176 new Mnemonic(ResourceStrings.getString("owning_server_label"));
177 l = new JLabel(mnOwn.getString(), SwingConstants.RIGHT);
178 ++c.gridy;
179 c.gridx = 0;
180 bag.setConstraints(l, c);
181 mainPanel.add(l);
182 server = new JTextField(20);
183
184 l.setLabelFor(server);
185 l.setToolTipText(mnOwn.getString());
186 l.setDisplayedMnemonic(mnOwn.getMnemonic());
187
188 ++c.gridx;
189 bag.setConstraints(server, c);
190 mainPanel.add(server);
191
192 // label and combo box for macro
193 Mnemonic mnMacro =
194 new Mnemonic(ResourceStrings.getString("config_macro_label"));
195 l = new JLabel(mnMacro.getString(), SwingConstants.RIGHT);
196 ++c.gridy;
197 c.gridx = 0;
198 bag.setConstraints(l, c);
199 mainPanel.add(l);
200 MacroListModel macroListModel = new MacroListModel();
201 macro = new JComboBox(macroListModel);
202
203 l.setLabelFor(macro);
204 l.setToolTipText(mnMacro.getString());
205 l.setDisplayedMnemonic(mnMacro.getMnemonic());
206
207 macro.setEditable(false);
208 ++c.gridx;
209 bag.setConstraints(macro, c);
210 mainPanel.add(macro);
211
212 // Comment
213 Mnemonic mnComm =
214 new Mnemonic(ResourceStrings.getString("comment_label"));
215 l = new JLabel(mnComm.getString(), SwingConstants.RIGHT);
216 ++c.gridy;
217 c.gridx = 0;
218 bag.setConstraints(l, c);
219 mainPanel.add(l);
220 comment = new JTextField(20);
221
222 l.setLabelFor(comment);
223 l.setToolTipText(mnComm.getString());
224 l.setDisplayedMnemonic(mnComm.getMnemonic());
225
226 ++c.gridx;
227 bag.setConstraints(comment, c);
228 mainPanel.add(comment);
229
230 // Create first panel of tabs
231 tabbedPane.addTab(ResourceStrings.getString("address_tab_label"),
232 mainPanel);
233
234 mainPanel = new JPanel(new BorderLayout(5, 5));
235
236 // Client ID
237 Mnemonic mnID =
238 new Mnemonic(ResourceStrings.getString("client_id_label"));
239 JPanel idPanel = new JPanel();
240 l = new JLabel(mnID.getString());
241 idPanel.add(l);
242 clientId = new JTextField(20);
243
244 l.setLabelFor(clientId);
245 l.setToolTipText(mnID.getString());
246 l.setDisplayedMnemonic(mnID.getMnemonic());
247 idPanel.add(clientId);
248
249 manual = new JCheckBox(ResourceStrings.getString("manual_checkbox"));
250 idPanel.add(manual);
251 manual.setToolTipText(
252 ResourceStrings.getString("manual_checkbox"));
253
254 mainPanel.add(idPanel, BorderLayout.NORTH);
255
256 // radio buttons for lease state
257 bag = new GridBagLayout();
258 JPanel leasePanel = new JPanel(bag);
259 /*
260 * Create a compound border with empty space on the outside and line
261 * border on the inside, then title it.
262 */
263 Border b = BorderFactory.createCompoundBorder(
264 BorderFactory.createEmptyBorder(0, 5, 0, 5),
265 BorderFactory.createLineBorder(Color.black));
266 leasePanel.setBorder(BorderFactory.createTitledBorder(b,
267 ResourceStrings.getString("lease_policy_label")));
268
269 // Reset constraints
270 c.gridx = c.gridy = 0;
271 c.gridwidth = 1;
272
273 buttonGroup = new ButtonGroup();
274 temporary = new JRadioButton();
275 buttonGroup.add(temporary);
276 c.weightx = 0.0;
277 bag.setConstraints(temporary, c);
278 leasePanel.add(temporary);
279
280 Mnemonic mnDyn =
281 new Mnemonic(ResourceStrings.getString("leased_label"));
282 l = new JLabel(mnDyn.getString());
283 ++c.gridx;
284 c.weightx = 1.0;
285 bag.setConstraints(l, c);
286 leasePanel.add(l);
287
288 expirationDate = new JTextField(30);
289
290 l.setLabelFor(expirationDate);
291 l.setToolTipText(mnDyn.getString());
292 l.setDisplayedMnemonic(mnDyn.getMnemonic());
293
294 ++c.gridy;
295 bag.setConstraints(expirationDate, c);
296 leasePanel.add(expirationDate);
297
298 permanent = new JRadioButton();
299 buttonGroup.add(permanent);
300 ++c.gridy;
301 c.gridx = 0;
302 c.weightx = 0.0;
303 bag.setConstraints(permanent, c);
304 leasePanel.add(permanent);
305
306 Mnemonic mnPerm =
307 new Mnemonic(ResourceStrings.getString("permanent_label"));
308 l = new JLabel(mnPerm.getString());
309 l.setLabelFor(leasePanel);
310 l.setToolTipText(mnPerm.getString());
311 l.setDisplayedMnemonic(mnPerm.getMnemonic());
312
313 ++c.gridx;
314 c.weightx = 1.0;
315 bag.setConstraints(l, c);
316 leasePanel.add(l);
317
318 mainPanel.add(leasePanel, BorderLayout.CENTER);
319
320 // Flag checkboxes
321 JPanel southPanel = new JPanel(new BorderLayout(5, 5));
322 southPanel.setBorder(BorderFactory.createEmptyBorder(0, 5, 0, 5));
323 bootp = new JCheckBox(ResourceStrings.getString("bootp_checkbox"));
324
325 bootp.setToolTipText(
326 ResourceStrings.getString("bootp_checkbox"));
327
328 bootp.setHorizontalAlignment(SwingConstants.LEFT);
329 southPanel.add(bootp, BorderLayout.CENTER);
330
331 unusable = new JCheckBox(
332 ResourceStrings.getString("unusable_checkbox"));
333
334 unusable.setToolTipText(
335 ResourceStrings.getString("unusable_checkbox"));
336
337 unusable.setHorizontalAlignment(SwingConstants.LEFT);
338 southPanel.add(unusable, BorderLayout.SOUTH);
339
340 mainPanel.add(southPanel, BorderLayout.SOUTH);
341
342 tabbedPane.addTab(ResourceStrings.getString("lease_tab_label"),
343 mainPanel);
344 JPanel borderPanel = new JPanel(new BorderLayout());
345 borderPanel.setBorder(BorderFactory.createEmptyBorder(5, 5, 5, 5));
346 borderPanel.add(tabbedPane, BorderLayout.CENTER);
347
348 getContentPane().add(borderPanel, BorderLayout.CENTER);
349
350 buttonPanel = new ButtonPanel(true);
351 buttonPanel.addButtonPanelListener(this);
352 getContentPane().add(buttonPanel, BorderLayout.SOUTH);
353
354 setClient(rec);
355
356 DocumentListener docListener = new DocumentListener() {
357 public void insertUpdate(DocumentEvent e) {
358 buttonPanel.setOkEnabled(address.getDocument().getLength() != 0
359 && server.getDocument().getLength() != 0);
360 }
361 public void changedUpdate(DocumentEvent e) {
362 insertUpdate(e);
363 }
364 public void removeUpdate(DocumentEvent e) {
365 insertUpdate(e);
366 }
367 };
368
369 address.getDocument().addDocumentListener(docListener);
370 server.getDocument().addDocumentListener(docListener);
371
372 if (mode == EDIT) {
373 buttonPanel.setOkEnabled(true);
374 }
375 }
376
377 public void setClient(DhcpClientRecord c) {
378 originalClient = (DhcpClientRecord)c.clone();
379 client = c;
380 resetValues();
381 }
382
383 private void resetValues() {
384 if (mode == DUPLICATE) {
385 address.setText("");
386 } else {
387 address.setText(client.getClientIPAddress());
388 }
389 if (mode == CREATE && (client.getServerName() == null ||
390 client.getServerName().length() == 0)) {
391 server.setText(DataManager.get().getShortServerName());
392 } else {
393 server.setText(client.getServerName());
394 }
395 if (mode == CREATE) {
396 macro.setSelectedItem(DataManager.get().getShortServerName());
397 } else {
398 macro.setSelectedItem(client.getMacro());
399 }
400 comment.setText(client.getComment());
401 clientId.setText(client.getClientId());
402 manual.setSelected(client.isManual());
403 if (client.isPermanent()) {
404 permanent.setSelected(true);
405 } else {
406 temporary.setSelected(true);
407 }
408 bootp.setSelected(client.isBootp());
409 unusable.setSelected(client.isUnusable());
410 Date d = client.getExpiration();
411 if (d == null || d.getTime() == 0) {
412 expirationDate.setText("");
413 } else {
414 expirationDate.setText(dateFormat.format(d));
415 }
416 }
417
418 public void buttonPressed(int buttonId) {
419 switch (buttonId) {
420 case OK:
421 IPAddress addr = address.getValue();
422 if (addr == null) {
423 // Bad IP address
424 MessageFormat form = new MessageFormat(
425 ResourceStrings.getString("invalid_address"));
426 Object [] args = new Object[] { address.getText() };
427 JOptionPane.showMessageDialog(this, form.format(args),
428 ResourceStrings.getString("input_error"),
429 JOptionPane.ERROR_MESSAGE);
430 return;
431 }
432 if (!network.containsAddress(addr)) {
433 // Address is not on the network we're editing
434 MessageFormat form = new MessageFormat(
435 ResourceStrings.getString("bad_network_address"));
436 Object [] args = new Object[] {
437 addr.getHostAddress(),
438 network.getAddress()
439 };
440 JOptionPane.showMessageDialog(this, form.format(args),
441 ResourceStrings.getString("input_error"),
442 JOptionPane.ERROR_MESSAGE);
443 return;
444 }
445 try {
446 client.setClientIP(address.getValue());
447 } catch (ValidationException e) {
448 // This shouldn't happen, should have caught any problem already
449 }
450
451 try {
452 if (!server.getText().equals(client.getServerName())) {
453 // Don't bother resetting if it hasn't changed
454 client.setServerIP(new IPAddress(server.getText()));
455 }
456 } catch (ValidationException e) {
457 // Bad server name
458 MessageFormat form = new MessageFormat(
459 ResourceStrings.getString("invalid_server"));
460 Object [] args = new Object[] { server.getText() };
461 JOptionPane.showMessageDialog(this, form.format(args),
462 ResourceStrings.getString("input_error"),
463 JOptionPane.ERROR_MESSAGE);
464 return;
465 }
466 int i = macro.getSelectedIndex();
467 if (i == 0) {
468 client.setMacro("");
469 } else {
470 client.setMacro((String)macro.getItemAt(i));
471 }
472 client.setComment(comment.getText());
473 try {
474 client.setClientId(clientId.getText());
475 } catch (ValidationException e) {
476 // Bad client ID
477 MessageFormat form = new MessageFormat(
478 ResourceStrings.getString("invalid_client_id"));
479 Object [] args = new Object[] { clientId.getText() };
480 JOptionPane.showMessageDialog(this, form.format(args),
481 ResourceStrings.getString("input_error"),
482 JOptionPane.ERROR_MESSAGE);
483 return;
484 }
485 client.setManual(manual.isSelected());
486 client.setPermanent(permanent.isSelected());
487 client.setBootp(bootp.isSelected());
488 client.setUnusable(unusable.isSelected());
489 try {
490 if (expirationDate.getText().length() == 0) {
491 client.setExpiration(new Date(0));
492 } else {
493 Date d = dateFormat.parse(expirationDate.getText());
494 client.setExpiration(d);
495 }
496 } catch (ParseException e) {
497 // Bad date/time entered
498 MessageFormat form = new MessageFormat(
499 ResourceStrings.getString("invalid_date"));
500 Object [] args = new Object[] {
501 expirationDate.getText(),
502 dateFormat.format(new Date())
503 };
504 JOptionPane.showMessageDialog(this, form.format(args),
505 ResourceStrings.getString("input_error"),
506 JOptionPane.ERROR_MESSAGE);
507 return;
508 }
509 // Got all the data, now update the data store
510 try {
511 DhcpNetMgr server = DataManager.get().getDhcpNetMgr();
512 if (mode == EDIT) {
513 server.modifyClient(originalClient, client,
514 network.toString());
515 } else {
516 server.addClient(client, network.toString());
517 }
518 fireActionPerformed();
519 setVisible(false);
520 dispose();
521 } catch (Exception e) {
522 /*
523 * Display an error message dialog. However, if the error
524 * related to editing the hosts table, we merely consider it
525 * a warning as the network table stuff actually was done.
526 */
527 String msg = e.getMessage();
528 int msgType = JOptionPane.ERROR_MESSAGE;
529 if (e instanceof ExistsException) {
530 msg = ResourceStrings.getString("address_exists");
531 } else if (e instanceof NoEntryException) {
532 msg = ResourceStrings.getString("address_missing");
533 } else if (e instanceof HostExistsException) {
534 msg = ResourceStrings.getString("host_exists");
535 msgType = JOptionPane.ERROR_MESSAGE;
536 } else if (e instanceof NoHostsEntryException) {
537 msg = ResourceStrings.getString("host_missing");
538 msgType = JOptionPane.WARNING_MESSAGE;
539 }
540 JOptionPane.showMessageDialog(this, msg,
541 ResourceStrings.getString("server_error_title"), msgType);
542 if (msgType == JOptionPane.WARNING_MESSAGE) {
543 fireActionPerformed();
544 setVisible(false);
545 dispose();
546 }
547 }
548 break;
549 case CANCEL:
550 setVisible(false);
551 dispose();
552 break;
553 case HELP:
554 String helpTag = null;
555 switch (mode) {
556 case CREATE:
557 helpTag = "create_address";
558 break;
559 case DUPLICATE:
560 helpTag = "duplicate_address";
561 break;
562 case EDIT:
563 helpTag = "modify_address";
564 break;
565 }
566 DhcpmgrApplet.showHelp(helpTag);
567 break;
568 case RESET:
569 setClient(originalClient);
570 break;
571 }
572 }
573
574 public void addActionListener(ActionListener l) {
575 listeners.addElement(l);
576 }
577
578 public void removeActionListener(ActionListener l) {
579 listeners.removeElement(l);
580 }
581
582 protected void fireActionPerformed() {
583 String command = null;
584 switch (mode) {
585 case CREATE:
586 command = DialogActions.CREATE;
587 break;
588 case DUPLICATE:
589 command = DialogActions.DUPLICATE;
590 break;
591 case EDIT:
592 command = DialogActions.EDIT;
593 break;
594 }
595 ActionEvent e = new ActionEvent(this, ActionEvent.ACTION_PERFORMED,
596 command);
597 Enumeration en = listeners.elements();
598 while (en.hasMoreElements()) {
599 ActionListener l = (ActionListener)en.nextElement();
600 l.actionPerformed(e);
601 }
602 }
603 }