Changed ETag calculation to SHA256
[pithos-ms-client] / trunk / Pithos.Core / Agents / CloudTransferAction.cs
index bc4a7fa..b3d35ca 100644 (file)
-using System;
-using System.IO;
-using System.Threading;
-using Pithos.Interfaces;
-using Pithos.Network;
-
-namespace Pithos.Core.Agents
-{
-    public enum CloudActionType
-    {
-        MustSynch,
-        UploadUnconditional,
-        DownloadUnconditional,
-        DeleteLocal,
-        DeleteCloud,
-        RenameCloud
-    }
-
-    public class CloudAction
-    {
-        public CloudActionType Action { get; set; }
-        public FileInfo LocalFile { get; set; }
-        public ObjectInfo CloudFile { get; set; }
-        public FileState FileState { get; set; }
-        public string Container { get; set; }
-
-
-        public Lazy<string> LocalHash { get; protected set; }
-        private Lazy<string> _topHash;
-        public Lazy<string> TopHash
-        {
-            get { return _topHash; }
-            set { _topHash = value; }
-        }
-
-
-        protected CloudAction(CloudActionType action)
-        {
-            Action = action;
-        }
-
-        public CloudAction(CloudActionType action, FileInfo localFile, ObjectInfo cloudFile,FileState state,int blockSize, string algorithm) : this(action)
-        {
-            LocalFile = localFile;
-            CloudFile = cloudFile;
-            FileState = state;
-            if (LocalFile != null)
-            {
-                LocalHash = new Lazy<string>(() => LocalFile.CalculateHash(blockSize,algorithm),
-                                             LazyThreadSafetyMode.ExecutionAndPublication);
-            }
-        }
-
-
-        //Constructor for downloading files
-        public CloudAction(CloudActionType action, ObjectInfo cloudFile)
-        {
-            Action = action;
-            CloudFile = cloudFile;
-        }
-
-    }    
-
-    public class CloudMoveAction:CloudAction
-    {
-        public string OldFileName { get; set; }
-        public string OldPath { get; set; }
-        public string NewFileName { get; set; }
-        public string NewPath { get; set; }
-
-        public CloudMoveAction(CloudActionType action, string oldPath, string oldFileName, string newFileName, string newPath)
-            :base(action)
-        {
-            OldFileName = oldFileName;
-            OldPath = oldPath;
-            NewFileName = newFileName;
-            NewPath = newPath;
-            //This is a rename operation, a hash will not be used
-            LocalHash = new Lazy<string>(() => String.Empty, LazyThreadSafetyMode.ExecutionAndPublication);
-        }
-
-
-    }
-
+#region\r
+/* -----------------------------------------------------------------------\r
+ * <copyright file="CloudTransferAction.cs" company="GRNet">\r
+ * \r
+ * Copyright 2011-2012 GRNET S.A. All rights reserved.\r
+ *\r
+ * Redistribution and use in source and binary forms, with or\r
+ * without modification, are permitted provided that the following\r
+ * conditions are met:\r
+ *\r
+ *   1. Redistributions of source code must retain the above\r
+ *      copyright notice, this list of conditions and the following\r
+ *      disclaimer.\r
+ *\r
+ *   2. Redistributions in binary form must reproduce the above\r
+ *      copyright notice, this list of conditions and the following\r
+ *      disclaimer in the documentation and/or other materials\r
+ *      provided with the distribution.\r
+ *\r
+ *\r
+ * THIS SOFTWARE IS PROVIDED BY GRNET S.A. ``AS IS'' AND ANY EXPRESS\r
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED\r
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR\r
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL GRNET S.A OR\r
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,\r
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT\r
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF\r
+ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED\r
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT\r
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN\r
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE\r
+ * POSSIBILITY OF SUCH DAMAGE.\r
+ *\r
+ * The views and conclusions contained in the software and\r
+ * documentation are those of the authors and should not be\r
+ * interpreted as representing official policies, either expressed\r
+ * or implied, of GRNET S.A.\r
+ * </copyright>\r
+ * -----------------------------------------------------------------------\r
+ */\r
+#endregion\r
+using System;\r
+using System.Diagnostics.Contracts;\r
+using System.IO;\r
+using System.Threading;\r
+using Pithos.Interfaces;\r
+using Pithos.Network;\r
+\r
+namespace Pithos.Core.Agents\r
+{\r
+    public enum CloudActionType\r
+    {\r
+        MustSynch,\r
+        UploadUnconditional,\r
+        DownloadUnconditional,\r
+        DeleteLocal,\r
+        DeleteCloud,\r
+        RenameCloud,\r
+        RenameLocal\r
+    }\r
+\r
+    public class CloudAction\r
+    {\r
+\r
+        public object Originator { get; set; }\r
+        public AccountInfo AccountInfo { get; set; }\r
+        public CloudActionType Action { get; set; }\r
+        public FileSystemInfo LocalFile { get; set; }\r
+        public ObjectInfo CloudFile { get; set; }\r
+        public FileState FileState { get; set; }\r
+        public string Container { get; set; }\r
+\r
+        public readonly DateTime Created = DateTime.Now;\r
+\r
+\r
+        public Lazy<TreeHash> TreeHash { get; protected set; }\r
+        //public Lazy<string> TopHash { get; set; }\r
+\r
+\r
+        [ContractInvariantMethod]\r
+        private void Invariants()\r
+        {\r
+            Contract.Invariant(AccountInfo!=null);\r
+        }\r
+\r
+        public bool IsShared\r
+        {\r
+            get { return  CloudFile!=null && AccountInfo.UserName != CloudFile.Account; }\r
+        }\r
+\r
+        protected CloudAction(AccountInfo accountInfo,CloudActionType action,object originator)\r
+        {\r
+            if (accountInfo==null)\r
+                throw new ArgumentNullException("accountInfo");\r
+            Contract.EndContractBlock();\r
+\r
+            Action = action;\r
+            AccountInfo = accountInfo;\r
+            Originator = originator;\r
+        }\r
+\r
+        public CloudAction(AccountInfo accountInfo, CloudActionType action, FileSystemInfo localFile, ObjectInfo cloudFile, FileState state, int blockSize, string algorithm,object originator,CancellationToken token,IProgress<double> progress )\r
+            : this(accountInfo,action,originator)\r
+        {\r
+            if(blockSize<=0)\r
+                throw new ArgumentOutOfRangeException("blockSize");\r
+            Contract.EndContractBlock();\r
+            LocalFile = localFile.WithProperCapitalization();\r
+            CloudFile = cloudFile;\r
+            FileState = state;\r
+            \r
+            if (LocalFile == null) \r
+                return;\r
+\r
+            TreeHash = new Lazy<TreeHash>(() => Signature.CalculateTreeHash(LocalFile, blockSize,algorithm,token,progress),\r
+                                            LazyThreadSafetyMode.ExecutionAndPublication);\r
+        }\r
+\r
+        //Calculate the download path for the cloud file\r
+        public string GetDownloadPath()\r
+        {\r
+            if (CloudFile == null)\r
+                return String.Empty;\r
+            var filePath = CloudFile.RelativeUrlToFilePath(AccountInfo.UserName);\r
+            return Path.Combine(AccountInfo.AccountPath, filePath);\r
+        }\r
+\r
+        public override string ToString()\r
+        {\r
+            return String.Format("{0}:{1}->{2}", Action, LocalFile.FullName, CloudFile.Name);\r
+        }\r
+\r
+        public static ObjectInfo CreateObjectInfoFor(AccountInfo accountInfo, FileSystemInfo fileInfo)\r
+        {\r
+            if(accountInfo==null)\r
+                throw new ArgumentNullException("accountInfo");\r
+            if(fileInfo==null)\r
+                throw new ArgumentNullException("fileInfo");\r
+            Contract.Ensures(Contract.Result<ObjectInfo>()!=null);\r
+            Contract.EndContractBlock();\r
+\r
+            var capitalizedFileInfo = fileInfo.WithProperCapitalization();\r
+            var fullLocalName = capitalizedFileInfo.FullName;\r
+            var othersPath = Path.Combine(accountInfo.AccountPath, FolderConstants.OthersFolder);\r
+\r
+            ObjectInfo objectInfo;\r
+\r
+            var isShared = fullLocalName.StartsWith(othersPath, StringComparison.InvariantCultureIgnoreCase);\r
+            if (isShared)\r
+            {                \r
+                var pathRelativeToOther = fullLocalName.Substring(othersPath.Length + 1);\r
+                var otherParts = pathRelativeToOther.Split('\\');\r
+                var otherName = otherParts[0];\r
+                var otherContainer = otherParts[1];\r
+                objectInfo=new ObjectInfo\r
+                           {\r
+                               Account = otherName, \r
+                               Container = otherContainer, \r
+                               Name = String.Join("/", otherParts.Splice(2))\r
+                           };\r
+            }\r
+            else\r
+                objectInfo=new ObjectInfo(accountInfo.AccountPath, accountInfo.UserName, fileInfo);\r
+            \r
+            objectInfo.Content_Type= (fileInfo is DirectoryInfo)\r
+                                    ?   "appication/directory"\r
+                                    :   "application/octet-stream";\r
+            return objectInfo;\r
+        }\r
+    }    \r
+\r
+    public class CloudDownloadAction:CloudAction\r
+    {\r
+        public CloudDownloadAction(AccountInfo accountInfo, ObjectInfo cloudFile,object originator)\r
+            :base(accountInfo,CloudActionType.DownloadUnconditional,originator)\r
+        {            \r
+            if (String.IsNullOrWhiteSpace(cloudFile.Container))\r
+                throw new ArgumentException("CloudFile.Container","cloudFile");\r
+            Contract.EndContractBlock();\r
+\r
+            CloudFile = cloudFile;\r
+        }\r
+\r
+        [ContractInvariantMethod]\r
+        private void Invariants()\r
+        {\r
+            Contract.Invariant(!String.IsNullOrWhiteSpace(CloudFile.Container));\r
+        }\r
+\r
+        public override string ToString()\r
+        {\r
+            return String.Format("{0}: _ <- {1}", Action, CloudFile.Name);\r
+        }\r
+        \r
+    }\r
+    public class CloudDeleteAction:CloudAction\r
+    {\r
+        public CloudDeleteAction(AccountInfo accountInfo,FileSystemInfo fileInfo, FileState fileState,object originator)\r
+            : this(accountInfo,fileInfo,CreateObjectInfoFor(accountInfo, fileInfo),fileState,originator)\r
+        {            \r
+        }\r
+\r
+        public CloudDeleteAction(AccountInfo accountInfo, FileSystemInfo fileInfo,ObjectInfo cloudFile, FileState fileState,object originator) \r
+            : base(accountInfo,CloudActionType.DeleteCloud,originator)\r
+        {\r
+            CloudFile = cloudFile;\r
+            LocalFile = fileInfo;\r
+            FileState = fileState;\r
+        }\r
+\r
+        public CloudDeleteAction(CloudAction action)\r
+            : this(action.AccountInfo,action.LocalFile,action.CloudFile,action.FileState,action)\r
+        {}\r
+\r
+        [ContractInvariantMethod]\r
+        private void Invariants()\r
+        {\r
+            Contract.Invariant(!String.IsNullOrWhiteSpace(CloudFile.Container));\r
+        }\r
+\r
+        public override string ToString()\r
+        {\r
+            return String.Format("{0}: _ ->{1}", Action, CloudFile.Name);\r
+        }\r
+\r
+    }\r
+\r
+    public class CloudUploadAction:CloudAction\r
+    {\r
+\r
+        public bool IsCreation { get; set; }\r
+\r
+        public CloudUploadAction(AccountInfo accountInfo, FileSystemInfo fileInfo, FileState state, int blockSize, string algorithm,object originator,bool isCreation,CancellationToken token,IProgress<double> progress,TreeHash treeHash=null )\r
+            : base(accountInfo, CloudActionType.UploadUnconditional,fileInfo,CreateObjectInfoFor(accountInfo,fileInfo),state,blockSize,algorithm,originator,token,progress)\r
+        {\r
+            IsCreation = isCreation;\r
+            if (treeHash != null)\r
+            {\r
+                TreeHash = new Lazy<TreeHash>(() => treeHash);\r
+                TreeHash.Force();\r
+            }\r
+\r
+        }\r
+\r
+        [ContractInvariantMethod]\r
+        private void Invariants()\r
+        {\r
+            Contract.Invariant(!String.IsNullOrWhiteSpace(CloudFile.Container));\r
+        }\r
+\r
+    }\r
+\r
+    public class CloudMoveAction:CloudAction\r
+    {\r
+        public ObjectInfo OldCloudFile { get; set; }\r
+\r
+        public FileSystemInfo OldLocalFile { get; set; }\r
+\r
+        public CloudMoveAction(AccountInfo accountInfo, CloudActionType action, FileSystemInfo oldFile, FileSystemInfo newFile,object originator)\r
+            :base(accountInfo,action,originator)\r
+        {\r
+            LocalFile = newFile;\r
+            CloudFile = CreateObjectInfoFor(accountInfo, newFile);\r
+            \r
+            OldLocalFile = oldFile;\r
+            OldCloudFile = CreateObjectInfoFor(accountInfo, oldFile);\r
+\r
+            //This is a rename operation, a hash will not be used\r
+            TreeHash = new Lazy<TreeHash>(() => Network.TreeHash.Empty, LazyThreadSafetyMode.ExecutionAndPublication);\r
+        }\r
+\r
+        public override string ToString()\r
+        {\r
+            return String.Format("{0}:{1}->{2}", Action, OldCloudFile.Name, CloudFile.Name);\r
+        }\r
+\r
+    }\r
+\r
 }
\ No newline at end of file