-/* ownCloud Android client application
- * Copyright (C) 2012-2013 ownCloud Inc.
+/**
+ * ownCloud Android client application
+ *
+ * @author David A. Velasco
+ * Copyright (C) 2015 ownCloud Inc.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2,
import org.apache.commons.httpclient.methods.PutMethod;
import org.apache.commons.httpclient.methods.RequestEntity;
+import android.accounts.Account;
+import android.content.Context;
+import android.net.Uri;
+
+import com.owncloud.android.MainApp;
import com.owncloud.android.datamodel.OCFile;
import com.owncloud.android.files.services.FileUploader;
-import com.owncloud.android.lib.common.network.ProgressiveDataTransferer;
-import com.owncloud.android.lib.common.network.OnDatatransferProgressListener;
import com.owncloud.android.lib.common.OwnCloudClient;
+import com.owncloud.android.lib.common.network.OnDatatransferProgressListener;
+import com.owncloud.android.lib.common.network.ProgressiveDataTransferer;
import com.owncloud.android.lib.common.operations.OperationCancelledException;
import com.owncloud.android.lib.common.operations.RemoteOperation;
import com.owncloud.android.lib.common.operations.RemoteOperationResult;
import com.owncloud.android.lib.common.operations.RemoteOperationResult.ResultCode;
+import com.owncloud.android.lib.common.utils.Log_OC;
import com.owncloud.android.lib.resources.files.ChunkedUploadRemoteFileOperation;
import com.owncloud.android.lib.resources.files.ExistenceCheckRemoteOperation;
import com.owncloud.android.lib.resources.files.UploadRemoteFileOperation;
import com.owncloud.android.utils.FileStorageUtils;
-import com.owncloud.android.utils.Log_OC;
-
-import android.accounts.Account;
-import android.content.Context;
+import com.owncloud.android.utils.UriUtils;
/**
* Remote operation performing the upload of a file to an ownCloud server
- *
- * @author David A. Velasco
*/
public class UploadFileOperation extends RemoteOperation {
private String mOriginalStoragePath = null;
PutMethod mPutMethod = null;
private Set<OnDatatransferProgressListener> mDataTransferListeners = new HashSet<OnDatatransferProgressListener>();
- private final AtomicBoolean mCancellationRequested = new AtomicBoolean(false);
+ private AtomicBoolean mCancellationRequested = new AtomicBoolean(false);
private Context mContext;
private UploadRemoteFileOperation mUploadOperation;
int localBehaviour,
Context context) {
if (account == null)
- throw new IllegalArgumentException("Illegal NULL account in UploadFileOperation creation");
+ 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())) {
+ if (file.getStoragePath() == null || file.getStoragePath().length() <= 0) {
throw new IllegalArgumentException(
- "Illegal file in UploadFileOperation; storage path invalid or file not found: "
+ "Illegal file in UploadFileOperation; storage path invalid: "
+ file.getStoragePath());
}
// check location of local file; if not the expected, copy to a
// temporal file before upload (if COPY is the expected behaviour)
- if (!mOriginalStoragePath.equals(expectedPath) && mLocalBehaviour == FileUploader.LOCAL_BEHAVIOUR_COPY) {
+ if (!mOriginalStoragePath.equals(expectedPath) &&
+ mLocalBehaviour == FileUploader.LOCAL_BEHAVIOUR_COPY) {
if (FileStorageUtils.getUsableSpace(mAccount.name) < originalFile.length()) {
result = new RemoteOperationResult(ResultCode.LOCAL_STORAGE_FULL);
// copied
} else {
- String temporalPath = FileStorageUtils.getTemporalPath(mAccount.name) + mFile.getRemotePath();
+
+ String temporalPath = FileStorageUtils.getTemporalPath(mAccount.name) +
+ mFile.getRemotePath();
mFile.setStoragePath(temporalPath);
temporalFile = new File(temporalPath);
- if (!mOriginalStoragePath.equals(temporalPath)) { // preventing
- // weird
- // but
- // possible
- // situation
- InputStream in = null;
- OutputStream out = null;
- try {
- File temporalParent = temporalFile.getParentFile();
- temporalParent.mkdirs();
- if (!temporalParent.isDirectory()) {
- throw new IOException("Unexpected error: parent directory could not be created");
- }
- temporalFile.createNewFile();
- if (!temporalFile.isFile()) {
- throw new IOException("Unexpected error: target file could not be created");
- }
- in = new FileInputStream(originalFile);
+
+ File temporalParent = temporalFile.getParentFile();
+ temporalParent.mkdirs();
+ if (!temporalParent.isDirectory()) {
+ throw new IOException("Unexpected error: parent directory could not be created");
+ }
+ temporalFile.createNewFile();
+ if (!temporalFile.isFile()) {
+ throw new IOException("Unexpected error: target file could not be created");
+ }
+
+ InputStream in = null;
+ OutputStream out = null;
+
+ try {
+
+ // In case document provider schema as 'content://'
+ if (mOriginalStoragePath.startsWith(UriUtils.URI_CONTENT_SCHEME)) {
+
+ Uri uri = Uri.parse(mOriginalStoragePath);
+
+ in = MainApp.getAppContext().getContentResolver().openInputStream(uri);
out = new FileOutputStream(temporalFile);
- byte[] buf = new byte[1024];
- int len;
- while ((len = in.read(buf)) > 0) {
- out.write(buf, 0, len);
- }
- } catch (Exception e) {
- result = new RemoteOperationResult(ResultCode.LOCAL_STORAGE_NOT_COPIED);
- return result;
-
- } finally {
- try {
- if (in != null)
- in.close();
- } catch (Exception e) {
- Log_OC.d(TAG, "Weird exception while closing input stream for " + mOriginalStoragePath + " (ignoring)", e);
+ int nRead;
+ byte[] data = new byte[16384];
+
+ while (!mCancellationRequested.get() &&
+ (nRead = in.read(data, 0, data.length)) != -1) {
+ out.write(data, 0, nRead);
}
- try {
- if (out != null)
- out.close();
- } catch (Exception e) {
- Log_OC.d(TAG, "Weird exception while closing output stream for " + expectedPath + " (ignoring)", e);
+ out.flush();
+
+ } else {
+ if (!mOriginalStoragePath.equals(temporalPath)) { // preventing
+ // weird
+ // but
+ // possible
+ // situation
+
+ in = new FileInputStream(originalFile);
+ out = new FileOutputStream(temporalFile);
+ byte[] buf = new byte[1024];
+ int len;
+ while (!mCancellationRequested.get() && (len = in.read(buf)) > 0) {
+ out.write(buf, 0, len);
+ }
}
}
+
+ if (mCancellationRequested.get()) {
+ result = new RemoteOperationResult(new OperationCancelledException());
+ }
+
+
+ } catch (Exception e) {
+ result = new RemoteOperationResult(ResultCode.LOCAL_STORAGE_NOT_COPIED);
+ return result;
+
+ } finally {
+ try {
+ if (in != null)
+ in.close();
+ } catch (Exception e) {
+ Log_OC.d(TAG, "Weird exception while closing input stream for " +
+ mOriginalStoragePath + " (ignoring)", e);
+ }
+ try {
+ if (out != null)
+ out.close();
+ } catch (Exception e) {
+ Log_OC.d(TAG, "Weird exception while closing output stream for " +
+ expectedPath + " (ignoring)", e);
+ }
}
}
}
- localCopyPassed = true;
+ localCopyPassed = (result == null);
/// perform the upload
- if ( mChunked && (new File(mFile.getStoragePath())).length() > ChunkedUploadRemoteFileOperation.CHUNK_SIZE ) {
- mUploadOperation = new ChunkedUploadRemoteFileOperation(mFile.getStoragePath(), mFile.getRemotePath(),
- mFile.getMimetype());
+ if ( mChunked &&
+ (new File(mFile.getStoragePath())).length() >
+ ChunkedUploadRemoteFileOperation.CHUNK_SIZE ) {
+ mUploadOperation = new ChunkedUploadRemoteFileOperation(mFile.getStoragePath(),
+ mFile.getRemotePath(), mFile.getMimetype());
} else {
- mUploadOperation = new UploadRemoteFileOperation(mFile.getStoragePath(), mFile.getRemotePath(),
- mFile.getMimetype());
+ mUploadOperation = new UploadRemoteFileOperation(mFile.getStoragePath(),
+ mFile.getRemotePath(), mFile.getMimetype());
}
Iterator <OnDatatransferProgressListener> listener = mDataTransferListeners.iterator();
while (listener.hasNext()) {
mUploadOperation.addDatatransferProgressListener(listener.next());
}
- result = mUploadOperation.execute(client);
-
- /// move local temporal file or original file to its corresponding
- // location in the ownCloud local folder
- if (result.isSuccess()) {
- if (mLocalBehaviour == FileUploader.LOCAL_BEHAVIOUR_FORGET) {
- mFile.setStoragePath(null);
-
- } else {
- mFile.setStoragePath(expectedPath);
- File fileToMove = null;
- if (temporalFile != null) { // FileUploader.LOCAL_BEHAVIOUR_COPY
- // ; see where temporalFile was
- // set
- fileToMove = temporalFile;
- } else { // FileUploader.LOCAL_BEHAVIOUR_MOVE
- fileToMove = originalFile;
- }
- if (!expectedFile.equals(fileToMove)) {
- File expectedFolder = expectedFile.getParentFile();
- expectedFolder.mkdirs();
- if (!expectedFolder.isDirectory() || !fileToMove.renameTo(expectedFile)) {
- mFile.setStoragePath(null); // forget the local file
- // by now, treat this as a success; the file was
- // uploaded; the user won't like that the local file
- // is not linked, but this should be a very rare
- // fail;
- // the best option could be show a warning message
- // (but not a fail)
- // result = new
- // RemoteOperationResult(ResultCode.LOCAL_STORAGE_NOT_MOVED);
- // return result;
+ if (!mCancellationRequested.get()) {
+ result = mUploadOperation.execute(client);
+
+ /// move local temporal file or original file to its corresponding
+ // location in the ownCloud local folder
+ if (result.isSuccess()) {
+ if (mLocalBehaviour == FileUploader.LOCAL_BEHAVIOUR_FORGET) {
+ mFile.setStoragePath(null);
+
+ } else {
+ mFile.setStoragePath(expectedPath);
+ File fileToMove = null;
+ if (temporalFile != null) { // FileUploader.LOCAL_BEHAVIOUR_COPY
+ // ; see where temporalFile was
+ // set
+ fileToMove = temporalFile;
+ } else { // FileUploader.LOCAL_BEHAVIOUR_MOVE
+ fileToMove = originalFile;
+ }
+ if (!expectedFile.equals(fileToMove)) {
+ File expectedFolder = expectedFile.getParentFile();
+ expectedFolder.mkdirs();
+ if (!expectedFolder.isDirectory() || !fileToMove.renameTo(expectedFile)) {
+ mFile.setStoragePath(null); // forget the local file
+ // by now, treat this as a success; the file was
+ // uploaded; the user won't like that the local file
+ // is not linked, but this should be a very rare
+ // fail;
+ // the best option could be show a warning message
+ // (but not a fail)
+ // result = new
+ // RemoteOperationResult(ResultCode.LOCAL_STORAGE_NOT_MOVED);
+ // return result;
+ }
}
}
}
temporalFile.delete();
}
if (result.isSuccess()) {
- Log_OC.i(TAG, "Upload of " + mOriginalStoragePath + " to " + mRemotePath + ": " + result.getLogMessage());
+ Log_OC.i(TAG, "Upload of " + mOriginalStoragePath + " to " + mRemotePath + ": " +
+ result.getLogMessage());
} else {
if (result.getException() != null) {
String complement = "";
if (!nameCheckPassed) {
complement = " (while checking file existence in server)";
} else if (!localCopyPassed) {
- complement = " (while copying local file to " + FileStorageUtils.getSavePath(mAccount.name)
+ complement = " (while copying local file to " +
+ FileStorageUtils.getSavePath(mAccount.name)
+ ")";
}
- Log_OC.e(TAG, "Upload of " + mOriginalStoragePath + " to " + mRemotePath + ": " + result.getLogMessage() + complement, result.getException());
+ Log_OC.e(TAG, "Upload of " + mOriginalStoragePath + " to " + mRemotePath +
+ ": " + result.getLogMessage() + complement, result.getException());
} else {
- Log_OC.e(TAG, "Upload of " + mOriginalStoragePath + " to " + mRemotePath + ": " + result.getLogMessage());
+ Log_OC.e(TAG, "Upload of " + mOriginalStoragePath + " to " + mRemotePath +
+ ": " + result.getLogMessage());
}
}
}
newFile.setFileLength(mFile.getFileLength());
newFile.setMimetype(mFile.getMimetype());
newFile.setModificationTimestamp(mFile.getModificationTimestamp());
- newFile.setModificationTimestampAtLastSyncForData(mFile.getModificationTimestampAtLastSyncForData());
+ newFile.setModificationTimestampAtLastSyncForData(
+ mFile.getModificationTimestampAtLastSyncForData());
// newFile.setEtag(mFile.getEtag())
newFile.setKeepInSync(mFile.keepInSync());
newFile.setLastSyncDateForProperties(mFile.getLastSyncDateForProperties());
* Checks if remotePath does not exist in the server and returns it, or adds
* a suffix to it in order to avoid the server file is overwritten.
*
- * @param string
+ * @param wc
+ * @param remotePath
* @return
*/
private String getAvailableRemotePath(OwnCloudClient wc, String remotePath) throws Exception {
}
private boolean existsFile(OwnCloudClient client, String remotePath){
- ExistenceCheckRemoteOperation existsOperation = new ExistenceCheckRemoteOperation(remotePath, mContext, false);
+ ExistenceCheckRemoteOperation existsOperation =
+ new ExistenceCheckRemoteOperation(remotePath, mContext, false);
RemoteOperationResult result = existsOperation.execute(client);
return result.isSuccess();
}
public void cancel() {
- mUploadOperation.cancel();
+ mCancellationRequested = new AtomicBoolean(true);
+ if (mUploadOperation != null) {
+ mUploadOperation.cancel();
+ }
}
-
}