ln.http.resources/collections/JSONCollectionResource<T>.cs

189 lines
7.0 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.Collections.ObjectModel;
using System.Linq;
using ln.types.odb;
using Newtonsoft.Json;
using ln.http.exceptions;
using Newtonsoft.Json.Linq;
using System.ComponentModel;
using ln.types.odb.mapped;
using ln.types.threads;
using ln.types.json;
using System.Reflection;
namespace ln.http.resources.collections
{
public class JSONCollectionResource<TENTITY, TIDENT> : Resource where TENTITY : class
{
public JSONConvert JSONConvert { get; set; }
public EntityMapper<TENTITY> EntityMapper { get;}
IEntityCollectionInterface<TENTITY, TIDENT> entityCollectionInterface;
public JSONCollectionResource(Resource container, IEntityCollectionInterface<TENTITY,TIDENT> entityCollectionInterface)
: base(container, typeof(TENTITY).Name)
{
this.entityCollectionInterface = entityCollectionInterface;
JSONConvert = JSONConvert.DefaultInstance;
EntityMapper = new EntityMapper<TENTITY>(JSONConvert);
}
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) => GetResponse(httpRequest, new Queue<string>());
public override HttpResponse GetResponse(HttpRequest httpRequest, Queue<string> pathStack)
{
CollectionResult collectionResult = null;
if (pathStack.Count == 0)
{
switch (httpRequest.Method)
{
case "GET":
collectionResult = Query(httpRequest);
break;
case "POST":
/*
T ni = PostItem(httpRequest);
object documentID = collection.Mapper.GetDocumentID(ni);
httpResponse.SetHeader("Location", String.Format("/{0}/{1}", String.Join("/", this.Path), documentID.ToString()));
httpResponse.StatusCode = 201;
responseValue = ni;
*/
break;
case "DESC":
collectionResult = Describe(httpRequest);
break;
default:
throw new NotSupportedException();
}
}
else
{
String documentID = pathStack.Dequeue();
TIDENT ident = this.JSONConvert.JSON2Value<TIDENT>(new JValue(documentID));
TENTITY entity = entityCollectionInterface.GetEntity(ident);
switch (httpRequest.Method)
{
case "GET":
collectionResult = new CollectionResult();
collectionResult.Values.Add(entity);
break;
case "PUT":
break;
default:
throw new NotSupportedException();
}
}
HttpResponse httpResponse = ConstructResponse(httpRequest, collectionResult);
return httpResponse;
}
private CollectionResult Describe(HttpRequest request)
{
CollectionResult collectionResult = new CollectionResult();
collectionResult.Descriptor = new JObject();
JArray jProperties = new JArray();
foreach (FieldInfo fieldInfo in EntityMapper.publicFields.Values)
{
String skyType = JSONConvert.GetSkyType(fieldInfo.FieldType);
if (skyType != null)
{
JObject field = new JObject();
field.Add("name", JToken.FromObject(fieldInfo.Name));
field.Add("type", JToken.FromObject(skyType));
jProperties.Add(field);
}
}
foreach (PropertyInfo propertyInfo in EntityMapper.publicProperties.Values)
{
String skyType = JSONConvert.GetSkyType(propertyInfo.PropertyType);
if (skyType != null)
{
JObject field = new JObject();
field.Add("name", JToken.FromObject(propertyInfo.Name));
field.Add("type", JToken.FromObject(skyType));
jProperties.Add(field);
}
}
collectionResult.Descriptor.Add("properties", jProperties);
return collectionResult;
}
private CollectionResult Query(HttpRequest request)
{
CollectionResult collectionResult = new CollectionResult();
foreach (TENTITY entity in entityCollectionInterface.List())
collectionResult.Values.Add(entity);
return collectionResult;
}
private string ConstructEntityURL(HttpRequest request,TIDENT identity)
{
return string.Format("{0}/{1}", String.Join("/", Path), identity.ToString());
}
private HttpResponse ConstructResponse(HttpRequest request,CollectionResult collectionResult)
{
HttpResponse response = new HttpResponse(request);
JObject surround = new JObject();
JObject jvalues = new JObject();
foreach (TENTITY entity in collectionResult.Values)
{
TIDENT identity = entityCollectionInterface.GetIdentity(entity);
jvalues.Add(ConstructEntityURL(request, identity), EntityMapper.MapEntity(entity));
}
surround.Add("values", jvalues);
JObject jfailed = new JObject();
foreach (TIDENT id in collectionResult.Failed.Keys)
{
jfailed.Add(id.ToString(), collectionResult.Failed[id]);
}
surround.Add("failed", jfailed);
if (collectionResult.Descriptor != null)
{
surround.Add("desc", collectionResult.Descriptor);
}
response.SetHeader("content-type", "application/json");
response.ContentWriter.Write(surround.ToString());
return response;
}
class CollectionResult
{
public List<TENTITY> Values { get; } = new List<TENTITY>();
public Dictionary<TIDENT, String> Failed { get; } = new Dictionary<TIDENT, string>();
public JObject Descriptor { get; set; }
}
}
}