Fixed update of shares database - grant that shares are removed after removing all...
[pub/Android/ownCloud.git] / src / com / owncloud / android / operations / SynchronizeFolderOperation.java
index 2fc9d28..97c7a08 100644 (file)
@@ -30,24 +30,21 @@ import java.util.Map;
 import java.util.Vector;
 
 import org.apache.http.HttpStatus;
-import org.apache.jackrabbit.webdav.DavConstants;
-import org.apache.jackrabbit.webdav.client.methods.PropFindMethod;
-
 import android.accounts.Account;
 import android.content.Context;
 import android.content.Intent;
+import android.support.v4.content.LocalBroadcastManager;
 
 import com.owncloud.android.datamodel.FileDataStorageManager;
 import com.owncloud.android.datamodel.OCFile;
-import com.owncloud.android.oc_framework.network.webdav.WebdavClient;
-import com.owncloud.android.oc_framework.network.webdav.WebdavEntry;
-import com.owncloud.android.oc_framework.network.webdav.WebdavUtils;
-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.ReadRemoteFolderOperation;
-import com.owncloud.android.oc_framework.operations.RemoteFile;
-import com.owncloud.android.syncadapter.FileSyncService;
+import com.owncloud.android.lib.network.OwnCloudClient;
+import com.owncloud.android.lib.operations.common.RemoteOperation;
+import com.owncloud.android.lib.operations.common.RemoteOperationResult;
+import com.owncloud.android.lib.operations.common.RemoteOperationResult.ResultCode;
+import com.owncloud.android.lib.operations.remote.ReadRemoteFileOperation;
+import com.owncloud.android.lib.operations.remote.ReadRemoteFolderOperation;
+import com.owncloud.android.lib.operations.common.RemoteFile;
+import com.owncloud.android.syncadapter.FileSyncAdapter;
 import com.owncloud.android.utils.FileStorageUtils;
 import com.owncloud.android.utils.Log_OC;
 
@@ -68,6 +65,7 @@ public class SynchronizeFolderOperation extends RemoteOperation {
 
     private static final String TAG = SynchronizeFolderOperation.class.getSimpleName();
 
+    public static final String EVENT_SINGLE_FOLDER_SYNCED = SynchronizeFolderOperation.class.getName() + ".EVENT_SINGLE_FOLDER_SYNCED";
     
     /** Time stamp for the synchronization process in progress */
     private long mCurrentSyncTime;
@@ -159,7 +157,7 @@ public class SynchronizeFolderOperation extends RemoteOperation {
      * {@inheritDoc}
      */
     @Override
-    protected RemoteOperationResult run(WebdavClient client) {
+    protected RemoteOperationResult run(OwnCloudClient client) {
         RemoteOperationResult result = null;
         mFailsInFavouritesFound = 0;
         mConflictsFound = 0;
@@ -176,7 +174,7 @@ public class SynchronizeFolderOperation extends RemoteOperation {
         }
         
         if (!mSyncFullAccount) {            
-            sendStickyBroadcast(false, mLocalFolder.getRemotePath(), result);
+            sendLocalBroadcast(mLocalFolder.getRemotePath(), result);
         }
 
         return result;
@@ -184,52 +182,31 @@ public class SynchronizeFolderOperation extends RemoteOperation {
     }
 
 
-    private RemoteOperationResult checkForChanges(WebdavClient client) {
+    private RemoteOperationResult checkForChanges(OwnCloudClient client) {
         mRemoteFolderChanged = false;
         RemoteOperationResult result = null;
         String remotePath = null;
-        PropFindMethod query = null;
-        
-        try {
+
             remotePath = mLocalFolder.getRemotePath();
             Log_OC.d(TAG, "Checking changes in " + mAccount.name + remotePath);
 
             // remote request 
-            query = new PropFindMethod(client.getBaseUri() + WebdavUtils.encodePath(remotePath),
-                    DavConstants.PROPFIND_ALL_PROP,
-                    DavConstants.DEPTH_0);
-            int status = client.executeMethod(query);
-
-            // check and process response
-            if (isMultiStatus(status)) {
-                // parse data from remote folder 
-                WebdavEntry we = new WebdavEntry(query.getResponseBodyAsMultiStatus().getResponses()[0], client.getBaseUri().getPath());
-                OCFile remoteFolder = fillOCFile(we);
-                
-                // check if remote and local folder are different
-                mRemoteFolderChanged = !(remoteFolder.getEtag().equalsIgnoreCase(mLocalFolder.getEtag()));
-                
-                result = new RemoteOperationResult(ResultCode.OK);
+            ReadRemoteFileOperation operation = new ReadRemoteFileOperation(remotePath);
+            result = operation.execute(client);
+            if (result.isSuccess()){
+                OCFile remoteFolder = FileStorageUtils.fillOCFile((RemoteFile) result.getData().get(0));
                 
+             // check if remote and local folder are different
+              mRemoteFolderChanged = !(remoteFolder.getEtag().equalsIgnoreCase(mLocalFolder.getEtag()));
+              
+              result = new RemoteOperationResult(ResultCode.OK);
+
+              Log_OC.i(TAG, "Checked " + mAccount.name + remotePath + " : " + (mRemoteFolderChanged ? "changed" : "not changed"));
             } else {
                 // check failed
-                client.exhaustResponse(query.getResponseBodyAsStream());
-                if (status == HttpStatus.SC_NOT_FOUND) {
+                if (result.getCode() == ResultCode.FILE_NOT_FOUND) {
                     removeLocalFolder();
                 }
-                result = new RemoteOperationResult(false, status, query.getResponseHeaders());
-            }
-
-        } catch (Exception e) {
-            result = new RemoteOperationResult(e);
-            
-
-        } finally {
-            if (query != null)
-                query.releaseConnection();  // let the connection available for other methods
-            if (result.isSuccess()) {
-                Log_OC.i(TAG, "Checked " + mAccount.name + remotePath + " : " + (mRemoteFolderChanged ? "changed" : "not changed"));
-            } else {
                 if (result.isException()) {
                     Log_OC.e(TAG, "Checked " + mAccount.name + remotePath  + " : " + result.getLogMessage(), result.getException());
                 } else {
@@ -237,21 +214,18 @@ public class SynchronizeFolderOperation extends RemoteOperation {
                 }
             }
             
-        }
         return result;
     }
 
 
-    private RemoteOperationResult fetchAndSyncRemoteFolder(WebdavClient client) {
+    private RemoteOperationResult fetchAndSyncRemoteFolder(OwnCloudClient client) {
         String remotePath = mLocalFolder.getRemotePath();
         ReadRemoteFolderOperation operation = new ReadRemoteFolderOperation(remotePath);
         RemoteOperationResult result = operation.execute(client);
         Log_OC.d(TAG, "Synchronizing " + mAccount.name + remotePath);
         
         if (result.isSuccess()) {
-            RemoteFile folder = result.getFile();
-            ArrayList<RemoteFile> files = result.getData();
-            synchronizeData(folder, files, client);
+            synchronizeData(result.getData(), client);
             if (mConflictsFound > 0  || mFailsInFavouritesFound > 0) { 
                 result = new RemoteOperationResult(ResultCode.SYNC_CONFLICT);   // should be different result, but will do the job
             }
@@ -278,26 +252,24 @@ public class SynchronizeFolderOperation extends RemoteOperation {
      *  
      *  Grants that mChildren is updated with fresh data after execution.
      *  
-     *  @param folder           Remote Folder to synchronize
-     *  
-     *  @param files            Remote Files in Folder 
+     *  @param folderAndFiles   Remote folder and children files in Folder 
      *  
      *  @param client           Client instance to the remote server where the data were 
      *                          retrieved.  
      *  @return                 'True' when any change was made in the local data, 'false' otherwise.
      */
-    private void synchronizeData(RemoteFile folder, ArrayList<RemoteFile> files, WebdavClient client) {
+    private void synchronizeData(ArrayList<Object> folderAndFiles, OwnCloudClient client) {
         // get 'fresh data' from the database
         mLocalFolder = mStorageManager.getFileByPath(mLocalFolder.getRemotePath());
         
         // parse data from remote folder 
-        OCFile remoteFolder = fillOCFile(folder);
+        OCFile remoteFolder = fillOCFile((RemoteFile)folderAndFiles.get(0));
         remoteFolder.setParentId(mLocalFolder.getParentId());
         remoteFolder.setFileId(mLocalFolder.getFileId());
         
         Log_OC.d(TAG, "Remote folder " + mLocalFolder.getRemotePath() + " changed - starting update of local data ");
         
-        List<OCFile> updatedFiles = new Vector<OCFile>(files.size());
+        List<OCFile> updatedFiles = new Vector<OCFile>(folderAndFiles.size() - 1);
         List<SynchronizeFileOperation> filesToSyncContents = new Vector<SynchronizeFileOperation>();
 
         // get current data about local contents of the folder to synchronize
@@ -309,9 +281,9 @@ public class SynchronizeFolderOperation extends RemoteOperation {
         
         // loop to update every child
         OCFile remoteFile = null, localFile = null;
-        for (RemoteFile file: files) { 
+        for (int i=1; i<folderAndFiles.size(); i++) {
             /// new OCFile instance with the data from the server
-            remoteFile = fillOCFile(file);
+            remoteFile = fillOCFile((RemoteFile)folderAndFiles.get(i));
             remoteFile.setParentId(mLocalFolder.getFileId());
 
             /// retrieve local data for the read file 
@@ -378,7 +350,7 @@ public class SynchronizeFolderOperation extends RemoteOperation {
      * @param filesToSyncContents       Synchronization operations to execute.
      * @param client                    Interface to the remote ownCloud server.
      */
-    private void startContentSynchronizations(List<SynchronizeFileOperation> filesToSyncContents, WebdavClient client) {
+    private void startContentSynchronizations(List<SynchronizeFileOperation> filesToSyncContents, OwnCloudClient client) {
         RemoteOperationResult contentsResult = null;
         for (SynchronizeFileOperation op: filesToSyncContents) {
             contentsResult = op.execute(client);   // returns without waiting for upload or download finishes
@@ -402,23 +374,6 @@ public class SynchronizeFolderOperation extends RemoteOperation {
         return (status == HttpStatus.SC_MULTI_STATUS); 
     }
 
-    
-    /**
-     * Creates and populates a new {@link OCFile} object with the data read from the server.
-     * 
-     * @param we        WebDAV entry read from the server for a WebDAV resource (remote file or folder).
-     * @return          New OCFile instance representing the remote resource described by we.
-     */
-    private OCFile fillOCFile(WebdavEntry we) {
-        OCFile file = new OCFile(we.decodedPath());
-        file.setCreationTimestamp(we.createTimestamp());
-        file.setFileLength(we.contentLength());
-        file.setMimetype(we.contentType());
-        file.setModificationTimestamp(we.modifiedTimestamp());
-        file.setEtag(we.etag());
-        return file;
-    }
-
     /**
      * Creates and populates a new {@link OCFile} object with the data read from the server.
      * 
@@ -523,17 +478,15 @@ public class SynchronizeFolderOperation extends RemoteOperation {
      * @param inProgress        'True' when the synchronization progress is not finished.
      * @param dirRemotePath     Remote path of a folder that was just synchronized (with or without success)
      */
-    private void sendStickyBroadcast(boolean inProgress, String dirRemotePath, RemoteOperationResult result) {
-        Intent i = new Intent(FileSyncService.getSyncMessage());
-        i.putExtra(FileSyncService.IN_PROGRESS, inProgress);
-        i.putExtra(FileSyncService.ACCOUNT_NAME, mAccount.name);
+    private void sendLocalBroadcast(String dirRemotePath, RemoteOperationResult result) {
+        Intent intent = new Intent(EVENT_SINGLE_FOLDER_SYNCED);
+        intent.putExtra(FileSyncAdapter.EXTRA_ACCOUNT_NAME, mAccount.name);
         if (dirRemotePath != null) {
-            i.putExtra(FileSyncService.SYNC_FOLDER_REMOTE_PATH, dirRemotePath);
-        }
-        if (result != null) {
-            i.putExtra(FileSyncService.SYNC_RESULT, result);
+            intent.putExtra(FileSyncAdapter.EXTRA_FOLDER_PATH, dirRemotePath);
         }
-        mContext.sendStickyBroadcast(i);
+        intent.putExtra(FileSyncAdapter.EXTRA_RESULT, result);
+        //mContext.sendStickyBroadcast(intent);
+        LocalBroadcastManager.getInstance(mContext).sendBroadcast(intent);
     }