blob: 72dff386d7a4dbbd657c1704a8a35b9be490f2c9 [file] [log] [blame]
/*
* 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>&lt;serverHome&gt;/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>&lt;name&gt; '&lt;' &lt;container&gt;
* [',' &lt;container&gt;] '&gt;'</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);
}
}