142 lines
3.8 KiB
C#
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());
|
|
}
|
|
|
|
|
|
}
|
|
}
|