public override string Format(FormatContext context, BareANY hl7Value, int indentLevel) { string result = base.Format(context, hl7Value, indentLevel); if (hl7Value != null) { string originalText = ((ANYMetaData)hl7Value).OriginalText; bool hasNullFlavor = hl7Value.HasNullFlavor(); bool hasAnyValues = HasAnyValues(hl7Value); this.pqValidationUtils.ValidateOriginalText(context.Type, originalText, hasAnyValues, hasNullFlavor, context.GetVersion() , null, context.GetPropertyPath(), context.GetModelToXmlResult()); // complete hack for BC if (SpecificationVersion.IsExactVersion(context.GetVersion(), SpecificationVersion.V02R04_BC)) { if (hasNullFlavor && HasAnyValues(hl7Value)) { // dump the result and rebuild, adding in NF IDictionary <string, string> attributeNameValuePairs = GetAttributeNameValuePairs(context, (PhysicalQuantity)hl7Value.BareValue , hl7Value); attributeNameValuePairs.PutAll(CreateNullFlavorAttributes(hl7Value.NullFlavor)); result = CreateElement(context, attributeNameValuePairs, indentLevel, true, true); } } if (StringUtils.IsNotBlank(originalText)) { string otElement = CreateElement("originalText", null, indentLevel + 1, false, false); otElement += XmlStringEscape.Escape(originalText); otElement += CreateElementClosure("originalText", 0, true); // pulling off the end "/>" is not the most elegant solution, but superclass would need significant refactoring otherwise result = Ca.Infoway.Messagebuilder.StringUtils.Substring(result, 0, result.IndexOf("/>")) + ">" + SystemUtils.LINE_SEPARATOR + otElement + CreateElementClosure(context.GetElementName(), indentLevel, true); } } return(result); }
protected virtual PeriodicIntervalTime ParseFrequency(ParseContext context, XmlElement element, Type expectedReturnType, XmlToModelResult xmlToModelResult) { XmlElement numerator = (XmlElement)GetNamedChildNode(element, "numerator"); XmlElement denominator = (XmlElement)GetNamedChildNode(element, "denominator"); if (numerator != null && denominator != null) { Int32?repetitions = ParseNumerator(context, numerator, xmlToModelResult); if (SpecificationVersion.IsExactVersion(SpecificationVersion.V01R04_2_SK, context.GetVersion())) { Interval <PhysicalQuantity> quantityInterval = ParseDenominatorSk(context, denominator, xmlToModelResult); return(PeriodicIntervalTimeSk.CreateFrequencySk(repetitions, quantityInterval == null ? null : quantityInterval.Low, quantityInterval == null ? null : quantityInterval.High)); } else { PhysicalQuantity quantity = ParseDenominator(context, denominator, xmlToModelResult); return(PeriodicIntervalTime.CreateFrequency(repetitions, quantity)); } } else { if (numerator == null) { CreateMandatoryChildElementHl7Error(element, "numerator", xmlToModelResult); } if (denominator == null) { CreateMandatoryChildElementHl7Error(element, "denominator", xmlToModelResult); } return(null); } }
private void ValidateDatePattern(string datePattern, FormatContext context) { StandardDataType standardDataType = StandardDataType.GetByTypeName(context); VersionNumber version = (context == null ? null : context.GetVersion()); string[] allowedDateFormats = TsDateFormats.GetAllDateFormats(standardDataType, version); if (ArrayContains(allowedDateFormats, datePattern)) { // check if this pattern is missing a timezone if (!IsCerx(standardDataType, version) && TsDateFormats.datetimeFormatsRequiringWarning.Contains(datePattern)) { context.GetModelToXmlResult().AddHl7Error(new Hl7Error(Hl7ErrorCode.DATA_TYPE_ERROR, System.String.Format("Date format {0} supplied for value of type {1} should also have a timezone (ZZZZZ)" , datePattern, context == null ? "TS" : context.Type), context.GetPropertyPath())); } } else { // MBR-368: a temporary work-around for producing AB PIN compliant date time renderings // with out error messages -- required until the runtime's knowledge of datatypes has been // corrected to distinguish between CeRx v3 (ie., V01R03) and CeRx v4 (ie., V01R04) if (!SpecificationVersion.IsExactVersion(SpecificationVersion.V01R04_1_AB, version)) { context.GetModelToXmlResult().AddHl7Error(new Hl7Error(Hl7ErrorCode.DATA_TYPE_ERROR, System.String.Format("Invalid date format {0} supplied for value of type {1}" , datePattern, context == null ? "TS" : context.Type), context.GetPropertyPath())); } } }
private void AddSpecializationTypeAttributesBasedOnVersion(IDictionary <string, string> attributes, string typeAsString, VersionNumber version) { AddSpecializationType(attributes, typeAsString); // exception for specification versions that reject II elements containing the specializationType // attribute itself, but still require the xsi:type and use attributes if (SpecificationVersion.IsExactVersion(SpecificationVersion.V01R04_1_AB, version)) { attributes.Remove(SPECIALIZATION_TYPE); } }
private void AppendIntervalBounds(PeriodicIntervalTime value, StringBuilder buffer, int indentLevel, FormatContext context ) { string period = CreatePeriodElement(value.Period, indentLevel, context); string phase = CreatePhaseElement(value.Phase, indentLevel, context); switch (value.Representation) { case Representation.PERIOD: { buffer.Append(period); break; } case Representation.PHASE: { buffer.Append(phase); break; } case Representation.PERIOD_PHASE: { buffer.Append(period); buffer.Append(phase); break; } case Representation.FREQUENCY: { // Change for Saskatchewan bool isSask = SpecificationVersion.IsExactVersion(SpecificationVersion.V01R04_2_SK, context != null ? context.GetVersion( ) : null); if (isSask && value is PeriodicIntervalTimeSk) { buffer.Append(CreateFrequencyElementForSk(FREQUENCY, value.Repetitions, ((PeriodicIntervalTimeSk)value).QuantitySk, indentLevel , context)); } else { buffer.Append(CreateFrequencyElement(value.Repetitions, value.Quantity, indentLevel, context)); } break; } default: { break; } } }
public virtual void ValidateOriginalText(string typeAsString, string originalText, bool hasAnyValues, bool hasNullFlavor, VersionNumber version, XmlElement element, string propertyPath, Hl7Errors errors) { StandardDataType type = StandardDataType.GetByTypeName(typeAsString); bool hasOriginalText = StringUtils.IsNotBlank(originalText); if (hasOriginalText) { // only PQ.LAB is allowed to have originalText if (!StandardDataType.PQ_LAB.Equals(type)) { CreateWarning(System.String.Format("Type {0} not allowed to have originalText. For physical quantity types, originalText is only allowed for PQ.LAB." , typeAsString), element, propertyPath, errors); } else { // no more than 150 characters int length = originalText.Length; if (length > MAX_ORIGINAL_TEXT_LENGTH) { CreateWarning(System.String.Format("PQ.LAB originalText has {0} characters, but only {1} are allowed.", length, MAX_ORIGINAL_TEXT_LENGTH ), element, propertyPath, errors); } } } // TM - HACK: these restrictions don't seem to apply to the R2 datatype version of PQ.LAB; currently only BC using this (refactor when implementing R2 datatypes) if (StandardDataType.PQ_LAB.Equals(type) && hasNullFlavor && !SpecificationVersion.IsExactVersion(version, SpecificationVersion .V02R04_BC)) { if (!hasOriginalText) { CreateWarning("For PQ.LAB values, originalText is mandatory when set to a NullFlavor.", element, propertyPath, errors); } if (hasAnyValues) { CreateWarning("PQ.LAB can not have quantity or units specified when set to a NullFlavor.", element, propertyPath, errors); } } }
private void ValidatePostalAddressParts(PostalAddress postalAddress, string type, VersionNumber version, XmlElement element , string propertyPath, Hl7Errors errors) { int countBlankParts = 0; bool isBasic = StandardDataType.AD_BASIC.Type.Equals(type); bool isSearch = StandardDataType.AD_SEARCH.Type.Equals(type); bool isFull = StandardDataType.AD_FULL.Type.Equals(type); bool isAd = StandardDataType.AD.Type.Equals(type); foreach (PostalAddressPart postalAddressPart in postalAddress.Parts) { int partLength = StringUtils.Length(postalAddressPart.Value); if (partLength > MAX_PART_LENGTH) { // value max length of 80 CreateError("Address part types have a maximum allowed length of " + MAX_PART_LENGTH + " (length found: " + partLength + ")", element, propertyPath, errors); } // error if part type not allowed PostalAddressPartType partType = postalAddressPart.Type; if (partType == null) { countBlankParts++; // no part type : only allowed for BASIC (max 4, plus max 4 delimiter) if (!isBasic) { CreateError("Text without an address part only allowed for AD.BASIC", element, propertyPath, errors); } } else { if (partType == PostalAddressPartType.DELIMITER) { if (isSearch) { CreateError("Part type " + partType.Value + " is not allowed for AD.SEARCH", element, propertyPath, errors); } } else { if (isFull || isAd) { if (!PostalAddressPartType.IsFullAddressPartType(partType)) { CreateError("Part type " + partType.Value + " is not allowed for AD or AD.FULL", element, propertyPath, errors); } } else { if (!PostalAddressPartType.IsBasicAddressPartType(partType)) { CreateError("Part type " + partType.Value + " is not allowed for AD.BASIC or AD.SEARCH", element, propertyPath, errors); } } } } // code/codesystem are only for state/country if (postalAddressPart.Code != null) { if (partType != PostalAddressPartType.STATE && partType != PostalAddressPartType.COUNTRY) { CreateError("Part type " + partType.Value + " is not allowed to specify code or codeSystem", element, propertyPath, errors ); } } } if (isBasic && countBlankParts > MAX_DELIMITED_LINES) { CreateError("AD.BASIC is only allowed a maximum of " + MAX_DELIMITED_LINES + " delimiter-separated address lines (address lines without an address part type)" , element, propertyPath, errors); } if (isSearch && CollUtils.IsEmpty(postalAddress.Parts)) { CreateError("AD.SEARCH must specify at least one part type", element, propertyPath, errors); } // city/state/postalCode/country mandatory for AD.FULL // new change for R02.05 (pre-adopted by R02.04.03 AB) onwards - these fields are now only *required*, not mandatory if (isFull && !SpecificationVersion.IsExactVersion(SpecificationVersion.R02_04_03_AB, version)) { ValidatePartTypeProvided(PostalAddressPartType.CITY, postalAddress.Parts, element, propertyPath, errors); ValidatePartTypeProvided(PostalAddressPartType.STATE, postalAddress.Parts, element, propertyPath, errors); ValidatePartTypeProvided(PostalAddressPartType.POSTAL_CODE, postalAddress.Parts, element, propertyPath, errors); ValidatePartTypeProvided(PostalAddressPartType.COUNTRY, postalAddress.Parts, element, propertyPath, errors); } }
public virtual bool IsSpecializationTypeRequired(VersionNumber version, string type, bool isCda) { StandardDataType standardDataType = StandardDataType.GetByTypeName(type); // AB does not treat II as abstract; for CeRx, II is concrete; Newfoundland is excepted to allow our legacy tests to pass return(IsIiBusAndVer(type) || (IsII(type) && !(isCda || SpecificationVersion.IsVersion(standardDataType, version, Hl7BaseVersion .CERX) || "NEWFOUNDLAND".Equals(version == null ? null : version.VersionLiteral) || SpecificationVersion.IsExactVersion( SpecificationVersion.V02R02_AB, version)))); }
private bool IsBC(VersionNumber version) { return(SpecificationVersion.IsExactVersion(version, SpecificationVersion.V02R04_BC)); }