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 2001-2002 by Sun Microsystems, Inc. All rights reserved. 24 * Use is subject to license terms. 25 */ 26 package com.sun.dhcpmgr.client; 27 28 import java.awt.*; 29 import java.awt.event.*; 30 import java.util.*; 31 import java.text.MessageFormat; 32 import java.net.*; 33 34 import javax.swing.*; 35 import javax.swing.table.*; 36 import javax.swing.event.*; 37 import javax.swing.border.*; 38 39 import com.sun.dhcpmgr.ui.*; 40 import com.sun.dhcpmgr.data.*; 41 import com.sun.dhcpmgr.server.*; 42 import com.sun.dhcpmgr.bridge.BridgeException; 43 import com.sun.dhcpmgr.bridge.ExistsException; 44 45 /** 46 * This wizard converts the DHCP service data store. 47 */ 48 public class ConvertWizard extends DSWizard { 49 50 /** 51 * Handle to the service server. 52 */ 53 private DhcpServiceMgr svcServer; 54 55 /** 56 * Handle to the dhcptab table server. 57 */ 58 private DhcptabMgr dhcptabServer; 59 60 /** 61 * Handle to the network tables server. 62 */ 63 private DhcpNetMgr netServer; 64 65 /** 66 * The DHCP defaults. 67 */ 68 private DhcpdOptions dhcpdOptions; 69 70 /** 71 * The old data store config. 72 */ 73 private DSConf defaultDsconf; 74 75 /** 76 * The save tables wizard step 77 */ 78 private SaveTablesStep saveTablesStep; 79 80 /** 81 * List of networks to be converted. 82 */ 83 private Network[] networks = null; 84 85 /** 86 * This class is the wizard step that presents the user with 87 * the option to save the tables after conversion. 88 */ 89 protected class SaveTablesStep implements WizardStep { 90 91 /** 92 * The component provided to the wizard. 93 */ 94 private Box stepBox; 95 96 /** 97 * The checkbox that determines whether the DHCP tables should be 98 * saved after conversion. 99 */ 100 private JCheckBox saveTables; 101 102 /** 103 * Basic constructor. 104 */ 105 public SaveTablesStep() { 106 107 stepBox = Box.createVerticalBox(); 108 109 // Explanatory text at the top 110 // 111 stepBox.add(Wizard.createTextArea( 112 ResourceStrings.getString("cvt_wiz_save_explain"), 4, 45)); 113 stepBox.add(Box.createVerticalStrut(10)); 114 stepBox.add(Box.createVerticalGlue()); 115 116 // Add the checkbox. 117 // 118 saveTables = new JCheckBox( 119 ResourceStrings.getString("cvt_wiz_save_label"), false); 120 saveTables.setToolTipText( 121 ResourceStrings.getString("cvt_wiz_save_label")); 122 saveTables.setAlignmentX(Component.LEFT_ALIGNMENT); 123 stepBox.add(saveTables); 124 stepBox.add(Box.createVerticalGlue()); 125 126 stepBox.add(Wizard.createTextArea( 127 ResourceStrings.getString("cvt_wiz_save_note"), 4, 45)); 128 stepBox.add(Box.createVerticalStrut(10)); 129 stepBox.add(Box.createVerticalGlue()); 130 131 } // constructor 132 133 public String getDescription() { 134 return ResourceStrings.getString("cvt_wiz_save_tables_desc"); 135 } // getDescription 136 137 public Component getComponent() { 138 return stepBox; 139 } // getComponent 140 141 public void setActive(int direction) { 142 setForwardEnabled(true); 143 } // setActive 144 145 public boolean setInactive(int direction) { 146 return true; 147 } // setInactive 148 149 public boolean isSaveTablesSelected() { 150 return saveTables.isSelected(); 151 } 152 153 } // SaveTablesStep 154 155 /** 156 * This class provides the review step for the conversion wizard. 157 */ 158 class ReviewStep implements WizardStep { 159 160 /** 161 * The label for the old data store. 162 */ 163 private JLabel oldStoreLabel; 164 165 /** 166 * The label for the new data store. 167 */ 168 private JLabel newStoreLabel; 169 170 /** 171 * The label for saving tables. 172 */ 173 private JLabel saveLabel; 174 175 /** 176 * The component to provide to the conversion wizard. 177 */ 178 private Box stepBox; 179 180 /** 181 * The panel used to create the review information. 182 */ 183 private JPanel panel; 184 185 /** 186 * The constructor for the step. 187 */ 188 public ReviewStep() { 189 190 stepBox = Box.createVerticalBox(); 191 stepBox.add(Wizard.createTextArea( 192 ResourceStrings.getString("cvt_wiz_review_explain"), 193 3, 45)); 194 195 panel = new JPanel(new FieldLayout()); 196 197 addLabel("cvt_wiz_old_datastore").setToolTipText( 198 ResourceStrings.getString("cvt_wiz_old_datastore")); 199 oldStoreLabel = addField("uninitialized"); 200 201 addLabel("cvt_wiz_new_datastore").setToolTipText( 202 ResourceStrings.getString("cvt_wiz_new_datastore")); 203 newStoreLabel = addField("uninitialized"); 204 205 addLabel("cvt_wiz_save_tables").setToolTipText( 206 ResourceStrings.getString("cvt_wiz_save_tables")); 207 saveLabel = addField("uninitialized"); 208 209 stepBox.add(panel); 210 stepBox.add(Box.createVerticalGlue()); 211 212 stepBox.add(Wizard.createTextArea( 213 ResourceStrings.getString("cvt_wiz_review_note"), 4, 45)); 214 stepBox.add(Box.createVerticalStrut(10)); 215 stepBox.add(Box.createVerticalGlue()); 216 217 } // constructor 218 219 /** 220 * Adds a label to the review panel. 221 * @param s the label string. 222 */ 223 private JLabel addLabel(String s) { 224 JLabel addLbl = 225 new JLabel(ResourceStrings.getString(s)); 226 panel.add(FieldLayout.LABEL, addLbl); 227 return addLbl; 228 } // addLabel 229 230 /** 231 * Adds a field to the review panel. 232 * @param s the field value. 233 * @return the label of which the field consists. 234 */ 235 private JLabel addField(String s) { 236 JLabel l = new JLabel(s); 237 l.setForeground(Color.black); 238 panel.add(FieldLayout.FIELD, l); 239 return l; 240 } // addField 241 242 public String getDescription() { 243 return ResourceStrings.getString("cvt_wiz_review_desc"); 244 } // getDescription 245 246 public Component getComponent() { 247 return stepBox; 248 } // getComponent 249 250 public void setActive(int direction) { 251 252 setFinishEnabled(true); 253 254 /** 255 * If no bean exists for the default data store, then use the 256 * name of the data store as the description. 257 */ 258 String description = null; 259 if (defaultDsconf != null) { 260 description = defaultDsconf.getModule().getDescription(); 261 } else { 262 description = dhcpdOptions.getResource(); 263 } 264 265 oldStoreLabel.setText(description); 266 newStoreLabel.setText(getDsconf().getModule().getDescription()); 267 268 String message = null; 269 if (saveTablesStep.isSaveTablesSelected()) { 270 message = ResourceStrings.getString("yes"); 271 } else { 272 message = ResourceStrings.getString("no"); 273 } 274 saveLabel.setText(message); 275 276 } // setActive 277 278 public boolean setInactive(int direction) { 279 return true; 280 } // setInactive 281 282 } // ReviewStep 283 284 /** 285 * Constructor for the ConvertWizard. 286 * @param owner owner of the wizard. 287 * @param title title of the wizard. 288 */ 289 public ConvertWizard(Frame owner, String title) { 290 291 super(owner, title); 292 293 // Go ahead and grab handles to the different servers and 294 // read the server defaults. 295 // 296 try { 297 svcServer = DataManager.get().getDhcpServiceMgr(); 298 dhcptabServer = DataManager.get().getDhcptabMgr(); 299 netServer = DataManager.get().getDhcpNetMgr(); 300 dhcpdOptions = svcServer.readDefaults(); 301 } catch (Throwable e) { 302 e.printStackTrace(); 303 return; 304 } 305 306 // Create the DSConfList and determine the default. Note that 307 // if the current data store has no management bean, then the 308 // defaultDsconf is null. 309 // 310 dsconfList = new DSConfList(); 311 dsconfList.init(svcServer); 312 defaultDsconf = 313 dsconfList.findDsconf(dhcpdOptions.getResource()); 314 315 // If no bean exists for the default data store, then use the 316 // name of the data store as the description. 317 // 318 String description = null; 319 if (defaultDsconf != null) { 320 description = defaultDsconf.getModule().getDescription(); 321 } else { 322 description = dhcpdOptions.getResource(); 323 } 324 325 326 // Build the wizard explanation message. 327 // 328 Object [] args = new Object[1]; 329 args[0] = description; 330 MessageFormat form = new MessageFormat( 331 ResourceStrings.getString("cvt_wiz_explain")); 332 String wizExplain = form.format(args); 333 334 // Add the steps for the wizard. 335 // 336 DatastoreStep datastoreStep = new DatastoreStep(wizExplain, 337 ResourceStrings.getString("cvt_wiz_store_explain")); 338 addStep(datastoreStep); 339 addStep(new DatastoreModuleStep()); 340 addStep(saveTablesStep = new SaveTablesStep()); 341 addStep(new ReviewStep()); 342 showFirstStep(); 343 } 344 345 public void doFinish() { 346 /* 347 * To convert the data store, we have to do the following items: 348 * 1. Create the new location/path 349 * 2. Convert the dhcptab 350 * 3. Convert the network tables 351 * 4. Modify the DHCP defaults 352 * 5. Delete old tables if necessary 353 */ 354 355 getDsconf().setLocation(); 356 getDsconf().setConfig(); 357 final DhcpDatastore newDhcpDatastore = getDsconf().getDS(); 358 final DhcpDatastore oldDhcpDatastore = dhcpdOptions.getDhcpDatastore(); 359 360 if (newDhcpDatastore.equals(oldDhcpDatastore)) { 361 JOptionPane.showMessageDialog(ConvertWizard.this, 362 ResourceStrings.getString("cvt_wiz_same_datastore_error"), 363 ResourceStrings.getString("cvt_wiz_error"), 364 JOptionPane.ERROR_MESSAGE); 365 return; 366 } 367 368 // Create the new location if it does not exist. 369 // 370 try { 371 svcServer.makeLocation(newDhcpDatastore); 372 } catch (ExistsException e) { 373 // this is o.k. 374 } catch (Throwable e) { 375 MessageFormat form = new MessageFormat( 376 ResourceStrings.getString("cvt_wiz_location_error")); 377 Object [] args = new Object[1]; 378 args[0] = newDhcpDatastore.getLocation(); 379 String msg = form.format(args); 380 JOptionPane.showMessageDialog(ConvertWizard.this, 381 msg, 382 ResourceStrings.getString("cvt_wiz_error"), 383 JOptionPane.ERROR_MESSAGE); 384 385 return; 386 } 387 388 // Go get a list of the network tables to convert. 389 // 390 try { 391 networks = netServer.getNetworks(oldDhcpDatastore); 392 if (networks == null) { 393 networks = new Network[0]; 394 } 395 } catch (Throwable e) { 396 MessageFormat form = new MessageFormat( 397 ResourceStrings.getString("cvt_wiz_networks_error")); 398 Object [] args = new Object[1]; 399 args[0] = e.getMessage(); 400 String msg = form.format(args); 401 JOptionPane.showMessageDialog(ConvertWizard.this, 402 msg, 403 ResourceStrings.getString("cvt_wiz_error"), 404 JOptionPane.ERROR_MESSAGE); 405 406 reallyFinish(); 407 return; 408 } 409 410 // Add 1 to tables count for dhcptab 411 final int tables = networks.length + 1; 412 // One update per table, plus one per table if deleting 413 int updates = 414 !saveTablesStep.isSaveTablesSelected() ? tables * 2 : tables; 415 // Add: one for shutdown, one for updating dhcpsvc.conf 416 updates += 2; 417 // If daemon will be restarted, then add 1 for start 418 if (dhcpdOptions.isDaemonEnabled()) { 419 ++updates; 420 } 421 final ProgressManager progress = new ProgressManager(this, 422 ResourceStrings.getString("cvt_wiz_progress"), 423 "", 0, updates); 424 425 // Called when doFinish() is really finished 426 // (i.e., the thread completes). 427 // 428 final Runnable finisher = new Runnable() { 429 public void run() { 430 reallyFinish(); 431 } 432 }; 433 434 435 // Here's the thread which does the conversion. 436 // 437 Thread convertThread = new Thread() { 438 public void run() { 439 440 String message = null; 441 MessageFormat form; 442 MessageFormat errForm; 443 Object [] args = new Object[1]; 444 boolean saveTables = 445 saveTablesStep.isSaveTablesSelected(); 446 447 // This is final so it can be used in the 448 // errorDisplay Runnable. 449 // 450 final ErrorTable failedTable = new ErrorTable( 451 ResourceStrings.getString("cvt_wiz_table"), 452 String.class); 453 454 // Shutdown the server. 455 // 456 int counter = 0; 457 try { 458 svcServer.shutdown(); 459 message = ResourceStrings.getString( 460 "cvt_wiz_server_shutdown"); 461 } catch (Throwable e) { 462 message = 463 ResourceStrings.getString("cvt_wiz_shutdown_err"); 464 failedTable.addError("", e.getMessage()); 465 saveTables = true; 466 } finally { 467 try { 468 progress.update(++counter, message); 469 } catch (InterruptedException e) { 470 SwingUtilities.invokeLater(finisher); 471 return; 472 } 473 } 474 475 // Convert the dhcptab. 476 // 477 try { 478 dhcptabServer.cvtDhcptab(newDhcpDatastore); 479 message = ResourceStrings.getString( 480 "cvt_wiz_progress_dhcptab_cvt"); 481 } catch (Throwable e) { 482 message = ResourceStrings.getString( 483 "cvt_wiz_progress_dhcptab_cvt_err"); 484 failedTable.addError(ResourceStrings.getString( 485 "cvt_wiz_dhcptab"), e.getMessage()); 486 saveTables = true; 487 } finally { 488 try { 489 progress.update(++counter, message); 490 } catch (InterruptedException e) { 491 SwingUtilities.invokeLater(finisher); 492 return; 493 } 494 } 495 496 // Convert the network tables. 497 // 498 form = new MessageFormat(ResourceStrings.getString( 499 "cvt_wiz_progress_network_cvt")); 500 errForm = new MessageFormat(ResourceStrings.getString( 501 "cvt_wiz_progress_network_cvt_err")); 502 503 for (int i = 0; i < networks.length; ++i) { 504 String netString = networks[i].toString(); 505 args[0] = netString; 506 try { 507 netServer.cvtNetwork(netString, newDhcpDatastore); 508 message = form.format(args); 509 } catch (Throwable e) { 510 message = errForm.format(args); 511 failedTable.addError(netString, e.getMessage()); 512 saveTables = true; 513 } finally { 514 try { 515 progress.update(++counter, message); 516 } catch (InterruptedException e) { 517 SwingUtilities.invokeLater(finisher); 518 return; 519 } 520 } 521 } 522 523 // Update the DHCP defaults file with the new values. 524 // 525 dhcpdOptions.setDhcpDatastore(newDhcpDatastore); 526 try { 527 svcServer.writeDefaults(dhcpdOptions); 528 message = ResourceStrings.getString( 529 "cvt_wiz_progress_defaults"); 530 } catch (Throwable e) { 531 message = ResourceStrings.getString( 532 "cvt_wiz_progress_defaults_err"); 533 failedTable.addError(ResourceStrings.getString( 534 "cvt_wiz_defaults"), e.getMessage()); 535 saveTables = true; 536 } finally { 537 try { 538 progress.update(++counter, message); 539 } catch (InterruptedException e) { 540 SwingUtilities.invokeLater(finisher); 541 return; 542 } 543 } 544 545 if (!saveTables) { 546 // Delete the network tables 547 // 548 form = new MessageFormat(ResourceStrings.getString( 549 "cvt_wiz_progress_network_del")); 550 errForm = new MessageFormat(ResourceStrings.getString( 551 "cvt_wiz_progress_network_del_err")); 552 553 for (int i = 0; i < networks.length; ++i) { 554 String netString = networks[i].toString(); 555 args[0] = netString; 556 try { 557 netServer.deleteNetwork(netString, false, 558 oldDhcpDatastore); 559 message = form.format(args); 560 } catch (Throwable e) { 561 message = errForm.format(args); 562 failedTable.addError(netString, e.getMessage()); 563 } finally { 564 try { 565 progress.update(++counter, message); 566 } catch (InterruptedException e) { 567 SwingUtilities.invokeLater(finisher); 568 return; 569 } 570 } 571 } 572 573 // Delete the dhcptab 574 // 575 try { 576 dhcptabServer.deleteDhcptab(oldDhcpDatastore); 577 message = ResourceStrings.getString( 578 "cvt_wiz_progress_dhcptab_del"); 579 } catch (Throwable e) { 580 message = ResourceStrings.getString( 581 "cvt_wiz_progress_dhcptab_del_err"); 582 failedTable.addError(ResourceStrings.getString( 583 "cvt_wiz_dhcptab"), e.getMessage()); 584 } finally { 585 try { 586 progress.update(++counter, message); 587 } catch (InterruptedException e) { 588 SwingUtilities.invokeLater(finisher); 589 return; 590 } 591 } 592 } else if (!saveTablesStep.isSaveTablesSelected()) { 593 try { 594 counter += tables; 595 progress.update(counter, ""); 596 } catch (InterruptedException e) { 597 SwingUtilities.invokeLater(finisher); 598 return; 599 } 600 } 601 602 // Start the server. 603 // 604 if (dhcpdOptions.isDaemonEnabled()) { 605 try { 606 svcServer.startup(); 607 message = ResourceStrings.getString( 608 "cvt_wiz_server_started"); 609 } catch (Throwable e) { 610 message = 611 ResourceStrings.getString("cvt_wiz_start_err"); 612 failedTable.addError("", e.getMessage()); 613 } finally { 614 try { 615 progress.update(++counter, message); 616 } catch (InterruptedException e) { 617 SwingUtilities.invokeLater(finisher); 618 return; 619 } 620 } 621 } 622 623 // If any errors occurred, display them all at once. 624 // 625 if (!failedTable.isEmpty()) { 626 Runnable errorDisplay = new Runnable() { 627 public void run() { 628 Object [] objs = new Object[2]; 629 objs[0] = 630 ResourceStrings.getString("cvt_wiz_errors"); 631 JScrollPane scrollPane = 632 new JScrollPane(failedTable); 633 634 // Resize the table to something kind of small 635 // 636 Dimension d = 637 failedTable. 638 getPreferredScrollableViewportSize(); 639 d.height = 80; 640 failedTable.setPreferredScrollableViewportSize(d); 641 objs[1] = scrollPane; 642 JOptionPane.showMessageDialog(ConvertWizard.this, 643 objs, 644 ResourceStrings.getString("server_error_title"), 645 JOptionPane.ERROR_MESSAGE); 646 } 647 }; 648 try { 649 SwingUtilities.invokeAndWait(errorDisplay); 650 } catch (Throwable e) { 651 e.printStackTrace(); 652 } 653 } 654 SwingUtilities.invokeLater(finisher); 655 } 656 }; 657 convertThread.start(); 658 } 659 660 public void doHelp() { 661 DhcpmgrApplet.showHelp("convert_wizard"); 662 } 663 664 /** 665 * Called by the worker thread upon completion to exec the Wizard 666 * doFinish(). 667 */ 668 protected void reallyFinish() { 669 super.doFinish(); 670 } // reallyFinish 671 672 } // ConvertWizard