Пример #1
0
        /// <summary>
        /// TODO: extract to base class together with class ApplyOverrideDocument
        /// </summary>
        /// <param name="models"></param>
        /// <param name="host"></param>
        private void ApplyOverrides(ImmutableList <FileModel> models, IHostService host)
        {
            foreach (var uid in host.GetAllUids())
            {
                var ms       = host.LookupByUid(uid);
                var od       = ms.Where(m => m.Type == DocumentType.Override).ToList();
                var articles = ms.Except(od).ToList();
                if (articles.Count == 0 || od.Count == 0)
                {
                    continue;
                }

                if (od.Count > 1)
                {
                    var uidDefinitions = od[0].Uids.Where(u => u.Name == uid);
                    var errorMessage   = string.Join(",", uidDefinitions.Select(s => $"\"{s.File}\" Line {s.Line}"));
                    throw new DocumentException($"UID \"{uid}\" is defined in multiple places: {errorMessage}. Only one overwrite document is allowed per particular UID.");
                }

                var ovm = ((List <RestApiItemViewModel>)od[0].Content).Single(vm => vm.Uid == uid);
                foreach (
                    var pair in
                    from model in articles
                    from item in new RestApiItemViewModel[] { (RestApiItemViewModel)model.Content }.Concat(((RestApiItemViewModel)model.Content).Children)
                    where item.Uid == uid
                    select new { model, item })
                {
                    var vm = pair.item;
                    Merger.Merge(ref vm, ovm);
                    vm.Metadata = MergeMetadata(vm.Metadata, ovm.Metadata);
                    ((HashSet <string>)pair.model.Properties.LinkToUids).UnionWith((HashSet <string>)od[0].Properties.LinkToUids);
                    ((HashSet <string>)pair.model.Properties.LinkToFiles).UnionWith((HashSet <string>)od[0].Properties.LinkToFiles);
                }
            }
        }
Пример #2
0
 private void FillCore(PageViewModel model, IHostService host)
 {
     if (model.References == null || model.References.Count == 0)
     {
         return;
     }
     foreach (var r in model.References)
     {
         var m = host.LookupByUid(r.Uid).Find(x => x.Type == DocumentType.Article);
         if (m == null)
         {
             continue;
         }
         var page = (PageViewModel)m.Content;
         var item = page.Items.Find(x => x.Uid == r.Uid);
         if (item == null)
         {
             continue;
         }
         r.Summary  = item.Summary;
         r.Type     = item.Type;
         r.Syntax   = item.Syntax;
         r.Platform = item.Platform;
     }
 }
Пример #3
0
 private void FillCore(PageViewModel model, IHostService host, string file)
 {
     TraceSourceInfo(model, file);
     if (model.References == null || model.References.Count == 0)
     {
         return;
     }
     foreach (var r in model.References)
     {
         var m = host.LookupByUid(r.Uid).Find(x => x.Type == DocumentType.Article);
         if (m == null)
         {
             SourceInfo i;
             if (_items.TryGetValue(r.Uid, out i))
             {
                 FillContent(r, i);
             }
             continue;
         }
         var page = (PageViewModel)m.Content;
         var item = page.Items.Find(x => x.Uid == r.Uid);
         if (item == null)
         {
             continue;
         }
         FillContent(r, item);
     }
 }
Пример #4
0
 private void ApplyOverrides(ImmutableList<FileModel> models, IHostService host)
 {
     foreach (var uid in host.GetAllUids())
     {
         var ms = host.LookupByUid(uid);
         var od = ms.SingleOrDefault(m => m.Type == DocumentType.Override);
         if (od != null)
         {
             var ovm = ((List<ItemViewModel>)od.Content).Single(vm => vm.Uid == uid);
             foreach (
                 var pair in
                     from model in ms
                     where model.Type == DocumentType.Article
                     from item in ((PageViewModel)model.Content).Items
                     where item.Uid == uid
                     select new { model, item })
             {
                 var vm = pair.item;
                 // todo : fix file path
                 Merger.Merge(ref vm, ovm);
                 ((HashSet<string>)pair.model.Properties.LinkToUids).UnionWith((HashSet<string>)od.Properties.LinkToUids);
                 ((HashSet<string>)pair.model.Properties.LinkToFiles).UnionWith((HashSet<string>)od.Properties.LinkToFiles);
             }
         }
     }
 }
Пример #5
0
 private void FillCore(PageViewModel model, IHostService host)
 {
     if (model.References == null || model.References.Count == 0)
     {
         return;
     }
     foreach (var r in model.References)
     {
         var m = host.LookupByUid(r.Uid).Find(x => x.Type == DocumentType.Article);
         if (m == null)
         {
             continue;
         }
         var page = (PageViewModel)m.Content;
         var item = page.Items.Find(x => x.Uid == r.Uid);
         if (item == null)
         {
             continue;
         }
         r.Additional["summary"] = item.Summary;
         r.Additional["type"] = item.Type;
         r.Additional["syntax"] = item.Syntax;
         r.Additional["platform"] = item.Platform;
     }
 }
Пример #6
0
 private void ApplyOverrides(ImmutableList <FileModel> models, IHostService host)
 {
     foreach (var uid in host.GetAllUids())
     {
         var ms = host.LookupByUid(uid);
         var od = ms.SingleOrDefault(m => m.Type == DocumentType.Override);
         if (od != null)
         {
             var ovm = ((List <ItemViewModel>)od.Content).Single(vm => vm.Uid == uid);
             foreach (
                 var pair in
                 from model in ms
                 where model.Type == DocumentType.Article
                 from item in ((PageViewModel)model.Content).Items
                 where item.Uid == uid
                 select new { model, item })
             {
                 var vm = pair.item;
                 // todo : fix file path
                 Merger.Merge(ref vm, ovm);
                 ((HashSet <string>)pair.model.Properties.LinkToUids).UnionWith((HashSet <string>)od.Properties.LinkToUids);
                 ((HashSet <string>)pair.model.Properties.LinkToFiles).UnionWith((HashSet <string>)od.Properties.LinkToFiles);
             }
         }
     }
 }
Пример #7
0
 public void Build(FileModel model, IHostService host)
 {
     if (model.Type == DocumentType.Article)
     {
         var contents = (IDictionary <string, object>)model.Content;
         if (contents.ContainsKey("related-topics"))
         {
             var newLinks = new List <Link>();
             var topics   = (string)contents["related-topics"];
             if (topics != null)
             {
                 foreach (var topic in topics.Split(','))
                 {
                     var found = host.LookupByUid(topic.Trim());
                     if (found != null && found.Count > 0)
                     {
                         var top         = found[0];
                         var topContents = (IDictionary <string, object>)top.Content;
                         var url         = (string)topContents["path"];
                         url = url.Substring(0, url.Length - 3); // cut off .md
                         newLinks.Add(new Link()
                         {
                             Title = (string)topContents["title"],
                             Url   = $"/{url}.html"
                         });
                     }
                 }
                 AddLinksDivToContents(contents, "related-topics", newLinks);
             }
         }
         if (contents.ContainsKey("links"))
         {
             var linkList = (List <object>)contents["links"];
             if (linkList != null)
             {
                 var newLinks = new List <Link>();
                 foreach (string mdLink in linkList)
                 {
                     var m = Regex.Match(mdLink, @"\[([^\]]+)\]\(([^\)]+)\)");
                     if (m.Success)
                     {
                         newLinks.Add(new Link()
                         {
                             Title = m.Groups[1].Value,
                             Url   = m.Groups[2].Value
                         });
                     }
                 }
                 AddLinksDivToContents(contents, "links", newLinks);
             }
         }
         model.Content = contents;
     }
 }
Пример #8
0
        protected virtual void ApplyOverwrites(ImmutableList <FileModel> models, IHostService host)
        {
            foreach (var uid in host.GetAllUids())
            {
                var ms       = host.LookupByUid(uid);
                var od       = ms.Where(m => m.Type == DocumentType.Overwrite).ToList();
                var articles = ms.Except(od).ToList();
                if (articles.Count == 0 || od.Count == 0)
                {
                    continue;
                }

                ApplyOverwrite(host, od, uid, articles);
            }
        }
Пример #9
0
        private void ApplyOverwrites(ImmutableList <FileModel> models, IHostService host)
        {
            foreach (var uid in host.GetAllUids())
            {
                var ms       = host.LookupByUid(uid);
                var od       = ms.Where(m => m.Type == DocumentType.Overwrite).ToList();
                var articles = ms.Except(od).ToList();
                if (articles.Count == 0 || od.Count == 0)
                {
                    continue;
                }

                // Multiple UID in overwrite documents is allowed now
                var ovms =
                    (from fm in od.Distinct()
                     from content in GetItemsFromOverwriteDocument(fm, uid, host)
                     select new
                {
                    model = content,
                    fileModel = fm
                }).ToList();

                if (ovms.Count == 0)
                {
                    continue;
                }

                // 1. merge all the overwrite document into one overwrite view model
                var ovm = ovms.Skip(1).Aggregate(ovms[0].model, (accum, item) => Merge(accum, item.model, item.fileModel));

                // 2. apply the view model to articles matching the uid
                foreach (
                    var pair in
                    from model in articles
                    from item in GetItemsToOverwrite(model, uid, host)
                    select new { model, item })
                {
                    var vm = pair.item;
                    Merge(vm, ovm, ovms[0].fileModel);
                    ((HashSet <string>)pair.model.Properties.LinkToUids).UnionWith((HashSet <string>)od[0].Properties.LinkToUids);
                    ((HashSet <string>)pair.model.Properties.LinkToFiles).UnionWith((HashSet <string>)od[0].Properties.LinkToFiles);
                }
            }
        }
Пример #10
0
        public override IEnumerable <FileModel> Prebuild(ImmutableList <FileModel> models, IHostService host)
        {
            host.LogInfo("Merging platform...");
            var processedUid = new HashSet <string>();
            var merged       = models.RunAll(m =>
            {
                if (m.Type != DocumentType.Article)
                {
                    return(m);
                }
                if (m.Uids.Length == 0)
                {
                    host.LogWarning("Unknown model without uid.", file: m.File);
                    return(m);
                }
                var mainUid = m.Uids[0].Name;
                if (processedUid.Contains(mainUid))
                {
                    return(null);
                }
                var sameTopics = host.LookupByUid(mainUid);
                if (sameTopics.Count == 1)
                {
                    return(m);
                }
                processedUid.Add(mainUid);
                var vm    = (PageViewModel)m.Content;
                m.Content = MergeCore(
                    mainUid,
                    m,
                    from topic in sameTopics
                    where topic != m
                    where topic.Type == DocumentType.Article
                    select topic,
                    host);
                return(m);
            });

            host.LogInfo("Platform merged.");
            return(from p in merged
                   where p != null
                   select p);
        }
 public override IEnumerable<FileModel> Prebuild(ImmutableList<FileModel> models, IHostService host)
 {
     host.LogInfo("Merging platform...");
     var processedUid = new HashSet<string>();
     var merged = models.RunAll(m =>
     {
         if (m.Type != DocumentType.Article)
         {
             return m;
         }
         if (m.Uids.Length == 0)
         {
             host.LogWarning("Unknown model without uid.", file: m.File);
             return m;
         }
         var mainUid = m.Uids[0];
         if (processedUid.Contains(mainUid))
         {
             return null;
         }
         var sameTopics = host.LookupByUid(mainUid);
         if (sameTopics.Count == 1)
         {
             return m;
         }
         processedUid.Add(mainUid);
         var vm = (PageViewModel)m.Content;
         m.Content = MergeCore(
             mainUid,
             m,
             from topic in sameTopics
             where topic != m
             where topic.Type == DocumentType.Article
             select topic,
             host);
         return m;
     });
     host.LogInfo("Platform merged.");
     return from p in merged
            where p != null
            select p;
 }
Пример #12
0
        public override void Postbuild(ImmutableList <FileModel> models, IHostService host)
        {
            var schemaProcessor = new SchemaProcessor(new MergeTypeInterpreter());

            foreach (var uid in host.GetAllUids())
            {
                var ms       = host.LookupByUid(uid);
                var od       = ms.Where(m => m.Type == DocumentType.Overwrite).ToList();
                var articles = ms.Except(od).ToList();
                if (articles.Count == 0 || od.Count == 0)
                {
                    continue;
                }

                if (articles.Count > 1)
                {
                    throw new DocumentException($"{uid} is defined in multiple articles {articles.Select(s => s.LocalPathFromRoot).ToDelimitedString()}");
                }
                var model = articles[0];
                var uids  = model.Properties.Uids;
                model.Content = schemaProcessor.Process(model.Content, model.Properties.Schema, new ProcessContext(host, model));
            }
        }
Пример #13
0
        private void ApplyOverwriteToModel(OverwriteApplier overwriteApplier, string uid, IHostService host)
        {
            var ms       = host.LookupByUid(uid);
            var ods      = ms.Where(m => m.Type == DocumentType.Overwrite).ToList();
            var articles = ms.Except(ods).ToList();

            if (articles.Count == 0 || ods.Count == 0)
            {
                return;
            }

            if (articles.Count > 1)
            {
                throw new DocumentException($"{uid} is defined in multiple articles {articles.Select(s => s.LocalPathFromRoot).ToDelimitedString()}");
            }

            var model  = articles[0];
            var schema = model.Properties.Schema as DocumentSchema;

            using (new LoggerFileScope(model.LocalPathFromRoot))
            {
                var uidDefiniton = model.Uids.Where(s => s.Name == uid).ToList();
                if (uidDefiniton.Count == 0)
                {
                    throw new DocfxException($"Unable to find UidDefinition for Uid {uid}");
                }

                try
                {
                    foreach (var ud in uidDefiniton)
                    {
                        var jsonPointer         = new JsonPointer(ud.Path).GetParentPointer();
                        var schemaForCurrentUid = jsonPointer.FindSchema(schema);
                        var source = jsonPointer.GetValue(model.Content);

                        foreach (var od in ods)
                        {
                            using (new LoggerFileScope(od.LocalPathFromRoot))
                            {
                                foreach (var fm in ((IEnumerable <OverwriteDocumentModel>)od.Content).Where(s => s.Uid == uid))
                                {
                                    // Suppose that BuildOverwriteWithSchema do the validation of the overwrite object
                                    var overwriteObject = overwriteApplier.BuildOverwriteWithSchema(od, fm, schemaForCurrentUid);
                                    overwriteApplier.MergeContentWithOverwrite(ref source, overwriteObject, ud.Name, string.Empty, schemaForCurrentUid);

                                    model.LinkToUids      = model.LinkToUids.Union(od.LinkToUids);
                                    model.LinkToFiles     = model.LinkToFiles.Union(od.LinkToFiles);
                                    model.FileLinkSources = model.FileLinkSources.Merge(od.FileLinkSources);
                                    model.UidLinkSources  = model.UidLinkSources.Merge(od.UidLinkSources);
                                }
                            }
                        }
                    }

                    // 1. Validate schema after the merge
                    // TODO: Issue exists - however unable to identify which overwrite document the issue is from
                    ((SchemaDrivenDocumentProcessor)host.Processor).SchemaValidator.Validate(model.Content);

                    // 2. Re-export xrefspec after the merge
                    overwriteApplier.UpdateXrefSpec(model, schema);
                }
                catch (DocumentException e)
                {
                    // Log error here to preserve file info
                    Logger.LogError(e.Message);
                    throw;
                }
            }
        }
Пример #14
0
        public override void Postbuild(ImmutableList<FileModel> models, IHostService host)
        {
            foreach (var uid in host.GetAllUids())
            {
                var ms = host.LookupByUid(uid);
                var ods = ms.Where(m => m.Type == DocumentType.Overwrite).ToList();
                var articles = ms.Except(ods).ToList();
                if (articles.Count == 0 || ods.Count == 0)
                {
                    continue;
                }

                if (articles.Count > 1)
                {
                    throw new DocumentException($"{uid} is defined in multiple articles {articles.Select(s => s.LocalPathFromRoot).ToDelimitedString()}");
                }

                var model = articles[0];
                var schema = model.Properties.Schema as DocumentSchema;
                using (new LoggerFileScope(model.LocalPathFromRoot))
                {
                    var uidDefiniton = model.Uids.Where(s => s.Name == uid).ToList();
                    if (uidDefiniton.Count == 0)
                    {
                        throw new DocfxException($"Unable to find UidDefinition for Uid {uid}");
                    }

                    foreach (var ud in uidDefiniton)
                    {
                        var jsonPointer = new JsonPointer(ud.Path).GetParentPointer();
                        var schemaForCurrentUid = jsonPointer.FindSchema(schema);
                        var source = jsonPointer.GetValue(model.Content);

                        foreach (var od in ods)
                        {
                            using (new LoggerFileScope(od.LocalPathFromRoot))
                            {
                                foreach (var fm in ((IEnumerable<OverwriteDocumentModel>)od.Content).Where(s => s.Uid == uid))
                                {
                                    // Suppose that BuildOverwriteWithSchema do the validation of the overwrite object
                                    var overwriteObject = BuildOverwriteWithSchema(od, fm, host, schemaForCurrentUid);
                                    _merger.Merge(ref source, overwriteObject, ud.Name, string.Empty, schemaForCurrentUid);

                                    model.LinkToUids = model.LinkToUids.Union(od.LinkToUids);
                                    model.LinkToFiles = model.LinkToFiles.Union(od.LinkToFiles);
                                    model.FileLinkSources = model.FileLinkSources.Merge(od.FileLinkSources);
                                    model.UidLinkSources = model.UidLinkSources.Merge(od.UidLinkSources);
                                }
                            }
                        }
                    }

                    // 1. Validate schema after the merge
                    ((SchemaDrivenDocumentProcessor)host.Processor).SchemaValidator.Validate(model.Content);

                    // 2. Re-export xrefspec after the merge
                    var context = new ProcessContext(host, model);
                    _xrefSpecUpdater.Process(model.Content, schema, context);

                    UpdateXRefSpecs((List<XRefSpec>)model.Properties.XRefSpecs, context.XRefSpecs);
                    UpdateXRefSpecs((List<XRefSpec>)model.Properties.ExternalXRefSpecs, context.ExternalXRefSpecs);
                }
            }
        }