浏览代码

OC-2256: New RemoteFile class

masensio 11 年之前
父节点
当前提交
007ca522ec

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

@@ -0,0 +1,148 @@
+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;
+
+
+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);		
+	}
+    
+    
+}

+ 23 - 4
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,14 @@ public class RemoteOperationResult implements Serializable {
     private ResultCode mCode = ResultCode.UNKNOWN_ERROR;
     private String mRedirectedLocation;
 
+    private RemoteFile mFile;
+    private ArrayList<RemoteFile> mFiles;
+	
     public RemoteOperationResult(ResultCode code) {
         mCode = code;
         mSuccess = (code == ResultCode.OK || code == ResultCode.OK_SSL || code == ResultCode.OK_NO_SSL);
+        mFile= null;
+        mFiles = null;
     }
 
     private RemoteOperationResult(boolean success, int httpCode) {
@@ -196,6 +200,21 @@ public class RemoteOperationResult implements Serializable {
 
     }
 
+
+    public void setFile(RemoteFile file){
+    	mFile = file;
+    }
+    public RemoteFile getFile(){
+    	return mFile;
+    }
+    public void setData(ArrayList<RemoteFile> files){
+    	mFiles = files;
+    }
+    
+	public ArrayList<RemoteFile> getData(){
+		return mFiles;
+	}
+    
     public boolean isSuccess() {
         return mSuccess;
     }

+ 62 - 9
oc_framework/src/com/owncloud/android/oc_framework/operations/remote/ReadRemoteFileOperation.java

@@ -1,5 +1,7 @@
 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;
@@ -8,7 +10,9 @@ 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;
 
@@ -24,12 +28,8 @@ public class ReadRemoteFileOperation extends RemoteOperation {
 	private static final String TAG = ReadRemoteFileOperation.class.getSimpleName();
 
 	private String mRemotePath;
-	private MultiStatus mDataInServer;
-
-	public MultiStatus getDataInServer() {
-		return mDataInServer;
-	}
-	
+	private RemoteFile mFolder;
+	private ArrayList<RemoteFile> mFiles;
 	
 	/**
      * Constructor
@@ -38,7 +38,6 @@ public class ReadRemoteFileOperation extends RemoteOperation {
      */
 	public ReadRemoteFileOperation(String remotePath) {
 		mRemotePath = remotePath;
-		mDataInServer = null;
 	}
 
 	/**
@@ -61,8 +60,16 @@ public class ReadRemoteFileOperation extends RemoteOperation {
             // check and process response
             if (isMultiStatus(status)) {
             	// get data from remote folder 
-            	mDataInServer = query.getResponseBodyAsMultiStatus();
+            	MultiStatus dataInServer = query.getResponseBodyAsMultiStatus();
+            	readData(dataInServer, client);
+            	
+            	// Result of the operation
             	result = new RemoteOperationResult(true, status, query.getResponseHeaders());
+            	// Add data to the result
+            	if (result.isSuccess()) {
+            		result.setFile(mFolder);
+            		result.setData(mFiles);
+            	}
             } else {
                 // synchronization failed
                 client.exhaustResponse(query.getResponseBodyAsStream());
@@ -93,5 +100,51 @@ public class ReadRemoteFileOperation extends RemoteOperation {
     public boolean isMultiStatus(int status) {
         return (status == HttpStatus.SC_MULTI_STATUS); 
     }
-	
+
+    /**
+     *  Read the data retrieved from the server about the contents of the target folder 
+     *  
+     * 
+     *  @param dataInServer     Full response got from the server with the data of the target 
+     *                          folder and its direct children.
+     *  @param client           Client instance to the remote server where the data were 
+     *                          retrieved.  
+     *  @return                
+     */
+    private void readData(MultiStatus dataInServer, WebdavClient client) {   	
+        // parse data from remote folder 
+        WebdavEntry we = new WebdavEntry(dataInServer.getResponses()[0], client.getBaseUri().getPath());
+        mFolder = fillOCFile(we);
+        
+        Log.d(TAG, "Remote folder " + mRemotePath + " changed - starting update of local data ");
+        
+        
+        // loop to update every child
+        RemoteFile remoteFile = null;
+        mFiles = new ArrayList<RemoteFile>();
+        for (int i = 1; i < dataInServer.getResponses().length; ++i) {
+            /// new OCFile instance with the data from the server
+            we = new WebdavEntry(dataInServer.getResponses()[i], client.getBaseUri().getPath());                        
+            remoteFile = fillOCFile(we);
+            
+            mFiles.add(remoteFile);
+        }
+        
+    }
+    
+    /**
+     * 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.
+     */
+    private 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;
+    }
 }

+ 32 - 77
src/com/owncloud/android/operations/SynchronizeFolderOperation.java

@@ -23,6 +23,7 @@ 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;
@@ -30,7 +31,6 @@ 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;
@@ -46,6 +46,7 @@ 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.RemoteFile;
 import com.owncloud.android.syncadapter.FileSyncService;
 import com.owncloud.android.utils.FileStorageUtils;
 import com.owncloud.android.utils.Log_OC;
@@ -248,8 +249,9 @@ public class SynchronizeFolderOperation extends RemoteOperation {
         Log_OC.d(TAG, "Synchronizing " + mAccount.name + remotePath);
         
         if (result.isSuccess()) {
-            MultiStatus dataInServer = ((ReadRemoteFileOperation) operation).getDataInServer();
-            synchronizeData(dataInServer, client);
+            RemoteFile folder = result.getFile();
+            ArrayList<RemoteFile> files = result.getData();
+            synchronizeData(folder, files, client);
             if (mConflictsFound > 0  || mFailsInFavouritesFound > 0) { 
                 result = new RemoteOperationResult(ResultCode.SYNC_CONFLICT);   // should be different result, but will do the job
             }
@@ -258,72 +260,9 @@ public class SynchronizeFolderOperation extends RemoteOperation {
                 removeLocalFolder();
         }
         
-//        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());
-//                }
-//            }
-//            
-//        }
         return result;
     }
 
-
-//    @Override
-//    public void onRemoteOperationFinish(RemoteOperation operation, RemoteOperationResult result) {
-//        if (operation instanceof ReadRemoteFileOperation) {
-//            if (result.isSuccess()) {
-//                MultiStatus dataInServer = ((ReadRemoteFileOperation) operation).getDataInServer();
-//                synchronizeData(dataInServer, client)
-//            } else {
-//                
-//            }
-//                
-//        }
-//        
-//    }
     
     private void removeLocalFolder() {
         if (mStorageManager.fileExists(mLocalFolder.getFileId())) {
@@ -338,26 +277,27 @@ public class SynchronizeFolderOperation extends RemoteOperation {
      *  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 folder           Remote Folder to synchronize
+     *  
+     *  @param files            Remote 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(RemoteFile folder, ArrayList<RemoteFile> files, 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(folder);
         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>(files.size());
         List<SynchronizeFileOperation> filesToSyncContents = new Vector<SynchronizeFileOperation>();
 
         // get current data about local contents of the folder to synchronize
@@ -369,10 +309,9 @@ public class SynchronizeFolderOperation extends RemoteOperation {
         
         // loop to update every child
         OCFile remoteFile = null, localFile = null;
-        for (int i = 1; i < dataInServer.getResponses().length; ++i) {
+        for (RemoteFile file: files) { 
             /// new OCFile instance with the data from the server
-            we = new WebdavEntry(dataInServer.getResponses()[i], client.getBaseUri().getPath());                        
-            remoteFile = fillOCFile(we);
+            remoteFile = fillOCFile(file);
             remoteFile.setParentId(mLocalFolder.getFileId());
 
             /// retrieve local data for the read file 
@@ -463,7 +402,7 @@ 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.
      * 
@@ -479,6 +418,22 @@ public class SynchronizeFolderOperation extends RemoteOperation {
         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;
+    }
     
 
     /**