001/*
002 * SPDX-FileCopyrightText: none
003 * SPDX-License-Identifier: CC0-1.0
004 */
005
006package dev.metaschema.cli.processor.command;
007
008import java.net.URI;
009import java.net.URISyntaxException;
010import java.nio.file.Path;
011import java.nio.file.Paths;
012
013import dev.metaschema.core.util.ObjectUtils;
014import dev.metaschema.core.util.UriUtils;
015import edu.umd.cs.findbugs.annotations.NonNull;
016import nl.talsmasoftware.lazy4j.Lazy;
017
018/**
019 * A base class for terminal commands in the command processing hierarchy.
020 * Terminal commands represent leaf nodes that perform actual operations and
021 * cannot have child commands.
022 */
023public abstract class AbstractTerminalCommand implements ICommand {
024  private static Lazy<Path> currentWorkingDirectory = Lazy.of(() -> Paths.get(System.getProperty("user.dir")));
025
026  /**
027   * A utility method that can be used to get the current working directory.
028   * <p>
029   * This method is thread-safe due to lazy initialization.
030   *
031   * @return the current working directory
032   */
033  @NonNull
034  protected static Path getCurrentWorkingDirectory() {
035    return ObjectUtils.notNull(currentWorkingDirectory.get());
036  }
037
038  /**
039   * A utility method that can be used to resolve a path against the current
040   * working directory.
041   * <p>
042   * If the path is already absolute, then the provided path is returned.
043   *
044   * @param path
045   *          the path to resolve
046   *
047   * @return the resolved path
048   */
049  @NonNull
050  protected static Path resolveAgainstCWD(@NonNull Path path) {
051
052    return path.isAbsolute()
053        ? path
054        : ObjectUtils.notNull(getCurrentWorkingDirectory().resolve(path).normalize());
055  }
056
057  /**
058   * A utility method that can be used to resolve a URI against the URI for the
059   * current working directory.
060   * <p>
061   * If the URI is already absolute, then the provided URI is returned.
062   * <p>
063   * The path is normalized after resolution to remove any redundant name elements
064   * (like "." or "..").
065   *
066   *
067   * @param uri
068   *          the uri to resolve
069   *
070   * @return the resolved URI
071   */
072  @NonNull
073  protected static URI resolveAgainstCWD(@NonNull URI uri) {
074    return uri.isAbsolute()
075        ? uri
076        : ObjectUtils.notNull(getCurrentWorkingDirectory().toUri().resolve(uri.normalize()));
077  }
078
079  /**
080   * A utility method that can be used to resolve a URI (as a string) against the
081   * URI for the current working directory.
082   *
083   * @param uri
084   *          the uri to resolve
085   * @return the resolved URI
086   * @throws URISyntaxException
087   *           if the provided URI is not a valid URI
088   */
089  @NonNull
090  protected static URI resolveAgainstCWD(@NonNull String uri) throws URISyntaxException {
091    return UriUtils.toUri(uri, ObjectUtils.notNull(getCurrentWorkingDirectory().toUri()));
092  }
093}