Esempio n. 1
0
        private static void StartTasksAndWaitForAll(IEnumerable <Task> tasks,
                                                    ISyncJobExecutionContext ctx)
        {
            var runningTasks = new List <Task>();

            foreach (var t in tasks)
            {
                try
                {
                    if (ctx.CancelToken.IsCancellationRequested)
                    {
                        break;
                    }

                    t.Start();
                    runningTasks.Add(t);
                }
                catch
                {
                    //TODO log
                }
            }

            TaskHelper.WaitAll(runningTasks);
        }
Esempio n. 2
0
        // Private Methods (20) 

        private static void CompareDirectoriesSyncAction(DirectoryInfo src, DirectoryInfo dest,
                                                         ISyncJobExecutionContext execCtx)
        {
            CreateCompareDirectoriesTask(src: src, dest: dest,
                                         execCtx: execCtx,
                                         recursive: true).RunSynchronously();
        }
Esempio n. 3
0
        private static Task CreateCopyFileTask(FileInfo src, FileInfo dest,
                                               ISyncJobExecutionContext execCtx)
        {
            return(new Task((state) =>
            {
                const string LOG_CATEGORY = "CopyFile";

                var ctx = (ISyncJobExecutionContext)state;

                try
                {
                    src.Refresh();
                    if (!src.Exists)
                    {
                        return;
                    }

                    var destDir = dest.Directory;
                    destDir.Refresh();
                    if (!destDir.Exists)
                    {
                        return;
                    }

                    dest.Refresh();

                    File.Copy(src.FullName,
                              dest.FullName,
                              true);

                    ctx.Log(msg: string.Format("File '{0}' was copied to '{1}'.",
                                               src.FullName,
                                               dest.Directory.FullName),
                            tag: LOG_CATEGORY,
                            type: SyncLogType.OK);
                }
                catch (Exception ex)
                {
                    ctx.Log(msg: string.Format("Copying file '{0}' to '{1}' failed: {2}",
                                               src.FullName,
                                               dest.Directory.FullName,
                                               ex.GetBaseException() ?? ex),
                            tag: LOG_CATEGORY,
                            type: SyncLogType.Error);
                }
                finally
                {
                    TrySyncCreationTimes(src, dest);
                    TrySyncLastWriteTimes(src, dest);
                }
            }, state: execCtx
                            , cancellationToken: execCtx.CancelToken));
        }
        // Public Methods (1) 

        /// <summary>
        ///
        /// </summary>
        /// <see cref="ISyncJobAction.Execute(ISyncJobExecutionContext)" />
        public void Execute(ISyncJobExecutionContext ctx)
        {
            lock (this._SYNC)
            {
                if (ctx == null)
                {
                    throw new ArgumentNullException("ctx");
                }

                try
                {
                    this.OnExecute(ctx);
                }
                catch (Exception ex)
                {
                    throw ex as AggregateException ?? new AggregateException(ex);
                }
            }
        }
Esempio n. 5
0
        private FileSystemEventHandler CreateFileSystemEventHandlerForSource(ISyncJobExecutionContext ctx)
        {
            return(new FileSystemEventHandler((sender, e) =>
            {
                lock (ctx.SyncRoot)
                {
                    try
                    {
                        var watchedDir = Path.GetDirectoryName(e.FullPath);
                        var normalizedWatchedDir = ToComparablePath(watchedDir);

                        var action = ctx.Queue
                                     .OrderBy(a => ToComparablePath(a.Tag.AsString(true)), StringComparer.InvariantCultureIgnoreCase)
                                     .FirstOrDefault(a => normalizedWatchedDir.Equals(a.Tag));
                        if (action != null)
                        {
                            return;
                        }

                        var relativeSrcPath = GetRelativePath(ctx.SourceDirectory,
                                                              watchedDir);

                        action = new DelegateSyncAction(action: CompareDirectoriesSyncAction,
                                                        src: new DirectoryInfo(watchedDir),
                                                        dest: new DirectoryInfo(Path.Combine(ctx.DestionationDirectory,
                                                                                             relativeSrcPath)));
                        action.Tag = normalizedWatchedDir;

                        ctx.Queue
                        .Enqueue(action);
                    }
                    catch (Exception ex)
                    {
                        ctx.Log(msg: string.Format("Sync failed: {0}",
                                                   ex.GetBaseException() ?? ex),
                                tag: "FileSystemEvent",
                                type: SyncLogType.Error);
                    }
                }
            }));
        }
Esempio n. 6
0
 private void HandleSyncActions(FileSystemWatcher watcher,
                                ISyncJobExecutionContext ctx)
 {
     while (!ctx.CancelSource.IsCancellationRequested)
     {
         try
         {
             ISyncJobAction action;
             if (ctx.Queue.TryDequeue(out action))
             {
                 action.Execute(ctx);
             }
         }
         catch (Exception ex)
         {
             ctx.Log(msg: string.Format("Handling of sync action failed: {0}",
                                        ex.GetBaseException() ?? ex),
                     tag: "HandleSyncAction",
                     type: SyncLogType.Error);
         }
     }
 }
Esempio n. 7
0
        private static Task CreateDeleteFileTask(FileInfo file,
                                                 ISyncJobExecutionContext execCtx)
        {
            return(new Task((state) =>
            {
                const string LOG_CATEGORY = "CopyFile";

                var ctx = (ISyncJobExecutionContext)state;
                if (ctx.CancelToken.IsCancellationRequested)
                {
                    return;
                }

                try
                {
                    file.Refresh();
                    if (file.Exists)
                    {
                        file.Delete();
                        file.Refresh();

                        ctx.Log(msg: string.Format("File '{0}' was deleted.",
                                                   file.FullName),
                                tag: LOG_CATEGORY,
                                type: SyncLogType.OK);
                    }
                }
                catch (Exception ex)
                {
                    ctx.Log(msg: string.Format("Deleting file '{0}' failed: {1}",
                                               file.FullName,
                                               ex.GetBaseException() ?? ex),
                            tag: LOG_CATEGORY,
                            type: SyncLogType.Error);
                }
            }, state: execCtx
                            , cancellationToken: execCtx.CancelToken));
        }
Esempio n. 8
0
        // Protected Methods (1) 

        protected override void OnExecute(ISyncJobExecutionContext ctx)
        {
            this._ACTION(this._SOURCE, this._DESTINATION,
                         ctx);
        }
Esempio n. 9
0
        private static Task CreateDelTreeTask(DirectoryInfo dir,
                                              ISyncJobExecutionContext execCtx)
        {
            return(new Task((state) =>
            {
                const string LOG_CATEGORY = "DelTree";

                var ctx = (ISyncJobExecutionContext)state;

                try
                {
                    dir.Refresh();

                    // files
                    StartTasksAndWaitForAll(dir.GetFiles()
                                            .Select(f => CreateDeleteFileTask(f, ctx)),
                                            ctx);

                    // directories
                    StartTasksAndWaitForAll(dir.GetDirectories()
                                            .Select(d => CreateDelTreeTask(d, ctx)),
                                            ctx);

                    if (!ctx.CancelToken.IsCancellationRequested)
                    {
                        dir.Refresh();

                        if (NormalizePath(dir) == NormalizePath(ctx.SourceDirectory) ||
                            NormalizePath(dir) == NormalizePath(ctx.DestionationDirectory))
                        {
                            // do not delete source or destination directory

                            return;
                        }

                        if (dir.GetFiles().IsEmpty() &&
                            dir.GetDirectories().IsEmpty())
                        {
                            if (dir.Exists)
                            {
                                dir.Delete();
                                dir.Refresh();

                                ctx.Log(msg: string.Format("Directory '{0}' was deleted.",
                                                           dir.FullName),
                                        tag: LOG_CATEGORY,
                                        type: SyncLogType.OK);
                            }
                        }
                        else
                        {
                            ctx.Log(msg: string.Format("Directory '{0}' is NOT empty!",
                                                       dir.FullName),
                                    tag: LOG_CATEGORY,
                                    type: SyncLogType.Warning);
                        }
                    }
                }
                catch (Exception ex)
                {
                    ctx.Log(msg: string.Format("Deleting directory structure '{0}' failed: {1}",
                                               dir.FullName,
                                               ex.GetBaseException() ?? ex),
                            tag: LOG_CATEGORY,
                            type: SyncLogType.Error);
                }
            }, state: execCtx
                            , cancellationToken: execCtx.CancelToken));
        }
Esempio n. 10
0
        private static Task CreateCompareDirectoriesTask(DirectoryInfo src, DirectoryInfo dest,
                                                         ISyncJobExecutionContext execCtx,
                                                         bool recursive)
        {
            return(new Task((state) =>
            {
                const string LOG_CATEGORY = "CompareDirectories";

                var ctx = (ISyncJobExecutionContext)state;

                try
                {
                    if (!NormalizePath(src).StartsWith(NormalizePath(ctx.SourceDirectory)))
                    {
                        // must be source or inside source directory
                        return;
                    }

                    if (!NormalizePath(dest).StartsWith(NormalizePath(ctx.DestionationDirectory)))
                    {
                        // must be destination or inside destination directory
                        return;
                    }

                    src.Refresh();
                    if (!src.Exists)
                    {
                        return;
                    }

                    var srcDisplayText = GetRelativePath(ctx.SourceDirectory, src.FullName);
                    if (string.IsNullOrWhiteSpace(srcDisplayText))
                    {
                        srcDisplayText = src.FullName;
                    }

                    var destDisplayText = GetRelativePath(ctx.DestionationDirectory, dest.FullName);
                    if (string.IsNullOrWhiteSpace(destDisplayText))
                    {
                        destDisplayText = dest.FullName;
                    }

                    ctx.RaiseProgressChanged(text: string.Format("Comparing '{0}' with '{1}'...",
                                                                 srcDisplayText,
                                                                 destDisplayText));

                    // EXTRA items
                    {
                        // files
                        if (!ctx.CancelToken.IsCancellationRequested)
                        {
                            dest.Refresh();

                            if (dest.Exists)
                            {
                                var tasks = new List <Task>();

                                foreach (var destFile in dest.GetFiles())
                                {
                                    try
                                    {
                                        var srcFile = new FileInfo(Path.Combine(src.FullName,
                                                                                destFile.Name));

                                        if (!srcFile.Exists)
                                        {
                                            tasks.Add(CreateDeleteFileTask(destFile,
                                                                           ctx));
                                        }
                                    }
                                    catch
                                    {
                                        //TODO log
                                    }
                                }

                                StartTasksAndWaitForAll(tasks,
                                                        ctx);
                            }
                        }

                        // directories
                        if (!ctx.CancelToken.IsCancellationRequested)
                        {
                            dest.Refresh();

                            if (dest.Exists)
                            {
                                var tasks = new List <Task>();

                                foreach (var destSubDir in dest.GetDirectories())
                                {
                                    try
                                    {
                                        var srcSubDir = new DirectoryInfo(Path.Combine(src.FullName,
                                                                                       destSubDir.Name));

                                        if (!srcSubDir.Exists)
                                        {
                                            tasks.Add(CreateDelTreeTask(destSubDir,
                                                                        ctx));
                                        }
                                    }
                                    catch
                                    {
                                        //TODO log
                                    }
                                }

                                StartTasksAndWaitForAll(tasks,
                                                        ctx);
                            }
                        }
                    }

                    // copy items
                    {
                        // files
                        if (!ctx.CancelToken.IsCancellationRequested)
                        {
                            dest.Refresh();

                            var tasks = new List <Task>();

                            // copy files
                            foreach (var srcFile in src.GetFiles())
                            {
                                try
                                {
                                    var destFile = new FileInfo(Path.Combine(dest.FullName,
                                                                             srcFile.Name));

                                    var copyFile = false;
                                    if (destFile.Exists)
                                    {
                                        copyFile = (srcFile.Length != destFile.Length) ||
                                                   (srcFile.LastWriteTimeUtc != destFile.LastWriteTimeUtc);
                                    }
                                    else
                                    {
                                        copyFile = true;
                                    }

                                    if (copyFile)
                                    {
                                        destFile.Directory
                                        .CreateDirectoryDeep(refreshBefore: true,
                                                             refreshAfter: true);

                                        tasks.Add(CreateCopyFileTask(srcFile, destFile,
                                                                     ctx));
                                    }
                                }
                                catch
                                {
                                    //TODO log
                                }
                            }

                            StartTasksAndWaitForAll(tasks,
                                                    ctx);
                        }

                        // sub directories
                        if (!ctx.CancelToken.IsCancellationRequested)
                        {
                            var tasks = new List <Task>();

                            foreach (var srcSubDir in src.GetDirectories())
                            {
                                try
                                {
                                    var destSubDir = new DirectoryInfo(Path.Combine(dest.FullName,
                                                                                    srcSubDir.Name));

                                    try
                                    {
                                        if (!destSubDir.Exists)
                                        {
                                            destSubDir.CreateDirectoryDeep(refreshBefore: false,
                                                                           refreshAfter: true);

                                            ctx.Log(msg: string.Format("Destionation directory '{0}' was created.",
                                                                       destSubDir.FullName),
                                                    tag: LOG_CATEGORY,
                                                    type: SyncLogType.OK);
                                        }
                                    }
                                    finally
                                    {
                                        tasks.Add(CreateCompareDirectoriesTask(srcSubDir, destSubDir,
                                                                               ctx,
                                                                               recursive: true));
                                    }
                                }
                                catch
                                {
                                    //TODO log
                                }
                            }

                            StartTasksAndWaitForAll(tasks,
                                                    ctx);
                        }
                    }

                    ctx.RaiseProgressChanged(text: "Done");
                }
                catch (Exception ex)
                {
                    ctx.Log(msg: string.Format("Comparing directory '{0}' to '{1}' failed: {2}",
                                               src.FullName,
                                               dest.FullName,
                                               ex.GetBaseException() ?? ex),
                            tag: LOG_CATEGORY,
                            type: SyncLogType.Error);
                }
                finally
                {
                    TrySyncCreationTimes(src, dest);
                    TrySyncLastWriteTimes(src, dest);
                }
            }, state: execCtx
                            , cancellationToken: execCtx.CancelToken));
        }
Esempio n. 11
0
        // Protected Methods (1) 

        /// <summary>
        /// The logic for <see cref="SyncJobActionBase.Execute()" /> method.
        /// </summary>
        /// <param name="ctx">The underlying context.</param>
        protected abstract void OnExecute(ISyncJobExecutionContext ctx);