Эх сурвалжийг харах

OC-2332: Isolate code to the upload a file to remove local dependences

masensio 11 жил өмнө
parent
commit
dc1ea137a2

+ 0 - 43
oc_framework/src/com/owncloud/android/oc_framework/operations/remote/UpdateRemoteFileOperation.java

@@ -1,43 +0,0 @@
-/* ownCloud Android client application
- *   Copyright (C) 2012-2013 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,
- *   as published by the Free Software Foundation.
- *
- *   This program is distributed in the hope that it will be useful,
- *   but WITHOUT ANY WARRANTY; without even the implied warranty of
- *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *   GNU General Public License for more details.
- *
- *   You should have received a copy of the GNU General Public License
- *   along with this program.  If not, see <http://www.gnu.org/licenses/>.
- *
- */
-
-package com.owncloud.android.oc_framework.operations.remote;
-
-import com.owncloud.android.oc_framework.network.webdav.WebdavClient;
-import com.owncloud.android.oc_framework.operations.RemoteOperation;
-import com.owncloud.android.oc_framework.operations.RemoteOperationResult;
-
-/**
- * Remote operation performing the upload of a remote file to the ownCloud server.
- * 
- * @author David A. Velasco
- * @author masensio
- */
-
-public class UpdateRemoteFileOperation extends RemoteOperation {
-
-	public UpdateRemoteFileOperation() {
-		// TODO Auto-generated constructor stub
-	}
-
-	@Override
-	protected RemoteOperationResult run(WebdavClient client) {
-		// TODO Auto-generated method stub
-		return null;
-	}
-
-}

+ 146 - 0
oc_framework/src/com/owncloud/android/oc_framework/operations/remote/UploadRemoteFileOperation.java

@@ -0,0 +1,146 @@
+/* ownCloud Android client application
+ *   Copyright (C) 2012-2013 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,
+ *   as published by the Free Software Foundation.
+ *
+ *   This program is distributed in the hope that it will be useful,
+ *   but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *   GNU General Public License for more details.
+ *
+ *   You should have received a copy of the GNU General Public License
+ *   along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+package com.owncloud.android.oc_framework.operations.remote;
+
+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.commons.httpclient.methods.RequestEntity;
+import org.apache.http.HttpStatus;
+
+import com.owncloud.android.oc_framework.network.ProgressiveDataTransferer;
+import com.owncloud.android.oc_framework.network.webdav.FileRequestEntity;
+import com.owncloud.android.oc_framework.network.webdav.OnDatatransferProgressListener;
+import com.owncloud.android.oc_framework.network.webdav.WebdavClient;
+import com.owncloud.android.oc_framework.network.webdav.WebdavUtils;
+import com.owncloud.android.oc_framework.operations.OperationCancelledException;
+import com.owncloud.android.oc_framework.operations.RemoteOperation;
+import com.owncloud.android.oc_framework.operations.RemoteOperationResult;
+
+/**
+ * Remote operation performing the upload of a remote file to the ownCloud server.
+ * 
+ * @author David A. Velasco
+ * @author masensio
+ */
+
+public class UploadRemoteFileOperation extends RemoteOperation {
+
+
+	private String mStoragePath;
+	private String mRemotePath;
+	private String mMimeType;
+	PutMethod mPutMethod = null;
+	private final AtomicBoolean mCancellationRequested = new AtomicBoolean(false);
+	private Set<OnDatatransferProgressListener> mDataTransferListeners = new HashSet<OnDatatransferProgressListener>();
+
+	protected RequestEntity mEntity = null;
+
+	public UploadRemoteFileOperation(String storagePath, String remotePath, String mimeType) {
+		mStoragePath = storagePath;
+		mRemotePath = remotePath;
+		mMimeType = mimeType;	
+	}
+
+	@Override
+	protected RemoteOperationResult run(WebdavClient client) {
+		RemoteOperationResult result = null;
+
+		try {
+			// / perform the upload
+			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, (mPutMethod != null ? mPutMethod.getResponseHeaders() : null));
+
+		} catch (Exception e) {
+			// TODO something cleaner with cancellations
+			if (mCancellationRequested.get()) {
+				result = new RemoteOperationResult(new OperationCancelledException());
+			} else {
+				result = new RemoteOperationResult(e);
+			}
+		}
+		return result;
+	}
+
+	public boolean isSuccess(int status) {
+		return ((status == HttpStatus.SC_OK || status == HttpStatus.SC_CREATED || status == HttpStatus.SC_NO_CONTENT));
+	}
+
+	protected int uploadFile(WebdavClient client) throws HttpException, IOException, OperationCancelledException {
+		int status = -1;
+		try {
+			File f = new File(mStoragePath);
+			mEntity  = new FileRequestEntity(f, mMimeType);
+			synchronized (mDataTransferListeners) {
+				((ProgressiveDataTransferer)mEntity).addDatatransferProgressListeners(mDataTransferListeners);
+			}
+			mPutMethod.setRequestEntity(mEntity);
+			status = client.executeMethod(mPutMethod);
+			client.exhaustResponse(mPutMethod.getResponseBodyAsStream());
+
+		} finally {
+			mPutMethod.releaseConnection(); // let the connection available for other methods
+		}
+		return status;
+	}
+	
+    public Set<OnDatatransferProgressListener> getDataTransferListeners() {
+        return mDataTransferListeners;
+    }
+    
+    public void addDatatransferProgressListener (OnDatatransferProgressListener listener) {
+        synchronized (mDataTransferListeners) {
+            mDataTransferListeners.add(listener);
+        }
+        if (mEntity != null) {
+            ((ProgressiveDataTransferer)mEntity).addDatatransferProgressListener(listener);
+        }
+    }
+    
+    public void removeDatatransferProgressListener(OnDatatransferProgressListener listener) {
+        synchronized (mDataTransferListeners) {
+            mDataTransferListeners.remove(listener);
+        }
+        if (mEntity != null) {
+            ((ProgressiveDataTransferer)mEntity).removeDatatransferProgressListener(listener);
+        }
+    }
+    
+    public void cancel() {
+        synchronized (mCancellationRequested) {
+            mCancellationRequested.set(true);
+            if (mPutMethod != null)
+                mPutMethod.abort();
+        }
+    }
+
+}

+ 2 - 2
src/com/owncloud/android/files/services/FileUploader.java

@@ -267,10 +267,10 @@ public class FileUploader extends Service implements OnDatatransferProgressListe
                 uploadKey = buildRemoteName(account, files[i].getRemotePath());
                 if (chunked) {
                     newUpload = new ChunkedUploadFileOperation(account, files[i], isInstant, forceOverwrite,
-                            localAction, getApplicationContext());
+                            localAction, getApplicationContext(), this);
                 } else {
                     newUpload = new UploadFileOperation(account, files[i], isInstant, forceOverwrite, localAction, 
-                            getApplicationContext());
+                            getApplicationContext(), this);
                 }
                 if (isInstant) {
                     newUpload.setRemoteFolderToBeCreated();

+ 4 - 2
src/com/owncloud/android/operations/ChunkedUploadFileOperation.java

@@ -30,6 +30,7 @@ import org.apache.commons.httpclient.methods.PutMethod;
 import com.owncloud.android.datamodel.OCFile;
 import com.owncloud.android.oc_framework.network.ProgressiveDataTransferer;
 import com.owncloud.android.oc_framework.network.webdav.ChunkFromFileChannelRequestEntity;
+import com.owncloud.android.oc_framework.network.webdav.OnDatatransferProgressListener;
 import com.owncloud.android.oc_framework.network.webdav.WebdavClient;
 import com.owncloud.android.oc_framework.network.webdav.WebdavUtils;
 import com.owncloud.android.utils.Log_OC;
@@ -49,9 +50,10 @@ public class ChunkedUploadFileOperation extends UploadFileOperation {
                                         OCFile file,
                                         boolean isInstant, 
                                         boolean forceOverwrite,
-                                        int localBehaviour, Context context) {
+                                        int localBehaviour, Context context, 
+                                        OnDatatransferProgressListener listener) {
         
-        super(account, file, isInstant, forceOverwrite, localBehaviour, context);
+        super(account, file, isInstant, forceOverwrite, localBehaviour, context, listener);
     }
 
     @Override

+ 14 - 20
src/com/owncloud/android/operations/UploadFileOperation.java

@@ -38,12 +38,12 @@ import com.owncloud.android.oc_framework.network.ProgressiveDataTransferer;
 import com.owncloud.android.oc_framework.network.webdav.FileRequestEntity;
 import com.owncloud.android.oc_framework.network.webdav.OnDatatransferProgressListener;
 import com.owncloud.android.oc_framework.network.webdav.WebdavClient;
-import com.owncloud.android.oc_framework.network.webdav.WebdavUtils;
 import com.owncloud.android.oc_framework.operations.OperationCancelledException;
 import com.owncloud.android.oc_framework.operations.RemoteOperation;
 import com.owncloud.android.oc_framework.operations.RemoteOperationResult;
 import com.owncloud.android.oc_framework.operations.RemoteOperationResult.ResultCode;
 import com.owncloud.android.oc_framework.operations.remote.ExistenceCheckRemoteOperation;
+import com.owncloud.android.oc_framework.operations.remote.UploadRemoteFileOperation;
 import com.owncloud.android.utils.FileStorageUtils;
 import com.owncloud.android.utils.Log_OC;
 
@@ -72,9 +72,12 @@ public class UploadFileOperation extends RemoteOperation {
     private String mOriginalFileName = null;
     private String mOriginalStoragePath = null;
     PutMethod mPutMethod = null;
+    private OnDatatransferProgressListener mDataTransferListener;
     private Set<OnDatatransferProgressListener> mDataTransferListeners = new HashSet<OnDatatransferProgressListener>();
     private final AtomicBoolean mCancellationRequested = new AtomicBoolean(false);
     private Context mContext;
+    
+    private UploadRemoteFileOperation mUploadOperation;
 
     protected RequestEntity mEntity = null;
 
@@ -84,7 +87,8 @@ public class UploadFileOperation extends RemoteOperation {
                                 boolean isInstant, 
                                 boolean forceOverwrite,
                                 int localBehaviour, 
-                                Context context) {
+                                Context context,
+                                OnDatatransferProgressListener listener) {
         if (account == null)
             throw new IllegalArgumentException("Illegal NULL account in UploadFileOperation creation");
         if (file == null)
@@ -105,6 +109,7 @@ public class UploadFileOperation extends RemoteOperation {
         mOriginalStoragePath = mFile.getStoragePath();
         mOriginalFileName = mFile.getFileName();
         mContext = context;
+        mDataTransferListener = listener;
     }
 
     public Account getAccount() {
@@ -265,19 +270,14 @@ public class UploadFileOperation extends RemoteOperation {
             }
             localCopyPassed = true;
 
-            // / perform the upload
-            synchronized (mCancellationRequested) {
-                if (mCancellationRequested.get()) {
-                    throw new OperationCancelledException();
-                } else {
-                    mPutMethod = new PutMethod(client.getBaseUri() + WebdavUtils.encodePath(mFile.getRemotePath()));
-                }
-            }
-            int status = uploadFile(client);
+            /// perform the upload
+            mUploadOperation = new UploadRemoteFileOperation(mFile.getStoragePath(), mFile.getRemotePath(), 
+                    mFile.getMimetype());
+            result = mUploadOperation.execute(client);
 
-            // / move local temporal file or original file to its corresponding
+            /// move local temporal file or original file to its corresponding
             // location in the ownCloud local folder
-            if (isSuccess(status)) {
+            if (result.isSuccess()) {
                 if (mLocalBehaviour == FileUploader.LOCAL_BEHAVIOUR_FORGET) {
                     mFile.setStoragePath(null);
 
@@ -310,8 +310,6 @@ public class UploadFileOperation extends RemoteOperation {
                 }
             }
 
-            result = new RemoteOperationResult(isSuccess(status), status, (mPutMethod != null ? mPutMethod.getResponseHeaders() : null));
-
         } catch (Exception e) {
             // TODO something cleaner with cancellations
             if (mCancellationRequested.get()) {
@@ -432,11 +430,7 @@ public class UploadFileOperation extends RemoteOperation {
     }
     
     public void cancel() {
-        synchronized (mCancellationRequested) {
-            mCancellationRequested.set(true);
-            if (mPutMethod != null)
-                mPutMethod.abort();
-        }
+        mUploadOperation.cancel();
     }
 
 }