ln.templates/ln.templates/RecursiveResolver.cs

112 lines
3.2 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 = templatePath.StartsWith(System.IO.Path.DirectorySeparatorChar) ? Root : this;
do
{
string templateFileName = System.IO.Path.Join(resolver.Path, templatePath);
if (File.Exists(templateFileName))
{
if (!_templates.TryGetValue(templateFileName, out Template template))
{
template = new Template(templateFileName, this);
_templates.Add(templateFileName, template);
}
return template;
}
if (resolver.Parent is null)
break;
resolver = resolver.Parent;
} while (true);
return null;
}
public Template GetTemplate(string name)
{
string filename = System.IO.Path.Combine(Path, name);
if (File.Exists(filename))
{
if (!_templates.TryGetValue(filename, out Template template))
{
template = new Template(filename, this);
_templates.Add(filename, template);
}
return template;
}
if (Parent is not null)
return Parent.GetTemplate(name);
return null;
}
public override string ToString()
{
return String.Format("[RecursiveResolver {0}]", Path);
}
}