1   /*
2    * SPDX-FileCopyrightText: none
3    * SPDX-License-Identifier: CC0-1.0
4    */
5   
6   package dev.metaschema.cli.processor.command;
7   
8   import java.net.URI;
9   import java.net.URISyntaxException;
10  import java.nio.file.Path;
11  import java.nio.file.Paths;
12  
13  import dev.metaschema.core.util.ObjectUtils;
14  import dev.metaschema.core.util.UriUtils;
15  import edu.umd.cs.findbugs.annotations.NonNull;
16  import nl.talsmasoftware.lazy4j.Lazy;
17  
18  /**
19   * A base class for terminal commands in the command processing hierarchy.
20   * Terminal commands represent leaf nodes that perform actual operations and
21   * cannot have child commands.
22   */
23  public abstract class AbstractTerminalCommand implements ICommand {
24    private static Lazy<Path> currentWorkingDirectory = Lazy.of(() -> Paths.get(System.getProperty("user.dir")));
25  
26    /**
27     * A utility method that can be used to get the current working directory.
28     * <p>
29     * This method is thread-safe due to lazy initialization.
30     *
31     * @return the current working directory
32     */
33    @NonNull
34    protected static Path getCurrentWorkingDirectory() {
35      return ObjectUtils.notNull(currentWorkingDirectory.get());
36    }
37  
38    /**
39     * A utility method that can be used to resolve a path against the current
40     * working directory.
41     * <p>
42     * If the path is already absolute, then the provided path is returned.
43     *
44     * @param path
45     *          the path to resolve
46     *
47     * @return the resolved path
48     */
49    @NonNull
50    protected static Path resolveAgainstCWD(@NonNull Path path) {
51  
52      return path.isAbsolute()
53          ? path
54          : ObjectUtils.notNull(getCurrentWorkingDirectory().resolve(path).normalize());
55    }
56  
57    /**
58     * A utility method that can be used to resolve a URI against the URI for the
59     * current working directory.
60     * <p>
61     * If the URI is already absolute, then the provided URI is returned.
62     * <p>
63     * The path is normalized after resolution to remove any redundant name elements
64     * (like "." or "..").
65     *
66     *
67     * @param uri
68     *          the uri to resolve
69     *
70     * @return the resolved URI
71     */
72    @NonNull
73    protected static URI resolveAgainstCWD(@NonNull URI uri) {
74      return uri.isAbsolute()
75          ? uri
76          : ObjectUtils.notNull(getCurrentWorkingDirectory().toUri().resolve(uri.normalize()));
77    }
78  
79    /**
80     * A utility method that can be used to resolve a URI (as a string) against the
81     * URI for the current working directory.
82     *
83     * @param uri
84     *          the uri to resolve
85     * @return the resolved URI
86     * @throws URISyntaxException
87     *           if the provided URI is not a valid URI
88     */
89    @NonNull
90    protected static URI resolveAgainstCWD(@NonNull String uri) throws URISyntaxException {
91      return UriUtils.toUri(uri, ObjectUtils.notNull(getCurrentWorkingDirectory().toUri()));
92    }
93  }