Statistics
| Branch: | Revision:

root / trunk / Pithos.Core / Agents / CloudTransferAction.cs @ 70f12b36

History | View | Annotate | Download (7.1 kB)

1
using System;
2
using System.Diagnostics.Contracts;
3
using System.IO;
4
using System.Threading;
5
using Pithos.Interfaces;
6
using Pithos.Network;
7

    
8
namespace Pithos.Core.Agents
9
{
10
    public enum CloudActionType
11
    {
12
        MustSynch,
13
        UploadUnconditional,
14
        DownloadUnconditional,
15
        DeleteLocal,
16
        DeleteCloud,
17
        RenameCloud
18
    }
19

    
20
    public class CloudAction
21
    {
22
        public AccountInfo AccountInfo { get; set; }
23
        public CloudActionType Action { get; set; }
24
        public FileSystemInfo LocalFile { get; set; }
25
        public ObjectInfo CloudFile { get; set; }
26
        public FileState FileState { get; set; }
27
        public string Container { get; set; }
28

    
29
        public readonly DateTime Created = DateTime.Now;
30

    
31

    
32
        public Lazy<string> LocalHash { get; protected set; }
33
        private Lazy<string> _topHash;
34
        public Lazy<string> TopHash
35
        {
36
            get { return _topHash; }
37
            set { _topHash = value; }
38
        }
39

    
40

    
41
        [ContractInvariantMethod]
42
        private void Invariants()
43
        {
44
            Contract.Invariant(AccountInfo!=null);
45
        }
46

    
47
        protected CloudAction(AccountInfo accountInfo,CloudActionType action)
48
        {
49
            if (accountInfo==null)
50
                throw new ArgumentNullException("accountInfo");
51
            Contract.EndContractBlock();
52

    
53
            Action = action;
54
            AccountInfo = accountInfo;
55
        }
56

    
57
        public CloudAction(AccountInfo accountInfo, CloudActionType action, FileSystemInfo localFile, ObjectInfo cloudFile, FileState state, int blockSize, string algorithm)
58
            : this(accountInfo,action)
59
        {
60
            LocalFile = localFile.WithProperCapitalization();
61
            CloudFile = cloudFile;
62
            FileState = state;
63
            if (LocalFile != null)
64
            {
65

    
66
                LocalHash = new Lazy<string>(() => LocalFile.CalculateHash(blockSize,algorithm),
67
                                             LazyThreadSafetyMode.ExecutionAndPublication);
68
            }
69
        }
70

    
71
        //Calculate the download path for the cloud file
72
        public string GetDownloadPath()
73
        {
74
            if (CloudFile == null)
75
                return String.Empty;
76
            var filePath = CloudFile.RelativeUrlToFilePath(AccountInfo.UserName);
77
            return Path.Combine(AccountInfo.AccountPath, filePath);
78
        }
79

    
80
        public override string ToString()
81
        {
82
            return String.Format("{0}:{1}->{2}", this.Action, this.LocalFile.FullName, this.CloudFile.Name);
83
        }
84

    
85
        protected static ObjectInfo CreateObjectInfoFor(AccountInfo accountInfo, FileSystemInfo fileInfo)
86
        {
87
            Contract.Requires(accountInfo!=null);
88
            Contract.Requires(fileInfo!=null);
89
            Contract.Ensures(Contract.Result<ObjectInfo>()!=null);
90

    
91
            var capitalizedFileInfo = fileInfo.WithProperCapitalization();
92
            var fullLocalName = capitalizedFileInfo.FullName;
93
            var othersPath = Path.Combine(accountInfo.AccountPath, FolderConstants.OthersFolder);
94
            
95
            var isShared = fullLocalName.StartsWith(othersPath, StringComparison.InvariantCultureIgnoreCase);
96
            if (isShared)
97
            {                
98
                var pathRelativeToOther = fullLocalName.Substring(othersPath.Length + 1);
99
                var otherParts = pathRelativeToOther.Split('\\');
100
                var otherName = otherParts[0];
101
                var otherContainer = otherParts[1];
102
                return new ObjectInfo
103
                           {
104
                               Account = otherName, 
105
                               Container = otherContainer, 
106
                               Name = String.Join("/", otherParts.Splice(2))
107
                           };
108
            }
109
            return new ObjectInfo(accountInfo.AccountPath, accountInfo.UserName, fileInfo);
110
        }
111
    }    
112

    
113
    public class CloudDownloadAction:CloudAction
114
    {
115
        public CloudDownloadAction(AccountInfo accountInfo, ObjectInfo cloudFile)
116
            :base(accountInfo,CloudActionType.DownloadUnconditional)
117
        {            
118
            if (String.IsNullOrWhiteSpace(cloudFile.Container))
119
                throw new ArgumentException("CloudFile.Container","cloudFile");
120
            Contract.EndContractBlock();
121

    
122
            CloudFile = cloudFile;
123
        }
124

    
125
        [ContractInvariantMethod]
126
        private void Invariants()
127
        {
128
            Contract.Invariant(!String.IsNullOrWhiteSpace(CloudFile.Container));
129
        }
130

    
131
        public override string ToString()
132
        {
133
            return String.Format("{0}: _ <- {1}", this.Action, this.CloudFile.Name);
134
        }
135
        
136
    }
137
    public class CloudDeleteAction:CloudAction
138
    {
139
        public CloudDeleteAction(AccountInfo accountInfo,FileSystemInfo fileInfo, FileState fileState)
140
            : this(accountInfo,fileInfo,CreateObjectInfoFor(accountInfo, fileInfo),fileState)
141
        {            
142
        }
143

    
144
        public CloudDeleteAction(AccountInfo accountInfo, FileSystemInfo fileInfo,ObjectInfo cloudFile, FileState fileState) 
145
            : base(accountInfo,CloudActionType.DeleteCloud)
146
        {
147
            CloudFile = cloudFile;
148
            LocalFile = fileInfo;
149
            FileState = fileState;
150
        }
151

    
152
        public CloudDeleteAction(CloudAction action)
153
            : this(action.AccountInfo,action.LocalFile,action.CloudFile,action.FileState)
154
        {}
155

    
156
        [ContractInvariantMethod]
157
        private void Invariants()
158
        {
159
            Contract.Invariant(!String.IsNullOrWhiteSpace(CloudFile.Container));
160
        }
161

    
162
        public override string ToString()
163
        {
164
            return String.Format("{0}: _ ->{1}", this.Action, this.CloudFile.Name);
165
        }
166

    
167
    }
168

    
169
    public class CloudUploadAction:CloudAction
170
    {
171
        public CloudUploadAction(AccountInfo accountInfo, FileSystemInfo fileInfo, FileState state, int blockSize, string algorithm)
172
            : base(accountInfo, CloudActionType.UploadUnconditional,fileInfo,CreateObjectInfoFor(accountInfo,fileInfo),state,blockSize,algorithm)             
173
        {
174
        }
175

    
176
        [ContractInvariantMethod]
177
        private void Invariants()
178
        {
179
            Contract.Invariant(!String.IsNullOrWhiteSpace(CloudFile.Container));
180
        }
181

    
182
    }
183

    
184
    public class CloudMoveAction:CloudAction
185
    {
186
        public ObjectInfo OldCloudFile { get; set; }
187

    
188
        public FileSystemInfo OldLocalFile { get; set; }
189

    
190
        public CloudMoveAction(AccountInfo accountInfo, CloudActionType action, FileSystemInfo oldFile, FileSystemInfo newFile)
191
            :base(accountInfo,action)
192
        {
193
            LocalFile = newFile;
194
            CloudFile = CreateObjectInfoFor(accountInfo, newFile);
195
            
196
            OldLocalFile = oldFile;
197
            OldCloudFile = CreateObjectInfoFor(accountInfo, oldFile);
198

    
199
            //This is a rename operation, a hash will not be used
200
            LocalHash = new Lazy<string>(() => String.Empty, LazyThreadSafetyMode.ExecutionAndPublication);
201
        }
202

    
203
        public override string ToString()
204
        {
205
            return String.Format("{0}:{1}->{2}", this.Action, OldCloudFile.Name, CloudFile.Name);
206
        }
207

    
208
    }
209

    
210
}