feat: add exception handling

This commit is contained in:
Manuel Jenny 2021-03-19 13:54:48 +01:00
parent 1146a5e8fc
commit 2fcf53b633
No known key found for this signature in database
GPG Key ID: 1C80FE62B2BEAA18
4 changed files with 283 additions and 185 deletions

View File

@ -0,0 +1,90 @@
package org.cryptomator.data.cloud.pcloud;
public class PCloudApiError {
public enum PCloudApiErrorCodes {
LOGIN_REQUIRED(1000),
NO_FULL_PATH_OR_NAME_FOLDER_ID_PROVIDED(1001),
NO_FULL_PATH_OR_FOLDER_ID_PROVIDED(1002),
NO_FILE_ID_OR_PATH_PROVIDED(1004),
INVALID_DATE_TIME_FORMAT(1013),
NO_DESTINATION_PROVIDED(1016),
INVALID_FOLDER_ID(1017),
INVALID_DESTINATION(1037),
PROVIDE_URL(1040),
UPLOAD_NOT_FOUND(1900),
TRANSFER_NOT_FOUND(1902),
LOGIN_FAILED(2000),
INVALID_FILE_OR_FOLDER_NAME(2001),
COMPONENT_OF_PARENT_DIRECTORY_DOES_NOT_EXIST(2002),
ACCESS_DENIED(2003),
FILE_OR_FOLDER_ALREADY_EXISTS(2004),
DIRECTORY_DOES_NOT_EXIST(2005),
FOLDER_NOT_EMPTY(2006),
CANNOT_DELETE_ROOT_FOLDER(2007),
USER_OVER_QUOTA(2008),
FILE_NOT_FOUND(2009),
INVALID_PATH(2010),
SHARED_FOLDER_IN_SHARED_FOLDER(2023),
ACTIVE_SHARES_OR_SHAREREQUESTS_PRESENT(2028),
CONNECTION_BROKE(2041),
CANNOT_RENAME_ROOT_FOLDER(2042),
CANNOT_MOVE_FOLDER_INTO_SUBFOLDER_OF_ITSELF(2043),
FILE_OR_FOLDER_NOT_FOUND(2055),
NO_FILE_UPLOAD_DETECTED(2088),
INVALID_ACCESS_TOKEN(2094),
ACCESS_TOKEN_REVOKED(2095),
TRANSFER_OVER_QUOTA(2097),
TARGET_FOLDER_DOES_NOT_EXIST(2208),
TOO_MANY_LOGIN_TRIES_FROM_IP(4000),
INTERNAL_ERROR(5000),
INTERNAL_UPLOAD_ERROR(5001);
private final int value;
PCloudApiErrorCodes(final int newValue) {
value = newValue;
}
public int getValue() {
return value;
}
}
public static boolean isCloudNodeAlreadyExistsException(int errorCode) {
return errorCode == PCloudApiErrorCodes.FILE_OR_FOLDER_ALREADY_EXISTS.getValue();
}
public static boolean isFatalBackendException(int errorCode) {
return errorCode == PCloudApiErrorCodes.INTERNAL_UPLOAD_ERROR.getValue()
|| errorCode == PCloudApiErrorCodes.INTERNAL_UPLOAD_ERROR.getValue()
|| errorCode == PCloudApiErrorCodes.UPLOAD_NOT_FOUND.getValue()
|| errorCode == PCloudApiErrorCodes.TRANSFER_NOT_FOUND.getValue();
}
public static boolean isForbiddenException(int errorCode) {
return errorCode == PCloudApiErrorCodes.ACCESS_DENIED.getValue();
}
public static boolean isNetworkConnectionException(int errorCode) {
return errorCode == PCloudApiErrorCodes.CONNECTION_BROKE.getValue();
}
public static boolean isNoSuchCloudFileException(int errorCode) {
return errorCode == PCloudApiErrorCodes.FILE_NOT_FOUND.getValue()
|| errorCode == PCloudApiErrorCodes.FILE_OR_FOLDER_NOT_FOUND.getValue()
|| errorCode == PCloudApiErrorCodes.DIRECTORY_DOES_NOT_EXIST.getValue();
}
public static boolean isWrongCredentialsException(int errorCode) {
return errorCode == PCloudApiErrorCodes.INVALID_ACCESS_TOKEN.getValue()
|| errorCode == PCloudApiErrorCodes.ACCESS_TOKEN_REVOKED.getValue();
}
public static boolean isUnauthorizedException(int errorCode) {
return errorCode == PCloudApiErrorCodes.LOGIN_FAILED.getValue()
|| errorCode == PCloudApiErrorCodes.LOGIN_REQUIRED.getValue()
|| errorCode == PCloudApiErrorCodes.TOO_MANY_LOGIN_TRIES_FROM_IP.getValue();
}
}

View File

@ -1,39 +0,0 @@
package org.cryptomator.data.cloud.pcloud;
public enum PCloudApiErrorCodes {
LOGIN_REQUIRED(1000),
NO_FULL_PATH_OR_NAME_FOLDER_ID_PROVIDED(1001),
NO_FULL_PATH_OR_FOLDER_ID_PROVIDED(1002),
NO_DESTINATION_PROVIDED(1016),
INVALID_FOLDER_ID(1017),
INVALID_DESTINATION(1037),
PROVIDE_URL(1040),
LOGIN_FAILED(2000),
INVALID_FILE_OR_FOLDER_NAME(2001),
COMPONENT_OF_PARENT_DIRECTORY_DOES_NOT_EXIST(2002),
ACCESS_DENIED(2003),
FILE_OR_FOLDER_ALREADY_EXISTS(2004),
DIRECTORY_DOES_NOT_EXIST(2005),
FOLDER_NOT_EMPTY(2006),
CANNOT_DELETE_ROOT_FOLDER(2007),
USER_OVER_QUOTA(2008),
FILE_NOT_FOUND(2009),
SHARED_FOLDER_IN_SHARED_FOLDER(2023),
ACTIVE_SHARES_OR_SHAREREQUESTS_PRESENT(2028),
CANNOT_RENAME_ROOT_FOLDER(2042),
CANNOT_MOVE_FOLDER_INTO_SUBFOLDER_OF_ITSELF(2043),
FILE_OR_FOLDER_NOT_FOUND(2055),
INVALID_ACCESS_TOKEN(2094),
ACCESS_TOKEN_REVOKED(2095),
TOO_MANY_LOGIN_TRIES_FROM_IP(4000),
INTERNAL_ERROR(5000),
INTERNAL_UPLOAD_ERROR(5001);
private final int value;
PCloudApiErrorCodes(final int newValue) {
value = newValue;
}
public int getValue() { return value; }
}

View File

@ -50,7 +50,8 @@ class PCloudContentRepository extends InterceptingCloudContentRepository<PCloud,
private void throwWrongCredentialsExceptionIfRequired(Exception e) {
if (e instanceof ApiError) {
int errorCode = ((ApiError)e).errorCode();
if (errorCode == PCloudApiErrorCodes.INVALID_ACCESS_TOKEN.getValue() || errorCode == PCloudApiErrorCodes.ACCESS_TOKEN_REVOKED.getValue()) {
if (errorCode == PCloudApiError.PCloudApiErrorCodes.INVALID_ACCESS_TOKEN.getValue()
|| errorCode == PCloudApiError.PCloudApiErrorCodes.ACCESS_TOKEN_REVOKED.getValue()) {
throw new WrongCredentialsException(cloud);
}
}
@ -69,30 +70,46 @@ class PCloudContentRepository extends InterceptingCloudContentRepository<PCloud,
}
@Override
public PCloudFolder resolve(PCloud cloud, String path) {
return this.cloud.resolve(path);
public PCloudFolder resolve(PCloud cloud, String path) throws BackendException {
try {
return this.cloud.resolve(path);
} catch(IOException ex) {
throw new FatalBackendException(ex);
}
}
@Override
public PCloudFile file(PCloudFolder parent, String name) {
return cloud.file(parent, name);
public PCloudFile file(PCloudFolder parent, String name) throws BackendException {
try {
return cloud.file(parent, name);
} catch(IOException ex) {
throw new FatalBackendException(ex);
}
}
@Override
public PCloudFile file(PCloudFolder parent, String name, Optional<Long> size) throws BackendException {
return cloud.file(parent, name, size);
try {
return cloud.file(parent, name, size);
} catch(IOException ex) {
throw new FatalBackendException(ex);
}
}
@Override
public PCloudFolder folder(PCloudFolder parent, String name) {
return cloud.folder(parent, name);
public PCloudFolder folder(PCloudFolder parent, String name) throws BackendException {
try {
return cloud.folder(parent, name);
} catch(IOException ex) {
throw new FatalBackendException(ex);
}
}
@Override
public boolean exists(PCloudNode node) throws BackendException {
try {
return cloud.exists(node);
} catch (ApiError|IOException e) {
} catch (IOException e) {
throw new FatalBackendException(e);
}
}
@ -101,12 +118,7 @@ class PCloudContentRepository extends InterceptingCloudContentRepository<PCloud,
public List<PCloudNode> list(PCloudFolder folder) throws BackendException {
try {
return cloud.list(folder);
} catch (ApiError | IOException e) {
if (e instanceof ApiError) {
if (((ApiError) e).errorCode() == PCloudApiErrorCodes.DIRECTORY_DOES_NOT_EXIST.getValue()) {
throw new NoSuchCloudFileException();
}
}
} catch (IOException e) {
throw new FatalBackendException(e);
}
}
@ -115,11 +127,7 @@ class PCloudContentRepository extends InterceptingCloudContentRepository<PCloud,
public PCloudFolder create(PCloudFolder folder) throws BackendException {
try {
return cloud.create(folder);
} catch (ApiError | IOException e) {
if (e instanceof ApiError) {
if (((ApiError) e).errorCode() == PCloudApiErrorCodes.FILE_OR_FOLDER_ALREADY_EXISTS.getValue())
throw new CloudNodeAlreadyExistsException(folder.getName());
}
} catch (IOException e) {
throw new FatalBackendException(e);
}
}
@ -128,15 +136,7 @@ class PCloudContentRepository extends InterceptingCloudContentRepository<PCloud,
public PCloudFolder move(PCloudFolder source, PCloudFolder target) throws BackendException {
try {
return (PCloudFolder) cloud.move(source, target);
} catch (ApiError | IOException e) {
if (e instanceof ApiError) {
if (((ApiError)e).errorCode() == PCloudApiErrorCodes.DIRECTORY_DOES_NOT_EXIST.getValue()) {
throw new NoSuchCloudFileException(source.getName());
} else if (((ApiError)e).errorCode() == PCloudApiErrorCodes.FILE_OR_FOLDER_ALREADY_EXISTS.getValue()) {
throw new CloudNodeAlreadyExistsException(target.getName());
}
throw new CloudNodeAlreadyExistsException(target.getName());
}
} catch (IOException e) {
throw new FatalBackendException(e);
}
}
@ -145,15 +145,7 @@ class PCloudContentRepository extends InterceptingCloudContentRepository<PCloud,
public PCloudFile move(PCloudFile source, PCloudFile target) throws BackendException {
try {
return (PCloudFile) cloud.move(source, target);
} catch (ApiError | IOException e) {
if (e instanceof ApiError) {
if (((ApiError)e).errorCode() == PCloudApiErrorCodes.FILE_NOT_FOUND.getValue()) {
throw new NoSuchCloudFileException(source.getName());
} else if (((ApiError)e).errorCode() == PCloudApiErrorCodes.FILE_OR_FOLDER_ALREADY_EXISTS.getValue()) {
throw new CloudNodeAlreadyExistsException(target.getName());
}
throw new CloudNodeAlreadyExistsException(target.getName());
}
} catch (IOException e) {
throw new FatalBackendException(e);
}
}
@ -162,10 +154,7 @@ class PCloudContentRepository extends InterceptingCloudContentRepository<PCloud,
public PCloudFile write(PCloudFile uploadFile, DataSource data, ProgressAware<UploadState> progressAware, boolean replace, long size) throws BackendException {
try {
return cloud.write(uploadFile, data, progressAware, replace, size);
} catch (ApiError | IOException e) {
if (e instanceof ApiError && ((ApiError)e).errorCode() == PCloudApiErrorCodes.FILE_NOT_FOUND.getValue()) {
throw new NoSuchCloudFileException(uploadFile.getName());
}
} catch (IOException e) {
throw new FatalBackendException(e);
}
}
@ -174,10 +163,7 @@ class PCloudContentRepository extends InterceptingCloudContentRepository<PCloud,
public void read(PCloudFile file, Optional<File> encryptedTmpFile, OutputStream data, ProgressAware<DownloadState> progressAware) throws BackendException {
try {
cloud.read(file, data, progressAware);
} catch (ApiError | IOException e) {
if (e instanceof ApiError && ((ApiError)e).errorCode() == PCloudApiErrorCodes.FILE_NOT_FOUND.getValue()) {
throw new NoSuchCloudFileException(file.getName());
}
} catch (IOException e) {
throw new FatalBackendException(e);
}
}
@ -186,12 +172,7 @@ class PCloudContentRepository extends InterceptingCloudContentRepository<PCloud,
public void delete(PCloudNode node) throws BackendException {
try {
cloud.delete(node);
} catch (ApiError | IOException e) {
if (e instanceof ApiError) {
if (((ApiError) e).errorCode() == PCloudApiErrorCodes.FILE_NOT_FOUND.getValue()) {
throw new NoSuchCloudFileException(node.getName());
}
}
} catch (IOException e) {
throw new FatalBackendException(e);
}
}
@ -200,7 +181,7 @@ class PCloudContentRepository extends InterceptingCloudContentRepository<PCloud,
public String checkAuthenticationAndRetrieveCurrentAccount(PCloud cloud) throws BackendException {
try {
return this.cloud.currentAccount();
} catch (ApiError | IOException e) {
} catch (IOException e) {
throw new FatalBackendException(e);
}
}

View File

@ -18,7 +18,11 @@ import org.cryptomator.data.util.CopyStream;
import org.cryptomator.domain.PCloud;
import org.cryptomator.domain.exception.BackendException;
import org.cryptomator.domain.exception.CloudNodeAlreadyExistsException;
import org.cryptomator.domain.exception.FatalBackendException;
import org.cryptomator.domain.exception.ForbiddenException;
import org.cryptomator.domain.exception.NetworkConnectionException;
import org.cryptomator.domain.exception.NoSuchCloudFileException;
import org.cryptomator.domain.exception.UnauthorizedException;
import org.cryptomator.domain.exception.authentication.NoAuthenticationProvidedException;
import org.cryptomator.domain.exception.authentication.WrongCredentialsException;
import org.cryptomator.domain.usecases.ProgressAware;
@ -33,8 +37,11 @@ import java.io.OutputStream;
import java.net.URLEncoder;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import okhttp3.internal.concurrent.TaskRunner;
import okio.BufferedSink;
import okio.BufferedSource;
import okio.Okio;
@ -51,6 +58,8 @@ class PCloudImpl {
private final RootPCloudFolder root;
private final Context context;
private final String UTF_8 = "UTF-8";
PCloudImpl(Context context, PCloud cloud, PCloudIdCache idCache) {
if (cloud.accessToken() == null) {
throw new NoAuthenticationProvidedException(cloud);
@ -70,7 +79,7 @@ class PCloudImpl {
return root;
}
public PCloudFolder resolve(String path) {
public PCloudFolder resolve(String path) throws IOException, BackendException {
if (path.startsWith("/")) {
path = path.substring(1);
}
@ -82,7 +91,7 @@ class PCloudImpl {
return folder;
}
private Optional<RemoteEntry> findEntry(Long folderId, String name, boolean isFolder) {
private Optional<RemoteEntry> findEntry(Long folderId, String name, boolean isFolder) throws IOException, BackendException {
try {
RemoteFolder remoteFolder = client().listFolder(folderId).execute();
for (RemoteEntry remoteEntry : remoteFolder.children()) {
@ -97,22 +106,19 @@ class PCloudImpl {
}
}
return Optional.empty();
} catch(ApiError | IOException ex) {
if (ex instanceof ApiError) {
int errorCode = ((ApiError)ex).errorCode();
if (errorCode == PCloudApiErrorCodes.INVALID_ACCESS_TOKEN.getValue() || errorCode == PCloudApiErrorCodes.ACCESS_TOKEN_REVOKED.getValue()) {
throw new WrongCredentialsException(cloud);
}
}
} catch(ApiError ex) {
Set<Integer> ignoredErrorCodes = new HashSet<>();
ignoredErrorCodes.add(PCloudApiError.PCloudApiErrorCodes.DIRECTORY_DOES_NOT_EXIST.getValue());
handleApiError(ex, ignoredErrorCodes);
return Optional.empty();
}
}
public PCloudFile file(PCloudFolder parent, String name) {
public PCloudFile file(PCloudFolder parent, String name) throws BackendException, IOException {
return file(parent, name, Optional.empty());
}
public PCloudFile file(PCloudFolder parent, String name, Optional<Long> size) {
public PCloudFile file(PCloudFolder parent, String name, Optional<Long> size) throws BackendException, IOException {
if (parent.getId() == null) {
return PCloudNodeFactory.file(parent, name, size);
}
@ -131,7 +137,7 @@ class PCloudImpl {
return PCloudNodeFactory.file(parent, name, size);
}
public PCloudFolder folder(PCloudFolder parent, String name) {
public PCloudFolder folder(PCloudFolder parent, String name) throws IOException, BackendException {
if (parent.getId() == null) {
return PCloudNodeFactory.folder(parent, name);
}
@ -149,7 +155,7 @@ class PCloudImpl {
return PCloudNodeFactory.folder(parent, name);
}
public boolean exists(PCloudNode node) throws ApiError, IOException {
public boolean exists(PCloudNode node) throws IOException, BackendException {
try {
if (node instanceof PCloudFolder) {
RemoteFolder remoteFolder = client().listFolder(node.getPath()).execute();
@ -159,38 +165,42 @@ class PCloudImpl {
idCache.add(PCloudNodeFactory.file(node.getParent(), remoteFile));
}
return true;
} catch (ApiError e) {
if (e.errorCode() == PCloudApiErrorCodes.DIRECTORY_DOES_NOT_EXIST.getValue()
|| e.errorCode() == PCloudApiErrorCodes.COMPONENT_OF_PARENT_DIRECTORY_DOES_NOT_EXIST.getValue()
|| e.errorCode() == PCloudApiErrorCodes.INVALID_FILE_OR_FOLDER_NAME.getValue()
|| e.errorCode() == PCloudApiErrorCodes.FILE_OR_FOLDER_NOT_FOUND.getValue()) {
return false;
}
throw e;
} catch (ApiError ex) {
Set<Integer> ignoredErrorCodes = new HashSet<>();
ignoredErrorCodes.add(PCloudApiError.PCloudApiErrorCodes.DIRECTORY_DOES_NOT_EXIST.getValue());
ignoredErrorCodes.add(PCloudApiError.PCloudApiErrorCodes.COMPONENT_OF_PARENT_DIRECTORY_DOES_NOT_EXIST.getValue());
ignoredErrorCodes.add(PCloudApiError.PCloudApiErrorCodes.INVALID_FILE_OR_FOLDER_NAME.getValue());
ignoredErrorCodes.add(PCloudApiError.PCloudApiErrorCodes.FILE_OR_FOLDER_NOT_FOUND.getValue());
handleApiError(ex, ignoredErrorCodes);
return false;
}
}
public List<PCloudNode> list(PCloudFolder folder) throws ApiError, IOException {
public List<PCloudNode> list(PCloudFolder folder) throws IOException, BackendException {
List<PCloudNode> result = new ArrayList<>();
Long folderId = folder.getId();
RemoteFolder listFolderResult;
if (folderId == null) {
listFolderResult = client().listFolder(folder.getPath()).execute();
} else {
listFolderResult = client() //
.listFolder(folder.getId()) //
.execute();
try {
if (folderId == null) {
listFolderResult = client().listFolder(folder.getPath()).execute();
} else {
listFolderResult = client() //
.listFolder(folder.getId()) //
.execute();
}
List<RemoteEntry> entryMetadata = listFolderResult.children();
for (RemoteEntry metadata : entryMetadata) {
result.add(idCache.cache(PCloudNodeFactory.from(folder, metadata)));
}
return result;
} catch(ApiError ex) {
handleApiError(ex);
throw new FatalBackendException(ex);
}
List<RemoteEntry> entryMetadata = listFolderResult.children();
for (RemoteEntry metadata : entryMetadata) {
result.add(idCache.cache(PCloudNodeFactory.from(folder, metadata)));
}
return result;
}
public PCloudFolder create(PCloudFolder folder) throws ApiError, IOException {
public PCloudFolder create(PCloudFolder folder) throws IOException, BackendException {
if (folder.getParent().getId() == null) {
folder = new PCloudFolder( //
create(folder.getParent()), //
@ -199,38 +209,48 @@ class PCloudImpl {
);
}
RemoteFolder createdFolder = client() //
.createFolder(folder.getParent().getId(), folder.getName()) //
.execute();
return idCache.cache( //
PCloudNodeFactory.folder(folder.getParent(), createdFolder));
try {
RemoteFolder createdFolder = client() //
.createFolder(folder.getParent().getId(), folder.getName()) //
.execute();
return idCache.cache( //
PCloudNodeFactory.folder(folder.getParent(), createdFolder));
} catch (ApiError ex) {
handleApiError(ex);
throw new FatalBackendException(ex);
}
}
public PCloudNode move(PCloudNode source, PCloudNode target) throws ApiError, BackendException, IOException {
public PCloudNode move(PCloudNode source, PCloudNode target) throws IOException, BackendException {
if (exists(target)) {
throw new CloudNodeAlreadyExistsException(target.getName());
}
RemoteEntry relocationResult;
if (source instanceof PCloudFolder) {
relocationResult = client().moveFolder(source.getId(), target.getParent().getId()).execute();
if (!relocationResult.name().equals(target.getName())) {
relocationResult = client().renameFolder(relocationResult.asFolder(), target.getName()).execute();
try {
if (source instanceof PCloudFolder) {
relocationResult = client().moveFolder(source.getId(), target.getParent().getId()).execute();
if (!relocationResult.name().equals(target.getName())) {
relocationResult = client().renameFolder(relocationResult.asFolder(), target.getName()).execute();
}
} else {
relocationResult = client().moveFile(source.getId(), target.getParent().getId()).execute();
if (!relocationResult.name().equals(target.getName())) {
relocationResult = client().renameFile(relocationResult.asFile(), target.getName()).execute();
}
}
} else {
relocationResult = client().moveFile(source.getId(), target.getParent().getId()).execute();
if (!relocationResult.name().equals(target.getName())) {
relocationResult = client().renameFile(relocationResult.asFile(), target.getName()).execute();
}
}
idCache.remove(source);
return idCache.cache(PCloudNodeFactory.from(target.getParent(), relocationResult));
idCache.remove(source);
return idCache.cache(PCloudNodeFactory.from(target.getParent(), relocationResult));
} catch(ApiError ex) {
handleApiError(ex);
throw new FatalBackendException(ex);
}
}
public PCloudFile write(PCloudFile file, DataSource data, final ProgressAware<UploadState> progressAware, boolean replace, long size)
throws ApiError, BackendException, IOException {
throws IOException, BackendException {
if (!replace && exists(file)) {
throw new CloudNodeAlreadyExistsException("CloudNode already exists and replace is false");
}
@ -253,7 +273,7 @@ class PCloudImpl {
}
private RemoteFile uploadFile(final PCloudFile file, DataSource data, final ProgressAware<UploadState> progressAware, UploadOptions uploadOptions, final long size) //
throws ApiError, IOException {
throws IOException, BackendException {
ProgressListener listener = (done, total) -> progressAware.onProgress( //
progress(UploadState.upload(file)) //
.between(0) //
@ -280,19 +300,23 @@ class PCloudImpl {
}
String filename = file.getName();
String encodedFilename = URLEncoder.encode(filename, "UTF-8");
String encodedFilename = URLEncoder.encode(filename, UTF_8);
RemoteFile newFile = client() //
.createFile(parentFolderId, encodedFilename, pCloudDataSource, new Date(), listener, uploadOptions) //
.execute();
if (!filename.equals(encodedFilename)) {
return client().renameFile(newFile.fileId(), filename).execute();
try {
RemoteFile newFile = client() //
.createFile(parentFolderId, encodedFilename, pCloudDataSource, new Date(), listener, uploadOptions) //
.execute();
if (!filename.equals(encodedFilename)) {
return client().renameFile(newFile.fileId(), filename).execute();
}
return newFile;
} catch (ApiError ex) {
handleApiError(ex);
throw new FatalBackendException(ex);
}
return newFile;
}
public void read(PCloudFile file, OutputStream data, final ProgressAware<DownloadState> progressAware) throws ApiError, IOException {
public void read(PCloudFile file, OutputStream data, final ProgressAware<DownloadState> progressAware) throws IOException, BackendException {
progressAware.onProgress(Progress.started(DownloadState.download(file)));
Long fileId = file.getId();
@ -300,41 +324,83 @@ class PCloudImpl {
fileId = idCache.get(file.getPath()).getId();
}
FileLink fileLink = client().createFileLink(fileId, DownloadOptions.DEFAULT).execute();
try {
FileLink fileLink = client().createFileLink(fileId, DownloadOptions.DEFAULT).execute();
ProgressListener listener = (done, total) -> progressAware.onProgress( //
progress(DownloadState.download(file)) //
.between(0) //
.and(file.getSize().orElse(Long.MAX_VALUE)) //
.withValue(done));
ProgressListener listener = (done, total) -> progressAware.onProgress( //
progress(DownloadState.download(file)) //
.between(0) //
.and(file.getSize().orElse(Long.MAX_VALUE)) //
.withValue(done));
DataSink sink = new DataSink() {
@Override
public void readAll(BufferedSource source) throws IOException {
CopyStream.copyStreamToStream(source.inputStream(), data);
}
};
DataSink sink = new DataSink() {
@Override
public void readAll(BufferedSource source) throws IOException {
CopyStream.copyStreamToStream(source.inputStream(), data);
}
};
client().download(fileLink, sink, listener).execute();
client().download(fileLink, sink, listener).execute();
progressAware.onProgress(Progress.completed(DownloadState.download(file)));
}
public void delete(PCloudNode node) throws ApiError, IOException {
if (node instanceof PCloudFolder) {
client() //
.deleteFolder(node.getId(), true).execute();
} else {
client() //
.deleteFile(node.getId()).execute();
progressAware.onProgress(Progress.completed(DownloadState.download(file)));
} catch(ApiError ex) {
handleApiError(ex);
}
idCache.remove(node);
}
public String currentAccount() throws ApiError, IOException {
UserInfo currentAccount = client() //
.getUserInfo() //
.execute();
return currentAccount.email();
public void delete(PCloudNode node) throws IOException, BackendException {
try {
if (node instanceof PCloudFolder) {
client() //
.deleteFolder(node.getId(), true).execute();
} else {
client() //
.deleteFile(node.getId()).execute();
}
idCache.remove(node);
} catch(ApiError ex) {
handleApiError(ex);
}
}
public String currentAccount() throws IOException, BackendException {
try {
UserInfo currentAccount = client() //
.getUserInfo() //
.execute();
return currentAccount.email();
} catch(ApiError ex) {
handleApiError(ex);
throw new FatalBackendException(ex);
}
}
private void handleApiError(ApiError ex) throws BackendException {
handleApiError(ex, null);
}
private void handleApiError(ApiError ex, Set<Integer> errorCodes) throws BackendException {
handleApiError(ex, errorCodes, null);
}
private void handleApiError(ApiError ex, Set<Integer> errorCodes, String name) throws BackendException {
if (errorCodes == null || !errorCodes.contains(ex.errorCode())) {
int errorCode = ex.errorCode();
if (PCloudApiError.isCloudNodeAlreadyExistsException(errorCode)) {
throw new CloudNodeAlreadyExistsException(name);
} else if (PCloudApiError.isForbiddenException(errorCode)){
throw new ForbiddenException();
} else if (PCloudApiError.isNetworkConnectionException(errorCode)) {
throw new NetworkConnectionException(ex);
} else if (PCloudApiError.isNoSuchCloudFileException(errorCode)) {
throw new NoSuchCloudFileException(name);
} else if (PCloudApiError.isWrongCredentialsException(errorCode)) {
throw new WrongCredentialsException(cloud);
} else if (PCloudApiError.isUnauthorizedException(errorCode)) {
throw new UnauthorizedException();
} else {
throw new FatalBackendException(ex);
}
}
}
}