// /** // * File: CollectionResource.cs // * Author: haraldwolff // * // * This file and it's content is copyrighted by the Author and / or copyright holder. // * Any use wihtout proper permission is illegal and may lead to legal actions. // * // * // **/ using System; using System.Collections.Generic; using System.Linq; using Newtonsoft.Json; using ln.http.exceptions; using Newtonsoft.Json.Linq; namespace ln.http.resources { public delegate IEnumerable EnumerationDelegate(); public delegate T LookupDelegate(string ID); public delegate String GetResourceNameDelegate(T o); public delegate T CreateDelegate(); public delegate bool DeleteDelegate(T o); public delegate bool StoreDelegate(T o); public class ObjectContainerResource : Resource where T:class { public EnumerationDelegate Enumeration { get; set; } public LookupDelegate Lookup { get; set; } public GetResourceNameDelegate GetResourceName { get; set; } public CreateDelegate Create { get; set; } public DeleteDelegate Delete { get; set; } public StoreDelegate Store { get; set; } public ObjectContainerResource(Resource container) : this(container, typeof(T).Name) {} public ObjectContainerResource(Resource container, String name) : base(container, name) { } public override bool HandlesDispatching => true; public override void AddResource(Resource resource) => throw new NotSupportedException(); public override void RemoveResource(Resource resource) => throw new NotSupportedException(); public override IEnumerable GetResources() => throw new NotImplementedException(); public override bool Contains(string name) => throw new NotImplementedException(); public override HttpResponse GetResponse(HttpRequest httpRequest,Queue pathStack) { object responseValue = null; HttpResponse httpResponse = new HttpResponse(httpRequest); httpResponse.SetHeader("content-type", "application/json"); if (pathStack.Count == 0) { switch (httpRequest.Method) { case "GET": T[] resources = Query(httpRequest); JObject result = new JObject(); foreach (T resource in resources) result.Add(String.Format("{0}/{1}",String.Join("/",Path),GetResourceName(resource)), JObject.FromObject(resource)); responseValue = result; break; case "POST": T ni = PostItem(httpRequest); string resourceName = GetResourceName(ni); httpResponse.SetHeader("Location", String.Format("/{0}/{1}", String.Join("/", this.Path),resourceName.ToString())); httpResponse.StatusCode = 201; responseValue = ni; break; default: throw new NotSupportedException(); } } else { String resourceName = String.Join("/", pathStack); T resource = Lookup(resourceName); switch (httpRequest.Method) { case "PUT": JsonConvert.PopulateObject(httpRequest.ContentReader.ReadToEnd(), resource); bool updated = Store(resource); if (updated) { responseValue = resource; httpResponse.StatusCode = 200; } else { httpResponse.StatusCode = 500; } break; default: throw new NotSupportedException(); } } httpResponse.ContentWriter.Write( responseValue is JValue ? (responseValue as JValue).ToString() : JsonConvert.SerializeObject(responseValue) ); return httpResponse; } public override HttpResponse GetResponse(HttpRequest httpRequest) { return GetResponse(httpRequest, new Queue()); } private T[] Query(HttpRequest httpRequest) { return Enumeration().ToArray(); } private T PostItem(HttpRequest httpRequest) { T newResource = Create(); JsonConvert.PopulateObject(httpRequest.ContentReader.ReadToEnd(), newResource); if (!Store(newResource)) throw new HttpException(500, "Object not created, may already exist"); return newResource; } } }