aboutsummaryrefslogtreecommitdiffstats
path: root/src/main/java/de/thedevstack/conversationsplus/services/filetransfer/FileTransferEntity.java
diff options
context:
space:
mode:
Diffstat (limited to 'src/main/java/de/thedevstack/conversationsplus/services/filetransfer/FileTransferEntity.java')
-rw-r--r--src/main/java/de/thedevstack/conversationsplus/services/filetransfer/FileTransferEntity.java194
1 files changed, 160 insertions, 34 deletions
diff --git a/src/main/java/de/thedevstack/conversationsplus/services/filetransfer/FileTransferEntity.java b/src/main/java/de/thedevstack/conversationsplus/services/filetransfer/FileTransferEntity.java
index a44cf49d..e1b40fa6 100644
--- a/src/main/java/de/thedevstack/conversationsplus/services/filetransfer/FileTransferEntity.java
+++ b/src/main/java/de/thedevstack/conversationsplus/services/filetransfer/FileTransferEntity.java
@@ -1,60 +1,95 @@
package de.thedevstack.conversationsplus.services.filetransfer;
import java.io.InputStream;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
import de.thedevstack.conversationsplus.entities.DownloadableFile;
import de.thedevstack.conversationsplus.entities.Message;
import de.thedevstack.conversationsplus.entities.Transferable;
import de.thedevstack.conversationsplus.persistance.FileBackend;
-import de.thedevstack.conversationsplus.utils.MessageUtil;
+import de.thedevstack.conversationsplus.utils.StreamUtil;
/**
*
*/
public class FileTransferEntity implements Transferable {
+ /**
+ * Listeners to inform about a status change.
+ */
+ private final List<FileTransferStatusListener> statusListeners = new ArrayList<>();
+ /**
+ * The associated message.
+ */
private final Message message;
- private int tries = 0;
- private boolean transferred = false;
- private boolean canceled = false;
- private boolean failed = false;
+ /**
+ * Number of attempts.
+ */
+ private int attempts = 0;
+ /**
+ * The status of the file transfer.
+ */
+ private FileTransferStatusEnum transferStatus;
+ /**
+ * Number of bytes transmitted.
+ */
private long transmitted = 0;
+ /**
+ * The associated file.
+ */
private DownloadableFile file;
+ /**
+ * The associated file as stream.
+ */
private InputStream fileInputStream;
+ /**
+ * Initializes the FileTransferEntity based on the associated message.
+ * This initialization includes loading the file and associating this transferable to the message.
+ * @param message the message in which the file to transfer is contained.
+ */
public FileTransferEntity(Message message) {
this.message = message;
this.message.setTransferable(this);
this.file = FileBackend.getFile(message, false);
}
- @Override
- public boolean equals(Object o) {
- FileTransferEntity other = (FileTransferEntity)o;
- if ((this.message == null && other.message != null)
- || (this.message != null && other.message == null)) {
- return false;
- } else if (this.message == null && other.message == null) {
- return true;
- }
- return this.message.getUuid().equals(other.message.getUuid());
- }
-
+ /**
+ * Start something.
+ * Empty implementation since documentation in interface is missing.
+ * @return <code>false</code>
+ */
@Override
public boolean start() {
return false;
}
+ /**
+ * Returns the global transferable status.
+ *
+ * @return {@value STATUS_FAILED} if #isFailed returns <code>true</code>, {@value STATUS_UPLOADING} otherwise
+ */
@Override
public int getStatus() {
- int status = (failed) ? STATUS_FAILED : STATUS_UPLOADING;
+ int status = (isFailed()) ? STATUS_FAILED : STATUS_UPLOADING;
return status;
}
+ /**
+ * Returns the expected file size of the underlying file.
+ * @return the expected file size or 0 if no file is associated.
+ */
@Override
public long getFileSize() {
return file == null ? 0 : file.getExpectedSize();
}
+ /**
+ * Calculates the current progress in percent.
+ *
+ * @return the current progress in percent
+ */
@Override
public int getProgress() {
if (file == null) {
@@ -63,46 +98,137 @@ public class FileTransferEntity implements Transferable {
return (int) ((((double) transmitted) / file.getExpectedSize()) * 100);
}
+ /**
+ * Cancels the file transfer and informs the listeners about cancellation.
+ */
@Override
public void cancel() {
- this.canceled = true;
+ this.transferStatus = FileTransferStatusEnum.CANCELED;
+
+ this.close();
+
+ for (FileTransferStatusListener listener : this.statusListeners) {
+ listener.onCancel(this);
+ }
}
- public void fail() {
- this.failed = true;
+ /**
+ * Starts an transfer attempt.
+ */
+ public void startAttempt() {
+ this.attempts++;
+ this.transferStatus = FileTransferStatusEnum.TRANSFERRING;
+ }
+
+ /**
+ * Fails an file transfer and informs the listeners about failure.
+ *
+ * @param failureReason the reason of failure.
+ */
+ public void fail(FileTransferFailureReason failureReason) {
+ this.transferStatus = FileTransferStatusEnum.FAILED;
+
+ this.close();
+
+ failureReason.setAttempt(this.attempts);
+ for (FileTransferStatusListener listener : this.statusListeners) {
+ listener.onFailure(this, failureReason);
+ }
+ }
+
+ /**
+ * Updates the progress by adding parameter value to current progress value.
+ *
+ * @param progress the number of newly transferred bytes
+ */
+ public void updateProgress(long progress) {
+ if (0 == this.attempts) {
+ this.startAttempt();
+ }
+ this.transmitted += progress;
+ }
+
+ /**
+ * Set the status of the file transfer to FileTransferStatusEnum#TRANSFERRED and informs the listeners about success.
+ */
+ public void transferred() {
+ this.transferStatus = FileTransferStatusEnum.TRANSFERRED;
+
+ this.close();
+
+ for (FileTransferStatusListener listener : this.statusListeners) {
+ listener.onSuccess(this);
+ }
+ }
+
+ /**
+ * Closes the file input stream (if it is not yet closed) and removes association with message.
+ */
+ private void close() {
+ StreamUtil.close(this.fileInputStream);
this.getMessage().setTransferable(null);
- MessageUtil.markMessage(this.getMessage(), Message.STATUS_SEND_FAILED);
}
- public Message getMessage() {
- return message;
+ /**
+ * Whether the file is transferred or not.
+ * @return <code>true</code> if the file is successfully transferred, <code>false</code> otherwise
+ */
+ public boolean isTransferred() {
+ return FileTransferStatusEnum.TRANSFERRED == this.transferStatus;
}
+ /**
+ * Whether the file transfer is canceled or not.
+ * @return <code>true</code> if the file transfer was canceled, <code>false</code> otherwise
+ */
public boolean isCanceled() {
- return this.canceled;
+ return FileTransferStatusEnum.CANCELED == this.transferStatus;
}
+ /**
+ * Whether the file transfer failed or not.
+ * @return <code>true</code> if the file transfer failed, <code>false</code> otherwise
+ */
public boolean isFailed() {
- return failed;
+ return FileTransferStatusEnum.FAILED == this.transferStatus;
}
- public void updateProgress(long progress) {
- this.transmitted += progress;
+ public void setFileInputStream(InputStream fileInputStream) {
+ this.fileInputStream = fileInputStream;
+ }
+
+ public InputStream getFileInputStream() {
+ return fileInputStream;
+ }
+
+ public Message getMessage() {
+ return message;
}
public DownloadableFile getFile() {
return file;
}
- public void transferred() {
- this.transferred = true;
+ public void addFileTransferStatusListener(FileTransferStatusListener... listeners) {
+ this.statusListeners.addAll(Arrays.asList(listeners));
}
- public void setFileInputStream(InputStream fileInputStream) {
- this.fileInputStream = fileInputStream;
+ @Override
+ public boolean equals(Object o) {
+ if (this == o) return true;
+ if (o == null || getClass() != o.getClass()) return false;
+
+ FileTransferEntity that = (FileTransferEntity) o;
+
+ String uuid = message != null ? message.getUuid() : null;
+ String thatUuid = that.message != null ? that.message.getUuid() : null;
+
+ return uuid != null ? uuid.equals(thatUuid) : thatUuid == null;
+
}
- public InputStream getFileInputStream() {
- return fileInputStream;
+ @Override
+ public int hashCode() {
+ return message != null && message.getUuid() != null ? message.getUuid().hashCode() : 0;
}
}