From 85caed9f34d0e1e48f0fcbaed6fb91cfce92353b Mon Sep 17 00:00:00 2001 From: Harald Wolff Date: Thu, 14 Feb 2019 09:19:43 +0100 Subject: [PATCH] Initial Commit --- .gitignore | 41 +++++++++++++++ BaseResource.cs | 78 +++++++++++++++++++++++++++ DirectoryResource.cs | 56 ++++++++++++++++++++ IPresentation.cs | 8 +++ ObjectBase.cs | 71 +++++++++++++++++++++++++ PresentationManager.cs | 13 +++++ Properties/AssemblyInfo.cs | 26 +++++++++ Resource.cs | 105 +++++++++++++++++++++++++++++++++++++ ResourceApplication.cs | 39 ++++++++++++++ ln.http.resources.csproj | 49 +++++++++++++++++ 10 files changed, 486 insertions(+) create mode 100644 .gitignore create mode 100644 BaseResource.cs create mode 100644 DirectoryResource.cs create mode 100644 IPresentation.cs create mode 100644 ObjectBase.cs create mode 100644 PresentationManager.cs create mode 100644 Properties/AssemblyInfo.cs create mode 100644 Resource.cs create mode 100644 ResourceApplication.cs create mode 100644 ln.http.resources.csproj diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..bf793ed --- /dev/null +++ b/.gitignore @@ -0,0 +1,41 @@ +# Autosave files +*~ + +# build +[Oo]bj/ +[Bb]in/ +packages/ +TestResults/ + +# globs +Makefile.in +*.DS_Store +*.sln.cache +*.suo +*.cache +*.pidb +*.userprefs +*.usertasks +config.log +config.make +config.status +aclocal.m4 +install-sh +autom4te.cache/ +*.user +*.tar.gz +tarballs/ +test-results/ +Thumbs.db +.vs/ + +# Mac bundle stuff +*.dmg +*.app + +# resharper +*_Resharper.* +*.Resharper + +# dotCover +*.dotCover diff --git a/BaseResource.cs b/BaseResource.cs new file mode 100644 index 0000000..29d14fb --- /dev/null +++ b/BaseResource.cs @@ -0,0 +1,78 @@ +using System; +using System.Collections.Generic; +using System.Linq; +namespace ln.http.resources +{ + public class BaseResource : Resource + { + Dictionary resources = new Dictionary(); + + public BaseResource(String name) + :base(name) + { + } + public BaseResource(Resource container,String name) + :base(container,name) + { + } + + public override bool Contains(String name) + { + return resources.ContainsKey(name); + } + public override bool Contains(Resource resource) + { + return resources.ContainsValue(resource); + } + + public override void AddResource(Resource resource) + { + this.resources.Add(resource.Name, resource); + } + public override void RemoveResource(Resource resource) + { + if (resource.Container != this) + throw new ArgumentOutOfRangeException("can't remove resource from foreign container"); + + this.resources.Remove(resource.Name); + } + + + public override Resource GetResource(string name) + { + return this.resources[name]; + } + + public override IEnumerable GetResources() + { + return this.resources.Values; + } + + public override IEnumerable GetResources(Type resourceType) + { + return this.resources.Values.Where((x) => resourceType.IsInstanceOfType(x)); + } + + + + + + + public virtual Resource CreateResource(string name) + { + throw new NotImplementedException(); + } + + + + public override HttpResponse GetResponse(HttpRequest httpRequest) + { + if (DefaultResource != null) + return httpRequest.Redirect(String.Join("/", DefaultResource.Path)); + + throw new NotImplementedException(); + } + + + } +} diff --git a/DirectoryResource.cs b/DirectoryResource.cs new file mode 100644 index 0000000..5c12832 --- /dev/null +++ b/DirectoryResource.cs @@ -0,0 +1,56 @@ +using System; +using System.Collections.Generic; +using System.IO; + +namespace ln.http.resources +{ + + public delegate Resource ResourceTypeHook(DirectoryResource directoryResource, FileInfo fileInfo); + + public class DirectoryResource : Resource + { + public ResourceTypeHook ResourceTypeHook { get; set; } + + DirectoryInfo DirectoryInfo { get; } + Dictionary cache = new Dictionary(); + + public DirectoryResource(String path) + :base(System.IO.Path.GetFileName(path)) + { + DirectoryInfo = new DirectoryInfo(path); + } + public DirectoryResource(Resource container,String path) + :base(container, System.IO.Path.GetFileName(path)) + { + DirectoryInfo = new DirectoryInfo(path); + } + + public override bool Contains(string name) + { + throw new NotImplementedException(); + } + + public override void AddResource(Resource resource) + { + throw new NotImplementedException(); + } + + public override void RemoveResource(Resource resource) + { + throw new NotImplementedException(); + } + + public override IEnumerable GetResources() + { + throw new NotImplementedException(); + } + + public override HttpResponse GetResponse(HttpRequest httpRequest) + { + if (DefaultResource != null) + return httpRequest.Redirect(String.Join("/", DefaultResource.Path)); + + throw new NotImplementedException(); + } + } +} diff --git a/IPresentation.cs b/IPresentation.cs new file mode 100644 index 0000000..33832e0 --- /dev/null +++ b/IPresentation.cs @@ -0,0 +1,8 @@ +using System; +namespace ln.http.resources +{ + public interface IPresentation + { + HttpResponse GetPresentation(HttpRequest request, object o); + } +} diff --git a/ObjectBase.cs b/ObjectBase.cs new file mode 100644 index 0000000..d0fb0cd --- /dev/null +++ b/ObjectBase.cs @@ -0,0 +1,71 @@ +using System; +using System.Collections.Generic; +namespace ln.http.resources +{ + public abstract class ObjectBase + { + string name; + public ObjectBase Container { get; private set; } + + Dictionary children = new Dictionary(); + + public ObjectBase(string name) + { + this.name = name; + } + + public void Add(ObjectBase child) + { + if (children.ContainsKey(child.Name)) + throw new ArgumentException(String.Format("Container already has child with name {0}",child.Name)); + + children.Add(child.Name, child); + } + public void Remove(ObjectBase child) + { + if (child.Container != this) + throw new ArgumentException("Can't remove child of other container"); + + children.Remove(child.Name); + } + public bool Contains(string name) + { + return children.ContainsKey(name); + } + public bool Contains(ObjectBase child) + { + return children.ContainsValue(child); + } + + public IEnumerable Children + { + get => this.children.Values; + } + + public String Name { + get { return this.name; } + set { + if (Container != null) + { + if (Container.Contains(value)) + throw new ArgumentException("Owning container already has a child with that name"); + + Container.children.Remove(this.name); + this.name = value; + Container.children.Add(this.name, this); + } + } + } + + public ObjectBase this[string name] + { + get + { + return children[name]; + } + } + + + + } +} diff --git a/PresentationManager.cs b/PresentationManager.cs new file mode 100644 index 0000000..9e1c0ff --- /dev/null +++ b/PresentationManager.cs @@ -0,0 +1,13 @@ +using System; +namespace ln.http.resources +{ + public class PresentationManager + { + public PresentationManager() + { + } + + + + } +} diff --git a/Properties/AssemblyInfo.cs b/Properties/AssemblyInfo.cs new file mode 100644 index 0000000..c9c1c88 --- /dev/null +++ b/Properties/AssemblyInfo.cs @@ -0,0 +1,26 @@ +using System.Reflection; +using System.Runtime.CompilerServices; + +// Information about this assembly is defined by the following attributes. +// Change them to the values specific to your project. + +[assembly: AssemblyTitle("ln.http.objects")] +[assembly: AssemblyDescription("")] +[assembly: AssemblyConfiguration("")] +[assembly: AssemblyCompany("")] +[assembly: AssemblyProduct("")] +[assembly: AssemblyCopyright("${AuthorCopyright}")] +[assembly: AssemblyTrademark("")] +[assembly: AssemblyCulture("")] + +// The assembly version has the format "{Major}.{Minor}.{Build}.{Revision}". +// The form "{Major}.{Minor}.*" will automatically update the build and revision, +// and "{Major}.{Minor}.{Build}.*" will update just the revision. + +[assembly: AssemblyVersion("1.0.*")] + +// The following attributes are used to specify the signing key for the assembly, +// if desired. See the Mono documentation for more information about signing. + +//[assembly: AssemblyDelaySign(false)] +//[assembly: AssemblyKeyFile("")] diff --git a/Resource.cs b/Resource.cs new file mode 100644 index 0000000..2f6071e --- /dev/null +++ b/Resource.cs @@ -0,0 +1,105 @@ +using System; +using System.Collections.Generic; +using System.Runtime.Remoting.Contexts; +using System.Linq; + +namespace ln.http.resources +{ + public abstract class Resource + { + public Resource Container { get; protected set; } + public Resource DefaultResource { get; set; } + + public Resource(String name) + { + Name = name; + } + public Resource(Resource container,String name) + :this(name) + { + container.AddResource(this); + Container = container; + } + + + string name; + public String Name + { + get => this.name; + set + { + if ((this.name != null) && this.Name.Equals(value)) + return; + + if (String.Empty.Equals(value) && Container != null) + throw new ArgumentOutOfRangeException("Name must not be empty"); + + if ((Container != null) && Container.Contains(value)) + throw new ArgumentOutOfRangeException("Container already has resource with this name"); + + if (Container != null) + Container.RemoveResource(this); + + this.name = value; + + if (Container != null) + Container.AddResource(this); + } + } + + + public abstract bool Contains(String name); + public virtual bool Contains(Resource resource) + { + return (resource != null) && (resource.Container == this) && (GetResource(resource.Name) == resource); + } + + public abstract void AddResource(Resource resource); + public abstract void RemoveResource(Resource resource); + + public virtual Resource GetResource(string name) + { + foreach (Resource r in GetResources()) + if (r.Name.Equals(name)) + return r; + throw new KeyNotFoundException(); + } + public abstract IEnumerable GetResources(); + + public virtual IEnumerable GetResources(Type resourceType) + { + return this.GetResources().Where((x) => resourceType.IsInstanceOfType(x)); + } + + public abstract HttpResponse GetResponse(HttpRequest httpRequest); + + private List ResourcePathList + { + get + { + List l = null; + if (Container != null) + l = Container.ResourcePathList; + else + l = new List(); + + l.Add(this); + return l; + } + } + public Resource[] ResourcePath + { + get + { + return ResourcePathList.ToArray(); + } + } + public String[] Path + { + get + { + return ResourcePathList.Select((x) => x.Name).ToArray(); + } + } + } +} diff --git a/ResourceApplication.cs b/ResourceApplication.cs new file mode 100644 index 0000000..4155c49 --- /dev/null +++ b/ResourceApplication.cs @@ -0,0 +1,39 @@ +using System; +using System.Collections.Generic; + +namespace ln.http.resources +{ + public class ResourceApplication : HttpApplication + { + public Resource RootResource { get; set; } + + public ResourceApplication() + { + RootResource = new BaseResource(""); + } + + public override HttpResponse GetResponse(HttpRequest httpRequest) + { + /* TODO: Implement Session Tracker here... */ + /* TODO: Implement Authentication here... */ + + + Resource currentResource = RootResource; + Queue pathStack = new Queue(httpRequest.URI.AbsolutePath.Split(new String[] { "/" }, StringSplitOptions.RemoveEmptyEntries)); + + while (pathStack.Count > 0) + { + String next = pathStack.Dequeue(); + + if (!currentResource.Contains(next)) + throw new KeyNotFoundException(); + + currentResource = currentResource.GetResource(next); + + /* TODO: Implement Authorization hook here... */ + } + + return currentResource.GetResponse(httpRequest); + } + } +} diff --git a/ln.http.resources.csproj b/ln.http.resources.csproj new file mode 100644 index 0000000..44b00c3 --- /dev/null +++ b/ln.http.resources.csproj @@ -0,0 +1,49 @@ + + + + Debug + AnyCPU + {F9086FE4-8925-42FF-A59C-607341604293} + Library + ln.http.resources + ln.http.objects + v4.7 + + + true + full + false + bin\Debug + DEBUG; + prompt + 4 + false + + + true + bin\Release + prompt + 4 + false + + + + + + + + + + + + + + + + + {CEEEEB41-3059-46A2-A871-2ADE22C013D9} + ln.http + + + + \ No newline at end of file