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

181 lines
6.9 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 ln.json.mapping;
using ln.json;
namespace ln.http.resources.collections
{
public class JSONCollectionResource<TENTITY, TIDENT> : Resource where TENTITY : class
{
public JSONMapper JSONMapper { 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;
this.JSONMapper = JSONMapper.DefaultMapper;
EntityMapper = new EntityMapper<TENTITY>(JSONMapper);
}
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.JSONMapper.FromJson<TIDENT>(this.JSONMapper.ToJson(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 JSONObject();
JSONArray jProperties = new JSONArray();
/* ToDo: Implement or remove */
//foreach (FieldInfo fieldInfo in EntityMapper.publicFields.Values)
//{
// String skyType = JSONMapper.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);
JSONObject surround = new JSONObject();
JSONObject jvalues = new JSONObject();
foreach (TENTITY entity in collectionResult.Values)
{
TIDENT identity = entityCollectionInterface.GetIdentity(entity);
jvalues.Add(ConstructEntityURL(request, identity), EntityMapper.MapEntity(entity));
}
surround.Add("values", jvalues);
JSONObject jfailed = new JSONObject();
foreach (TIDENT id in collectionResult.Failed.Keys)
{
jfailed.Add(id.ToString(), new JSONString(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 JSONObject Descriptor { get; set; }
}
}
}