sharp-application-server/resources/Resource.cs

142 lines
3.8 KiB
C#

using System;
using appsrv.server;
using System.Collections.Generic;
using System.Dynamic;
using appsrv.exceptions;
using System.Linq;
namespace appsrv.resources
{
public abstract class Resource
{
public Resource Container { get; }
public String Name { get; }
Dictionary<String, Resource> resources = new Dictionary<string, Resource>();
public Resource(String name)
{
Name = name;
}
public Resource(String name,Resource container)
{
Name = name;
Container = container;
if (container != null)
container.Add(this);
}
protected virtual void Add(Resource resource){
resources.Add(resource.Name, resource);
}
protected virtual void Remove(Resource resource){
if (resources.ContainsValue(resource)){
resources.Remove(resource.Name);
}
}
public bool Contains(String resName)
{
return resources.ContainsKey(resName);
}
public bool Contains(Resource resource)
{
return resources.ContainsValue(resource);
}
public ISet<Resource> Resources { get => new HashSet<Resource>(resources.Values); }
public Resource Root {
get {
if (Container == null)
return this;
else
return Container.Root;
}
}
public IList<String> PathList {
get {
if (Container != null)
{
IList<String> pl = Container.PathList;
pl.Add(Name);
return pl;
} else {
return new List<String>();
}
}
}
public String Path {
get {
return String.Format("/{0}",String.Join("/",PathList));
}
}
public virtual Resource this[string name]{
get => resources[name];
}
public virtual void Request(Stack<String> requestPath, HttpRequest request)
{
try
{
if ((requestPath.Count > 0) && (Contains(requestPath.Peek())))
{
this[requestPath.Pop()].Request(requestPath, request);
}
else
{
Hit(requestPath, request);
}
}
catch (ApplicationServerException ase)
{
HandleException(ase);
}
}
public virtual void Hit(Stack<String> requestPath, HttpRequest request){
if (requestPath.Count > 0){
throw new ResourceNotFoundException(Path, requestPath.Peek());
} else {
throw new ApplicationServerException("unimplemented resource has been hit");
}
}
public Resource FindByPath(String path)
{
String[] pathTokens = path.Split(new char[]{'/'},StringSplitOptions.RemoveEmptyEntries);
if (path[0] == '/')
return Root.FindByPath(pathTokens);
else
return FindByPath(pathTokens);
}
public Resource FindByPath(IEnumerable<String> path)
{
return FindByPath(path.GetEnumerator());
}
public Resource FindByPath(IEnumerator<String> path)
{
if (path.MoveNext())
{
return this[path.Current].FindByPath(path);
}
else
{
return this;
}
}
protected void HandleException(ApplicationServerException ase){
Console.WriteLine("ASE: " + ase.ToString());
}
}
}