Files
Fileinterface_Cron_Job/FileinterfaceCronScheduler/Scheduler/WatcherJobRepository.cs
2026-08-19 19:27:41 +02:00

110 lines
4.5 KiB
C#

using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Web.Script.Serialization;
namespace FileInterface.Scheduler
{
public sealed class WatcherJobRepository
{
private readonly object _sync = new object();
private readonly string _fileName;
private readonly JavaScriptSerializer _serializer = new JavaScriptSerializer();
private List<WatcherJobConfig> _jobs;
public WatcherJobRepository(string fileName)
{
_fileName = Path.GetFullPath(fileName);
_serializer.MaxJsonLength = Int32.MaxValue;
_jobs = LoadInternal();
}
public IList<WatcherJobConfig> GetAll()
{
lock (_sync) return Clone(_jobs);
}
public WatcherJobConfig GetById(string id)
{
lock (_sync)
{
WatcherJobConfig job = _jobs.FirstOrDefault(j => String.Equals(j.Id, id, StringComparison.OrdinalIgnoreCase));
return job == null ? null : Clone(job);
}
}
public WatcherJobConfig Save(WatcherJobConfig job)
{
if (job == null) throw new ArgumentNullException("job");
Validate(job);
lock (_sync)
{
if (String.IsNullOrWhiteSpace(job.Id)) job.Id = Guid.NewGuid().ToString("N");
int index = _jobs.FindIndex(j => String.Equals(j.Id, job.Id, StringComparison.OrdinalIgnoreCase));
if (index >= 0) _jobs[index] = Clone(job); else _jobs.Add(Clone(job));
SaveInternal();
return Clone(job);
}
}
public bool Delete(string id)
{
lock (_sync)
{
int count = _jobs.RemoveAll(j => String.Equals(j.Id, id, StringComparison.OrdinalIgnoreCase));
if (count > 0) SaveInternal();
return count > 0;
}
}
private List<WatcherJobConfig> LoadInternal()
{
if (!File.Exists(_fileName)) return new List<WatcherJobConfig>();
string json = File.ReadAllText(_fileName, Encoding.UTF8);
if (String.IsNullOrWhiteSpace(json)) return new List<WatcherJobConfig>();
return _serializer.Deserialize<List<WatcherJobConfig>>(json) ?? new List<WatcherJobConfig>();
}
private void SaveInternal()
{
string dir = Path.GetDirectoryName(_fileName);
if (!String.IsNullOrWhiteSpace(dir)) Directory.CreateDirectory(dir);
string json = _serializer.Serialize(_jobs);
string tmp = _fileName + ".tmp";
File.WriteAllText(tmp, json, new UTF8Encoding(false));
if (File.Exists(_fileName))
{
string backup = _fileName + ".bak";
try { File.Replace(tmp, _fileName, backup, true); }
catch { File.Delete(_fileName); File.Move(tmp, _fileName); }
}
else File.Move(tmp, _fileName);
}
private static void Validate(WatcherJobConfig job)
{
if (String.IsNullOrWhiteSpace(job.Name)) throw new InvalidOperationException("Name is required.");
if (String.IsNullOrWhiteSpace(job.SourceDirectory)) throw new InvalidOperationException("SourceDirectory is required.");
if (String.IsNullOrWhiteSpace(job.CustomFunction)) throw new InvalidOperationException("CustomFunction is required.");
if (!job.WatchCreated && !job.WatchChanged && !job.WatchRenamed)
throw new InvalidOperationException("At least one watcher event (Created, Changed, Renamed) must be enabled.");
if (job.MoveFileAfterSuccess && String.IsNullOrWhiteSpace(job.MoveTargetDirectory))
throw new InvalidOperationException("MoveTargetDirectory is required when MoveFileAfterSuccess=true.");
if (job.InArgs == null) job.InArgs = new List<string>();
if (String.IsNullOrWhiteSpace(job.SearchPattern)) job.SearchPattern = "*.*";
if (job.JoinSeparator == null) job.JoinSeparator = ";";
if (job.DebounceMilliseconds < 0) job.DebounceMilliseconds = 0;
if (job.FileReadyRetries < 1) job.FileReadyRetries = 1;
if (job.FileReadyRetries > 1000) job.FileReadyRetries = 1000;
if (job.FileReadyDelayMilliseconds < 10) job.FileReadyDelayMilliseconds = 10;
}
private T Clone<T>(T value)
{
return _serializer.Deserialize<T>(_serializer.Serialize(value));
}
}
}