Implements FS#245: Implement FiletransferHttp (upload and delete), some minor bug fixes including to fail a JingleTransfer in case criterias are not met
This commit is contained in:
parent
2d41916750
commit
11e2b1accd
30 changed files with 278 additions and 207 deletions
|
@ -73,7 +73,7 @@ ext {
|
|||
|
||||
android {
|
||||
compileSdkVersion 23
|
||||
buildToolsVersion "23.0.2"
|
||||
buildToolsVersion '23.0.2'
|
||||
|
||||
defaultConfig {
|
||||
minSdkVersion 14
|
||||
|
|
4
gradle/wrapper/gradle-wrapper.properties
vendored
4
gradle/wrapper/gradle-wrapper.properties
vendored
|
@ -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
|
||||
|
|
BIN
libs/3rdParty/picasso-2.5.2.jar
vendored
Normal file
BIN
libs/3rdParty/picasso-2.5.2.jar
vendored
Normal file
Binary file not shown.
|
@ -11,7 +11,7 @@ apply plugin: 'android-library'
|
|||
|
||||
android {
|
||||
compileSdkVersion 19
|
||||
buildToolsVersion "19.1"
|
||||
buildToolsVersion '19.1'
|
||||
defaultConfig {
|
||||
minSdkVersion 7
|
||||
targetSdkVersion 19
|
||||
|
|
|
@ -2,7 +2,7 @@ apply plugin: 'com.android.library'
|
|||
|
||||
android {
|
||||
compileSdkVersion 21
|
||||
buildToolsVersion "21.1.2"
|
||||
buildToolsVersion '21.1.2'
|
||||
|
||||
defaultConfig {
|
||||
minSdkVersion 7
|
||||
|
|
|
@ -2,7 +2,7 @@ apply plugin: 'com.android.library'
|
|||
|
||||
android {
|
||||
compileSdkVersion 21
|
||||
buildToolsVersion "21.1.2"
|
||||
buildToolsVersion '21.1.2'
|
||||
|
||||
defaultConfig {
|
||||
minSdkVersion 8
|
||||
|
|
|
@ -2,7 +2,7 @@ apply plugin: 'com.android.library'
|
|||
|
||||
android {
|
||||
compileSdkVersion 22
|
||||
buildToolsVersion "22.0.1"
|
||||
buildToolsVersion '22.0.1'
|
||||
|
||||
defaultConfig {
|
||||
minSdkVersion 14
|
||||
|
|
|
@ -16,5 +16,5 @@ public enum FileStatus {
|
|||
DELETING,
|
||||
NOT_FOUND,
|
||||
DOWNLOADING,
|
||||
CHECKING_FILE_SIZE;
|
||||
CHECKING_FILE_SIZE, UPLOAD_FAILED;
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
path += "." + extension;
|
||||
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 {
|
||||
String path = getFilePath(message, "jpg");
|
||||
message.getFileParams().setPath(path);
|
||||
message.setRelativeFilePath(path); // TODO: Remove
|
||||
if (null == message.getFileParams() || null == message.getFileParams().getPath()) {
|
||||
String path = getFilePath(message, "jpg");
|
||||
message.setRelativeFilePath(path); // TODO: Remove
|
||||
}
|
||||
|
||||
DownloadableFile file = getFile(message);
|
||||
file.getParentFile().mkdirs();
|
||||
OutputStream os = null;
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -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());
|
||||
XmppSendUtil.sendIqPacket(account, request, new HttpUploadSlotRequestReceived(entity));
|
||||
MessageUtil.markMessage(message, Message.STATUS_UNSEND);
|
||||
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;
|
||||
}
|
||||
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()));
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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()) {
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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";
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
}
|
|
@ -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;
|
||||
}
|
||||
}
|
|
@ -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;
|
||||
}
|
||||
}
|
|
@ -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
|
||||
}
|
||||
}
|
|
@ -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);
|
||||
}
|
||||
}
|
|
@ -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);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -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);
|
|
@ -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");
|
||||
|
|
|
@ -464,6 +464,8 @@ public class JingleConnection implements Transferable {
|
|||
}
|
||||
});
|
||||
|
||||
} else {
|
||||
fail();
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Add table
Reference in a new issue