Skip to content
This repository was archived by the owner on Mar 14, 2025. It is now read-only.

Commit fc3f932

Browse files
Refinded docs
1 parent 13608b8 commit fc3f932

File tree

2 files changed

+158
-89
lines changed

2 files changed

+158
-89
lines changed

src/main/java/org/cryptomator/cloudaccess/api/CloudProvider.java

Lines changed: 147 additions & 89 deletions
Original file line numberDiff line numberDiff line change
@@ -6,106 +6,164 @@
66
import java.util.concurrent.CompletableFuture;
77
import java.util.concurrent.CompletionStage;
88

9+
/**
10+
* Common interface of all providers that provide access to a certain cloud.
11+
* Due to the nature of remotely stored data, every operation is expected to take while to complete. Implementers of this
12+
* API are expected to immediately return a {@link CompletionStage} (e.g. by facilitating {@link CompletableFuture}) and
13+
* perform the actual cloud access async. In case of exceptions, it must be guaranteed that the <code>CompletionStage</code>
14+
* is still completed, e.g. using {@link CompletableFuture#completeExceptionally(Throwable)}.
15+
* Consumers of this API are expected to handle timeouts when handling the result of a <code>CompletionStage</code>.
16+
*/
917
public interface CloudProvider {
1018

11-
/**
12-
* Fetches the metadata for a file or folder.
13-
*
14-
* @param node The remote path of the file or folder, whose metadata to fetch.
15-
* @return CompletionStage with the metadata for a file or folder. If the fetch fails, it completes exceptionally.
16-
*/
17-
CompletionStage<CloudItemMetadata> itemMetadata(Path node);
19+
/**
20+
* Fetches the metadata for a file or folder.
21+
* <p>
22+
* The returned CompletionStage might complete exceptionally with one of the following exceptions:
23+
* <ul>
24+
* <li>{@link java.nio.file.NoSuchFileException} If no item exists for the given path</li>
25+
* <li>{@link java.io.IOException} in case of generic I/O errors</li>
26+
* </ul>
27+
*
28+
* @param node The remote path of the file or folder, whose metadata to fetch.
29+
* @return CompletionStage with the metadata for a file or folder. If the fetch fails, it completes exceptionally.
30+
*/
31+
CompletionStage<CloudItemMetadata> itemMetadata(Path node);
1832

19-
/**
20-
* Starts fetching the contents of a folder.
21-
* If the result's <code>CloudItemList</code> has a <code>nextPageToken</code>, calling this method again with the provided token will continue listing.
22-
* If on the other hand the end of the list is reached, <code>nextPageToken</code> will be absent.
23-
*
24-
* @param folder The remote path of the folder to list.
25-
* @param pageToken An optional {@link CloudItemList#getNextPageToken() nextPageToken} to continue a previous listing
26-
* @return CompletionStage with a potentially incomplete list of items.
27-
*/
28-
CompletionStage<CloudItemList> list(Path folder, Optional<String> pageToken);
33+
/**
34+
* Starts fetching the contents of a folder.
35+
* If the result's <code>CloudItemList</code> has a <code>nextPageToken</code>, calling this method again with the provided token will continue listing.
36+
* If on the other hand the end of the list is reached, <code>nextPageToken</code> will be absent.
37+
* <p>
38+
* The returned CompletionStage might complete exceptionally with one of the following exceptions:
39+
* <ul>
40+
* <li>{@link java.nio.file.NoSuchFileException} If no item exists for the given path</li>
41+
* <li>{@link java.nio.file.NotDirectoryException} If the path doesn't represent a folder</li>
42+
* <li>{@link java.io.IOException} in case of generic I/O errors</li>
43+
* <li>{@link InvalidPageTokenException} if <code>pageToekn</code> is invalid</li>
44+
* </ul>
45+
*
46+
* @param folder The remote path of the folder to list.
47+
* @param pageToken An optional {@link CloudItemList#getNextPageToken() nextPageToken} to continue a previous listing
48+
* @return CompletionStage with a potentially incomplete list of items.
49+
*/
50+
CompletionStage<CloudItemList> list(Path folder, Optional<String> pageToken);
2951

30-
/**
31-
* Convenience wrapper for {@link #list(Path, Optional)} that fetches all items.
32-
*
33-
* @param folder The remote path of the folder to list.
34-
* @return CompletionStage with a complete list of items.
35-
*/
36-
default CompletionStage<CloudItemList> listExhaustively(Path folder) {
37-
return listExhaustively(this, folder, CloudItemList.empty());
38-
}
52+
/**
53+
* Convenience wrapper for {@link #list(Path, Optional)} that fetches all items.
54+
*
55+
* @param folder The remote path of the folder to list.
56+
* @return CompletionStage with a complete list of items.
57+
* @see #list(Path, Optional)
58+
*/
59+
default CompletionStage<CloudItemList> listExhaustively(Path folder) {
60+
return listExhaustively(this, folder, CloudItemList.empty());
61+
}
3962

40-
private static CompletionStage<CloudItemList> listExhaustively(CloudProvider provider, Path folder, CloudItemList itemList) {
41-
return provider.list(folder, itemList.getNextPageToken()).thenCompose(nextItems -> {
42-
var combined = itemList.add(nextItems.getItems(), nextItems.getNextPageToken());
43-
if (nextItems.getNextPageToken().isPresent()) {
44-
return listExhaustively(provider, folder, combined);
45-
} else {
46-
return CompletableFuture.completedStage(combined);
47-
}
48-
});
49-
}
63+
private static CompletionStage<CloudItemList> listExhaustively(CloudProvider provider, Path folder, CloudItemList itemList) {
64+
return provider.list(folder, itemList.getNextPageToken()).thenCompose(nextItems -> {
65+
var combined = itemList.add(nextItems.getItems(), nextItems.getNextPageToken());
66+
if (nextItems.getNextPageToken().isPresent()) {
67+
return listExhaustively(provider, folder, combined);
68+
} else {
69+
return CompletableFuture.completedStage(combined);
70+
}
71+
});
72+
}
5073

51-
/**
52-
* Reads from the given file.
53-
*
54-
* @param file A remote path referencing a file
55-
* @param progressListener TODO Future use
56-
* @return CompletionStage with an InputStream to read from. If accessing the file fails, it'll complete exceptionally.
57-
*/
58-
default CompletionStage<InputStream> read(Path file, ProgressListener progressListener) {
59-
return read(file, 0, Long.MAX_VALUE, progressListener);
60-
}
74+
/**
75+
* Reads from the given file.
76+
* <p>
77+
* The returned CompletionStage might complete exceptionally with the same exceptions as specified in {@link #read(Path, long, long, ProgressListener)}.
78+
*
79+
* @param file A remote path referencing a file
80+
* @param progressListener TODO Future use
81+
* @return CompletionStage with an InputStream to read from. If accessing the file fails, it'll complete exceptionally.
82+
* @see #read(Path, long, long, ProgressListener)
83+
*/
84+
default CompletionStage<InputStream> read(Path file, ProgressListener progressListener) {
85+
return read(file, 0, Long.MAX_VALUE, progressListener);
86+
}
6187

62-
/**
63-
* Reads part of a given file.
64-
*
65-
* @param file A remote path referencing a file
66-
* @param offset The first byte (inclusive) to read.
67-
* @param count The number of bytes requested. Can exceed the actual file length. Set to {@link Long#MAX_VALUE} to read till EOF.
68-
* @param progressListener TODO Future use
69-
* @return CompletionStage with an InputStream to read from. If accessing the file fails, it'll complete exceptionally.
70-
*/
71-
CompletionStage<InputStream> read(Path file, long offset, long count, ProgressListener progressListener);
88+
/**
89+
* Reads part of a given file.
90+
* <p>
91+
* The returned CompletionStage might complete exceptionally with one of the following exceptions:
92+
* <ul>
93+
* <li>{@link java.nio.file.NoSuchFileException} If no item exists for the given path</li>
94+
* <li>{@link java.io.IOException} in case of generic I/O errors</li>
95+
* </ul>
96+
*
97+
* @param file A remote path referencing a file
98+
* @param offset The first byte (inclusive) to read.
99+
* @param count The number of bytes requested. Can exceed the actual file length. Set to {@link Long#MAX_VALUE} to read till EOF.
100+
* @param progressListener TODO Future use
101+
* @return CompletionStage with an InputStream to read from. If accessing the file fails, it'll complete exceptionally.
102+
*/
103+
CompletionStage<InputStream> read(Path file, long offset, long count, ProgressListener progressListener);
72104

73-
/**
74-
* Writes to a given file, creating it if it doesn't exist yet.
75-
*
76-
* @param file A remote path referencing a file
77-
* @param replace Flag indicating whether to overwrite the file if it already exists.
78-
* @param data A data source from which to copy contents to the remote file
79-
* @param progressListener TODO Future use
80-
* @return CompletionStage that will be completed after writing all <code>data</code> and holds the new metadata of the item referenced by <code>file</code>.
81-
*/
82-
CompletionStage<CloudItemMetadata> write(Path file, boolean replace, InputStream data, ProgressListener progressListener);
105+
/**
106+
* Writes to a given file, creating it if it doesn't exist yet.
107+
* <p>
108+
* The returned CompletionStage might complete exceptionally with one of the following exceptions:
109+
* <ul>
110+
* <li>{@link java.nio.file.NoSuchFileException} If the parent directory of this file doesn't exist</li>
111+
* <li>{@link java.nio.file.FileAlreadyExistsException} If a node with the given path already exists and <code>replace</code> is false</li>
112+
* <li>{@link java.io.IOException} in case of generic I/O errors</li>
113+
* </ul>
114+
*
115+
* @param file A remote path referencing a file
116+
* @param replace Flag indicating whether to overwrite the file if it already exists.
117+
* @param data A data source from which to copy contents to the remote file
118+
* @param progressListener TODO Future use
119+
* @return CompletionStage that will be completed after writing all <code>data</code> and holds the new metadata of the item referenced by <code>file</code>.
120+
*/
121+
CompletionStage<CloudItemMetadata> write(Path file, boolean replace, InputStream data, ProgressListener progressListener);
83122

84-
/**
85-
* Create a folder. Does not create any potentially missing parent directories.
86-
*
87-
* @param folder The remote path of the folder to create.
88-
* @return CompletionStage with the same path as <code>folder</code> if created successfully.
89-
*/
90-
CompletionStage<Path> createFolder(Path folder);
123+
/**
124+
* Create a folder. Does not create any potentially missing parent directories.
125+
* <p>
126+
* The returned CompletionStage might complete exceptionally with one of the following exceptions:
127+
* <ul>
128+
* <li>{@link java.nio.file.FileAlreadyExistsException} If a node with the given path already exists</li>
129+
* <li>{@link java.io.IOException} in case of generic I/O errors</li>
130+
* </ul>
131+
*
132+
* @param folder The remote path of the folder to create.
133+
* @return CompletionStage with the same path as <code>folder</code> if created successfully.
134+
*/
135+
CompletionStage<Path> createFolder(Path folder);
91136

92-
/**
93-
* Recursively delete a file or folder.
94-
*
95-
* @param node The remote path of the file or folder to delete.
96-
* @return CompletionStage completing successfully if node was deleted.
97-
*/
98-
CompletionStage<Void> delete(Path node);
137+
/**
138+
* Recursively delete a file or folder.
139+
* <p>
140+
* The returned CompletionStage might complete exceptionally with one of the following exceptions:
141+
* <ul>
142+
* <li>{@link java.nio.file.NoSuchFileException} If no item exists for the given path</li>
143+
* <li>{@link java.io.IOException} in case of generic I/O errors</li>
144+
* </ul>
145+
*
146+
* @param node The remote path of the file or folder to delete.
147+
* @return CompletionStage completing successfully if node was deleted.
148+
*/
149+
CompletionStage<Void> delete(Path node);
99150

100-
/**
101-
* Move a file or folder to a different location.
102-
*
103-
* @param source The remote path of the file or folder to be moved.
104-
* @param target The remote path of the desired destination.
105-
* @param replace Flag indicating whether to overwrite <code>target</code> if it already exists.
106-
* @return CompletionStage completing successfully if node was moved.
107-
*/
108-
CompletionStage<Path> move(Path source, Path target, boolean replace);
151+
/**
152+
* Move a file or folder to a different location.
153+
* <p>
154+
* The returned CompletionStage might complete exceptionally with one of the following exceptions:
155+
* <ul>
156+
* <li>{@link java.nio.file.NoSuchFileException} If no item exists for the given source path</li>
157+
* <li>{@link java.nio.file.FileAlreadyExistsException} If a node with the given target path already exists and <code>replace</code> is false</li>
158+
* <li>{@link java.io.IOException} in case of generic I/O errors</li>
159+
* </ul>
160+
*
161+
* @param source The remote path of the file or folder to be moved.
162+
* @param target The remote path of the desired destination.
163+
* @param replace Flag indicating whether to overwrite <code>target</code> if it already exists.
164+
* @return CompletionStage completing successfully if node was moved.
165+
*/
166+
CompletionStage<Path> move(Path source, Path target, boolean replace);
109167

110168
}
111169

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
package org.cryptomator.cloudaccess.api;
2+
3+
public class InvalidPageTokenException extends IllegalArgumentException {
4+
public InvalidPageTokenException(String message) {
5+
super(message);
6+
}
7+
8+
public InvalidPageTokenException(String message, Throwable cause) {
9+
super(message, cause);
10+
}
11+
}

0 commit comments

Comments
 (0)