using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Security.Cryptography;
namespace gehGassi.Web.Services
{
///
/// Schnittstellenbeschreibung für einen Service der für alle Dateien in einem Orndern einen gemeinsamen Hash errechnet.
///
public interface IScriptVersionCalculator
{
///
/// Gibt eine Versionsnummer (hash) für alle Dateien in einem Ordner zurück
///
/// Absoluter Pfad des Ordners
/// Datei-Pattern
/// Errechnete Versionsnummer oder string.empty
string GetVersion(string absolutePath, string filePattern);
///
/// Entfernt eine Kombination aus dem Versions-Cache, wenn vorhanden
///
/// Absoluter Pfad des Ordners
/// Datei-Pattern
void Clear(string absolutePath, string filePattern);
///
/// Löscht alle Kombinationen aus dem Versions-Cache
///
void ClearAll();
}
///
/// Service der für alle Dateien in einem Orndern einen gemeinsamen Hash errechnet.
///
public class ScriptVersionCalculator : IScriptVersionCalculator
{
private Dictionary _versions;
///
/// Erstellt eine Instanz
///
public ScriptVersionCalculator()
{
_versions = new Dictionary();
}
///
/// Gibt eine Versionsnummer (hash) für alle Dateien in einem Ordner zurück
///
/// Absoluter Pfad des Ordners
/// Datei-Pattern
/// Errechnete Versionsnummer oder string.empty
public string GetVersion(string absolutePath, string filePattern)
{
var result = string.Empty;
if (_versions.ContainsKey($"{absolutePath}/{filePattern}"))
return _versions[$"{absolutePath}/{filePattern}"];
if (Directory.Exists(absolutePath))
{
using (var md5 = MD5.Create())
{
byte[] totalBytes = { };
foreach (var file in Directory.EnumerateFiles(absolutePath, filePattern, SearchOption.AllDirectories))
{
using (var stream = File.OpenRead(file))
{
var hash = md5.ComputeHash(stream);
totalBytes = totalBytes.Concat(hash).ToArray();
}
}
if (totalBytes.Length > 0)
{
var finalHash = md5.ComputeHash(totalBytes);
result = Convert.ToBase64String(finalHash);
_versions.Add($"{absolutePath}/{filePattern}", result);
}
}
}
return result;
}
///
/// Entfernt eine Kombination aus dem Versions-Cache, wenn vorhanden
///
/// Absoluter Pfad des Ordners
/// Datei-Pattern
public void Clear(string absolutePath, string filePattern)
{
if (_versions.ContainsKey($"{absolutePath}/{filePattern}"))
_versions.Remove($"{absolutePath}/{filePattern}");
}
///
/// Löscht alle Kombinationen aus dem Versions-Cache
///
public void ClearAll()
{
_versions.Clear();
}
}
}