/* * CDDL HEADER START * * The contents of this file are subject to the terms of the * Common Development and Distribution License, Version 1.0 only * (the "License"). You may not use this file except in compliance * with the License. * * You can obtain a copy of the license at * trunk/opends/resource/legal-notices/OpenDS.LICENSE * or https://OpenDS.dev.java.net/OpenDS.LICENSE. * See the License for the specific language governing permissions * and limitations under the License. * * When distributing Covered Code, include this CDDL HEADER in each * file and include the License file at * trunk/opends/resource/legal-notices/OpenDS.LICENSE. If applicable, * add the following below this CDDL HEADER, with the fields enclosed * by brackets "[]" replaced with your own identifying * information: * Portions Copyright [yyyy] [name of copyright owner] * * CDDL HEADER END * * * Portions Copyright 2006 Sun Microsystems, Inc. */ package org.opends.quicksetup.util; import java.awt.Component; import java.awt.Dimension; import java.awt.Toolkit; import java.awt.Window; import java.io.BufferedOutputStream; import java.io.BufferedWriter; import java.io.File; import java.io.FileOutputStream; import java.io.FileWriter; import java.io.IOException; import java.io.InputStream; import java.io.PrintWriter; import java.io.RandomAccessFile; import java.io.Writer; import java.net.ConnectException; import java.net.InetSocketAddress; import java.net.ServerSocket; import java.net.Socket; import java.util.ArrayList; import java.util.Collection; import java.util.HashSet; import java.util.Hashtable; import java.util.Set; import javax.naming.CommunicationException; import javax.naming.Context; import javax.naming.NamingException; import javax.naming.directory.SearchControls; import javax.naming.ldap.InitialLdapContext; import javax.naming.ldap.LdapName; import javax.swing.JFrame; import javax.swing.JOptionPane; import org.opends.quicksetup.CurrentInstallStatus; import org.opends.quicksetup.i18n.ResourceProvider; import org.opends.quicksetup.installer.webstart.JnlpProperties; /** * This class provides some static convenience methods of different nature. * */ public class Utils { private static final int BUFFER_SIZE = 1024; private static final int MAX_LINE_WIDTH = 80; private static final String[] OPEN_DS_JAR_RELATIVE_PATHS = { "lib/quicksetup.jar", "lib/OpenDS.jar", "lib/je.jar" }; /** * The relative path where all the binaries (scripts) are. */ private static final String BINARIES_PATH_RELATIVE = "bin"; /** * The relative path where all the libraries (jar files) are. */ private static final String LIBRARIES_PATH_RELATIVE = "lib"; /** * The relative path where the database files are. */ private static final String DATABASES_PATH_RELATIVE = "db"; /** * The relative path where the log files are. */ private static final String LOGS_PATH_RELATIVE = "logs"; /** * The relative path where the LDIF files are. */ private static final String LDIFS_PATH_RELATIVE = "ldif"; /** * The relative path where the backup files are. */ private static final String BACKUPS_PATH_RELATIVE = "bak"; /** * The relative path where the config files are. */ private static final String CONFIG_PATH_RELATIVE = "config"; /** * The relative path to the Configuration LDIF file. */ private static final String CONFIG_FILE_PATH_RELATIVE = "config/config.ldif"; private Utils() { } /** * Center the component location based on its preferred size. The code * considers the particular case of 2 screens and puts the component on the * center of the left screen * * @param comp the component to be centered. */ public static void centerOnScreen(Component comp) { Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize(); int width = (int) comp.getPreferredSize().getWidth(); int height = (int) comp.getPreferredSize().getHeight(); boolean multipleScreen = screenSize.width / screenSize.height >= 2; if (multipleScreen) { comp.setLocation((screenSize.width / 4) - (width / 2), (screenSize.height - height) / 2); } else { comp.setLocation((screenSize.width - width) / 2, (screenSize.height - height) / 2); } } /** * Center the component location of the ref component. * * @param comp the component to be centered. * @param ref the component to be used as reference. * */ public static void centerOnComponent(Window comp, Component ref) { comp.setLocationRelativeTo(ref); } /** * Returns true if the provided port is free and we can use it, * false otherwise. * @param port the port we are analyzing. * @return true if the provided port is free and we can use it, * false otherwise. */ public static boolean canUseAsPort(int port) { boolean canUseAsPort = false; ServerSocket serverSocket = null; try { InetSocketAddress socketAddress = new InetSocketAddress(port); serverSocket = new ServerSocket(); if (!isWindows()) { serverSocket.setReuseAddress(true); } serverSocket.bind(socketAddress); canUseAsPort = true; serverSocket.close(); /* Try to create a socket because sometimes even if we can create a server * socket there is already someone listening to the port (is the case * of products as Sun DS 6.0). */ try { new Socket("localhost", port); canUseAsPort = false; } catch (IOException ioe) { } } catch (IOException ex) { canUseAsPort = false; } finally { try { if (serverSocket != null) { serverSocket.close(); } } catch (Exception ex) { } } return canUseAsPort; } /** * Returns true if the provided port is a priviledged port, * false otherwise. * @param port the port we are analyzing. * @return true if the provided port is a priviledged port, * false otherwise. */ public static boolean isPriviledgedPort(int port) { return (port <= 1024) && !isWindows(); } /** * Returns the absolute path for the given parentPath and relativePath. * @param parentPath the parent path. * @param relativePath the relative path. * @return the absolute path for the given parentPath and relativePath. */ public static String getPath(String parentPath, String relativePath) { File f = new File(new File(parentPath), relativePath); try { /* * Do a best effort to avoid having a relative representation (for * instance to avoid having ../../../). */ File canonical = f.getCanonicalFile(); f = canonical; } catch (IOException ioe) { /* This is a best effort to get the best possible representation of the * file: reporting the error is not necessary. */ } return f.toString(); } /** * Returns true if the first provided path is under the second * path in the file system. * @param descendant the descendant candidate path. * @param path the path. * @return true if the first provided path is under the second * path in the file system. */ public static boolean isDescendant(String descendant, String path) { boolean isDescendant = false; File f1; File f2; try { f1 = (new File(path)).getCanonicalFile(); } catch (IOException ioe) { f1 = new File(path); } try { f2 = (new File(descendant)).getCanonicalFile(); } catch (IOException ioe) { f2 = new File(descendant); } f2 = f2.getParentFile(); while ((f2 != null) && !isDescendant) { isDescendant = f1.equals(f2); if (!isDescendant) { f2 = f2.getParentFile(); } } return isDescendant; } /** * Returns true if we are running under windows and * false otherwise. * @return true if we are running under windows and * false otherwise. */ public static boolean isWindows() { return containsOsProperty("windows"); } /** * Returns true if we are running under Mac OS and * false otherwise. * @return true if we are running under Mac OS and * false otherwise. */ public static boolean isMacOS() { return containsOsProperty("mac os"); } /** * Returns true if we are running under Unix and * false otherwise. * @return true if we are running under Unix and * false otherwise. */ public static boolean isUnix() { return !isWindows(); } /** * Returns true if the parent directory for the provided path * exists and false otherwise. * @param path the path that we are analyzing. * @return true if the parent directory for the provided path * exists and false otherwise. */ public static boolean parentDirectoryExists(String path) { boolean parentExists = false; File f = new File(path); if (f != null) { File parentFile = f.getParentFile(); if (parentFile != null) { parentExists = parentFile.isDirectory(); } } return parentExists; } /** * Returns true if the the provided path is a file and exists and * false otherwise. * @param path the path that we are analyzing. * @return true if the the provided path is a file and exists and * false otherwise. */ public static boolean fileExists(String path) { boolean isFile = false; File f = new File(path); if (f != null) { isFile = f.isFile(); } return isFile; } /** * Returns true if the the provided path is a directory, exists * and is not empty false otherwise. * @param path the path that we are analyzing. * @return true if the the provided path is a directory, exists * and is not empty false otherwise. */ public static boolean directoryExistsAndIsNotEmpty(String path) { boolean directoryExistsAndIsNotEmpty = false; boolean isDirectory = false; File f = new File(path); if (f != null) { isDirectory = f.isDirectory(); } if (isDirectory) { String[] ch = f.list(); directoryExistsAndIsNotEmpty = (ch != null) && (ch.length > 0); } return directoryExistsAndIsNotEmpty; } /** * Returns true if the the provided string is a DN and * false otherwise. * @param dn the String we are analyzing. * @return true if the the provided string is a DN and * false otherwise. */ public static boolean isDn(String dn) { boolean isDn = true; try { new LdapName(dn); } catch (Exception ex) { isDn = false; } return isDn; } /** * Returns true if the the provided string is a configuration DN * and false otherwise. * @param dn the String we are analyzing. * @return true if the the provided string is a configuration DN * and false otherwise. */ public static boolean isConfigurationDn(String dn) { boolean isConfigurationDn = false; String[] configDns = { "cn=config", "cn=schema" }; for (int i = 0; i < configDns.length && !isConfigurationDn; i++) { isConfigurationDn = areDnsEqual(dn, configDns[i]); } return isConfigurationDn; } /** * Returns true if the the provided strings represent the same * DN and false otherwise. * @param dn1 the first dn to compare. * @param dn2 the second dn to compare. * @return true if the the provided strings represent the same * DN and false otherwise. */ public static boolean areDnsEqual(String dn1, String dn2) { boolean areDnsEqual = false; try { LdapName name1 = new LdapName(dn1); LdapName name2 = new LdapName(dn2); areDnsEqual = name1.equals(name2); } catch (Exception ex) { } return areDnsEqual; } /** * Creates the parent path for the provided path. * @param path the path. * @return true if the parent path was created or already existed * and false otherwise. */ public static boolean createParentPath(String path) { boolean parentPathExists = true; if (!parentDirectoryExists(path)) { File f = new File(path); if (f != null) { File parentFile = f.getParentFile(); parentPathExists = parentFile.mkdirs(); } } return parentPathExists; } /** * Returns true if we can write on the provided path and * false otherwise. * @param path the path. * @return true if we can write on the provided path and * false otherwise. */ public static boolean canWrite(String path) { boolean canWrite; File file = new File(path); if (file.exists()) { canWrite = file.canWrite(); } else { File parentFile = file.getParentFile(); if (parentFile != null) { canWrite = parentFile.canWrite(); } else { canWrite = false; } } return canWrite; } /** * Creates the a directory in the provided path. * @param path the path. * @return true if the path was created or already existed (and * was a directory) and false otherwise. * @throws IOException if something goes wrong. */ public static boolean createDirectory(String path) throws IOException { boolean directoryCreated; File f = new File(path); if (!f.exists()) { directoryCreated = f.mkdirs(); } else { directoryCreated = f.isDirectory(); } return directoryCreated; } /** * Creates a file on the specified path with the contents of the provided * stream. * @param path the path where the file will be created. * @param is the InputStream with the contents of the file. * @throws IOException if something goes wrong. */ public static void createFile(String path, InputStream is) throws IOException { FileOutputStream out; BufferedOutputStream dest; byte[] data = new byte[BUFFER_SIZE]; int count; out = new FileOutputStream(path); dest = new BufferedOutputStream(out); while ((count = is.read(data, 0, BUFFER_SIZE)) != -1) { dest.write(data, 0, count); } dest.flush(); dest.close(); } /** * Creates a file on the specified path with the contents of the provided * String. * @param path the path where the file will be created. * @param content the String with the contents of the file. * @throws IOException if something goes wrong. */ public static void createFile(String path, String content) throws IOException { FileWriter file = new FileWriter(path); PrintWriter out = new PrintWriter(file); out.println(content); out.flush(); out.close(); } /** * This is a helper method that gets a String representation of the elements * in the Collection. The String will display the different elements separated * by the separator String. * * @param col * the collection containing the String. * @param separator * the separator String to be used. * @return the String representation for the collection. */ public static String getStringFromCollection(Collection col, String separator) { String msg = null; for (String m : col) { if (msg == null) { msg = m; } else { msg += separator + m; } } return msg; } /** * Returns the default server location that will be proposed to the user * in the installation. * @return the default server location that will be proposed to the user * in the installation. */ public static String getDefaultServerLocation() { String userDir = System.getProperty("user.home"); String firstLocation = userDir + File.separator + org.opends.server.util.DynamicConstants.COMPACT_VERSION_STRING; String serverLocation = firstLocation; int i = 1; while (fileExists(serverLocation) || directoryExistsAndIsNotEmpty(serverLocation)) { serverLocation = firstLocation + "-" + i; i++; } return serverLocation; } /** * Returns true if there is more disk space in the provided path * than what is specified with the bytes parameter. * @param directoryPath the path. * @param bytes the disk space. * @return true if there is more disk space in the provided path * than what is specified with the bytes parameter. */ public static synchronized boolean hasEnoughSpace(String directoryPath, long bytes) { // TODO This does not work with quotas etc. but at least it seems that // we do not write all data on disk if it fails. boolean hasEnoughSpace = false; File file = null; RandomAccessFile raf = null; File directory = new File(directoryPath); boolean deleteDirectory = false; if (!directory.exists()) { deleteDirectory = directory.mkdir(); } try { file = File.createTempFile("temp" + System.nanoTime(), ".tmp", directory); raf = new RandomAccessFile(file, "rw"); raf.setLength(bytes); hasEnoughSpace = true; } catch (IOException ex) { } finally { if (raf != null) { try { raf.close(); } catch (IOException ex2) { } } if (file != null) { file.delete(); } } if (deleteDirectory) { directory.delete(); } return hasEnoughSpace; } /** * Returns a localized message for a given properties key an throwable. * @param key the key of the message in the properties file. * @param i18n the ResourceProvider to be used. * @param args the arguments of the message in the properties file. * @param t the throwable for which we want to get a message. * * @return a localized message for a given properties key and throwable. */ public static String getThrowableMsg(ResourceProvider i18n, String key, String[] args, Throwable t) { String msg; if (args != null) { msg = i18n.getMsg(key, args); } else { msg = i18n.getMsg(key); } String detail = t.toString(); if (detail != null) { String[] arg = { detail }; msg = msg + " " + i18n.getMsg("exception-details", arg); } return msg; } /** * Commodity method to help identifying the OS we are running on. * @param s the String that represents an OS. * @return true if there is os java property exists and contains * the value specified in s, false otherwise. */ private static boolean containsOsProperty(String s) { boolean containsOsProperty = false; String osName = System.getProperty("os.name"); if (osName != null) { containsOsProperty = osName.toLowerCase().indexOf(s) != -1; } return containsOsProperty; } /** * Sets the permissions of the provided paths with the provided permission * String. * @param paths the paths to set permissions on. * @param permissions the UNIX-mode file system permission representation * (for example "644" or "755") * @return the return code of the chmod command. * @throws IOException if something goes wrong. * @throws InterruptedException if the Runtime.exec method is interrupted. */ public static int setPermissionsUnix(ArrayList paths, String permissions) throws IOException, InterruptedException { String[] args = new String[paths.size() + 2]; args[0] = "chmod"; args[1] = permissions; for (int i = 2; i < args.length; i++) { args[i] = paths.get(i - 2); } Process p = Runtime.getRuntime().exec(args); return p.waitFor(); } // Very limited for the moment: apply only permissions to the current user and // does not work in non-English environments... to work in non English we // should use xcalcs but it does not come in the windows default install... // :-( // This method is not called for the moment, but the code works, so that is // why // is kept. private static int changePermissionsWindows(String path, String unixPerm) throws IOException, InterruptedException { String windowsPerm; int i = Integer.parseInt(unixPerm.substring(0, 1)); if (Integer.lowestOneBit(i) == 1) { // Executable: give full permissions windowsPerm = "F"; } else if (Integer.highestOneBit(i) == 4) { // Writable windowsPerm = "W"; } else if (Integer.highestOneBit(i) == 2) { // Readable windowsPerm = "R"; } else { // No permissions windowsPerm = "N"; } String user = System.getProperty("user.name"); String[] args = { "cacls", path, "/P", user + ":" + windowsPerm }; Process p = Runtime.getRuntime().exec(args); // TODO: This only works in ENGLISH systems!!!!!! p.getOutputStream().write("Y\n".getBytes()); p.getOutputStream().flush(); return p.waitFor(); } /** * Indicates whether we are in a web start installation or not. * * @return true if we are in a web start installation and * false if not. */ public static boolean isWebStart() { return "true".equals(System.getProperty(JnlpProperties.IS_WEBSTART)); } /** * Returns true if this is an uninstallation and * false otherwise. * @return true if this is an uninstallation and * false otherwise. */ public static boolean isUninstall() { return "true".equals(System.getProperty("org.opends.quicksetup.uninstall")); } /** * Returns true if this is executed from command line and * false otherwise. * @return true if this is executed from command line and * false otherwise. */ public static boolean isCli() { return "true".equals(System.getProperty("org.opends.quicksetup.cli")); } /** * Creates a clear LDAP connection and returns the corresponding LdapContext. * This methods uses the specified parameters to create a JNDI environment * hashtable and creates an InitialLdapContext instance. * * @param ldapURL * the target LDAP URL * @param dn * passed as Context.SECURITY_PRINCIPAL if not null * @param pwd * passed as Context.SECURITY_CREDENTIALS if not null * @param timeout * passed as com.sun.jndi.ldap.connect.timeout if > 0 * @param env * null or additional environment properties * * @throws NamingException * the exception thrown when instantiating InitialLdapContext * * @return the created InitialLdapContext. * @see javax.naming.Context * @see javax.naming.ldap.InitialLdapContext */ public static InitialLdapContext createLdapContext(String ldapURL, String dn, String pwd, int timeout, Hashtable env) throws NamingException { if (env != null) { // We clone 'env' so that we can modify it freely env = new Hashtable(env); } else { env = new Hashtable(); } env .put(Context.INITIAL_CONTEXT_FACTORY, "com.sun.jndi.ldap.LdapCtxFactory"); env.put(Context.PROVIDER_URL, ldapURL); if (timeout >= 1) { env.put("com.sun.jndi.ldap.connect.timeout", String.valueOf(timeout)); } if (dn != null) { env.put(Context.SECURITY_PRINCIPAL, dn); } if (pwd != null) { env.put(Context.SECURITY_CREDENTIALS, pwd); } /* Contains the DirContext and the Exception if any */ final Object[] pair = new Object[] { null, null }; final Hashtable fEnv = env; Thread t = new Thread(new Runnable() { public void run() { try { pair[0] = new InitialLdapContext(fEnv, null); } catch (NamingException ne) { pair[1] = ne; } catch (Throwable t) { pair[1] = t; } } }); return getInitialLdapContext(t, pair, timeout); } /** * Method used to know if we can connect as administrator in a server with a * given password and dn. * @param ldapUrl the ldap URL of the server. * @param dn the dn to be used. * @param pwd the password to be used. * @return true if we can connect and read the configuration and * false otherwise. */ public static boolean canConnectAsAdministrativeUser(String ldapUrl, String dn, String pwd) { boolean canConnectAsAdministrativeUser = false; try { InitialLdapContext ctx = Utils.createLdapContext(ldapUrl, dn, pwd, 3000, null); /* * Search for the config to check that it is the directory manager. */ SearchControls searchControls = new SearchControls(); searchControls.setCountLimit(1); searchControls.setSearchScope( SearchControls. OBJECT_SCOPE); searchControls.setReturningAttributes( new String[] {"dn"}); ctx.search("cn=config", "objectclass=*", searchControls); canConnectAsAdministrativeUser = true; } catch (NamingException ne) { // Nothing to do. } catch (Throwable t) { throw new IllegalStateException("Unexpected throwable.", t); } return canConnectAsAdministrativeUser; } /** * Returns the path of the installation of the directory server. Note that * this method assumes that this code is being run locally. * @return the path of the installation of the directory server. */ public static String getInstallPathFromClasspath() { String installPath; /* Get the install path from the Class Path */ String sep = System.getProperty("path.separator"); String[] classPaths = System.getProperty("java.class.path").split(sep); String path = null; for (int i = 0; i < classPaths.length && (path == null); i++) { for (int j = 0; j < OPEN_DS_JAR_RELATIVE_PATHS.length && (path == null); j++) { String normPath = classPaths[i].replace(File.separatorChar, '/'); if (normPath.endsWith(OPEN_DS_JAR_RELATIVE_PATHS[j])) { path = classPaths[i]; } } } File f = new File(path).getAbsoluteFile(); File binariesDir = f.getParentFile(); /* * Do a best effort to avoid having a relative representation (for * instance to avoid having ../../../). */ try { installPath = binariesDir.getParentFile().getCanonicalPath(); } catch (IOException ioe) { // Best effort installPath = binariesDir.getParent(); } return installPath; } /** * Returns the path to the configuration file of the directory server. Note * that this method assumes that this code is being run locally. * @return the path of the configuration file of the directory server. */ public static String getConfigFileFromClasspath() { return getPath(getInstallPathFromClasspath(), CONFIG_FILE_PATH_RELATIVE); } /** * Returns the list of jar files that might be used to execute the code of * the installation and uninstallation. * @return the list of jar files that might be used to execute the code of * the installation and uninstallation. */ public static String[] getOpenDSJarPaths() { return OPEN_DS_JAR_RELATIVE_PATHS; } /** * Returns the relative path of the directory containing the binaries of the * Open DS installation. The path is relative to the installation path. * @return the relative path of the directory containing the binaries of the * Open DS installation. */ public static String getBinariesRelativePath() { return BINARIES_PATH_RELATIVE; } /** * Returns the relative path of the directory containing the libraries of the * Open DS installation. The path is relative to the installation path. * @return the relative path of the directory containing the libraries of the * Open DS installation. */ public static String getLibrariesRelativePath() { return LIBRARIES_PATH_RELATIVE; } /** * Returns the relative path of the directory containing the databases of the * Open DS installation. The path is relative to the installation path. * @return the relative path of the directory containing the databases of the * Open DS installation. */ public static String getDatabasesRelativePath() { return DATABASES_PATH_RELATIVE; } /** * Returns the relative path of the directory containing the logs of the * Open DS installation. The path is relative to the installation path. * @return the relative path of the directory containing the logs of the * Open DS installation. */ public static String getLogsRelativePath() { return LOGS_PATH_RELATIVE; } /** * Returns the relative path of the directory containing the LDIF files of the * Open DS installation. The path is relative to the installation path. * @return the relative path of the directory containing the LDIF files of the * Open DS installation. */ public static String getLDIFsRelativePath() { return LDIFS_PATH_RELATIVE; } /** * Returns the relative path of the directory containing the backup files of * the Open DS installation. The path is relative to the installation path. * @return the relative path of the directory containing the backup files of * the Open DS installation. */ public static String getBackupsRelativePath() { return BACKUPS_PATH_RELATIVE; } /** * Returns the relative path of the directory containing the config files of * the Open DS installation. The path is relative to the installation path. * @return the relative path of the directory containing the config files of * the Open DS installation. */ public static String getConfigRelativePath() { return CONFIG_PATH_RELATIVE; } /** * Displays a confirmation message dialog. * * @param parent * the parent frame of the confirmation dialog. * @param msg * the confirmation message. * @param title * the title of the dialog. * @return true if the user confirms the message, or * false if not. */ public static boolean displayConfirmation(JFrame parent, String msg, String title) { return JOptionPane.YES_OPTION == JOptionPane.showOptionDialog( parent, msg, title, JOptionPane.YES_NO_OPTION, JOptionPane.QUESTION_MESSAGE, null, // don't use a custom // Icon null, // the titles of buttons null); // default button title } /** * Displays an error message dialog. * * @param parent * the parent frame of the error dialog. * @param msg * the error message. * @param title * the title for the dialog. */ public static void displayError(JFrame parent, String msg, String title) { JOptionPane.showMessageDialog(parent, msg, title, JOptionPane.ERROR_MESSAGE); } /** * Displays an information message dialog. * * @param parent * the parent frame of the information dialog. * @param msg * the error message. * @param title * the title for the dialog. */ public static void displayInformationMessage(JFrame parent, String msg, String title) { JOptionPane.showMessageDialog(parent, msg, title, JOptionPane.INFORMATION_MESSAGE); } /** * Returns a Set of relative paths containing the db paths outside the * installation. * @param installStatus the Current Install Status object. * @return a Set of relative paths containing the db paths outside the * installation. */ public static Set getOutsideDbs(CurrentInstallStatus installStatus) { String installPath = getInstallPathFromClasspath(); Set dbs = installStatus.getDatabasePaths(); Set outsideDbs = new HashSet(); for (String relativePath : dbs) { /* The db paths are relative */ String fullDbPath = getPath(installPath, relativePath); if (!isDescendant(fullDbPath, installPath)) { outsideDbs.add(fullDbPath); } } return outsideDbs; } /** * Returns a Set of relative paths containing the log paths outside the * installation. * @param installStatus the Current Install Status object. * @return a Set of relative paths containing the log paths outside the * installation. */ public static Set getOutsideLogs(CurrentInstallStatus installStatus) { String installPath = getInstallPathFromClasspath(); Set logs = installStatus.getLogPaths(); Set outsideLogs = new HashSet(); for (String relativePath : logs) { /* The db paths are relative */ String fullDbPath = getPath(installPath, relativePath); if (!isDescendant(fullDbPath, installPath)) { outsideLogs.add(fullDbPath); } } return outsideLogs; } /** * Returns if the server is running on the given path. * @param serverPath the installation path of the server. * @return true if the server is running and false * otherwise. */ public static boolean isServerRunning(String serverPath) { boolean isServerRunning; if (isWindows()) { String testPath = serverPath+File.separator+ "locks"+File.separator+"server.lock"; File testFile = new File(testPath); boolean canWriteFile = false; Writer output = null; try { //use buffering //FileWriter always assumes default encoding is OK! output = new BufferedWriter( new FileWriter(testFile) ); output.write("test"); output.close(); output = new BufferedWriter( new FileWriter(testFile) ); output.write(""); output.close(); canWriteFile = true; } catch (Throwable t) { } finally { if (output != null) { try { output.close(); } catch (Throwable t) { } } } isServerRunning = !canWriteFile; } else { isServerRunning = fileExists(serverPath+File.separator+ "logs"+File.separator+"server.pid"); } return isServerRunning; } /** * This is just a commodity method used to try to get an InitialLdapContext. * @param t the Thread to be used to create the InitialLdapContext. * @param pair an Object[] array that contains the InitialLdapContext and the * Throwable if any occurred. * @param timeout the timeout. If we do not get to create the connection * before the timeout a CommunicationException will be thrown. * @return the created InitialLdapContext * @throws NamingException if something goes wrong during the creation. */ private static InitialLdapContext getInitialLdapContext(Thread t, Object[] pair, int timeout) throws NamingException { try { if (timeout > 0) { t.start(); t.join(timeout); } else { t.run(); } } catch (InterruptedException x) { // This might happen for problems in sockets // so it does not necessarily imply a bug } boolean throwException = false; if ((timeout > 0) && t.isAlive()) { t.interrupt(); try { t.join(2000); } catch (InterruptedException x) { // This might happen for problems in sockets // so it does not necessarily imply a bug } throwException = true; } if ((pair[0] == null) && (pair[1] == null)) { throwException = true; } if (throwException) { NamingException xx; ConnectException x = new ConnectException("Connection timed out"); xx = new CommunicationException("Connection timed out"); xx.initCause(x); throw xx; } if (pair[1] != null) { if (pair[1] instanceof NamingException) { throw (NamingException) pair[1]; } else if (pair[1] instanceof RuntimeException) { throw (RuntimeException) pair[1]; } else if (pair[1] instanceof Throwable) { throw new IllegalStateException("Unexpected throwable occurred", (Throwable) pair[1]); } } return (InitialLdapContext) pair[0]; } /** * Returns the max size in character of a line to be displayed in the command * line. * @return the max size in character of a line to be displayed in the command * line. */ public static int getCommandLineMaxLineWidth() { return MAX_LINE_WIDTH; } }