Exemplo n.º 1
0
        public static void ResourceDocument(ParameterExpression jsonWriter,
                                            ResourceModel model,
                                            Expression resource,
                                            Expression options,
                                            Action <ParameterExpression> variable,
                                            Action <Expression> statement, IMetaModelRepository models)
        {
            var uriResolverFunc = MakeMemberAccess(options, SerializationContextUriResolverPropertyInfo);

            var contextUri = StringConcat(
                Call(MakeMemberAccess(options, SerializationContextBaseUriPropertyInfo),
                     typeof(object).GetMethod(nameof(ToString))),
                Constant(".hydra/context.jsonld"));

            var resolver = Variable(typeof(CustomResolver), "resolver");

            variable(resolver);
            statement(Assign(resolver, New(typeof(CustomResolver))));

            foreach (var exp in WriteBeginObjectContext(jsonWriter, contextUri))
            {
                statement(exp);
            }

            WriteNode(jsonWriter, model, resource, variable, statement, uriResolverFunc, models, new Stack <ResourceModel>(),
                      resolver);

            statement(JsonWriterMethods.WriteEndObject(jsonWriter));
        }
Exemplo n.º 2
0
        Func <object, SerializationContext, Stream, Task> CreateDocumentSerializer(ResourceModel model,
                                                                                   IMetaModelRepository repository)
        {
            var renderer  = new List <Expression>();
            var variables = new List <ParameterExpression>();


            var resourceIn = Parameter(typeof(object), "resource");
            var options    = Parameter(typeof(SerializationContext), "options");
            var stream     = Parameter(typeof(Stream), "stream");
            var retVal     = Variable(typeof(Task), "retVal");

            var resource = Variable(model.ResourceType, "typedResource");

            renderer.Add(Assign(resource, Convert(resourceIn, model.ResourceType)));
            var jsonWriter = Variable(typeof(JsonWriter), "jsonWriter");
            var buffer     = Variable(typeof(ArraySegment <byte>), "buffer");


            renderer.Add(Assign(jsonWriter, New(typeof(JsonWriter))));

            TypeMethods.ResourceDocument(jsonWriter, model, resource, options, variables.Add, renderer.Add, repository);

            renderer.Add(Assign(buffer, JsonWriterMethods.GetBuffer(jsonWriter)));
            renderer.Add(Assign(retVal, ClassLibMethods.StreamWriteAsync(stream, buffer)));
            renderer.Add(retVal);

            var block  = Block(variables.Concat(new[] { jsonWriter, buffer, retVal, resource }).ToArray(), renderer);
            var lambda =
                Lambda <Func <object, SerializationContext, Stream, Task> >(block, "Render", new[] { resourceIn, options, stream });

            return(lambda.Compile());
        }
Exemplo n.º 3
0
        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));
        }
Exemplo n.º 4
0
        public static Expression WriteString(ParameterExpression jsonWriter, string value)
        {
            var writer = new JsonWriter();

            writer.WriteString(value);
            var bytes = writer.ToUtf8ByteArray();

            return(JsonWriterMethods.WriteRaw(jsonWriter, bytes));
        }
Exemplo n.º 5
0
        public static Expression WritePropertyName(ParameterExpression jsonWriter, string propertyName)
        {
            var writer = new JsonWriter();

            writer.WritePropertyName(propertyName);
            var bytes = writer.ToUtf8ByteArray();

            return(JsonWriterMethods.WriteRaw(jsonWriter, bytes));
        }
Exemplo n.º 6
0
        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));
        }
Exemplo n.º 7
0
        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);
        }
Exemplo n.º 8
0
        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())));
        }