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 }