ln.http.resources/ObjectContainerResource.cs

152 lines
5.5 KiB
C#

// /**
// * File: CollectionResource<T>.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 ln.http.exceptions;
using ln.json;
using ln.json.mapping;
namespace ln.http.resources
{
public delegate IEnumerable<T> EnumerationDelegate<T>();
public delegate T LookupDelegate<T>(string ID);
public delegate String GetResourceNameDelegate<T>(T o);
public delegate T CreateDelegate<T>();
public delegate bool DeleteDelegate<T>(T o);
public delegate bool StoreDelegate<T>(T o);
public class ObjectContainerResource<T> : Resource where T:class
{
public EnumerationDelegate<T> Enumeration { get; set; }
public LookupDelegate<T> Lookup { get; set; }
public GetResourceNameDelegate<T> GetResourceName { get; set; }
public CreateDelegate<T> Create { get; set; }
public DeleteDelegate<T> Delete { get; set; }
public StoreDelegate<T> Store { get; set; }
public ObjectContainerResource(Resource container)
: this(container, typeof(T).Name)
{}
public ObjectContainerResource(Resource container, String name)
: base(container, name)
{
}
public ObjectContainerResource(Resource container, String name,
EnumerationDelegate<T> Enumeration,
LookupDelegate<T> Lookup,
GetResourceNameDelegate<T> GetResourceName,
CreateDelegate<T> Create,
DeleteDelegate<T> Delete,
StoreDelegate<T> Store
)
: base(container, name)
{
this.Enumeration = Enumeration;
this.Lookup = Lookup;
this.GetResourceName = GetResourceName;
this.Create = Create;
this.Delete = Delete;
this.Store = Store;
}
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<Resource> GetResources() => throw new NotImplementedException();
public override bool Contains(string name) => throw new NotImplementedException();
public override HttpResponse GetResponse(HttpRequest httpRequest,Queue<string> 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);
JSONObject result = new JSONObject();
foreach (T resource in resources)
result.Add(String.Format("{0}/{1}",String.Join("/",Path),GetResourceName(resource)), JSONMapper.DefaultMapper.ToJson(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":
JSONMapper.DefaultMapper.Apply(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 JSONValue ? (responseValue as JSONValue).ToString() : JSONMapper.DefaultMapper.ToJson(responseValue).ToString()
);
return httpResponse;
}
public override HttpResponse GetResponse(HttpRequest httpRequest)
{
return GetResponse(httpRequest, new Queue<string>());
}
private T[] Query(HttpRequest httpRequest)
{
return Enumeration().ToArray();
}
private T PostItem(HttpRequest httpRequest)
{
T newResource = Create();
JSONMapper.DefaultMapper.Apply(httpRequest.ContentReader.ReadToEnd(), newResource);
if (!Store(newResource))
throw new HttpException(500, "Object not created, may already exist");
return newResource;
}
}
}