root / trunk / Pithos.Core / Agents / FileAgent.cs @ 025046f1
History | View | Annotate | Download (15.1 kB)
1 | 9c4346c9 | Panagiotis Kanavos | using System; |
---|---|---|---|
2 | 9c4346c9 | Panagiotis Kanavos | using System.Collections.Generic; |
3 | 9c4346c9 | Panagiotis Kanavos | using System.ComponentModel.Composition; |
4 | 9c4346c9 | Panagiotis Kanavos | using System.Diagnostics; |
5 | bfc13ed8 | Panagiotis Kanavos | using System.Diagnostics.Contracts; |
6 | 9c4346c9 | Panagiotis Kanavos | using System.IO; |
7 | 9c4346c9 | Panagiotis Kanavos | using System.Linq; |
8 | 9c4346c9 | Panagiotis Kanavos | using System.Text; |
9 | a64c87c8 | Panagiotis Kanavos | using System.Threading.Tasks; |
10 | 9c4346c9 | Panagiotis Kanavos | using Pithos.Interfaces; |
11 | 1caef52e | Panagiotis Kanavos | using Pithos.Network; |
12 | 5120f3cb | Panagiotis Kanavos | using log4net; |
13 | 5120f3cb | Panagiotis Kanavos | using log4net.Core; |
14 | 9c4346c9 | Panagiotis Kanavos | |
15 | 9c4346c9 | Panagiotis Kanavos | namespace Pithos.Core.Agents |
16 | 9c4346c9 | Panagiotis Kanavos | { |
17 | 4ec636f6 | Panagiotis Kanavos | // [Export] |
18 | 1caef52e | Panagiotis Kanavos | public class FileAgent |
19 | 9c4346c9 | Panagiotis Kanavos | { |
20 | 4ec636f6 | Panagiotis Kanavos | Agent<WorkflowState> _agent; |
21 | 9c4346c9 | Panagiotis Kanavos | private FileSystemWatcher _watcher; |
22 | 78ebfd2d | Panagiotis Kanavos | private FileSystemWatcherAdapter _adapter; |
23 | 9c4346c9 | Panagiotis Kanavos | |
24 | 4ec636f6 | Panagiotis Kanavos | //[Import] |
25 | 9c4346c9 | Panagiotis Kanavos | public IStatusKeeper StatusKeeper { get; set; } |
26 | 4ec636f6 | Panagiotis Kanavos | //[Import] |
27 | 9c4346c9 | Panagiotis Kanavos | public IPithosWorkflow Workflow { get; set; } |
28 | 4ec636f6 | Panagiotis Kanavos | //[Import] |
29 | 9c4346c9 | Panagiotis Kanavos | public WorkflowAgent WorkflowAgent { get; set; } |
30 | 9c4346c9 | Panagiotis Kanavos | |
31 | c53aa229 | Panagiotis Kanavos | private AccountInfo AccountInfo { get; set; } |
32 | c53aa229 | Panagiotis Kanavos | |
33 | c53aa229 | Panagiotis Kanavos | private string RootPath { get; set; } |
34 | 1caef52e | Panagiotis Kanavos | |
35 | 5120f3cb | Panagiotis Kanavos | private static readonly ILog Log = LogManager.GetLogger("FileAgent"); |
36 | cfed7823 | Panagiotis Kanavos | |
37 | 4ec636f6 | Panagiotis Kanavos | public void Start(AccountInfo accountInfo,string rootPath) |
38 | 9c4346c9 | Panagiotis Kanavos | { |
39 | 4ec636f6 | Panagiotis Kanavos | if (accountInfo==null) |
40 | 4ec636f6 | Panagiotis Kanavos | throw new ArgumentNullException("accountInfo"); |
41 | 4ec636f6 | Panagiotis Kanavos | if (String.IsNullOrWhiteSpace(rootPath)) |
42 | 4ec636f6 | Panagiotis Kanavos | throw new ArgumentNullException("rootPath"); |
43 | 4ec636f6 | Panagiotis Kanavos | if (!Path.IsPathRooted(rootPath)) |
44 | 4ec636f6 | Panagiotis Kanavos | throw new ArgumentException("rootPath must be an absolute path","rootPath"); |
45 | 4ec636f6 | Panagiotis Kanavos | Contract.EndContractBlock(); |
46 | 4ec636f6 | Panagiotis Kanavos | |
47 | 4ec636f6 | Panagiotis Kanavos | AccountInfo = accountInfo; |
48 | 4ec636f6 | Panagiotis Kanavos | RootPath = rootPath; |
49 | 78ebfd2d | Panagiotis Kanavos | _watcher = new FileSystemWatcher(rootPath) {IncludeSubdirectories = true}; |
50 | 78ebfd2d | Panagiotis Kanavos | _adapter = new FileSystemWatcherAdapter(_watcher); |
51 | 78ebfd2d | Panagiotis Kanavos | |
52 | 78ebfd2d | Panagiotis Kanavos | _adapter.Changed += OnFileEvent; |
53 | 78ebfd2d | Panagiotis Kanavos | _adapter.Created += OnFileEvent; |
54 | 78ebfd2d | Panagiotis Kanavos | _adapter.Deleted += OnFileEvent; |
55 | 78ebfd2d | Panagiotis Kanavos | _adapter.Renamed += OnRenameEvent; |
56 | 78ebfd2d | Panagiotis Kanavos | _adapter.Moved += OnMoveEvent; |
57 | 4ec636f6 | Panagiotis Kanavos | _watcher.EnableRaisingEvents = true; |
58 | 4ec636f6 | Panagiotis Kanavos | |
59 | 4ec636f6 | Panagiotis Kanavos | |
60 | 4ec636f6 | Panagiotis Kanavos | _agent = Agent<WorkflowState>.Start(inbox => |
61 | 4ec636f6 | Panagiotis Kanavos | { |
62 | 4ec636f6 | Panagiotis Kanavos | Action loop = null; |
63 | 4ec636f6 | Panagiotis Kanavos | loop = () => |
64 | 4ec636f6 | Panagiotis Kanavos | { |
65 | 4ec636f6 | Panagiotis Kanavos | var message = inbox.Receive(); |
66 | 4ec636f6 | Panagiotis Kanavos | var process=message.Then(Process,inbox.CancellationToken); |
67 | 4ec636f6 | Panagiotis Kanavos | |
68 | 4ec636f6 | Panagiotis Kanavos | inbox.LoopAsync(process,loop,ex=> |
69 | 4ec636f6 | Panagiotis Kanavos | Log.ErrorFormat("[ERROR] File Event Processing:\r{0}", ex)); |
70 | 4ec636f6 | Panagiotis Kanavos | }; |
71 | 4ec636f6 | Panagiotis Kanavos | loop(); |
72 | 4ec636f6 | Panagiotis Kanavos | }); |
73 | 9c4346c9 | Panagiotis Kanavos | } |
74 | 9c4346c9 | Panagiotis Kanavos | |
75 | 4ec636f6 | Panagiotis Kanavos | private Task<object> Process(WorkflowState state) |
76 | a64c87c8 | Panagiotis Kanavos | { |
77 | 4ec636f6 | Panagiotis Kanavos | if (state==null) |
78 | 4ec636f6 | Panagiotis Kanavos | throw new ArgumentNullException("state"); |
79 | 4ec636f6 | Panagiotis Kanavos | Contract.EndContractBlock(); |
80 | 4ec636f6 | Panagiotis Kanavos | |
81 | 4f6d51d4 | Panagiotis Kanavos | if (Ignore(state.Path)) |
82 | 4f6d51d4 | Panagiotis Kanavos | return CompletedTask<object>.Default; |
83 | 4ec636f6 | Panagiotis Kanavos | |
84 | 4ec636f6 | Panagiotis Kanavos | var networkState = NetworkGate.GetNetworkState(state.Path); |
85 | 4ec636f6 | Panagiotis Kanavos | //Skip if the file is already being downloaded or uploaded and |
86 | 4ec636f6 | Panagiotis Kanavos | //the change is create or modify |
87 | 4ec636f6 | Panagiotis Kanavos | if (networkState != NetworkOperation.None && |
88 | 4ec636f6 | Panagiotis Kanavos | ( |
89 | 4ec636f6 | Panagiotis Kanavos | state.TriggeringChange == WatcherChangeTypes.Created || |
90 | 4ec636f6 | Panagiotis Kanavos | state.TriggeringChange == WatcherChangeTypes.Changed |
91 | 4ec636f6 | Panagiotis Kanavos | )) |
92 | 4ec636f6 | Panagiotis Kanavos | return CompletedTask<object>.Default; |
93 | a64c87c8 | Panagiotis Kanavos | |
94 | a64c87c8 | Panagiotis Kanavos | try |
95 | a64c87c8 | Panagiotis Kanavos | { |
96 | 4ec636f6 | Panagiotis Kanavos | UpdateFileStatus(state); |
97 | 4ec636f6 | Panagiotis Kanavos | UpdateOverlayStatus(state); |
98 | 4ec636f6 | Panagiotis Kanavos | UpdateFileChecksum(state); |
99 | 4ec636f6 | Panagiotis Kanavos | WorkflowAgent.Post(state); |
100 | a64c87c8 | Panagiotis Kanavos | } |
101 | a64c87c8 | Panagiotis Kanavos | catch (IOException exc) |
102 | a64c87c8 | Panagiotis Kanavos | { |
103 | 4ec636f6 | Panagiotis Kanavos | if (File.Exists(state.Path)) |
104 | 0af3141d | Panagiotis Kanavos | { |
105 | 4ec636f6 | Panagiotis Kanavos | Log.WarnFormat("File access error occured, retrying {0}\n{1}", state.Path, exc); |
106 | 4ec636f6 | Panagiotis Kanavos | _agent.Post(state); |
107 | 0af3141d | Panagiotis Kanavos | } |
108 | 0af3141d | Panagiotis Kanavos | else |
109 | 0af3141d | Panagiotis Kanavos | { |
110 | 4ec636f6 | Panagiotis Kanavos | Log.WarnFormat("File {0} does not exist. Will be ignored\n{1}", state.Path, exc); |
111 | 0af3141d | Panagiotis Kanavos | } |
112 | a64c87c8 | Panagiotis Kanavos | } |
113 | a64c87c8 | Panagiotis Kanavos | catch (Exception exc) |
114 | a64c87c8 | Panagiotis Kanavos | { |
115 | 4ec636f6 | Panagiotis Kanavos | Log.WarnFormat("Error occured while indexing{0}. The file will be skipped\n{1}", |
116 | 4ec636f6 | Panagiotis Kanavos | state.Path, exc); |
117 | a64c87c8 | Panagiotis Kanavos | } |
118 | 4ec636f6 | Panagiotis Kanavos | return CompletedTask<object>.Default; |
119 | 5e31048f | Panagiotis Kanavos | } |
120 | a64c87c8 | Panagiotis Kanavos | |
121 | 9c4346c9 | Panagiotis Kanavos | public bool Pause |
122 | 9c4346c9 | Panagiotis Kanavos | { |
123 | 9c4346c9 | Panagiotis Kanavos | get { return _watcher == null || !_watcher.EnableRaisingEvents; } |
124 | 9c4346c9 | Panagiotis Kanavos | set |
125 | 9c4346c9 | Panagiotis Kanavos | { |
126 | 9c4346c9 | Panagiotis Kanavos | if (_watcher != null) |
127 | 9c4346c9 | Panagiotis Kanavos | _watcher.EnableRaisingEvents = !value; |
128 | 9c4346c9 | Panagiotis Kanavos | } |
129 | 9c4346c9 | Panagiotis Kanavos | } |
130 | 9c4346c9 | Panagiotis Kanavos | |
131 | 77e10b4f | Panagiotis Kanavos | public string CachePath { get; set; } |
132 | 1caef52e | Panagiotis Kanavos | |
133 | d3a13891 | Panagiotis Kanavos | private List<string> _selectivePaths = new List<string>(); |
134 | d3a13891 | Panagiotis Kanavos | public List<string> SelectivePaths |
135 | d3a13891 | Panagiotis Kanavos | { |
136 | d3a13891 | Panagiotis Kanavos | get { return _selectivePaths; } |
137 | d3a13891 | Panagiotis Kanavos | set { _selectivePaths = value; } |
138 | d3a13891 | Panagiotis Kanavos | } |
139 | d3a13891 | Panagiotis Kanavos | |
140 | d3a13891 | Panagiotis Kanavos | |
141 | 9c4346c9 | Panagiotis Kanavos | public void Post(WorkflowState workflowState) |
142 | 9c4346c9 | Panagiotis Kanavos | { |
143 | cfed7823 | Panagiotis Kanavos | if (workflowState == null) |
144 | cfed7823 | Panagiotis Kanavos | throw new ArgumentNullException("workflowState"); |
145 | cfed7823 | Panagiotis Kanavos | Contract.EndContractBlock(); |
146 | cfed7823 | Panagiotis Kanavos | |
147 | 9c4346c9 | Panagiotis Kanavos | _agent.Post(workflowState); |
148 | 9c4346c9 | Panagiotis Kanavos | } |
149 | 9c4346c9 | Panagiotis Kanavos | |
150 | 9c4346c9 | Panagiotis Kanavos | public void Stop() |
151 | 9c4346c9 | Panagiotis Kanavos | { |
152 | 9c4346c9 | Panagiotis Kanavos | if (_watcher != null) |
153 | 9c4346c9 | Panagiotis Kanavos | { |
154 | 9c4346c9 | Panagiotis Kanavos | _watcher.Changed -= OnFileEvent; |
155 | 9c4346c9 | Panagiotis Kanavos | _watcher.Created -= OnFileEvent; |
156 | 9c4346c9 | Panagiotis Kanavos | _watcher.Deleted -= OnFileEvent; |
157 | 9c4346c9 | Panagiotis Kanavos | _watcher.Renamed -= OnRenameEvent; |
158 | 9c4346c9 | Panagiotis Kanavos | _watcher.Dispose(); |
159 | 9c4346c9 | Panagiotis Kanavos | } |
160 | 9c4346c9 | Panagiotis Kanavos | _watcher = null; |
161 | 9c4346c9 | Panagiotis Kanavos | |
162 | cfed7823 | Panagiotis Kanavos | if (_agent!=null) |
163 | 4ec636f6 | Panagiotis Kanavos | _agent.Stop(); |
164 | 9c4346c9 | Panagiotis Kanavos | } |
165 | 9c4346c9 | Panagiotis Kanavos | |
166 | 1caef52e | Panagiotis Kanavos | // Enumerate all files in the Pithos directory except those in the Fragment folder |
167 | 1caef52e | Panagiotis Kanavos | // and files with a .ignore extension |
168 | 1caef52e | Panagiotis Kanavos | public IEnumerable<string> EnumerateFiles(string searchPattern="*") |
169 | 1caef52e | Panagiotis Kanavos | { |
170 | 1caef52e | Panagiotis Kanavos | var monitoredFiles = from filePath in Directory.EnumerateFileSystemEntries(RootPath, searchPattern, SearchOption.AllDirectories) |
171 | 1caef52e | Panagiotis Kanavos | where !Ignore(filePath) |
172 | 1caef52e | Panagiotis Kanavos | select filePath; |
173 | 1caef52e | Panagiotis Kanavos | return monitoredFiles; |
174 | 1caef52e | Panagiotis Kanavos | } |
175 | 1caef52e | Panagiotis Kanavos | |
176 | 1caef52e | Panagiotis Kanavos | public IEnumerable<FileInfo> EnumerateFileInfos(string searchPattern="*") |
177 | 1caef52e | Panagiotis Kanavos | { |
178 | 1caef52e | Panagiotis Kanavos | var rootDir = new DirectoryInfo(RootPath); |
179 | 1caef52e | Panagiotis Kanavos | var monitoredFiles = from file in rootDir.EnumerateFiles(searchPattern, SearchOption.AllDirectories) |
180 | 1caef52e | Panagiotis Kanavos | where !Ignore(file.FullName) |
181 | 1caef52e | Panagiotis Kanavos | select file; |
182 | 1caef52e | Panagiotis Kanavos | return monitoredFiles; |
183 | 1caef52e | Panagiotis Kanavos | } |
184 | 1caef52e | Panagiotis Kanavos | |
185 | 1caef52e | Panagiotis Kanavos | public IEnumerable<string> EnumerateFilesAsRelativeUrls(string searchPattern="*") |
186 | 1caef52e | Panagiotis Kanavos | { |
187 | 1caef52e | Panagiotis Kanavos | var rootDir = new DirectoryInfo(RootPath); |
188 | 1caef52e | Panagiotis Kanavos | var monitoredFiles = from file in rootDir.EnumerateFiles(searchPattern, SearchOption.AllDirectories) |
189 | 1caef52e | Panagiotis Kanavos | where !Ignore(file.FullName) |
190 | 1caef52e | Panagiotis Kanavos | select file.AsRelativeUrlTo(RootPath); |
191 | 1caef52e | Panagiotis Kanavos | return monitoredFiles; |
192 | 1caef52e | Panagiotis Kanavos | } |
193 | 1caef52e | Panagiotis Kanavos | |
194 | 540b8cf8 | Panagiotis Kanavos | public IEnumerable<string> EnumerateFilesSystemInfosAsRelativeUrls(string searchPattern="*") |
195 | 540b8cf8 | Panagiotis Kanavos | { |
196 | 540b8cf8 | Panagiotis Kanavos | var rootDir = new DirectoryInfo(RootPath); |
197 | 540b8cf8 | Panagiotis Kanavos | var monitoredFiles = from file in rootDir.EnumerateFileSystemInfos(searchPattern, SearchOption.AllDirectories) |
198 | 540b8cf8 | Panagiotis Kanavos | where !Ignore(file.FullName) |
199 | 540b8cf8 | Panagiotis Kanavos | select file.AsRelativeUrlTo(RootPath); |
200 | 540b8cf8 | Panagiotis Kanavos | return monitoredFiles; |
201 | 540b8cf8 | Panagiotis Kanavos | } |
202 | 540b8cf8 | Panagiotis Kanavos | |
203 | 1caef52e | Panagiotis Kanavos | |
204 | 1caef52e | Panagiotis Kanavos | |
205 | 1caef52e | Panagiotis Kanavos | |
206 | 1caef52e | Panagiotis Kanavos | private bool Ignore(string filePath) |
207 | 1caef52e | Panagiotis Kanavos | { |
208 | 4f6d51d4 | Panagiotis Kanavos | var pithosPath = Path.Combine(RootPath, "pithos"); |
209 | 4f6d51d4 | Panagiotis Kanavos | if (pithosPath.Equals(filePath, StringComparison.InvariantCultureIgnoreCase)) |
210 | 4f6d51d4 | Panagiotis Kanavos | return true; |
211 | 77e10b4f | Panagiotis Kanavos | if (filePath.StartsWith(CachePath)) |
212 | 1caef52e | Panagiotis Kanavos | return true; |
213 | 0af3141d | Panagiotis Kanavos | if (_ignoreFiles.ContainsKey(filePath.ToLower())) |
214 | 0af3141d | Panagiotis Kanavos | return true; |
215 | 1caef52e | Panagiotis Kanavos | return false; |
216 | 1caef52e | Panagiotis Kanavos | } |
217 | 1caef52e | Panagiotis Kanavos | |
218 | 1caef52e | Panagiotis Kanavos | //Post a Change message for all events except rename |
219 | 9c4346c9 | Panagiotis Kanavos | void OnFileEvent(object sender, FileSystemEventArgs e) |
220 | 9c4346c9 | Panagiotis Kanavos | { |
221 | 77e10b4f | Panagiotis Kanavos | //Ignore events that affect the cache folder |
222 | 1caef52e | Panagiotis Kanavos | var filePath = e.FullPath; |
223 | 1caef52e | Panagiotis Kanavos | if (Ignore(filePath)) |
224 | a0dcfcc9 | Panagiotis Kanavos | return; |
225 | 3c76f045 | Panagiotis Kanavos | |
226 | 1bfc38f1 | Panagiotis Kanavos | _agent.Post(new WorkflowState{AccountInfo=AccountInfo, Path = filePath, FileName = e.Name, TriggeringChange = e.ChangeType }); |
227 | 9c4346c9 | Panagiotis Kanavos | } |
228 | 9c4346c9 | Panagiotis Kanavos | |
229 | 1caef52e | Panagiotis Kanavos | |
230 | 1caef52e | Panagiotis Kanavos | //Post a Change message for renames containing the old and new names |
231 | 9c4346c9 | Panagiotis Kanavos | void OnRenameEvent(object sender, RenamedEventArgs e) |
232 | 9c4346c9 | Panagiotis Kanavos | { |
233 | 1caef52e | Panagiotis Kanavos | var oldFullPath = e.OldFullPath; |
234 | 1caef52e | Panagiotis Kanavos | var fullPath = e.FullPath; |
235 | 1caef52e | Panagiotis Kanavos | if (Ignore(oldFullPath) || Ignore(fullPath)) |
236 | 1caef52e | Panagiotis Kanavos | return; |
237 | 1caef52e | Panagiotis Kanavos | |
238 | 1bfc38f1 | Panagiotis Kanavos | _agent.Post(new WorkflowState |
239 | 9c4346c9 | Panagiotis Kanavos | { |
240 | 1bfc38f1 | Panagiotis Kanavos | AccountInfo=AccountInfo, |
241 | 1caef52e | Panagiotis Kanavos | OldPath = oldFullPath, |
242 | 9c4346c9 | Panagiotis Kanavos | OldFileName = e.OldName, |
243 | 1caef52e | Panagiotis Kanavos | Path = fullPath, |
244 | 9c4346c9 | Panagiotis Kanavos | FileName = e.Name, |
245 | 78ebfd2d | Panagiotis Kanavos | TriggeringChange = e.ChangeType |
246 | 78ebfd2d | Panagiotis Kanavos | }); |
247 | 78ebfd2d | Panagiotis Kanavos | } |
248 | 78ebfd2d | Panagiotis Kanavos | |
249 | 78ebfd2d | Panagiotis Kanavos | //Post a Change message for renames containing the old and new names |
250 | 78ebfd2d | Panagiotis Kanavos | void OnMoveEvent(object sender, MovedEventArgs e) |
251 | 78ebfd2d | Panagiotis Kanavos | { |
252 | 78ebfd2d | Panagiotis Kanavos | var oldFullPath = e.OldFullPath; |
253 | 78ebfd2d | Panagiotis Kanavos | var fullPath = e.FullPath; |
254 | 78ebfd2d | Panagiotis Kanavos | if (Ignore(oldFullPath) || Ignore(fullPath)) |
255 | 78ebfd2d | Panagiotis Kanavos | return; |
256 | 78ebfd2d | Panagiotis Kanavos | |
257 | 78ebfd2d | Panagiotis Kanavos | _agent.Post(new WorkflowState |
258 | 78ebfd2d | Panagiotis Kanavos | { |
259 | 78ebfd2d | Panagiotis Kanavos | AccountInfo=AccountInfo, |
260 | 78ebfd2d | Panagiotis Kanavos | OldPath = oldFullPath, |
261 | 78ebfd2d | Panagiotis Kanavos | OldFileName = e.OldName, |
262 | 78ebfd2d | Panagiotis Kanavos | Path = fullPath, |
263 | 78ebfd2d | Panagiotis Kanavos | FileName = e.Name, |
264 | 9c4346c9 | Panagiotis Kanavos | TriggeringChange = e.ChangeType |
265 | 9c4346c9 | Panagiotis Kanavos | }); |
266 | 9c4346c9 | Panagiotis Kanavos | } |
267 | 9c4346c9 | Panagiotis Kanavos | |
268 | 9c4346c9 | Panagiotis Kanavos | |
269 | 9c4346c9 | Panagiotis Kanavos | |
270 | 9c4346c9 | Panagiotis Kanavos | private Dictionary<WatcherChangeTypes, FileStatus> _statusDict = new Dictionary<WatcherChangeTypes, FileStatus> |
271 | 9c4346c9 | Panagiotis Kanavos | { |
272 | 9c4346c9 | Panagiotis Kanavos | {WatcherChangeTypes.Created,FileStatus.Created}, |
273 | 9c4346c9 | Panagiotis Kanavos | {WatcherChangeTypes.Changed,FileStatus.Modified}, |
274 | 9c4346c9 | Panagiotis Kanavos | {WatcherChangeTypes.Deleted,FileStatus.Deleted}, |
275 | 9c4346c9 | Panagiotis Kanavos | {WatcherChangeTypes.Renamed,FileStatus.Renamed} |
276 | 9c4346c9 | Panagiotis Kanavos | }; |
277 | 9c4346c9 | Panagiotis Kanavos | |
278 | 0af3141d | Panagiotis Kanavos | private Dictionary<string,string> _ignoreFiles=new Dictionary<string, string>(); |
279 | 0af3141d | Panagiotis Kanavos | |
280 | 9c4346c9 | Panagiotis Kanavos | private WorkflowState UpdateFileStatus(WorkflowState state) |
281 | 9c4346c9 | Panagiotis Kanavos | { |
282 | cfed7823 | Panagiotis Kanavos | if (state==null) |
283 | cfed7823 | Panagiotis Kanavos | throw new ArgumentNullException("state"); |
284 | cfed7823 | Panagiotis Kanavos | if (String.IsNullOrWhiteSpace(state.Path)) |
285 | cfed7823 | Panagiotis Kanavos | throw new ArgumentException("The state's Path can't be empty","state"); |
286 | cfed7823 | Panagiotis Kanavos | Contract.EndContractBlock(); |
287 | 1caef52e | Panagiotis Kanavos | |
288 | cfed7823 | Panagiotis Kanavos | var path = state.Path; |
289 | cfed7823 | Panagiotis Kanavos | var status = _statusDict[state.TriggeringChange]; |
290 | 9c4346c9 | Panagiotis Kanavos | var oldStatus = Workflow.StatusKeeper.GetFileStatus(path); |
291 | 9c4346c9 | Panagiotis Kanavos | if (status == oldStatus) |
292 | 9c4346c9 | Panagiotis Kanavos | { |
293 | 9c4346c9 | Panagiotis Kanavos | state.Status = status; |
294 | 9c4346c9 | Panagiotis Kanavos | state.Skip = true; |
295 | 9c4346c9 | Panagiotis Kanavos | return state; |
296 | 9c4346c9 | Panagiotis Kanavos | } |
297 | 9c4346c9 | Panagiotis Kanavos | if (state.Status == FileStatus.Renamed) |
298 | 9c4346c9 | Panagiotis Kanavos | Workflow.ClearFileStatus(path); |
299 | 9c4346c9 | Panagiotis Kanavos | |
300 | 9c4346c9 | Panagiotis Kanavos | state.Status = Workflow.SetFileStatus(path, status); |
301 | 9c4346c9 | Panagiotis Kanavos | return state; |
302 | 9c4346c9 | Panagiotis Kanavos | } |
303 | 9c4346c9 | Panagiotis Kanavos | |
304 | 9c4346c9 | Panagiotis Kanavos | private WorkflowState UpdateOverlayStatus(WorkflowState state) |
305 | 9c4346c9 | Panagiotis Kanavos | { |
306 | cfed7823 | Panagiotis Kanavos | if (state==null) |
307 | cfed7823 | Panagiotis Kanavos | throw new ArgumentNullException("state"); |
308 | cfed7823 | Panagiotis Kanavos | Contract.EndContractBlock(); |
309 | cfed7823 | Panagiotis Kanavos | |
310 | 9c4346c9 | Panagiotis Kanavos | if (state.Skip) |
311 | 9c4346c9 | Panagiotis Kanavos | return state; |
312 | 9c4346c9 | Panagiotis Kanavos | |
313 | 9c4346c9 | Panagiotis Kanavos | switch (state.Status) |
314 | 9c4346c9 | Panagiotis Kanavos | { |
315 | 9c4346c9 | Panagiotis Kanavos | case FileStatus.Created: |
316 | 9c4346c9 | Panagiotis Kanavos | case FileStatus.Modified: |
317 | 9c4346c9 | Panagiotis Kanavos | this.StatusKeeper.SetFileOverlayStatus(state.Path, FileOverlayStatus.Modified); |
318 | 9c4346c9 | Panagiotis Kanavos | break; |
319 | 9c4346c9 | Panagiotis Kanavos | case FileStatus.Deleted: |
320 | cfed7823 | Panagiotis Kanavos | //this.StatusAgent.RemoveFileOverlayStatus(state.Path); |
321 | 9c4346c9 | Panagiotis Kanavos | break; |
322 | 9c4346c9 | Panagiotis Kanavos | case FileStatus.Renamed: |
323 | cfed7823 | Panagiotis Kanavos | this.StatusKeeper.ClearFileStatus(state.OldPath); |
324 | 9c4346c9 | Panagiotis Kanavos | this.StatusKeeper.SetFileOverlayStatus(state.Path, FileOverlayStatus.Modified); |
325 | 9c4346c9 | Panagiotis Kanavos | break; |
326 | 9c4346c9 | Panagiotis Kanavos | case FileStatus.Unchanged: |
327 | 9c4346c9 | Panagiotis Kanavos | this.StatusKeeper.SetFileOverlayStatus(state.Path, FileOverlayStatus.Normal); |
328 | 9c4346c9 | Panagiotis Kanavos | break; |
329 | 9c4346c9 | Panagiotis Kanavos | } |
330 | 9c4346c9 | Panagiotis Kanavos | |
331 | 9c4346c9 | Panagiotis Kanavos | if (state.Status == FileStatus.Deleted) |
332 | 1caef52e | Panagiotis Kanavos | NativeMethods.RaiseChangeNotification(Path.GetDirectoryName(state.Path)); |
333 | 9c4346c9 | Panagiotis Kanavos | else |
334 | 1caef52e | Panagiotis Kanavos | NativeMethods.RaiseChangeNotification(state.Path); |
335 | 9c4346c9 | Panagiotis Kanavos | return state; |
336 | 9c4346c9 | Panagiotis Kanavos | } |
337 | 9c4346c9 | Panagiotis Kanavos | |
338 | 9c4346c9 | Panagiotis Kanavos | |
339 | 9c4346c9 | Panagiotis Kanavos | private WorkflowState UpdateFileChecksum(WorkflowState state) |
340 | 9c4346c9 | Panagiotis Kanavos | { |
341 | 9c4346c9 | Panagiotis Kanavos | if (state.Skip) |
342 | 9c4346c9 | Panagiotis Kanavos | return state; |
343 | 9c4346c9 | Panagiotis Kanavos | |
344 | 9c4346c9 | Panagiotis Kanavos | if (state.Status == FileStatus.Deleted) |
345 | 9c4346c9 | Panagiotis Kanavos | return state; |
346 | 9c4346c9 | Panagiotis Kanavos | |
347 | 1caef52e | Panagiotis Kanavos | var path = state.Path; |
348 | 1caef52e | Panagiotis Kanavos | //Skip calculation for folders |
349 | 1caef52e | Panagiotis Kanavos | if (Directory.Exists(path)) |
350 | 1caef52e | Panagiotis Kanavos | return state; |
351 | 1caef52e | Panagiotis Kanavos | |
352 | 0af3141d | Panagiotis Kanavos | var info = new FileInfo(path); |
353 | 0af3141d | Panagiotis Kanavos | string hash = info.CalculateHash(StatusKeeper.BlockSize,StatusKeeper.BlockHash); |
354 | 9c4346c9 | Panagiotis Kanavos | StatusKeeper.UpdateFileChecksum(path, hash); |
355 | 9c4346c9 | Panagiotis Kanavos | |
356 | 9c4346c9 | Panagiotis Kanavos | state.Hash = hash; |
357 | 9c4346c9 | Panagiotis Kanavos | return state; |
358 | 9c4346c9 | Panagiotis Kanavos | } |
359 | 9c4346c9 | Panagiotis Kanavos | |
360 | bfc13ed8 | Panagiotis Kanavos | //Does the file exist in the container's local folder? |
361 | bfc13ed8 | Panagiotis Kanavos | public bool Exists(string relativePath) |
362 | bfc13ed8 | Panagiotis Kanavos | { |
363 | bfc13ed8 | Panagiotis Kanavos | if (String.IsNullOrWhiteSpace(relativePath)) |
364 | bfc13ed8 | Panagiotis Kanavos | throw new ArgumentNullException("relativePath"); |
365 | bfc13ed8 | Panagiotis Kanavos | //A RootPath must be set before calling this method |
366 | bfc13ed8 | Panagiotis Kanavos | if (String.IsNullOrWhiteSpace(RootPath)) |
367 | bfc13ed8 | Panagiotis Kanavos | throw new InvalidOperationException("RootPath was not set"); |
368 | bfc13ed8 | Panagiotis Kanavos | Contract.EndContractBlock(); |
369 | bfc13ed8 | Panagiotis Kanavos | //Create the absolute path by combining the RootPath with the relativePath |
370 | bfc13ed8 | Panagiotis Kanavos | var absolutePath=Path.Combine(RootPath, relativePath); |
371 | bfc13ed8 | Panagiotis Kanavos | //Is this a valid file? |
372 | bfc13ed8 | Panagiotis Kanavos | if (File.Exists(absolutePath)) |
373 | bfc13ed8 | Panagiotis Kanavos | return true; |
374 | bfc13ed8 | Panagiotis Kanavos | //Or a directory? |
375 | a64c87c8 | Panagiotis Kanavos | if (Directory.Exists(absolutePath)) |
376 | bfc13ed8 | Panagiotis Kanavos | return true; |
377 | bfc13ed8 | Panagiotis Kanavos | //Fail if it is neither |
378 | bfc13ed8 | Panagiotis Kanavos | return false; |
379 | bfc13ed8 | Panagiotis Kanavos | } |
380 | 9c4346c9 | Panagiotis Kanavos | |
381 | f3d080df | Panagiotis Kanavos | public FileSystemInfo GetFileSystemInfo(string relativePath) |
382 | bfc13ed8 | Panagiotis Kanavos | { |
383 | bfc13ed8 | Panagiotis Kanavos | if (String.IsNullOrWhiteSpace(relativePath)) |
384 | bfc13ed8 | Panagiotis Kanavos | throw new ArgumentNullException("relativePath"); |
385 | bfc13ed8 | Panagiotis Kanavos | //A RootPath must be set before calling this method |
386 | bfc13ed8 | Panagiotis Kanavos | if (String.IsNullOrWhiteSpace(RootPath)) |
387 | bfc13ed8 | Panagiotis Kanavos | throw new InvalidOperationException("RootPath was not set"); |
388 | bfc13ed8 | Panagiotis Kanavos | Contract.EndContractBlock(); |
389 | bfc13ed8 | Panagiotis Kanavos | |
390 | bfc13ed8 | Panagiotis Kanavos | var absolutePath = Path.Combine(RootPath, relativePath); |
391 | bfc13ed8 | Panagiotis Kanavos | |
392 | 4f6d51d4 | Panagiotis Kanavos | if (Directory.Exists(absolutePath)) |
393 | f3d080df | Panagiotis Kanavos | return new DirectoryInfo(absolutePath).WithProperCapitalization(); |
394 | 4f6d51d4 | Panagiotis Kanavos | else |
395 | f3d080df | Panagiotis Kanavos | return new FileInfo(absolutePath).WithProperCapitalization(); |
396 | bfc13ed8 | Panagiotis Kanavos | |
397 | bfc13ed8 | Panagiotis Kanavos | } |
398 | a27aa447 | Panagiotis Kanavos | |
399 | 0af3141d | Panagiotis Kanavos | public void Delete(string relativePath) |
400 | 0af3141d | Panagiotis Kanavos | { |
401 | 4f6d51d4 | Panagiotis Kanavos | var absolutePath = Path.Combine(RootPath, relativePath).ToLower(); |
402 | 0af3141d | Panagiotis Kanavos | if (File.Exists(absolutePath)) |
403 | 4f6d51d4 | Panagiotis Kanavos | { |
404 | 4f6d51d4 | Panagiotis Kanavos | try |
405 | 4f6d51d4 | Panagiotis Kanavos | { |
406 | 4f6d51d4 | Panagiotis Kanavos | File.Delete(absolutePath); |
407 | 4f6d51d4 | Panagiotis Kanavos | } |
408 | 4f6d51d4 | Panagiotis Kanavos | //The file may have been deleted by another thread. Just ignore the relevant exception |
409 | 4f6d51d4 | Panagiotis Kanavos | catch (FileNotFoundException) { } |
410 | 4f6d51d4 | Panagiotis Kanavos | } |
411 | 4f6d51d4 | Panagiotis Kanavos | else if (Directory.Exists(absolutePath)) |
412 | 4f6d51d4 | Panagiotis Kanavos | { |
413 | 4f6d51d4 | Panagiotis Kanavos | try |
414 | 4f6d51d4 | Panagiotis Kanavos | { |
415 | 4f6d51d4 | Panagiotis Kanavos | Directory.Delete(absolutePath, true); |
416 | 4f6d51d4 | Panagiotis Kanavos | } |
417 | 4f6d51d4 | Panagiotis Kanavos | //The directory may have been deleted by another thread. Just ignore the relevant exception |
418 | 4f6d51d4 | Panagiotis Kanavos | catch (DirectoryNotFoundException){} |
419 | 0af3141d | Panagiotis Kanavos | } |
420 | 4f6d51d4 | Panagiotis Kanavos | |
421 | 4f6d51d4 | Panagiotis Kanavos | //_ignoreFiles[absolutePath] = absolutePath; |
422 | 0af3141d | Panagiotis Kanavos | StatusKeeper.ClearFileStatus(absolutePath); |
423 | 0af3141d | Panagiotis Kanavos | } |
424 | 9c4346c9 | Panagiotis Kanavos | } |
425 | 9c4346c9 | Panagiotis Kanavos | } |