Statistics
| Branch: | Revision:

root / trunk / Pithos.Core / Agents / CloudTransferAction.cs @ 255f5f86

History | View | Annotate | Download (9 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
    }
60

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

    
70
        public readonly DateTime Created = DateTime.Now;
71

    
72

    
73
        public Lazy<string> LocalHash { get; protected set; }
74
        private Lazy<string> _topHash;
75
        public Lazy<string> TopHash
76
        {
77
            get { return _topHash; }
78
            set { _topHash = value; }
79
        }
80

    
81

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

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

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

    
99
            Action = action;
100
            AccountInfo = accountInfo;
101
        }
102

    
103
        public CloudAction(AccountInfo accountInfo, CloudActionType action, FileSystemInfo localFile, ObjectInfo cloudFile, FileState state, int blockSize, string algorithm)
104
            : this(accountInfo,action)
105
        {
106
            LocalFile = localFile.WithProperCapitalization();
107
            CloudFile = cloudFile;
108
            FileState = state;
109
            if (LocalFile != null)
110
            {
111

    
112
                LocalHash = new Lazy<string>(() => LocalFile.CalculateHash(blockSize,algorithm),
113
                                             LazyThreadSafetyMode.ExecutionAndPublication);
114
            }
115
        }
116

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

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

    
131
        protected static ObjectInfo CreateObjectInfoFor(AccountInfo accountInfo, FileSystemInfo fileInfo)
132
        {
133
            Contract.Requires(accountInfo!=null);
134
            Contract.Requires(fileInfo!=null);
135
            Contract.Ensures(Contract.Result<ObjectInfo>()!=null);
136

    
137
            var capitalizedFileInfo = fileInfo.WithProperCapitalization();
138
            var fullLocalName = capitalizedFileInfo.FullName;
139
            var othersPath = Path.Combine(accountInfo.AccountPath, FolderConstants.OthersFolder);
140
            
141
            var isShared = fullLocalName.StartsWith(othersPath, StringComparison.InvariantCultureIgnoreCase);
142
            if (isShared)
143
            {                
144
                var pathRelativeToOther = fullLocalName.Substring(othersPath.Length + 1);
145
                var otherParts = pathRelativeToOther.Split('\\');
146
                var otherName = otherParts[0];
147
                var otherContainer = otherParts[1];
148
                return new ObjectInfo
149
                           {
150
                               Account = otherName, 
151
                               Container = otherContainer, 
152
                               Name = String.Join("/", otherParts.Splice(2))
153
                           };
154
            }
155
            return new ObjectInfo(accountInfo.AccountPath, accountInfo.UserName, fileInfo);
156
        }
157
    }    
158

    
159
    public class CloudDownloadAction:CloudAction
160
    {
161
        public CloudDownloadAction(AccountInfo accountInfo, ObjectInfo cloudFile)
162
            :base(accountInfo,CloudActionType.DownloadUnconditional)
163
        {            
164
            if (String.IsNullOrWhiteSpace(cloudFile.Container))
165
                throw new ArgumentException("CloudFile.Container","cloudFile");
166
            Contract.EndContractBlock();
167

    
168
            CloudFile = cloudFile;
169
        }
170

    
171
        [ContractInvariantMethod]
172
        private void Invariants()
173
        {
174
            Contract.Invariant(!String.IsNullOrWhiteSpace(CloudFile.Container));
175
        }
176

    
177
        public override string ToString()
178
        {
179
            return String.Format("{0}: _ <- {1}", this.Action, this.CloudFile.Name);
180
        }
181
        
182
    }
183
    public class CloudDeleteAction:CloudAction
184
    {
185
        public CloudDeleteAction(AccountInfo accountInfo,FileSystemInfo fileInfo, FileState fileState)
186
            : this(accountInfo,fileInfo,CreateObjectInfoFor(accountInfo, fileInfo),fileState)
187
        {            
188
        }
189

    
190
        public CloudDeleteAction(AccountInfo accountInfo, FileSystemInfo fileInfo,ObjectInfo cloudFile, FileState fileState) 
191
            : base(accountInfo,CloudActionType.DeleteCloud)
192
        {
193
            CloudFile = cloudFile;
194
            LocalFile = fileInfo;
195
            FileState = fileState;
196
        }
197

    
198
        public CloudDeleteAction(CloudAction action)
199
            : this(action.AccountInfo,action.LocalFile,action.CloudFile,action.FileState)
200
        {}
201

    
202
        [ContractInvariantMethod]
203
        private void Invariants()
204
        {
205
            Contract.Invariant(!String.IsNullOrWhiteSpace(CloudFile.Container));
206
        }
207

    
208
        public override string ToString()
209
        {
210
            return String.Format("{0}: _ ->{1}", this.Action, this.CloudFile.Name);
211
        }
212

    
213
    }
214

    
215
    public class CloudUploadAction:CloudAction
216
    {
217
        public CloudUploadAction(AccountInfo accountInfo, FileSystemInfo fileInfo, FileState state, int blockSize, string algorithm)
218
            : base(accountInfo, CloudActionType.UploadUnconditional,fileInfo,CreateObjectInfoFor(accountInfo,fileInfo),state,blockSize,algorithm)             
219
        {
220
        }
221

    
222
        [ContractInvariantMethod]
223
        private void Invariants()
224
        {
225
            Contract.Invariant(!String.IsNullOrWhiteSpace(CloudFile.Container));
226
        }
227

    
228
    }
229

    
230
    public class CloudMoveAction:CloudAction
231
    {
232
        public ObjectInfo OldCloudFile { get; set; }
233

    
234
        public FileSystemInfo OldLocalFile { get; set; }
235

    
236
        public CloudMoveAction(AccountInfo accountInfo, CloudActionType action, FileSystemInfo oldFile, FileSystemInfo newFile)
237
            :base(accountInfo,action)
238
        {
239
            LocalFile = newFile;
240
            CloudFile = CreateObjectInfoFor(accountInfo, newFile);
241
            
242
            OldLocalFile = oldFile;
243
            OldCloudFile = CreateObjectInfoFor(accountInfo, oldFile);
244

    
245
            //This is a rename operation, a hash will not be used
246
            LocalHash = new Lazy<string>(() => String.Empty, LazyThreadSafetyMode.ExecutionAndPublication);
247
        }
248

    
249
        public override string ToString()
250
        {
251
            return String.Format("{0}:{1}->{2}", this.Action, OldCloudFile.Name, CloudFile.Name);
252
        }
253

    
254
    }
255

    
256
}