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 }