/// <summary> /// Used to test green artifact generation. /// </summary> /// <returns></returns> public static MockObjectRepository GenerateGreenMockDataset1() { MockObjectRepository mockRepo = new MockObjectRepository(); mockRepo.FindOrCreateCodeSystem("SNOMED CT", "6.96"); mockRepo.FindOrCreateCodeSystem("HL7ActStatus", "113883.5.14"); mockRepo.FindOrCreateValueSet("GenderCode", "11.1"); ImplementationGuideType igType = mockRepo.FindOrCreateImplementationGuideType("CDA", "CDA.xsd", "cda", "urn:hl7-org:v3"); TemplateType docType = mockRepo.FindOrCreateTemplateType(igType, "Document", "ClinicalDocument", "ClinicalDocument", 1); TemplateType sectionType = mockRepo.FindOrCreateTemplateType(igType, "Section", "section", "Section", 2); mockRepo.GenerateDataType(igType, "II"); mockRepo.GenerateDataType(igType, "INT"); mockRepo.GenerateDataType(igType, "TS"); mockRepo.GenerateDataType(igType, "CE"); ImplementationGuide ig1 = mockRepo.FindOrAddImplementationGuide(igType, "Test IG 1"); Template t1 = mockRepo.GenerateTemplate("urn:oid:1.2.3.4", docType, "Test Template 1", ig1, null, null, null); TemplateConstraint tc1 = mockRepo.GenerateConstraint(t1, null, null, "code", "SHALL", "1..1", "CE"); TemplateConstraint tc1_1 = mockRepo.GenerateConstraint(t1, tc1, null, "@code", "SHALL", "1..1", null, "SHALL", "1234-x", "Test Doc Code", null, null); TemplateConstraint tc1_2 = mockRepo.GenerateConstraint(t1, tc1, null, "@codeSystem", "SHALL", "1..1", null, "SHALL", "1.5.4.2.3", "Test Code System OID", null, null); TemplateConstraint tc2 = mockRepo.GenerateConstraint(t1, null, null, "setId", "SHALL", "1..1", "II"); TemplateConstraint tc3 = mockRepo.GenerateConstraint(t1, null, null, "versionNumber", "SHALL", "1..1", "INT"); TemplateConstraint tc4 = mockRepo.GenerateConstraint(t1, null, null, "recordTarget", "SHALL", "1..*", null); TemplateConstraint tc4_1 = mockRepo.GenerateConstraint(t1, tc4, null, "patientRole", "SHALL", "1..1", null); TemplateConstraint tc4_1_1 = mockRepo.GenerateConstraint(t1, tc4_1, null, "id", "SHALL", "1..1", "II"); TemplateConstraint tc4_1_2 = mockRepo.GenerateConstraint(t1, tc4_1, null, "patient", "SHALL", "1..1", null); TemplateConstraint tc4_1_2_1 = mockRepo.GenerateConstraint(t1, tc4_1_2, null, "birthTime", "SHALL", "1..1", "TS"); TemplateConstraint tc4_1_2_2 = mockRepo.GenerateConstraint(t1, tc4_1_2, null, "administrativeGenderCode", "SHALL", "1..1", "CE"); // Green Info GreenTemplate gt1 = new GreenTemplate() { Id = 1, Template = t1, TemplateId = t1.Id, Name = "Test Green Template 1" }; mockRepo.GreenTemplates.AddObject(gt1); t1.GreenTemplates.Add(gt1); GreenConstraint gc1 = mockRepo.GenerateGreenConstraint(gt1, tc2, null, 1, "VersionSet", true); GreenConstraint gc2 = mockRepo.GenerateGreenConstraint(gt1, tc3, null, 2, "VersionNumber", true); GreenConstraint gc3 = mockRepo.GenerateGreenConstraint(gt1, tc4, null, 3, "Patient", false); GreenConstraint gc4 = mockRepo.GenerateGreenConstraint(gt1, tc4_1_1, gc3, 1, "Id", true); GreenConstraint gc5 = mockRepo.GenerateGreenConstraint(gt1, tc4_1_2_1, gc3, 2, "BirthDate", true); GreenConstraint gc6 = mockRepo.GenerateGreenConstraint(gt1, tc4_1_2_2, gc3, 3, "Gender", true); return(mockRepo); }
/// <summary> /// Gets the lower and upper bounds of a constraint to be used by XSD element's MinOccurs and MaxOccurs values. /// If the green constraint is not collapsing canonical constraints, it simply returns the cardinality defined /// by the canonical constraint. If it *is* collapsing one or more canonical constraints, it finds /// the maximum possible bounds of the constraints that it is collapsing. /// </summary> /// <param name="greenConstraint">The green constraint whose bounds should be determined.</param> /// <param name="lowerBound">Out parameter that is set to the maximum available lower bound of the constraint</param> /// <param name="upperBound">Out parameter that is set to the maximum available upper bound of the constraint</param> private void GetConstraintBounds(GreenConstraint greenConstraint, out string lowerBound, out string upperBound) { int maxLowerBound = greenConstraint.TemplateConstraint.CardinalityType.Left; int maxUpperBound = greenConstraint.TemplateConstraint.CardinalityType.Right; int?templateParentConstrantId = greenConstraint.TemplateConstraint.ParentConstraintId; int?greenParentConstraintId = greenConstraint.ParentGreenConstraint != null ? (int?)greenConstraint.ParentGreenConstraint.TemplateConstraintId : null; // If we are collapsing some elements... if (templateParentConstrantId != greenParentConstraintId) { TemplateConstraint current = greenConstraint.TemplateConstraint.ParentConstraint; while (current != null && current.Id != greenParentConstraintId) { if (current.CardinalityType.Left > maxLowerBound) { maxLowerBound = current.CardinalityType.Left; } if (current.CardinalityType.Right > maxUpperBound) { maxUpperBound = current.CardinalityType.Right; } current = current.ParentConstraint; } } if (maxLowerBound == int.MaxValue) { lowerBound = "unbounded"; } else { lowerBound = maxLowerBound.ToString(); } if (maxUpperBound == int.MaxValue) { upperBound = "unbounded"; } else { upperBound = maxUpperBound.ToString(); } }
private GreenConstraint CreateGreenConstraint(GreenTemplate greenTemplate, TemplateConstraint constraint, GreenConstraint parent, string businessName = null, string elementName = null, string xpath = null, ImplementationGuideTypeDataType dataType = null) { if (string.IsNullOrEmpty(constraint.Context)) { throw new ArgumentException(constraint.Context); } if (string.IsNullOrEmpty(elementName)) { elementName = constraint.Context; } if (string.IsNullOrEmpty(businessName)) { businessName = constraint.Context; } GreenConstraint newGreenConstraint = new GreenConstraint() { GreenTemplate = greenTemplate, GreenTemplateId = greenTemplate.Id, TemplateConstraint = constraint, TemplateConstraintId = constraint.Id, Description = businessName, Name = elementName, RootXpath = xpath, ImplementationGuideTypeDataType = dataType, ImplementationGuideTypeDataTypeId = dataType != null ? (int?)dataType.Id : null }; if (parent != null) { newGreenConstraint.ParentGreenConstraint = parent; newGreenConstraint.ParentGreenConstraintId = parent.Id; parent.ChildGreenConstraints.Add(newGreenConstraint); } constraint.GreenConstraints.Add(newGreenConstraint); greenTemplate.ChildGreenConstraints.Add(newGreenConstraint); this.mockRepo.GreenConstraints.AddObject(newGreenConstraint); return(newGreenConstraint); }
private void CreateTemplateConstraint(XmlElement parent, TemplateConstraint constraint) { GreenConstraint greenConstraint = null; XmlElement newElement = null; if (this.greenTemplates.ContainsKey(constraint.TemplateId)) { long greenTemplateId = this.greenTemplates[constraint.TemplateId]; greenConstraint = tdb.GreenConstraints.SingleOrDefault(y => y.GreenTemplateId == greenTemplateId && y.TemplateConstraintId == constraint.Id); } if (greenConstraint != null) { newElement = CreateGreenMapping(parent, greenConstraint); } else if (!string.IsNullOrEmpty(constraint.Context)) { newElement = CreateNormativeMapping(parent, constraint); } else if (!string.IsNullOrEmpty(constraint.PrimitiveText)) { XmlComment newComment = this.transformDoc.CreateComment("CONF# " + constraint.Id.ToString() + ":" + constraint.PrimitiveText); parent.AppendChild(newComment); } else { XmlComment newComment = this.transformDoc.CreateComment("CONF# " + constraint.Id.ToString() + " is not mapping via green, does not have a context " + "and does not have narrative, therefore cannot be mapped in the transform."); parent.AppendChild(newComment); } if (newElement != null) { List <TemplateConstraint> childConstraints = (from tc in tdb.TemplateConstraints where tc.TemplateId == constraint.TemplateId && tc.ParentConstraintId == constraint.Id select tc).ToList(); childConstraints.ForEach(y => CreateTemplateConstraint(newElement, y)); } }
private XmlElement CreateGreenMapping(XmlElement parent, GreenConstraint greenConstraint) { // If the constraint represents a contained template, we should simply apply the rules of the contained template here. if (greenConstraint.TemplateConstraint.ContainedTemplate != null) { if (allGreenTemplates.Exists(y => y.TemplateId == greenConstraint.TemplateConstraint.ContainedTemplateId)) { XmlElement applyTemplatesElement = TransformHelper.CreateXsltApplyTemplates(this.transformDoc, greenConstraint.Name); parent.AppendChild(applyTemplatesElement); } else { XmlComment newComent = this.transformDoc.CreateComment("CONF# " + greenConstraint.TemplateConstraintId.ToString() + " has a green constraint '" + greenConstraint.Name + "' that references a contained template, which does not have a green template defined for."); parent.AppendChild(newComent); } } else { if (greenConstraint.ChildGreenConstraints.Count > 0) { // Create loop for child constraints XmlElement forEachElement = TransformHelper.CreateXsltForEach(this.transformDoc, greenConstraint.Name); parent.AppendChild(forEachElement); XmlElement contextElement = this.transformDoc.CreateElement(TransformHelper.IgNamespacePrefix, greenConstraint.TemplateConstraint.Context, this.schemaNamespace); forEachElement.AppendChild(contextElement); if (greenConstraint.IsEditable == true) { // Identify if the editable green object is data-typed. If it is, apply the data-type template string dataTypeTemplate = string.Empty; if (!string.IsNullOrEmpty(greenConstraint.TemplateConstraint.DataType)) { dataTypeTemplate = FindOrAddDataTypeTemplate(greenConstraint.TemplateConstraint.DataType); } if (!string.IsNullOrEmpty(dataTypeTemplate)) { XmlElement applyTemplatesElement = TransformHelper.CreateXsltApplyTemplates(this.transformDoc, dataTypeTemplate, null, "instance", greenConstraint.Name); contextElement.AppendChild(applyTemplatesElement); } else { XmlElement textMappingElement = TransformHelper.CreateXsltValueOf(this.transformDoc, "value()"); contextElement.AppendChild(textMappingElement); } } return(contextElement); } else if (greenConstraint.Name.StartsWith("@")) // TODO: Assuming that attributes are all editable for now { XmlElement attributeMappingElement = TransformHelper.CreateXsltAttributeWithValueOf( this.transformDoc, greenConstraint.TemplateConstraint.Context.Replace("@", ""), greenConstraint.Name); parent.AppendChild(attributeMappingElement); } else if (greenConstraint.IsEditable == true) { // Identify if the editable green object is data-typed. If it is, apply the data-type template string dataTypeTemplate = string.Empty; if (!string.IsNullOrEmpty(greenConstraint.TemplateConstraint.DataType)) { dataTypeTemplate = FindOrAddDataTypeTemplate(greenConstraint.TemplateConstraint.DataType); } if (!string.IsNullOrEmpty(dataTypeTemplate)) { XmlElement newElement = TransformHelper.CreateXsltElement(this.transformDoc, greenConstraint.TemplateConstraint.Context); parent.AppendChild(newElement); XmlElement applyTemplatesElement = TransformHelper.CreateXsltApplyTemplates(this.transformDoc, dataTypeTemplate, null, "instance", greenConstraint.Name); newElement.AppendChild(applyTemplatesElement); } else { XmlElement attributeValueElement = TransformHelper.CreateXsltValueOf(this.transformDoc, greenConstraint.Name); parent.AppendChild(attributeValueElement); } } else { XmlComment newComent = this.transformDoc.CreateComment("CONF# " + greenConstraint.TemplateConstraintId.ToString() + " has a green constraint '" + greenConstraint.Name + "' that is not editable and has no children."); parent.AppendChild(newComent); } } return(null); }
/// <summary> /// Builds a schema object from the green constraint specified, and returns the new object. /// </summary> /// <returns> /// An XmlSchemaChoice when the constraint represents a contained template that has multiple derived children. /// An XmlElement when the constraint is either an editable constraint, or represents a single contained template. /// </returns> /// <remarks> /// When the constraint represents a simple editable constraint (not one or more contained templates), /// the datatype of the constraint is checked and copied from the base schema /// Recursively iterates through all child constraints and adds the return of BuildConstraint to a /// complexContent/sequence within the constraint's element /// </remarks> private XmlSchemaObject BuildConstraint(GreenConstraint greenConstraint) { string lowerBound; string upperBound; GetConstraintBounds(greenConstraint, out lowerBound, out upperBound); // Check if there is a contained template on this constraint if (greenConstraint.TemplateConstraint.ContainedTemplate != null) { var containedTemplate = greenConstraint.TemplateConstraint.ContainedTemplate; var implyingGreenTemplates = containedTemplate.ImplyingTemplates .Where(y => y.GreenTemplates.Count > 0) .Select(y => y.GreenTemplates.First()); // If the contained template has a green template if (containedTemplate.GreenTemplates.Count > 0) { XmlSchemaElement newConstraintElement = new XmlSchemaElement() { Name = greenConstraint.Name, MinOccursString = lowerBound, MaxOccursString = upperBound }; if (!string.IsNullOrEmpty(greenConstraint.RootXpath)) { newConstraintElement.Annotation = this.CreateAnnotation("XPATH = " + greenConstraint.RootXpath); } var containedGreenTemplate = containedTemplate.GreenTemplates.FirstOrDefault(); if (containedGreenTemplate != null) { BuildTemplate(containedGreenTemplate); newConstraintElement.SchemaTypeName = new XmlQualifiedName(containedGreenTemplate.Name); } return(newConstraintElement); } // Or if the contained template has derived templates which have green templates else if (implyingGreenTemplates.Count() > 0) { XmlSchemaChoice newChoice = new XmlSchemaChoice(); foreach (var currentGreenTemplate in implyingGreenTemplates) { BuildTemplate(currentGreenTemplate); XmlSchemaElement newConstraintElement = new XmlSchemaElement() { Name = currentGreenTemplate.Name, SchemaTypeName = new XmlQualifiedName(currentGreenTemplate.Name), MinOccursString = lowerBound, MaxOccursString = upperBound }; if (!string.IsNullOrEmpty(greenConstraint.RootXpath)) { newConstraintElement.Annotation = this.CreateAnnotation("XPATH = " + greenConstraint.RootXpath); } newChoice.Items.Add(newConstraintElement); } return(newChoice); } } else { XmlSchemaElement newConstraintElement = new XmlSchemaElement() { Name = greenConstraint.Name, MinOccursString = lowerBound, MaxOccursString = upperBound }; if (!string.IsNullOrEmpty(greenConstraint.RootXpath)) { newConstraintElement.Annotation = this.CreateAnnotation("XPATH = " + greenConstraint.RootXpath); } // If we aren't a branch, then check the datatype of the green constraint and copy it // from the base schema. Otherwise, create complex content for its children constraints if (greenConstraint.ChildGreenConstraints.Count == 0) { if (greenConstraint.ImplementationGuideTypeDataType != null) { string dataType = greenConstraint.ImplementationGuideTypeDataType.DataTypeName; this.schemaCopier.CopyDataType(dataType); if (this.separateDataTypes) { newConstraintElement.SchemaTypeName = new XmlQualifiedName(dataType, this.baseSchema.TargetNamespace); } else { newConstraintElement.SchemaTypeName = new XmlQualifiedName(dataType); } } else { newConstraintElement.SchemaTypeName = new XmlQualifiedName("xs:string"); } } else { XmlSchemaComplexType childComplexType = new XmlSchemaComplexType(); newConstraintElement.SchemaType = childComplexType; XmlSchemaSequence sequence = new XmlSchemaSequence(); childComplexType.Particle = sequence; foreach (var currentChildGreenConstraint in greenConstraint.ChildGreenConstraints) { XmlSchemaObject newChildConstraintElement = BuildConstraint(currentChildGreenConstraint); if (newChildConstraintElement != null) { sequence.Items.Add(newChildConstraintElement); } } } return(newConstraintElement); } return(null); }