Example #1
0
 /**
  * Handles the following tokens:
  *
  * <p>--L -L --l -l
  *
  * @param token the command line token to handle
  */
 private void handleLongOptionWithoutEqual(String token) throws ParseException {
   List<String> matchingOpts = options.getMatchingOptions(token);
   if (matchingOpts.isEmpty()) {
     handleUnknownToken(currentToken);
   } else if (matchingOpts.size() > 1) {
     throw new AmbiguousOptionException(token, matchingOpts);
   } else {
     handleOption(options.getOption(matchingOpts.get(0)));
   }
 }
  /**
   * If an {@link Option} exists for <code>token</code> then add the token to the processed list.
   *
   * <p>If an {@link Option} does not exist and <code>stopAtNonOption</code> is set then add the
   * remaining tokens to the processed tokens list directly.
   *
   * @param token The current option token
   * @param stopAtNonOption Specifies whether flattening should halt at the first non option.
   */
  private void processOptionToken(String token, boolean stopAtNonOption) {
    if (stopAtNonOption && !options.hasOption(token)) {
      eatTheRest = true;
    }

    if (options.hasOption(token)) {
      currentOption = options.getOption(token);
    } else {
      currentOption = null;
    }

    tokens.add(token);
  }
  /**
   * An implementation of {@link Parser}'s abstract {@link Parser#flatten(Options,String[],boolean)
   * flatten} method.
   *
   * <p>The following are the rules used by this flatten method.
   *
   * <ol>
   *   <li>if <code>stopAtNonOption</code> is <b>true</b> then do not burst anymore of <code>
   *       arguments</code> entries, just add each successive entry without further processing.
   *       Otherwise, ignore <code>stopAtNonOption</code>.
   *   <li>if the current <code>arguments</code> entry is "<b>--</b>" just add the entry to the list
   *       of processed tokens
   *   <li>if the current <code>arguments</code> entry is "<b>-</b>" just add the entry to the list
   *       of processed tokens
   *   <li>if the current <code>arguments</code> entry is two characters in length and the first
   *       character is "<b>-</b>" then check if this is a valid {@link Option} id. If it is a valid
   *       id, then add the entry to the list of processed tokens and set the current {@link Option}
   *       member. If it is not a valid id and <code>stopAtNonOption</code> is true, then the
   *       remaining entries are copied to the list of processed tokens. Otherwise, the current
   *       entry is ignored.
   *   <li>if the current <code>arguments</code> entry is more than two characters in length and the
   *       first character is "<b>-</b>" then we need to burst the entry to determine its
   *       constituents. For more information on the bursting algorithm see {@link
   *       GroovyInternalPosixParser#burstToken(String, boolean) burstToken}.
   *   <li>if the current <code>arguments</code> entry is not handled by any of the previous rules,
   *       then the entry is added to the list of processed tokens.
   * </ol>
   *
   * @param options The command line {@link Options}
   * @param arguments The command line arguments to be parsed
   * @param stopAtNonOption Specifies whether to stop flattening when an non option is found.
   * @return The flattened <code>arguments</code> String array.
   */
  protected String[] flatten(Options options, String[] arguments, boolean stopAtNonOption) {
    init();
    this.options = options;

    // an iterator for the command line tokens
    Iterator iter = Arrays.asList(arguments).iterator();

    // process each command line token
    while (iter.hasNext()) {
      // get the next command line token
      String token = (String) iter.next();

      // handle long option --foo or --foo=bar
      if (token.startsWith("--")) {
        int pos = token.indexOf('=');
        String opt = pos == -1 ? token : token.substring(0, pos); // --foo

        if (!options.hasOption(opt)) {
          processNonOptionToken(token, stopAtNonOption);
        } else {
          tokens.add(opt);
          if (pos != -1) {
            tokens.add(token.substring(pos + 1));
          } else {
            currentOption = options.getOption(opt);
          }
        }
      }

      // single hyphen
      else if ("-".equals(token)) {
        tokens.add(token);
      } else if (token.startsWith("-")) {
        if (token.length() == 2 || options.hasOption(token)) {
          processOptionToken(token, stopAtNonOption);
        }
        // requires bursting
        else {
          burstToken(token, stopAtNonOption);
        }
      } else {
        processNonOptionToken(token, stopAtNonOption);
      }

      gobble(iter);
    }

    return (String[]) tokens.toArray(new String[tokens.size()]);
  }
Example #4
0
  /**
   * Breaks <code>token</code> into its constituent parts using the following algorithm.
   *
   * <ul>
   *   <li>ignore the first character ("<b>-</b>")
   *   <li>foreach remaining character check if an {@link Option} exists with that id.
   *   <li>if an {@link Option} does exist then add that character prepended with "<b>-</b>" to the
   *       list of processed tokens.
   *   <li>if the {@link Option} can have an argument value and there are remaining characters in
   *       the token then add the remaining characters as a token to the list of processed tokens.
   *   <li>if an {@link Option} does <b>NOT</b> exist <b>AND</b> <code>stopAtNonOption</code>
   *       <b>IS</b> set then add the special token "<b>--</b>" followed by the remaining characters
   *       and also the remaining tokens directly to the processed tokens list.
   *   <li>if an {@link Option} does <b>NOT</b> exist <b>AND</b> <code>stopAtNonOption</code> <b>IS
   *       NOT</b> set then add that character prepended with "<b>-</b>".
   * </ul>
   *
   * @param token The current token to be <b>burst</b> at the first non-Option encountered.
   * @throws ParseException if there are any problems encountered while parsing the command line
   *     token.
   */
  protected void handleConcatenatedOptions(String token) throws ParseException {
    for (int i = 1; i < token.length(); i++) {
      String ch = String.valueOf(token.charAt(i));

      if (options.hasOption(ch)) {
        handleOption(options.getOption(ch));

        if (currentOption != null && token.length() != i + 1) {
          // add the trail as an argument of the option
          currentOption.addValueForProcessing(token.substring(i + 1));
          break;
        }
      } else {
        handleUnknownToken(stopAtNonOption && i > 1 ? token.substring(i) : token);
        break;
      }
    }
  }
  /**
   * Breaks <code>token</code> into its constituent parts using the following algorithm.
   *
   * <ul>
   *   <li>ignore the first character ("<b>-</b>")
   *   <li>foreach remaining character check if an {@link Option} exists with that id.
   *   <li>if an {@link Option} does exist then add that character prepended with "<b>-</b>" to the
   *       list of processed tokens.
   *   <li>if the {@link Option} can have an argument value and there are remaining characters in
   *       the token then add the remaining characters as a token to the list of processed tokens.
   *   <li>if an {@link Option} does <b>NOT</b> exist <b>AND</b> <code>stopAtNonOption</code>
   *       <b>IS</b> set then add the special token "<b>--</b>" followed by the remaining characters
   *       and also the remaining tokens directly to the processed tokens list.
   *   <li>if an {@link Option} does <b>NOT</b> exist <b>AND</b> <code>stopAtNonOption</code> <b>IS
   *       NOT</b> set then add that character prepended with "<b>-</b>".
   * </ul>
   *
   * @param token The current token to be <b>burst</b>
   * @param stopAtNonOption Specifies whether to stop processing at the first non-Option
   *     encountered.
   */
  protected void burstToken(String token, boolean stopAtNonOption) {
    for (int i = 1; i < token.length(); i++) {
      String ch = String.valueOf(token.charAt(i));

      if (options.hasOption(ch)) {
        tokens.add("-" + ch);
        currentOption = options.getOption(ch);

        if (currentOption.hasArg() && (token.length() != (i + 1))) {
          tokens.add(token.substring(i + 1));
          break;
        }
      } else if (stopAtNonOption) {
        processNonOptionToken(token.substring(i), true);
        break;
      } else {
        tokens.add(token);
        break;
      }
    }
  }
Example #6
0
  /**
   * Sets the values of Options using the values in <code>properties</code>.
   *
   * @param properties The value properties to be processed.
   */
  private void handleProperties(Properties properties) throws ParseException {
    if (properties == null) {
      return;
    }

    for (Enumeration<?> e = properties.propertyNames(); e.hasMoreElements(); ) {
      String option = e.nextElement().toString();

      Option opt = options.getOption(option);
      if (opt == null) {
        throw new UnrecognizedOptionException("Default option wasn't defined", option);
      }

      // if the option is part of a group, check if another option of the group has been selected
      OptionGroup group = options.getOptionGroup(opt);
      boolean selected = group != null && group.getSelected() != null;

      if (!cmd.hasOption(option) && !selected) {
        // get the value from the properties
        String value = properties.getProperty(option);

        if (opt.hasArg()) {
          if (opt.getValues() == null || opt.getValues().length == 0) {
            opt.addValueForProcessing(value);
          }
        } else if (!("yes".equalsIgnoreCase(value)
            || "true".equalsIgnoreCase(value)
            || "1".equalsIgnoreCase(value))) {
          // if the value is not yes, true or 1 then don't add the option to the CommandLine
          continue;
        }

        handleOption(opt);
        currentOption = null;
      }
    }
  }
Example #7
0
  /**
   * Handles the following tokens:
   *
   * <p>--L=V -L=V --l=V -l=V
   *
   * @param token the command line token to handle
   */
  private void handleLongOptionWithEqual(String token) throws ParseException {
    int pos = token.indexOf('=');

    String value = token.substring(pos + 1);

    String opt = token.substring(0, pos);

    List<String> matchingOpts = options.getMatchingOptions(opt);
    if (matchingOpts.isEmpty()) {
      handleUnknownToken(currentToken);
    } else if (matchingOpts.size() > 1) {
      throw new AmbiguousOptionException(opt, matchingOpts);
    } else {
      Option option = options.getOption(matchingOpts.get(0));

      if (option.acceptsArg()) {
        handleOption(option);
        currentOption.addValueForProcessing(value);
        currentOption = null;
      } else {
        handleUnknownToken(currentToken);
      }
    }
  }
Example #8
0
  /** Check if the specified token is a Java-like property (-Dkey=value). */
  private boolean isJavaProperty(String token) {
    String opt = token.substring(0, 1);
    Option option = options.getOption(opt);

    return option != null && (option.getArgs() >= 2 || option.getArgs() == Option.UNLIMITED_VALUES);
  }
Example #9
0
  /**
   * Handles the following tokens:
   *
   * <p>-S -SV -S V -S=V -S1S2 -S1S2 V -SV1=V2
   *
   * <p>-L -LV -L V -L=V -l
   *
   * @param token the command line token to handle
   */
  private void handleShortAndLongOption(String token) throws ParseException {
    String t = Util.stripLeadingHyphens(token);

    int pos = t.indexOf('=');

    if (t.length() == 1) {
      // -S
      if (options.hasShortOption(t)) {
        handleOption(options.getOption(t));
      } else {
        handleUnknownToken(token);
      }
    } else if (pos == -1) {
      // no equal sign found (-xxx)
      if (options.hasShortOption(t)) {
        handleOption(options.getOption(t));
      } else if (!options.getMatchingOptions(t).isEmpty()) {
        // -L or -l
        handleLongOptionWithoutEqual(token);
      } else {
        // look for a long prefix (-Xmx512m)
        String opt = getLongPrefix(t);

        if (opt != null && options.getOption(opt).acceptsArg()) {
          handleOption(options.getOption(opt));
          currentOption.addValueForProcessing(t.substring(opt.length()));
          currentOption = null;
        } else if (isJavaProperty(t)) {
          // -SV1 (-Dflag)
          handleOption(options.getOption(t.substring(0, 1)));
          currentOption.addValueForProcessing(t.substring(1));
          currentOption = null;
        } else {
          // -S1S2S3 or -S1S2V
          handleConcatenatedOptions(token);
        }
      }
    } else {
      // equal sign found (-xxx=yyy)
      String opt = t.substring(0, pos);
      String value = t.substring(pos + 1);

      if (opt.length() == 1) {
        // -S=V
        Option option = options.getOption(opt);
        if (option != null && option.acceptsArg()) {
          handleOption(option);
          currentOption.addValueForProcessing(value);
          currentOption = null;
        } else {
          handleUnknownToken(token);
        }
      } else if (isJavaProperty(opt)) {
        // -SV1=V2 (-Dkey=value)
        handleOption(options.getOption(opt.substring(0, 1)));
        currentOption.addValueForProcessing(opt.substring(1));
        currentOption.addValueForProcessing(value);
        currentOption = null;
      } else {
        // -L=V or -l=V
        handleLongOptionWithEqual(token);
      }
    }
  }
Example #10
0
  public static void main(String[] args) throws Exception {
    boolean isInteractive = false;
    classUrl = MynaInstaller.class.getResource("MynaInstaller.class").toString();
    isJar = (classUrl.indexOf("jar") == 0);
    if (!isJar) {
      System.err.println("Installer can only be run from inside a Myna distribution war file");
      System.exit(1);
    }

    Thread.sleep(1000);

    Console console = System.console();
    String response = null;
    CommandLineParser parser = new PosixParser();

    // create the Options
    Options options = new Options();
    options.addOption(
        "c", "context", true, "Webapp context. Must Start with \"/\" Default: " + webctx);
    options.addOption("h", "help", false, "Displays help.");
    options.addOption(
        "w",
        "webroot",
        true,
        "Webroot to use. Will be created if webroot/WEB-INF does not exist. Default: " + webroot);
    options.addOption(
        "l",
        "logfile",
        true,
        "Log file to use. Will be created if it does not exist. Default: ./<context>.log");
    options.addOption(
        "s",
        "servername",
        true,
        "Name of this instance. Will also be the name of the init script. Defaults to either \"myna\" or the value of <context> if defined");
    // options.addOption( "P", "purpose", true, "Purpose of the Server, such as DEV,PROD,TRAIN, etc.
    // Defaults to DEV" );

    options.addOption("p", "port", true, "HTTP port. Set to 0 to disable HTTP. Default: " + port);
    options.addOption(
        "sp", "ssl-port", true, "SSL (HTTPS) port. Set to 0 to disable SSL, Default: 0");

    options.addOption(
        "ks", "keystore", true, "keystore path. Default: <webroot>/WEB-INF/myna/myna_keystore");
    options.addOption("ksp", "ks-pass", true, "keystore password. Default: " + ksPass);
    options.addOption("ksa", "ks-alias", true, "certificate alias. Default: " + ksAlias);

    modeOptions.add("upgrade");
    modeOptions.add("install");
    options.addOption(
        "m",
        "mode",
        true,
        "Mode: one of "
            + modeOptions.toString()
            + ". \n"
            + "\"upgrade\": Upgrades myna installation in webroot and exits. "
            + "\"install\": Unpacks to webroot, and installs startup files");
    options.addOption(
        "u",
        "user",
        true,
        "User to own and run the Myna installation. Only applies to unix installs. Default: nobody");

    HelpFormatter formatter = new HelpFormatter();

    String cmdSyntax = "java -jar myna-X.war -m <mode> [options]";
    try {
      CommandLine line = parser.parse(options, args);
      Option option;
      if (args.length == 0) {
        formatter.printHelp(cmdSyntax, options);
        response = console.readLine("\nContinue with Interactive Install? (y/N)");
        if (response.toLowerCase().equals("y")) {
          isInteractive = true;

        } else System.exit(1);
      }
      // Help
      if (line.hasOption("help")) {
        formatter.printHelp(cmdSyntax, options);
        System.exit(1);
      }
      // mode
      if (line.hasOption("mode")) {
        mode = line.getOptionValue("mode");
        if (!modeOptions.contains(mode)) {
          System.err.println(
              "Invalid Arguments.  Reason: Mode must be in " + modeOptions.toString());
          formatter.printHelp(cmdSyntax, options);
          System.exit(1);
        }
      } else if (isInteractive) {
        option = options.getOption("mode");
        console.printf("\n" + option.getDescription());

        do {
          response = console.readLine("\nEnter " + option.getLongOpt() + "(" + mode + "): ");
          if (!response.isEmpty()) mode = response;
        } while (!modeOptions.contains(mode));
      }
      // webroot
      if (line.hasOption("webroot")) {
        webroot = line.getOptionValue("webroot");
      } else if (isInteractive) {
        option = options.getOption("webroot");
        console.printf("\n" + option.getDescription());
        response = console.readLine("\nEnter " + option.getLongOpt() + "(" + webroot + "): ");
        if (!response.isEmpty()) webroot = response;
      }
      // port
      if (line.hasOption("port")) {
        port = Integer.parseInt(line.getOptionValue("port"));
      } else if (isInteractive && mode.equals("install")) {
        option = options.getOption("port");
        console.printf("\n" + option.getDescription());
        response = console.readLine("\nEnter " + option.getLongOpt() + "(" + port + "): ");
        if (!response.isEmpty()) port = Integer.parseInt(response);
      }
      // context
      if (line.hasOption("context")) {
        webctx = line.getOptionValue("context");

      } else if (isInteractive && mode.equals("install")) {
        option = options.getOption("context");
        console.printf("\n" + option.getDescription());
        response = console.readLine("\nEnter " + option.getLongOpt() + "(" + webctx + "): ");
        if (!response.isEmpty()) webctx = response;
      }
      if (!webctx.startsWith("/")) {
        webctx = "/" + webctx;
      }
      // servername (depends on context)
      if (!webctx.equals("/")) {
        serverName = webctx.substring(1);
      }
      if (line.hasOption("servername")) {
        serverName = line.getOptionValue("servername");
      } else if (isInteractive && mode.equals("install")) {
        option = options.getOption("servername");
        console.printf("\n" + option.getDescription());
        response = console.readLine("\nEnter " + option.getLongOpt() + "(" + serverName + "): ");
        if (!response.isEmpty()) serverName = response;
      }
      // user
      if (line.hasOption("user")) {
        user = line.getOptionValue("user");
      } else if (isInteractive && mode.equals("install")) {
        option = options.getOption("user");
        console.printf("\n" + option.getDescription());
        response = console.readLine("\nEnter " + option.getLongOpt() + "(" + user + "): ");
        if (!response.isEmpty()) user = response;
      }
      // logfile
      logFile = "myna.log";
      if (!webctx.equals("/")) {
        logFile = webctx.substring(1) + ".log";
      }
      if (line.hasOption("logfile")) {
        logFile = line.getOptionValue("logfile");
      } else if (isInteractive && mode.equals("install")) {
        option = options.getOption("logfile");
        console.printf("\n" + option.getDescription());
        response = console.readLine("\nEnter " + option.getLongOpt() + "path(" + logFile + "): ");
        if (!response.isEmpty()) logFile = response;
      }

      // ssl-port
      if (line.hasOption("ssl-port")) {
        sslPort = Integer.parseInt(line.getOptionValue("ssl-port"));
      } else if (isInteractive && mode.equals("install")) {
        option = options.getOption("ssl-port");
        console.printf("\n" + option.getDescription());
        response = console.readLine("\nEnter " + option.getLongOpt() + "(" + sslPort + "): ");
        if (!response.isEmpty()) sslPort = Integer.parseInt(response);
      }
      // ks-pass
      if (line.hasOption("ks-pass")) {
        ksPass = line.getOptionValue("ks-pass");
      } else if (isInteractive && mode.equals("install")) {
        option = options.getOption("ks-pass");
        console.printf("\n" + option.getDescription());
        response = console.readLine("\nEnter " + option.getLongOpt() + "(" + ksPass + "): ");
        if (!response.isEmpty()) ksPass = response;
      }
      // ks-alias
      if (line.hasOption("ks-alias")) {
        ksAlias = line.getOptionValue("ks-alias");
      } else if (isInteractive && mode.equals("install")) {
        option = options.getOption("ks-alias");
        console.printf("\n" + option.getDescription());
        response = console.readLine("\nEnter " + option.getLongOpt() + "(" + ksAlias + "): ");
        if (!response.isEmpty()) ksAlias = response;
      }
      // keystore
      String appBase = new File(webroot).getCanonicalPath();
      if (keystore == null) {
        keystore = appBase + "/WEB-INF/myna/myna_keystore";
      }
      if (line.hasOption("keystore")) {
        keystore = line.getOptionValue("keystore");
      } else if (isInteractive && mode.equals("install")) {
        option = options.getOption("keystore");
        console.printf("\n" + option.getDescription());
        response = console.readLine("\nEnter " + option.getLongOpt() + "(" + keystore + "): ");
        if (!response.isEmpty()) keystore = response;
      }

      javaOpts = line.getArgList();
    } catch (ParseException exp) {
      System.err.println("Invalid Arguments.	Reason: " + exp.getMessage());

      formatter.printHelp(cmdSyntax, options);
      System.exit(1);
    }

    if (isInteractive) {
      System.out.println("\nProceeed with the following settings?:\n");
      System.out.println("mode        = " + mode);
      System.out.println("webroot     = " + webroot);
      if (mode.equals("install")) {
        System.out.println("port        = " + port);
        System.out.println("context     = " + webctx);
        System.out.println("servername  = " + serverName);
        System.out.println("user        = "******"logfile     = " + logFile);
        System.out.println("ssl-port    = " + sslPort);
        System.out.println("ks-pass     = "******"ks-alias    = " + ksAlias);
        System.out.println("keystore    = " + keystore);
      }
      response = console.readLine("Continue? (Y/n)");
      if (response.toLowerCase().equals("n")) System.exit(1);
    }
    File wrFile = new File(webroot);
    webroot = wrFile.toString();
    if (mode.equals("install")) {
      adminPassword = console.readLine("\nCreate an Admin password for this installation: ");
    }
    // unpack myna if necessary
    if (!wrFile.exists() || mode.equals("upgrade") || mode.equals("install")) {
      upgrade(wrFile);
    }

    if (mode.equals("install")) {
      File propertiesFile = new File(wrFile.toURI().resolve("WEB-INF/classes/general.properties"));
      FileInputStream propertiesFileIS = new FileInputStream(propertiesFile);
      Properties generalProperties = new Properties();
      generalProperties.load(propertiesFileIS);
      propertiesFileIS.close();
      if (!adminPassword.isEmpty()) {
        org.jasypt.util.password.StrongPasswordEncryptor cryptTool =
            new org.jasypt.util.password.StrongPasswordEncryptor();
        generalProperties.setProperty("admin_password", cryptTool.encryptPassword(adminPassword));
      }
      generalProperties.setProperty("instance_id", serverName);

      generalProperties.store(
          new java.io.FileOutputStream(propertiesFile), "Myna General Properties");

      String javaHome = System.getProperty("java.home");
      webroot = new File(webroot).getCanonicalPath();
      if (serverName.length() == 0) serverName = "myna";
      if (java.lang.System.getProperty("os.name").toLowerCase().indexOf("win") >= 0) {
        if (!new File(logFile).isAbsolute()) {
          logFile = new File(wrFile.toURI().resolve("WEB-INF/" + logFile)).toString();
        }
        File templateFile =
            new File(
                wrFile.toURI().resolve("WEB-INF/myna/install/windows/update_myna_service.cmd"));

        String initScript =
            FileUtils.readFileToString(templateFile)
                .replaceAll("\\{webctx\\}", webctx)
                .replaceAll("\\{server\\}", Matcher.quoteReplacement(serverName))
                .replaceAll("\\{webroot\\}", Matcher.quoteReplacement(webroot))
                .replaceAll("\\{logfile\\}", Matcher.quoteReplacement(logFile))
                .replaceAll("\\{javahome\\}", Matcher.quoteReplacement(javaHome))
                .replaceAll("\\{port\\}", new Integer(port).toString())
                .replaceAll("\\{sslPort\\}", new Integer(sslPort).toString())
                .replaceAll("\\{keystore\\}", Matcher.quoteReplacement(keystore))
                .replaceAll("\\{ksPass\\}", Matcher.quoteReplacement(ksPass))
                .replaceAll("\\{ksAlias\\}", Matcher.quoteReplacement(ksAlias));

        File scriptFile =
            new File(wrFile.toURI().resolve("WEB-INF/myna/install/update_myna_service.cmd"));

        FileUtils.writeStringToFile(scriptFile, initScript);

        // Runtime.getRuntime().exec("cmd /c start " + scriptFile.toString()).waitFor();

        System.out.println(
            "\nInstalled Service 'Myna App Server " + serverName + "' the following settings:\n");
        System.out.println(
            "\nInit script '" + scriptFile + "' created with the following settings:\n");
        System.out.println("memory=256MB");
        System.out.println("serverName=" + serverName);
        System.out.println("javaHome=" + javaHome);
        System.out.println("context=" + webctx);
        System.out.println("port=" + port);
        System.out.println("myna_home=" + webroot);
        System.out.println("logfile=" + logFile);

        System.out.println("sslPort=" + sslPort);
        System.out.println("keyStore=" + keystore);
        System.out.println("ksPass="******"ksAlias=" + ksAlias);

        System.out.println(
            "\nEdit and and run the command file in " + scriptFile + " to update this service");

      } else {
        String curUser = java.lang.System.getProperty("user.name");
        if (!curUser.equals("root")) {
          System.out.println("Install mode must be run as root.");
          System.exit(1);
        }

        if (!new File(logFile).isAbsolute()) {
          logFile = new File(wrFile.toURI().resolve("WEB-INF/" + logFile)).toString();
        }
        File templateFile =
            new File(wrFile.toURI().resolve("WEB-INF/myna/install/linux/init_script"));
        String initScript =
            FileUtils.readFileToString(templateFile)
                .replaceAll("\\{webctx\\}", webctx)
                .replaceAll("\\{server\\}", serverName)
                .replaceAll("\\{user\\}", user)
                .replaceAll("\\{webroot\\}", webroot)
                .replaceAll("\\{javahome\\}", javaHome)
                .replaceAll("\\{logfile\\}", logFile)
                .replaceAll("\\{port\\}", new Integer(port).toString())
                .replaceAll("\\{sslPort\\}", new Integer(sslPort).toString())
                .replaceAll("\\{keystore\\}", keystore)
                .replaceAll("\\{ksPass\\}", ksPass)
                .replaceAll("\\{ksAlias\\}", ksAlias);

        File scriptFile = new File(wrFile.toURI().resolve("WEB-INF/myna/install/" + serverName));

        FileUtils.writeStringToFile(scriptFile, initScript);

        if (new File("/etc/init.d").exists()) {

          exec("chown  -R " + user + " " + webroot);
          exec("chown root " + scriptFile.toString());
          exec("chmod 700 " + scriptFile.toString());
          exec("cp " + scriptFile.toString() + " /etc/init.d/");

          System.out.println(
              "\nInit script '/etc/init.d/"
                  + serverName
                  + "' created with the following settings:\n");
        } else {
          System.out.println(
              "\nInit script '" + scriptFile + "' created with the following settings:\n");
        }

        System.out.println("user="******"memory=256MB");
        System.out.println("server=" + serverName);
        System.out.println("context=" + webctx);
        System.out.println("port=" + port);
        System.out.println("myna_home=" + webroot);
        System.out.println("logfile=" + logFile);

        System.out.println("sslPort=" + sslPort);
        System.out.println("keyStore=" + keystore);
        System.out.println("ksPass="******"ksAlias=" + ksAlias);

        System.out.println("\nEdit this file to customize startup behavior");
      }
    }
  }