-/* 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 java.util.Set;
import java.util.concurrent.atomic.AtomicBoolean;
-import org.apache.commons.httpclient.methods.PutMethod;
+import org.apache.commons.httpclient.HttpStatus;
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.resources.files.ExistenceCheckRemoteOperation;
import com.owncloud.android.lib.resources.files.UploadRemoteFileOperation;
import com.owncloud.android.utils.FileStorageUtils;
-
-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 boolean mWasRenamed = false;
private String mOriginalFileName = null;
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(), mFile.getEtagInConflict());
} else {
- mUploadOperation = new UploadRemoteFileOperation(mFile.getStoragePath(), mFile.getRemotePath(),
- mFile.getMimetype());
+ mUploadOperation = new UploadRemoteFileOperation(mFile.getStoragePath(),
+ mFile.getRemotePath(), mFile.getMimetype(), mFile.getEtagInConflict());
}
Iterator <OnDatatransferProgressListener> listener = mDataTransferListeners.iterator();
while (listener.hasNext()) {
mUploadOperation.addDatatransferProgressListener(listener.next());
}
+ if (mCancellationRequested.get()) {
+ throw new OperationCancelledException();
+ }
+
result = mUploadOperation.execute(client);
/// move local temporal file or original file to its corresponding
mFile.setStoragePath(expectedPath);
File fileToMove = null;
if (temporalFile != null) { // FileUploader.LOCAL_BEHAVIOUR_COPY
- // ; see where temporalFile was
- // set
+ // ; see where temporalFile was
+ // set
fileToMove = temporalFile;
} else { // FileUploader.LOCAL_BEHAVIOUR_MOVE
fileToMove = originalFile;
}
}
}
+
+ } else if (result.getHttpCode() == HttpStatus.SC_PRECONDITION_FAILED ) {
+ result = new RemoteOperationResult(ResultCode.SYNC_CONFLICT);
}
} catch (Exception e) {
- // TODO something cleaner with cancellations
- if (mCancellationRequested.get()) {
- result = new RemoteOperationResult(new OperationCancelledException());
- } else {
- result = new RemoteOperationResult(e);
- }
+ result = new RemoteOperationResult(e);
} finally {
if (temporalFile != null && !originalFile.equals(temporalFile)) {
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.setEtag(mFile.getEtag())
- newFile.setKeepInSync(mFile.keepInSync());
+ newFile.setModificationTimestampAtLastSyncForData(
+ mFile.getModificationTimestampAtLastSyncForData());
+ newFile.setEtag(mFile.getEtag());
+ newFile.setFavorite(mFile.isFavorite());
newFile.setLastSyncDateForProperties(mFile.getLastSyncDateForProperties());
newFile.setLastSyncDateForData(mFile.getLastSyncDateForData());
newFile.setStoragePath(mFile.getStoragePath());
* 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();
+ }
}
-
}