001/*
002 * Copyright (C) 2022 - 2024, the original author or authors.
003 *
004 * Licensed under the Apache License, Version 2.0 (the "License");
005 * you may not use this file except in compliance with the License.
006 * You may obtain a copy of the License at
007 *
008 *    http://www.apache.org/licenses/LICENSE-2.0
009 *
010 * Unless required by applicable law or agreed to in writing, software
011 * distributed under the License is distributed on an "AS IS" BASIS,
012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
013 * See the License for the specific language governing permissions and
014 * limitations under the License.
015 */
016package io.github.ascopes.jct.workspaces;
017
018import java.io.Closeable;
019import java.io.IOException;
020import java.util.List;
021import org.apiguardian.api.API;
022import org.apiguardian.api.API.Status;
023
024/**
025 * Base interface for a managed directory, including the interfaces for creating fluent-style
026 * builders.
027 *
028 * @author Ashley Scopes
029 * @since 0.0.1
030 */
031@API(since = "0.0.1", status = Status.STABLE)
032public interface ManagedDirectory extends DirectoryBuilder, PathRoot {
033
034  /**
035   * Method that returns the object it is called upon to enable creating fluent-language builders.
036   *
037   * <p>For example:
038   *
039   * <pre><code>
040   *   thisDirectory
041   *       .createFile("foo", "bar", "baz.txt").withContents(...)
042   *       .and().also()
043   *       .createFile("foo", "bar", "bork.txt").withContents(...);
044   * </code></pre>
045   *
046   * @return this object.
047   * @see #and
048   * @see #then
049   */
050  default ManagedDirectory also() {
051    return this;
052  }
053
054  /**
055   * Method that returns the object it is called upon to enable creating fluent-language builders.
056   *
057   * <p>For example:
058   *
059   * <pre><code>
060   *   thisDirectory
061   *       .createFile("foo", "bar", "baz.txt").withContents(...)
062   *       .and()
063   *       .createFile("foo", "bar", "bork.txt").withContents(...);
064   * </code></pre>
065   *
066   * @return this object.
067   * @see #also
068   * @see #then
069   */
070  default ManagedDirectory and() {
071    return this;
072  }
073
074  /**
075   * Close the resource.
076   *
077   * <p>This specifically is not provided by implementing {@link Closeable} as to prevent IDEs
078   * giving false linting errors about not closing resources.
079   *
080   * <p>Users should not need to call this directly if they are using instances produced from a
081   * {@link Workspace} implementation.
082   *
083   * @throws IOException if an IO exception occurs.
084   */
085  void close() throws IOException;
086
087  /**
088   * Create a directory builder for the given path in this RAM file system.
089   *
090   * <p>Examples:
091   *
092   * <pre><code>
093   *   // Using platform-specific separators.
094   *   dir.createDirectory("foo/bar/baz")...;
095   *
096   *   // Letting JCT infer the correct path separators to use (recommended).
097   *   dir.createDirectory("foo", "bar", "baz")...;
098   * </code></pre>
099   *
100   * @param fragments the parts of the path.
101   * @return the directory builder.
102   * @throws IllegalArgumentException if no path fragments are provided.
103   * @throws NullPointerException     if any of the path fragments are {@code null}.
104   */
105  default DirectoryBuilder createDirectory(String... fragments) {
106    return createDirectory(List.of(fragments));
107  }
108
109  /**
110   * Create a directory builder for the given path in this RAM file system.
111   *
112   * <p>Examples:
113   *
114   * <pre><code>
115   *   // Using platform-specific separators.
116   *   dir.createDirectory(List.of("foo/bar/baz"))...;
117   *
118   *   // Letting JCT infer the correct path separators to use (recommended).
119   *   dir.createDirectory(List.of("foo", "bar", "baz"))...;
120   * </code></pre>
121   *
122   * @param fragments the parts of the path.
123   * @return the directory builder.
124   * @throws IllegalArgumentException if no path fragments are provided.
125   * @throws NullPointerException     if any of the path fragments are {@code null}.
126   * @since 4.0.0
127   */
128  @API(since = "4.0.0", status = Status.STABLE)
129  DirectoryBuilder createDirectory(List<String> fragments);
130
131  /**
132   * Create a file builder for the given path in this RAM file system.
133   *
134   * <pre><code>
135   *   // Using platform-specific separators.
136   *   dir.createFile("foo/bar/baz.txt")...;
137   *
138   *   // Letting JCT infer the correct path separators to use (recommended).
139   *   dir.createFile("foo", "bar", "baz.txt")...;
140   * </code></pre>
141   *
142   * @param fragments the parts of the path.
143   * @return the file builder.
144   * @throws IllegalArgumentException if no path fragments are provided.
145   * @throws NullPointerException     if any of the path fragments are {@code null}.
146   */
147  default FileBuilder createFile(String... fragments) {
148    return createFile(List.of(fragments));
149  }
150
151  /**
152   * Create a file builder for the given path in this RAM file system.
153   *
154   * <pre><code>
155   *   // Using platform-specific separators.
156   *   dir.createFile(List.of("foo/bar/baz.txt"))...;
157   *
158   *   // Letting JCT infer the correct path separators to use (recommended).
159   *   dir.createFile(List.of("foo", "bar", "baz.txt"))...;
160   * </code></pre>
161   *
162   * @param fragments the parts of the path.
163   * @return the file builder.
164   * @throws IllegalArgumentException if no path fragments are provided.
165   * @throws NullPointerException     if any of the path fragments are {@code null}.
166   * @since 4.0.0
167   */
168  @API(since = "4.0.0", status = Status.STABLE)
169  FileBuilder createFile(List<String> fragments);
170
171  /**
172   * Get the identifying name of the temporary file system.
173   *
174   * @return the identifier string.
175   */
176  String getName();
177
178  /**
179   * Method that returns the object it is called upon to enable creating fluent-language builders.
180   *
181   * <p>For example:
182   *
183   * <pre><code>
184   *   thisDirectory
185   *       .createFile("foo", "bar", "baz.txt").withContents(...)
186   *       .and().then()
187   *       .createFile("foo", "bar", "bork.txt").withContents(...);
188   * </code></pre>
189   *
190   * @return this object.
191   * @see #and
192   * @see #also
193   */
194  default ManagedDirectory then() {
195    return this;
196  }
197
198}