Merge branch 'develop' into refactor_remote_operation_to_read_file
authormasensio <masensio@solidgear.es>
Mon, 2 Dec 2013 11:40:29 +0000 (12:40 +0100)
committermasensio <masensio@solidgear.es>
Mon, 2 Dec 2013 11:40:29 +0000 (12:40 +0100)
Conflicts:
oc_framework/src/com/owncloud/android/oc_framework/operations/RemoteFile.java
oc_framework/src/com/owncloud/android/oc_framework/operations/RemoteOperationResult.java
oc_framework/src/com/owncloud/android/oc_framework/utils/FileUtils.java
src/com/owncloud/android/operations/SynchronizeFolderOperation.java

1  2 
oc_framework-test-project/oc_framework-test-test/src/com/owncloud/android/oc_framework_test_project/test/ReadFileTest.java
oc_framework/src/com/owncloud/android/oc_framework/operations/RemoteOperationResult.java
oc_framework/src/com/owncloud/android/oc_framework/utils/FileUtils.java
src/com/owncloud/android/operations/SynchronizeFolderOperation.java

index 0000000,0000000..b75732b
new file mode 100644 (file)
--- /dev/null
--- /dev/null
@@@ -1,0 -1,0 +1,61 @@@
++/* 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_test_project.test;
++
++import com.owncloud.android.oc_framework.operations.RemoteOperationResult;
++import com.owncloud.android.oc_framework_test_project.TestActivity;
++
++import android.test.ActivityInstrumentationTestCase2;
++
++/**
++ * Class to test Read File Operation
++ * @author masensio
++ *
++ */
++
++public class ReadFileTest extends     ActivityInstrumentationTestCase2<TestActivity> {
++      
++      /* File data to read. This file must exist on the account */
++    private final String mRemoteFolderPath = "/fileToRead.txt";
++    
++    
++    private TestActivity mActivity;
++    
++    public ReadFileTest() {
++        super(TestActivity.class);
++    }
++    
++    @Override
++      protected void setUp() throws Exception {
++        super.setUp();
++        setActivityInitialTouchMode(false);
++        mActivity = getActivity();
++    }
++
++    /**
++     * Test Read File
++     */
++    public void testReadFile() {
++
++            RemoteOperationResult result = mActivity.readFile(mRemoteFolderPath);
++            assertTrue(result.getData().size() ==  1);
++            assertTrue(result.isSuccess());
++    }
++    
++
++}
@@@ -52,8 -52,8 +52,8 @@@ import android.util.Log
   */
  public class RemoteOperationResult implements Serializable {
  
-         /** Generated - should be refreshed every time the class changes!! */
-         private static final long serialVersionUID = -2469951225222759283L;
+       /** Generated - should be refreshed every time the class changes!! */
+       private static final long serialVersionUID = -2469951225222759283L;
      
      private static final String TAG = "RemoteOperationResult";
      
@@@ -99,7 -99,7 +99,7 @@@
      private String mRedirectedLocation;
  
      private ArrayList<RemoteFile> mFiles;
-         
 -      
++    
      public RemoteOperationResult(ResultCode code) {
          mCode = code;
          mSuccess = (code == ResultCode.OK || code == ResultCode.OK_SSL || code == ResultCode.OK_NO_SSL);
  
  
      public void setData(ArrayList<RemoteFile> files){
-             mFiles = files;
+       mFiles = files;
      }
      
-         public ArrayList<RemoteFile> getData(){
-                 return mFiles;
-         }
+       public ArrayList<RemoteFile> getData(){
+               return mFiles;
+       }
      
      public boolean isSuccess() {
          return mSuccess;
          } else if (mCode == ResultCode.ACCOUNT_NOT_THE_SAME) {
              return "Authenticated with a different account than the one updating";
          } else if (mCode == ResultCode.INVALID_CHARACTER_IN_NAME) {
 -              return "The file name contains an forbidden character";
 +                return "The file name contains an forbidden character";
          }
  
          return "Operation finished with HTTP status code " + mHttpCode + " (" + (isSuccess() ? "success" : "fail") + ")";
                  mRedirectedLocation.toLowerCase().contains("wayf")));
      }
  
- }
+ }
   *   along with this program.  If not, see <http://www.gnu.org/licenses/>.
   *
   */
  package com.owncloud.android.oc_framework.utils;
  
  import java.io.File;
  
 +import com.owncloud.android.oc_framework.network.webdav.WebdavEntry;
 +import com.owncloud.android.oc_framework.operations.RemoteFile;
 +
  import android.util.Log;
  
  public class FileUtils {
                }
                return result;
        }
 +      
 +      /**
 +     * Creates and populates a new {@link RemoteFile} 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.
 +     */
 +    public static RemoteFile fillOCFile(WebdavEntry we) {
 +        RemoteFile file = new RemoteFile(we.decodedPath());
 +        file.setCreationTimestamp(we.createTimestamp());
 +        file.setLength(we.contentLength());
 +        file.setMimeType(we.contentType());
 +        file.setModifiedTimestamp(we.modifiedTimestamp());
 +        file.setEtag(we.etag());
 +        return file;
 +    }
 +    
  }
@@@ -23,16 -23,16 +23,13 @@@ import java.io.FileOutputStream
  import java.io.IOException;
  import java.io.InputStream;
  import java.io.OutputStream;
+ import java.util.ArrayList;
  import java.util.HashMap;
  import java.util.List;
  import java.util.Map;
  import java.util.Vector;
  
  import org.apache.http.HttpStatus;
--import org.apache.jackrabbit.webdav.DavConstants;
- import org.apache.jackrabbit.webdav.MultiStatus;
--import org.apache.jackrabbit.webdav.client.methods.PropFindMethod;
--
  import android.accounts.Account;
  import android.content.Context;
  import android.content.Intent;
@@@ -41,11 -41,12 +38,12 @@@ import com.owncloud.android.datamodel.F
  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.ReadRemoteFileOperation;
+ 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.utils.FileStorageUtils;
  import com.owncloud.android.utils.Log_OC;
@@@ -187,27 -188,48 +185,27 @@@ public class SynchronizeFolderOperatio
          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(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 {
                  }
              }
              
 -        }
          return result;
      }
  
  
      private RemoteOperationResult fetchAndSyncRemoteFolder(WebdavClient client) {
-         RemoteOperationResult result = null;
-         String remotePath = null;
-         PropFindMethod query = null;
-         try {
-             remotePath = mLocalFolder.getRemotePath();
-             Log_OC.d(TAG, "Synchronizing " + mAccount.name + remotePath);
-             // remote request 
-             query = new PropFindMethod(client.getBaseUri() + WebdavUtils.encodePath(remotePath),
-                     DavConstants.PROPFIND_ALL_PROP,
-                     DavConstants.DEPTH_1);
-             int status = client.executeMethod(query);
-             // check and process response
-             if (isMultiStatus(status)) {
-                 synchronizeData(query.getResponseBodyAsMultiStatus(), client);
-                 if (mConflictsFound > 0  || mFailsInFavouritesFound > 0) { 
-                     result = new RemoteOperationResult(ResultCode.SYNC_CONFLICT);   // should be different result, but will do the job
-                 } else {
-                     result = new RemoteOperationResult(true, status, query.getResponseHeaders());
-                 }
-                 
-             } else {
-                 // synchronization failed
-                 client.exhaustResponse(query.getResponseBodyAsStream());
-                 if (status == HttpStatus.SC_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, "Synchronized " + mAccount.name + remotePath + ": " + result.getLogMessage());
-             } else {
-                 if (result.isException()) {
-                     Log_OC.e(TAG, "Synchronized " + mAccount.name + remotePath  + ": " + result.getLogMessage(), result.getException());
-                 } else {
-                     Log_OC.e(TAG, "Synchronized " + mAccount.name + remotePath + ": " + result.getLogMessage());
-                 }
+         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()) {
+             synchronizeData(result.getData(), client);
+             if (mConflictsFound > 0  || mFailsInFavouritesFound > 0) { 
+                 result = new RemoteOperationResult(ResultCode.SYNC_CONFLICT);   // should be different result, but will do the job
              }
-             
+         } else {
+             if (result.getCode() == ResultCode.FILE_NOT_FOUND)
+                 removeLocalFolder();
          }
+         
          return result;
      }
  
+     
      private void removeLocalFolder() {
          if (mStorageManager.fileExists(mLocalFolder.getFileId())) {
              String currentSavePath = FileStorageUtils.getSavePath(mAccount.name);
       *  with the current data in the local database.
       *  
       *  Grants that mChildren is updated with fresh data after execution.
-      * 
-      *  @param dataInServer     Full response got from the server with the data of the target 
-      *                          folder and its direct children.
+      *  
+      *  @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(MultiStatus dataInServer, WebdavClient client) {
+     private void synchronizeData(ArrayList<RemoteFile> folderAndFiles, WebdavClient client) {
          // get 'fresh data' from the database
          mLocalFolder = mStorageManager.getFileByPath(mLocalFolder.getRemotePath());
          
          // parse data from remote folder 
-         WebdavEntry we = new WebdavEntry(dataInServer.getResponses()[0], client.getBaseUri().getPath());
-         OCFile remoteFolder = fillOCFile(we);
+         OCFile remoteFolder = fillOCFile(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>(dataInServer.getResponses().length - 1);
+         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
          
          // loop to update every child
          OCFile remoteFile = null, localFile = null;
-         for (int i = 1; i < dataInServer.getResponses().length; ++i) {
+         for (int i=1; i<folderAndFiles.size(); i++) {
              /// new OCFile instance with the data from the server
-             we = new WebdavEntry(dataInServer.getResponses()[i], client.getBaseUri().getPath());                        
-             remoteFile = fillOCFile(we);
+             remoteFile = fillOCFile(folderAndFiles.get(i));
              remoteFile.setParentId(mLocalFolder.getFileId());
  
              /// retrieve local data for the read file 
          return (status == HttpStatus.SC_MULTI_STATUS); 
      }
  
+     
      /**
       * Creates and populates a new {@link OCFile} object with the data read from the server.
       * 
          file.setEtag(we.etag());
          return file;
      }
+     /**
+      * Creates and populates a new {@link OCFile} object with the data read from the server.
+      * 
+      * @param remote    remote file read from the server (remote file or folder).
+      * @return          New OCFile instance representing the remote resource described by we.
+      */
+     private OCFile fillOCFile(RemoteFile remote) {
+         OCFile file = new OCFile(remote.getRemotePath());
+         file.setCreationTimestamp(remote.getCreationTimestamp());
+         file.setFileLength(remote.getLength());
+         file.setMimetype(remote.getMimeType());
+         file.setModificationTimestamp(remote.getModifiedTimestamp());
+         file.setEtag(remote.getEtag());
+         return file;
+     }
      
  
      /**