示例#1
0
        private static MethodHandler <SemanticDocument> BuildPostHandlerForMethodInfo(MethodInfoNode methodNode,
                                                                                      ServiceLocatorDelegate serviceLocator)
        {
            MethodHandler <SemanticDocument> .InvokeMethodDelegate invoke2 = async(submittedArgs) =>
            {
                var argsEnumerator = submittedArgs.GetEnumerator();
                var argsList       = methodNode.MethodInfo.GetParameters()
                                     .Select(pi =>
                {
                    if (pi.GetCustomAttribute <InjectAttribute>() != null)
                    {
                        if (serviceLocator == null)
                        {
                            throw new InvalidOperationException(
                                $"Cannot [Inject] parameter {pi.Name} for {methodNode.MethodInfo.DeclaringType.Name}.{methodNode.MethodInfo.DeclaringType.Name} Please set ServiceLocator at startup");
                        }
                        return(serviceLocator(pi.ParameterType));
                    }
                    else
                    {
                        argsEnumerator.MoveNext();
                        var current = argsEnumerator.Current;
                        if (current.Item1 != new UrlPart(pi.Name))
                        {
                            throw new ArgumentException("Mismatch: expected " + pi.Name + ", received" +
                                                        current.Item1.ToString());
                        }
                        return(Tuple.Create(current.Item2, null as Action));
                    }
                }).ToList();
                var parameters   = argsList.Select(a => a.Item1).ToArray();
                var invokeResult = methodNode.MethodInfo.Invoke(methodNode.Parent, parameters);
                foreach (var tuple in argsList)
                {
                    tuple.Item2?.Invoke();
                }

                if (methodNode.MethodInfo.ReturnType == typeof(void))
                {
                }
                var task = invokeResult as Task;
                if (task != null)
                {
                    await task;
                    invokeResult = task.GetType().GetRuntimeProperty("Result")?.GetValue(task) ?? invokeResult;
                }
                var representation = new SemanticDocument();


                //Add a link back to the thing that the action happened to
                {
                    OneOf.OneOf <Modified, Created> result = default(OneOf.OneOf <Modified, Created>);
                    if (invokeResult is Created)
                    {
                        result = (Created)invokeResult;
                    }
                    if (invokeResult is Modified)
                    {
                        result = (Modified)invokeResult;
                    }
                    if (invokeResult is AbstractNode)
                    {
                        result = new Created((AbstractNode)invokeResult);
                    }
                    result = new Modified(methodNode.Parent);

                    result.Switch(
                        modified => representation.AddLink(Links.CreateLink($"Modified \'{modified.Node.Title}\'",
                                                                            modified.Node.Uri, modified.Node.Term)),
                        created => representation.AddLink(Links.CreateLink($"Created \'{created.Node.Title}\'",
                                                                           created.Node.Uri, created.Node.Term)));
                }

                representation.Value.Add(SemanticProperty.CreateValue(Terms.Title, JToken.FromObject(methodNode.Title)));
                return(new InvokeResult <SemanticDocument> .RepresentationResult(representation));
            };

            var parameterInfo = methodNode.GetParameters();

            return(new MethodHandler <SemanticDocument>(new Method.Post(), parameterInfo, invoke2));
        }
示例#2
0
        public static Router <SemanticDocument> MakeHypermediaRouterFromRootNode(RootNode root, ServiceLocatorDelegate serviceLocator)
        {
            return(async url =>
            {
                var nodeRouter = RouteByWalkingNode(root);

                var oneOf = await nodeRouter(url);

                var router = oneOf.Match <OneOf <Resource <SemanticDocument>, None> >(
                    node => Functions.MakeResourceFromNode(node, serviceLocator),
                    none => none
                    );

                return router;
            });
        }
示例#3
0
        public static Resource <SemanticDocument> MakeResourceFromNode(AbstractNode node, ServiceLocatorDelegate serviceLocator)
        {
            var rules = new List <IAbstractNodeToSemanticDocumentMappingRule>()
            {
                new TheNodeTitleWillBeAddedAsAProperty(),
                new ThereWillBeALinkToTheParentNodeInTheDocument(),
                new ImplementingIHasChildNodesWillExposeTheItemsAsNodeResources(),
                new ImplementingIHasHyperlinksWillAddALinkPropertyToDocument(),
                new MarkingAPropertyWithExposeAttributeWillAddAValuePropertyToDocument(),
                new MarkingAMethodWithExposeAttributeWillAddTheMethodAsAnActionResource(),
            };

            var methodNode = node as MethodInfoNode;

            if (methodNode != null)
            {
                return(new Resource <SemanticDocument>(new[]
                {
                    BuildGetHandlerForMethodInfo(methodNode),
                    BuildPostHandlerForMethodInfo(methodNode, serviceLocator)
                }));
            }

            var methodHandlers = new[]
            {
                new MethodHandler <SemanticDocument>(new Method.Get(), new MethodParameter[0], arguments =>
                {
                    var doc = new SemanticDocument();
                    foreach (var mappingRule in rules)
                    {
                        mappingRule.Apply(node, doc);
                    }
                    return(Task.FromResult <InvokeResult <SemanticDocument> >(new InvokeResult <SemanticDocument> .RepresentationResult(doc)));
                })
            };

            return(new Resource <SemanticDocument>(methodHandlers.ToArray()));
        }
示例#4
0
        public static IAppBuilder ExposeRootNodeAsHypermediaApi(this IAppBuilder appBuilder, RootNode root, ServiceLocatorDelegate serviceLocatorDelegate, Representor <SemanticDocument>[] representors)
        {
            var            router          = NodeRouting.MakeHypermediaRouterFromRootNode(root, serviceLocatorDelegate);
            FindUriForTerm locatorDelegate = term => root.GlossaryNode.GetUriForTerm(term);

            return(appBuilder.ExposeRouterAsHypermediaApi(router, locatorDelegate, representors, root.Uri.ToString()));
        }