From b1ab7347b92329512bebe57f6624cae33c27036f Mon Sep 17 00:00:00 2001 From: steckbrief Date: Sun, 29 May 2016 20:33:36 +0200 Subject: FileTransfer reworked (first steps - functionality as is), HttpUpload separated, some bugfixes - HttpUpload moved into own package - FileTransfer managed by a central manager class, several FileTransferService implementation can be used - Security initializations moved to ConversationsPlusApplication - Access to PowerManager moved to ConversationsPlusApplication - Removed unused code fragments - Access to HttpConnectionManager is now static --- .../services/filetransfer/FileTransferManager.java | 127 +++++++++++++++++++++ 1 file changed, 127 insertions(+) create mode 100644 src/main/java/de/thedevstack/conversationsplus/services/filetransfer/FileTransferManager.java (limited to 'src/main/java/de/thedevstack/conversationsplus/services/filetransfer/FileTransferManager.java') diff --git a/src/main/java/de/thedevstack/conversationsplus/services/filetransfer/FileTransferManager.java b/src/main/java/de/thedevstack/conversationsplus/services/filetransfer/FileTransferManager.java new file mode 100644 index 00000000..f7b3f4e2 --- /dev/null +++ b/src/main/java/de/thedevstack/conversationsplus/services/filetransfer/FileTransferManager.java @@ -0,0 +1,127 @@ +package de.thedevstack.conversationsplus.services.filetransfer; + +import java.util.HashMap; +import java.util.Map; +import java.util.SortedSet; +import java.util.TreeSet; + +import de.thedevstack.android.logcat.Logging; +import de.thedevstack.conversationsplus.Config; +import de.thedevstack.conversationsplus.entities.Message; +import de.thedevstack.conversationsplus.services.FileTransferService; + +/** + * + */ +public class FileTransferManager implements FileTransferService { + private SortedSet transferServices; + private static final FileTransferManager INSTANCE = new FileTransferManager(); + + private FileTransferManager() { + this.transferServices = new TreeSet<>(); + } + + public static FileTransferManager getInstance() { + return INSTANCE; + } + + public static void init(FileTransferService... fileTransferServices) { + if (null != fileTransferServices && fileTransferServices.length > 0) { + for (FileTransferService fts : fileTransferServices) { + addFileTransferService(fts); + } + } + } + + public static void init(HashMap fileTransferServices) { + for (Map.Entry entry : fileTransferServices.entrySet()) { + addFileTransferService(entry.getKey(), entry.getValue()); + } + } + + public static void addFileTransferService(int weight, FileTransferService fts) { + INSTANCE.transferServices.add(new WeightedTransferService(weight, fts)); + } + + public static void addFileTransferService(FileTransferService fts) { + int weight = 1; + if (!INSTANCE.transferServices.isEmpty()) { + weight = INSTANCE.transferServices.last().weight + 1; + } + addFileTransferService(weight, fts); + } + + /** + * Transfers a file for the corresponding message. + * + * @param message the message containing the file to transfer + * @return true if the file transfer was successful, false otherwise + */ + public boolean transferFile(Message message) { + return this.transferFile(message, false); + } + + /** + * Transfers a file for the corresponding message. + * + * @param message the message containing the file to transfer + * @param delay whether the message is delayed or not + * @return true if the file transfer was successful, false otherwise + */ + @Override + public boolean transferFile(Message message, boolean delay) { + Logging.d(Config.LOGTAG, "send file message"); + boolean transferSuccessfullyStarted = false; + for (WeightedTransferService wts : this.transferServices) { + try { + if (wts.fileTransferService.accept(message)) { + transferSuccessfullyStarted = wts.fileTransferService.transferFile(message, delay); + if (transferSuccessfullyStarted) { + break; + } + } + } catch (Exception e) { + //TODO Do real exception handling!!!!! + } + } + return transferSuccessfullyStarted; + } + + /** + * Checks whether a message can be sent using this service or not. + * + * @param message the message to be checked + * @return true if the message can be processed, false otherwise + */ + @Override + public boolean accept(Message message) { + return message.needsUploading(); + } + + static class WeightedTransferService implements Comparable { + int weight; + FileTransferService fileTransferService; + + WeightedTransferService(int weight, FileTransferService service) { + this.weight = weight; + this.fileTransferService = service; + } + + /** + * Compares this object to the specified object to determine their relative + * order. + * + * @param another the object to compare to this instance. + * @return a negative integer if this instance is less than {@code another}; + * a positive integer if this instance is greater than + * {@code another}; 0 if this instance has the same order as + * {@code another}. + * @throws ClassCastException if {@code another} cannot be converted into something + * comparable to {@code this} instance. + */ + @Override + public int compareTo(WeightedTransferService another) { + return this.weight - another.weight; + } + } +} -- cgit v1.2.3 From f45ad10b1baaf09fd4a40d6b63d1cd093623eedc Mon Sep 17 00:00:00 2001 From: steckbrief Date: Mon, 6 Jun 2016 09:05:50 +0200 Subject: Related to FS#131, FS#129, FS#220: - FileTransferFailureReason including types introduced. A failure can be recoverable, non-recoverable or limited recoverable - in case file transfer with the highest weight factor fails, the next file transfer method is used - improved logging - javadoc comments added --- .../services/filetransfer/FileTransferManager.java | 58 ++++++++++++++++++++-- 1 file changed, 54 insertions(+), 4 deletions(-) (limited to 'src/main/java/de/thedevstack/conversationsplus/services/filetransfer/FileTransferManager.java') diff --git a/src/main/java/de/thedevstack/conversationsplus/services/filetransfer/FileTransferManager.java b/src/main/java/de/thedevstack/conversationsplus/services/filetransfer/FileTransferManager.java index f7b3f4e2..017b88ea 100644 --- a/src/main/java/de/thedevstack/conversationsplus/services/filetransfer/FileTransferManager.java +++ b/src/main/java/de/thedevstack/conversationsplus/services/filetransfer/FileTransferManager.java @@ -9,13 +9,16 @@ import de.thedevstack.android.logcat.Logging; import de.thedevstack.conversationsplus.Config; import de.thedevstack.conversationsplus.entities.Message; import de.thedevstack.conversationsplus.services.FileTransferService; +import de.thedevstack.conversationsplus.services.filetransfer.httpupload.HttpFileTransferEntity; +import de.thedevstack.conversationsplus.utils.MessageUtil; /** * */ -public class FileTransferManager implements FileTransferService { +public class FileTransferManager implements FileTransferStatusListener { private SortedSet transferServices; private static final FileTransferManager INSTANCE = new FileTransferManager(); + private final HashMap activeTransfers = new HashMap<>(); private FileTransferManager() { this.transferServices = new TreeSet<>(); @@ -40,6 +43,7 @@ public class FileTransferManager implements FileTransferService { } public static void addFileTransferService(int weight, FileTransferService fts) { + fts.addFileTransferStatusListener(INSTANCE); INSTANCE.transferServices.add(new WeightedTransferService(weight, fts)); } @@ -68,14 +72,13 @@ public class FileTransferManager implements FileTransferService { * @param delay whether the message is delayed or not * @return true if the file transfer was successful, false otherwise */ - @Override public boolean transferFile(Message message, boolean delay) { Logging.d(Config.LOGTAG, "send file message"); boolean transferSuccessfullyStarted = false; for (WeightedTransferService wts : this.transferServices) { try { if (wts.fileTransferService.accept(message)) { - transferSuccessfullyStarted = wts.fileTransferService.transferFile(message, delay); + transferSuccessfullyStarted = this.startFileTransfer(message, delay, wts); if (transferSuccessfullyStarted) { break; } @@ -93,11 +96,58 @@ public class FileTransferManager implements FileTransferService { * @param message the message to be checked * @return true if the message can be processed, false otherwise */ - @Override public boolean accept(Message message) { return message.needsUploading(); } + @Override + public void onFailure(FileTransferEntity entity, FileTransferFailureReason failureReason) { + WeightedTransferService wts = this.activeTransfers.get(entity.getMessage().getUuid()); + if (null == wts) { + return; + } + boolean delayed = (entity instanceof HttpFileTransferEntity) && ((HttpFileTransferEntity) entity).isDelayed(); + if (failureReason.isRecoverable()) { + wts.fileTransferService.transferFile(entity.getMessage(), delayed); + } else { + boolean retransferStarted = false; + this.activeTransfers.remove(entity.getMessage().getUuid()); + for (WeightedTransferService newWts : this.transferServices.tailSet(wts)) { + if (newWts == wts) { // Same Reference + continue; + } + if (newWts.fileTransferService.accept(entity.getMessage())) { + retransferStarted = startFileTransfer(entity.getMessage(), delayed, newWts); + if (retransferStarted) { + break; + } + } + } + if (!retransferStarted) { + MessageUtil.markMessage(entity.getMessage(), Message.STATUS_SEND_FAILED); + } + } + } + + @Override + public void onCancel(FileTransferEntity entity) { + this.activeTransfers.remove(entity.getMessage().getUuid()); + MessageUtil.markMessage(entity.getMessage(), Message.STATUS_SEND_FAILED); // TODO New Status CANCELED! + } + + @Override + public void onSuccess(FileTransferEntity entity) { + this.activeTransfers.remove(entity.getMessage().getUuid()); + } + + private boolean startFileTransfer(Message message, boolean delayed, WeightedTransferService wts) { + boolean transferSuccessfullyStarted = wts.fileTransferService.transferFile(message, delayed); + if (transferSuccessfullyStarted) { + this.activeTransfers.put(message.getUuid(), wts); + } + return transferSuccessfullyStarted; + } + static class WeightedTransferService implements Comparable { int weight; FileTransferService fileTransferService; -- cgit v1.2.3 From e91e8a30b1f4a806d77d74871df5af6cdb87ca0e Mon Sep 17 00:00:00 2001 From: steckbrief Date: Tue, 23 Aug 2016 09:49:06 +0200 Subject: services.filetransfer.httpupload moved to new namespace services.filetransfer.http.upload; delete parts of services.filetransfer.http moved to .delete package --- .../conversationsplus/services/filetransfer/FileTransferManager.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/main/java/de/thedevstack/conversationsplus/services/filetransfer/FileTransferManager.java') diff --git a/src/main/java/de/thedevstack/conversationsplus/services/filetransfer/FileTransferManager.java b/src/main/java/de/thedevstack/conversationsplus/services/filetransfer/FileTransferManager.java index 017b88ea..2f9a819b 100644 --- a/src/main/java/de/thedevstack/conversationsplus/services/filetransfer/FileTransferManager.java +++ b/src/main/java/de/thedevstack/conversationsplus/services/filetransfer/FileTransferManager.java @@ -9,7 +9,7 @@ import de.thedevstack.android.logcat.Logging; import de.thedevstack.conversationsplus.Config; import de.thedevstack.conversationsplus.entities.Message; import de.thedevstack.conversationsplus.services.FileTransferService; -import de.thedevstack.conversationsplus.services.filetransfer.httpupload.HttpFileTransferEntity; +import de.thedevstack.conversationsplus.services.filetransfer.http.upload.HttpFileTransferEntity; import de.thedevstack.conversationsplus.utils.MessageUtil; /** -- cgit v1.2.3