Revision badcef63 trunk/Pithos.Core/Agents/FileSystemWatcherAdapter.cs

b/trunk/Pithos.Core/Agents/FileSystemWatcherAdapter.cs
39 39
 * -----------------------------------------------------------------------
40 40
 */
41 41
#endregion
42

  
43
using System.Diagnostics;
42 44
using System.Diagnostics.Contracts;
43 45
using System.IO;
44 46
using System.Reflection;
......
84 86
        }
85 87

  
86 88
        private string _cachedDeletedFullPath;
89
        private string CachedDeletedFullPath
90
        {
91
            get { return _cachedDeletedFullPath; }
92
            set
93
            {
94
                Debug.Assert(Path.IsPathRooted(CachedDeletedFullPath));
95
                if (!Path.IsPathRooted(CachedDeletedFullPath))
96
                    Log.WarnFormat("Storing a relative CachedDeletedFullPath: {0}",value);
97
                _cachedDeletedFullPath = value;
98
            }
99
        }
100

  
101
        /// <summary>
102
        /// Clears any cached deleted file path
103
        /// </summary>
104
        /// <remarks>
105
        /// This method was added to bypass the null checking in the property's setter
106
        /// </remarks>
107
        private void ClearCachedDeletedPath()
108
        {
109
            _cachedDeletedFullPath = null;
110
        }
111

  
112

  
87 113
        private const int PropagateDelay = 10;
88 114

  
89 115
        private void OnDeleted(object sender, FileSystemEventArgs e)
......
115 141
            //TODO: Moving a folder to the recycle bin results in a single delete event for the entire folder and its contents
116 142
            //      as this is actually a MOVE operation
117 143
            //Deleting by Shift+Delete results in a delete event for each file followed by the delete of the folder itself
118
            _cachedDeletedFullPath = e.FullPath;
144
            CachedDeletedFullPath = e.FullPath;
119 145

  
120
            //TODO: This requires synchronization of the _cachedDeletedFullPath field
146
            //TODO: This requires synchronization of the CachedDeletedFullPath field
121 147
            //TODO: This creates a new task for each file even though we can cancel any existing tasks if a new event arrives
122 148
            //Maybe, use a timer instead of a task
123 149

  
124 150
            TaskEx.Delay(PropagateDelay).ContinueWith(t =>
125 151
                                                          {
126 152
                                                              var myPath = e.FullPath;
127
                                                              if (_cachedDeletedFullPath == myPath)
153
                                                              if (CachedDeletedFullPath == myPath)
128 154
                                                                  PropagateCachedDeleted(sender);
129 155
                                                          });
130 156
        }
......
184 210
            }
185 211
            finally
186 212
            {
187
                _cachedDeletedFullPath = null;
213
                ClearCachedDeletedPath();
188 214
            }
189 215
        }
190 216

  
......
225 251
            finally
226 252
            {
227 253
                //Finally, make sure the cached path is cleared
228
                _cachedDeletedFullPath = null;
254
                ClearCachedDeletedPath();
229 255
            }
230 256
        }
231 257

  
258

  
232 259
        private void RaiseCreatedForChildren(object sender, FileSystemEventArgs e)
233 260
        {
234 261
            Contract.Requires(sender!=null);
......
269 296
            //instead of a sequence of independent actions
270 297
            //One way to detect this would be to request that the full paths are NOT the same
271 298

  
272
            var oldName = Path.GetFileName(_cachedDeletedFullPath);
299
            var oldName = Path.GetFileName(CachedDeletedFullPath);
273 300
            //NOTE: e.Name is a path relative to the watched path. We MUST call Path.GetFileName to get the actual path
274 301
            var newName = Path.GetFileName(e.Name);
275 302
            //If the last deleted filename is equal to the current and the action is create, we have a MOVE operation
276
            var hasMoved = (_cachedDeletedFullPath != e.FullPath && oldName == newName);
303
            var hasMoved = (CachedDeletedFullPath != e.FullPath && oldName == newName);
277 304

  
278 305
            if (!hasMoved)
279 306
                return false;
......
285 312

  
286 313
                //If the actual action is a Move, raise a Move event instead of the actual event
287 314
                var newDirectory = Path.GetDirectoryName(e.FullPath);
288
                var oldDirectory = Path.GetDirectoryName(_cachedDeletedFullPath);
315
                var oldDirectory = Path.GetDirectoryName(CachedDeletedFullPath);
289 316

  
290 317
                if (Moved != null)
291 318
                {
......
313 340
            }
314 341
            finally
315 342
            {
316
                _cachedDeletedFullPath = null;
343
                ClearCachedDeletedPath();
317 344
            }
318 345
            return true;
319 346
        }
......
322 349
        {
323 350
            if (sender == null)
324 351
                throw new ArgumentNullException("sender");
325
            Contract.Ensures(_cachedDeletedFullPath == null);
352
            Contract.Ensures(CachedDeletedFullPath == null);
326 353
            Contract.EndContractBlock();
327 354

  
328 355
            //Nothing to handle if there is no cached deleted file
329
            if (String.IsNullOrWhiteSpace(_cachedDeletedFullPath))
356
            if (String.IsNullOrWhiteSpace(CachedDeletedFullPath))
330 357
                return;
331 358
            
332
            var deletedFileName = Path.GetFileName(_cachedDeletedFullPath);
333
            var deletedFileDirectory = Path.GetDirectoryName(_cachedDeletedFullPath);
359
            var deletedFileName = Path.GetFileName(CachedDeletedFullPath);
360
            var deletedFileDirectory = Path.GetDirectoryName(CachedDeletedFullPath);
334 361

  
335 362
            if (Log.IsDebugEnabled)
336
                Log.DebugFormat("Propagating delete for [{0}]", _cachedDeletedFullPath);
363
                Log.DebugFormat("Propagating delete for [{0}]", CachedDeletedFullPath);
337 364

  
338 365
            //Only a single file Delete event is raised when moving a file to the Recycle Bin, as this is actually a MOVE operation
339 366
            //In this case we need to raise the proper events for all child objects of the deleted directory.
......
342 369
            if (Deleted != null)            
343 370
                Deleted(sender,new FileSystemEventArgs(WatcherChangeTypes.Deleted, deletedFileDirectory, deletedFileName));
344 371

  
345
            _cachedDeletedFullPath = null;
372
            ClearCachedDeletedPath();
346 373
        }
347 374
    }
348 375
}

Also available in: Unified diff