com.edugility.h2.maven.plugin.AbstractH2Mojo.java Source code

Java tutorial

Introduction

Here is the source code for com.edugility.h2.maven.plugin.AbstractH2Mojo.java

Source

/* -*- mode: Java; c-basic-offset: 2; indent-tabs-mode: nil -*-
 *
 * Copyright (c) 2011-2012 Edugility LLC.
 *
 * Permission is hereby granted, free of charge, to any person
 * obtaining a copy of this software and associated documentation
 * files (the "Software"), to deal in the Software without
 * restriction, including without limitation the rights to use, copy,
 * modify, merge, publish, distribute, sublicense and/or sell copies
 * of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 * 
 * The above copyright notice and this permission notice shall be
 * included in all copies or substantial portions of the Software.
 * 
 * THIS SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
 * NONINFRINGEMENT.  IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
 * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
 * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
 * DEALINGS IN THE SOFTWARE.
 *
 * The original copy of this license is available at
 * http://www.opensource.org/license/mit-license.html.
 */
package com.edugility.h2.maven.plugin;

import java.io.File;
import java.io.IOException;

import java.net.URISyntaxException;
import java.net.URL;

import java.security.CodeSource;
import java.security.ProtectionDomain;

import java.sql.SQLException;

import java.util.Collections;
import java.util.LinkedList;
import java.util.List;

import org.apache.maven.plugin.AbstractMojo;

import org.apache.maven.plugin.logging.Log;

import org.h2.server.TcpServer;

import org.h2.tools.Server;

/**
 * An abstract <a href="http://maven.apache.org/">Maven</a> plugin, or
 * <i>mojo</i>, that helps with interacting with an <a
 * href="http://www.h2database.com/">H2</a> <a
 * href="http://h2database.com/html/tutorial.html#using_server">TCP
 * server</a>.
 *
 * @author <a href="mailto:ljnelson@gmail.com">Laird Nelson</a>
 *
 * @since 1.0
 */
public abstract class AbstractH2Mojo extends AbstractMojo {

    /**
     * The {@link Service}s to spawn.
     *
     * @parameter property="services"
     */
    private List<Service> services;

    /**
     * Whether SSL should be used.  See <a
     * href="http://www.h2database.com/javadoc/org/h2/tools/Server.html#main_String...">the
     * documentation for the {@code Server} class</a> for more details.
     * 
     * @parameter expression="${h2.useSSL}" property="useSSL"
     */
    private boolean useSSL;

    /**
     * Whether other processes may connect to the spawned server.  See
     * <a
     * href="http://www.h2database.com/javadoc/org/h2/tools/Server.html#main_String...">the
     * documentation for the {@code Server} class</a> for more details.
     *
     * @parameter expression="${h2.allowOthers}" property="allowOthers"
     */
    private boolean allowOthers;

    /**
     * The port to run the H2 TCP server on; {@code 9092} by default.
     * See <a
     * href="http://www.h2database.com/javadoc/org/h2/tools/Server.html#main_String...">the
     * documentation for the {@code Server} class</a> for more details.
     *
     * @parameter default-value="9092" expression="${h2.port}" property="port"
     */
    private int port;

    /**
     * The base directory beneath which H2 databases will be created by
     * the spawned H2 TCP server.  See <a
     * href="http://www.h2database.com/javadoc/org/h2/tools/Server.html#main_String...">the
     * documentation for the {@code Server} class</a> for more details.
     *
     * @parameter expression="${h2.baseDirectory}" property="baseDirectory"
     */
    private File baseDirectory;

    /**
     * Whether databases must exist in order to be connected to, or
     * whether they will be created on demand.  See <a
     * href="http://www.h2database.com/javadoc/org/h2/tools/Server.html#main_String...">the
     * documentation for the {@code Server} class</a> for more details.
     *
     * @parameter expression="${h2.ifExists}" property="ifExists"
     */
    private boolean ifExists;

    /**
     * The password required to shut down a spawned H2 TCP server.  See
     * <a
     * href="http://www.h2database.com/javadoc/org/h2/tools/Server.html#main_String...">the
     * documentation for the {@code Server} class</a> for more details.
     *
     * @parameter expression="${h2.shutdownPassword}" property="shutdownPassword" default-value="h2-maven-plugin"
     */
    private String shutdownPassword;

    /**
     * The hostname to which shutdown requests will be directed. See <a
     * href="http://www.h2database.com/javadoc/org/h2/tools/Server.html#main_String...">the
     * documentation for the {@code Server} class</a> for more details.
     *
     * @parameter expression="${h2.shutdownHost}" property="shutdownHost" default-value="localhost"
     */
    private String shutdownHost;

    /**
     * Whether shutdown should be forced or attempted normally.  See <a
     * href="http://www.h2database.com/javadoc/org/h2/tools/Server.html#main_String...">the
     * documentation for the {@code Server} class</a> for more details.
     *
     * @parameter expression="${h2.forceShutdown}" property="forceShutdown"
     */
    private boolean forceShutdown;

    /**
     * Whether shutdown should force <i>all</i> servers spawned on the
     * same host to shut down.  See <a
     * href="http://www.h2database.com/javadoc/org/h2/tools/Server.html#main_String...">the
     * documentation for the {@code Server} class</a> for more details.
     *
     * @parameter expression="${h2.shutdownAllServers}" property="shutdownAllServers"
     */
    private boolean shutdownAllServers;

    /**
     * Whether trace information should be output. See <a
     * href="http://www.h2database.com/javadoc/org/h2/tools/Server.html#main_String...">the
     * documentation for the {@code Server} class</a> for more details.
     *
     * @parameter expression="${h2.trace}" property="trace"
     */
    private boolean trace;

    /**
     * The {@link File} that identifies the Java executable to use to
     * spawn a new H2 TCP server.  The default value used, if this field
     * is {@code null}, will be the path formed by concatenating the
     * value of the {@code java.home} {@linkplain
     * System#getProperty(String) System property} with "{@code bin}"
     * and "{@code java}".
     *
     * @parameter expression="${h2.java}" property="java"
     */
    private File java;

    /**
     * Any options to pass to the Java executable on the command line.
     * Each element of this array will <i>not</i> be split on
     * whitespace or otherwise tokenized.
     *
     * @parameter property="javaOptions"
     */
    private String[] javaOptions;

    /**
     * Creates a new {@link AbstractH2Mojo}.
     */
    protected AbstractH2Mojo() {
        super();
        final Service tcpService = new Service("tcp", Service.getDefaultPort("tcp"), false, false);
        this.setServices(Collections.singletonList(tcpService));
        this.setPort(Service.getDefaultPort("tcp"));
        this.setShutdownPassword("h2-maven-plugin");
        this.setJava(new File(new File(new File(System.getProperty("java.home")), "bin"), "java"));
    }

    /**
     * Returns a {@link List} of {@link Service}s that will be
     * {@linkplain #spawnServer() spawned}.  This method never returns
     * {@code null}.
     *
     * @return a non-{@code null} {@link List} of {@link Service}s
     */
    public List<Service> getServices() {
        return this.services;
    }

    /**
     * Returns the {@link Service} whose {@link Service#getId() id} is
     * equal to the supplied {@link String}, or {@code null} if there is
     * no such {@link Service}.
     *
     * @param the {@link Service#getId() id} of the {@link Service} to
     * return; may be {@code null}
     *
     * @return a {@link Service} that is a member of this {@link
     * AbstractH2Mojo}'s {@linkplain #getServices() list of
     * <tt>Service</tt>s}, or {@code null} if there is no such {@link
     * Service}
     */
    public Service getService(final String id) {
        Service service = null;
        final List<Service> services = this.getServices();
        if (services != null && !services.isEmpty()) {
            for (final Service s : services) {
                if (s != null) {
                    if (id == null) {
                        if (s.getId() == null) {
                            service = s;
                            break;
                        }
                    } else if (id.equals(s.getId())) {
                        service = s;
                        break;
                    }
                }
            }
        }
        return service;
    }

    /**
     * Installs a {@link List} of {@link Service}s that this {@link
     * AbstractH2Mojo} is capable of {@linkplain #spawnServer()
     * spawning}.
     *
     * @param services a {@link List} of {@link Service}s; may be {@code
     * null}
     */
    public void setServices(final List<Service> services) {
        if (services == null || services.isEmpty()) {
            this.services = Collections.emptyList();
        } else {
            this.services = services;
        }
    }

    /**
     * Returns {@code true} if a shutdown operation should shut down all
     * H2 TCP servers running on the host in question.
     *
     * @return {@code true} if a shutdown operation should shut down all
     * H2 TCP servers running on the host in question; {@code false} otherwise
     */
    public boolean getShutdownAllServers() {
        return this.shutdownAllServers;
    }

    /**
     * Sets whether a shutdown operation should shut down all H2 TCP
     * servers running on the host in question.
     *
     * @param shutdownAllServers if a shutdown operation should shut
     * down all H2 TCP servers running on the host in question
     */
    public void setShutdownAllServers(final boolean shutdownAllServers) {
        this.shutdownAllServers = shutdownAllServers;
    }

    /**
     * Returns the password necessary to shut down spawned H2 TCP
     * servers.
     *
     * <p>This method may return {@code null}.</p>
     *
     * @return the shutdown password, or {@code null}
     */
    public String getShutdownPassword() {
        return this.shutdownPassword;
    }

    /**
     * Sets the password necessary to shut down spawned H2 TCP servers.
     *
     * @param pw the new password; may be {@code null}
     */
    public void setShutdownPassword(final String pw) {
        this.shutdownPassword = pw;
    }

    /**
     * Returns the hostname to which shutdown requests will be routed.
     *
     * <p>This method may return {@code null}.  Consumers of this method
     * should interpret such return values as being equal to {@code
     * localhost}.</p>
     *
     * @return the hostname to which shutdown requests will be routed,
     * or {@code null}
     */
    public String getShutdownHost() {
        return this.shutdownHost;
    }

    /**
     * Sets the hostname to which shutdown requests will be routed.
     * Passing a {@code null} parameter to this method will result in
     * "{@code localhost}" being used.
     *
     * @param shutdownHost the hostname to which shutdown requests will
     * be routed; may be {@code null}
     */
    public void setShutdownHost(final String shutdownHost) {
        this.shutdownHost = shutdownHost;
    }

    /**
     * Returns whether shutdown should be forced (if shutdown has been
     * requested).  See <a
     * href="http://www.h2database.com/javadoc/org/h2/tools/Server.html#main_String...">the
     * documentation for the {@code Server} class</a> for more details.
     *
     * @return {@code true} if shutdown should be forced
     */
    public boolean getForceShutdown() {
        return this.forceShutdown;
    }

    /**
     * Sets whether shutdown should be forced (if shutdown has been
     * requested).  See <a
     * href="http://www.h2database.com/javadoc/org/h2/tools/Server.html#main_String...">the
     * documentation for the {@code Server} class</a> for more details.
     *
     * @param shutdown if {@code true}, then shutdown operations will be
     * forced
     */
    public void setForceShutdown(final boolean shutdown) {
        this.forceShutdown = shutdown;
    }

    /**
     * Returns the {@link File} representing the path to the H2 jar file
     * that is on the classpath.  This method never returns {@code
     * null}.
     *
     * @return the {@link File} representing the path to the H2 jar
     * file; never {@code null}
     */
    public final File getH2() {
        final ProtectionDomain pd = Server.class.getProtectionDomain();
        assert pd != null;
        final CodeSource cs = pd.getCodeSource();
        assert cs != null;
        final URL location = cs.getLocation();
        assert location != null;
        try {
            return new File(location.toURI());
        } catch (final URISyntaxException wontHappen) {
            throw (InternalError) new InternalError().initCause(wontHappen);
        }
    }

    /**
     * Returns the {@link File} representing the path to the Java
     * executable used to spawn H2 TCP servers.  This method may return
     * {@code null}.
     *
     * @return the {@link File} representing the path to the Java
     * executable, or {@code null}
     */
    public File getJava() {
        return this.java;
    }

    /**
     * Sets the {@link File} representing the path to the Java
     * executable used to spawn H2 TCP servers.
     *
     * @param java the {@link File} to use; may be {@code null}
     */
    public void setJava(final File java) {
        this.java = java;
    }

    /**
     * Returns any Java options passed to the spawned H2 process.  This
     * method may return {@code null}.
     *
     * @return any Java options passed to the spawned H2 process, or
     * {@code null}
     */
    public String[] getJavaOptions() {
        return this.javaOptions;
    }

    /**
     * Sets any command-line options to be passed to the Java runtime
     * when spawning a new H2 TCP server.
     *
     * @param javaOptions the options; may be {@code null}
     */
    public void setJavaOptions(final String... javaOptions) {
        this.javaOptions = javaOptions;
    }

    /**
     * Returns {@code true} if the {@code -trace} option will be
     * supplied to the spawned H2 TCP server.  See <a
     * href="http://www.h2database.com/javadoc/org/h2/tools/Server.html#main_String...">the
     * documentation for the {@code Server} class</a> for more details.
     *
     * @return {@code true} if the {@code -trace} option will be
     * supplied to the spawned H2 TCP server
     */
    public boolean getTrace() {
        return this.trace;
    }

    /**
     * Sets whether the {@code -trace} option will be supplied to new H2
     * TCP servers.  See <a
     * href="http://www.h2database.com/javadoc/org/h2/tools/Server.html#main_String...">the
     * documentation for the {@code Server} class</a> for more details.
     *
     * @param trace whether the {@code -trace} option will be supplied
     * to new H2 TCP servers
     */
    public void setTrace(final boolean trace) {
        this.trace = trace;
    }

    /**
     * Returns {@code true} if the {@code -ifExists} option will be
     * supplied to the spawned H2 TCP server.  See <a
     * href="http://www.h2database.com/javadoc/org/h2/tools/Server.html#main_String...">the
     * documentation for the {@code Server} class</a> for more details.
     *
     * @return {@code true} if the {@code -ifExists} option will be
     * supplied to the spawned H2 TCP server
     */
    public boolean getIfExists() {
        return this.ifExists;
    }

    /**
     * Sets whether the {@code -ifExists} option will be supplied to the
     * spawned H2 TCP server.  See <a
     * href="http://www.h2database.com/javadoc/org/h2/tools/Server.html#main_String...">the
     * documentation for the {@code Server} class</a> for more details.
     *
     * @param ifExists whether the {@code -ifExists} option will be
     * supplied to new H2 TCP servers
     */
    public void setIfExists(final boolean ifExists) {
        this.ifExists = ifExists;
    }

    /**
     * Returns {@code true} if the {@code -tcpAllowOthers} option will
     * be supplied to the spawned H2 TCP server.  See <a
     * href="http://www.h2database.com/javadoc/org/h2/tools/Server.html#main_String...">the
     * documentation for the {@code Server} class</a> for more details.
     *
     * @return {@code true} if the {@code -tcpAllowOthers} option will
     * be supplied to the spawned H2 TCP server
     *
     * @deprecated Use the correct {@link Service} instead.
     */
    @Deprecated
    public boolean getAllowOthers() {
        return this.allowOthers;
    }

    /**
     * Sets whether the {@code -tcpAllowOthers} option will be supplied
     * to the spawned H2 TCP server.  See <a
     * href="http://www.h2database.com/javadoc/org/h2/tools/Server.html#main_String...">the
     * documentation for the {@code Server} class</a> for more details.
     *
     * @param allowOthers whether the {@code -tcpAllowOthers} option
     * will be supplied to new H2 TCP servers
     *
     * @deprecated Use the correct {@link Service} instead.
     */
    @Deprecated
    public void setAllowOthers(final boolean allowOthers) {
        this.allowOthers = allowOthers;
        final Service tcpService = this.getService("tcp");
        if (tcpService != null) {
            tcpService.setAllowOthers(this.getAllowOthers());
        }
    }

    /**
     * Returns {@code true} if the {@code -tcpSSL} option will
     * be supplied to the spawned H2 TCP server.  See <a
     * href="http://www.h2database.com/javadoc/org/h2/tools/Server.html#main_String...">the
     * documentation for the {@code Server} class</a> for more details.
     *
     * @return {@code true} if the {@code -tcpSSL} option will
     * be supplied to the spawned H2 TCP server
     *
     * @deprecated Use the correct {@link Service} instead.
     */
    @Deprecated
    public boolean getUseSSL() {
        return this.useSSL;
    }

    /**
     * Sets whether the {@code -tcpSSL} option will be supplied
     * to the spawned H2 TCP server.  See <a
     * href="http://www.h2database.com/javadoc/org/h2/tools/Server.html#main_String...">the
     * documentation for the {@code Server} class</a> for more details.
     *
     * @param useSSL whether the {@code -tcpSSL} option
     * will be supplied to new H2 TCP servers
     *
     * @deprecated Use the correct {@link Service} instead.
     */
    @Deprecated
    public void setUseSSL(final boolean useSSL) {
        this.useSSL = useSSL;
        final Service tcpService = this.getService("tcp");
        if (tcpService != null) {
            tcpService.setSSL(this.getUseSSL());
        }
    }

    /**
     * Returns the {@link File} representing the base directory from
     * which H2 TCP servers will be spawned.  
     *
     * <p>This property corresponds to the {@code -baseDir} option
     * supplied to spawned H2 TCP servers.  See <a
     * href="http://www.h2database.com/javadoc/org/h2/tools/Server.html#main_String...">the
     * documentation for the {@code Server} class</a> for more
     * details.</p>
     *
     * <p>This method may return {@code null}.</p>
     *
     * @return the {@link File} representing the base directory, or
     * {@code null}
     */
    public File getBaseDirectory() {
        return this.baseDirectory;
    }

    /**
     * Sets the base directory from which H2 TCP servers will be
     * spawned.
     *
     * <p>This property corresponds to the {@code -baseDir} option
     * supplied to spawned H2 TCP servers.  See <a
     * href="http://www.h2database.com/javadoc/org/h2/tools/Server.html#main_String...">the
     * documentation for the {@code Server} class</a> for more
     * details.</p>
     *
     * @param baseDirectory a {@link File} representing the new base
     * directory; may be {@code null}
     */
    public void setBaseDirectory(final File baseDirectory) {
        this.baseDirectory = baseDirectory;
    }

    /**
     * Returns the port on which new H2 TCP servers spawned by this
     * class will listen.  H2's default port is 9092.
     *
     * @return the port on which new H2 TCP servers spawned by this
     * class will listen; this will be a number between {@code 0} and
     * {@code 65535}, inclusive
     *
     * @deprecated Use the correct {@link Service} instead.
     */
    @Deprecated
    public int getPort() {
        return this.port;
    }

    /**
     * Sets the port on which new H2 TCP servers spawned by this class
     * will listen.  H2's default port is 9092.
     *
     * @param port the new port; will be constrained to be between
     * {@code 0} and {@code 65535}, inclusive
     *
     * @deprecated Use the correct {@link Service} instead.
     */
    @Deprecated
    public void setPort(final int port) {
        this.port = Math.min(65535, Math.max(0, port));
        final Service tcpService = this.getService("tcp");
        if (tcpService != null) {
            tcpService.setPort(this.getPort());
        }
    }

    /**
     * Creates a new {@link Server} using H2's {@link
     * Server#createTcpServer(String[])}, {@link
     * Server#createPgServer(String[])} or {@link
     * Server#createWebServer(String[])} method.  This method must never
     * return {@code null}.
     *
     * <p><strong>Note:</strong> This method is experimental.</p>
     *
     * @return a new {@link Server} as produced by the {@link
     * Server#createTcpServer(String[])} method; never {@code null}
     *
     * @exception SQLException if an error occurs
     */
    protected Server createServer() throws SQLException {
        Server server = null;
        final List<String> args = this.getServerArguments();
        if (args == null || args.isEmpty()) {
            throw new SQLException("Cannot create server; no arguments");
        } else if (args.contains("-tcp")) {
            server = Server.createTcpServer(args.toArray(new String[args.size()]));
        } else if (args.contains("-pg")) {
            server = Server.createPgServer(args.toArray(new String[args.size()]));
        } else if (args.contains("-web")) {
            server = Server.createWebServer(args.toArray(new String[args.size()]));
        } else {
            throw new SQLException("Unknown service");
        }
        return server;
    }

    /**
     * Returns a {@link ProcessBuilder} that can be used and reused to
     * spawn new fully configured H2 TCP servers.
     *
     * <p>This method never returns {@code null}.</p>
     *
     * <h2>Design Notes</h2>
     *
     * <p>At the moment, the implementation of this method returns a new
     * {@link ProcessBuilder} in all cases, but this behavior should not
     * be relied upon.</p>
     *
     * @return a {@link ProcessBuilder}; never {@code null}
     */
    protected ProcessBuilder getServerSpawner() {
        final List<String> args = this.getServerArguments();
        assert args != null;

        // A spawned server should never run as a daemon.
        args.remove("-tcpDaemon");
        args.remove("-pgDaemon");
        args.remove("-webDaemon");

        int argumentIndex = 0;

        File java = this.getJava();
        if (java == null) {
            java = new File(new File(new File(System.getProperty("java.home")), "bin"), "java");
        }
        args.add(argumentIndex++, java.getAbsolutePath());

        final String[] javaOptions = this.getJavaOptions();
        if (javaOptions != null && javaOptions.length > 0) {
            for (final String option : javaOptions) {
                if (option != null && !option.trim().isEmpty()) {
                    args.add(argumentIndex++, option);
                }
            }
        }

        args.add(argumentIndex++, "-cp");
        final File fileLocation = this.getH2();
        assert fileLocation != null;
        args.add(argumentIndex++, fileLocation.getAbsolutePath());

        args.add(argumentIndex++, Server.class.getName());

        final Log log = this.getLog();
        if (log != null && log.isDebugEnabled()) {
            log.debug("Process arguments: " + args);
        }
        return new ProcessBuilder(args);
    }

    /**
     * Returns a {@link Process} representing an H2 TCP server that has
     * been started.  The returned {@link Process} is guaranteed not to
     * be {@code null} and will not have been {@linkplain
     * Process#destroy() destroyed}.
     *
     * @return a non-{@code null} {@link Process}
     *
     * @exception IOException if an error occurred during {@link
     * Process} creation, usually because of a {@link
     * ProcessBuilder#start()} failure
     */
    protected Process spawnServer() throws IOException {
        return this.getServerSpawner().start();
    }

    /**
     * Shuts down a server spawned earlier by the {@link #spawnServer()} method.
     *
     * @exception SQLException if the server could not be shut down
     */
    protected void shutdownServer() throws SQLException {
        String password = this.getShutdownPassword();
        if (password == null) {
            password = "";
        }
        final int port = this.getPort();
        String host = this.getShutdownHost();
        if (host == null) {
            host = "";
        } else {
            host = host.trim();
        }
        if (host.isEmpty()) {
            host = "localhost";
        }
        TcpServer.shutdown(String.format("tcp://%s:%d", host, port), password, this.getForceShutdown(),
                this.getShutdownAllServers());
    }

    /**
     * Returns a {@link List} of arguments suitable for feeding to a new
     * H2 TCP server process, or to the parameters accepted by the
     * {@link Server#createTcpServer(String[])} method.
     *
     * <p>This method never returns {@code null}.</p>
     *
     * @return a new, mutable, non-{@code null} {@link List} of
     * arguments for new H2 processes
     */
    protected List<String> getServerArguments() {

        List<String> args = null;

        final List<Service> services = this.getServices();
        int serviceCount = 0;
        if (services != null && !services.isEmpty()) {
            for (final Service service : services) {
                if (service != null) {

                    if (args == null) {
                        args = new LinkedList<String>();
                    }

                    final String id = service.getId();
                    if (id != null) {
                        args.add(new StringBuilder("-").append(id).toString());
                    }

                    final int port = service.getPort();
                    if (port >= 0) {
                        args.add(new StringBuilder("-").append(id).append("Port").toString());
                        args.add(String.format("%d", Math.min(65535, Math.max(0, this.getPort()))));
                    }

                    final boolean allowOthers = service.getAllowOthers();
                    if (allowOthers) {
                        args.add(new StringBuilder("-").append(id).append("AllowOthers").toString());
                    }

                    final boolean ssl = service.getSSL();
                    if (ssl) {
                        args.add(new StringBuilder("-").append(id).append("SSL").toString());
                    }

                    serviceCount++;
                }
            }
        }
        if (args != null && serviceCount > 0) {

            final File baseDirectory = this.getBaseDirectory();
            if (baseDirectory != null) {
                args.add("-baseDir");
                args.add(String.format("%s", baseDirectory.getAbsolutePath()));
            }

            if (this.getIfExists()) {
                args.add("-ifExists");
            }

            if (this.getTrace()) {
                args.add("-trace");
            }

            final String password = this.getShutdownPassword();
            if (password != null && !password.isEmpty()) {
                args.add("-tcpPassword");
                args.add(password);
            }

        }
        if (args == null) {
            args = Collections.emptyList();
        }
        return args;
    }

}