001/* 002 * CDDL HEADER START 003 * 004 * The contents of this file are subject to the terms of the 005 * Common Development and Distribution License, Version 1.0 only 006 * (the "License"). You may not use this file except in compliance 007 * with the License. 008 * 009 * You can obtain a copy of the license at legal-notices/CDDLv1_0.txt 010 * or http://forgerock.org/license/CDDLv1.0.html. 011 * See the License for the specific language governing permissions 012 * and limitations under the License. 013 * 014 * When distributing Covered Code, include this CDDL HEADER in each 015 * file and include the License file at legal-notices/CDDLv1_0.txt. 016 * If applicable, add the following below this CDDL HEADER, with the 017 * fields enclosed by brackets "[]" replaced with your own identifying 018 * information: 019 * Portions Copyright [yyyy] [name of copyright owner] 020 * 021 * CDDL HEADER END 022 * 023 * 024 * Copyright 2006-2010 Sun Microsystems, Inc. 025 * Portions Copyright 2014-2015 ForgeRock AS 026 */ 027package org.opends.guitools.uninstaller; 028 029import static org.forgerock.util.Utils.*; 030import static org.opends.admin.ads.util.ConnectionUtils.*; 031import static org.opends.messages.AdminToolMessages.*; 032import static org.opends.messages.QuickSetupMessages.*; 033 034import static com.forgerock.opendj.cli.ArgumentConstants.*; 035import static com.forgerock.opendj.cli.Utils.*; 036 037import java.io.BufferedReader; 038import java.io.File; 039import java.io.FileReader; 040import java.io.IOException; 041import java.net.URI; 042import java.util.Collections; 043import java.util.HashSet; 044import java.util.LinkedHashSet; 045import java.util.Set; 046 047import javax.naming.NamingException; 048import javax.naming.NoPermissionException; 049import javax.naming.ldap.InitialLdapContext; 050import javax.net.ssl.TrustManager; 051 052import org.forgerock.i18n.LocalizableMessage; 053import org.forgerock.i18n.LocalizableMessageBuilder; 054import org.forgerock.i18n.slf4j.LocalizedLogger; 055import org.opends.admin.ads.ADSContext; 056import org.opends.admin.ads.ServerDescriptor; 057import org.opends.admin.ads.TopologyCache; 058import org.opends.admin.ads.TopologyCacheException; 059import org.opends.admin.ads.util.ApplicationTrustManager; 060import org.opends.admin.ads.util.ConnectionUtils; 061import org.opends.guitools.controlpanel.datamodel.ConnectionProtocolPolicy; 062import org.opends.guitools.controlpanel.datamodel.ControlPanelInfo; 063import org.opends.quicksetup.Application; 064import org.opends.quicksetup.ApplicationException; 065import org.opends.quicksetup.Configuration; 066import org.opends.quicksetup.Constants; 067import org.opends.quicksetup.Installation; 068import org.opends.quicksetup.ProgressStep; 069import org.opends.quicksetup.Step; 070import org.opends.quicksetup.UserDataException; 071import org.opends.quicksetup.event.ProgressUpdateEvent; 072import org.opends.quicksetup.event.ProgressUpdateListener; 073import org.opends.quicksetup.util.PlainTextProgressMessageFormatter; 074import org.opends.quicksetup.util.ServerController; 075import org.opends.quicksetup.util.Utils; 076import org.opends.server.admin.client.cli.SecureConnectionCliArgs; 077import org.opends.server.util.StaticUtils; 078import org.opends.server.util.cli.LDAPConnectionConsoleInteraction; 079 080import com.forgerock.opendj.cli.ArgumentException; 081import com.forgerock.opendj.cli.ClientException; 082import com.forgerock.opendj.cli.ConsoleApplication; 083import com.forgerock.opendj.cli.Menu; 084import com.forgerock.opendj.cli.MenuBuilder; 085import com.forgerock.opendj.cli.MenuResult; 086import com.forgerock.opendj.cli.ReturnCode; 087 088/** 089 * The class used to provide some CLI interface in the uninstall. 090 * 091 * This class basically is in charge of parsing the data provided by the user 092 * in the command line and displaying messages asking the user for information. 093 * 094 * Once the user has provided all the required information it calls Uninstaller 095 * and launches it. 096 * 097 */ 098public class UninstallCliHelper extends ConsoleApplication { 099 100 private static final LocalizedLogger logger = LocalizedLogger.getLoggerForThisClass(); 101 102 private UninstallerArgumentParser parser; 103 private LDAPConnectionConsoleInteraction ci; 104 private ControlPanelInfo info; 105 106 private boolean forceNonInteractive; 107 private boolean useSSL = true; 108 private boolean useStartTLS; 109 110 /** 111 * Default constructor. 112 */ 113 public UninstallCliHelper() 114 { 115 // Nothing to do. 116 } 117 118 /** 119 * Creates a UserData based in the arguments provided. It asks user for 120 * additional information if what is provided in the arguments is not enough. 121 * 122 * @param args 123 * the ArgumentParser with the allowed arguments of the command line. 124 * The code assumes that the arguments have already been parsed. 125 * @param rawArguments 126 * the arguments provided in the command line. 127 * @return the UserData object with what the user wants to uninstall and null 128 * if the user cancels the uninstallation. 129 * @throws UserDataException 130 * if there is an error with the data in the arguments. 131 * @throws ClientException 132 * If there is an error processing data in non-interactive mode and 133 * an error must be thrown (not in force on error mode). 134 */ 135 public UninstallUserData createUserData(UninstallerArgumentParser args, 136 String[] rawArguments) 137 throws UserDataException, ClientException 138 { 139 parser = args; 140 UninstallUserData userData = new UninstallUserData(); 141 try 142 { 143 boolean isInteractive; 144 boolean isQuiet; 145 boolean isVerbose; 146 boolean isCanceled = false; 147 148 /* Step 1: analyze the arguments. 149 */ 150 151 isInteractive = args.isInteractive(); 152 153 isQuiet = args.isQuiet(); 154 155 isVerbose = args.isVerbose(); 156 157 userData.setQuiet(isQuiet); 158 userData.setVerbose(isVerbose); 159 userData.setForceOnError(args.isForceOnError()); 160 userData.setTrustManager(args.getTrustManager()); 161 162 userData.setConnectTimeout(getConnectTimeout()); 163 164 /* 165 * Step 2: check that the provided parameters are compatible. 166 */ 167 LocalizableMessageBuilder buf = new LocalizableMessageBuilder(); 168 int v = args.validateGlobalOptions(buf); 169 if (v != ReturnCode.SUCCESS.get()) 170 { 171 throw new UserDataException(null, buf.toMessage()); 172 } 173 174 /* Step 3: If this is an interactive uninstall ask for confirmation to 175 * delete the different parts of the installation if the user did not 176 * specify anything to delete. If we are not in interactive mode 177 * check that the user specified something to be deleted. 178 */ 179 Set<String> outsideDbs; 180 Set<String> outsideLogs; 181 Configuration config = 182 Installation.getLocal().getCurrentConfiguration(); 183 try { 184 outsideDbs = config.getOutsideDbs(); 185 } catch (IOException ioe) { 186 outsideDbs = Collections.emptySet(); 187 logger.info(LocalizableMessage.raw("error determining outside databases", ioe)); 188 } 189 190 try { 191 outsideLogs = config.getOutsideLogs(); 192 } catch (IOException ioe) { 193 outsideLogs = Collections.emptySet(); 194 logger.info(LocalizableMessage.raw("error determining outside logs", ioe)); 195 } 196 197 boolean somethingSpecifiedToDelete = 198 args.removeAll() || 199 args.removeBackupFiles() || 200 args.removeDatabases() || 201 args.removeLDIFFiles() || 202 args.removeConfigurationFiles() || 203 args.removeLogFiles() || 204 args.removeServerLibraries(); 205 206 if (somethingSpecifiedToDelete) 207 { 208 userData.setRemoveBackups(args.removeAll() || args.removeBackupFiles()); 209 userData.setRemoveConfigurationAndSchema(args.removeAll() || 210 args.removeConfigurationFiles()); 211 userData.setRemoveDatabases(args.removeAll() || args.removeDatabases()); 212 userData.setRemoveLDIFs(args.removeAll() || args.removeLDIFFiles()); 213 userData.setRemoveLibrariesAndTools(args.removeAll() || 214 args.removeServerLibraries()); 215 userData.setRemoveLogs(args.removeAll() || args.removeLogFiles()); 216 217 userData.setExternalDbsToRemove(outsideDbs); 218 userData.setExternalLogsToRemove(outsideLogs); 219 } 220 else if (!isInteractive) 221 { 222 throw new UserDataException(null, 223 ERR_CLI_UNINSTALL_NOTHING_TO_BE_UNINSTALLED_NON_INTERACTIVE.get()); 224 } 225 else 226 { 227 isCanceled = askWhatToDelete(userData, outsideDbs, outsideLogs); 228 } 229 String adminUid = args.getAdministratorUID(); 230 if (adminUid == null && !args.isInteractive()) 231 { 232 adminUid = args.getDefaultAdministratorUID(); 233 } 234 userData.setAdminUID(adminUid); 235 userData.setAdminPwd(args.getBindPassword()); 236 String referencedHostName = args.getReferencedHostName(); 237 if (referencedHostName == null && !args.isInteractive()) 238 { 239 referencedHostName = args.getDefaultReferencedHostName(); 240 } 241 try 242 { 243 UninstallData d = new UninstallData(Installation.getLocal()); 244 userData.setReplicationServer( 245 referencedHostName+":"+d.getReplicationServerPort()); 246 } 247 catch (Throwable t) 248 { 249 logger.error(LocalizableMessage.raw("Could not create UninstallData: "+t, t)); 250 userData.setReplicationServer( 251 referencedHostName+":8989"); 252 } 253 info = ControlPanelInfo.getInstance(); 254 info.setTrustManager(userData.getTrustManager()); 255 info.setConnectTimeout(getConnectTimeout()); 256 info.regenerateDescriptor(); 257 info.setConnectionPolicy(ConnectionProtocolPolicy.USE_ADMIN); 258 259 String adminConnectorUrl = info.getAdminConnectorURL(); 260 261 if (adminConnectorUrl == null) 262 { 263 logger.warn(LocalizableMessage.raw( 264 "Error retrieving a valid LDAP URL in conf file.")); 265 if (!parser.isInteractive()) 266 { 267 LocalizableMessage msg = ERR_COULD_NOT_FIND_VALID_LDAPURL.get(); 268 throw new ClientException(ReturnCode.APPLICATION_ERROR, msg); 269 } 270 } 271 userData.setLocalServerUrl(adminConnectorUrl); 272 userData.setReferencedHostName(referencedHostName); 273 274 /* 275 * Step 4: check if server is running. Depending if it is running and the 276 * OS we are running, ask for authentication information. 277 */ 278 if (!isCanceled) 279 { 280 isCanceled = checkServerState(userData); 281 } 282 283 if (isCanceled && !userData.isForceOnError()) 284 { 285 logger.info(LocalizableMessage.raw("User cancelled uninstall.")); 286 userData = null; 287 } 288 289 if (userData != null && !args.isQuiet()) 290 { 291 println(); 292 } 293 } 294 catch (Throwable t) 295 { 296 logger.warn(LocalizableMessage.raw("Exception: "+t, t)); 297 if (t instanceof UserDataException) 298 { 299 throw (UserDataException)t; 300 } 301 else if (t instanceof ClientException) 302 { 303 throw (ClientException)t; 304 } 305 else 306 { 307 throw new IllegalStateException("Unexpected error: "+t, t); 308 } 309 } 310 logger.info(LocalizableMessage.raw("Successfully created user data")); 311 return userData; 312 } 313 314 /** 315 * Commodity method used to ask the user to confirm the deletion of certain 316 * parts of the server. It updates the provided UserData object 317 * accordingly. Returns <CODE>true</CODE> if the user cancels and <CODE> 318 * false</CODE> otherwise. 319 * @param userData the UserData object to be updated. 320 * @param outsideDbs the set of relative paths of databases located outside 321 * the installation path of the server. 322 * @param outsideLogs the set of relative paths of log files located outside 323 * the installation path of the server. 324 * @return <CODE>true</CODE> if the user cancels and <CODE>false</CODE> 325 * otherwise. 326 */ 327 private boolean askWhatToDelete(UninstallUserData userData, 328 Set<String> outsideDbs, Set<String> outsideLogs) throws UserDataException 329 { 330 boolean cancelled = false; 331 final int REMOVE_ALL = 1; 332 final int SPECIFY_TO_REMOVE = 2; 333 int[] indexes = {REMOVE_ALL, SPECIFY_TO_REMOVE}; 334 LocalizableMessage[] msgs = new LocalizableMessage[] { 335 INFO_CLI_UNINSTALL_REMOVE_ALL.get(), 336 INFO_CLI_UNINSTALL_SPECIFY_WHAT_REMOVE.get() 337 }; 338 339 MenuBuilder<Integer> builder = new MenuBuilder<>(this); 340 builder.setPrompt(INFO_CLI_UNINSTALL_WHAT_TO_DELETE.get()); 341 342 for (int i=0; i<indexes.length; i++) 343 { 344 builder.addNumberedOption(msgs[i], MenuResult.success(indexes[i])); 345 } 346 347 builder.addQuitOption(); 348 349 builder.setDefault(LocalizableMessage.raw(String.valueOf(REMOVE_ALL)), 350 MenuResult.success(REMOVE_ALL)); 351 352 builder.setMaxTries(CONFIRMATION_MAX_TRIES); 353 354 Menu<Integer> menu = builder.toMenu(); 355 int choice; 356 try 357 { 358 MenuResult<Integer> m = menu.run(); 359 if (m.isSuccess()) 360 { 361 choice = m.getValue(); 362 } 363 else if (m.isQuit()) 364 { 365 choice = REMOVE_ALL; 366 cancelled = true; 367 } 368 else 369 { 370 // Should never happen. 371 throw new RuntimeException(); 372 } 373 } 374 catch (ClientException ce) 375 { 376 logger.warn(LocalizableMessage.raw("Error reading input: "+ce, ce)); 377 throw new UserDataException(null, ce.getMessageObject(), ce); 378 } 379 380 if (cancelled) 381 { 382 // Nothing to do 383 } 384 else if (choice == REMOVE_ALL) 385 { 386 userData.setRemoveBackups(true); 387 userData.setRemoveConfigurationAndSchema(true); 388 userData.setRemoveDatabases(true); 389 userData.setRemoveLDIFs(true); 390 userData.setRemoveLibrariesAndTools(true); 391 userData.setRemoveLogs(true); 392 393 userData.setExternalDbsToRemove(outsideDbs); 394 userData.setExternalLogsToRemove(outsideLogs); 395 } 396 else 397 { 398 boolean somethingSelected = false; 399 while (!somethingSelected && !cancelled) 400 { 401 println(); 402// Ask for confirmation for the different items 403 msgs = new LocalizableMessage [] { 404 INFO_CLI_UNINSTALL_CONFIRM_LIBRARIES_BINARIES.get(), 405 INFO_CLI_UNINSTALL_CONFIRM_DATABASES.get(), 406 INFO_CLI_UNINSTALL_CONFIRM_LOGS.get(), 407 INFO_CLI_UNINSTALL_CONFIRM_CONFIGURATION_SCHEMA.get(), 408 INFO_CLI_UNINSTALL_CONFIRM_BACKUPS.get(), 409 INFO_CLI_UNINSTALL_CONFIRM_LDIFS.get(), 410 INFO_CLI_UNINSTALL_CONFIRM_OUTSIDEDBS.get( 411 joinAsString(Constants.LINE_SEPARATOR, outsideDbs)), 412 INFO_CLI_UNINSTALL_CONFIRM_OUTSIDELOGS.get( 413 joinAsString(Constants.LINE_SEPARATOR, outsideLogs) 414 ) 415 }; 416 417 boolean[] answers = new boolean[msgs.length]; 418 try 419 { 420 for (int i=0; i<msgs.length; i++) 421 { 422 boolean ignore = (i == 6 && outsideDbs.isEmpty()) 423 || (i == 7 && outsideLogs.isEmpty()); 424 if (!ignore) 425 { 426 answers[i] = askConfirmation(msgs[i], true, logger); 427 } 428 else 429 { 430 answers[i] = false; 431 } 432 } 433 } 434 catch (ClientException ce) 435 { 436 throw new UserDataException(null, ce.getMessageObject(), ce); 437 } 438 439 if (!cancelled) 440 { 441 for (int i=0; i<answers.length; i++) 442 { 443 switch (i) 444 { 445 case 0: 446 userData.setRemoveLibrariesAndTools(answers[i]); 447 break; 448 449 case 1: 450 userData.setRemoveDatabases(answers[i]); 451 break; 452 453 case 2: 454 userData.setRemoveLogs(answers[i]); 455 break; 456 457 case 3: 458 userData.setRemoveConfigurationAndSchema(answers[i]); 459 break; 460 461 case 4: 462 userData.setRemoveBackups(answers[i]); 463 break; 464 465 case 5: 466 userData.setRemoveLDIFs(answers[i]); 467 break; 468 469 case 6: 470 if (answers[i]) 471 { 472 userData.setExternalDbsToRemove(outsideDbs); 473 } 474 break; 475 476 case 7: 477 if (answers[i]) 478 { 479 userData.setExternalLogsToRemove(outsideLogs); 480 } 481 break; 482 } 483 } 484 if (userData.getExternalDbsToRemove().isEmpty() && 485 userData.getExternalLogsToRemove().isEmpty() && 486 !userData.getRemoveLibrariesAndTools() && 487 !userData.getRemoveDatabases() && 488 !userData.getRemoveConfigurationAndSchema() && 489 !userData.getRemoveBackups() && 490 !userData.getRemoveLDIFs() && 491 !userData.getRemoveLogs()) 492 { 493 somethingSelected = false; 494 println(); 495 printErrorMessage( 496 ERR_CLI_UNINSTALL_NOTHING_TO_BE_UNINSTALLED.get()); 497 } 498 else 499 { 500 somethingSelected = true; 501 } 502 } 503 } 504 } 505 506 return cancelled; 507 } 508 509 /** 510 * Commodity method used to ask the user (when necessary) if the server must 511 * be stopped or not. It also prompts (if required) for authentication. 512 * 513 * @param userData 514 * the UserData object to be updated with the authentication of the 515 * user. 516 * @return <CODE>true</CODE> if the user wants to continue with uninstall and 517 * <CODE>false</CODE> otherwise. 518 * @throws UserDataException 519 * if there is a problem with the data provided by the user (in the 520 * particular case where we are on non-interactive uninstall and 521 * some data is missing or not valid). 522 * @throws ClientException 523 * If there is an error processing data in non-interactive mode and 524 * an error must be thrown (not in force on error mode). 525 */ 526 private boolean checkServerState(UninstallUserData userData) 527 throws UserDataException, ClientException 528 { 529 boolean cancelled = false; 530 boolean interactive = parser.isInteractive(); 531 boolean forceOnError = parser.isForceOnError(); 532 UninstallData conf = null; 533 try 534 { 535 conf = new UninstallData(Installation.getLocal()); 536 } 537 catch (Throwable t) 538 { 539 logger.warn(LocalizableMessage.raw("Error processing task: "+t, t)); 540 throw new UserDataException(Step.CONFIRM_UNINSTALL, 541 getThrowableMsg(INFO_BUG_MSG.get(), t)); 542 } 543 logger.info(LocalizableMessage.raw("interactive: "+interactive)); 544 logger.info(LocalizableMessage.raw("forceOnError: "+forceOnError)); 545 logger.info(LocalizableMessage.raw("conf.isADS(): "+conf.isADS())); 546 logger.info(LocalizableMessage.raw("conf.isReplicationServer(): "+ 547 conf.isReplicationServer())); 548 logger.info(LocalizableMessage.raw("conf.isServerRunning(): "+conf.isServerRunning())); 549 if (conf.isADS() && conf.isReplicationServer()) 550 { 551 if (conf.isServerRunning()) 552 { 553 if (interactive) 554 { 555 try 556 { 557 println(); 558 if (confirmToUpdateRemote()) 559 { 560 cancelled = !askForAuthenticationIfNeeded(userData); 561 if (cancelled) 562 { 563 /* Ask for confirmation to stop server */ 564 println(); 565 cancelled = !confirmToStopServer(); 566 } 567 else 568 { 569 cancelled = !updateUserUninstallDataWithRemoteServers(userData); 570 if (cancelled) 571 { 572 println(); 573 /* Ask for confirmation to stop server */ 574 cancelled = !confirmToStopServer(); 575 } 576 } 577 } 578 else 579 { 580 /* Ask for confirmation to stop server */ 581 cancelled = !confirmToStopServer(); 582 } 583 } 584 catch (ClientException ce) 585 { 586 throw new UserDataException(null, ce.getMessageObject(), ce); 587 } 588 } 589 else 590 { 591 boolean errorWithRemote = 592 !updateUserUninstallDataWithRemoteServers(userData); 593 cancelled = errorWithRemote && !parser.isForceOnError(); 594 logger.info(LocalizableMessage.raw("Non interactive mode. errorWithRemote: "+ 595 errorWithRemote)); 596 } 597 } 598 else if (interactive) 599 { 600 println(); 601 try 602 { 603 if (confirmToUpdateRemoteAndStart()) 604 { 605 boolean startWorked = startServer(userData.isQuiet()); 606 // Ask for authentication if needed, etc. 607 if (startWorked) 608 { 609 cancelled = !askForAuthenticationIfNeeded(userData); 610 if (cancelled) 611 { 612 println(); 613 /* Ask for confirmation to stop server */ 614 cancelled = !confirmToStopServer(); 615 } 616 else 617 { 618 cancelled = 619 !updateUserUninstallDataWithRemoteServers(userData); 620 if (cancelled) 621 { 622 println(); 623 /* Ask for confirmation to stop server */ 624 cancelled = !confirmToStopServer(); 625 } 626 } 627 userData.setStopServer(true); 628 } 629 else 630 { 631 userData.setStopServer(false); 632 println(); 633 /* Ask for confirmation to delete files */ 634 cancelled = !confirmDeleteFiles(); 635 } 636 } 637 else 638 { 639 println(); 640 /* Ask for confirmation to delete files */ 641 cancelled = !confirmDeleteFiles(); 642 } 643 } 644 catch (ClientException ce) 645 { 646 throw new UserDataException(null, ce.getMessageObject(), ce); 647 } 648 } 649 else 650 { 651 boolean startWorked = startServer(userData.isQuiet()); 652 // Ask for authentication if needed, etc. 653 if (startWorked) 654 { 655 userData.setStopServer(true); 656 boolean errorWithRemote = 657 !updateUserUninstallDataWithRemoteServers(userData); 658 cancelled = errorWithRemote && !parser.isForceOnError(); 659 } 660 else 661 { 662 cancelled = !forceOnError; 663 userData.setStopServer(false); 664 } 665 } 666 if (!cancelled || parser.isForceOnError()) 667 { 668 /* During all the confirmations, the server might be stopped. */ 669 userData.setStopServer( 670 Installation.getLocal().getStatus().isServerRunning()); 671 logger.info(LocalizableMessage.raw("Must stop the server after confirmations? "+ 672 userData.getStopServer())); 673 } 674 } 675 else if (conf.isServerRunning()) 676 { 677 try 678 { 679 if (interactive) 680 { 681 println(); 682 /* Ask for confirmation to stop server */ 683 cancelled = !confirmToStopServer(); 684 } 685 686 if (!cancelled) 687 { 688 /* During all the confirmations, the server might be stopped. */ 689 userData.setStopServer( 690 Installation.getLocal().getStatus().isServerRunning()); 691 logger.info(LocalizableMessage.raw("Must stop the server after confirmations? "+ 692 userData.getStopServer())); 693 } 694 } 695 catch (ClientException ce) 696 { 697 throw new UserDataException(null, ce.getMessageObject(), ce); 698 } 699 } 700 else 701 { 702 userData.setStopServer(false); 703 if (interactive) 704 { 705 println(); 706 /* Ask for confirmation to delete files */ 707 try 708 { 709 cancelled = !confirmDeleteFiles(); 710 } 711 catch (ClientException ce) 712 { 713 throw new UserDataException(null, ce.getMessageObject(), ce); 714 } 715 } 716 } 717 logger.info(LocalizableMessage.raw("cancelled: "+cancelled)); 718 return cancelled; 719 } 720 721 /** 722 * Ask for confirmation to stop server. 723 * @return <CODE>true</CODE> if the user wants to continue and stop the 724 * server. <CODE>false</CODE> otherwise. 725 * @throws ClientException if the user reached the confirmation limit. 726 */ 727 private boolean confirmToStopServer() throws ClientException 728 { 729 return askConfirmation(INFO_CLI_UNINSTALL_CONFIRM_STOP.get(), true, logger); 730 } 731 732 /** 733 * Ask for confirmation to delete files. 734 * @return <CODE>true</CODE> if the user wants to continue and delete the 735 * files. <CODE>false</CODE> otherwise. 736 * @throws ClientException if the user reached the confirmation limit. 737 */ 738 private boolean confirmDeleteFiles() throws ClientException 739 { 740 return askConfirmation(INFO_CLI_UNINSTALL_CONFIRM_DELETE_FILES.get(), true, 741 logger); 742 } 743 744 /** 745 * Ask for confirmation to update configuration on remote servers. 746 * @return <CODE>true</CODE> if the user wants to continue and stop the 747 * server. <CODE>false</CODE> otherwise. 748 * @throws ClientException if the user reached the confirmation limit. 749 */ 750 private boolean confirmToUpdateRemote() throws ClientException 751 { 752 return askConfirmation(INFO_CLI_UNINSTALL_CONFIRM_UPDATE_REMOTE.get(), true, 753 logger); 754 } 755 756 /** 757 * Ask for confirmation to update configuration on remote servers. 758 * @return <CODE>true</CODE> if the user wants to continue and stop the 759 * server. <CODE>false</CODE> otherwise. 760 * @throws ClientException if the user reached the confirmation limit. 761 */ 762 private boolean confirmToUpdateRemoteAndStart() throws ClientException 763 { 764 return askConfirmation( 765 INFO_CLI_UNINSTALL_CONFIRM_UPDATE_REMOTE_AND_START.get(), true, logger); 766 } 767 768 /** 769 * Ask for confirmation to provide again authentication. 770 * @return <CODE>true</CODE> if the user wants to provide authentication 771 * again. <CODE>false</CODE> otherwise. 772 * @throws ClientException if the user reached the confirmation limit. 773 */ 774 private boolean promptToProvideAuthenticationAgain() throws ClientException 775 { 776 return askConfirmation( 777 INFO_UNINSTALL_CONFIRM_PROVIDE_AUTHENTICATION_AGAIN.get(), true, logger); 778 } 779 780 /** 781 * Ask for data required to update configuration on remote servers. If all the 782 * data is provided and validated, we assume that the user wants to update the 783 * remote servers. 784 * 785 * @return <CODE>true</CODE> if the user wants to continue and update the 786 * remote servers. <CODE>false</CODE> otherwise. 787 * @throws UserDataException 788 * if there is a problem with the information provided by the user. 789 * @throws ClientException 790 * If there is an error processing data. 791 */ 792 private boolean askForAuthenticationIfNeeded(UninstallUserData userData) 793 throws UserDataException, ClientException 794 { 795 boolean accepted = true; 796 String uid = userData.getAdminUID(); 797 String pwd = userData.getAdminPwd(); 798 799 boolean couldConnect = false; 800 801 while (!couldConnect && accepted) 802 { 803 804 // This is done because we do not need to ask the user about these 805 // parameters. If we force their presence the class 806 // LDAPConnectionConsoleInteraction will not prompt the user for 807 // them. 808 SecureConnectionCliArgs secureArgsList = parser.getSecureArgsList(); 809 810 secureArgsList.hostNameArg.setPresent(true); 811 secureArgsList.portArg.setPresent(true); 812 secureArgsList.hostNameArg.clearValues(); 813 secureArgsList.hostNameArg.addValue( 814 secureArgsList.hostNameArg.getDefaultValue()); 815 secureArgsList.portArg.clearValues(); 816 secureArgsList.portArg.addValue( 817 secureArgsList.portArg.getDefaultValue()); 818 secureArgsList.bindDnArg.clearValues(); 819 if (uid != null) 820 { 821 secureArgsList.bindDnArg.addValue(ADSContext.getAdministratorDN(uid)); 822 secureArgsList.bindDnArg.setPresent(true); 823 } 824 else 825 { 826 secureArgsList.bindDnArg.setPresent(false); 827 } 828 secureArgsList.bindPasswordArg.clearValues(); 829 if (pwd != null) 830 { 831 secureArgsList.bindPasswordArg.addValue(pwd); 832 secureArgsList.bindPasswordArg.setPresent(true); 833 } 834 else 835 { 836 secureArgsList.bindPasswordArg.setPresent(false); 837 } 838 839 if (ci == null) 840 { 841 ci = 842 new LDAPConnectionConsoleInteraction(this, parser.getSecureArgsList()); 843 ci.setDisplayLdapIfSecureParameters(true); 844 } 845 846 try 847 { 848 ci.run(false); 849 userData.setAdminUID(ci.getAdministratorUID()); 850 userData.setAdminPwd(ci.getBindPassword()); 851 852 info.setConnectionPolicy(ConnectionProtocolPolicy.USE_ADMIN); 853 854 String adminConnectorUrl = info.getAdminConnectorURL(); 855 if (adminConnectorUrl == null) 856 { 857 logger.warn(LocalizableMessage.raw( 858 "Error retrieving a valid Administration Connector URL in conf file.")); 859 LocalizableMessage msg = ERR_COULD_NOT_FIND_VALID_LDAPURL.get(); 860 throw new ClientException(ReturnCode.APPLICATION_ERROR, msg); 861 } 862 try 863 { 864 URI uri = new URI(adminConnectorUrl); 865 int port = uri.getPort(); 866 secureArgsList.portArg.clearValues(); 867 secureArgsList.portArg.addValue(String.valueOf(port)); 868 ci.setPortNumber(port); 869 } 870 catch (Throwable t) 871 { 872 logger.error(LocalizableMessage.raw("Error parsing url: "+adminConnectorUrl)); 873 } 874 updateTrustManager(userData, ci); 875 876 info.setConnectionPolicy(ConnectionProtocolPolicy.USE_ADMIN); 877 878 adminConnectorUrl = info.getAdminConnectorURL(); 879 880 if (adminConnectorUrl == null) 881 { 882 logger.warn(LocalizableMessage.raw( 883 "Error retrieving a valid Administration Connector URL in conf file.")); 884 LocalizableMessage msg = ERR_COULD_NOT_FIND_VALID_LDAPURL.get(); 885 throw new ClientException(ReturnCode.APPLICATION_ERROR, msg); 886 } 887 888 userData.setLocalServerUrl(adminConnectorUrl); 889 couldConnect = true; 890 } 891 catch (ArgumentException e) 892 { 893 parser.displayMessageAndUsageReference(getErrStream(), e.getMessageObject()); 894 } 895 catch (ClientException e) { 896 printErrorMessage(e.getMessageObject()); 897 println(); 898 } 899 900 if (!couldConnect) 901 { 902 try 903 { 904 accepted = promptToProvideAuthenticationAgain(); 905 if (accepted) 906 { 907 uid = null; 908 pwd = null; 909 } 910 } 911 catch (ClientException ce) 912 { 913 throw new UserDataException(null, ce.getMessageObject(), ce); 914 } 915 } 916 } 917 918 if (accepted) 919 { 920 String referencedHostName = parser.getReferencedHostName(); 921 while (referencedHostName == null) 922 { 923 println(); 924 referencedHostName = askForReferencedHostName(userData.getHostName()); 925 } 926 try 927 { 928 UninstallData d = new UninstallData(Installation.getLocal()); 929 userData.setReplicationServer( 930 referencedHostName+":"+d.getReplicationServerPort()); 931 userData.setReferencedHostName(referencedHostName); 932 } 933 catch (Throwable t) 934 { 935 logger.error(LocalizableMessage.raw("Could not create UninstallData: "+t, t)); 936 } 937 } 938 userData.setUpdateRemoteReplication(accepted); 939 return accepted; 940 } 941 942 private String askForReferencedHostName(String defaultHostName) 943 { 944 String s = defaultHostName; 945 try 946 { 947 s = readInput(INFO_UNINSTALL_CLI_REFERENCED_HOSTNAME_PROMPT.get(), 948 defaultHostName); 949 } 950 catch (ClientException ce) 951 { 952 logger.warn(LocalizableMessage.raw("Error reading input: %s", ce), ce); 953 } 954 return s; 955 } 956 957 private boolean startServer(boolean suppressOutput) 958 { 959 logger.info(LocalizableMessage.raw("startServer, suppressOutput: " + suppressOutput)); 960 boolean serverStarted = false; 961 Application application = new Application() 962 { 963 /** {@inheritDoc} */ 964 @Override 965 public String getInstallationPath() 966 { 967 return Installation.getLocal().getRootDirectory().getAbsolutePath(); 968 } 969 /** {@inheritDoc} */ 970 @Override 971 public String getInstancePath() 972 { 973 String installPath = getInstallationPath(); 974 975 // look for <installPath>/lib/resource.loc 976 String instancePathFileName = installPath + File.separator + "lib" 977 + File.separator + "resource.loc"; 978 File f = new File(instancePathFileName); 979 980 if (! f.exists()) 981 { 982 return installPath; 983 } 984 985 BufferedReader reader; 986 try 987 { 988 reader = new BufferedReader(new FileReader(instancePathFileName)); 989 } 990 catch (Exception e) 991 { 992 return installPath; 993 } 994 995 996 // Read the first line and close the file. 997 String line; 998 try 999 { 1000 line = reader.readLine(); 1001 return new File(line).getAbsolutePath(); 1002 } 1003 catch (Exception e) 1004 { 1005 return installPath; 1006 } 1007 finally 1008 { 1009 StaticUtils.close(reader); 1010 } 1011 } 1012 /** {@inheritDoc} */ 1013 @Override 1014 public ProgressStep getCurrentProgressStep() 1015 { 1016 return UninstallProgressStep.NOT_STARTED; 1017 } 1018 /** {@inheritDoc} */ 1019 @Override 1020 public Integer getRatio(ProgressStep step) 1021 { 1022 return 0; 1023 } 1024 /** {@inheritDoc} */ 1025 @Override 1026 public LocalizableMessage getSummary(ProgressStep step) 1027 { 1028 return null; 1029 } 1030 /** {@inheritDoc} */ 1031 @Override 1032 public boolean isFinished() 1033 { 1034 return false; 1035 } 1036 /** {@inheritDoc} */ 1037 @Override 1038 public boolean isCancellable() 1039 { 1040 return false; 1041 } 1042 /** {@inheritDoc} */ 1043 @Override 1044 public void cancel() 1045 { 1046 } 1047 /** {@inheritDoc} */ 1048 @Override 1049 public void run() 1050 { 1051 } 1052 }; 1053 application.setProgressMessageFormatter( 1054 new PlainTextProgressMessageFormatter()); 1055 if (!suppressOutput) 1056 { 1057 application.addProgressUpdateListener( 1058 new ProgressUpdateListener() { 1059 @Override 1060 public void progressUpdate(ProgressUpdateEvent ev) { 1061 System.out.print(ev.getNewLogs().toString()); 1062 System.out.flush(); 1063 } 1064 }); 1065 } 1066 ServerController controller = new ServerController(application, 1067 Installation.getLocal()); 1068 try 1069 { 1070 if (!suppressOutput) 1071 { 1072 println(); 1073 } 1074 controller.startServer(suppressOutput); 1075 if (!suppressOutput) 1076 { 1077 println(); 1078 } 1079 serverStarted = Installation.getLocal().getStatus().isServerRunning(); 1080 logger.info(LocalizableMessage.raw("server started successfully. serverStarted: "+ 1081 serverStarted)); 1082 } 1083 catch (ApplicationException ae) 1084 { 1085 logger.warn(LocalizableMessage.raw("ApplicationException: "+ae, ae)); 1086 if (!suppressOutput) 1087 { 1088 printErrorMessage(ae.getMessageObject()); 1089 } 1090 } 1091 catch (Throwable t) 1092 { 1093 logger.error(LocalizableMessage.raw("Unexpected error: "+t, t)); 1094 throw new IllegalStateException("Unexpected error: "+t, t); 1095 } 1096 return serverStarted; 1097 } 1098 1099 /** 1100 * Returns an InitialLdapContext using the provided parameters. We try to 1101 * guarantee that the connection is able to read the configuration. 1102 * 1103 * @param host 1104 * the host name. 1105 * @param port 1106 * the port to connect. 1107 * @param useSSL 1108 * whether to use SSL or not. 1109 * @param useStartTLS 1110 * whether to use StartTLS or not. 1111 * @param bindDn 1112 * the bind dn to be used. 1113 * @param pwd 1114 * the password. 1115 * @param connectTimeout 1116 * the timeout in milliseconds to connect to the server. 1117 * @param trustManager 1118 * the trust manager. 1119 * @return an InitialLdapContext connected. 1120 * @throws NamingException 1121 * if there was an error establishing the connection. 1122 */ 1123 private InitialLdapContext createAdministrativeContext(String host, 1124 int port, boolean useSSL, boolean useStartTLS, String bindDn, String pwd, 1125 int connectTimeout, ApplicationTrustManager trustManager) 1126 throws NamingException 1127 { 1128 InitialLdapContext ctx; 1129 String ldapUrl = ConnectionUtils.getLDAPUrl(host, port, useSSL); 1130 if (useSSL) 1131 { 1132 ctx = createLdapsContext(ldapUrl, bindDn, pwd, connectTimeout, null, trustManager, null); 1133 } 1134 else if (useStartTLS) 1135 { 1136 ctx = 1137 Utils.createStartTLSContext(ldapUrl, bindDn, pwd, connectTimeout, 1138 null, trustManager, null); 1139 } 1140 else 1141 { 1142 ctx = createLdapContext(ldapUrl, bindDn, pwd, connectTimeout, null); 1143 } 1144 if (!ConnectionUtils.connectedAsAdministrativeUser(ctx)) 1145 { 1146 throw new NoPermissionException(ERR_NOT_ADMINISTRATIVE_USER.get() 1147 .toString()); 1148 } 1149 return ctx; 1150 } 1151 1152 /** 1153 * Updates the contents of the UninstallUserData while trying to connect to 1154 * the remote servers. It returns <CODE>true</CODE> if we could connect to the 1155 * remote servers and all the presented certificates were accepted and 1156 * <CODE>false</CODE> otherwise. continue if 1157 * 1158 * @param userData 1159 * the user data to be updated. 1160 * @return <CODE>true</CODE> if we could connect to the remote servers and all 1161 * the presented certificates were accepted and <CODE>false</CODE> 1162 * otherwise. 1163 * @throws UserDataException 1164 * if were are not in interactive mode and not in force on error 1165 * mode and the operation must be stopped. 1166 * @throws ClientException 1167 * If there is an error processing data in non-interactive mode and 1168 * an error must be thrown (not in force on error mode). 1169 */ 1170 private boolean updateUserUninstallDataWithRemoteServers( 1171 UninstallUserData userData) throws UserDataException, ClientException 1172 { 1173 boolean accepted = false; 1174 boolean interactive = parser.isInteractive(); 1175 boolean forceOnError = parser.isForceOnError(); 1176 1177 boolean exceptionOccurred = true; 1178 1179 LocalizableMessage exceptionMsg = null; 1180 1181 logger.info(LocalizableMessage.raw("Updating user data with remote servers.")); 1182 1183 InitialLdapContext ctx = null; 1184 try 1185 { 1186 info.setTrustManager(userData.getTrustManager()); 1187 info.setConnectTimeout(getConnectTimeout()); 1188 String host = "localhost"; 1189 int port = 389; 1190 String adminUid = userData.getAdminUID(); 1191 String pwd = userData.getAdminPwd(); 1192 String dn = ADSContext.getAdministratorDN(adminUid); 1193 1194 info.setConnectionPolicy(ConnectionProtocolPolicy.USE_ADMIN); 1195 String adminConnectorUrl = info.getAdminConnectorURL(); 1196 try 1197 { 1198 URI uri = new URI(adminConnectorUrl); 1199 host = uri.getHost(); 1200 port = uri.getPort(); 1201 } 1202 catch (Throwable t) 1203 { 1204 logger.error(LocalizableMessage.raw("Error parsing url: "+adminConnectorUrl)); 1205 } 1206 ctx = createAdministrativeContext(host, port, useSSL, useStartTLS, dn, 1207 pwd, getConnectTimeout(), 1208 userData.getTrustManager()); 1209 1210 ADSContext adsContext = new ADSContext(ctx); 1211 if (interactive && userData.getTrustManager() == null) 1212 { 1213 // This is required when the user did connect to the server using SSL 1214 // or Start TLS in interactive mode. In this case 1215 // LDAPConnectionInteraction.run does not initialize the keystore and 1216 // the trust manager is null. 1217 forceTrustManagerInitialization(); 1218 updateTrustManager(userData, ci); 1219 } 1220 logger.info(LocalizableMessage.raw("Reloading topology")); 1221 TopologyCache cache = new TopologyCache(adsContext, 1222 userData.getTrustManager(), getConnectTimeout()); 1223 cache.getFilter().setSearchMonitoringInformation(false); 1224 cache.reloadTopology(); 1225 1226 accepted = handleTopologyCache(cache, userData); 1227 1228 exceptionOccurred = false; 1229 } 1230 catch (NamingException ne) 1231 { 1232 logger.warn(LocalizableMessage.raw("Error connecting to server: "+ne, ne)); 1233 if (isCertificateException(ne)) 1234 { 1235 String details = ne.getMessage() != null ? 1236 ne.getMessage() : ne.toString(); 1237 exceptionMsg = INFO_ERROR_READING_CONFIG_LDAP_CERTIFICATE.get(details); 1238 } 1239 else 1240 { 1241 exceptionMsg = getThrowableMsg(INFO_ERROR_CONNECTING_TO_LOCAL.get(), ne); 1242 } 1243 } catch (TopologyCacheException te) 1244 { 1245 logger.warn(LocalizableMessage.raw("Error connecting to server: "+te, te)); 1246 exceptionMsg = Utils.getMessage(te); 1247 1248 } catch (ClientException ce) 1249 { 1250 throw ce; 1251 1252 } catch (Throwable t) 1253 { 1254 logger.warn(LocalizableMessage.raw("Error connecting to server: "+t, t)); 1255 exceptionMsg = getThrowableMsg(INFO_BUG_MSG.get(), t); 1256 } 1257 finally 1258 { 1259 StaticUtils.close(ctx); 1260 } 1261 if (exceptionOccurred) 1262 { 1263 if (!interactive) 1264 { 1265 if (forceOnError) 1266 { 1267 println(); 1268 printErrorMessage(ERR_UNINSTALL_ERROR_UPDATING_REMOTE_FORCE.get( 1269 "--"+parser.getSecureArgsList().adminUidArg.getLongIdentifier(), 1270 "--"+OPTION_LONG_BINDPWD, 1271 "--"+OPTION_LONG_BINDPWD_FILE, 1272 exceptionMsg)); 1273 } 1274 else 1275 { 1276 println(); 1277 throw new UserDataException(null, 1278 ERR_UNINSTALL_ERROR_UPDATING_REMOTE_NO_FORCE.get( 1279 "--"+ 1280 parser.getSecureArgsList().adminUidArg.getLongIdentifier(), 1281 "--"+OPTION_LONG_BINDPWD, 1282 "--"+OPTION_LONG_BINDPWD_FILE, 1283 "--"+parser.forceOnErrorArg.getLongIdentifier(), 1284 exceptionMsg)); 1285 } 1286 } 1287 else 1288 { 1289 try 1290 { 1291 accepted = askConfirmation( 1292 ERR_UNINSTALL_NOT_UPDATE_REMOTE_PROMPT.get(), 1293 false, logger); 1294 } 1295 catch (ClientException ce) 1296 { 1297 throw new UserDataException(null, ce.getMessageObject(), ce); 1298 } 1299 } 1300 } 1301 userData.setUpdateRemoteReplication(accepted); 1302 logger.info(LocalizableMessage.raw("accepted: "+accepted)); 1303 return accepted; 1304 } 1305 1306 /** 1307 * Method that interacts with the user depending on what errors where 1308 * encountered in the TopologyCache object. This method assumes that the 1309 * TopologyCache has been reloaded. 1310 * Returns <CODE>true</CODE> if the user accepts all the problems encountered 1311 * and <CODE>false</CODE> otherwise. 1312 * @param userData the user data. 1313 * @throws UserDataException if there is an error with the information 1314 * provided by the user when we are in non-interactive mode. 1315 * @throws ClientException if there is an error processing data in 1316 * non-interactive mode and an error must be thrown (not in force on error 1317 * mode). 1318 */ 1319 private boolean handleTopologyCache(TopologyCache cache, 1320 UninstallUserData userData) throws UserDataException, ClientException 1321 { 1322 boolean returnValue; 1323 boolean stopProcessing = false; 1324 boolean reloadTopologyCache = false; 1325 1326 logger.info(LocalizableMessage.raw("Handle topology cache.")); 1327 1328 Set<TopologyCacheException> exceptions = new HashSet<>(); 1329 /* Analyze if we had any exception while loading servers. For the moment 1330 * only throw the exception found if the user did not provide the 1331 * Administrator DN and this caused a problem authenticating in one server 1332 * or if there is a certificate problem. 1333 */ 1334 Set<ServerDescriptor> servers = cache.getServers(); 1335 userData.setRemoteServers(servers); 1336 for (ServerDescriptor server : servers) 1337 { 1338 TopologyCacheException e = server.getLastException(); 1339 if (e != null) 1340 { 1341 exceptions.add(e); 1342 } 1343 } 1344 Set<LocalizableMessage> exceptionMsgs = new LinkedHashSet<>(); 1345 /* Check the exceptions and see if we throw them or not. */ 1346 for (TopologyCacheException e : exceptions) 1347 { 1348 logger.info(LocalizableMessage.raw("Analyzing exception: "+e, e)); 1349 if (stopProcessing) 1350 { 1351 break; 1352 } 1353 switch (e.getType()) 1354 { 1355 case NOT_GLOBAL_ADMINISTRATOR: 1356 println(); 1357 printErrorMessage(INFO_NOT_GLOBAL_ADMINISTRATOR_PROVIDED.get()); 1358 stopProcessing = true; 1359 break; 1360 case GENERIC_CREATING_CONNECTION: 1361 if (isCertificateException(e.getCause())) 1362 { 1363 if (isInteractive()) 1364 { 1365 println(); 1366 stopProcessing = true; 1367 if (ci.promptForCertificateConfirmation(e.getCause(), 1368 e.getTrustManager(), e.getLdapUrl(), logger)) 1369 { 1370 reloadTopologyCache = true; 1371 updateTrustManager(userData, ci); 1372 } 1373 } 1374 else 1375 { 1376 exceptionMsgs.add( 1377 INFO_ERROR_READING_CONFIG_LDAP_CERTIFICATE_SERVER.get( 1378 e.getHostPort(), e.getCause().getMessage())); 1379 } 1380 } 1381 else 1382 { 1383 exceptionMsgs.add(Utils.getMessage(e)); 1384 } 1385 break; 1386 default: 1387 exceptionMsgs.add(Utils.getMessage(e)); 1388 } 1389 } 1390 if (isInteractive()) 1391 { 1392 if (!stopProcessing && !exceptionMsgs.isEmpty()) 1393 { 1394 println(); 1395 try 1396 { 1397 returnValue = askConfirmation( 1398 ERR_UNINSTALL_READING_REGISTERED_SERVERS_CONFIRM_UPDATE_REMOTE.get( 1399 Utils.getMessageFromCollection(exceptionMsgs, 1400 Constants.LINE_SEPARATOR)), true, logger); 1401 } 1402 catch (ClientException ce) 1403 { 1404 throw new UserDataException(null, ce.getMessageObject(), ce); 1405 } 1406 } 1407 else if (reloadTopologyCache) 1408 { 1409 returnValue = updateUserUninstallDataWithRemoteServers(userData); 1410 } 1411 else 1412 { 1413 returnValue = !stopProcessing; 1414 } 1415 } 1416 else 1417 { 1418 logger.info(LocalizableMessage.raw("exceptionMsgs: "+exceptionMsgs)); 1419 if (!exceptionMsgs.isEmpty()) 1420 { 1421 if (parser.isForceOnError()) 1422 { 1423 LocalizableMessage msg = Utils.getMessageFromCollection(exceptionMsgs, 1424 Constants.LINE_SEPARATOR); 1425 println(); 1426 printErrorMessage(msg); 1427 returnValue = false; 1428 } 1429 else 1430 { 1431 LocalizableMessage msg = 1432 ERR_UNINSTALL_ERROR_UPDATING_REMOTE_NO_FORCE.get( 1433 "--"+ 1434 parser.getSecureArgsList().adminUidArg.getLongIdentifier(), 1435 "--"+OPTION_LONG_BINDPWD, 1436 "--"+OPTION_LONG_BINDPWD_FILE, 1437 "--"+parser.forceOnErrorArg.getLongIdentifier(), 1438 Utils.getMessageFromCollection(exceptionMsgs, 1439 Constants.LINE_SEPARATOR)); 1440 throw new ClientException(ReturnCode.APPLICATION_ERROR, msg); 1441 } 1442 } 1443 else 1444 { 1445 returnValue = true; 1446 } 1447 } 1448 logger.info(LocalizableMessage.raw("Return value: "+returnValue)); 1449 return returnValue; 1450 } 1451 1452 /** {@inheritDoc} */ 1453 @Override 1454 public boolean isAdvancedMode() { 1455 return false; 1456 } 1457 1458 1459 1460 /** {@inheritDoc} */ 1461 @Override 1462 public boolean isInteractive() { 1463 return !forceNonInteractive && parser.isInteractive(); 1464 } 1465 1466 1467 1468 /** {@inheritDoc} */ 1469 @Override 1470 public boolean isMenuDrivenMode() { 1471 return true; 1472 } 1473 1474 1475 1476 /** {@inheritDoc} */ 1477 @Override 1478 public boolean isQuiet() { 1479 return false; 1480 } 1481 1482 1483 1484 /** {@inheritDoc} */ 1485 @Override 1486 public boolean isScriptFriendly() { 1487 return false; 1488 } 1489 1490 1491 1492 /** {@inheritDoc} */ 1493 @Override 1494 public boolean isVerbose() { 1495 return true; 1496 } 1497 1498 /** 1499 * Commodity method to update the user data with the trust manager in the 1500 * LDAPConnectionConsoleInteraction object. 1501 * @param userData the user data to be updated. 1502 * @param ci the LDAPConnectionConsoleInteraction object to be used to update 1503 * the user data object. 1504 */ 1505 private void updateTrustManager(UninstallUserData userData, 1506 LDAPConnectionConsoleInteraction ci) 1507 { 1508 ApplicationTrustManager trust = null; 1509 TrustManager t = ci.getTrustManager(); 1510 if (t != null) 1511 { 1512 if (t instanceof ApplicationTrustManager) 1513 { 1514 trust = (ApplicationTrustManager)t; 1515 } 1516 else 1517 { 1518 trust = new ApplicationTrustManager(ci.getKeyStore()); 1519 } 1520 } 1521 userData.setTrustManager(trust); 1522 } 1523 1524 1525 1526 /** 1527 * Forces the initialization of the trust manager in the 1528 * LDAPConnectionInteraction object. 1529 */ 1530 private void forceTrustManagerInitialization() 1531 { 1532 forceNonInteractive = true; 1533 try 1534 { 1535 ci.initializeTrustManagerIfRequired(); 1536 } 1537 catch (ArgumentException ae) 1538 { 1539 logger.warn(LocalizableMessage.raw("Error initializing trust store: "+ae, ae)); 1540 } 1541 forceNonInteractive = false; 1542 } 1543 1544 private void printErrorMessage(LocalizableMessage msg) 1545 { 1546 super.println(msg); 1547 logger.warn(LocalizableMessage.raw(msg)); 1548 } 1549 1550 /** 1551 * Returns the timeout to be used to connect in milliseconds. The method 1552 * must be called after parsing the arguments. 1553 * @return the timeout to be used to connect in milliseconds. Returns 1554 * {@code 0} if there is no timeout. 1555 * @throw {@code IllegalStateException} if the method is called before 1556 * parsing the arguments. 1557 */ 1558 private int getConnectTimeout() 1559 { 1560 try 1561 { 1562 return parser.getSecureArgsList().connectTimeoutArg.getIntValue(); 1563 } 1564 catch (ArgumentException ae) 1565 { 1566 throw new IllegalStateException("Argument parser is not parsed: "+ae, 1567 ae); 1568 } 1569 } 1570}