| /* |
| * Licensed to the Apache Software Foundation (ASF) under one |
| * or more contributor license agreements. See the NOTICE file |
| * distributed with this work for additional information |
| * regarding copyright ownership. The ASF licenses this file |
| * to you under the Apache License, Version 2.0 (the |
| * "License"); you may not use this file except in compliance |
| * with the License. You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, |
| * software distributed under the License is distributed on an |
| * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY |
| * KIND, either express or implied. See the License for the |
| * specific language governing permissions and limitations |
| * under the License. |
| */ |
| package org.netbeans.modules.glassfish.tooling.utils; |
| |
| import java.io.File; |
| import java.io.FileFilter; |
| import java.io.IOException; |
| import java.lang.reflect.InvocationTargetException; |
| import java.lang.reflect.Method; |
| import java.net.*; |
| import java.util.ArrayList; |
| import java.util.List; |
| import java.util.Map; |
| import java.util.jar.JarFile; |
| import java.util.jar.Manifest; |
| import java.util.logging.Level; |
| import java.util.regex.Matcher; |
| import java.util.regex.Pattern; |
| import javax.xml.bind.DatatypeConverter; |
| import org.netbeans.modules.glassfish.tooling.admin.CommandException; |
| import org.netbeans.modules.glassfish.tooling.data.GlassFishContainer; |
| import org.netbeans.modules.glassfish.tooling.data.GlassFishServer; |
| import org.netbeans.modules.glassfish.tooling.data.GlassFishVersion; |
| import org.netbeans.modules.glassfish.tooling.logging.Logger; |
| |
| /** |
| * Common utilities. |
| * <p/> |
| * @author Vince Kraemer, Tomas Kraus, Peter Benedikovic |
| */ |
| public class ServerUtils { |
| |
| //////////////////////////////////////////////////////////////////////////// |
| // Inner Classes // |
| //////////////////////////////////////////////////////////////////////////// |
| |
| /** |
| * Filtering the set of directories with GlassFish server home subdirectory |
| * shown to the user in file filter. |
| */ |
| public static class GlassFishFilter implements FileFilter { |
| |
| /** |
| * Test whether or not the specified pathname is GlassFish server |
| * subdirectory. |
| * <p/> |
| * @param path Pathname to be tested. |
| * @return Returns <code>true</code> when given <code>File</code> |
| * should be included or <code>false</code> otherwise. |
| */ |
| @Override |
| public boolean accept(final File path) { |
| if (path.isDirectory() && path.canRead()) { |
| File commonUtilJar |
| = getCommonUtilJarInModules(path.getAbsolutePath()); |
| if (commonUtilJar.isFile() && commonUtilJar.canRead()) { |
| return true; |
| } else { |
| return false; |
| } |
| } else { |
| return false; |
| } |
| } |
| |
| } |
| |
| /** |
| * Filtering the set of GlassFish servers using file name pattern. |
| */ |
| private static class VersionFilter implements FileFilter { |
| |
| /** Compiled file name pattern. */ |
| private final Pattern pattern; |
| |
| /** |
| * Creates an instance of GlassFish servers file name pattern filter. |
| * <p/> |
| * @param namePattern GlassFish servers file name pattern. |
| */ |
| public VersionFilter(final String namePattern) { |
| pattern = Pattern.compile(namePattern); |
| } |
| |
| @Override |
| /** |
| * Test whether or not the specified pathname is valid GlassFish server. |
| * <p/> |
| * @param path Pathname to be tested. |
| * @return Returns <code>true</code> when given <code>File</code> |
| * should be included or <code>false</code> otherwise. |
| */ |
| public boolean accept(final File file) { |
| return pattern.matcher(file.getName()).matches(); |
| } |
| |
| } |
| |
| //////////////////////////////////////////////////////////////////////////// |
| // Class attributes // |
| //////////////////////////////////////////////////////////////////////////// |
| |
| /** Logger instance for this class. */ |
| private static final Logger LOGGER = new Logger(ServerUtils.class); |
| |
| /** GlassFish Java VM system environment <code>AS_JAVA</code> variable name. |
| * This value should be equal to system environment <code>JAVA_HOME</code> |
| * value. */ |
| public static final String AS_JAVA_ENV = "AS_JAVA"; |
| |
| /** GlassFish server Java VM root property name. */ |
| public static final String GF_JAVA_ROOT_PROPERTY |
| = "com.sun.aas.javaRoot"; |
| |
| /** GlassFish server home property name. |
| * <p/> |
| * It's value says it is server installation root but in reality it is just |
| * <code>glassfish</code> subdirectory under server installation root which |
| * we usually call server home. */ |
| public static final String GF_HOME_PROPERTY |
| = "com.sun.aas.installRoot"; |
| |
| /** GlassFish server domain root property name. |
| * </p> |
| * It's value says it is server instance root which is the same. */ |
| public static final String GF_DOMAIN_ROOT_PROPERTY |
| = "com.sun.aas.instanceRoot"; |
| |
| /** GlassFish server Derby root property name. */ |
| public static final String GF_DERBY_ROOT_PROPERTY |
| = "com.sun.aas.derbyRoot"; |
| |
| /** GlassFish server home subdirectory filter instance. */ |
| public static final GlassFishFilter GF_HOME_DIR_FILTER |
| = new GlassFishFilter(); |
| |
| /** GlassFish server domains subdirectory. */ |
| public static final String GF_DOMAINS_DIR_NAME = "domains"; |
| |
| /** GlassFish server domains subdirectory. */ |
| public static final String GF_DOMAIN_CONFIG_DIR_NAME = "config"; |
| |
| /** GlassFish server domains subdirectory. */ |
| public static final String GF_DOMAIN_CONFIG_FILE_NAME = "domain.xml"; |
| |
| /** GlassFish server modules subdirectory. */ |
| public static final String GF_MODULES_DIR_NAME = "modules"; |
| |
| /** GlassFish server Derby subdirectory. */ |
| public static final String GF_DERBY_DIR_NAME = "javadb"; |
| |
| /** GlassFish server libraries subdirectory. */ |
| public static final String GF_LIB_DIR_NAME = "lib"; |
| |
| /** GlassFish server embedded libraries subdirectory under libraries. */ |
| public static final String GF_EMBEDDED_DIR_NAME = "embedded"; |
| |
| /** GlassFish server logs subdirectory. */ |
| public static String GF_LOG_DIR_NAME = "logs"; |
| |
| /** GlassFish server log file. */ |
| public static String GF_LOG_FILE_NAME = "server.log"; |
| |
| public static final String GFV3_VERSION_MATCHER |
| = "(?:-[0-9bSNAPHOT]+(?:\\.[0-9]+(?:_[0-9]+|)|).*|).jar"; |
| public static final String GFV3_JAR_MATCHER |
| = "glassfish" + GFV3_VERSION_MATCHER; |
| |
| /** Manifest attribute Bundle-Version containing GlassFish |
| * version <code>String</code>. */ |
| public static final String BUNDLE_VERSION = "Bundle-Version"; |
| |
| /** Common utilities JAR file name. */ |
| public static final String GF_COMMON_UTIL_JAR = "common-util.jar"; |
| |
| /** Jersey 2.x common JAR file name. */ |
| public static final String GF_JERSEY_2_COMMON_JAR = "jersey-common.jar"; |
| |
| /** Jersey 1.x core JAR file name. */ |
| public static final String GF_JERSEY_1_CORE_JAR = "jersey-core.jar"; |
| |
| /** Embedded static shell JAR file name. */ |
| public static final String GF_EMBEDDED_STATIC_SHELL_JAR |
| = "glassfish-embedded-static-shell.jar"; |
| |
| /** Verifier JAR file name. */ |
| public static final String GF_VERIFIER_JAR = "verifier.jar"; |
| |
| /** JavaHelp JAR file name. */ |
| public static final String GF_JAVAHELP_JAR = "javahelp.jar"; |
| |
| /** GlassFish Version class name (including package). */ |
| private static String VERSION_CLASS = "com.sun.appserv.server.util.Version"; |
| |
| /** GlassFish VerifierMain class name (including package). */ |
| public static String VERIFIER_MAIN_CLASS |
| = "com.sun.enterprise.tools.verifier.VerifierMain"; |
| |
| /** Regex pattern to retrieve version string like 3.1.2.2 from |
| * full version string. */ |
| private static String FULL_VERSION_PATTERN = "[0-9]+(\\.[0-9]+){1,3}"; |
| |
| /** GlassFish full version string getter method name. */ |
| private static String FULL_VERSION_METHOD = "getFullVersion"; |
| |
| /** GlassFish Basic Authorization user and password separator. */ |
| private static String AUTH_BASIC_FIELD_SEPARATPR = ":"; |
| |
| /** GlassFish server domain name command line argument. */ |
| public static String GF_DOMAIN_ARG = "--domain"; |
| |
| /** GlassFish server domain directory command line argument. */ |
| public static String GF_DOMAIN_DIR_ARG = "--domaindir"; |
| |
| /** GlassFish server service response while server is not yet ready. |
| * Copy-pasted from |
| * <code>com.sun.enterprise.v3.admin.AdminAdapter</code>. */ |
| public static final String GF_SERVICE_NOT_YET_READY_MSG |
| = "V3 cannot process this command at this time, please wait"; |
| /** End of line sequence in Manifest. */ |
| public static final String MANIFEST_EOL = "%%%EOL%%%"; |
| |
| /** REGEX expression used to split resources returned in |
| * <code>Manifest</code> object from HTTP response. */ |
| public static final String MANIFEST_RESOURCES_SEPARATOR = "[,;]"; |
| |
| /** REGEX expression used to split components (applications) returned in |
| * <code>Manifest</code> object from HTTP response. */ |
| public static final String MANIFEST_COMPONENTS_SEPARATOR = ";"; |
| |
| /** REGEX expression used to extract component name and containers from |
| * <code>Manifest</code> attribute. */ |
| private static final String MANIFEST_COMPONENT_FULL_REGEX |
| = " *([^ ]+) +< *([^ ,]+) *((?:, *[^ ,]+ *)*)> *"; |
| |
| /** REGEX expression used to extract additional containers from containers |
| * list of <code>Manifest</code> attribute. */ |
| private static final String MANIFEST_COMPONENT_COMP_REGEX = ", *([^ ,]+) *"; |
| |
| /** REGEX pattern used to extract component name and containers from |
| * <code>Manifest</code> attribute. */ |
| private static final Pattern MANIFEST_COMPONENT_FULL_PATTERN |
| = Pattern.compile(MANIFEST_COMPONENT_FULL_REGEX, |
| Pattern.CASE_INSENSITIVE); |
| |
| /** REGEX pattern used to extract additional containers from containers |
| * list of <code>Manifest</code> attribute. */ |
| private static final Pattern MANIFEST_COMPONENT_COMP_PATTERN |
| = Pattern.compile(MANIFEST_COMPONENT_COMP_REGEX, |
| Pattern.CASE_INSENSITIVE); |
| |
| //////////////////////////////////////////////////////////////////////////// |
| // Static methods // |
| //////////////////////////////////////////////////////////////////////////// |
| |
| /** |
| * Search for <code>.jar</code> file matching given pattern |
| * in <code><serverHome>/modules</code> directory tree. |
| * <p/> |
| * @param serverHome GlassFish server home. |
| * @param pattern File name pattern. |
| * @return <code>File</code> object containing full <code>.jar<code> file |
| * path or <code>null</code> if no file was found. |
| */ |
| public static File getJarName(final String serverHome, |
| final String pattern) { |
| return getJarName(serverHome, pattern, GF_MODULES_DIR_NAME); |
| } |
| |
| /** |
| * Search for <code>.jar</code> file matching given pattern |
| * in given directory tree. |
| * <p/> |
| * @param serverHome GlassFish server home. |
| * @param pattern File name pattern. |
| * @param dir Directory tree root to be searched for |
| * <code>.jar<code> file. |
| * @return <code>File</code> object containing full <code>.jar<code> file |
| * path or <code>null</code> if no file was found. |
| */ |
| public static File getJarName(final String serverHome, final String pattern, |
| final String dir) { |
| File dirFile = new File(serverHome + File.separatorChar + dir); |
| return getFileFromPattern(pattern, dirFile); |
| } |
| |
| /** |
| * Search for file matching given <code>pattern</code> in given |
| * <code>dir</code>ectory tree. |
| * <p/> |
| * @param pattern Name pattern to search for. |
| * @param dir Directory tree root to be searched for pattern. |
| * @return <code>File</code> object that matches given <code>pattern</code> |
| * or <code>null</code> otherwise. |
| */ |
| public static File getFileFromPattern(String pattern, File dir) { |
| assert pattern != null : "Search pattern should not be null"; |
| assert dir != null : "Search directory tree root should not be null"; |
| // TODO: Check if this is OK of File.pathSeparator should be used. |
| int subindex = pattern.lastIndexOf("/"); |
| if (subindex != -1) { |
| String subdir = pattern.substring(0, subindex); |
| pattern = pattern.substring(subindex + 1); |
| dir = new File(dir, subdir); |
| } |
| if (dir.canRead() && dir.isDirectory()) { |
| // Express check first. |
| String expressPattern = pattern.replace(GFV3_VERSION_MATCHER, |
| ".jar"); |
| File candidate = new File(dir, expressPattern); |
| if (!"".equals(expressPattern) && candidate.exists()) { |
| return candidate; |
| } |
| // Longer check second. |
| File[] candidates = dir.listFiles(new VersionFilter(pattern)); |
| if (candidates != null && candidates.length > 0) { |
| // First one is returned. |
| return candidates[0]; |
| } |
| } |
| return null; |
| } |
| |
| /** |
| * Append next path element to existing path in <code>StringBuilder</code>. |
| * Path separator is added only when there is no one at the end of existing |
| * path. |
| * <p/> |
| * @param rootPath Already existing path in <code>StringBuilder</code>. |
| * @param next Path to be appended at the end of already existing path. |
| */ |
| public static void addPathElement(final StringBuilder rootPath, |
| final String next) { |
| int rootPathLength = rootPath.length(); |
| if (rootPathLength > 0 && rootPath.lastIndexOf(File.separator) |
| + OsUtils.FILE_SEPARATOR_LENGTH != rootPathLength) { |
| rootPath.append(File.separator); |
| } |
| rootPath.append(next); |
| } |
| |
| /** |
| * Build path to the <code>common-util.jar</code> file in GlassFish modules |
| * directory. |
| * <p/> |
| * @param serverHome GlassFish server home directory. |
| * @return Path to the <code>common-util.jar</code> file in GlassFish |
| * modules directory. |
| */ |
| public static File getCommonUtilJarInModules(final String serverHome) { |
| StringBuilder commonUtilJarPath = new StringBuilder(serverHome.length() |
| + GF_MODULES_DIR_NAME.length() + GF_COMMON_UTIL_JAR.length() |
| + 2 * OsUtils.FILE_SEPARATOR_LENGTH); |
| commonUtilJarPath.append(serverHome); |
| addPathElement(commonUtilJarPath, GF_MODULES_DIR_NAME); |
| addPathElement(commonUtilJarPath, GF_COMMON_UTIL_JAR); |
| return new File(commonUtilJarPath.toString()); |
| } |
| |
| /** |
| * Build path to the supplied <code>.jar</code> file in GlassFish |
| * modules directory. |
| * <p/> |
| * @param serverHome GlassFish server home directory. This argument |
| * should not be <code>null</code>. |
| * @param jarName Supplied JAR file name. This argument should not |
| * be <code>null</code>. |
| * @return Path to the <code>.jar</code> file in GlassFish |
| * modules directory. |
| */ |
| public static File getJarInModules(final String serverHome, |
| final String jarName) { |
| StringBuilder commonUtilJarPath = new StringBuilder(serverHome.length() |
| + GF_MODULES_DIR_NAME.length() + jarName.length() |
| + 2 * OsUtils.FILE_SEPARATOR_LENGTH); |
| commonUtilJarPath.append(serverHome); |
| addPathElement(commonUtilJarPath, GF_MODULES_DIR_NAME); |
| addPathElement(commonUtilJarPath, jarName); |
| return new File(commonUtilJarPath.toString()); |
| } |
| |
| /** |
| * Build path to the <code>jersey-common.jar</code> or |
| * <code>jersey-core.jar</code> file in GlassFish modules directory. |
| * <p/> |
| * Searches for Jersey 1.x or 2.x common (core) jersey JAR file name |
| * in GlassFish modules directory and returns <code>File</code> that was |
| * found or <code>null</code> when no such a file exists and is readable. |
| * <p/> |
| * @param serverHome GlassFish server home directory. This argument |
| * should not be <code>null</code>. |
| */ |
| public static File getJerseyCommonJarInModules(final String serverHome) { |
| File jerseyCommon = ServerUtils.getJarInModules( |
| serverHome, ServerUtils.GF_JERSEY_2_COMMON_JAR); |
| if (jerseyCommon.isFile() && jerseyCommon.canRead()) { |
| return jerseyCommon; |
| } |
| jerseyCommon = ServerUtils.getJarInModules( |
| serverHome, ServerUtils.GF_JERSEY_1_CORE_JAR); |
| if (jerseyCommon.isFile() && jerseyCommon.canRead()) { |
| return jerseyCommon; |
| } else { |
| return null; |
| } |
| } |
| |
| /** |
| * Build path to the supplied <code>verifier.jar</code> library in GlassFish |
| * modules directory. |
| * <p/> |
| * @param serverHome GlassFish server home directory. This argument |
| * should not be <code>null</code>. |
| * @return Path to the <code>verifier.ja</code> file in GlassFish |
| * modules directory. |
| */ |
| public static String getVerifierJar(final String serverHome) { |
| assert serverHome != null |
| : "GlassFish server home directory should not be null"; |
| boolean appendSeparator = serverHome.lastIndexOf(File.separator) |
| + OsUtils.FILE_SEPARATOR_LENGTH != serverHome.length(); |
| StringBuilder sb = new StringBuilder(serverHome.length() |
| + (appendSeparator ? 2 * OsUtils.FILE_SEPARATOR_LENGTH |
| : 1 * OsUtils.FILE_SEPARATOR_LENGTH) |
| + GF_MODULES_DIR_NAME.length() + GF_VERIFIER_JAR.length()); |
| sb.append(serverHome); |
| if (appendSeparator) { |
| sb.append(File.separator); |
| } |
| sb.append(GF_MODULES_DIR_NAME); |
| sb.append(File.separator); |
| sb.append(GF_VERIFIER_JAR); |
| return sb.toString(); |
| } |
| |
| /** |
| * Build path to the supplied <code>javahelp.jar</code> library in GlassFish |
| * modules directory. |
| * <p/> |
| * @param serverHome GlassFish server home directory. This argument |
| * should not be <code>null</code>. |
| * @return Path to the <code>javahelp.jar</code> file in GlassFish |
| * libraries directory. |
| */ |
| public static String getJavaHelpJar(final String serverHome) { |
| assert serverHome != null |
| : "GlassFish server home directory should not be null"; |
| boolean appendSeparator = serverHome.lastIndexOf(File.separator) |
| + OsUtils.FILE_SEPARATOR_LENGTH != serverHome.length(); |
| StringBuilder sb = new StringBuilder(serverHome.length() |
| + (appendSeparator ? 2 * OsUtils.FILE_SEPARATOR_LENGTH |
| : 1 * OsUtils.FILE_SEPARATOR_LENGTH) |
| + GF_LIB_DIR_NAME.length() + GF_JAVAHELP_JAR.length()); |
| sb.append(serverHome); |
| if (appendSeparator) { |
| sb.append(File.separator); |
| } |
| sb.append(GF_LIB_DIR_NAME); |
| sb.append(File.separator); |
| sb.append(GF_JAVAHELP_JAR); |
| return sb.toString(); |
| } |
| |
| /** |
| * Build path to the <code>glassfish-embedded-static-shell.jar</code> |
| * library in embedded libraries directory. |
| * <p/> |
| * @param serverHome GlassFish server home directory. This argument |
| * should not be <code>null</code>. |
| * @return Path to the <code>glassfish-embedded-static-shell.jar</code> |
| * file in GlassFish embedded libraries directory. |
| */ |
| public static String getEmbeddedStaticShellJar(final String serverHome) { |
| assert serverHome != null |
| : "GlassFish server home directory should not be null"; |
| boolean appendSeparator = serverHome.lastIndexOf(File.separator) |
| + OsUtils.FILE_SEPARATOR_LENGTH != serverHome.length(); |
| StringBuilder sb = new StringBuilder(serverHome.length() |
| + (appendSeparator ? 3 * OsUtils.FILE_SEPARATOR_LENGTH |
| : 2 * OsUtils.FILE_SEPARATOR_LENGTH) |
| + GF_LIB_DIR_NAME.length() + GF_EMBEDDED_DIR_NAME.length() |
| + GF_EMBEDDED_STATIC_SHELL_JAR.length()); |
| sb.append(serverHome); |
| if (appendSeparator) { |
| sb.append(File.separator); |
| } |
| sb.append(GF_LIB_DIR_NAME); |
| sb.append(File.separator); |
| sb.append(GF_EMBEDDED_DIR_NAME); |
| sb.append(File.separator); |
| sb.append(GF_EMBEDDED_STATIC_SHELL_JAR); |
| return sb.toString(); |
| } |
| |
| /** |
| * Retrieve Jersey version string from GlassFish modules. |
| * <p/> |
| * @param serverHome GlassFish server home directory. This argument |
| * should not be <code>null</code>. |
| * @return Jersey version string from GlassFish modules. |
| */ |
| public static String getJerseyVersion(final String serverHome) { |
| File jerseyFile = ServerUtils.getJerseyCommonJarInModules(serverHome); |
| if (jerseyFile != null) { |
| Jar jerseyJar = new Jar(jerseyFile); |
| String version = jerseyJar.getBundleVersion(); |
| jerseyJar.close(); |
| return version; |
| } else { |
| return null; |
| } |
| } |
| |
| /** |
| * Retrieve version numbers substring from full version string. |
| * <p/> |
| * @param fullVersionString GlassFish server full version string, e.g. |
| * <code>GlassFish Server Open Source Edition |
| * 3.1.2.2 (build 5)</code> |
| * @return Version numbers substring, e.g. <code>3.1.2.2</code> |
| */ |
| public static String getVersionString(final String fullVersionString) { |
| if (fullVersionString != null) { |
| Pattern p = Pattern.compile(FULL_VERSION_PATTERN); |
| Matcher m = p.matcher(fullVersionString); |
| if (m.find()) { |
| return fullVersionString.substring(m.start(), m.end()); |
| } |
| } |
| return null; |
| } |
| |
| /** |
| * Retrieve GlassFish version from local installation using file access. |
| * <p/> |
| * GlassFish version is read from modules <code>common-util.jar</code> |
| * archive and <code>com.sun.appserv.server.util.Version</code> class. |
| * It's not public GlassFish API so there is no guaranty for this to work |
| * forever. However GlassFish development team promised to keep this |
| * API working the same way in GlassFish 3 and 4. |
| * <p/> |
| * @param serverHome GlassFish server home directory. |
| * @return GlassFish server version. |
| */ |
| public static GlassFishVersion getServerVersion(final String serverHome) { |
| GlassFishVersion version = null; |
| File commonUtilJar = getCommonUtilJarInModules(serverHome); |
| if (commonUtilJar.canRead()) { |
| try { |
| ClassLoader cl = new URLClassLoader(new URL[] {commonUtilJar. |
| toURI().toURL()}); |
| Class c = cl.loadClass(VERSION_CLASS); |
| // Try to get version from com.sun.appserv.server.util.Version. |
| try { |
| Method mGetFullVersion = c.getMethod(FULL_VERSION_METHOD); |
| System.getProperties().put(GF_HOME_PROPERTY, serverHome); |
| String fullVersionString |
| = (String)mGetFullVersion.invoke(c); |
| System.getProperties().remove(GF_HOME_PROPERTY); |
| String versionString |
| = getVersionString(fullVersionString); |
| if (versionString != null) { |
| version = GlassFishVersion.toValue(versionString); |
| } |
| } catch (IllegalAccessException | IllegalArgumentException |
| | InvocationTargetException | NoSuchMethodException |
| | SecurityException | NoClassDefFoundError ex) { |
| Logger.log(Level.WARNING, "Cannot retrieve Glassfish version: " |
| + commonUtilJar.getAbsolutePath() + ": ", ex); |
| } |
| // Use Manifest Bundle-Version as fallback option. |
| if (version == null) { |
| try { |
| JarFile jar = new JarFile(commonUtilJar); |
| Manifest manifest = jar.getManifest(); |
| String versionString = getVersionString(manifest |
| .getMainAttributes().getValue(BUNDLE_VERSION)); |
| if (versionString != null) { |
| version = GlassFishVersion.toValue(versionString); |
| } |
| } catch (IOException ioe) { |
| Logger.log(Level.WARNING, "Cannot retrieve Glassfish version: " |
| + commonUtilJar.getAbsolutePath() + ": ", ioe); |
| } |
| } |
| } catch (MalformedURLException | ClassNotFoundException ex) { |
| Logger.log(Level.WARNING, "Cannot retrieve Glassfish version: " |
| + commonUtilJar.getAbsolutePath() + ": ", ex); |
| } |
| } else { |
| Logger.log(Level.WARNING, "Cannot retrieve Glassfish version: " |
| + commonUtilJar.getAbsolutePath() + " is not readable:" |
| + " Exists: " + commonUtilJar.exists() |
| + " Can read: " + commonUtilJar.canRead(), (Throwable) null); |
| } |
| return version; |
| } |
| |
| /** |
| * Decode <code>Manifest</code> string to remove EOL sequences. |
| * <p/> |
| * @param str String to be decoded. |
| */ |
| public static String manifestDecode(final String str) { |
| if (str == null) { |
| return null; |
| } |
| return str.replaceAll(MANIFEST_EOL, "\n"); |
| } |
| |
| /** |
| * Build HTTP Basic authorization base64 encoded credentials argument |
| * containing user name and password. |
| * <p/> |
| * @param user Username to be stored into encoded argument. |
| * @param password Password to be stored into encoded argument. |
| */ |
| public static String basicAuthCredentials(final String user, |
| final String password) { |
| StringBuilder sb = new StringBuilder(user.length() |
| + AUTH_BASIC_FIELD_SEPARATPR.length() + password.length()); |
| sb.append(user); |
| sb.append(AUTH_BASIC_FIELD_SEPARATPR); |
| sb.append(password); |
| return DatatypeConverter.printBase64Binary(sb.toString().getBytes()); |
| } |
| |
| /** |
| * Tests if the server listener port is occupied. |
| * <p/> |
| * @param server GlassFish server entity |
| * @return Value of <code>true</code> when server listener port |
| * is occupied or <code>false</code> otherwise. |
| */ |
| public static boolean isHttpPortListening(final GlassFishServer server) { |
| return server.isRemote() |
| ? NetUtils.isPortListeningRemote( |
| server.getHost(), server.getPort()) |
| : NetUtils.isPortListeningLocal( |
| server.getHost(), server.getPort()); |
| } |
| |
| /** |
| * Tests if the server listener port is occupied. |
| * <p/> |
| * @param server GlassFish server entity |
| * @param timeout Network timeout [ms]. |
| * @return Value of <code>true</code> when server listener port |
| * is occupied or <code>false</code> otherwise. |
| */ |
| public static boolean isHttpPortListening(final GlassFishServer server, |
| final int timeout) { |
| return server.isRemote() |
| ? NetUtils.isPortListeningRemote( |
| server.getHost(), server.getPort(), timeout) |
| : NetUtils.isPortListeningLocal( |
| server.getHost(), server.getPort()); |
| } |
| |
| /** |
| * Tests if the server administrator's port is occupied. |
| * <p/> |
| * @param server GlassFish server entity. |
| * @return Value of <code>true</code> when server administrator port |
| * is occupied or <code>false</code> otherwise. |
| */ |
| public static boolean isAdminPortListening(final GlassFishServer server) { |
| return server.isRemote() |
| ? NetUtils.isPortListeningRemote( |
| server.getHost(), server.getAdminPort()) |
| : NetUtils.isPortListeningLocal( |
| server.getHost(), server.getAdminPort()); |
| } |
| |
| /** |
| * Tests if the server administrator's port is occupied. |
| * <p/> |
| * @param server GlassFish server entity. |
| * @param timeout Network timeout [ms]. |
| * @return Value of <code>true</code> when server administrator port |
| * is occupied or <code>false</code> otherwise. |
| */ |
| public static boolean isAdminPortListening(final GlassFishServer server, |
| final int timeout) { |
| return server.isRemote() |
| ? NetUtils.isPortListeningRemote( |
| server.getHost(), server.getAdminPort(), timeout) |
| : NetUtils.isPortListeningLocal( |
| server.getHost(), server.getAdminPort()); |
| } |
| |
| /** |
| * Builds command line argument containing argument identifier, space |
| * and argument value, e.g. <code>--name value</code>. |
| * <p/> |
| * @param name Command line argument name including dashes at |
| * the beginning. |
| * @param value Value to be appended prefixed with single space. |
| * @return Command line argument concatenated together. |
| */ |
| public static String cmdLineArgument(final String name, |
| final String value) { |
| StringBuilder sb = new StringBuilder(name.length() + " ".length() |
| + value.length()); |
| sb.append(name); |
| sb.append(" "); |
| sb.append(value); |
| return sb.toString(); |
| } |
| |
| /** |
| * Parse server component (application) record and add it into |
| * <code>Map</code> containing container to components <code>List</code> |
| * mapping. |
| * <p/> |
| * Component records: <code><name> '<' <container> |
| * [',' <container>] '>'</code> |
| * </p> |
| * @param map Map where new component is stored under it's container key. |
| * @param component Component record retrieved from server. |
| * @throws <code>NullPointerException</code> when provided map argument |
| * is <code>null</code>. |
| */ |
| public static void addComponentToMap(final Map<String, List<String>> map, |
| final String component) { |
| Logger.log(Level.FINER, "Processing component \"{0}\"", |
| new Object[]{component}); |
| Matcher fullMatecher = ServerUtils.MANIFEST_COMPONENT_FULL_PATTERN |
| .matcher(component); |
| if (fullMatecher.matches()) { |
| String componentName = fullMatecher.group(1); |
| GlassFishContainer container = GlassFishContainer.toValue( |
| fullMatecher.group(2)); |
| String moreContainers = fullMatecher.group(3); |
| if (moreContainers != null && moreContainers.length() > 0) { |
| Matcher compMatcher = ServerUtils |
| .MANIFEST_COMPONENT_COMP_PATTERN.matcher( |
| moreContainers); |
| while (compMatcher.find()) { |
| GlassFishContainer nextContainer = GlassFishContainer |
| .toValue(compMatcher.group(1)); |
| if (nextContainer != null && container != null |
| && nextContainer.ordinal() < container.ordinal()) { |
| container = nextContainer; |
| } else if (nextContainer == null) { |
| Logger.log(Level.WARNING, |
| "Error processing component \"{0}\"", |
| new Object[]{component}); |
| } |
| } |
| } |
| String containerName = container != null |
| ? container.toString() : "null"; |
| List<String> componentList = map.get(containerName); |
| if (componentList == null) { |
| componentList = new ArrayList<>(); |
| map.put(containerName, componentList); |
| } |
| componentList.add(componentName); |
| } else { |
| throw new CommandException( |
| CommandException.MANIFEST_INVALID_COMPONENT_ITEM); |
| } |
| } |
| |
| /** |
| * Build GlassFish server log file sub path under domains root directory. |
| * <p/> |
| * @return GlassFish server log file path under domains root directory. |
| */ |
| public static String serverLogFileRelativePath() { |
| StringBuilder sb = new StringBuilder(GF_LOG_DIR_NAME.length() |
| + File.separator.length() + GF_LOG_FILE_NAME.length()); |
| sb.append(GF_LOG_DIR_NAME); |
| sb.append(File.separator); |
| sb.append(GF_LOG_FILE_NAME); |
| return sb.toString(); |
| } |
| |
| /** |
| * Get GlassFish server domain root full path. |
| * <p/> |
| * @param server GlassFish server entity |
| * @return GlassFish server domain root full path or <code>null</code> |
| * when server domains root folder or domain name is not set. |
| */ |
| public static String getDomainPath(final GlassFishServer server) { |
| String domainName = server.getDomainName(); |
| String domainsFolder = server.getDomainsFolder(); |
| boolean appendSeparator = domainsFolder.lastIndexOf(File.separator) |
| + OsUtils.FILE_SEPARATOR_LENGTH != domainsFolder.length(); |
| StringBuilder sb = new StringBuilder(server.getDomainsFolder().length() |
| + (appendSeparator ? OsUtils.FILE_SEPARATOR_LENGTH : 0) |
| + domainName.length()); |
| sb.append(domainsFolder); |
| if (appendSeparator) { |
| sb.append(File.separator); |
| } |
| sb.append(domainName); |
| return sb.toString(); |
| } |
| |
| /** |
| * Get GlassFish server domain configuration directory full path from |
| * domain root. |
| * <p/> |
| * @param domainDir GlassFish server domain root full path. |
| * @return GlassFish server domain configuration directory full path |
| */ |
| public static String getDomainConfigPath(final String domainDir) { |
| if (domainDir == null) { |
| return GF_DOMAIN_CONFIG_DIR_NAME; |
| } |
| boolean appendSeparator = domainDir.lastIndexOf(File.separator) |
| + OsUtils.FILE_SEPARATOR_LENGTH != domainDir.length(); |
| StringBuilder sb = new StringBuilder(domainDir.length() |
| + (appendSeparator ? OsUtils.FILE_SEPARATOR_LENGTH : 0) |
| + GF_DOMAIN_CONFIG_DIR_NAME.length()); |
| sb.append(domainDir); |
| if (appendSeparator) { |
| sb.append(File.separator); |
| } |
| sb.append(GF_DOMAIN_CONFIG_DIR_NAME); |
| return sb.toString(); |
| } |
| |
| /** |
| * Get GlassFish server domain configuration file (domain.xml) full path |
| * from domains root and domain name. |
| * <p/> |
| * @param domainsRoot GlassFish server domains root full path. |
| * @param domainName GlassFish server domain name. |
| * @return GlassFish server domain configuration file full path |
| */ |
| public static String getDomainConfigFile(final String domainsRoot, |
| final String domainName) { |
| final String METHOD = "getDomainConfigFile"; |
| if (domainsRoot == null) { |
| throw new IllegalArgumentException( |
| LOGGER.excMsg(METHOD, "domainsRootNull")); |
| } |
| if (domainName == null) { |
| throw new IllegalArgumentException( |
| LOGGER.excMsg(METHOD, "domainNameNull")); |
| } |
| StringBuilder sb = new StringBuilder(domainsRoot.length() |
| + domainName.length() + GF_DOMAIN_CONFIG_DIR_NAME.length() |
| + GF_DOMAIN_CONFIG_FILE_NAME.length() |
| + (3 * OsUtils.FILE_SEPARATOR_LENGTH)); |
| sb.append(domainsRoot).append(File.separator); |
| sb.append(domainName).append(File.separator); |
| sb.append(GF_DOMAIN_CONFIG_DIR_NAME).append(File.separator); |
| sb.append(GF_DOMAIN_CONFIG_FILE_NAME); |
| return sb.toString(); |
| } |
| |
| /** |
| * Get GlassFish server log {@link File} object. |
| * <p/> |
| * @param server GlassFish server entity. |
| * @return GlassFish server log {@link File} object. |
| */ |
| public static File getServerLogFile(final GlassFishServer server) { |
| return new File(getDomainPath(server), |
| serverLogFileRelativePath()); |
| } |
| |
| /** |
| * Get GlassFish server derby root full path. |
| * <p/> |
| * @param server GlassFish server entity |
| * @return GlassFish server derby root full path or <code>null</code> |
| * when server server installation directory is not set. |
| */ |
| public static String getDerbyRoot(final GlassFishServer server) { |
| String serverRoot = server.getServerRoot(); |
| if (serverRoot == null) { |
| return null; |
| } |
| StringBuilder sb = new StringBuilder(serverRoot.length() |
| + File.separator.length() + GF_DERBY_DIR_NAME.length()); |
| sb.append(serverRoot); |
| sb.append(File.separator); |
| sb.append(GF_DERBY_DIR_NAME); |
| return sb.toString(); |
| } |
| |
| /** |
| * Get GlassFish server Java VM root property. |
| * <p/> |
| * @param javaHome Java VM root (home) directory to be set as property |
| * value. |
| * @return GlassFish server Java VM root property to be passed to server |
| * startup command. |
| */ |
| public static String javaRootProperty(final String javaHome) { |
| return JavaUtils.systemProperty(GF_JAVA_ROOT_PROPERTY, javaHome); |
| } |
| |
| /** |
| * Check if given message is the one returned by GlassFish server service |
| * response while server is not yet ready. |
| * <p/> |
| * @param msg Message to be checked. |
| * @return Returns <code>true</code> if given message is server service |
| * response while server is not yet ready or <code>false</code> |
| * otherwise. |
| */ |
| public static boolean notYetReadyMsg(final String msg) { |
| if (msg == null) { |
| return false; |
| } |
| return msg.startsWith(GF_SERVICE_NOT_YET_READY_MSG); |
| } |
| |
| } |