|
26 | 26 | */
|
27 | 27 | package engineering.swat.watch;
|
28 | 28 |
|
| 29 | +import java.io.FileNotFoundException; |
29 | 30 | import java.io.IOException;
|
| 31 | +import java.nio.file.FileSystemException; |
30 | 32 | import java.nio.file.Files;
|
| 33 | +import java.nio.file.InvalidPathException; |
31 | 34 | import java.nio.file.LinkOption;
|
| 35 | +import java.nio.file.NoSuchFileException; |
| 36 | +import java.nio.file.NotDirectoryException; |
32 | 37 | import java.nio.file.Path;
|
33 | 38 | import java.util.concurrent.Executor;
|
34 | 39 | import java.util.function.BiConsumer;
|
@@ -76,28 +81,13 @@ private Watch(Path path, WatchScope scope) {
|
76 | 81 | * Watch a path for updates, optionally also get events for its children/descendants
|
77 | 82 | * @param path which absolute path to monitor, can be a file or a directory, but has to be absolute
|
78 | 83 | * @param scope for directories you can also choose to monitor it's direct children or all it's descendants
|
79 |
| - * @throws IllegalArgumentException in case a path is not supported (in relation to the scope) |
| 84 | + * @throws IllegalArgumentException in case a path is not supported |
80 | 85 | * @return watch builder that can be further configured and then started
|
81 | 86 | */
|
82 | 87 | public static Watch build(Path path, WatchScope scope) {
|
83 | 88 | if (!path.isAbsolute()) {
|
84 | 89 | throw new IllegalArgumentException("We can only watch absolute paths");
|
85 | 90 | }
|
86 |
| - switch (scope) { |
87 |
| - case PATH_AND_CHILDREN: // intended fallthrough |
88 |
| - case PATH_AND_ALL_DESCENDANTS: |
89 |
| - if (!Files.isDirectory(path, LinkOption.NOFOLLOW_LINKS)) { |
90 |
| - throw new IllegalArgumentException("Only directories are supported for this scope: " + scope); |
91 |
| - } |
92 |
| - break; |
93 |
| - case PATH_ONLY: |
94 |
| - if (Files.isSymbolicLink(path)) { |
95 |
| - throw new IllegalArgumentException("Symlinks are not supported"); |
96 |
| - } |
97 |
| - break; |
98 |
| - default: |
99 |
| - throw new IllegalArgumentException("Unsupported scope: " + scope); |
100 |
| - } |
101 | 91 | return new Watch(path, scope);
|
102 | 92 | }
|
103 | 93 |
|
@@ -192,16 +182,38 @@ public Watch onOverflow(Approximation whichFiles) {
|
192 | 182 | return this;
|
193 | 183 | }
|
194 | 184 |
|
| 185 | + private void validateOptions() throws IOException { |
| 186 | + if (this.eventHandler == EMPTY_HANDLER) { |
| 187 | + throw new IllegalStateException("There is no onEvent handler defined"); |
| 188 | + } |
| 189 | + if (!Files.exists(path)) { |
| 190 | + throw new FileSystemException(path.toString(), null, "Cannot open a watch on a non-existing path"); |
| 191 | + } |
| 192 | + switch (scope) { |
| 193 | + case PATH_AND_CHILDREN: // intended fallthrough |
| 194 | + case PATH_AND_ALL_DESCENDANTS: |
| 195 | + if (!Files.isDirectory(path, LinkOption.NOFOLLOW_LINKS)) { |
| 196 | + throw new FileSystemException(path.toString(), null, "Only directories are supported for this scope: " + scope); |
| 197 | + } |
| 198 | + break; |
| 199 | + case PATH_ONLY: |
| 200 | + if (Files.isSymbolicLink(path)) { |
| 201 | + throw new FileSystemException(path.toString(), null, "Symlinks are not supported"); |
| 202 | + } |
| 203 | + break; |
| 204 | + default: |
| 205 | + throw new IllegalArgumentException("Unsupported scope: " + scope); |
| 206 | + } |
| 207 | + } |
| 208 | + |
195 | 209 | /**
|
196 | 210 | * Start watch the path for events.
|
197 | 211 | * @return a subscription for the watch, when closed, new events will stop being registered to the worker pool.
|
198 |
| - * @throws IOException in case the starting of the watcher caused an underlying IO exception |
| 212 | + * @throws IOException in case the starting of the watcher caused an underlying IO exception or we detect it is an invalid watch |
199 | 213 | * @throws IllegalStateException the watchers is not configured correctly (for example, missing {@link #on(Consumer)}, or a watcher is started twice)
|
200 | 214 | */
|
201 | 215 | public ActiveWatch start() throws IOException {
|
202 |
| - if (this.eventHandler == EMPTY_HANDLER) { |
203 |
| - throw new IllegalStateException("There is no onEvent handler defined"); |
204 |
| - } |
| 216 | + validateOptions(); |
205 | 217 | var executor = this.executor;
|
206 | 218 | if (executor == null) {
|
207 | 219 | executor = FALLBACK_EXECUTOR;
|
|
0 commit comments