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) { private void throwWrongCredentialsExceptionIfRequired(Exception e) {
if (e instanceof ApiError) { if (e instanceof ApiError) {
int errorCode = ((ApiError)e).errorCode(); 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); throw new WrongCredentialsException(cloud);
} }
} }
@ -69,30 +70,46 @@ class PCloudContentRepository extends InterceptingCloudContentRepository<PCloud,
} }
@Override @Override
public PCloudFolder resolve(PCloud cloud, String path) { public PCloudFolder resolve(PCloud cloud, String path) throws BackendException {
try {
return this.cloud.resolve(path); return this.cloud.resolve(path);
} catch(IOException ex) {
throw new FatalBackendException(ex);
}
} }
@Override @Override
public PCloudFile file(PCloudFolder parent, String name) { public PCloudFile file(PCloudFolder parent, String name) throws BackendException {
try {
return cloud.file(parent, name); return cloud.file(parent, name);
} catch(IOException ex) {
throw new FatalBackendException(ex);
}
} }
@Override @Override
public PCloudFile file(PCloudFolder parent, String name, Optional<Long> size) throws BackendException { public PCloudFile file(PCloudFolder parent, String name, Optional<Long> size) throws BackendException {
try {
return cloud.file(parent, name, size); return cloud.file(parent, name, size);
} catch(IOException ex) {
throw new FatalBackendException(ex);
}
} }
@Override @Override
public PCloudFolder folder(PCloudFolder parent, String name) { public PCloudFolder folder(PCloudFolder parent, String name) throws BackendException {
try {
return cloud.folder(parent, name); return cloud.folder(parent, name);
} catch(IOException ex) {
throw new FatalBackendException(ex);
}
} }
@Override @Override
public boolean exists(PCloudNode node) throws BackendException { public boolean exists(PCloudNode node) throws BackendException {
try { try {
return cloud.exists(node); return cloud.exists(node);
} catch (ApiError|IOException e) { } catch (IOException e) {
throw new FatalBackendException(e); throw new FatalBackendException(e);
} }
} }
@ -101,12 +118,7 @@ class PCloudContentRepository extends InterceptingCloudContentRepository<PCloud,
public List<PCloudNode> list(PCloudFolder folder) throws BackendException { public List<PCloudNode> list(PCloudFolder folder) throws BackendException {
try { try {
return cloud.list(folder); return cloud.list(folder);
} catch (ApiError | IOException e) { } catch (IOException e) {
if (e instanceof ApiError) {
if (((ApiError) e).errorCode() == PCloudApiErrorCodes.DIRECTORY_DOES_NOT_EXIST.getValue()) {
throw new NoSuchCloudFileException();
}
}
throw new FatalBackendException(e); throw new FatalBackendException(e);
} }
} }
@ -115,11 +127,7 @@ class PCloudContentRepository extends InterceptingCloudContentRepository<PCloud,
public PCloudFolder create(PCloudFolder folder) throws BackendException { public PCloudFolder create(PCloudFolder folder) throws BackendException {
try { try {
return cloud.create(folder); return cloud.create(folder);
} catch (ApiError | IOException e) { } catch (IOException e) {
if (e instanceof ApiError) {
if (((ApiError) e).errorCode() == PCloudApiErrorCodes.FILE_OR_FOLDER_ALREADY_EXISTS.getValue())
throw new CloudNodeAlreadyExistsException(folder.getName());
}
throw new FatalBackendException(e); throw new FatalBackendException(e);
} }
} }
@ -128,15 +136,7 @@ class PCloudContentRepository extends InterceptingCloudContentRepository<PCloud,
public PCloudFolder move(PCloudFolder source, PCloudFolder target) throws BackendException { public PCloudFolder move(PCloudFolder source, PCloudFolder target) throws BackendException {
try { try {
return (PCloudFolder) cloud.move(source, target); return (PCloudFolder) cloud.move(source, target);
} catch (ApiError | IOException e) { } catch (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());
}
throw new FatalBackendException(e); throw new FatalBackendException(e);
} }
} }
@ -145,15 +145,7 @@ class PCloudContentRepository extends InterceptingCloudContentRepository<PCloud,
public PCloudFile move(PCloudFile source, PCloudFile target) throws BackendException { public PCloudFile move(PCloudFile source, PCloudFile target) throws BackendException {
try { try {
return (PCloudFile) cloud.move(source, target); return (PCloudFile) cloud.move(source, target);
} catch (ApiError | IOException e) { } catch (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());
}
throw new FatalBackendException(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 { public PCloudFile write(PCloudFile uploadFile, DataSource data, ProgressAware<UploadState> progressAware, boolean replace, long size) throws BackendException {
try { try {
return cloud.write(uploadFile, data, progressAware, replace, size); return cloud.write(uploadFile, data, progressAware, replace, size);
} catch (ApiError | IOException e) { } catch (IOException e) {
if (e instanceof ApiError && ((ApiError)e).errorCode() == PCloudApiErrorCodes.FILE_NOT_FOUND.getValue()) {
throw new NoSuchCloudFileException(uploadFile.getName());
}
throw new FatalBackendException(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 { public void read(PCloudFile file, Optional<File> encryptedTmpFile, OutputStream data, ProgressAware<DownloadState> progressAware) throws BackendException {
try { try {
cloud.read(file, data, progressAware); cloud.read(file, data, progressAware);
} catch (ApiError | IOException e) { } catch (IOException e) {
if (e instanceof ApiError && ((ApiError)e).errorCode() == PCloudApiErrorCodes.FILE_NOT_FOUND.getValue()) {
throw new NoSuchCloudFileException(file.getName());
}
throw new FatalBackendException(e); throw new FatalBackendException(e);
} }
} }
@ -186,12 +172,7 @@ class PCloudContentRepository extends InterceptingCloudContentRepository<PCloud,
public void delete(PCloudNode node) throws BackendException { public void delete(PCloudNode node) throws BackendException {
try { try {
cloud.delete(node); cloud.delete(node);
} catch (ApiError | IOException e) { } catch (IOException e) {
if (e instanceof ApiError) {
if (((ApiError) e).errorCode() == PCloudApiErrorCodes.FILE_NOT_FOUND.getValue()) {
throw new NoSuchCloudFileException(node.getName());
}
}
throw new FatalBackendException(e); throw new FatalBackendException(e);
} }
} }
@ -200,7 +181,7 @@ class PCloudContentRepository extends InterceptingCloudContentRepository<PCloud,
public String checkAuthenticationAndRetrieveCurrentAccount(PCloud cloud) throws BackendException { public String checkAuthenticationAndRetrieveCurrentAccount(PCloud cloud) throws BackendException {
try { try {
return this.cloud.currentAccount(); return this.cloud.currentAccount();
} catch (ApiError | IOException e) { } catch (IOException e) {
throw new FatalBackendException(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.PCloud;
import org.cryptomator.domain.exception.BackendException; import org.cryptomator.domain.exception.BackendException;
import org.cryptomator.domain.exception.CloudNodeAlreadyExistsException; 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.NoSuchCloudFileException;
import org.cryptomator.domain.exception.UnauthorizedException;
import org.cryptomator.domain.exception.authentication.NoAuthenticationProvidedException; import org.cryptomator.domain.exception.authentication.NoAuthenticationProvidedException;
import org.cryptomator.domain.exception.authentication.WrongCredentialsException; import org.cryptomator.domain.exception.authentication.WrongCredentialsException;
import org.cryptomator.domain.usecases.ProgressAware; import org.cryptomator.domain.usecases.ProgressAware;
@ -33,8 +37,11 @@ import java.io.OutputStream;
import java.net.URLEncoder; import java.net.URLEncoder;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Date; import java.util.Date;
import java.util.HashSet;
import java.util.List; import java.util.List;
import java.util.Set;
import okhttp3.internal.concurrent.TaskRunner;
import okio.BufferedSink; import okio.BufferedSink;
import okio.BufferedSource; import okio.BufferedSource;
import okio.Okio; import okio.Okio;
@ -51,6 +58,8 @@ class PCloudImpl {
private final RootPCloudFolder root; private final RootPCloudFolder root;
private final Context context; private final Context context;
private final String UTF_8 = "UTF-8";
PCloudImpl(Context context, PCloud cloud, PCloudIdCache idCache) { PCloudImpl(Context context, PCloud cloud, PCloudIdCache idCache) {
if (cloud.accessToken() == null) { if (cloud.accessToken() == null) {
throw new NoAuthenticationProvidedException(cloud); throw new NoAuthenticationProvidedException(cloud);
@ -70,7 +79,7 @@ class PCloudImpl {
return root; return root;
} }
public PCloudFolder resolve(String path) { public PCloudFolder resolve(String path) throws IOException, BackendException {
if (path.startsWith("/")) { if (path.startsWith("/")) {
path = path.substring(1); path = path.substring(1);
} }
@ -82,7 +91,7 @@ class PCloudImpl {
return folder; 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 { try {
RemoteFolder remoteFolder = client().listFolder(folderId).execute(); RemoteFolder remoteFolder = client().listFolder(folderId).execute();
for (RemoteEntry remoteEntry : remoteFolder.children()) { for (RemoteEntry remoteEntry : remoteFolder.children()) {
@ -97,22 +106,19 @@ class PCloudImpl {
} }
} }
return Optional.empty(); return Optional.empty();
} catch(ApiError | IOException ex) { } catch(ApiError ex) {
if (ex instanceof ApiError) { Set<Integer> ignoredErrorCodes = new HashSet<>();
int errorCode = ((ApiError)ex).errorCode(); ignoredErrorCodes.add(PCloudApiError.PCloudApiErrorCodes.DIRECTORY_DOES_NOT_EXIST.getValue());
if (errorCode == PCloudApiErrorCodes.INVALID_ACCESS_TOKEN.getValue() || errorCode == PCloudApiErrorCodes.ACCESS_TOKEN_REVOKED.getValue()) { handleApiError(ex, ignoredErrorCodes);
throw new WrongCredentialsException(cloud);
}
}
return Optional.empty(); 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()); 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) { if (parent.getId() == null) {
return PCloudNodeFactory.file(parent, name, size); return PCloudNodeFactory.file(parent, name, size);
} }
@ -131,7 +137,7 @@ class PCloudImpl {
return PCloudNodeFactory.file(parent, name, size); 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) { if (parent.getId() == null) {
return PCloudNodeFactory.folder(parent, name); return PCloudNodeFactory.folder(parent, name);
} }
@ -149,7 +155,7 @@ class PCloudImpl {
return PCloudNodeFactory.folder(parent, name); return PCloudNodeFactory.folder(parent, name);
} }
public boolean exists(PCloudNode node) throws ApiError, IOException { public boolean exists(PCloudNode node) throws IOException, BackendException {
try { try {
if (node instanceof PCloudFolder) { if (node instanceof PCloudFolder) {
RemoteFolder remoteFolder = client().listFolder(node.getPath()).execute(); RemoteFolder remoteFolder = client().listFolder(node.getPath()).execute();
@ -159,22 +165,23 @@ class PCloudImpl {
idCache.add(PCloudNodeFactory.file(node.getParent(), remoteFile)); idCache.add(PCloudNodeFactory.file(node.getParent(), remoteFile));
} }
return true; return true;
} catch (ApiError e) { } catch (ApiError ex) {
if (e.errorCode() == PCloudApiErrorCodes.DIRECTORY_DOES_NOT_EXIST.getValue() Set<Integer> ignoredErrorCodes = new HashSet<>();
|| e.errorCode() == PCloudApiErrorCodes.COMPONENT_OF_PARENT_DIRECTORY_DOES_NOT_EXIST.getValue() ignoredErrorCodes.add(PCloudApiError.PCloudApiErrorCodes.DIRECTORY_DOES_NOT_EXIST.getValue());
|| e.errorCode() == PCloudApiErrorCodes.INVALID_FILE_OR_FOLDER_NAME.getValue() ignoredErrorCodes.add(PCloudApiError.PCloudApiErrorCodes.COMPONENT_OF_PARENT_DIRECTORY_DOES_NOT_EXIST.getValue());
|| e.errorCode() == PCloudApiErrorCodes.FILE_OR_FOLDER_NOT_FOUND.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; return false;
} }
throw e;
}
} }
public List<PCloudNode> list(PCloudFolder folder) throws ApiError, IOException { public List<PCloudNode> list(PCloudFolder folder) throws IOException, BackendException {
List<PCloudNode> result = new ArrayList<>(); List<PCloudNode> result = new ArrayList<>();
Long folderId = folder.getId(); Long folderId = folder.getId();
RemoteFolder listFolderResult; RemoteFolder listFolderResult;
try {
if (folderId == null) { if (folderId == null) {
listFolderResult = client().listFolder(folder.getPath()).execute(); listFolderResult = client().listFolder(folder.getPath()).execute();
} else { } else {
@ -182,15 +189,18 @@ class PCloudImpl {
.listFolder(folder.getId()) // .listFolder(folder.getId()) //
.execute(); .execute();
} }
List<RemoteEntry> entryMetadata = listFolderResult.children(); List<RemoteEntry> entryMetadata = listFolderResult.children();
for (RemoteEntry metadata : entryMetadata) { for (RemoteEntry metadata : entryMetadata) {
result.add(idCache.cache(PCloudNodeFactory.from(folder, metadata))); result.add(idCache.cache(PCloudNodeFactory.from(folder, metadata)));
} }
return result; return result;
} catch(ApiError ex) {
handleApiError(ex);
throw new FatalBackendException(ex);
}
} }
public PCloudFolder create(PCloudFolder folder) throws ApiError, IOException { public PCloudFolder create(PCloudFolder folder) throws IOException, BackendException {
if (folder.getParent().getId() == null) { if (folder.getParent().getId() == null) {
folder = new PCloudFolder( // folder = new PCloudFolder( //
create(folder.getParent()), // create(folder.getParent()), //
@ -199,20 +209,26 @@ class PCloudImpl {
); );
} }
try {
RemoteFolder createdFolder = client() // RemoteFolder createdFolder = client() //
.createFolder(folder.getParent().getId(), folder.getName()) // .createFolder(folder.getParent().getId(), folder.getName()) //
.execute(); .execute();
return idCache.cache( // return idCache.cache( //
PCloudNodeFactory.folder(folder.getParent(), createdFolder)); 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)) { if (exists(target)) {
throw new CloudNodeAlreadyExistsException(target.getName()); throw new CloudNodeAlreadyExistsException(target.getName());
} }
RemoteEntry relocationResult; RemoteEntry relocationResult;
try {
if (source instanceof PCloudFolder) { if (source instanceof PCloudFolder) {
relocationResult = client().moveFolder(source.getId(), target.getParent().getId()).execute(); relocationResult = client().moveFolder(source.getId(), target.getParent().getId()).execute();
if (!relocationResult.name().equals(target.getName())) { if (!relocationResult.name().equals(target.getName())) {
@ -227,10 +243,14 @@ class PCloudImpl {
idCache.remove(source); idCache.remove(source);
return idCache.cache(PCloudNodeFactory.from(target.getParent(), relocationResult)); 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) 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)) { if (!replace && exists(file)) {
throw new CloudNodeAlreadyExistsException("CloudNode already exists and replace is false"); 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) // 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( // ProgressListener listener = (done, total) -> progressAware.onProgress( //
progress(UploadState.upload(file)) // progress(UploadState.upload(file)) //
.between(0) // .between(0) //
@ -280,19 +300,23 @@ class PCloudImpl {
} }
String filename = file.getName(); String filename = file.getName();
String encodedFilename = URLEncoder.encode(filename, "UTF-8"); String encodedFilename = URLEncoder.encode(filename, UTF_8);
try {
RemoteFile newFile = client() // RemoteFile newFile = client() //
.createFile(parentFolderId, encodedFilename, pCloudDataSource, new Date(), listener, uploadOptions) // .createFile(parentFolderId, encodedFilename, pCloudDataSource, new Date(), listener, uploadOptions) //
.execute(); .execute();
if (!filename.equals(encodedFilename)) { if (!filename.equals(encodedFilename)) {
return client().renameFile(newFile.fileId(), filename).execute(); return client().renameFile(newFile.fileId(), filename).execute();
} }
return newFile; return newFile;
} catch (ApiError ex) {
handleApiError(ex);
throw new FatalBackendException(ex);
}
} }
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))); progressAware.onProgress(Progress.started(DownloadState.download(file)));
Long fileId = file.getId(); Long fileId = file.getId();
@ -300,6 +324,7 @@ class PCloudImpl {
fileId = idCache.get(file.getPath()).getId(); fileId = idCache.get(file.getPath()).getId();
} }
try {
FileLink fileLink = client().createFileLink(fileId, DownloadOptions.DEFAULT).execute(); FileLink fileLink = client().createFileLink(fileId, DownloadOptions.DEFAULT).execute();
ProgressListener listener = (done, total) -> progressAware.onProgress( // ProgressListener listener = (done, total) -> progressAware.onProgress( //
@ -318,9 +343,13 @@ class PCloudImpl {
client().download(fileLink, sink, listener).execute(); client().download(fileLink, sink, listener).execute();
progressAware.onProgress(Progress.completed(DownloadState.download(file))); progressAware.onProgress(Progress.completed(DownloadState.download(file)));
} catch(ApiError ex) {
handleApiError(ex);
}
} }
public void delete(PCloudNode node) throws ApiError, IOException { public void delete(PCloudNode node) throws IOException, BackendException {
try {
if (node instanceof PCloudFolder) { if (node instanceof PCloudFolder) {
client() // client() //
.deleteFolder(node.getId(), true).execute(); .deleteFolder(node.getId(), true).execute();
@ -329,12 +358,49 @@ class PCloudImpl {
.deleteFile(node.getId()).execute(); .deleteFile(node.getId()).execute();
} }
idCache.remove(node); idCache.remove(node);
} catch(ApiError ex) {
handleApiError(ex);
}
} }
public String currentAccount() throws ApiError, IOException { public String currentAccount() throws IOException, BackendException {
try {
UserInfo currentAccount = client() // UserInfo currentAccount = client() //
.getUserInfo() // .getUserInfo() //
.execute(); .execute();
return currentAccount.email(); 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);
}
}
} }
} }