static IEnumerable <Expression> WriteBeginObjectContext(ParameterExpression jsonWriter, Expression contextUri) { yield return(JsonWriterMethods.WriteRaw(jsonWriter, Nodes.BeginObjectContext)); yield return(JsonWriterMethods.WriteString(jsonWriter, contextUri)); yield return(JsonWriterMethods.WriteValueSeparator(jsonWriter)); }
static IEnumerable <Expression> WriteIdType(ParameterExpression jsonWriter, string type, Expression uri, ResourceModel model) { yield return(JsonWriterMethods.WriteRaw(jsonWriter, Nodes.IdProperty)); yield return(JsonWriterMethods.WriteString(jsonWriter, uri)); yield return(JsonWriterMethods.WriteValueSeparator(jsonWriter)); yield return(WritePropertyName(jsonWriter, "@type")); yield return(WriteString(jsonWriter, type)); }
static void WriteNodePropertyValue(ParameterExpression jsonWriter, Action <ParameterExpression> variable, Action <Expression> statement, PropertyInfo pi, ParameterExpression jsonFormatterResolver, MemberExpression propertyGet) { statement(JsonWriterMethods.WriteValueSeparator(jsonWriter)); var propertyName = GetJsonPropertyName(pi); statement(WritePropertyName(jsonWriter, propertyName)); var propertyType = pi.PropertyType; var(formatterInstance, serializeMethod) = GetFormatter(variable, statement, jsonFormatterResolver, propertyType); var serializeFormatter = Call(formatterInstance, serializeMethod, jsonWriter, propertyGet, jsonFormatterResolver); statement(serializeFormatter); }
static void WriteNodeProperty(ParameterExpression jsonWriter, Expression resource, Action <ParameterExpression> variable, Action <Expression> statement, MemberExpression uriResolverFunc, IMetaModelRepository models, Stack <ResourceModel> recursionDefender, PropertyInfo pi, ParameterExpression resolver) { var propertyStatements = new List <Expression>(); var propertyVars = new List <ParameterExpression>(); // var propertyValue; var propertyValue = Variable(pi.PropertyType, $"val{pi.DeclaringType.Name}{pi.Name}"); variable(propertyValue); // propertyValue = resource.Property; statement(Assign(propertyValue, MakeMemberAccess(resource, pi))); if (models.TryGetResourceModel(pi.PropertyType, out var propertyResourceModel)) { // property has a registration, it's either an iri node or a blank node propertyStatements.Add(JsonWriterMethods.WriteValueSeparator(jsonWriter)); propertyStatements.Add(WritePropertyName(jsonWriter, GetJsonPropertyName(pi))); propertyStatements.Add(JsonWriterMethods.WriteBeginObject(jsonWriter)); WriteNode(jsonWriter, propertyResourceModel, propertyValue, propertyVars.Add, propertyStatements.Add, uriResolverFunc, models, recursionDefender, resolver); propertyStatements.Add(JsonWriterMethods.WriteEndObject(jsonWriter)); } else { // not an iri node itself, but is it a list of nodes? var itemResourceRegistrations = ( from i in pi.PropertyType.GetInterfaces() where i.IsGenericType && i.GetGenericTypeDefinition() == typeof(IEnumerable <>) let itemType = i.GetGenericArguments()[0] where itemType != typeof(object) let resourceModels = models.ResourceRegistrations.Where(r => itemType.IsAssignableFrom(r.ResourceType)) where resourceModels.Any() orderby resourceModels.Count() descending select new { itemType, models = (from possible in resourceModels orderby possible.ResourceType.GetInheritanceDistance(itemType) select possible).ToList() }).FirstOrDefault(); if (itemResourceRegistrations == null) { // not a list of iri or blank nodes WriteNodePropertyValue(jsonWriter, propertyVars.Add, propertyStatements.Add, pi, resolver, MakeMemberAccess(resource, pi)); } else { // it's a list of nodes var itemArrayType = itemResourceRegistrations.itemType.MakeArrayType(); var itemArray = Variable(itemArrayType); var toArrayMethod = typeof(Enumerable).GetMethod("ToArray") .MakeGenericMethod(itemResourceRegistrations.itemType); var assign = Assign(itemArray, Call(toArrayMethod, propertyValue)); propertyVars.Add(itemArray); propertyStatements.Add(assign); var i = Variable(typeof(int)); propertyVars.Add(i); var initialValue = Assign(i, Constant(0)); propertyStatements.Add(initialValue); var itemVars = new List <ParameterExpression>(); var itemStatements = new List <Expression>(); var @break = Label("break"); propertyStatements.Add(JsonWriterMethods.WriteValueSeparator(jsonWriter)); propertyStatements.Add(WritePropertyName(jsonWriter, GetJsonPropertyName(pi))); propertyStatements.Add(JsonWriterMethods.WriteBeginArray(jsonWriter)); itemStatements.Add(IfThen(GreaterThan(i, Constant(0)), JsonWriterMethods.WriteValueSeparator(jsonWriter))); itemStatements.Add(JsonWriterMethods.WriteBeginObject(jsonWriter)); BlockExpression resourceBlock(ResourceModel r, ParameterExpression typed) { var vars = new List <ParameterExpression>(); var statements = new List <Expression>(); WriteNode( jsonWriter, r, typed, vars.Add, statements.Add, uriResolverFunc, models, recursionDefender, resolver); return(Block(vars.ToArray(), statements.ToArray())); } Expression renderBlock = Block(Throw(New(typeof(InvalidOperationException)))); // with C : B : A, if is C else if is B else if is A else throw foreach (var specificModel in itemResourceRegistrations.models) { var typed = Variable(specificModel.ResourceType, "as" + specificModel.ResourceType.Name); itemVars.Add(typed); var @as = Assign(typed, TypeAs(ArrayAccess(itemArray, i), specificModel.ResourceType)); renderBlock = IfThenElse( NotEqual(@as, Default(specificModel.ResourceType)), resourceBlock(specificModel, @typed), renderBlock); } itemStatements.Add(renderBlock); itemStatements.Add(PostIncrementAssign(i)); itemStatements.Add(JsonWriterMethods.WriteEndObject(jsonWriter)); var loop = Loop( IfThenElse( LessThan(i, MakeMemberAccess(itemArray, itemArrayType.GetProperty("Length"))), Block(itemVars.ToArray(), itemStatements.ToArray()), Break(@break)), @break ); propertyStatements.Add(loop); propertyStatements.Add(JsonWriterMethods.WriteEndArray(jsonWriter)); } } statement(IfThen( NotEqual(propertyValue, Default(pi.PropertyType)), Block(propertyVars.ToArray(), propertyStatements.ToArray()))); }