ln.templates/ln.templates/RecursiveResolver.cs

102 lines
2.9 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 = System.IO.Path.Combine(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(
path.Split(System.IO.Path.DirectorySeparatorChar) ?? Array.Empty<string>());
private RecursiveResolver FindResolver(Span<string> pathElements)
{
if (pathElements.Length == 0)
return this;
if (!_children.TryGetValue(pathElements[0], out RecursiveResolver child))
{
if (Directory.Exists(System.IO.Path.Combine(Path, pathElements[0])))
{
child = new RecursiveResolver(this, pathElements[0]);
_children.Add(pathElements[0], child);
}
}
if (child?.IsAlive ?? false)
return child.FindResolver(pathElements.Slice(1));
if (child is not null)
_children.Remove(pathElements[0]);
return null;
}
public Template GetTemplateByPath(string templatePath)
{
RecursiveResolver resolver;
Span<string> pathElements = templatePath.Split(System.IO.Path.DirectorySeparatorChar);
if (string.Empty.Equals(pathElements[0]))
resolver = Root;
else
resolver = FindResolver(pathElements.Slice(0, pathElements.Length - 1));
Template template = resolver?.GetTemplate(pathElements[^1]);
if (template is null)
return null;
template.Resolver = this;
return template;
}
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;
}
if (Parent is not null)
return Parent.GetTemplate(name);
return null;
}
public override string ToString()
{
return String.Format("[RecursiveResolver {0}]", Path);
}
}