001/* 002 * The contents of this file are subject to the terms of the Common Development and 003 * Distribution License (the License). You may not use this file except in compliance with the 004 * License. 005 * 006 * You can obtain a copy of the License at legal/CDDLv1.0.txt. See the License for the 007 * specific language governing permission and limitations under the License. 008 * 009 * When distributing Covered Software, include this CDDL Header Notice in each file and include 010 * the License file at legal/CDDLv1.0.txt. If applicable, add the following below the CDDL 011 * Header, with the fields enclosed by brackets [] replaced by your own identifying 012 * information: "Portions Copyright [year] [name of copyright owner]". 013 * 014 * Copyright 2006-2010 Sun Microsystems, Inc. 015 * Portions Copyright 2011-2016 ForgeRock AS. 016 */ 017package org.opends.quicksetup; 018 019import static com.forgerock.opendj.util.OperatingSystem.*; 020 021import static org.opends.messages.QuickSetupMessages.*; 022import static org.opends.server.util.ServerConstants.*; 023 024import java.io.BufferedReader; 025import java.io.File; 026import java.io.FileReader; 027import java.io.IOException; 028import java.util.Set; 029import java.util.concurrent.Callable; 030import java.util.concurrent.ExecutionException; 031import java.util.concurrent.FutureTask; 032 033import org.forgerock.i18n.LocalizableMessage; 034import org.forgerock.i18n.slf4j.LocalizedLogger; 035import org.opends.quicksetup.util.Utils; 036import org.opends.server.util.CollectionUtils; 037import org.opends.server.util.SetupUtils; 038 039/** 040 * This class represents the physical state of an OpenDJ installation. All the 041 * operations are dependent upon the root directory that is specified in the 042 * constructor. 043 */ 044public final class Installation 045{ 046 /** Relative path to bootstrap OpenDJ jar file. */ 047 public static final String OPENDJ_BOOTSTRAP_JAR_RELATIVE_PATH = "lib/bootstrap.jar"; 048 /** Relative path to bootstrap-client OpenDJ jar file. */ 049 public static final String OPENDJ_BOOTSTRAP_CLIENT_JAR_RELATIVE_PATH = "lib/bootstrap-client.jar"; 050 051 /** The relative path where all the Windows binaries (batch files) are. */ 052 public static final String WINDOWS_BINARIES_PATH_RELATIVE = "bat"; 053 /** The relative path where all the UNIX binaries (scripts) are. */ 054 public static final String UNIX_BINARIES_PATH_RELATIVE = "bin"; 055 /** The relative path where all the MacOS X Applications are. */ 056 private static final String MAC_APPLICATIONS_PATH_RELATIVE = "bin"; 057 /** The relative path where all the libraries (jar files) are. */ 058 public static final String LIBRARIES_PATH_RELATIVE = SetupUtils.LIBRARIES_PATH_RELATIVE; 059 /** The relative path where the resources directory (to customize the product) is. */ 060 private static final String RESOURCES_PATH_RELATIVE = "resources"; 061 /** The relative path where customer classes are. */ 062 private static final String CLASSES_PATH_RELATIVE = "classes"; 063 /** The relative path where the database files are. */ 064 private static final String DATABASES_PATH_RELATIVE = "db"; 065 /** The relative path where the log files are. */ 066 private static final String LOGS_PATH_RELATIVE = "logs"; 067 /** The relative path where the LDIF files are. */ 068 private static final String LDIFS_PATH_RELATIVE = "ldif"; 069 /** The relative path where the backup files are. */ 070 public static final String BACKUPS_PATH_RELATIVE = "bak"; 071 /** The relative path where the config files are. */ 072 public static final String CONFIG_PATH_RELATIVE = "config"; 073 /** The relative path where the config files are. */ 074 private static final String HISTORY_PATH_RELATIVE = "history"; 075 /** Path to the config/upgrade directory where upgrade base files are stored. */ 076 private static final String UPGRADE_PATH = "upgrade"; 077 /** Relative path to the locks directory. */ 078 public static final String LOCKS_PATH_RELATIVE = "locks"; 079 /** Relative path to the locks directory. */ 080 private static final String TMP_PATH_RELATIVE = "tmp"; 081 /** The relative path to the current Configuration LDIF file. */ 082 private static final String CURRENT_CONFIG_FILE_NAME = "config.ldif"; 083 /** The relative path to the current Configuration LDIF file. */ 084 private static final String BASE_CONFIG_FILE_PREFIX = "config.ldif."; 085 /** The relative path to the instance.loc file. */ 086 public static final String INSTANCE_LOCATION_PATH_RELATIVE = "instance.loc"; 087 /** The path to the instance.loc file. */ 088 public static final String INSTANCE_LOCATION_PATH = "/etc/opendj/" 089 + INSTANCE_LOCATION_PATH_RELATIVE; 090 /** The relative path to tmpl_instance. */ 091 private static final String TEMPLATE_RELATIVE_PATH = "template"; 092 /** The relative path to buildinfo file. */ 093 private static final String BUILDINFO_RELATIVE_PATH = "buildinfo"; 094 /** The UNIX setup script file name. */ 095 public static final String UNIX_SETUP_FILE_NAME = "setup"; 096 /** The Windows setup batch file name. */ 097 private static final String WINDOWS_SETUP_FILE_NAME = "setup.bat"; 098 /** The UNIX uninstall script file name. */ 099 public static final String UNIX_UNINSTALL_FILE_NAME = "uninstall"; 100 /** The Windows uninstall batch file name. */ 101 public static final String WINDOWS_UNINSTALL_FILE_NAME = "uninstall.bat"; 102 /** The UNIX upgrade script file name. */ 103 public static final String UNIX_UPGRADE_FILE_NAME = "upgrade"; 104 /** The UNIX start script file name. */ 105 public static final String UNIX_START_FILE_NAME = "start-ds"; 106 /** The Windows start batch file name. */ 107 public static final String WINDOWS_START_FILE_NAME = "start-ds.bat"; 108 /** The UNIX stop script file name. */ 109 public static final String UNIX_STOP_FILE_NAME = "stop-ds"; 110 /** The Windows stop batch file name. */ 111 public static final String WINDOWS_STOP_FILE_NAME = "stop-ds.bat"; 112 /** The UNIX control panel script file name. */ 113 public static final String UNIX_CONTROLPANEL_FILE_NAME = "control-panel"; 114 /** The Windows control panel batch file name. */ 115 public static final String WINDOWS_CONTROLPANEL_FILE_NAME = "control-panel.bat"; 116 /** The MacOS X Java application stub name. */ 117 public static final String MAC_JAVA_APP_STUB_NAME = "universalJavaApplicationStub"; 118 /** The MacOS X control panel application bundle name. */ 119 public static final String MAC_CONTROLPANEL_FILE_NAME = "ControlPanel.app"; 120 /** The UNIX status command line script file name. */ 121 public static final String UNIX_STATUSCLI_FILE_NAME = "status"; 122 /** The Windows status command line batch file name. */ 123 public static final String WINDOWS_STATUSCLI_FILE_NAME = "status.bat"; 124 /** The UNIX import LDIF script file name. */ 125 public static final String UNIX_IMPORT_LDIF = "import-ldif"; 126 /** The Windows import LDIF batch file name. */ 127 public static final String WINDOWS_IMPORT_LDIF = "import-ldif.bat"; 128 129 /** Name of the file kept in the history directory containing logs of upgrade and reversions. */ 130 public static final String HISTORY_LOG_FILE_NAME = "log"; 131 /** The default java properties file. */ 132 public static final String DEFAULT_JAVA_PROPERTIES_FILE = "java.properties"; 133 /** The default java properties file relative path. */ 134 public static final String RELATIVE_JAVA_PROPERTIES_FILE = 135 CONFIG_PATH_RELATIVE + File.separator + "java.properties"; 136 /** The set java home and arguments properties file for Windows. */ 137 public static final String SET_JAVA_PROPERTIES_FILE_WINDOWS = "set-java-home.bat"; 138 /** Script utils file for UNIX systems. */ 139 public static final String SCRIPT_UTIL_FILE_UNIX = "_script-util.sh"; 140 /** Script utils file for Windows. */ 141 public static final String SCRIPT_UTIL_FILE_WINDOWS = "_script-util.bat"; 142 /** The set java home and arguments properties file for UNIX systems. */ 143 public static final String SET_JAVA_PROPERTIES_FILE_UNIX = "set-java-home"; 144 145 /** Directories required to be present for this installation to be considered valid. */ 146 public static final String[] REQUIRED_DIRECTORIES = new String[] { 147 CONFIG_PATH_RELATIVE, DATABASES_PATH_RELATIVE, LIBRARIES_PATH_RELATIVE }; 148 149 /** The default base DN prompted to user in setup interactive mode. */ 150 public static final String DEFAULT_INTERACTIVE_BASE_DN = "dc=example,dc=com"; 151 152 /** 153 * Performs validation on the specified file to make sure that it is an actual 154 * OpenDJ installation. 155 * 156 * @param rootDirectory 157 * File directory candidate 158 * @throws IllegalArgumentException 159 * if root directory does not appear to be an OpenDJ installation 160 * root. The thrown exception contains a localized message 161 * indicating the reason why <code>rootDirectory</code> is not a 162 * valid OpenDJ install root. 163 */ 164 public static void validateRootDirectory(File rootDirectory) 165 throws IllegalArgumentException 166 { 167 LocalizableMessage failureReason = null; 168 if (rootDirectory == null) 169 { 170 failureReason = INFO_ERROR_INSTALL_ROOT_DIR_NULL.get(); 171 } 172 else if (!rootDirectory.exists()) 173 { 174 failureReason = INFO_ERROR_INSTALL_ROOT_DIR_NO_EXIST.get(Utils 175 .getPath(rootDirectory)); 176 } 177 else if (!rootDirectory.isDirectory()) 178 { 179 failureReason = INFO_ERROR_INSTALL_ROOT_DIR_NOT_DIR.get(Utils 180 .getPath(rootDirectory)); 181 } 182 else 183 { 184 String[] children = rootDirectory.list(); 185 if (children != null) 186 { 187 Set<String> childrenSet = CollectionUtils.newHashSet(children); 188 for (String dir : REQUIRED_DIRECTORIES) 189 { 190 if (!childrenSet.contains(dir)) 191 { 192 failureReason = INFO_ERROR_INSTALL_ROOT_DIR_NO_DIR.get( 193 Utils.getPath(rootDirectory), dir); 194 } 195 } 196 } 197 else 198 { 199 failureReason = INFO_ERROR_INSTALL_ROOT_DIR_EMPTY.get(Utils 200 .getPath(rootDirectory)); 201 } 202 } 203 if (failureReason != null) 204 { 205 throw new IllegalArgumentException(failureReason.toString()); 206 } 207 } 208 209 private static Installation local; 210 211 /** 212 * Obtains the installation by reading the classpath of the running JVM to 213 * determine the location of the jars and determine the installation root. 214 * 215 * @return Installation obtained by reading the classpath 216 */ 217 public static Installation getLocal() 218 { 219 if (local == null) 220 { 221 // This allows testing of configuration components when the OpenDJ.jar 222 // in the classpath does not necessarily point to the server's 223 String installRoot = System.getProperty("org.opends.quicksetup.Root"); 224 String instanceRoot = System 225 .getProperty("org.opends.quicksetup.instance"); 226 227 if (installRoot == null) 228 { 229 installRoot = Utils.getInstallPathFromClasspath(); 230 } 231 if (instanceRoot == null) 232 { 233 instanceRoot = Utils.getInstancePathFromInstallPath(installRoot); 234 } 235 local = new Installation(installRoot, instanceRoot); 236 } 237 return local; 238 } 239 240 private static final LocalizedLogger logger = LocalizedLogger.getLoggerForThisClass(); 241 242 private File rootDirectory; 243 private File instanceDirectory; 244 245 private Status status; 246 247 private Configuration configuration; 248 private Configuration baseConfiguration; 249 250 private BuildInformation buildInformation; 251 private BuildInformation instanceInformation; 252 253 /** 254 * Creates a new instance from a root directory specified as a string. 255 * 256 * @param rootDirectory 257 * of this installation 258 * @param instanceRootDirectory 259 * The instance root directory 260 */ 261 public Installation(String rootDirectory, String instanceRootDirectory) 262 { 263 this(new File(rootDirectory), new File(instanceRootDirectory)); 264 } 265 266 /** 267 * Creates a new instance from a root directory specified as a File. 268 * 269 * @param rootDirectory 270 * of this installation 271 * @param instanceDirectory 272 * of the instance 273 */ 274 public Installation(File rootDirectory, File instanceDirectory) 275 { 276 setRootDirectory(rootDirectory); 277 setInstanceDirectory(instanceDirectory); 278 } 279 280 /** 281 * Gets the top level directory of an OpenDJ installation. 282 * 283 * @return File object representing the top level directory of and OpenDJ 284 * installation 285 */ 286 public File getRootDirectory() 287 { 288 return this.rootDirectory; 289 } 290 291 /** 292 * Gets the top level directory of an OpenDJ instance. 293 * 294 * @return File object representing the top level directory of and OpenDK 295 * installation 296 */ 297 public File getInstanceDirectory() 298 { 299 return this.instanceDirectory; 300 } 301 302 /** 303 * Sets the root directory of this installation. 304 * 305 * @param rootDirectory 306 * File of this installation 307 */ 308 public void setRootDirectory(File rootDirectory) 309 { 310 // Hold off on doing validation of rootDirectory since 311 // some applications (like the Installer) create an Installation 312 // before the actual bits have been laid down on the file system. 313 this.rootDirectory = rootDirectory; 314 315 // Obtaining build information is a fairly time consuming operation. 316 // Try to get a head start if possible. 317 if (isValid(rootDirectory)) 318 { 319 try 320 { 321 BuildInformation bi = getBuildInformation(); 322 logger.info(LocalizableMessage.raw("build info for " + rootDirectory.getName() + ": " 323 + bi)); 324 } 325 catch (ApplicationException e) 326 { 327 logger.info(LocalizableMessage.raw("error determining build information", e)); 328 } 329 } 330 } 331 332 /** 333 * Sets the root directory of this instance. 334 * 335 * @param instanceDirectory 336 * File of this instance 337 */ 338 public void setInstanceDirectory(File instanceDirectory) 339 { 340 // Hold off on doing validation of rootDirectory since 341 // some applications (like the Installer) create an Installation 342 // before the actual bits have been laid down on the filesystem. 343 this.instanceDirectory = instanceDirectory; 344 345 // Obtaining build information is a fairly time consuming operation. 346 // Try to get a head start if possible. 347 if (isValid(instanceDirectory)) 348 { 349 try 350 { 351 BuildInformation bi = getBuildInformation(); 352 logger.info(LocalizableMessage.raw("build info for " + instanceDirectory.getName() 353 + ": " + bi)); 354 } 355 catch (ApplicationException e) 356 { 357 logger.info(LocalizableMessage.raw("error determining build information", e)); 358 } 359 } 360 } 361 362 /** 363 * Indicates whether this installation appears to be an actual OpenDJ 364 * installation. 365 * 366 * @param file 367 * The root directory 368 * @return boolean where true indicates that this does indeed appear to be a 369 * valid OpenDJ installation; false otherwise 370 */ 371 public boolean isValid(File file) 372 { 373 try 374 { 375 validateRootDirectory(file); 376 return true; 377 } 378 catch (IllegalArgumentException e) 379 { 380 return false; 381 } 382 } 383 384 /** 385 * Creates a string explaining why this is not a legitimate OpenDJ 386 * installation. Null if this is in fact a valid installation. 387 * 388 * @return localized message indicating the reason this is not an OpenDJ 389 * installation 390 */ 391 public String getInvalidityReason() 392 { 393 try 394 { 395 validateRootDirectory(rootDirectory); 396 return null; 397 } 398 catch (IllegalArgumentException e) 399 { 400 return e.getLocalizedMessage(); 401 } 402 } 403 404 /** 405 * Gets the Configuration object representing this file. The current 406 * configuration is stored in config/config.ldif. 407 * 408 * @return Configuration representing the current configuration. 409 */ 410 public Configuration getCurrentConfiguration() 411 { 412 if (configuration == null) 413 { 414 configuration = new Configuration(this, getCurrentConfigurationFile()); 415 } 416 return configuration; 417 } 418 419 /** 420 * Gets the Configuration object representing this file. The base 421 * configuration is stored in config/upgrade/config.ldif.[svn rev]. 422 * 423 * @return Configuration object representing the base configuration. 424 * @throws ApplicationException 425 * if there was a problem determining the svn rev number. 426 */ 427 public Configuration getBaseConfiguration() throws ApplicationException 428 { 429 if (baseConfiguration == null) 430 { 431 baseConfiguration = new Configuration(this, getBaseConfigurationFile()); 432 } 433 return baseConfiguration; 434 } 435 436 /** 437 * Gets the current status of this installation. 438 * 439 * @return Status object representing the state of this installation. 440 */ 441 public Status getStatus() 442 { 443 if (status == null) 444 { 445 status = new Status(this); 446 } 447 return status; 448 } 449 450 /** 451 * Returns the path to the libraries. 452 * 453 * @return the path to the libraries. 454 */ 455 public File getLibrariesDirectory() 456 { 457 return new File(getRootDirectory(), LIBRARIES_PATH_RELATIVE); 458 } 459 460 /** 461 * Returns the path to the resources directory. 462 * 463 * @return the path to the resources directory. 464 */ 465 public File getResourcesDirectory() 466 { 467 return new File(getRootDirectory(), RESOURCES_PATH_RELATIVE); 468 } 469 470 /** 471 * Returns the path to the classes directory. 472 * 473 * @return the path to the classes directory. 474 */ 475 public File getClassesDirectory() 476 { 477 return new File(getRootDirectory(), CLASSES_PATH_RELATIVE); 478 } 479 480 /** 481 * Creates a File object representing config/upgrade/schema.ldif.current which 482 * the server creates the first time it starts if there are schema 483 * customizations. 484 * 485 * @return File object with no 486 */ 487 public File getSchemaConcatFile() 488 { 489 return new File(getConfigurationUpgradeDirectory(), SCHEMA_CONCAT_FILE_NAME); 490 } 491 492 /** 493 * Creates a File object representing config/upgrade/schema.ldif.current which 494 * the server creates the first time it starts if there are schema 495 * customizations. 496 * 497 * @return File object with no 498 * @throws ApplicationException 499 * if there was a problem determining the svn revision number 500 */ 501 public File getBaseSchemaFile() throws ApplicationException 502 { 503 return new File(getConfigurationUpgradeDirectory(), "schema.ldif." + getInstanceVCSRevision()); 504 } 505 506 /** 507 * Creates a File object representing config/upgrade/schema.ldif.current which 508 * the server creates the first time it starts if there are schema 509 * customizations. 510 * 511 * @return File object with no 512 * @throws ApplicationException 513 * if there was a problem determining the svn revision number 514 */ 515 public File getBaseConfigurationFile() throws ApplicationException 516 { 517 return new File(getConfigurationUpgradeDirectory(), BASE_CONFIG_FILE_PREFIX + getInstanceVCSRevision()); 518 } 519 520 /** 521 * Gets the VCS revision of the build. 522 * 523 * @return String representing the VCS revision 524 * @throws ApplicationException 525 * if for some reason the number could not be determined 526 */ 527 public String getVCSRevision() throws ApplicationException 528 { 529 return getBuildInformation().getRevision(); 530 } 531 532 /** 533 * Gets the VCS revision of the instance. 534 * 535 * @return Integer representing the svn number 536 * @throws ApplicationException 537 * if for some reason the number could not be determined 538 */ 539 public String getInstanceVCSRevision() throws ApplicationException 540 { 541 return getInstanceBuildInformation().getRevision(); 542 } 543 544 /** 545 * Returns the path to the configuration file of the directory server. Note 546 * that this method assumes that this code is being run locally. 547 * 548 * @return the path of the configuration file of the directory server. 549 */ 550 public File getCurrentConfigurationFile() 551 { 552 return new File(getConfigurationDirectory(), CURRENT_CONFIG_FILE_NAME); 553 } 554 555 /** 556 * Returns the relative path of the directory containing the binaries/scripts 557 * of the Open DS installation. The path is relative to the installation path. 558 * 559 * @return the relative path of the directory containing the binaries/scripts 560 * of the Open DS installation. 561 */ 562 public File getBinariesDirectory() 563 { 564 String binDir = isWindows() ? WINDOWS_BINARIES_PATH_RELATIVE : UNIX_BINARIES_PATH_RELATIVE; 565 return new File(getRootDirectory(), binDir); 566 } 567 568 /** 569 * Returns the path to the database files under the install path. 570 * 571 * @return the path to the database files under the install path. 572 */ 573 public File getDatabasesDirectory() 574 { 575 return new File(getInstanceDirectory(), DATABASES_PATH_RELATIVE); 576 } 577 578 /** 579 * Returns the path to the backup files under the install path. 580 * 581 * @return the path to the backup files under the install path. 582 */ 583 public File getBackupDirectory() 584 { 585 return new File(getInstanceDirectory(), BACKUPS_PATH_RELATIVE); 586 } 587 588 /** 589 * Returns the path to the config files under the install path. 590 * 591 * @return the path to the config files under the install path. 592 */ 593 public File getConfigurationDirectory() 594 { 595 return new File(getInstanceDirectory(), CONFIG_PATH_RELATIVE); 596 } 597 598 /** 599 * Returns the path to the log files under the install path. 600 * 601 * @return the path to the log files under the install path. 602 */ 603 public File getLogsDirectory() 604 { 605 return new File(getInstanceDirectory(), LOGS_PATH_RELATIVE); 606 } 607 608 /** 609 * Returns the directory where the lock files are stored. 610 * 611 * @return the path to the lock files. 612 */ 613 public File getLocksDirectory() 614 { 615 return new File(getInstanceDirectory(), LOCKS_PATH_RELATIVE); 616 } 617 618 /** 619 * Gets the directory used to store the template configuration. 620 * 621 * @return The directory used to store the template configuration. 622 */ 623 public File getTemplateDirectory() 624 { 625 return new File(getRootDirectory(), TEMPLATE_RELATIVE_PATH); 626 } 627 628 /** 629 * Gets the directory used to store files temporarily. 630 * 631 * @return File temporary directory 632 */ 633 public File getTemporaryDirectory() 634 { 635 return new File(getInstanceDirectory(), TMP_PATH_RELATIVE); 636 } 637 638 /** 639 * Returns the directory where the lock files are stored. 640 * 641 * @return the path to the lock files. 642 */ 643 public File getHistoryDirectory() 644 { 645 return new File(getInstanceDirectory(), HISTORY_PATH_RELATIVE); 646 } 647 648 /** 649 * Creates a new directory in the history directory appropriate for backing up 650 * an installation during an upgrade. 651 * 652 * @return File representing a new backup directory. The directory can be 653 * assumed to exist if this method returns cleanly. 654 * @throws IOException 655 * if an error occurred creating the directory. 656 */ 657 public File createHistoryBackupDirectory() throws IOException 658 { 659 File backupDirectory = new File(getHistoryDirectory(), Long.toString(System 660 .currentTimeMillis())); 661 if (backupDirectory.exists()) 662 { 663 backupDirectory.delete(); 664 } 665 if (!backupDirectory.mkdirs()) 666 { 667 throw new IOException("failed to create history backup directory"); 668 } 669 return backupDirectory; 670 } 671 672 /** 673 * Gets the log file where the history of upgrades and reversions is kept. 674 * 675 * @return File containing upgrade/reversion history. 676 */ 677 public File getHistoryLogFile() 678 { 679 return new File(getHistoryDirectory(), HISTORY_LOG_FILE_NAME); 680 } 681 682 /** 683 * Gets the directory config/upgrade. 684 * 685 * @return File representing the config/upgrade directory 686 */ 687 public File getConfigurationUpgradeDirectory() 688 { 689 return new File(getConfigurationDirectory(), UPGRADE_PATH); 690 } 691 692 /** 693 * Gets the directory where the upgrader stores files temporarily. 694 * 695 * @return File representing the upgrader's temporary directory 696 */ 697 public File getTemporaryUpgradeDirectory() 698 { 699 return new File(getTemporaryDirectory(), UPGRADE_PATH); 700 } 701 702 /** 703 * Gets the file for invoking a particular command appropriate for the current 704 * operating system. 705 * 706 * @param command 707 * name of the command 708 * @return File representing the command 709 */ 710 public File getCommandFile(String command) 711 { 712 String filename = isWindows() ? command + ".bat" : command; 713 return new File(getBinariesDirectory(), filename); 714 } 715 716 /** 717 * Gets the file responsible for stopping the server appropriate for the 718 * current operating system. 719 * 720 * @return File representing the stop command 721 */ 722 public File getServerStartCommandFile() 723 { 724 return getCommandFile(UNIX_START_FILE_NAME); 725 } 726 727 /** 728 * Gets the file responsible for stopping the server appropriate for the 729 * current operating system. 730 * 731 * @return File representing the stop command 732 */ 733 public File getServerStopCommandFile() 734 { 735 return getCommandFile(UNIX_STOP_FILE_NAME); 736 } 737 738 /** 739 * Returns the setup file name to use with the current operating system. 740 * 741 * @return the setup file name to use with the current operating system. 742 */ 743 public static String getSetupFileName() 744 { 745 return isWindows() ? WINDOWS_SETUP_FILE_NAME : UNIX_SETUP_FILE_NAME; 746 } 747 748 /** 749 * Returns the 'ldif' directory. 750 * 751 * @return the 'ldif' directory. 752 */ 753 public File getLdifDirectory() 754 { 755 return new File(getRootDirectory(), LDIFS_PATH_RELATIVE); 756 } 757 758 /** 759 * Returns the path to the quicksetup jar file. 760 * 761 * @return the path to the quicksetup jar file. 762 */ 763 public File getQuicksetupJarFile() 764 { 765 return new File(getLibrariesDirectory(), "quicksetup.jar"); 766 } 767 768 /** 769 * Returns the path to the opends jar file. 770 * 771 * @return the path to the opends jar file. 772 */ 773 public File getOpenDSJarFile() 774 { 775 return new File(getLibrariesDirectory(), "OpenDJ.jar"); 776 } 777 778 /** 779 * Returns the path to the uninstall.bat file. 780 * 781 * @return the path to the uninstall.bat file. 782 */ 783 public File getUninstallBatFile() 784 { 785 return new File(getRootDirectory(), "uninstall.bat"); 786 } 787 788 /** 789 * Gets the control panel command file appropriate for the current operating 790 * system. 791 * 792 * @return File object representing the control panel command 793 */ 794 public File getControlPanelCommandFile() 795 { 796 if (isMacOS()) 797 { 798 String binDir = getRootDirectory() + File.separator + MAC_APPLICATIONS_PATH_RELATIVE; 799 return new File(binDir, MAC_CONTROLPANEL_FILE_NAME); 800 } 801 return getCommandFile(UNIX_CONTROLPANEL_FILE_NAME); 802 } 803 804 /** 805 * Gets information about the build that was used to produce the bits for this 806 * installation. 807 * 808 * @return BuildInformation object describing this installation 809 * @throws ApplicationException 810 * if there is a problem obtaining the build information 811 */ 812 public BuildInformation getBuildInformation() throws ApplicationException 813 { 814 return getBuildInformation(true); 815 } 816 817 /** 818 * Gets information about the build that was used to produce the bits for this 819 * installation. 820 * 821 * @param useCachedVersion 822 * where true indicates that a potentially cached version of the 823 * build information is acceptable for use; false indicates the the 824 * build information will be created from scratch which is 825 * potentially time consuming 826 * @return BuildInformation object describing this installation 827 * @throws ApplicationException 828 * if there is a problem obtaining the build information 829 */ 830 public BuildInformation getBuildInformation(boolean useCachedVersion) 831 throws ApplicationException 832 { 833 if (buildInformation == null || !useCachedVersion) 834 { 835 FutureTask<BuildInformation> ft = new FutureTask<>( 836 new Callable<BuildInformation>() 837 { 838 @Override 839 public BuildInformation call() throws ApplicationException 840 { 841 return BuildInformation.create(Installation.this); 842 } 843 }); 844 new Thread(ft).start(); 845 try 846 { 847 buildInformation = ft.get(); 848 } 849 catch (InterruptedException e) 850 { 851 logger.info(LocalizableMessage.raw("interrupted trying to get build information", e)); 852 } 853 catch (ExecutionException e) 854 { 855 throw (ApplicationException) e.getCause(); 856 } 857 } 858 return buildInformation; 859 } 860 861 /** 862 * Gets information about the build that was used to produce the instance. 863 * 864 * @return BuildInformation object describing this instance 865 */ 866 public BuildInformation getInstanceBuildInformation() 867 { 868 return getInstanceBuildInformation(true); 869 } 870 871 /** 872 * Gets information about the build that was used to produce the instance. 873 * 874 * @param useCachedVersion 875 * where true indicates that a potentially cached version of the 876 * build information is acceptable for use; false indicates the build 877 * information will be created from scratch which is potentially time 878 * consuming 879 * @return BuildInformation object describing this instance 880 */ 881 private BuildInformation getInstanceBuildInformation(boolean useCachedVersion) 882 { 883 if (instanceInformation == null || !useCachedVersion) 884 { 885 try 886 { 887 File bif = new File(getConfigurationDirectory(), BUILDINFO_RELATIVE_PATH); 888 if (bif.exists()) 889 { 890 // Read the first line and close the file. 891 try (BufferedReader reader = new BufferedReader(new FileReader(bif))) 892 { 893 instanceInformation = BuildInformation.fromBuildString(reader.readLine()); 894 } 895 } 896 else 897 { 898 return getBuildInformation(); 899 } 900 } 901 catch (Exception e) 902 { 903 logger.error(LocalizableMessage.raw("error getting build information for current instance", e)); 904 } 905 } 906 return instanceInformation; 907 } 908}