Statistics
| Branch: | Revision:

root / trunk / Pithos.Core / Agents / CloudTransferAction.cs @ 43dd02a8

History | View | Annotate | Download (9.7 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

    
65
        public object Originator { get; set; }
66
        public AccountInfo AccountInfo { get; set; }
67
        public CloudActionType Action { get; set; }
68
        public FileSystemInfo LocalFile { get; set; }
69
        public ObjectInfo CloudFile { get; set; }
70
        public FileState FileState { get; set; }
71
        public string Container { get; set; }
72

    
73
        public readonly DateTime Created = DateTime.Now;
74

    
75

    
76
        public Lazy<TreeHash> TreeHash { get; protected set; }
77
        //public Lazy<string> TopHash { get; set; }
78

    
79

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

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

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

    
97
            Action = action;
98
            AccountInfo = accountInfo;
99
            Originator = originator;
100
        }
101

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

    
115
            TreeHash = new Lazy<TreeHash>(() => Signature.CalculateTreeHash(LocalFile, blockSize,algorithm),
116
                                            LazyThreadSafetyMode.ExecutionAndPublication);
117
        }
118

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

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

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

    
142
            var capitalizedFileInfo = fileInfo.WithProperCapitalization();
143
            var fullLocalName = capitalizedFileInfo.FullName;
144
            var othersPath = Path.Combine(accountInfo.AccountPath, FolderConstants.OthersFolder);
145

    
146
            ObjectInfo objectInfo;
147

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

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

    
181
            CloudFile = cloudFile;
182
        }
183

    
184
        [ContractInvariantMethod]
185
        private void Invariants()
186
        {
187
            Contract.Invariant(!String.IsNullOrWhiteSpace(CloudFile.Container));
188
        }
189

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

    
203
        public CloudDeleteAction(AccountInfo accountInfo, FileSystemInfo fileInfo,ObjectInfo cloudFile, FileState fileState,object originator) 
204
            : base(accountInfo,CloudActionType.DeleteCloud,originator)
205
        {
206
            CloudFile = cloudFile;
207
            LocalFile = fileInfo;
208
            FileState = fileState;
209
        }
210

    
211
        public CloudDeleteAction(CloudAction action)
212
            : this(action.AccountInfo,action.LocalFile,action.CloudFile,action.FileState,action)
213
        {}
214

    
215
        [ContractInvariantMethod]
216
        private void Invariants()
217
        {
218
            Contract.Invariant(!String.IsNullOrWhiteSpace(CloudFile.Container));
219
        }
220

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

    
226
    }
227

    
228
    public class CloudUploadAction:CloudAction
229
    {
230
        public CloudUploadAction(AccountInfo accountInfo, FileSystemInfo fileInfo, FileState state, int blockSize, string algorithm,object originator)
231
            : base(accountInfo, CloudActionType.UploadUnconditional,fileInfo,CreateObjectInfoFor(accountInfo,fileInfo),state,blockSize,algorithm,originator)             
232
        {
233
        }
234

    
235
        [ContractInvariantMethod]
236
        private void Invariants()
237
        {
238
            Contract.Invariant(!String.IsNullOrWhiteSpace(CloudFile.Container));
239
        }
240

    
241
    }
242

    
243
    public class CloudMoveAction:CloudAction
244
    {
245
        public ObjectInfo OldCloudFile { get; set; }
246

    
247
        public FileSystemInfo OldLocalFile { get; set; }
248

    
249
        public CloudMoveAction(AccountInfo accountInfo, CloudActionType action, FileSystemInfo oldFile, FileSystemInfo newFile,object originator)
250
            :base(accountInfo,action,originator)
251
        {
252
            LocalFile = newFile;
253
            CloudFile = CreateObjectInfoFor(accountInfo, newFile);
254
            
255
            OldLocalFile = oldFile;
256
            OldCloudFile = CreateObjectInfoFor(accountInfo, oldFile);
257

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

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

    
267
    }
268

    
269
}