/// <summary> /// If this IG is a new version of a previous IG, scan the templates for new versions and add them as an appendix /// </summary> private void LoadChangesAppendix() { List <IGDifferenceViewModel> lDifferences = new List <IGDifferenceViewModel>(); if (this.implementationGuide.PreviousVersionImplementationGuideId.HasValue) { VersionComparer lComparer = VersionComparer.CreateComparer(_tdb); var versionedTemplates = this._templates.Where(y => y.OwningImplementationGuideId == this.implementationGuide.Id); foreach (Template lChildTemplate in versionedTemplates) { IGDifferenceViewModel lModel = new IGDifferenceViewModel() { TemplateName = lChildTemplate.Name, TemplateOid = lChildTemplate.Oid, TemplateBookmark = lChildTemplate.Bookmark }; if (lChildTemplate.PreviousVersionTemplateId.HasValue) { Template lPreviousTemplate = _tdb.Templates.Single(t => t.Id == lChildTemplate.PreviousVersionTemplateId); lModel.Difference = lComparer.Compare(lPreviousTemplate, lChildTemplate); lDifferences.Add(lModel); } } this.LoadDifferencesAsAppendix(this.implementationGuide.Name, lDifferences); } }
public ActionResult ViewIgChanges(int id) { if (!CheckPoint.Instance.GrantViewImplementationGuide(id)) { throw new AuthorizationException("You do not have access to view this implementation guide's changes."); } ImplementationGuide lGuide = this.tdb.ImplementationGuides.Single(ig => ig.Id == id); ViewChangesModel lModel = new ViewChangesModel(); IGSettingsManager igSettings = new IGSettingsManager(this.tdb, lGuide.Id); IIGTypePlugin igTypePlugin = lGuide.ImplementationGuideType.GetPlugin(); VersionComparer lComparer = VersionComparer.CreateComparer(tdb, igTypePlugin, igSettings); lModel.IgName = lGuide.Name; // Modified templates foreach (Template lNewTemplate in lGuide.ChildTemplates.Where(t => t.PreviousVersionTemplateId.HasValue)) { Template lPreviousVersion = this.tdb.Templates.Single(t => t.Id == lNewTemplate.PreviousVersionTemplateId.Value); ComparisonResult lResult = lComparer.Compare(lPreviousVersion, lNewTemplate); lModel.TemplateDifferences.Add( new DifferenceModel(lResult) { Id = lNewTemplate.Id, IsAdded = false, TemplateName = lNewTemplate.Name, PreviousTemplateName = string.Format("{0} ({1})", lPreviousVersion.Name, lPreviousVersion.Oid), PreviousTemplateId = lPreviousVersion.Id, Difference = lResult, InlineConstraints = GetInlineConstraintChanges(lResult) }); } // Added templates foreach (Template lNewTemplate in lGuide.ChildTemplates.Where(t => !t.PreviousVersionTemplateId.HasValue)) { ComparisonResult lResult = lComparer.Compare(new Template(), lNewTemplate); lModel.TemplateDifferences.Add( new DifferenceModel(lResult) { Id = lNewTemplate.Id, IsAdded = true, TemplateName = lNewTemplate.Name }); } return(View(lModel)); }
public void VersionComparerTest1() { Template parentTemplate = this.mockRepo.GenerateTemplate("3.2.1.4.3", this.documentType, "Parent Template", this.ig); Template aTemplate = this.mockRepo.GenerateTemplate("1.2.3.4", this.documentType, "Test Template", this.ig, description: "Test Description 1"); aTemplate.IsOpen = false; this.mockRepo.GenerateConstraint(aTemplate, null, null, "id", "SHALL", "1..1", number: 1); this.mockRepo.GenerateConstraint(aTemplate, null, null, "effectiveTime", "SHALL", "1..1", number: 2); this.mockRepo.GenerateConstraint(aTemplate, null, null, "entryRelationship", "SHALL", "1..1", number: 3); Template bTemplate = this.mockRepo.GenerateTemplate("4.3.2.1", this.documentType, "New Test Template", this.ig, description: "Test Description 2", impliedTemplate: parentTemplate); bTemplate.IsOpen = true; this.mockRepo.GenerateConstraint(bTemplate, null, null, "id", "SHALL", "1..*", number: 1); this.mockRepo.GenerateConstraint(bTemplate, null, null, "entryRelationship", "SHALL", "1..1", number: 3); this.mockRepo.GenerateConstraint(bTemplate, null, null, "author", "SHALL", "1..1", number: 4); VersionComparer comparer = VersionComparer.CreateComparer(mockRepo); ComparisonResult compared = comparer.Compare(aTemplate, bTemplate); // Test template changes Assert.AreEqual(5, compared.ChangedFields.Count, "Expected to find 5 template fields changed"); var changedName = compared.ChangedFields.Single(y => y.Name == "Name"); Assert.AreEqual(aTemplate.Name, changedName.Old); Assert.AreEqual(bTemplate.Name, changedName.New); var changedDescription = compared.ChangedFields.Single(y => y.Name == "Description"); Assert.AreEqual(aTemplate.Description, changedDescription.Old); Assert.AreEqual(bTemplate.Description, changedDescription.New); var changedOid = compared.ChangedFields.Single(y => y.Name == "Oid"); Assert.AreEqual(aTemplate.Oid, changedOid.Old); Assert.AreEqual(bTemplate.Oid, changedOid.New); var changedImpliedTemplate = compared.ChangedFields.Single(y => y.Name == "Implied Template"); Assert.AreEqual("", changedImpliedTemplate.Old); Assert.AreEqual("Parent Template (3.2.1.4.3)", changedImpliedTemplate.New); var changedIsOpen = compared.ChangedFields.Single(y => y.Name == "Open/Closed"); Assert.AreEqual("Closed", changedIsOpen.Old); Assert.AreEqual("Open", changedIsOpen.New); // Test constraint changes Assert.AreEqual(4, compared.ChangedConstraints.Count, "Expected to find 3 changed constraints"); var removedConstraint = compared.ChangedConstraints.Single(y => y.Type == CompareStatuses.Removed); Assert.AreEqual("1-2", removedConstraint.Number); Assert.AreEqual(0, removedConstraint.ChangedFields.Count); Assert.IsFalse(string.IsNullOrEmpty(removedConstraint.OldNarrative)); var addedConstraint = compared.ChangedConstraints.Single(y => y.Type == CompareStatuses.Added); Assert.AreEqual("1-4", addedConstraint.Number); Assert.AreEqual(0, addedConstraint.ChangedFields.Count); Assert.IsFalse(string.IsNullOrEmpty(addedConstraint.NewNarrative)); var changedConstraint = compared.ChangedConstraints.Single(y => y.Type == CompareStatuses.Modified); Assert.AreEqual("1-1", changedConstraint.Number); Assert.IsFalse(string.IsNullOrEmpty(changedConstraint.NewNarrative)); Assert.IsFalse(string.IsNullOrEmpty(changedConstraint.OldNarrative)); Assert.AreNotEqual(changedConstraint.OldNarrative, changedConstraint.NewNarrative); Assert.AreEqual(1, changedConstraint.ChangedFields.Count); Assert.IsNotNull(changedConstraint.ChangedFields.SingleOrDefault(y => y.Name == "Cardinality")); var unchangedConstraint = compared.ChangedConstraints.Single(y => y.Type == CompareStatuses.Unchanged); Assert.AreEqual("1-3", unchangedConstraint.Number); }
public ViewDataModel GetExportData(int implementationGuideId, int?fileId, int[] templateIds, bool inferred) { ImplementationGuide ig = this.tdb.ImplementationGuides.Single(y => y.Id == implementationGuideId); ViewDataModel model = null; SimpleSchema schema = ig.ImplementationGuideType.GetSimpleSchema(); if (fileId != null) { var file = ig.Files.Single(y => y.Id == fileId); var fileData = file.GetLatestData(); if (file.ContentType != "DataSnapshot") { throw new Exception("File specified is not a data snapshot!"); } string fileDataContent = System.Text.Encoding.UTF8.GetString(fileData.Data); model = JsonConvert.DeserializeObject <ViewDataModel>(fileDataContent); model.ImplementationGuideFileId = fileId; } else { Log.For(this).Trace("Generating HTML export for " + implementationGuideId); IGSettingsManager igSettings = new IGSettingsManager(this.tdb, implementationGuideId); var igTypePlugin = ig.ImplementationGuideType.GetPlugin(); var firstTemplateType = ig.ImplementationGuideType.TemplateTypes.OrderBy(y => y.OutputOrder).FirstOrDefault(); var valueSets = ig.GetValueSets(this.tdb); var parentTemplateIds = templateIds != null?templateIds.ToList() : null; var templates = ig.GetQueryableRecursiveTemplates(this.tdb, parentTemplateIds, inferred) .IncludeDetails(true, true, true) .ToList(); var constraints = templates.SelectMany(y => y.ChildConstraints); var previousVersionIds = templates.Where(y => y.PreviousVersionTemplateId != null).Select(y => y.PreviousVersionTemplateId.Value).ToList(); var previousVersions = this.tdb.Templates.Where(y => previousVersionIds.Contains(y.Id)) .IncludeDetails(true, true, true) .ToList(); var containedTemplates = (from st in templates join vtr in this.tdb.ViewTemplateRelationships.AsNoTracking() on st.Id equals vtr.ParentTemplateId join t in this.tdb.Templates.AsNoTracking() on vtr.ChildTemplateId equals t.Id select new { Relationship = vtr, Template = t }).ToList(); var containedByTemplates = (from st in templates join vtr in this.tdb.ViewTemplateRelationships.AsNoTracking() on st.Id equals vtr.ChildTemplateId join t in this.tdb.Templates.AsNoTracking() on vtr.ParentTemplateId equals t.Id select new { Relationship = vtr, Template = t }).ToList(); this.constraintReferences = (from c in constraints join tcr in this.tdb.TemplateConstraintReferences.AsNoTracking() on c.Id equals tcr.TemplateConstraintId join t in this.tdb.Templates.AsNoTracking() on tcr.ReferenceIdentifier equals t.Oid join ig1 in this.tdb.ImplementationGuides.AsNoTracking() on t.OwningImplementationGuideId equals ig1.Id where tcr.ReferenceType == ConstraintReferenceTypes.Template select new ExportConstraintReference() { Bookmark = t.Bookmark, Identifier = t.Oid, Name = t.Name, TemplateConstraintId = tcr.TemplateConstraintId, IncludedInIG = templates.Contains(t), ImplementationGuide = !string.IsNullOrEmpty(ig1.DisplayName) ? ig1.DisplayName : ig1.Name + " V" + ig1.Version.ToString(), PublishDate = ig1.PublishDate }).ToList(); model = new ViewDataModel() { ImplementationGuideId = implementationGuideId, ImplementationGuideName = !string.IsNullOrEmpty(ig.DisplayName) ? ig.DisplayName : ig.NameWithVersion, ImplementationGuideFileId = fileId, Status = ig.PublishStatus.Status, PublishDate = ig.PublishDate != null?ig.PublishDate.Value.ToShortDateString() : null, Volume1Html = igSettings.GetSetting(IGSettingsManager.SettingProperty.Volume1Html) }; model.ImplementationGuideDescription = ig.WebDescription; model.ImplementationGuideDisplayName = !string.IsNullOrEmpty(ig.WebDisplayName) ? ig.WebDisplayName : model.ImplementationGuideName; Log.For(this).Trace("Including Volume 1 sections"); // Create the section models var sections = ig.Sections.OrderBy(y => y.Order).ToList(); model.Volume1Sections = (from igs in sections select new ViewDataModel.Section() { Heading = igs.Heading, Content = igs.Content.MarkdownToHtml(), Level = igs.Level }).ToList(); Log.For(this).Trace("Including FHIR resources attached to IG"); // Include any FHIR Resource Instance attachments with the IG foreach (var fhirResourceInstanceFile in ig.Files.Where(y => y.ContentType == "FHIRResourceInstance")) { var fileData = fhirResourceInstanceFile.GetLatestData(); string fileContent = System.Text.Encoding.UTF8.GetString(fileData.Data); ViewDataModel.FHIRResource newFhirResource = new ViewDataModel.FHIRResource() { Name = fhirResourceInstanceFile.FileName, JsonContent = igTypePlugin.GetFHIRResourceInstanceJson(fileContent), XmlContent = igTypePlugin.GetFHIRResourceInstanceXml(fileContent) }; if (!string.IsNullOrEmpty(newFhirResource.JsonContent) || !string.IsNullOrEmpty(newFhirResource.XmlContent)) { model.FHIRResources.Add(newFhirResource); } } Log.For(this).Trace("Including value sets"); foreach (var valueSet in valueSets) { var newValueSetModel = new ViewDataModel.ValueSet() { Identifier = valueSet.ValueSet.GetIdentifier(igTypePlugin), Name = valueSet.ValueSet.Name, Source = valueSet.ValueSet.Source, Description = valueSet.ValueSet.Description, BindingDate = valueSet.BindingDate != null?valueSet.BindingDate.Value.ToShortDateString() : null }; var members = valueSet.ValueSet.GetActiveMembers(valueSet.BindingDate); newValueSetModel.Members = (from vsm in members join cs in this.tdb.CodeSystems on vsm.CodeSystemId equals cs.Id select new ViewDataModel.ValueSetMember() { Code = vsm.Code, DisplayName = vsm.DisplayName, CodeSystemIdentifier = cs.Oid, CodeSystemName = cs.Name }).ToList(); model.ValueSets.Add(newValueSetModel); // Add code systems used by this value set to the IG var codeSystems = (from vsm in members join cs in this.tdb.CodeSystems on vsm.CodeSystemId equals cs.Id select new ViewDataModel.CodeSystem() { Identifier = cs.Oid, Name = cs.Name }); model.CodeSystems.AddRange(codeSystems); } Log.For(this).Trace("Including templates"); foreach (var template in templates) { var templateId = template.Id; var templateSchema = schema.GetSchemaFromContext(template.PrimaryContextType); var previousVersion = previousVersions.SingleOrDefault(y => y.Id == template.PreviousVersionTemplateId); var newTemplateModel = new ViewDataModel.Template() { Identifier = template.Oid, Bookmark = template.Bookmark, ContextType = template.PrimaryContextType, Context = template.PrimaryContext, Name = template.Name, ImpliedTemplate = template.ImpliedTemplate != null ? new ViewDataModel.TemplateReference(template.ImpliedTemplate) : null, Description = template.Description.MarkdownToHtml(), Extensibility = template.IsOpen ? "Open" : "Closed", TemplateTypeId = template.TemplateTypeId }; // Load Template Changes if (previousVersion != null) { var comparer = VersionComparer.CreateComparer(this.tdb, igTypePlugin, igSettings); var result = comparer.Compare(previousVersion, template); newTemplateModel.Changes = new DifferenceModel(result) { Id = template.Id, TemplateName = template.Name, PreviousTemplateName = string.Format("{0} ({1})", previousVersion.Name, previousVersion.Oid), PreviousTemplateId = previousVersion.Id }; } // Code systems used in this template to the IG var codeSystems = (from tc in template.ChildConstraints where tc.CodeSystem != null select new ViewDataModel.CodeSystem() { Identifier = tc.CodeSystem.Oid, Name = tc.CodeSystem.Name }); model.CodeSystems.AddRange(codeSystems); // Samples newTemplateModel.Samples = (from ts in template.TemplateSamples select new ViewDataModel.Sample() { Id = ts.Id, Name = ts.Name, SampleText = ts.XmlSample }).ToList(); // Contained templates var thisContainedTemplates = containedTemplates .Where(y => y.Relationship.ParentTemplateId == templateId) .GroupBy(y => y.Template) .Select(y => y.First()); newTemplateModel.ContainedTemplates = thisContainedTemplates.Select(y => new ViewDataModel.TemplateReference(y.Template)).ToList(); // Contained by templates var thisContainedByTemplates = containedByTemplates .Where(y => y.Relationship.ChildTemplateId == templateId) .GroupBy(y => y.Template) .Select(y => y.First()); newTemplateModel.ContainedByTemplates = thisContainedByTemplates.Select(y => new ViewDataModel.TemplateReference(y.Template)).ToList(); // Implying templates var implyingTemplates = (from t in templates where t.ImpliedTemplateId == template.Id select t).Distinct().ToList(); newTemplateModel.ImplyingTemplates = implyingTemplates.Select(y => new ViewDataModel.TemplateReference(y)).ToList(); model.Templates.Add(newTemplateModel); // Create the constraint models (hierarchically) var parentConstraints = template.ChildConstraints.Where(y => y.ParentConstraintId == null); CreateConstraints(igSettings, igTypePlugin, parentConstraints, newTemplateModel.Constraints, templateSchema); } Log.For(this).Trace("Including template types"); // Create models for template types in the IG model.TemplateTypes = (from igt in igSettings.TemplateTypes join tt in this.tdb.TemplateTypes.AsNoTracking() on igt.TemplateTypeId equals tt.Id where model.Templates.Exists(y => y.TemplateTypeId == tt.Id) select new ViewDataModel.TemplateType() { TemplateTypeId = tt.Id, Name = igt.Name, ContextType = tt.RootContextType, Description = igt.DetailsText }).ToList(); Log.For(this).Trace("Including code systems"); model.CodeSystems = model.CodeSystems.Distinct().ToList(); } this.FixImagePaths(model); Log.For(this).Trace("Done generating HTML export for " + implementationGuideId); return(model); }