aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorsteckbrief <steckbrief@chefmail.de>2017-07-31 08:44:32 +0200
committersteckbrief <steckbrief@chefmail.de>2017-07-31 08:44:32 +0200
commit11e2b1accd933eb9fcb4477a60dd0864d9f72a67 (patch)
treee1d27c488d5a697557095add001dca868f523ef4
parent2d41916750e2c31b57cf6325441ff37a8639fe93 (diff)
Implements FS#245: Implement FiletransferHttp (upload and delete), some minor bug fixes including to fail a JingleTransfer in case criterias are not met
-rw-r--r--build.gradle2
-rw-r--r--gradle/wrapper/gradle-wrapper.properties4
-rw-r--r--libs/3rdParty/picasso-2.5.2.jarbin0 -> 120459 bytes
-rw-r--r--libs/MemorizingTrustManager/build.gradle2
-rw-r--r--libs/colorpicker/build.gradle2
-rw-r--r--libs/emojicon/build.gradle2
-rw-r--r--libs/thedevstacklogcat/build.gradle2
-rw-r--r--src/main/java/de/thedevstack/conversationsplus/enums/FileStatus.java2
-rw-r--r--src/main/java/de/thedevstack/conversationsplus/persistance/FileBackend.java35
-rw-r--r--src/main/java/de/thedevstack/conversationsplus/services/filetransfer/FileTransferManager.java2
-rw-r--r--src/main/java/de/thedevstack/conversationsplus/services/filetransfer/http/delete/DeleteRemoteFileService.java9
-rw-r--r--src/main/java/de/thedevstack/conversationsplus/services/filetransfer/http/delete/DeleteTokenReceived.java97
-rw-r--r--src/main/java/de/thedevstack/conversationsplus/services/filetransfer/http/delete/DeletedIqPacketReceived.java47
-rw-r--r--src/main/java/de/thedevstack/conversationsplus/services/filetransfer/http/upload/HttpUploadFileTransferService.java19
-rw-r--r--src/main/java/de/thedevstack/conversationsplus/ui/adapter/ConversationAdapter.java6
-rw-r--r--src/main/java/de/thedevstack/conversationsplus/ui/adapter/MessageAdapter.java30
-rw-r--r--src/main/java/de/thedevstack/conversationsplus/ui/dialogs/MessageDetailsDialog.java2
-rw-r--r--src/main/java/de/thedevstack/conversationsplus/ui/listeners/ResizePictureUserDecisionListener.java2
-rw-r--r--src/main/java/de/thedevstack/conversationsplus/utils/MessageUtil.java3
-rw-r--r--src/main/java/de/thedevstack/conversationsplus/xmpp/XmppConnection.java1
-rw-r--r--src/main/java/de/thedevstack/conversationsplus/xmpp/filetransfer/http/FileTransferHttp.java3
-rw-r--r--src/main/java/de/thedevstack/conversationsplus/xmpp/filetransfer/http/delete/DeleteRequestPacket.java (renamed from src/main/java/de/thedevstack/conversationsplus/xmpp/filetransfer/http/delete/DeleteSlotRequestPacket.java)8
-rw-r--r--src/main/java/de/thedevstack/conversationsplus/xmpp/filetransfer/http/delete/DeleteSlotPacketParser.java29
-rw-r--r--src/main/java/de/thedevstack/conversationsplus/xmpp/filetransfer/http/delete/DeletedPacketParser.java43
-rw-r--r--src/main/java/de/thedevstack/conversationsplus/xmpp/filetransfer/http/delete/FileTransferHttpDeleteRequestPacketGenerator.java (renamed from src/main/java/de/thedevstack/conversationsplus/xmpp/filetransfer/http/delete/FileTransferHttpDeleteSlotRequestPacketGenerator.java)6
-rw-r--r--src/main/java/de/thedevstack/conversationsplus/xmpp/filetransfer/http/upload/FileTransferHttpUploadSlotRequestPacket.java53
-rw-r--r--src/main/java/de/thedevstack/conversationsplus/xmpp/filetransfer/http/upload/HttpUploadRequestSlotPacketGenerator.java35
-rw-r--r--src/main/java/de/thedevstack/conversationsplus/xmpp/filetransfer/http/upload/HttpUploadSlotRequestPacket.java (renamed from src/main/java/de/thedevstack/conversationsplus/xmpp/filetransfer/http/upload/SlotRequestPacket.java)11
-rw-r--r--src/main/java/de/thedevstack/conversationsplus/xmpp/filetransfer/http/upload/SlotPacketParser.java12
-rw-r--r--src/main/java/de/thedevstack/conversationsplus/xmpp/jingle/JingleConnection.java2
30 files changed, 271 insertions, 200 deletions
diff --git a/build.gradle b/build.gradle
index 354456f1..0d7069a3 100644
--- a/build.gradle
+++ b/build.gradle
@@ -73,7 +73,7 @@ ext {
android {
compileSdkVersion 23
- buildToolsVersion "23.0.2"
+ buildToolsVersion '23.0.2'
defaultConfig {
minSdkVersion 14
diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties
index e1adff10..518d1f1f 100644
--- a/gradle/wrapper/gradle-wrapper.properties
+++ b/gradle/wrapper/gradle-wrapper.properties
@@ -1,6 +1,6 @@
-#Sat Apr 09 13:15:52 CEST 2016
+#Wed May 31 19:49:33 CEST 2017
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists
-distributionUrl=http\://services.gradle.org/distributions/gradle-2.12-all.zip
+distributionUrl=https\://services.gradle.org/distributions/gradle-2.12-all.zip
diff --git a/libs/3rdParty/picasso-2.5.2.jar b/libs/3rdParty/picasso-2.5.2.jar
new file mode 100644
index 00000000..6acbaa14
--- /dev/null
+++ b/libs/3rdParty/picasso-2.5.2.jar
Binary files differ
diff --git a/libs/MemorizingTrustManager/build.gradle b/libs/MemorizingTrustManager/build.gradle
index dc2e7b60..5349c4d5 100644
--- a/libs/MemorizingTrustManager/build.gradle
+++ b/libs/MemorizingTrustManager/build.gradle
@@ -11,7 +11,7 @@ apply plugin: 'android-library'
android {
compileSdkVersion 19
- buildToolsVersion "19.1"
+ buildToolsVersion '19.1'
defaultConfig {
minSdkVersion 7
targetSdkVersion 19
diff --git a/libs/colorpicker/build.gradle b/libs/colorpicker/build.gradle
index 1920d0f6..fc6b96fc 100644
--- a/libs/colorpicker/build.gradle
+++ b/libs/colorpicker/build.gradle
@@ -2,7 +2,7 @@ apply plugin: 'com.android.library'
android {
compileSdkVersion 21
- buildToolsVersion "21.1.2"
+ buildToolsVersion '21.1.2'
defaultConfig {
minSdkVersion 7
diff --git a/libs/emojicon/build.gradle b/libs/emojicon/build.gradle
index 659dafb0..8e3728ed 100644
--- a/libs/emojicon/build.gradle
+++ b/libs/emojicon/build.gradle
@@ -2,7 +2,7 @@ apply plugin: 'com.android.library'
android {
compileSdkVersion 21
- buildToolsVersion "21.1.2"
+ buildToolsVersion '21.1.2'
defaultConfig {
minSdkVersion 8
diff --git a/libs/thedevstacklogcat/build.gradle b/libs/thedevstacklogcat/build.gradle
index 00fe2a0b..13cf1dc8 100644
--- a/libs/thedevstacklogcat/build.gradle
+++ b/libs/thedevstacklogcat/build.gradle
@@ -2,7 +2,7 @@ apply plugin: 'com.android.library'
android {
compileSdkVersion 22
- buildToolsVersion "22.0.1"
+ buildToolsVersion '22.0.1'
defaultConfig {
minSdkVersion 14
diff --git a/src/main/java/de/thedevstack/conversationsplus/enums/FileStatus.java b/src/main/java/de/thedevstack/conversationsplus/enums/FileStatus.java
index e4254aeb..31b40512 100644
--- a/src/main/java/de/thedevstack/conversationsplus/enums/FileStatus.java
+++ b/src/main/java/de/thedevstack/conversationsplus/enums/FileStatus.java
@@ -16,5 +16,5 @@ public enum FileStatus {
DELETING,
NOT_FOUND,
DOWNLOADING,
- CHECKING_FILE_SIZE;
+ CHECKING_FILE_SIZE, UPLOAD_FAILED;
}
diff --git a/src/main/java/de/thedevstack/conversationsplus/persistance/FileBackend.java b/src/main/java/de/thedevstack/conversationsplus/persistance/FileBackend.java
index 6643c276..d1da4a8e 100644
--- a/src/main/java/de/thedevstack/conversationsplus/persistance/FileBackend.java
+++ b/src/main/java/de/thedevstack/conversationsplus/persistance/FileBackend.java
@@ -23,6 +23,7 @@ import de.thedevstack.conversationsplus.ConversationsPlusPreferences;
import de.thedevstack.conversationsplus.entities.FileParams;
import de.thedevstack.conversationsplus.exceptions.FileCopyException;
import de.thedevstack.conversationsplus.persistance.observers.FileDeletionObserver;
+import de.thedevstack.conversationsplus.utils.FileUtils;
import de.thedevstack.conversationsplus.utils.StreamUtil;
import de.thedevstack.conversationsplus.Config;
import de.thedevstack.conversationsplus.R;
@@ -44,10 +45,25 @@ public class FileBackend {
if (null == INSTANCE) {
INSTANCE = new FileBackend();
}
+ INSTANCE.checkIfDirectoriesExistAndCreateIfNot();
INSTANCE.initFileObservers();
INSTANCE.createNoMedia();
}
+ private void checkIfDirectoriesExistAndCreateIfNot() {
+ this.checkIfDirectoryExistsAndCreateIfNot(FileBackend.getPrivateFileDirectoryPath());
+ this.checkIfDirectoryExistsAndCreateIfNot(FileBackend.getConversationsFileDirectory());
+ this.checkIfDirectoryExistsAndCreateIfNot(FileBackend.getConversationsImageDirectory());
+ this.checkIfDirectoryExistsAndCreateIfNot(FileBackend.getPrivateImageDirectoryPath());
+ }
+
+ private void checkIfDirectoryExistsAndCreateIfNot(String directoryPath) {
+ File directory = new File(directoryPath);
+ if (!directory.exists()) {
+ directory.mkdirs();
+ }
+ }
+
private void initFileObservers() {
this.privateFilesDirectoryObserver = new FileDeletionObserver(FileBackend.getPrivateFileDirectoryPath());
this.privateFilesImageDirectoryObserver = new FileDeletionObserver(FileBackend.getConversationsFileDirectory());
@@ -72,6 +88,7 @@ public class FileBackend {
}
public static void onFileTransferFolderChanged() {
+ INSTANCE.checkIfDirectoryExistsAndCreateIfNot(FileBackend.getConversationsFileDirectory());
INSTANCE.conversationsFilesDirectoryObserver.stopWatching();
INSTANCE.conversationsFilesDirectoryObserver = new FileDeletionObserver(FileBackend.getConversationsFileDirectory());
INSTANCE.conversationsFilesDirectoryObserver.startWatching();
@@ -79,6 +96,7 @@ public class FileBackend {
}
public static void onImageTransferFolderChanged() {
+ INSTANCE.checkIfDirectoryExistsAndCreateIfNot(FileBackend.getConversationsImageDirectory());
INSTANCE.conversationsImagesDirectoryObserver.stopWatching();
INSTANCE.conversationsImagesDirectoryObserver = new FileDeletionObserver(FileBackend.getConversationsImageDirectory());
INSTANCE.conversationsImagesDirectoryObserver.startWatching();
@@ -107,7 +125,7 @@ public class FileBackend {
}
public static DownloadableFile getFile(Message message, boolean decrypted) {
- DownloadableFile downloadableFile = new DownloadableFile(getFilePath(message, decrypted));
+ DownloadableFile downloadableFile = new DownloadableFile(getFilePath(message, decrypted, null));
FileParams fileParams = message.getFileParams();
if (null != fileParams) {
if (null != fileParams.getKey()) {
@@ -122,10 +140,7 @@ public class FileBackend {
}
protected static String getFilePath(Message message, String extension) {
- String path = FileBackend.getFilePath(message, true);
- if (!path.endsWith(extension)) {
- path += "." + extension;
- }
+ String path = FileBackend.getFilePath(message, true, extension);
return path;
}
@@ -137,7 +152,7 @@ public class FileBackend {
return getFilePath(message, extension);
}
- protected static String getFilePath(Message message, boolean decrypted) {
+ protected static String getFilePath(Message message, boolean decrypted, String fallbackExtension) {
final boolean encrypted = !decrypted
&& (message.getEncryption() == Message.ENCRYPTION_PGP
|| message.getEncryption() == Message.ENCRYPTION_DECRYPTED);
@@ -157,7 +172,11 @@ public class FileBackend {
path = getConversationsFileDirectory() + path;
}
String extension = MimeTypeMap.getSingleton().getExtensionFromMimeType(mime);
+ if (null != extension) {
path += "." + extension;
+ } else if (null != fallbackExtension) {
+ path += "." +fallbackExtension;
+ }
fileParams.setPath(path);
}
@@ -218,9 +237,11 @@ public class FileBackend {
}
public static DownloadableFile compressImageAndCopyToPrivateStorage(Message message, Bitmap scaledBitmap) throws FileCopyException {
+ if (null == message.getFileParams() || null == message.getFileParams().getPath()) {
String path = getFilePath(message, "jpg");
- message.getFileParams().setPath(path);
message.setRelativeFilePath(path); // TODO: Remove
+ }
+
DownloadableFile file = getFile(message);
file.getParentFile().mkdirs();
OutputStream os = null;
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 8d971bb2..b99f8d82 100644
--- a/src/main/java/de/thedevstack/conversationsplus/services/filetransfer/FileTransferManager.java
+++ b/src/main/java/de/thedevstack/conversationsplus/services/filetransfer/FileTransferManager.java
@@ -8,6 +8,7 @@ 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.enums.FileStatus;
import de.thedevstack.conversationsplus.services.FileTransferService;
import de.thedevstack.conversationsplus.services.filetransfer.http.upload.HttpUploadFileTransferEntity;
import de.thedevstack.conversationsplus.utils.MessageUtil;
@@ -124,6 +125,7 @@ public class FileTransferManager implements FileTransferStatusListener {
}
}
if (!retransferStarted) {
+ entity.getMessage().getFileParams().setFileStatus(FileStatus.UPLOAD_FAILED);
MessageUtil.markMessage(entity.getMessage(), Message.STATUS_SEND_FAILED);
}
}
diff --git a/src/main/java/de/thedevstack/conversationsplus/services/filetransfer/http/delete/DeleteRemoteFileService.java b/src/main/java/de/thedevstack/conversationsplus/services/filetransfer/http/delete/DeleteRemoteFileService.java
index 2085cf4b..83f7e359 100644
--- a/src/main/java/de/thedevstack/conversationsplus/services/filetransfer/http/delete/DeleteRemoteFileService.java
+++ b/src/main/java/de/thedevstack/conversationsplus/services/filetransfer/http/delete/DeleteRemoteFileService.java
@@ -1,16 +1,13 @@
package de.thedevstack.conversationsplus.services.filetransfer.http.delete;
-import de.thedevstack.conversationsplus.ConversationsPlusApplication;
import de.thedevstack.conversationsplus.entities.Account;
import de.thedevstack.conversationsplus.entities.Message;
import de.thedevstack.conversationsplus.enums.FileStatus;
-import de.thedevstack.conversationsplus.persistance.DatabaseBackend;
import de.thedevstack.conversationsplus.ui.listeners.SimpleUserDecisionCallback;
import de.thedevstack.conversationsplus.utils.MessageUtil;
-import de.thedevstack.conversationsplus.utils.UiUpdateHelper;
import de.thedevstack.conversationsplus.utils.XmppSendUtil;
import de.thedevstack.conversationsplus.xmpp.filetransfer.http.FileTransferHttp;
-import de.thedevstack.conversationsplus.xmpp.filetransfer.http.delete.FileTransferHttpDeleteSlotRequestPacketGenerator;
+import de.thedevstack.conversationsplus.xmpp.filetransfer.http.delete.FileTransferHttpDeleteRequestPacketGenerator;
import de.thedevstack.conversationsplus.xmpp.jid.Jid;
import de.thedevstack.conversationsplus.xmpp.stanzas.IqPacket;
@@ -36,9 +33,9 @@ public class DeleteRemoteFileService implements SimpleUserDecisionCallback {
Account account = this.message.getConversation().getAccount();
Jid host = account.getXmppConnection().findDiscoItemByFeature(FileTransferHttp.NAMESPACE);
if (null != host) {
- IqPacket request = FileTransferHttpDeleteSlotRequestPacketGenerator.generate(host, path);
+ IqPacket request = FileTransferHttpDeleteRequestPacketGenerator.generate(host, path);
MessageUtil.setAndSaveFileStatus(this.message, FileStatus.DELETING);
- XmppSendUtil.sendIqPacket(account, request, new DeleteTokenReceived(remoteFile));
+ XmppSendUtil.sendIqPacket(account, request, new DeletedIqPacketReceived(remoteFile));
}
}
}
diff --git a/src/main/java/de/thedevstack/conversationsplus/services/filetransfer/http/delete/DeleteTokenReceived.java b/src/main/java/de/thedevstack/conversationsplus/services/filetransfer/http/delete/DeleteTokenReceived.java
deleted file mode 100644
index d61a5c6a..00000000
--- a/src/main/java/de/thedevstack/conversationsplus/services/filetransfer/http/delete/DeleteTokenReceived.java
+++ /dev/null
@@ -1,97 +0,0 @@
-package de.thedevstack.conversationsplus.services.filetransfer.http.delete;
-
-import android.widget.Toast;
-
-import org.json.JSONException;
-import org.json.JSONObject;
-
-import java.io.IOException;
-
-import de.thedevstack.android.logcat.Logging;
-import de.thedevstack.conversationsplus.R;
-import de.thedevstack.conversationsplus.entities.Account;
-import de.thedevstack.conversationsplus.enums.FileStatus;
-import de.thedevstack.conversationsplus.http.HttpClient;
-import de.thedevstack.conversationsplus.utils.MessageUtil;
-import de.thedevstack.conversationsplus.utils.ui.ConversationsPlusToast;
-import de.thedevstack.conversationsplus.xmpp.OnIqPacketReceived;
-import de.thedevstack.conversationsplus.xmpp.exceptions.ServiceUnavailableException;
-import de.thedevstack.conversationsplus.xmpp.exceptions.XmppException;
-import de.thedevstack.conversationsplus.xmpp.filetransfer.http.delete.DeleteSlotPacketParser;
-import de.thedevstack.conversationsplus.xmpp.stanzas.IqPacket;
-import okhttp3.Call;
-import okhttp3.Callback;
-import okhttp3.OkHttpClient;
-import okhttp3.Request;
-import okhttp3.Response;
-
-/**
- *
- */
-public class DeleteTokenReceived implements OnIqPacketReceived {
- private static final String HEADER_NAME_DELETE_TOKEN = "X-FILETRANSFER-HTTP-DELETE-TOKEN";
- private final DeleteRemoteFile remoteFile;
-
- public DeleteTokenReceived(DeleteRemoteFile remoteFile) {
- this.remoteFile = remoteFile;
- }
-
- @Override
- public void onIqPacketReceived(Account account, IqPacket packet) {
- try {
- String url = this.remoteFile.getPath();
- String deleteToken = DeleteSlotPacketParser.parseDeleteToken(packet);
- Logging.d("filetransfer.http.delete", "Got delete token '" + deleteToken + "' for remote file '" + remoteFile.getPath() + "'");
- OkHttpClient client = HttpClient.getOkHttpClient(true);
- Request request = new Request.Builder()
- .url(url)
- .addHeader(HEADER_NAME_DELETE_TOKEN, deleteToken)
- .delete()
- .build();
- client.newCall(request).enqueue(new Callback() {
- @Override
- public void onFailure(Call call, IOException e) {
- Logging.e("filetransfer.http.delete", "Error while connecting to '" + call.request().url() + "': " + e.getMessage());
- MessageUtil.setAndSaveFileStatus(remoteFile.getMessage(), FileStatus.DELETE_FAILED);
- }
-
- @Override
- public void onResponse(Call call, Response response) throws IOException {
- if (response.isSuccessful()) {
- MessageUtil.setAndSaveFileStatus(remoteFile.getMessage(), FileStatus.DELETED);
- Logging.i("filetransfer.http.delete", "Remote file successfully deleted '" + remoteFile.getPath() + "'");
- } else {
- String detailedMessage = response.body().string();
- FileStatus fileStatus = FileStatus.DELETE_FAILED;
- switch (response.code()) {
- case 403:
- case 500:
- try {
- JSONObject jsonObject = new JSONObject(detailedMessage);
- detailedMessage = jsonObject.getString("msg");
- } catch (JSONException e) {
- Logging.e("filetransfer.http.delete", "Failed to get error message from expected json response: " + detailedMessage);
- }
- break;
- case 404:
- fileStatus = FileStatus.DELETED;
- Logging.i("filetransfer.http.delete", "Failed to delete file - it was already deleted.");
- break;
- }
- Logging.e("filetransfer.http.delete", "Could not delete remote file '" + remoteFile.getPath() + "'. Response Code: " + response.code() + ", details: " + detailedMessage);
- MessageUtil.setAndSaveFileStatus(remoteFile.getMessage(), fileStatus);
- }
- }
- });
-
- } catch (XmppException e) {
- Logging.e("filetransfer.http.delete", "Error while trying to get the delete token: " + e.getMessage());
- int messageResId = R.string.cplus_remote_file_delete_failed;
- if (e instanceof ServiceUnavailableException) {
- messageResId = R.string.cplus_remote_file_delete_service_unavailable;
- }
- ConversationsPlusToast.makeErrorToast(messageResId, Toast.LENGTH_LONG);
- MessageUtil.setAndSaveFileStatus(remoteFile.getMessage(), FileStatus.DELETE_FAILED);
- }
- }
-}
diff --git a/src/main/java/de/thedevstack/conversationsplus/services/filetransfer/http/delete/DeletedIqPacketReceived.java b/src/main/java/de/thedevstack/conversationsplus/services/filetransfer/http/delete/DeletedIqPacketReceived.java
new file mode 100644
index 00000000..470a6010
--- /dev/null
+++ b/src/main/java/de/thedevstack/conversationsplus/services/filetransfer/http/delete/DeletedIqPacketReceived.java
@@ -0,0 +1,47 @@
+package de.thedevstack.conversationsplus.services.filetransfer.http.delete;
+
+import android.widget.Toast;
+
+import de.thedevstack.android.logcat.Logging;
+import de.thedevstack.conversationsplus.R;
+import de.thedevstack.conversationsplus.entities.Account;
+import de.thedevstack.conversationsplus.enums.FileStatus;
+import de.thedevstack.conversationsplus.utils.MessageUtil;
+import de.thedevstack.conversationsplus.utils.ui.ConversationsPlusToast;
+import de.thedevstack.conversationsplus.xmpp.OnIqPacketReceived;
+import de.thedevstack.conversationsplus.xmpp.exceptions.ServiceUnavailableException;
+import de.thedevstack.conversationsplus.xmpp.exceptions.XmppException;
+import de.thedevstack.conversationsplus.xmpp.filetransfer.http.delete.DeletedPacketParser;
+import de.thedevstack.conversationsplus.xmpp.stanzas.IqPacket;
+
+/**
+ *
+ */
+public class DeletedIqPacketReceived implements OnIqPacketReceived {
+ private final DeleteRemoteFile remoteFile;
+
+ public DeletedIqPacketReceived(DeleteRemoteFile remoteFile) {
+ this.remoteFile = remoteFile;
+ }
+
+ @Override
+ public void onIqPacketReceived(Account account, IqPacket packet) {
+ try {
+ boolean fileIsDeleted = DeletedPacketParser.parseDeleteToken(packet);
+ if (fileIsDeleted) {
+ MessageUtil.setAndSaveFileStatus(remoteFile.getMessage(), FileStatus.DELETED);
+ Logging.i("filetransfer.http.delete", "Remote file successfully deleted '" + remoteFile.getPath() + "'");
+ } else {
+ Logging.e("filetransfer.http.delete", "Unexpectedly failed to delete remote file.");
+ }
+ } catch (XmppException e) {
+ Logging.e("filetransfer.http.delete", "Error while trying to delete remote file: " + e.getMessage());
+ int messageResId = R.string.cplus_remote_file_delete_failed;
+ if (e instanceof ServiceUnavailableException) {
+ messageResId = R.string.cplus_remote_file_delete_service_unavailable;
+ }
+ ConversationsPlusToast.makeErrorToast(messageResId, Toast.LENGTH_LONG);
+ MessageUtil.setAndSaveFileStatus(remoteFile.getMessage(), FileStatus.DELETE_FAILED);
+ }
+ }
+}
diff --git a/src/main/java/de/thedevstack/conversationsplus/services/filetransfer/http/upload/HttpUploadFileTransferService.java b/src/main/java/de/thedevstack/conversationsplus/services/filetransfer/http/upload/HttpUploadFileTransferService.java
index c2e92a9e..28bb3a1c 100644
--- a/src/main/java/de/thedevstack/conversationsplus/services/filetransfer/http/upload/HttpUploadFileTransferService.java
+++ b/src/main/java/de/thedevstack/conversationsplus/services/filetransfer/http/upload/HttpUploadFileTransferService.java
@@ -15,10 +15,7 @@ import de.thedevstack.conversationsplus.services.filetransfer.AbstractFileTransf
import de.thedevstack.conversationsplus.utils.AccountUtil;
import de.thedevstack.conversationsplus.utils.MessageUtil;
import de.thedevstack.conversationsplus.utils.XmppSendUtil;
-import de.thedevstack.conversationsplus.xmpp.filetransfer.http.FileTransferHttp;
-import de.thedevstack.conversationsplus.xmpp.filetransfer.http.upload.HttpUpload;
import de.thedevstack.conversationsplus.xmpp.filetransfer.http.upload.HttpUploadRequestSlotPacketGenerator;
-import de.thedevstack.conversationsplus.xmpp.jid.Jid;
import de.thedevstack.conversationsplus.xmpp.stanzas.IqPacket;
/**
@@ -63,29 +60,18 @@ public class HttpUploadFileTransferService extends AbstractFileTransferService i
file.setExpectedSize(inputStreamAndExpectedSize.second);
Logging.d("httpupload", "Requesting upload slot for file upload");
- Jid host = this.getHost(account);
- if (null != host) {
- IqPacket request = HttpUploadRequestSlotPacketGenerator.generate(host, file.getName(), file.getSize(), file.getMimeType());
+ IqPacket request = HttpUploadRequestSlotPacketGenerator.generate(account, message.getContact().getJid(), file.getName(), file.getSize(), file.getMimeType());
XmppSendUtil.sendIqPacket(account, request, new HttpUploadSlotRequestReceived(entity));
MessageUtil.markMessage(message, Message.STATUS_UNSEND);
Logging.d("httpupload", "Upload slot for file upload requested");
started = true;
- }
} catch (FileNotFoundException e) {
Logging.e("httpupload", "Could not find file, exception message: " + e.getMessage());
}
return started;
}
- private Jid getHost(Account account) {
- Jid host = account.getXmppConnection().findDiscoItemByFeature(FileTransferHttp.NAMESPACE);
- if (null == host) {
- host = account.getXmppConnection().findDiscoItemByFeature(HttpUpload.NAMESPACE);
- }
- return host;
- }
-
/**
* Checks whether a message can be sent using this service or not.
*
@@ -99,6 +85,7 @@ public class HttpUploadFileTransferService extends AbstractFileTransferService i
&& null != message.getConversation().getAccount()
&& null != message.getFileParams()
&& message.needsUploading()
- && AccountUtil.isHttpUploadAvailable(message.getConversation().getAccount(), message.getFileParams().getSize());
+ && (AccountUtil.isHttpUploadAvailable(message.getConversation().getAccount(), message.getFileParams().getSize())
+ || AccountUtil.isFileTransferHttpAvailable(message.getConversation().getAccount()));
}
}
diff --git a/src/main/java/de/thedevstack/conversationsplus/ui/adapter/ConversationAdapter.java b/src/main/java/de/thedevstack/conversationsplus/ui/adapter/ConversationAdapter.java
index df7fc922..9e550988 100644
--- a/src/main/java/de/thedevstack/conversationsplus/ui/adapter/ConversationAdapter.java
+++ b/src/main/java/de/thedevstack/conversationsplus/ui/adapter/ConversationAdapter.java
@@ -24,6 +24,7 @@ import de.thedevstack.conversationsplus.ConversationsPlusColors;
import de.thedevstack.conversationsplus.ConversationsPlusPreferences;
import de.thedevstack.conversationsplus.ui.listeners.ShowResourcesListDialogListener;
import de.thedevstack.conversationsplus.utils.ImageUtil;
+import de.thedevstack.conversationsplus.utils.MessageUtil;
import de.tzur.conversations.Settings;
import de.thedevstack.conversationsplus.R;
import de.thedevstack.conversationsplus.entities.Account;
@@ -108,10 +109,7 @@ public class ConversationAdapter extends ArrayAdapter<Conversation> {
imagePreview.setVisibility(View.GONE);
CharSequence msgText = preview.first;
String msgPrefix = null;
- if (message.getStatus() == Message.STATUS_SEND
- || message.getStatus() == Message.STATUS_SEND_DISPLAYED
- || message.getStatus() == Message.STATUS_SEND_FAILED
- || message.getStatus() == Message.STATUS_SEND_RECEIVED) {
+ if (MessageUtil.isMessageSent(message)) {
msgPrefix = activity.getString(R.string.cplus_me);
} else if (conversation.getMode() == Conversation.MODE_MULTI) {
msgPrefix = UIHelper.getMessageDisplayName(message);
diff --git a/src/main/java/de/thedevstack/conversationsplus/ui/adapter/MessageAdapter.java b/src/main/java/de/thedevstack/conversationsplus/ui/adapter/MessageAdapter.java
index e49575f6..9a501b89 100644
--- a/src/main/java/de/thedevstack/conversationsplus/ui/adapter/MessageAdapter.java
+++ b/src/main/java/de/thedevstack/conversationsplus/ui/adapter/MessageAdapter.java
@@ -496,14 +496,31 @@ public class MessageAdapter extends ArrayAdapter<Message> {
private void displayFileMessage(final Message message, ViewHolder viewHolder) {
Transferable transferable = message.getTransferable();
- if (null != transferable) {
+ if (FileStatus.CHECKING_FILE_SIZE == message.getFileParams().getFileStatus()) {
+ displayInfoMessage(viewHolder, activity.getString(R.string.checking_remote_filesize));
+ } else if (MessageUtil.isAttachedFileAnImage(message)
+ && (FileStatus.DOWNLOADED == message.getFileParams().getFileStatus())
+ || FileStatus.DELETED == message.getFileParams().getFileStatus()
+ || FileStatus.DELETING == message.getFileParams().getFileStatus()
+ || FileStatus.DELETE_FAILED == message.getFileParams().getFileStatus()
+ || FileStatus.UPLOADED == message.getFileParams().getFileStatus()) {
+ displayImageMessage(viewHolder, message);
+ } else if ((MessageUtil.isTypeFileAndDecrypted(message) || FileStatus.DOWNLOADED == message.getFileParams().getFileStatus())
+ && !MessageUtil.needsDownload(message)) {
+ displayOpenableMessage(viewHolder, message);
+ } else if (Message.Decision.NEVER == message.treatAsDownloadable() || !MessageUtil.mayFileRemoteAvailable(message)) {
+ displayTextMessage(viewHolder, message);
+ } else if (FileStatus.UPLOAD_FAILED == message.getFileParams().getFileStatus()) {
+ displayImageMessage(viewHolder, message); // TODO Show failed status
+ } else if (null != transferable) {
switch (transferable.getStatus()) {
case Transferable.STATUS_OFFER:
case Transferable.STATUS_OFFER_CHECK_FILESIZE:
displayDownloadableMessage(viewHolder, message);
break;
case Transferable.STATUS_UPLOADING:
- displayFileMessage(message, viewHolder);
+ // Should not happen, since this is now covered by the other if-statements
+ // TODO Maybe in Jingle File Transfer?? Needs to be checked!
break;
case Transferable.STATUS_DELETED:
case Transferable.STATUS_CHECKING:
@@ -513,15 +530,6 @@ public class MessageAdapter extends ArrayAdapter<Message> {
displayInfoMessage(viewHolder, UIHelper.getMessagePreview(activity, message).first);
break;
}
- } else if (FileStatus.CHECKING_FILE_SIZE == message.getFileParams().getFileStatus()) {
- displayInfoMessage(viewHolder, activity.getString(R.string.checking_remote_filesize));
- } else if (MessageUtil.isAttachedFileAnImage(message) && FileStatus.DOWNLOADED == message.getFileParams().getFileStatus()) {
- displayImageMessage(viewHolder, message);
- } else if ((MessageUtil.isTypeFileAndDecrypted(message) || FileStatus.DOWNLOADED == message.getFileParams().getFileStatus())
- && !MessageUtil.needsDownload(message)) {
- displayOpenableMessage(viewHolder, message);
- } else if (Message.Decision.NEVER == message.treatAsDownloadable() || !MessageUtil.mayFileRemoteAvailable(message)) {
- displayTextMessage(viewHolder, message);
} else {
displayDownloadableMessage(viewHolder, message);
}
diff --git a/src/main/java/de/thedevstack/conversationsplus/ui/dialogs/MessageDetailsDialog.java b/src/main/java/de/thedevstack/conversationsplus/ui/dialogs/MessageDetailsDialog.java
index c640ce6d..b43384a4 100644
--- a/src/main/java/de/thedevstack/conversationsplus/ui/dialogs/MessageDetailsDialog.java
+++ b/src/main/java/de/thedevstack/conversationsplus/ui/dialogs/MessageDetailsDialog.java
@@ -56,7 +56,7 @@ public class MessageDetailsDialog extends AbstractAlertDialog {
* @param message the message to display in dialog
*/
protected void displayFileInfo(View view, Message message) {
- if (message.getType() == Message.TYPE_IMAGE || message.getType() == Message.TYPE_FILE || message.getTransferable() != null) {
+ if (message.isHttpUploaded() || message.getType() == Message.TYPE_IMAGE || message.getType() == Message.TYPE_FILE || message.getTransferable() != null) {
Logging.d("messagedetailsfile", "File is stored in path: " + message.getRelativeFilePath());
view.findViewById(R.id.dlgMsgDetFileTable).setVisibility(View.VISIBLE);
if (null != message.getFileParams()) {
diff --git a/src/main/java/de/thedevstack/conversationsplus/ui/listeners/ResizePictureUserDecisionListener.java b/src/main/java/de/thedevstack/conversationsplus/ui/listeners/ResizePictureUserDecisionListener.java
index 1574bb85..68d2e47c 100644
--- a/src/main/java/de/thedevstack/conversationsplus/ui/listeners/ResizePictureUserDecisionListener.java
+++ b/src/main/java/de/thedevstack/conversationsplus/ui/listeners/ResizePictureUserDecisionListener.java
@@ -31,6 +31,7 @@ import de.thedevstack.conversationsplus.ui.UiCallback;
import de.thedevstack.conversationsplus.ui.XmppActivity;
import de.thedevstack.conversationsplus.utils.MimeUtils;
import de.thedevstack.conversationsplus.utils.StreamUtil;
+import de.thedevstack.conversationsplus.utils.UiUpdateHelper;
/**
* Listener to let the user decide whether to resize a picture before sending or not.
@@ -57,6 +58,7 @@ public class ResizePictureUserDecisionListener implements UserDecisionListener {
@Override
public void success(Message message) {
+ UiUpdateHelper.updateConversationUi();
ResizePictureUserDecisionListener.this.xmppConnectionService.sendMessage(message);
}
diff --git a/src/main/java/de/thedevstack/conversationsplus/utils/MessageUtil.java b/src/main/java/de/thedevstack/conversationsplus/utils/MessageUtil.java
index e0d627b9..5e629485 100644
--- a/src/main/java/de/thedevstack/conversationsplus/utils/MessageUtil.java
+++ b/src/main/java/de/thedevstack/conversationsplus/utils/MessageUtil.java
@@ -181,6 +181,7 @@ public final class MessageUtil {
switch (message.getStatus()) {
case Message.STATUS_SEND:
case Message.STATUS_SEND_DISPLAYED:
+ case Message.STATUS_SEND_FAILED:
case Message.STATUS_SEND_RECEIVED:
return true;
default:
@@ -283,7 +284,7 @@ public final class MessageUtil {
fileParams.setHeight(imageHeight);
}
String relativeFilePathFromMessage = message.getRelativeFilePath();
- if (null != relativeFilePathFromMessage && relativeFilePathFromMessage.startsWith("/")) {
+ if (null != relativeFilePathFromMessage && relativeFilePathFromMessage.startsWith("/") && (null == fileParams.getPath() || !relativeFilePathFromMessage.equals(fileParams.getPath()))) {
fileParams.setPath(relativeFilePathFromMessage);
}
}
diff --git a/src/main/java/de/thedevstack/conversationsplus/xmpp/XmppConnection.java b/src/main/java/de/thedevstack/conversationsplus/xmpp/XmppConnection.java
index 1082e19f..b886bf65 100644
--- a/src/main/java/de/thedevstack/conversationsplus/xmpp/XmppConnection.java
+++ b/src/main/java/de/thedevstack/conversationsplus/xmpp/XmppConnection.java
@@ -1208,6 +1208,7 @@ public class XmppConnection implements Runnable {
disconnect(true);
return;
}
+ Logging.d("SendIqPacket", "Outgoing stanza: " + packet.toString());
tagWriter.writeStanzaAsync(packet);
if (packet instanceof AbstractAcknowledgeableStanza) {
AbstractAcknowledgeableStanza stanza = (AbstractAcknowledgeableStanza) packet;
diff --git a/src/main/java/de/thedevstack/conversationsplus/xmpp/filetransfer/http/FileTransferHttp.java b/src/main/java/de/thedevstack/conversationsplus/xmpp/filetransfer/http/FileTransferHttp.java
index 28f4f870..1c6544b4 100644
--- a/src/main/java/de/thedevstack/conversationsplus/xmpp/filetransfer/http/FileTransferHttp.java
+++ b/src/main/java/de/thedevstack/conversationsplus/xmpp/filetransfer/http/FileTransferHttp.java
@@ -1,8 +1,9 @@
package de.thedevstack.conversationsplus.xmpp.filetransfer.http;
/**
- * Created by steckbrief on 21.08.2016.
+ *
*/
public interface FileTransferHttp {
String NAMESPACE = "urn:xmpp:filetransfer:http";
+ String DEFAULT_MIME_TYPE = "application/octet-stream";
}
diff --git a/src/main/java/de/thedevstack/conversationsplus/xmpp/filetransfer/http/delete/DeleteSlotRequestPacket.java b/src/main/java/de/thedevstack/conversationsplus/xmpp/filetransfer/http/delete/DeleteRequestPacket.java
index e389d851..d358a266 100644
--- a/src/main/java/de/thedevstack/conversationsplus/xmpp/filetransfer/http/delete/DeleteSlotRequestPacket.java
+++ b/src/main/java/de/thedevstack/conversationsplus/xmpp/filetransfer/http/delete/DeleteRequestPacket.java
@@ -7,19 +7,19 @@ import de.thedevstack.conversationsplus.xmpp.stanzas.IqPacket;
/**
* Created by steckbrief on 21.08.2016.
*/
-public class DeleteSlotRequestPacket extends IqPacket {
+public class DeleteRequestPacket extends IqPacket {
public static final String ELEMENT_NAME = "request";
public static final String FILEURL_ELEMENT_NAME = "fileurl";
private Element requestElement;
private String fileurl;
- private DeleteSlotRequestPacket() {
+ private DeleteRequestPacket() {
super(TYPE.GET);
- this.requestElement = super.addChild(DeleteSlotRequestPacket.ELEMENT_NAME, FileTransferHttp.NAMESPACE);
+ this.requestElement = super.addChild(DeleteRequestPacket.ELEMENT_NAME, FileTransferHttp.NAMESPACE);
this.requestElement.setAttribute("type", "delete");
}
- public DeleteSlotRequestPacket(String fileurl) {
+ public DeleteRequestPacket(String fileurl) {
this();
this.setFileURL(fileurl);
}
diff --git a/src/main/java/de/thedevstack/conversationsplus/xmpp/filetransfer/http/delete/DeleteSlotPacketParser.java b/src/main/java/de/thedevstack/conversationsplus/xmpp/filetransfer/http/delete/DeleteSlotPacketParser.java
deleted file mode 100644
index 7c011449..00000000
--- a/src/main/java/de/thedevstack/conversationsplus/xmpp/filetransfer/http/delete/DeleteSlotPacketParser.java
+++ /dev/null
@@ -1,29 +0,0 @@
-package de.thedevstack.conversationsplus.xmpp.filetransfer.http.delete;
-
-import de.thedevstack.conversationsplus.xml.Element;
-import de.thedevstack.conversationsplus.xmpp.IqPacketParser;
-import de.thedevstack.conversationsplus.xmpp.exceptions.UnexpectedIqPacketTypeException;
-import de.thedevstack.conversationsplus.xmpp.exceptions.XmppException;
-import de.thedevstack.conversationsplus.xmpp.filetransfer.http.FileTransferHttp;
-import de.thedevstack.conversationsplus.xmpp.stanzas.IqPacket;
-import de.thedevstack.conversationsplus.xmpp.utils.ErrorIqPacketExceptionHelper;
-
-/**
- * Created by steckbrief on 21.08.2016.
- */
-public class DeleteSlotPacketParser extends IqPacketParser {
- public static String parseDeleteToken(IqPacket packet) throws XmppException {
- String deletetoken = null;
- if (packet.getType() == IqPacket.TYPE.RESULT) {
- Element slot = findRequiredChild(packet, "slot", FileTransferHttp.NAMESPACE);
-
- deletetoken = findRequiredChildContent(slot, "deletetoken");
- } else if (packet.getType() == IqPacket.TYPE.ERROR) {
- ErrorIqPacketExceptionHelper.throwIqErrorException(packet);
- } else {
- throw new UnexpectedIqPacketTypeException(packet, packet.getType(), IqPacket.TYPE.RESULT, IqPacket.TYPE.ERROR);
- }
-
- return deletetoken;
- }
-}
diff --git a/src/main/java/de/thedevstack/conversationsplus/xmpp/filetransfer/http/delete/DeletedPacketParser.java b/src/main/java/de/thedevstack/conversationsplus/xmpp/filetransfer/http/delete/DeletedPacketParser.java
new file mode 100644
index 00000000..df17a997
--- /dev/null
+++ b/src/main/java/de/thedevstack/conversationsplus/xmpp/filetransfer/http/delete/DeletedPacketParser.java
@@ -0,0 +1,43 @@
+package de.thedevstack.conversationsplus.xmpp.filetransfer.http.delete;
+
+import de.thedevstack.conversationsplus.xml.Element;
+import de.thedevstack.conversationsplus.xmpp.IqPacketParser;
+import de.thedevstack.conversationsplus.xmpp.exceptions.UnexpectedIqPacketTypeException;
+import de.thedevstack.conversationsplus.xmpp.exceptions.XmppException;
+import de.thedevstack.conversationsplus.xmpp.filetransfer.http.FileTransferHttp;
+import de.thedevstack.conversationsplus.xmpp.stanzas.IqPacket;
+import de.thedevstack.conversationsplus.xmpp.utils.ErrorIqPacketExceptionHelper;
+
+/**
+ * IqPacketParser to parse the response of a remote file delete request.
+ * This parser parses a IqPacket according to the specification 'filetransfer for XMPP over http".
+ */
+public class DeletedPacketParser extends IqPacketParser {
+ /**
+ * Parses an IqPacket.
+ * <pre>
+ * <iq from='montague.tld'
+ * id='delete-file_002'
+ * to='romeo@montague.tld/garden'
+ * type='result'>
+ * <deleted xmlns='urn:xmpp:filetransfer:http'/>
+ * </iq>
+ * </pre>
+ * @param packet the packet to parse
+ * @return <code>true</code> if the result packet contains a deleted element of namespace <code>urn:xmpp:filetransfer:http</code>
+ * @throws XmppException in case of IqPacket type error or {@link UnexpectedIqPacketTypeException} in case of an unexpected IqPacket type.
+ */
+ public static boolean parseDeleteToken(IqPacket packet) throws XmppException {
+ boolean successfullyDeleted = false;
+ if (packet.getType() == IqPacket.TYPE.RESULT) {
+ Element deletedElement = findRequiredChild(packet, "deleted", FileTransferHttp.NAMESPACE);
+ successfullyDeleted = null != deletedElement;
+ } else if (packet.getType() == IqPacket.TYPE.ERROR) {
+ ErrorIqPacketExceptionHelper.throwIqErrorException(packet);
+ } else {
+ throw new UnexpectedIqPacketTypeException(packet, packet.getType(), IqPacket.TYPE.RESULT, IqPacket.TYPE.ERROR);
+ }
+
+ return successfullyDeleted;
+ }
+}
diff --git a/src/main/java/de/thedevstack/conversationsplus/xmpp/filetransfer/http/delete/FileTransferHttpDeleteSlotRequestPacketGenerator.java b/src/main/java/de/thedevstack/conversationsplus/xmpp/filetransfer/http/delete/FileTransferHttpDeleteRequestPacketGenerator.java
index ac7de74e..88ad5d5a 100644
--- a/src/main/java/de/thedevstack/conversationsplus/xmpp/filetransfer/http/delete/FileTransferHttpDeleteSlotRequestPacketGenerator.java
+++ b/src/main/java/de/thedevstack/conversationsplus/xmpp/filetransfer/http/delete/FileTransferHttpDeleteRequestPacketGenerator.java
@@ -6,7 +6,7 @@ import de.thedevstack.conversationsplus.xmpp.stanzas.IqPacket;
/**
* Created by steckbrief on 21.08.2016.
*/
-public final class FileTransferHttpDeleteSlotRequestPacketGenerator {
+public final class FileTransferHttpDeleteRequestPacketGenerator {
/**
* Generates the IqPacket to request a slot to delete a file previously uploaded via http upload.
* The attributes from and id are not set in here - this is added while sending the packet.
@@ -25,7 +25,7 @@ public final class FileTransferHttpDeleteSlotRequestPacketGenerator {
* @return the IqPacket
*/
public static IqPacket generate(Jid host, String fileurl) {
- DeleteSlotRequestPacket packet = new DeleteSlotRequestPacket(fileurl);
+ DeleteRequestPacket packet = new DeleteRequestPacket(fileurl);
packet.setTo(host);
return packet;
}
@@ -33,7 +33,7 @@ public final class FileTransferHttpDeleteSlotRequestPacketGenerator {
/**
* Utility class - avoid instantiation
*/
- private FileTransferHttpDeleteSlotRequestPacketGenerator() {
+ private FileTransferHttpDeleteRequestPacketGenerator() {
// Helper class - avoid instantiation
}
}
diff --git a/src/main/java/de/thedevstack/conversationsplus/xmpp/filetransfer/http/upload/FileTransferHttpUploadSlotRequestPacket.java b/src/main/java/de/thedevstack/conversationsplus/xmpp/filetransfer/http/upload/FileTransferHttpUploadSlotRequestPacket.java
new file mode 100644
index 00000000..2d7ed1c7
--- /dev/null
+++ b/src/main/java/de/thedevstack/conversationsplus/xmpp/filetransfer/http/upload/FileTransferHttpUploadSlotRequestPacket.java
@@ -0,0 +1,53 @@
+package de.thedevstack.conversationsplus.xmpp.filetransfer.http.upload;
+
+import de.thedevstack.conversationsplus.xml.Element;
+import de.thedevstack.conversationsplus.xmpp.filetransfer.http.FileTransferHttp;
+import de.thedevstack.conversationsplus.xmpp.stanzas.IqPacket;
+
+/**
+ *
+ */
+public class FileTransferHttpUploadSlotRequestPacket extends IqPacket {
+ public static final String ELEMENT_NAME = "request";
+ public static final String FILENAME_ELEMENT_NAME = "filename";
+ public static final String FILESIZE_ELEMENT_NAME = "size";
+ public static final String MIME_ELEMENT_NAME = "content-type";
+ private static final String RECIPIENT_ATTRIBUTE_NAME = "recipient";
+ private Element requestElement;
+ private String filename;
+ private long filesize;
+ private String mime;
+
+ public FileTransferHttpUploadSlotRequestPacket(String recipient, String filename, long filesize, String mime) {
+ super(TYPE.GET);
+ this.requestElement = super.addChild(FileTransferHttpUploadSlotRequestPacket.ELEMENT_NAME, FileTransferHttp.NAMESPACE);
+ this.requestElement.setAttribute(RECIPIENT_ATTRIBUTE_NAME, recipient);
+ this.setFilename(filename);
+ this.setFilesize(filesize);
+ this.setMime(mime);
+ }
+
+ public void setFilename(String filename) {
+ if (null == filename || filename.isEmpty()) {
+ throw new IllegalArgumentException("filename must not be null or empty.");
+ }
+ this.filename = filename;
+ this.requestElement.addChild(FILENAME_ELEMENT_NAME).setContent(filename);
+ }
+
+ public void setFilesize(long filesize) {
+ if (0 >= filesize) {
+ throw new IllegalArgumentException("filesize must not be null or empty.");
+ }
+ this.filesize = filesize;
+ this.requestElement.addChild(FILESIZE_ELEMENT_NAME).setContent(String.valueOf(filesize));
+ }
+
+ public void setMime(String mime) {
+ if (null == mime || mime.isEmpty()) {
+ mime = FileTransferHttp.DEFAULT_MIME_TYPE;
+ }
+ this.mime = mime;
+ this.requestElement.addChild(MIME_ELEMENT_NAME).setContent(mime);
+ }
+}
diff --git a/src/main/java/de/thedevstack/conversationsplus/xmpp/filetransfer/http/upload/HttpUploadRequestSlotPacketGenerator.java b/src/main/java/de/thedevstack/conversationsplus/xmpp/filetransfer/http/upload/HttpUploadRequestSlotPacketGenerator.java
index 4b0a956c..db455b7a 100644
--- a/src/main/java/de/thedevstack/conversationsplus/xmpp/filetransfer/http/upload/HttpUploadRequestSlotPacketGenerator.java
+++ b/src/main/java/de/thedevstack/conversationsplus/xmpp/filetransfer/http/upload/HttpUploadRequestSlotPacketGenerator.java
@@ -1,5 +1,7 @@
package de.thedevstack.conversationsplus.xmpp.filetransfer.http.upload;
+import de.thedevstack.conversationsplus.entities.Account;
+import de.thedevstack.conversationsplus.xmpp.filetransfer.http.FileTransferHttp;
import de.thedevstack.conversationsplus.xmpp.jid.Jid;
import de.thedevstack.conversationsplus.xmpp.stanzas.IqPacket;
@@ -24,17 +26,38 @@ public final class HttpUploadRequestSlotPacketGenerator {
* </request>
* </iq>
* </pre>
- * @param host the jid of the host to request a slot from
+ * @param account the account requesting a slot
* @param filename the filename of the file which will be transferred
* @param filesize the filesize of the file which will be transferred
* @param mime the mime type of the file which will be transferred - <code>optional</code> and therefore nullable
* @return the IqPacket
*/
- public static IqPacket generate(Jid host, String filename, long filesize, String mime) {
- SlotRequestPacket packet = new SlotRequestPacket(filename, filesize);
- packet.setTo(host);
- packet.setMime((mime == null || mime.isEmpty()) ? HttpUpload.DEFAULT_MIME_TYPE : mime);
- return packet;
+ public static IqPacket generate(Account account, Jid recipient, String filename, long filesize, String mime) {
+ String namespace = getNamespace(account);
+ Jid host = getHost(account, namespace);
+ IqPacket requestPacket;
+ switch (namespace) {
+ case HttpUpload.NAMESPACE:
+ requestPacket = new HttpUploadSlotRequestPacket(filename, filesize, mime);
+ break;
+ case FileTransferHttp.NAMESPACE:
+ default:
+ requestPacket = new FileTransferHttpUploadSlotRequestPacket(recipient.toString(), filename, filesize, mime);
+ }
+ requestPacket.setTo(host);
+ return requestPacket;
+ }
+
+ private static String getNamespace(Account account) {
+ if (null != account.getXmppConnection().findDiscoItemByFeature(FileTransferHttp.NAMESPACE)) {
+ return FileTransferHttp.NAMESPACE;
+ } else {
+ return HttpUpload.NAMESPACE;
+ }
+ }
+
+ private static Jid getHost(Account account, String namespace) {
+ return account.getXmppConnection().findDiscoItemByFeature(namespace);
}
/**
diff --git a/src/main/java/de/thedevstack/conversationsplus/xmpp/filetransfer/http/upload/SlotRequestPacket.java b/src/main/java/de/thedevstack/conversationsplus/xmpp/filetransfer/http/upload/HttpUploadSlotRequestPacket.java
index d0866508..93422d3f 100644
--- a/src/main/java/de/thedevstack/conversationsplus/xmpp/filetransfer/http/upload/SlotRequestPacket.java
+++ b/src/main/java/de/thedevstack/conversationsplus/xmpp/filetransfer/http/upload/HttpUploadSlotRequestPacket.java
@@ -6,7 +6,7 @@ import de.thedevstack.conversationsplus.xmpp.stanzas.IqPacket;
/**
*
*/
-public class SlotRequestPacket extends IqPacket {
+public class HttpUploadSlotRequestPacket extends IqPacket {
public static final String ELEMENT_NAME = "request";
public static final String FILENAME_ELEMENT_NAME = "filename";
public static final String FILESIZE_ELEMENT_NAME = "size";
@@ -16,15 +16,16 @@ public class SlotRequestPacket extends IqPacket {
private long filesize;
private String mime;
- private SlotRequestPacket() {
+ private HttpUploadSlotRequestPacket() {
super(TYPE.GET);
- this.requestElement = super.addChild(SlotRequestPacket.ELEMENT_NAME, HttpUpload.NAMESPACE);
+ this.requestElement = super.addChild(HttpUploadSlotRequestPacket.ELEMENT_NAME, HttpUpload.NAMESPACE);
}
- public SlotRequestPacket(String filename, long filesize) {
+ public HttpUploadSlotRequestPacket(String filename, long filesize, String mime) {
this();
this.setFilename(filename);
this.setFilesize(filesize);
+ this.setMime(mime);
}
public void setFilename(String filename) {
@@ -45,7 +46,7 @@ public class SlotRequestPacket extends IqPacket {
public void setMime(String mime) {
if (null == mime || mime.isEmpty()) {
- throw new IllegalArgumentException("mime type must not be null or empty.");
+ mime = HttpUpload.DEFAULT_MIME_TYPE;
}
this.mime = mime;
this.requestElement.addChild(MIME_ELEMENT_NAME).setContent(mime);
diff --git a/src/main/java/de/thedevstack/conversationsplus/xmpp/filetransfer/http/upload/SlotPacketParser.java b/src/main/java/de/thedevstack/conversationsplus/xmpp/filetransfer/http/upload/SlotPacketParser.java
index 85d11b6b..e2d629e4 100644
--- a/src/main/java/de/thedevstack/conversationsplus/xmpp/filetransfer/http/upload/SlotPacketParser.java
+++ b/src/main/java/de/thedevstack/conversationsplus/xmpp/filetransfer/http/upload/SlotPacketParser.java
@@ -2,8 +2,10 @@ package de.thedevstack.conversationsplus.xmpp.filetransfer.http.upload;
import de.thedevstack.conversationsplus.xml.Element;
import de.thedevstack.conversationsplus.xmpp.IqPacketParser;
+import de.thedevstack.conversationsplus.xmpp.exceptions.MissingRequiredElementException;
import de.thedevstack.conversationsplus.xmpp.exceptions.UnexpectedIqPacketTypeException;
import de.thedevstack.conversationsplus.xmpp.exceptions.XmppException;
+import de.thedevstack.conversationsplus.xmpp.filetransfer.http.FileTransferHttp;
import de.thedevstack.conversationsplus.xmpp.stanzas.IqPacket;
import de.thedevstack.conversationsplus.xmpp.utils.ErrorIqPacketExceptionHelper;
@@ -11,10 +13,18 @@ import de.thedevstack.conversationsplus.xmpp.utils.ErrorIqPacketExceptionHelper;
*
*/
public final class SlotPacketParser extends IqPacketParser {
+ private static final String SLOT_ELEMENT_NAME = "slot";
+
public static HttpUploadSlot parseGetAndPutUrl(IqPacket packet) throws XmppException {
HttpUploadSlot httpUploadSlot = null;
if (packet.getType() == IqPacket.TYPE.RESULT) {
- Element slot = findRequiredChild(packet, "slot", HttpUpload.NAMESPACE);
+ Element slot = findChild(packet, SLOT_ELEMENT_NAME, FileTransferHttp.NAMESPACE);
+ if (null == slot) {
+ slot = findChild(packet, SLOT_ELEMENT_NAME, HttpUpload.NAMESPACE);
+ }
+ if (null == slot) {
+ throw new MissingRequiredElementException(SLOT_ELEMENT_NAME, "neither " + FileTransferHttp.NAMESPACE + " nor " + HttpUpload.NAMESPACE, packet);
+ }
String getUrl = findRequiredChildContent(slot, "get");
String putUrl = findRequiredChildContent(slot, "put");
diff --git a/src/main/java/de/thedevstack/conversationsplus/xmpp/jingle/JingleConnection.java b/src/main/java/de/thedevstack/conversationsplus/xmpp/jingle/JingleConnection.java
index aa85430b..ea93fdb8 100644
--- a/src/main/java/de/thedevstack/conversationsplus/xmpp/jingle/JingleConnection.java
+++ b/src/main/java/de/thedevstack/conversationsplus/xmpp/jingle/JingleConnection.java
@@ -464,6 +464,8 @@ public class JingleConnection implements Transferable {
}
});
+ } else {
+ fail();
}
}