示例#1
0
        public void SectionMerge_6()
        {
            var conf1 = "r{ a{} c{}}".AsLaconicConfig(handling: ConvertErrorHandling.Throw);
            var conf2 = "r{ b{ z = 134 } c{name='id1' y=456} c{name='id2' z=789 } c{ gg=123}}".AsLaconicConfig(handling: ConvertErrorHandling.Throw);

            var rules = new NodeOverrideRules {
                AppendSectionsWithoutMatchAttr = true
            };

            conf1.OverrideBy(conf2, rules);

            Aver.AreEqual(6, conf1.ChildCount); //<-- 6 because names are different, but 6th gets added due to rules
            Aver.IsTrue(conf1.Navigate("/a").Exists);
            Aver.IsTrue(conf1.Navigate("/b").Exists);
            Aver.IsTrue(conf1.Navigate("/c").Exists);
            Aver.IsTrue(conf1.Navigate("/c[name=id1]").Exists);
            Aver.IsTrue(conf1.Navigate("/c[name=id2]").Exists);
            Aver.IsTrue(conf1.Navigate("/c[gg=123]").Exists);
            Aver.IsTrue(conf1.Navigate("/b/$z").Exists);
            Aver.AreEqual(134, conf1.Navigate("/b/$z").ValueAsInt());

            Aver.IsTrue(conf1.Navigate("/c[gg=123]/$gg").Exists);
            Aver.IsTrue(conf1.Navigate("/c[name=id1]/$y").Exists);
            Aver.IsTrue(conf1.Navigate("/c[name=id2]/$z").Exists);

            Aver.AreEqual(123, conf1.Navigate("/c[gg=123]/$gg").ValueAsInt());
            Aver.AreEqual(456, conf1.Navigate("/c[name=id1]/$y").ValueAsInt());
            Aver.AreEqual(789, conf1.Navigate("/c[name=id2]/$z").ValueAsInt());
        }
示例#2
0
        public void SectionMerge_3()
        {
            var conf1 = "r{ a{} c{}}".AsLaconicConfig(handling: ConvertErrorHandling.Throw);
            var conf2 = "r{ b{ z = 134 } c{ y=456} c{z=789 }}".AsLaconicConfig(handling: ConvertErrorHandling.Throw);

            var rules = new NodeOverrideRules {
                AppendSectionsWithoutMatchAttr = true
            };

            conf1.OverrideBy(conf2, rules);

            Aver.AreEqual(5, conf1.ChildCount);//<---- 5 because all "C" get appended
            Aver.IsTrue(conf1.Navigate("/a").Exists);
            Aver.IsTrue(conf1.Navigate("/b").Exists);
            Aver.IsTrue(conf1.Navigate("/c").Exists);
            Aver.IsTrue(conf1.Navigate("/b/$z").Exists);
            Aver.AreEqual(134, conf1.Navigate("/b/$z").ValueAsInt());

            Aver.IsTrue(conf1.Navigate("/c[y=456]").Exists);
            Aver.IsTrue(conf1.Navigate("/c[z=789]").Exists);

            Aver.AreEqual(456, conf1.Navigate("/c[y=456]/$y").ValueAsInt());
            Aver.AreEqual(789, conf1.Navigate("/c[z=789]/$z").ValueAsInt());
        }
示例#3
0
        public override ConfigSectionNode ProvideMetadata(MemberInfo member, object instance, IMetadataGenerator context, ConfigSectionNode dataRoot, NodeOverrideRules overrideRules = null)
        {
            if (instance is ReleaseAttribute release)
            {
                var node = dataRoot.AddChildNode("release");
                node.AddAttributeNode("type", release.Type);
                node.AddAttributeNode("utc", release.ReleaseTimestampUtc);
                node.AddAttributeNode("title", release.Title);

                if (release.Tags.IsNotNullOrWhiteSpace())
                {
                    node.AddAttributeNode("tags", release.Tags);
                }

                if (release.Description.IsNotNullOrWhiteSpace())
                {
                    node.AddAttributeNode("descr", release.Description);
                }

                if (context.DetailLevel > MetadataDetailLevel.Public)
                {
                    if (release.Metadata.IsNotNullOrWhiteSpace())
                    {
                        node.AddAttributeNode("meta", release.Metadata);
                    }
                }
            }

            return(dataRoot);
        }
示例#4
0
        public override ConfigSectionNode ProvideMetadata(MemberInfo member, object instance, IMetadataGenerator context, ConfigSectionNode dataRoot, NodeOverrideRules overrideRules = null)
        {
            var tperm = member.NonNull(nameof(member)) as Type;

            if (tperm == null || !typeof(Permission).IsAssignableFrom(tperm))
            {
                return(null);
            }

            var node = dataRoot.AddChildNode("permission");

            MetadataUtils.AddMetadataTokenIdAttribute(node, tperm);
            if (instance is Permission perm)
            {
                node.AddAttributeNode("name", perm.Name);
                node.AddAttributeNode("path", perm.Path);
                node.AddAttributeNode("description", perm.Description);
                node.AddAttributeNode("level", perm.Level);
            }
            else
            {
                node.AddAttributeNode("name", tperm.Name.Replace("Permission", string.Empty));
                node.AddAttributeNode("ns", tperm.Namespace);
            }
            return(dataRoot);
        }
        public override ConfigSectionNode ProvideMetadata(MemberInfo member, object instance, IMetadataGenerator context, ConfigSectionNode dataRoot, NodeOverrideRules overrideRules = null)
        {
            if (member is Type tController && instance is ApiDocGenerator.ControllerContext apictx)
            {
                var apiAttr = tController.GetCustomAttribute <ApiControllerDocAttribute>();
                if (apiAttr != null)
                {
                    return(describe(tController, instance, apictx, dataRoot, overrideRules));
                }
            }

            return(null);
        }
        private ConfigSectionNode describe(Type tController, object instance, ApiDocGenerator.ControllerContext apictx, ConfigSectionNode dataRoot, NodeOverrideRules overrideRules)
        {
            var cdata          = dataRoot.AddChildNode("scope");
            var cattr          = apictx.ApiDocAttr;
            var docContent     = tController.GetText(cattr.DocFile ?? "{0}.md".Args(tController.Name));
            var ctlTitle       = MarkdownUtils.GetTitle(docContent);
            var ctlDescription = MarkdownUtils.GetTitleDescription(docContent);

            (var drequest, var dresponse) = writeCommon(ctlTitle, ctlDescription, tController, apictx.Generator, cattr, cdata);
            cdata.AddAttributeNode("uri-base", cattr.BaseUri);
            cdata.AddAttributeNode("auth", cattr.Authentication);

            cdata.AddAttributeNode("doc-content", docContent);

            var allMethodContexts = apictx.Generator.GetApiMethods(tController, apictx.ApiDocAttr);

            foreach (var mctx in allMethodContexts)
            {
                var edata = cdata.AddChildNode("endpoint");
                (var mrequest, var mresponse) = writeCommon(null, null, mctx.Method, apictx.Generator, mctx.ApiEndpointDocAttr, edata);

                var epuri = mctx.ApiEndpointDocAttr.Uri.AsString().Trim();
                if (epuri.IsNullOrWhiteSpace())
                {
                    // infer from action attribute
                    var action = mctx.Method.GetCustomAttributes <ActionBaseAttribute>().FirstOrDefault();
                    if (action != null)
                    {
                        epuri = action.Name;
                    }
                    if (epuri.IsNullOrWhiteSpace())
                    {
                        epuri = mctx.Method.Name;
                    }
                }


                if (!epuri.StartsWith("/"))
                {
                    var bu = cattr.BaseUri.Trim();
                    if (!bu.EndsWith("/"))
                    {
                        bu += "/";
                    }
                    epuri = bu + epuri;
                }

                edata.AddAttributeNode("uri", epuri);
                writeCollection(mctx.ApiEndpointDocAttr.Methods, "method", mrequest, ':');

                //docAnchor
                var docAnchor = mctx.ApiEndpointDocAttr.DocAnchor.Default("### " + epuri);
                edata.AddAttributeNode("doc-content", MarkdownUtils.GetSectionContent(docContent, docAnchor));

                //Get all method attributes except ApiDoc
                var epattrs = mctx.Method
                              .GetCustomAttributes(true)
                              .Where(a => !(a is ApiDocAttribute) && !(a is ActionBaseAttribute));

                writeInstanceCollection(epattrs.Where(a => !(a is IInstanceCustomMetadataProvider) ||
                                                      (a is IInstanceCustomMetadataProvider cip &&
                                                       cip.ShouldProvideInstanceMetadata(apictx.Generator, edata))).ToArray(), TYPE_REF, edata, apictx.Generator);

                writeTypeCollection(epattrs.Select(a => a.GetType())
                                    .Where(t => !apictx.Generator.IsWellKnownType(t))
                                    .Distinct()
                                    .ToArray(),
                                    TYPE_REF, edata, apictx.Generator);//distinct attr types

                //todo Get app parameters look for Docs and register them and also permissions
                var epargs = mctx.Method.GetParameters()
                             .Where(pi => !pi.IsOut && !pi.ParameterType.IsByRef && !apictx.Generator.IsWellKnownType(pi.ParameterType))
                             .Select(pi => pi.ParameterType).ToArray();
                writeTypeCollection(epargs, TYPE_REF, edata, apictx.Generator);
            }

            return(cdata);
        }
        private ConfigSectionNode describe(Type tController, object instance, ApiDocGenerator.ControllerContext apictx, ConfigSectionNode dataRoot, NodeOverrideRules overrideRules)
        {
            var cdata          = dataRoot.AddChildNode("scope");
            var cattr          = apictx.ApiDocAttr;
            var docContent     = tController.GetText(cattr.DocFile ?? "{0}.md".Args(tController.Name));
            var ctlTitle       = MarkdownUtils.GetTitle(docContent);
            var ctlDescription = MarkdownUtils.GetTitleDescription(docContent);

            (var drequest, var dresponse) = writeCommon(ctlTitle, ctlDescription, tController, apictx.Generator, cattr, cdata);
            cdata.AddAttributeNode("uri-base", cattr.BaseUri);
            cdata.AddAttributeNode("auth", cattr.Authentication);

            cdata.AddAttributeNode("doc-content-tpl", docContent);

            var allMethodContexts = apictx.Generator.GetApiMethods(tController, apictx.ApiDocAttr);

            foreach (var mctx in allMethodContexts)
            {
                var edata = cdata.AddChildNode("endpoint");
                (var mrequest, var mresponse) = writeCommon(null, null, mctx.Method, apictx.Generator, mctx.ApiEndpointDocAttr, edata);

                var epuri = mctx.ApiEndpointDocAttr.Uri.AsString().Trim();
                if (epuri.IsNullOrWhiteSpace())
                {
                    // infer from action attribute
                    var action = mctx.Method.GetCustomAttributes <ActionBaseAttribute>().FirstOrDefault();
                    if (action != null)
                    {
                        epuri = action.Name;
                    }
                    if (epuri.IsNullOrWhiteSpace())
                    {
                        epuri = mctx.Method.Name;
                    }
                }


                if (!epuri.StartsWith("/"))
                {
                    var bu = cattr.BaseUri.Trim();
                    if (!bu.EndsWith("/"))
                    {
                        bu += "/";
                    }
                    epuri = bu + epuri;
                }

                edata.AddAttributeNode("uri", epuri);
                writeCollection(mctx.ApiEndpointDocAttr.Methods, "method", mrequest, ':');

                //Get all method attributes except ApiDoc
                var epattrs = mctx.Method
                              .GetCustomAttributes(true)
                              .Where(a => !(a is ApiDocAttribute) &&
                                     !(a is ActionBaseAttribute) &&
                                     !apictx.Generator.IgnoreTypePatterns.Any(ignore => a.GetType().FullName.MatchPattern(ignore))
                                     );

                writeInstanceCollection(epattrs.Where(a => !(a is IInstanceCustomMetadataProvider) ||
                                                      (a is IInstanceCustomMetadataProvider cip &&
                                                       cip.ShouldProvideInstanceMetadata(apictx.Generator, edata))).ToArray(), TYPE_REF, edata, apictx.Generator);

                writeTypeCollection(epattrs.Select(a => a.GetType())
                                    .Where(t => !apictx.Generator.IsWellKnownType(t))
                                    .Distinct()
                                    .ToArray(),
                                    TYPE_REF, edata, apictx.Generator);//distinct attr types

                //get method parameters
                var epargs = mctx.Method.GetParameters()
                             .Where(pi => !pi.IsOut &&
                                    !pi.ParameterType.IsByRef &&
                                    !apictx.Generator.IsWellKnownType(pi.ParameterType) &&
                                    !apictx.Generator.IgnoreTypePatterns.Any(ignore => pi.ParameterType.FullName.MatchPattern(ignore))
                                    )
                             .Select(pi => pi.ParameterType).ToArray();
                writeTypeCollection(epargs, TYPE_REF, edata, apictx.Generator);

                //docAnchor
                var docAnchor    = mctx.ApiEndpointDocAttr.DocAnchor.Default("### " + epuri);
                var epDocContent = MarkdownUtils.GetSectionContent(docContent, docAnchor);

                edata.AddAttributeNode("doc-content-tpl", epDocContent);

                //finally regenerate doc content expanding all variables
                epDocContent = MarkdownUtils.EvaluateVariables(epDocContent, (v) =>
                {
                    if (v.IsNullOrWhiteSpace())
                    {
                        return(v);
                    }
                    //Escape: ``{{a}}`` -> `{a}`
                    if (v.StartsWith("{") && v.EndsWith("}"))
                    {
                        return(v.Substring(1, v.Length - 2));
                    }
                    if (v.StartsWith("@"))
                    {
                        return($"`{{{v}}}`");        //do not expand TYPE spec here
                    }
                    //else navigate config path
                    return(edata.Navigate(v).Value);
                });

                edata.AddAttributeNode("doc-content", epDocContent);
            }//all endpoints

            //finally regenerate doc content expanding all variables for the controller
            docContent = MarkdownUtils.EvaluateVariables(docContent, (v) =>
            {
                if (v.IsNullOrWhiteSpace())
                {
                    return(v);
                }
                //Escape: ``{{a}}`` -> `{a}`
                if (v.StartsWith("{") && v.EndsWith("}"))
                {
                    return(v.Substring(1, v.Length - 2));
                }
                if (v.StartsWith("@"))
                {
                    return($"`{{{v}}}`");          //do not expand TYPE spec here
                }
                //else navigate config path
                return(cdata.Navigate(v).Value);
            });

            cdata.AddAttributeNode("doc-content", docContent);

            return(cdata);
        }
示例#8
0
 public override ConfigSectionNode ProvideInstanceMetadata(IMetadataGenerator context, ConfigSectionNode dataRoot, NodeOverrideRules overrideRules = null)
 {
     dataRoot.AddAttributeNode("max-content-length", MaxContentLength);
     return(dataRoot);
 }
            public override ConfigSectionNode ProvideMetadata(MemberInfo member, object instance, IMetadataGenerator context, ConfigSectionNode dataRoot, NodeOverrideRules overrideRules = null)
            {
                var data = "score=110 description='Cars built in Japan' origin{_override=stop country=jap} z=1".AsLaconicConfig();

                dataRoot.MergeAttributes(data);
                dataRoot.MergeSections(data);
                return(dataRoot);
            }
            public override ConfigSectionNode ProvideMetadata(MemberInfo member, object instance, IMetadataGenerator context, ConfigSectionNode dataRoot, NodeOverrideRules overrideRules = null)
            {
                var data = "description='Honda motors'".AsLaconicConfig();

                dataRoot.MergeAttributes(data);
                dataRoot.MergeSections(data);
                return(dataRoot);
            }
            public override ConfigSectionNode ProvideMetadata(MemberInfo member, object instance, IMetadataGenerator context, ConfigSectionNode dataRoot, NodeOverrideRules overrideRules = null)
            {
                var data = "score=40 description='Luxury item, but unreliable'  origin{country=XYZYZ/*this will never take effect*/}".AsLaconicConfig();

                dataRoot.MergeAttributes(data);
                dataRoot.MergeSections(data);
                return(dataRoot);
            }
            public override ConfigSectionNode ProvideMetadata(MemberInfo member, object instance, IMetadataGenerator context, ConfigSectionNode dataRoot, NodeOverrideRules overrideRules = null)
            {
                var data = "score=90 description='Very usable and decent quality' a=-900".AsLaconicConfig();

                dataRoot.MergeAttributes(data);
                dataRoot.MergeSections(data);
                return(dataRoot);
            }
            public override ConfigSectionNode ProvideMetadata(MemberInfo member, object instance, IMetadataGenerator context, ConfigSectionNode dataRoot, NodeOverrideRules overrideRules = null)
            {
                var data = "a=123 b=789 score=100 description='Generic car' origin{_override=all country=world} z=0".AsLaconicConfig();

                dataRoot.MergeAttributes(data);
                dataRoot.MergeSections(data);
                return(dataRoot);
            }
示例#14
0
 /// <summary>
 /// Called by various metadata consumers to get additional metadata about the decorated type
 /// </summary>
 /// <param name="member">A member (e.g. a type or a method) which is being described</param>
 /// <param name="instance">
 /// Optional instance of Type when member represents a type, this way the metadata may depend on instance,
 /// e.g. when generating permissions the instance contains the required access level
 /// </param>
 /// <param name="context">IMetadataGenerator context in which the metadata acquisition takes place</param>
 /// <param name="dataRoot">Root data node under which THIS entity is supposed to create its sub-node to provide its metadata into</param>
 /// <param name="overrideRules">Config node override rules to use for structured merging, or null to use the defaults</param>
 /// <returns>A new data node that this provider has written into, such as a new node which is a child of dataRoot</returns>
 public abstract ConfigSectionNode ProvideMetadata(MemberInfo member, object instance, IMetadataGenerator context, ConfigSectionNode dataRoot, NodeOverrideRules overrideRules = null);
示例#15
0
        public override ConfigSectionNode ProvideMetadata(MemberInfo member, object instance, IMetadataGenerator context, ConfigSectionNode dataRoot, NodeOverrideRules overrideRules = null)
        {
            var tdoc = member.NonNull(nameof(member)) as Type;

            if (tdoc == null || !typeof(Doc).IsAssignableFrom(tdoc))
            {
                return(null);
            }

            var typed = tdoc.IsSubclassOf(typeof(TypedDoc));

            var    ndoc = dataRoot.AddChildNode("data-doc");
            Schema schema;

            if (instance is Doc doc)
            {
                schema = doc.Schema;
            }
            else if (typed)
            {
                schema = Schema.GetForTypedDoc(tdoc);
            }
            else
            {
                schema = null;
            }

            MetadataUtils.AddMetadataTokenIdAttribute(ndoc, tdoc);
            ndoc.AddAttributeNode("kind", typed ? "typed" : "dynamic");

            CustomMetadataAttribute.Apply(typeof(Schema), schema, context, ndoc, overrideRules);

            return(ndoc);
        }
示例#16
0
        public override ConfigSectionNode ProvideMetadata(MemberInfo member, object instance, IMetadataGenerator context, ConfigSectionNode dataRoot, NodeOverrideRules overrideRules = null)
        {
            var schema = instance as Schema;//is a sealed class by design

            if (schema == null)
            {
                return(null);
            }

            var ndoc = dataRoot.AddChildNode("schema");

            if (context.DetailLevel > MetadataDetailLevel.Public)
            {
                ndoc.AddAttributeNode("name", schema.Name);
            }
            else
            {
                ndoc.AddAttributeNode("name", schema.TypedDocType?.Name ?? schema.Name);
            }

            ndoc.AddAttributeNode("read-only", schema.ReadOnly);

            TypedDoc doc = null;

            if (schema.TypedDocType != null)
            {
                ndoc.AddAttributeNode("typed-doc-type", context.AddTypeToDescribe(schema.TypedDocType));

                if (!schema.TypedDocType.IsAbstract)
                {
                    try
                    { //this may fail because there may be constructor incompatibility, then we just can get instance-specific metadata
                        doc = Activator.CreateInstance(schema.TypedDocType, true) as TypedDoc;
                        context.App.InjectInto(doc);
                    }
                    catch { }
                }
            }

            foreach (var def in schema)
            {
                var nfld = ndoc.AddChildNode("field");
                try
                {
                    var targetName = context.GetSchemaDataTargetName(schema, doc);
                    field(targetName, def, context, nfld, doc);
                }
                catch (Exception error)
                {
                    var err = new CustomMetadataException(StringConsts.METADATA_GENERATION_SCHEMA_FIELD_ERROR.Args(schema.Name, def.Name, error.ToMessageWithType()), error);
                    nfld.AddAttributeNode("--ERROR--", StringConsts.METADATA_GENERATION_SCHEMA_FIELD_ERROR.Args(schema.Name, def.Name, "<logged>"));
                    context.ReportError(Log.MessageType.CriticalAlert, err);
                }
            }

            return(ndoc);
        }
示例#17
0
 public virtual ConfigSectionNode ProvideInstanceMetadata(IMetadataGenerator context, ConfigSectionNode dataRoot, NodeOverrideRules overrideRules = null)
 => dataRoot;