Statistics
| Branch: | Revision:

root / trunk / Pithos.Core / Agents / CloudTransferAction.cs @ 8f44fd3a

History | View | Annotate | Download (9.5 kB)

1
#region
2
/* -----------------------------------------------------------------------
3
 * <copyright file="CloudTransferAction.cs" company="GRNet">
4
 * 
5
 * Copyright 2011-2012 GRNET S.A. All rights reserved.
6
 *
7
 * Redistribution and use in source and binary forms, with or
8
 * without modification, are permitted provided that the following
9
 * conditions are met:
10
 *
11
 *   1. Redistributions of source code must retain the above
12
 *      copyright notice, this list of conditions and the following
13
 *      disclaimer.
14
 *
15
 *   2. Redistributions in binary form must reproduce the above
16
 *      copyright notice, this list of conditions and the following
17
 *      disclaimer in the documentation and/or other materials
18
 *      provided with the distribution.
19
 *
20
 *
21
 * THIS SOFTWARE IS PROVIDED BY GRNET S.A. ``AS IS'' AND ANY EXPRESS
22
 * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
23
 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
24
 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL GRNET S.A OR
25
 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
26
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
27
 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
28
 * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
29
 * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
30
 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
31
 * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
32
 * POSSIBILITY OF SUCH DAMAGE.
33
 *
34
 * The views and conclusions contained in the software and
35
 * documentation are those of the authors and should not be
36
 * interpreted as representing official policies, either expressed
37
 * or implied, of GRNET S.A.
38
 * </copyright>
39
 * -----------------------------------------------------------------------
40
 */
41
#endregion
42
using System;
43
using System.Diagnostics.Contracts;
44
using System.IO;
45
using System.Threading;
46
using Pithos.Interfaces;
47
using Pithos.Network;
48

    
49
namespace Pithos.Core.Agents
50
{
51
    public enum CloudActionType
52
    {
53
        MustSynch,
54
        UploadUnconditional,
55
        DownloadUnconditional,
56
        DeleteLocal,
57
        DeleteCloud,
58
        RenameCloud,
59
        RenameLocal
60
    }
61

    
62
    public class CloudAction
63
    {
64
        public AccountInfo AccountInfo { get; set; }
65
        public CloudActionType Action { get; set; }
66
        public FileSystemInfo LocalFile { get; set; }
67
        public ObjectInfo CloudFile { get; set; }
68
        public FileState FileState { get; set; }
69
        public string Container { get; set; }
70

    
71
        public readonly DateTime Created = DateTime.Now;
72

    
73

    
74
        public Lazy<TreeHash> TreeHash { get; protected set; }
75
        //public Lazy<string> TopHash { get; set; }
76

    
77

    
78
        [ContractInvariantMethod]
79
        private void Invariants()
80
        {
81
            Contract.Invariant(AccountInfo!=null);
82
        }
83

    
84
        public bool IsShared
85
        {
86
            get { return  CloudFile!=null && AccountInfo.UserName != CloudFile.Account; }
87
        }
88

    
89
        protected CloudAction(AccountInfo accountInfo,CloudActionType action)
90
        {
91
            if (accountInfo==null)
92
                throw new ArgumentNullException("accountInfo");
93
            Contract.EndContractBlock();
94

    
95
            Action = action;
96
            AccountInfo = accountInfo;
97
        }
98

    
99
        public CloudAction(AccountInfo accountInfo, CloudActionType action, FileSystemInfo localFile, ObjectInfo cloudFile, FileState state, int blockSize, string algorithm)
100
            : this(accountInfo,action)
101
        {
102
            if(blockSize<=0)
103
                throw new ArgumentOutOfRangeException("blockSize");
104
            Contract.EndContractBlock();
105
            LocalFile = localFile.WithProperCapitalization();
106
            CloudFile = cloudFile;
107
            FileState = state;
108
            
109
            if (LocalFile == null) 
110
                return;
111

    
112
            TreeHash = new Lazy<TreeHash>(() => Signature.CalculateTreeHash(LocalFile, blockSize,algorithm),
113
                                            LazyThreadSafetyMode.ExecutionAndPublication);
114
        }
115

    
116
        //Calculate the download path for the cloud file
117
        public string GetDownloadPath()
118
        {
119
            if (CloudFile == null)
120
                return String.Empty;
121
            var filePath = CloudFile.RelativeUrlToFilePath(AccountInfo.UserName);
122
            return Path.Combine(AccountInfo.AccountPath, filePath);
123
        }
124

    
125
        public override string ToString()
126
        {
127
            return String.Format("{0}:{1}->{2}", Action, LocalFile.FullName, CloudFile.Name);
128
        }
129

    
130
        protected static ObjectInfo CreateObjectInfoFor(AccountInfo accountInfo, FileSystemInfo fileInfo)
131
        {
132
            if(accountInfo==null)
133
                throw new ArgumentNullException("accountInfo");
134
            if(fileInfo==null)
135
                throw new ArgumentNullException("fileInfo");
136
            Contract.Ensures(Contract.Result<ObjectInfo>()!=null);
137
            Contract.EndContractBlock();
138

    
139
            var capitalizedFileInfo = fileInfo.WithProperCapitalization();
140
            var fullLocalName = capitalizedFileInfo.FullName;
141
            var othersPath = Path.Combine(accountInfo.AccountPath, FolderConstants.OthersFolder);
142

    
143
            ObjectInfo objectInfo;
144

    
145
            var isShared = fullLocalName.StartsWith(othersPath, StringComparison.InvariantCultureIgnoreCase);
146
            if (isShared)
147
            {                
148
                var pathRelativeToOther = fullLocalName.Substring(othersPath.Length + 1);
149
                var otherParts = pathRelativeToOther.Split('\\');
150
                var otherName = otherParts[0];
151
                var otherContainer = otherParts[1];
152
                objectInfo=new ObjectInfo
153
                           {
154
                               Account = otherName, 
155
                               Container = otherContainer, 
156
                               Name = String.Join("/", otherParts.Splice(2))
157
                           };
158
            }
159
            else
160
                objectInfo=new ObjectInfo(accountInfo.AccountPath, accountInfo.UserName, fileInfo);
161
            
162
            objectInfo.Content_Type= (fileInfo is DirectoryInfo)
163
                                    ?   "appication/directory"
164
                                    :   "application/octet-stream";
165
            return objectInfo;
166
        }
167
    }    
168

    
169
    public class CloudDownloadAction:CloudAction
170
    {
171
        public CloudDownloadAction(AccountInfo accountInfo, ObjectInfo cloudFile)
172
            :base(accountInfo,CloudActionType.DownloadUnconditional)
173
        {            
174
            if (String.IsNullOrWhiteSpace(cloudFile.Container))
175
                throw new ArgumentException("CloudFile.Container","cloudFile");
176
            Contract.EndContractBlock();
177

    
178
            CloudFile = cloudFile;
179
        }
180

    
181
        [ContractInvariantMethod]
182
        private void Invariants()
183
        {
184
            Contract.Invariant(!String.IsNullOrWhiteSpace(CloudFile.Container));
185
        }
186

    
187
        public override string ToString()
188
        {
189
            return String.Format("{0}: _ <- {1}", Action, CloudFile.Name);
190
        }
191
        
192
    }
193
    public class CloudDeleteAction:CloudAction
194
    {
195
        public CloudDeleteAction(AccountInfo accountInfo,FileSystemInfo fileInfo, FileState fileState)
196
            : this(accountInfo,fileInfo,CreateObjectInfoFor(accountInfo, fileInfo),fileState)
197
        {            
198
        }
199

    
200
        public CloudDeleteAction(AccountInfo accountInfo, FileSystemInfo fileInfo,ObjectInfo cloudFile, FileState fileState) 
201
            : base(accountInfo,CloudActionType.DeleteCloud)
202
        {
203
            CloudFile = cloudFile;
204
            LocalFile = fileInfo;
205
            FileState = fileState;
206
        }
207

    
208
        public CloudDeleteAction(CloudAction action)
209
            : this(action.AccountInfo,action.LocalFile,action.CloudFile,action.FileState)
210
        {}
211

    
212
        [ContractInvariantMethod]
213
        private void Invariants()
214
        {
215
            Contract.Invariant(!String.IsNullOrWhiteSpace(CloudFile.Container));
216
        }
217

    
218
        public override string ToString()
219
        {
220
            return String.Format("{0}: _ ->{1}", Action, CloudFile.Name);
221
        }
222

    
223
    }
224

    
225
    public class CloudUploadAction:CloudAction
226
    {
227
        public CloudUploadAction(AccountInfo accountInfo, FileSystemInfo fileInfo, FileState state, int blockSize, string algorithm)
228
            : base(accountInfo, CloudActionType.UploadUnconditional,fileInfo,CreateObjectInfoFor(accountInfo,fileInfo),state,blockSize,algorithm)             
229
        {
230
        }
231

    
232
        [ContractInvariantMethod]
233
        private void Invariants()
234
        {
235
            Contract.Invariant(!String.IsNullOrWhiteSpace(CloudFile.Container));
236
        }
237

    
238
    }
239

    
240
    public class CloudMoveAction:CloudAction
241
    {
242
        public ObjectInfo OldCloudFile { get; set; }
243

    
244
        public FileSystemInfo OldLocalFile { get; set; }
245

    
246
        public CloudMoveAction(AccountInfo accountInfo, CloudActionType action, FileSystemInfo oldFile, FileSystemInfo newFile)
247
            :base(accountInfo,action)
248
        {
249
            LocalFile = newFile;
250
            CloudFile = CreateObjectInfoFor(accountInfo, newFile);
251
            
252
            OldLocalFile = oldFile;
253
            OldCloudFile = CreateObjectInfoFor(accountInfo, oldFile);
254

    
255
            //This is a rename operation, a hash will not be used
256
            TreeHash = new Lazy<TreeHash>(() => Network.TreeHash.Empty, LazyThreadSafetyMode.ExecutionAndPublication);
257
        }
258

    
259
        public override string ToString()
260
        {
261
            return String.Format("{0}:{1}->{2}", Action, OldCloudFile.Name, CloudFile.Name);
262
        }
263

    
264
    }
265

    
266
}