82 lines
2.4 KiB
C#
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;
|
|
}
|
|
|
|
|
|
} |