import java.io.File;
import java.io.IOException;
+import java.util.HashSet;
+import java.util.Set;
+import java.util.concurrent.atomic.AtomicBoolean;
import org.apache.commons.httpclient.HttpException;
import org.apache.commons.httpclient.methods.PutMethod;
import org.apache.http.HttpStatus;
+import com.owncloud.android.datamodel.OCFile;
import com.owncloud.android.operations.RemoteOperation;
import com.owncloud.android.operations.RemoteOperationResult;
import eu.alefzero.webdav.OnDatatransferProgressListener;
import eu.alefzero.webdav.WebdavClient;
import eu.alefzero.webdav.WebdavUtils;
+import android.accounts.Account;
import android.util.Log;
-import android.webkit.MimeTypeMap;
/**
* Remote operation performing the upload of a file to an ownCloud server
*/
public class UploadFileOperation extends RemoteOperation {
- private static final String TAG = UploadFileOperation.class.getCanonicalName();
+ private static final String TAG = UploadFileOperation.class.getSimpleName();
- private String mLocalPath = null;
+ private Account mAccount;
+ private OCFile mFile;
private String mRemotePath = null;
- private String mMimeType = null;
private boolean mIsInstant = false;
+ private boolean mRemoteFolderToBeCreated = false;
private boolean mForceOverwrite = false;
- private OnDatatransferProgressListener mDataTransferListener = null;
+ PutMethod mPutMethod = null;
+ private Set<OnDatatransferProgressListener> mDataTransferListeners = new HashSet<OnDatatransferProgressListener>();
+ private final AtomicBoolean mCancellationRequested = new AtomicBoolean(false);
+
+ public UploadFileOperation( Account account,
+ OCFile file,
+ boolean isInstant,
+ boolean forceOverwrite) {
+ if (account == null)
+ throw new IllegalArgumentException("Illegal NULL account in UploadFileOperation creation");
+ if (file == null)
+ throw new IllegalArgumentException("Illegal NULL file in UploadFileOperation creation");
+ if (file.getStoragePath() == null || file.getStoragePath().length() <= 0 || !(new File(file.getStoragePath()).exists())) {
+ throw new IllegalArgumentException("Illegal file in UploadFileOperation; storage path invalid or file not found: " + file.getStoragePath());
+ }
+
+ mAccount = account;
+ mFile = file;
+ mRemotePath = file.getRemotePath();
+ mIsInstant = isInstant;
+ mForceOverwrite = forceOverwrite;
+ }
+
+ public Account getAccount() {
+ return mAccount;
+ }
- public String getLocalPath() {
- return mLocalPath;
+ public OCFile getFile() {
+ return mFile;
+ }
+
+ public String getStoragePath() {
+ return mFile.getStoragePath();
}
public String getRemotePath() {
+ //return mFile.getRemotePath(); // DON'T MAKE THIS ; the remotePath used can be different to mFile.getRemotePath() if mForceOverwrite is 'false'; see run(...)
return mRemotePath;
}
public String getMimeType() {
- return mMimeType;
+ return mFile.getMimetype();
}
-
public boolean isInstant() {
return mIsInstant;
}
+
+ public boolean isRemoteFolderToBeCreated() {
+ return mRemoteFolderToBeCreated;
+ }
-
+ public void setRemoteFolderToBeCreated() {
+ mRemoteFolderToBeCreated = true;
+ }
+
public boolean getForceOverwrite() {
return mForceOverwrite;
}
-
- public OnDatatransferProgressListener getDataTransferListener() {
- return mDataTransferListener ;
+
+ public Set<OnDatatransferProgressListener> getDataTransferListeners() {
+ return mDataTransferListeners;
}
-
- public UploadFileOperation( String localPath,
- String remotePath,
- String mimeType,
- boolean isInstant,
- boolean forceOverwrite,
- OnDatatransferProgressListener dataTransferProgressListener) {
- mLocalPath = localPath;
- mRemotePath = remotePath;
- mMimeType = mimeType;
- if (mMimeType == null) {
- try {
- mMimeType = MimeTypeMap.getSingleton()
- .getMimeTypeFromExtension(
- localPath.substring(localPath.lastIndexOf('.') + 1));
- } catch (IndexOutOfBoundsException e) {
- Log.e(TAG, "Trying to find out MIME type of a file without extension: " + localPath);
- }
- }
- if (mMimeType == null) {
- mMimeType = "application/octet-stream";
- }
- mIsInstant = isInstant;
- mForceOverwrite = forceOverwrite;
- mDataTransferListener = dataTransferProgressListener;
+ public void addDatatransferProgressListener (OnDatatransferProgressListener listener) {
+ mDataTransferListeners.add(listener);
}
+
@Override
protected RemoteOperationResult run(WebdavClient client) {
RemoteOperationResult result = null;
/// perform the upload
nameCheckPassed = true;
+ synchronized(mCancellationRequested) {
+ if (mCancellationRequested.get()) {
+ throw new OperationCancelledException();
+ } else {
+ mPutMethod = new PutMethod(client.getBaseUri() + WebdavUtils.encodePath(mRemotePath));
+ }
+ }
int status = uploadFile(client);
result = new RemoteOperationResult(isSuccess(status), status);
- Log.i(TAG, "Upload of " + mLocalPath + " to " + mRemotePath + ": " + result.getLogMessage());
-
+ Log.i(TAG, "Upload of " + mFile.getStoragePath() + " to " + mRemotePath + ": " + result.getLogMessage());
+
} catch (Exception e) {
- result = new RemoteOperationResult(e);
- Log.e(TAG, "Upload of " + mLocalPath + " to " + mRemotePath + ": " + result.getLogMessage() + (nameCheckPassed?"":" (while checking file existence in server)"), e);
-
+ // TODO something cleaner
+ if (mCancellationRequested.get()) {
+ result = new RemoteOperationResult(new OperationCancelledException());
+ } else {
+ result = new RemoteOperationResult(e);
+ }
+ Log.e(TAG, "Upload of " + mFile.getStoragePath() + " to " + mRemotePath + ": " + result.getLogMessage() + (nameCheckPassed?"":" (while checking file existence in server)"), result.getException());
}
return result;
}
- protected int uploadFile(WebdavClient client) throws HttpException, IOException {
+ protected int uploadFile(WebdavClient client) throws HttpException, IOException, OperationCancelledException {
int status = -1;
- PutMethod put = new PutMethod(client.getBaseUri() + WebdavUtils.encodePath(mRemotePath));
-
try {
- File f = new File(mLocalPath);
- FileRequestEntity entity = new FileRequestEntity(f, mMimeType);
- entity.setOnDatatransferProgressListener(mDataTransferListener);
- put.setRequestEntity(entity);
- status = client.executeMethod(put);
- client.exhaustResponse(put.getResponseBodyAsStream());
+ File f = new File(mFile.getStoragePath());
+ FileRequestEntity entity = new FileRequestEntity(f, getMimeType());
+ entity.addOnDatatransferProgressListeners(mDataTransferListeners);
+ mPutMethod.setRequestEntity(entity);
+ status = client.executeMethod(mPutMethod);
+ client.exhaustResponse(mPutMethod.getResponseBodyAsStream());
} finally {
- put.releaseConnection(); // let the connection available for other methods
+ mPutMethod.releaseConnection(); // let the connection available for other methods
}
return status;
}
}
}
+
+ public void cancel() {
+ synchronized(mCancellationRequested) {
+ mCancellationRequested.set(true);
+ if (mPutMethod != null)
+ mPutMethod.abort();
+ }
+ }
+
+
}