Fixed local path NULL when making favourite a file not down ; fixed change of local...
[pub/Android/ownCloud.git] / src / com / owncloud / android / operations / UploadFileOperation.java
index 38be5f9..36f70c3 100644 (file)
@@ -20,11 +20,15 @@ package com.owncloud.android.operations;
 
 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;
 
@@ -32,8 +36,8 @@ import eu.alefzero.webdav.FileRequestEntity;
 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
@@ -42,70 +46,85 @@ import android.webkit.MimeTypeMap;
  */
 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;
@@ -118,14 +137,25 @@ public class UploadFileOperation extends RemoteOperation {
         
             /// 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;
@@ -137,20 +167,18 @@ public class UploadFileOperation extends RemoteOperation {
     }
     
     
-    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;
     }
@@ -192,4 +220,14 @@ public class UploadFileOperation extends RemoteOperation {
         }
     }
 
+
+    public void cancel() {
+        synchronized(mCancellationRequested) {
+            mCancellationRequested.set(true);
+            if (mPutMethod != null)
+                mPutMethod.abort();
+        }
+    }
+
+
 }