浏览代码

OC-2280: Isolate the code for ReadFile (PROPFIND 0) to remove local dependences

masensio 11 年之前
父节点
当前提交
26f68e0eac

+ 170 - 0
oc_framework/src/com/owncloud/android/oc_framework/operations/RemoteFile.java

@@ -0,0 +1,170 @@
+/* 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;
+
+import java.io.Serializable;
+
+import android.os.Parcel;
+import android.os.Parcelable;
+
+import com.owncloud.android.oc_framework.utils.FileUtils;
+
+/**
+ *  Contains the data of a Remote File from a WebDavEntry
+ * 
+ *  @author masensio
+ */
+
+public class RemoteFile implements Parcelable, Serializable {
+
+        /** Generated - should be refreshed every time the class changes!! */
+        private static final long serialVersionUID = 7256606476031992757L;
+        
+        private String mRemotePath;
+        private String mMimeType;
+        private long mLength;
+        private long mCreationTimestamp;
+        private long mModifiedTimestamp;
+        private String mEtag;
+        
+        /** 
+         * Getters and Setters
+         */
+        
+    public String getRemotePath() {
+                return mRemotePath;
+        }
+
+        public void setRemotePath(String remotePath) {
+                this.mRemotePath = remotePath;
+        }
+
+        public String getMimeType() {
+                return mMimeType;
+        }
+
+        public void setMimeType(String mimeType) {
+                this.mMimeType = mimeType;
+        }
+
+        public long getLength() {
+                return mLength;
+        }
+
+        public void setLength(long length) {
+                this.mLength = length;
+        }
+
+        public long getCreationTimestamp() {
+                return mCreationTimestamp;
+        }
+
+        public void setCreationTimestamp(long creationTimestamp) {
+                this.mCreationTimestamp = creationTimestamp;
+        }
+
+        public long getModifiedTimestamp() {
+                return mModifiedTimestamp;
+        }
+
+        public void setModifiedTimestamp(long modifiedTimestamp) {
+                this.mModifiedTimestamp = modifiedTimestamp;
+        }
+
+        public String getEtag() {
+                return mEtag;
+        }
+
+        public void setEtag(String etag) {
+                this.mEtag = etag;
+        }
+
+        /**
+     * Create new {@link RemoteFile} with given path.
+     * 
+     * The path received must be URL-decoded. Path separator must be OCFile.PATH_SEPARATOR, and it must be the first character in 'path'.
+     * 
+     * @param path The remote path of the file.
+     */
+        public RemoteFile(String path) {
+                resetData();
+        if (path == null || path.length() <= 0 || !path.startsWith(FileUtils.PATH_SEPARATOR)) {
+            throw new IllegalArgumentException("Trying to create a OCFile with a non valid remote path: " + path);
+        }
+        mRemotePath = path;
+        }
+
+        /**
+     * Used internally. Reset all file properties
+     */
+    private void resetData() {
+        mRemotePath = null;
+        mMimeType = null;
+        mLength = 0;
+        mCreationTimestamp = 0;
+        mModifiedTimestamp = 0;
+        mEtag = null;
+    }
+
+    /** 
+     * Parcelable Methods
+     */
+    public static final Parcelable.Creator<RemoteFile> CREATOR = new Parcelable.Creator<RemoteFile>() {
+        @Override
+        public RemoteFile createFromParcel(Parcel source) {
+            return new RemoteFile(source);
+        }
+
+        @Override
+        public RemoteFile[] newArray(int size) {
+            return new RemoteFile[size];
+        }
+    };
+    
+    
+    /**
+     * Reconstruct from parcel
+     * 
+     * @param source The source parcel
+     */
+    private RemoteFile(Parcel source) {
+        mRemotePath = source.readString();
+        mMimeType = source.readString();
+        mLength = source.readLong();
+        mCreationTimestamp = source.readLong();
+        mModifiedTimestamp = source.readLong();
+        mEtag = source.readString();
+    }
+    
+        @Override
+        public int describeContents() {
+                return this.hashCode();
+        }
+
+        @Override
+        public void writeToParcel(Parcel dest, int flags) {
+                dest.writeString(mRemotePath);
+                dest.writeString(mMimeType);    
+                dest.writeLong(mLength);
+                dest.writeLong(mCreationTimestamp);
+                dest.writeLong(mModifiedTimestamp);
+                dest.writeString(mEtag);                
+        }
+    
+    
+}

+ 17 - 6
oc_framework/src/com/owncloud/android/oc_framework/operations/RemoteOperationResult.java

@@ -24,6 +24,7 @@ import java.net.MalformedURLException;
 import java.net.SocketException;
 import java.net.SocketTimeoutException;
 import java.net.UnknownHostException;
+import java.util.ArrayList;
 
 import javax.net.ssl.SSLException;
 
@@ -51,10 +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 = -4415103901492836870L;
-    
-
+        /** Generated - should be refreshed every time the class changes!! */
+        private static final long serialVersionUID = -2469951225222759283L;
     
     private static final String TAG = "RemoteOperationResult";
     
@@ -99,9 +98,12 @@ public class RemoteOperationResult implements Serializable {
     private ResultCode mCode = ResultCode.UNKNOWN_ERROR;
     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);
+        mFiles = null;
     }
 
     private RemoteOperationResult(boolean success, int httpCode) {
@@ -196,6 +198,15 @@ public class RemoteOperationResult implements Serializable {
 
     }
 
+
+    public void setData(ArrayList<RemoteFile> files){
+            mFiles = files;
+    }
+    
+        public ArrayList<RemoteFile> getData(){
+                return mFiles;
+        }
+    
     public boolean isSuccess() {
         return mSuccess;
     }
@@ -309,7 +320,7 @@ public class RemoteOperationResult implements Serializable {
         } 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") + ")";
@@ -338,4 +349,4 @@ public class RemoteOperationResult implements Serializable {
                 mRedirectedLocation.toLowerCase().contains("wayf")));
     }
 
-}
+}

+ 111 - 0
oc_framework/src/com/owncloud/android/oc_framework/operations/remote/ReadRemoteFileOperation.java

@@ -0,0 +1,111 @@
+/* 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.util.ArrayList;
+
+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.util.Log;
+
+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.RemoteFile;
+import com.owncloud.android.oc_framework.operations.RemoteOperation;
+import com.owncloud.android.oc_framework.operations.RemoteOperationResult;
+import com.owncloud.android.oc_framework.utils.FileUtils;
+
+
+/**
+ * Remote operation performing the read a file from the ownCloud server.
+ * 
+ * @author David A. Velasco
+ * @author masensio
+ */
+
+public class ReadRemoteFileOperation extends RemoteOperation {
+
+    private static final String TAG = ReadRemoteFileOperation.class.getSimpleName();
+    private static final int SYNC_READ_TIMEOUT = 10000;
+    private static final int SYNC_CONNECTION_TIMEOUT = 5000;
+    
+    private String mRemotePath;
+    
+	
+    /**
+     * Constructor
+     * 
+     * @param remotePath		Remote path of the file. 
+     */
+    public ReadRemoteFileOperation(String remotePath) {
+    	mRemotePath = remotePath;
+    }
+
+    /**
+     * Performs the read operation.
+     * 
+     * @param client		Client object to communicate with the remote ownCloud server.
+     */
+    @Override
+    protected RemoteOperationResult run(WebdavClient client) {
+    	PropFindMethod propfind = null;
+    	RemoteOperationResult result = null;
+
+    	/// take the duty of check the server for the current state of the file there
+    	try {
+    		propfind = new PropFindMethod(client.getBaseUri() + WebdavUtils.encodePath(mRemotePath),
+    				DavConstants.PROPFIND_ALL_PROP,
+    				DavConstants.DEPTH_0);
+    		int status;
+    		status = client.executeMethod(propfind, SYNC_READ_TIMEOUT, SYNC_CONNECTION_TIMEOUT);
+
+    		boolean isMultiStatus = status == HttpStatus.SC_MULTI_STATUS;
+    		if (isMultiStatus) {
+    			MultiStatus resp = propfind.getResponseBodyAsMultiStatus();
+    			// Result of the operation
+    			result = new RemoteOperationResult(true, status, propfind.getResponseHeaders());
+    			
+    			// Add data to the result
+    			if (result.isSuccess()) {
+    				WebdavEntry we = new WebdavEntry(resp.getResponses()[0], client.getBaseUri().getPath());
+    				RemoteFile remoteFile = FileUtils.fillOCFile(we);
+    				ArrayList<RemoteFile> files = new ArrayList<RemoteFile>();
+    				files.add(remoteFile);
+    				result.setData(files); 
+    			}
+
+    		} else {
+    			client.exhaustResponse(propfind.getResponseBodyAsStream());
+    			result = new RemoteOperationResult(false, status, propfind.getResponseHeaders());
+    		}
+
+    	} catch (Exception e) {
+    		result = new RemoteOperationResult(e);
+    		e.printStackTrace();
+    		Log.e(TAG, "Synchronizing  file " + mRemotePath + ": " + result.getLogMessage(), result.getException());
+    	} finally {
+    		if (propfind != null)
+    			propfind.releaseConnection();
+    	}
+    	return result;
+    }
+
+}

+ 36 - 0
oc_framework/src/com/owncloud/android/oc_framework/utils/FileUtils.java

@@ -1,7 +1,26 @@
+/* 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.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 {
@@ -49,4 +68,21 @@ 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;
+    }
+    
 }

+ 76 - 115
src/com/owncloud/android/operations/SynchronizeFileOperation.java

@@ -18,33 +18,32 @@
 
 package com.owncloud.android.operations;
 
-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 com.owncloud.android.datamodel.FileDataStorageManager;
 import com.owncloud.android.datamodel.OCFile;
 import com.owncloud.android.files.services.FileDownloader;
 import com.owncloud.android.files.services.FileUploader;
 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.utils.FileStorageUtils;
 import com.owncloud.android.utils.Log_OC;
 
 import android.accounts.Account;
 import android.content.Context;
 import android.content.Intent;
 
+/**
+ * Remote operation performing the read of remote file in the ownCloud server.
+ * 
+ * @author David A. Velasco
+ * @author masensio
+ */
 
 public class SynchronizeFileOperation extends RemoteOperation {
 
     private String TAG = SynchronizeFileOperation.class.getSimpleName();
-    private static final int SYNC_READ_TIMEOUT = 10000;
-    private static final int SYNC_CONNECTION_TIMEOUT = 5000;
     
     private OCFile mLocalFile;
     private OCFile mServerFile;
@@ -74,103 +73,83 @@ public class SynchronizeFileOperation extends RemoteOperation {
 
     @Override
     protected RemoteOperationResult run(WebdavClient client) {
-        
-        PropFindMethod propfind = null;
+
         RemoteOperationResult result = null;
         mTransferWasRequested = false;
-        try {
-            if (!mLocalFile.isDown()) {
-                /// easy decision
-                requestForDownload(mLocalFile);
-                result = new RemoteOperationResult(ResultCode.OK);
-                
-            } else {
-                /// local copy in the device -> need to think a bit more before do anything
-                
-                if (mServerFile == null) {
-                    /// take the duty of check the server for the current state of the file there
-                    propfind = new PropFindMethod(client.getBaseUri() + WebdavUtils.encodePath(mLocalFile.getRemotePath()),
-                            DavConstants.PROPFIND_ALL_PROP,
-                            DavConstants.DEPTH_0);
-                    int status = client.executeMethod(propfind, SYNC_READ_TIMEOUT, SYNC_CONNECTION_TIMEOUT);
-                    boolean isMultiStatus = status == HttpStatus.SC_MULTI_STATUS;
-                    if (isMultiStatus) {
-                        MultiStatus resp = propfind.getResponseBodyAsMultiStatus();
-                        WebdavEntry we = new WebdavEntry(resp.getResponses()[0],
-                                               client.getBaseUri().getPath());
-                        mServerFile = fillOCFile(we);
-                        mServerFile.setLastSyncDateForProperties(System.currentTimeMillis());
-                        
-                    } else {
-                        client.exhaustResponse(propfind.getResponseBodyAsStream());
-                        result = new RemoteOperationResult(false, status, propfind.getResponseHeaders());
-                    }
+        if (!mLocalFile.isDown()) {
+            /// easy decision
+            requestForDownload(mLocalFile);
+            result = new RemoteOperationResult(ResultCode.OK);
+
+        } else {
+            /// local copy in the device -> need to think a bit more before do anything
+
+            if (mServerFile == null) {
+                String remotePath = mLocalFile.getRemotePath();
+                ReadRemoteFileOperation operation = new ReadRemoteFileOperation(remotePath);
+                result = operation.execute(client);
+                if (result.isSuccess()){
+                    mServerFile = FileStorageUtils.fillOCFile(result.getData().get(0));
+                    mServerFile.setLastSyncDateForProperties(System.currentTimeMillis());
                 }
-                
-                if (result == null) {   // true if the server was not checked. nothing was wrong with the remote request
-              
-                    /// check changes in server and local file
-                    boolean serverChanged = false;
-                    /* time for eTag is coming, but not yet
+            }
+
+            if (result == null) {   // true if the server was not checked. nothing was wrong with the remote request
+
+                /// check changes in server and local file
+                boolean serverChanged = false;
+                /* time for eTag is coming, but not yet
                     if (mServerFile.getEtag() != null) {
                         serverChanged = (!mServerFile.getEtag().equals(mLocalFile.getEtag()));   // TODO could this be dangerous when the user upgrades the server from non-tagged to tagged?
                     } else { */
-                        // server without etags
-                        serverChanged = (mServerFile.getModificationTimestamp() > mLocalFile.getModificationTimestampAtLastSyncForData());
-                    //}
-                    boolean localChanged = (mLocalFile.getLocalModificationTimestamp() > mLocalFile.getLastSyncDateForData());
-                        // TODO this will be always true after the app is upgraded to database version 2; will result in unnecessary uploads
-              
-                    /// decide action to perform depending upon changes
-                    //if (!mLocalFile.getEtag().isEmpty() && localChanged && serverChanged) {
-                    if (localChanged && serverChanged) {
-                        result = new RemoteOperationResult(ResultCode.SYNC_CONFLICT);
-                  
-                    } else if (localChanged) {
-                        if (mSyncFileContents) {
-                            requestForUpload(mLocalFile);
-                            // the local update of file properties will be done by the FileUploader service when the upload finishes
-                        } else {
-                            // NOTHING TO DO HERE: updating the properties of the file in the server without uploading the contents would be stupid; 
-                            // So, an instance of SynchronizeFileOperation created with syncFileContents == false is completely useless when we suspect
-                            // that an upload is necessary (for instance, in FileObserverService).
-                        }
-                        result = new RemoteOperationResult(ResultCode.OK);
-                  
-                    } else if (serverChanged) {
-                        if (mSyncFileContents) {
-                            requestForDownload(mLocalFile); // local, not server; we won't to keep the value of keepInSync!
-                            // the update of local data will be done later by the FileUploader service when the upload finishes
-                        } else {
-                            // TODO CHECK: is this really useful in some point in the code?
-                            mServerFile.setKeepInSync(mLocalFile.keepInSync());
-                            mServerFile.setLastSyncDateForData(mLocalFile.getLastSyncDateForData());
-                            mServerFile.setStoragePath(mLocalFile.getStoragePath());
-                            mServerFile.setParentId(mLocalFile.getParentId());
-                            mStorageManager.saveFile(mServerFile);
-                            
-                        }
-                        result = new RemoteOperationResult(ResultCode.OK);
-              
+                // server without etags
+                serverChanged = (mServerFile.getModificationTimestamp() > mLocalFile.getModificationTimestampAtLastSyncForData());
+                //}
+                boolean localChanged = (mLocalFile.getLocalModificationTimestamp() > mLocalFile.getLastSyncDateForData());
+                // TODO this will be always true after the app is upgraded to database version 2; will result in unnecessary uploads
+
+                /// decide action to perform depending upon changes
+                //if (!mLocalFile.getEtag().isEmpty() && localChanged && serverChanged) {
+                if (localChanged && serverChanged) {
+                    result = new RemoteOperationResult(ResultCode.SYNC_CONFLICT);
+
+                } else if (localChanged) {
+                    if (mSyncFileContents) {
+                        requestForUpload(mLocalFile);
+                        // the local update of file properties will be done by the FileUploader service when the upload finishes
                     } else {
-                        // nothing changed, nothing to do
-                        result = new RemoteOperationResult(ResultCode.OK);
+                        // NOTHING TO DO HERE: updating the properties of the file in the server without uploading the contents would be stupid; 
+                        // So, an instance of SynchronizeFileOperation created with syncFileContents == false is completely useless when we suspect
+                        // that an upload is necessary (for instance, in FileObserverService).
                     }
-              
-                } 
-          
-            }
-            
-            Log_OC.i(TAG, "Synchronizing " + mAccount.name + ", file " + mLocalFile.getRemotePath() + ": " + result.getLogMessage());
-          
-        } catch (Exception e) {
-            result = new RemoteOperationResult(e);
-            Log_OC.e(TAG, "Synchronizing " + mAccount.name + ", file " + (mLocalFile != null ? mLocalFile.getRemotePath() : "NULL") + ": " + result.getLogMessage(), result.getException());
-
-        } finally {
-            if (propfind != null)
-                propfind.releaseConnection();
+                    result = new RemoteOperationResult(ResultCode.OK);
+
+                } else if (serverChanged) {
+                    if (mSyncFileContents) {
+                        requestForDownload(mLocalFile); // local, not server; we won't to keep the value of keepInSync!
+                        // the update of local data will be done later by the FileUploader service when the upload finishes
+                    } else {
+                        // TODO CHECK: is this really useful in some point in the code?
+                        mServerFile.setKeepInSync(mLocalFile.keepInSync());
+                        mServerFile.setLastSyncDateForData(mLocalFile.getLastSyncDateForData());
+                        mServerFile.setStoragePath(mLocalFile.getStoragePath());
+                        mServerFile.setParentId(mLocalFile.getParentId());
+                        mStorageManager.saveFile(mServerFile);
+
+                    }
+                    result = new RemoteOperationResult(ResultCode.OK);
+
+                } else {
+                    // nothing changed, nothing to do
+                    result = new RemoteOperationResult(ResultCode.OK);
+                }
+
+            } 
+
         }
+
+        Log_OC.i(TAG, "Synchronizing " + mAccount.name + ", file " + mLocalFile.getRemotePath() + ": " + result.getLogMessage());
+
         return result;
     }
 
@@ -207,24 +186,6 @@ public class SynchronizeFileOperation extends RemoteOperation {
     }
 
 
-    /**
-     * 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;
-    }
-
-
     public boolean transferWasRequested() {
         return mTransferWasRequested;
     }

+ 13 - 34
src/com/owncloud/android/operations/SynchronizeFolderOperation.java

@@ -45,6 +45,7 @@ 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.syncadapter.FileSyncService;
 import com.owncloud.android.utils.FileStorageUtils;
 import com.owncloud.android.utils.Log_OC;
@@ -186,48 +187,27 @@ public class SynchronizeFolderOperation extends RemoteOperation {
         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 {
@@ -235,7 +215,6 @@ public class SynchronizeFolderOperation extends RemoteOperation {
                 }
             }
             
-        }
         return result;
     }
 

+ 17 - 0
src/com/owncloud/android/utils/FileStorageUtils.java

@@ -22,6 +22,7 @@ import java.io.File;
 import com.owncloud.android.MainApp;
 import com.owncloud.android.R;
 import com.owncloud.android.datamodel.OCFile;
+import com.owncloud.android.oc_framework.operations.RemoteFile;
 
 import android.annotation.SuppressLint;
 import android.content.Context;
@@ -82,5 +83,21 @@ public class FileStorageUtils {
         parentPath = parentPath.endsWith(OCFile.PATH_SEPARATOR) ? parentPath : parentPath + OCFile.PATH_SEPARATOR;
         return parentPath;
     }
+    
+    /**
+     * 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.
+     */
+    public static 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;
+    }
   
 }