private TemplateConstraint CloneTemplateConstraint(Template newTemplate, TemplateConstraint parentConstraint, TemplateConstraint constraint) { TemplateConstraint newConstraint = new TemplateConstraint() { Template = newTemplate, Conformance = constraint.Conformance, Cardinality = constraint.Cardinality, Value = constraint.Value, PrimitiveText = constraint.PrimitiveText, DataType = constraint.DataType, Context = constraint.Context, CodeSystemId = constraint.CodeSystemId, DisplayName = constraint.DisplayName, IsBranch = constraint.IsBranch, Order = constraint.Order, Schematron = constraint.Schematron, ValueConformance = constraint.ValueConformance, ValueSetId = constraint.ValueSetId, IsStatic = constraint.IsStatic, IsBranchIdentifier = constraint.IsBranchIdentifier, IsSchRooted = constraint.IsSchRooted, IsPrimitive = constraint.IsPrimitive, IsInheritable = constraint.IsInheritable, ValueSetDate = constraint.ValueSetDate, Label = constraint.Label, Notes = constraint.Notes, Description = constraint.Description, Number = constraint.Number.Value, Category = constraint.Category }; if (parentConstraint != null) { newConstraint.ParentConstraintId = null; newConstraint.ParentConstraint = parentConstraint; } if (constraint.ContainedTemplate != null) { newConstraint.ContainedTemplateId = null; newConstraint.ContainedTemplate = constraint.ContainedTemplate; } // Clone each child constraint constraint.ChildConstraints.ToList().ForEach(y => { newTemplate.ChildConstraints.Add( CloneTemplateConstraint(newTemplate, newConstraint, y)); }); return(newConstraint); }
private void AddImportConstraint(TDBTemplate template, TDBTemplateConstraint parentConstraint, ImportConstraint importConstraint) { if (importConstraint.isVerbose) { return; } TDBTemplateConstraint constraint = null; if (importConstraint.numberSpecified) { constraint = template.ChildConstraints.SingleOrDefault(y => y.ParentConstraint == parentConstraint && y.Number == importConstraint.number); } else if (!string.IsNullOrEmpty(importConstraint.displayNumber)) { constraint = template.ChildConstraints.SingleOrDefault(y => y.ParentConstraint == parentConstraint && y.DisplayNumber == importConstraint.displayNumber); } if (constraint == null) { constraint = new TDBTemplateConstraint(); constraint.Number = importConstraint.number; constraint.DisplayNumber = importConstraint.displayNumber; constraint.Template = template; constraint.ParentConstraint = parentConstraint; this.tdb.TemplateConstraints.Add(constraint); // TODO: Order the constraint? Or let the template re-order the constraints when it is edited? } this.UpdateConstraintProperties(constraint, importConstraint); this.UpdateConstraintContainedTemplate(constraint, importConstraint.ContainedTemplate); this.UpdateConstraintBinding(constraint, importConstraint); this.UpdateConstraintCodeSystem(constraint, importConstraint); this.UpdateConstraintCategories(constraint, importConstraint); this.UpdateConstraintSamples(constraint, importConstraint); // Add each of the constraint's child constraints if (importConstraint.Constraint != null) { importConstraint.Constraint.ToList().ForEach(y => AddImportConstraint(template, constraint, y)); } }
public object Clone() { TemplateConstraint clone = new TemplateConstraint(); clone._Cardinality = this._Cardinality; clone._CodeSystemId = this._CodeSystemId; clone._Conformance = this._Conformance; clone._ContainedTemplateId = this._ContainedTemplateId; clone._Context = this._Context; clone._DataType = this._DataType; clone._Description = this._Description; clone._DisplayName = this._DisplayName; clone._Id = this._Id; clone._IsBranch = this._IsBranch; clone._IsBranchIdentifier = this._IsBranchIdentifier; clone._IsInheritable = this._IsInheritable; clone._IsPrimitive = this._IsPrimitive; clone._IsSchRooted = this._IsSchRooted; clone._IsStatic = this._IsStatic; clone._Label = this._Label; clone._Notes = this._Notes; clone._Order = this._Order; clone._ParentConstraintId = this._ParentConstraintId; clone._PrimitiveText = this._PrimitiveText; clone._Schematron = this._Schematron; clone._TemplateId = this._TemplateId; clone._Value = this._Value; clone._ValueConformance = this._ValueConformance; clone._ValueSetDate = this._ValueSetDate; clone._ValueSetId = this._ValueSetId; clone.Template = this.Template; clone.ParentConstraint = this.ParentConstraint; clone.CodeSystem = this.CodeSystem; clone.ContainedTemplate = this.ContainedTemplate; clone.ValueSet = this.ValueSet; clone.Number = this.Number; return(clone); }
public string GetXpath() { if (this.IsPrimitive) { return(string.Empty); } StringBuilder sb = new StringBuilder(); TemplateConstraint current = this; while (current != null && !string.IsNullOrEmpty(current.Context)) { if (sb.Length > 0) { sb.Insert(0, "/"); } sb.Insert(0, current.Context); current = current.ParentConstraint; } return(sb.ToString()); }
private TemplateConstraint CloneTemplateConstraint(Template newTemplate, TemplateConstraint parentConstraint, TemplateConstraint constraint) { TemplateConstraint newConstraint = new TemplateConstraint() { Template = newTemplate, Conformance = constraint.Conformance, Cardinality = constraint.Cardinality, Value = constraint.Value, PrimitiveText = constraint.PrimitiveText, DataType = constraint.DataType, Context = constraint.Context, CodeSystemId = constraint.CodeSystemId, DisplayName = constraint.DisplayName, IsBranch = constraint.IsBranch, Order = constraint.Order, Schematron = constraint.Schematron, ValueConformance = constraint.ValueConformance, ValueSetId = constraint.ValueSetId, IsStatic = constraint.IsStatic, IsBranchIdentifier = constraint.IsBranchIdentifier, IsSchRooted = constraint.IsSchRooted, IsPrimitive = constraint.IsPrimitive, IsInheritable = constraint.IsInheritable, ValueSetDate = constraint.ValueSetDate, Label = constraint.Label, Notes = constraint.Notes, Description = constraint.Description, Number = constraint.Number.Value, Category = constraint.Category, MustSupport = constraint.MustSupport, IsModifier = constraint.IsModifier, IsFixed = constraint.IsFixed, IsChoice = constraint.IsChoice, IsHeading = constraint.IsHeading, HeadingDescription = constraint.HeadingDescription }; if (parentConstraint != null) { newConstraint.ParentConstraintId = null; newConstraint.ParentConstraint = parentConstraint; } constraint.References.ToList().ForEach(y => { newConstraint.References.Add(new TemplateConstraintReference() { Constraint = newConstraint, ReferenceIdentifier = y.ReferenceIdentifier, ReferenceType = y.ReferenceType }); }); // Clone each child constraint constraint.ChildConstraints.ToList().ForEach(y => { newTemplate.ChildConstraints.Add( CloneTemplateConstraint(newTemplate, newConstraint, y)); }); return(newConstraint); }
private void SetPropeties(TemplateConstraint constraint) { }
/// <summary> /// Perform validations on a single constraint. /// </summary> /// <param name="errors">The list of errors that should be added to when a constraint has an error matching the schema</param> /// <param name="schemaObjects">The list of sibling-level schema objects that the constraint should be compared to</param> /// <param name="currentConstraint">The current constraint to match against the schema</param> public static void ValidateTemplateConstraint(this Template template, XPathNavigator xpathNavigator, List <TemplateValidationResult> errors, SimpleSchema schema, List <SimpleSchema.SchemaObject> schemaObjects, TemplateConstraint currentConstraint) { List <TemplateConstraint> childConstraints = currentConstraint.ChildConstraints.ToList(); if (!string.IsNullOrEmpty(currentConstraint.Schematron)) { try { XPathExpression expr = xpathNavigator.Compile(currentConstraint.Schematron); } catch (XPathException ex) { errors.Add(TemplateValidationResult.CreateResult(currentConstraint.Number, ValidationLevels.Error, "Custom schematron is not valid: " + ex.Message)); } } if (currentConstraint.IsPrimitive && string.IsNullOrEmpty(currentConstraint.PrimitiveText)) { errors.Add(TemplateValidationResult.CreateResult(currentConstraint.Number, ValidationLevels.Error, "Primitive does not have any narrative text.")); return; } else if (!string.IsNullOrEmpty(currentConstraint.Context)) { string context = currentConstraint.Context; bool isAttribute = context.StartsWith("@"); // If it is an attribute, then we need to remove the @ from the context if (isAttribute) { context = context.Substring(1); } SimpleSchema.SchemaObject foundSchemaObject = schemaObjects.SingleOrDefault(y => y.Name.ToLower() == context.ToLower() && y.IsAttribute == isAttribute); // Verify that the template (if specified) matches the datatype of the constraints if (currentConstraint.ContainedTemplate != null && currentConstraint.ContainedTemplate.PrimaryContextType != null && foundSchemaObject != null) { string containedTemplateDataType = currentConstraint.ContainedTemplate.PrimaryContextType; string constraintDataType = !string.IsNullOrEmpty(currentConstraint.DataType) ? currentConstraint.DataType : foundSchemaObject.DataType; bool isFhirResourceReference = schema.Schema.TargetNamespace == "http://hl7.org/fhir" && (constraintDataType == "ResourceReference" || constraintDataType == "Reference"); if (!isFhirResourceReference && containedTemplateDataType.ToLower() != constraintDataType.ToLower()) { errors.Add(TemplateValidationResult.CreateResult( currentConstraint.Number, ValidationLevels.Error, "Contained template \"{0}\" has a type of \"{1}\" which does not match the containing element \"{2}\"", currentConstraint.ContainedTemplate.Oid, containedTemplateDataType, constraintDataType)); } } // Verify that branched elements have at least one identifier if (currentConstraint.IsBranch && childConstraints.Count(y => y.IsBranchIdentifier) == 0) { errors.Add(TemplateValidationResult.CreateResult(currentConstraint.Number, ValidationLevels.Warning, "Branched constraint \"{0}\" does not have any identifiers associated with it.", currentConstraint.GetXpath())); } // Verify that a schema-object can be matched to this constraint if (foundSchemaObject == null) { errors.Add(TemplateValidationResult.CreateResult(currentConstraint.Number, ValidationLevels.Error, "Constraint has context of \"{0}\" which is not found in the schema.", currentConstraint.GetXpath())); return; // Do not process child constraints when the parent is not matched to the schema } else if (foundSchemaObject.Cardinality != null && currentConstraint.Cardinality != null) { // Warn when a constraint that is associated with the schema that has multiple cardinality but is not branched if (template.IsOpen && !foundSchemaObject.Cardinality.EndsWith("..1") && !foundSchemaObject.Cardinality.EndsWith("..0") && !currentConstraint.IsBranch) { var error = TemplateValidationResult.CreateResult(currentConstraint.Number, ValidationLevels.Warning, "Schema allows multiple for \"{0}\" but the constraint is not branched. Consider branching this constraint.", currentConstraint.GetXpath()); errors.Add(error); } if (foundSchemaObject.Cardinality.EndsWith("..1") && !(currentConstraint.Cardinality.EndsWith("..0") || currentConstraint.Cardinality.EndsWith("..1"))) { var error = TemplateValidationResult.CreateResult(currentConstraint.Number, ValidationLevels.Error, "The cardinality for the element is loosened in the constraint from the underlying schema."); errors.Add(error); } } List <SimpleSchema.SchemaObject> childSchemaObjects = foundSchemaObject.Children; // If a data-type is specified, then we should find the data-type within the schema, since it is likely different than what // is specified by default. if (!string.IsNullOrEmpty(currentConstraint.DataType)) { SimpleSchema.SchemaObject foundSchemaTypeObject = schema.FindFromType(currentConstraint.DataType); if (foundSchemaTypeObject != null) { childSchemaObjects = foundSchemaTypeObject.Children; } } childConstraints.ForEach(y => template.ValidateTemplateConstraint(xpathNavigator, errors, schema, childSchemaObjects, y)); } }