ln.templates/ln.templates/RecursiveResolver.cs

82 lines
2.4 KiB
C#

using System;
using System.Collections.Generic;
using System.IO;
using Esprima.Ast;
using ln.templates.html;
namespace ln.templates;
public class RecursiveResolver : ITemplateResolver
{
public RecursiveResolver(string path)
:this(null, path)
{
}
private RecursiveResolver(RecursiveResolver parent, string path)
{
Parent = parent;
Path = path;
if (!Directory.Exists(path))
throw new DirectoryNotFoundException(path);
}
public RecursiveResolver Root => Parent?.Root ?? this;
public RecursiveResolver Parent { get; private set; }
public string Path { get; private set; }
private bool IsAlive => Directory.Exists(Path);
private Dictionary<string, RecursiveResolver> _children = new Dictionary<string, RecursiveResolver>();
private Dictionary<string, Template> _templates = new Dictionary<string, Template>();
public RecursiveResolver FindResolver(string path) => FindResolver(
System.IO.Path.GetDirectoryName(path)?.Split(System.IO.Path.PathSeparator) ?? Array.Empty<string>());
private RecursiveResolver FindResolver(Span<string> pathElements)
{
if (pathElements.Length == 0)
throw new ArgumentOutOfRangeException(nameof(pathElements));
if (_children.TryGetValue(pathElements[0], out RecursiveResolver child))
{
if (!child.IsAlive)
{
_children.Remove(pathElements[0]);
return null;
}
if (pathElements.Length > 1)
return child.FindResolver(pathElements.Slice(1));
return child;
}
return null;
}
public Template GetTemplateByPath(string templatePath)
{
Span<string> pathElements = templatePath.Split(System.IO.Path.DirectorySeparatorChar);
RecursiveResolver resolver = FindResolver(pathElements.Slice(0, pathElements.Length - 1));
return resolver?.GetTemplate(pathElements[^1]);
}
public Template GetTemplate(string name)
{
string filename = System.IO.Path.Combine(Path, name);
if (File.Exists(filename))
{
if (!_templates.TryGetValue(name, out Template template))
{
template = new Template(filename, this);
_templates.Add(name, template);
}
return template;
}
return null;
}
}