All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.eclipse.jetty.start.CommandLineBuilder Maven / Gradle / Ivy

There is a newer version: 9.4.8.v20171121
Show newest version
//
// ========================================================================
// Copyright (c) 1995 Mort Bay Consulting Pty Ltd and others.
//
// This program and the accompanying materials are made available under the
// terms of the Eclipse Public License v. 2.0 which is available at
// https://www.eclipse.org/legal/epl-2.0, or the Apache License, Version 2.0
// which is available at https://www.apache.org/licenses/LICENSE-2.0.
//
// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0
// ========================================================================
//

package org.eclipse.jetty.start;

import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;

public class CommandLineBuilder
{
    public static String findJavaBin()
    {
        Path javaHome = Paths.get(System.getProperty("java.home"));
        if (!Files.exists(javaHome))
            return null;

        Path javabin = javaHome.resolve("bin/java");
        if (Files.exists(javabin))
            return javabin.toAbsolutePath().toString();

        javabin = javaHome.resolve("bin/java.exe");
        if (Files.exists(javabin))
            return javabin.toAbsolutePath().toString();

        return "java";
    }

    private final StringBuilder commandLine = new StringBuilder();
    private final List args = new ArrayList<>();
    private final String separator;

    public CommandLineBuilder()
    {
        this(false);
    }

    public CommandLineBuilder(boolean multiline)
    {
        separator = multiline ? (" \\" + System.lineSeparator() + "  ") : " ";
    }

    /**
     * This method applies single quotes suitable for a POSIX compliant shell if
     * necessary.
     *
     * @param input The string to quote if needed
     * @return The quoted string or the original string if quotes are not necessary
     */
    public static String shellQuoteIfNeeded(String input)
    {
        // Single quotes are used because double quotes
        // are evaluated differently by some shells.

        if (input == null)
            return null;
        if (input.length() == 0)
            return "''";

        int i = 0;
        boolean needsQuoting = false;
        while (!needsQuoting && i < input.length())
        {
            char c = input.charAt(i++);

            // needs quoting unless a limited set of known good characters
            needsQuoting = !(
                (c >= 'A' && c <= 'Z') ||
                (c >= 'a' && c <= 'z') ||
                (c >= '0' && c <= '9') ||
                c == '/' ||
                c == ':' ||
                c == '.' ||
                c == ',' ||
                c == '+' ||
                c == '-' ||
                c == '_'
                );
        }

        if (!needsQuoting)
            return input;

        StringBuilder builder = new StringBuilder(input.length() * 2);
        builder.append("'");
        builder.append(input, 0, --i);

        while (i < input.length())
        {
            char c = input.charAt(i++);
            if (c == '\'')
            {
                // There is no escape for a literal single quote, so we must leave the quotes
                // and then escape the single quote. We test for the start/end of the string, so
                // we can be less ugly in those cases.
                if (i == 1)
                    builder.insert(0, "\\").append("'");
                else if (i == input.length())
                    builder.append("'\\");
                else
                    builder.append("'\\''");
            }
            else
                builder.append(c);
        }
        builder.append("'");

        return builder.toString();
    }

    /**
     * Add a simple argument to the command line, quoted if necessary.
     *
     * @param arg the simple argument to add
     */
    public void addArg(String arg)
    {
        if (arg != null)
        {
            if (commandLine.length() > 0)
                commandLine.append(separator);
            args.add(arg);
            commandLine.append(shellQuoteIfNeeded(arg));
        }
    }

    /**
     * Add a "name=value" style argument to the command line with
     * name and value quoted if necessary.
     * @param name the name
     * @param value the value
     */
    public void addArg(String name, String value)
    {
        Objects.requireNonNull(name);

        if (commandLine.length() > 0)
            commandLine.append(separator);

        if ((value != null) && (value.length() > 0))
        {
            args.add(name + "=" + value);
            commandLine.append(shellQuoteIfNeeded(name)).append('=').append(shellQuoteIfNeeded(value));
        }
        else
        {
            args.add(name);
            commandLine.append(shellQuoteIfNeeded(name));
        }
    }

    /**
     * Adds a "-OPTION" style option to the command line with no quoting, for example `--help`.
     * @param option the option
     */
    public void addOption(String option)
    {
        addOption(option, null, null);
    }

    /**
     * Adds a "-OPTIONname=value" style option to the command line with
     * name and value quoted if necessary, for example "-Dprop=value".
     * @param option the option
     * @param name the name
     * @param value the value
     */
    public void addOption(String option, String name, String value)
    {
        Objects.requireNonNull(option);

        if (commandLine.length() > 0)
            commandLine.append(separator);

        if (name == null || name.length() == 0)
        {
            commandLine.append(option);
            args.add(option);
        }
        else if ((value != null) && (value.length() > 0))
        {
            args.add(option + name + "=" + value);
            commandLine.append(option).append(shellQuoteIfNeeded(name)).append('=').append(shellQuoteIfNeeded(value));
        }
        else
        {
            args.add(option + name);
            commandLine.append(option).append(shellQuoteIfNeeded(name));
        }
    }

    public List getArgs()
    {
        return args;
    }

    @Override
    public String toString()
    {
        StringBuilder buf = new StringBuilder();
        for (String arg : args)
        {
            if (buf.length() > 0)
                buf.append(' ');
            buf.append(arg); // we assume escaping has occurred during addArg
        }

        return buf.toString();
    }

    /**
     * A version of {@link #toString()} where every arg is evaluated for potential {@code '} (single-quote tick) wrapping.
     *
     * @return the toString but each arg that has spaces is surrounded by {@code '} (single-quote tick)
     */
    public String toCommandLine()
    {
        return commandLine.toString();
    }

    public void debug()
    {
        if (!StartLog.isDebugEnabled())
        {
            return;
        }

        int len = args.size();
        StartLog.debug("Command Line: %,d entries", args.size());
        for (int i = 0; i < len; i++)
        {
            StartLog.debug(" [%d]: \"%s\"", i, args.get(i));
        }
    }
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy