예제 #1
0
 private void HandleConstraints(string type, ICollection <BareANY> parsedItems, ConstrainedDatatype constraints, IList <XmlNode
                                                                                                                        > nodes, XmlToModelResult xmlToModelResult)
 {
     IiCollectionConstraintHandler.ConstraintResult constraintResult = this.constraintHandler.CheckConstraints(type, constraints
                                                                                                               , parsedItems);
     if (constraintResult != null)
     {
         bool isTemplateId = constraintResult.IsTemplateId();
         if (constraintResult.IsFoundMatch())
         {
             if (isTemplateId)
             {
                 string msg = System.String.Format("Found match for templateId fixed constraint: {0}", constraintResult.GetIdentifer());
                 xmlToModelResult.AddHl7Error(new Hl7Error(Hl7ErrorCode.CDA_TEMPLATEID_FIXED_CONSTRAINT_MATCH, ErrorLevel.INFO, msg, nodes
                                                           .Count > 0 ? nodes[0] : null));
             }
         }
         else
         {
             Hl7ErrorCode errorCode = (isTemplateId ? Hl7ErrorCode.CDA_TEMPLATEID_FIXED_CONSTRAINT_MISSING : Hl7ErrorCode.CDA_FIXED_CONSTRAINT_MISSING
                                       );
             string msg = "Expected to find an identifier with: " + constraintResult.GetIdentifer();
             xmlToModelResult.AddHl7Error(new Hl7Error(errorCode, ErrorLevel.WARNING, msg, nodes.Count > 0 ? nodes[0] : null));
         }
     }
 }
예제 #2
0
		// public as a result of needing to call this method from ValidatingVistor
		public virtual Boolean? ParseBooleanValue(XmlToModelResult result, string unparsedBoolean, XmlElement element, XmlAttribute
			 attr)
		{
			Boolean? booleanResult = null;
			if (StringUtils.IsBlank(unparsedBoolean))
			{
				result.AddHl7Error(Hl7Error.CreateMandatoryBooleanValueError(element, attr));
			}
			else
			{
				if (VALID_BOOLEAN_STRINGS.Contains(unparsedBoolean))
				{
					booleanResult = Ca.Infoway.Messagebuilder.BooleanUtils.ValueOf(unparsedBoolean);
				}
				else
				{
					if (VALID_BOOLEAN_STRINGS.Contains(unparsedBoolean.ToLower()))
					{
						result.AddHl7Error(Hl7Error.CreateIncorrectCapitalizationBooleanValueError(unparsedBoolean, element, attr));
						booleanResult = Ca.Infoway.Messagebuilder.BooleanUtils.ValueOf(unparsedBoolean);
					}
					else
					{
						result.AddHl7Error(Hl7Error.CreateInvalidBooleanValueError(element, attr));
					}
				}
			}
			return booleanResult;
		}
예제 #3
0
        /// <exception cref="Ca.Infoway.Messagebuilder.Marshalling.HL7.XmlToModelTransformationException"></exception>
        protected override EntityName ParseNonNullNode(ParseContext context, XmlNode node, BareANY parseResult, Type expectedReturnType
                                                       , XmlToModelResult xmlToModelResult)
        {
            EntityName result = null;
            // The incoming xml should specify a specializationType or xsi:type in order to determine how to process the field. (CDA/R1 does allow for EN)
            // However, it should be possible to determine which concrete type to use by applying all known name parsers.
            string specializationType = GetSpecializationType(node);

            if (StringUtils.IsBlank(specializationType))
            {
                specializationType = GetXsiType(node);
            }
            string     upperCaseST = StringUtils.IsBlank(specializationType) ? string.Empty : specializationType.ToUpper();
            NameParser nameParser  = nameParsers.SafeGet(upperCaseST);

            if (nameParser == null && StringUtils.IsNotBlank(specializationType))
            {
                // log error based on bad ST/XT
                xmlToModelResult.AddHl7Error(new Hl7Error(Hl7ErrorCode.DATA_TYPE_ERROR, "Could not determine appropriate parser to use for EN specializationType/xsi:type of: "
                                                          + specializationType, (XmlElement)node));
            }
            if (nameParser != null && nameParser.IsParseable(node, context))
            {
                result = (EntityName)nameParser.Parse(context, node, xmlToModelResult).BareValue;
            }
            else
            {
                string actualParserUsed = null;
                // try all known name parsers
                if (tnElementParser.IsParseable(node, context))
                {
                    actualParserUsed = "TN";
                    result           = (EntityName)tnElementParser.Parse(context, node, xmlToModelResult).BareValue;
                }
                else
                {
                    if (pnElementParser.IsParseable(node, context))
                    {
                        actualParserUsed = "PN";
                        result           = (EntityName)pnElementParser.Parse(context, node, xmlToModelResult).BareValue;
                    }
                    else
                    {
                        if (onElementParser.IsParseable(node, context))
                        {
                            actualParserUsed = "ON";
                            result           = (EntityName)onElementParser.Parse(context, node, xmlToModelResult).BareValue;
                        }
                        else
                        {
                            throw new XmlToModelTransformationException("Cannot figure out how to parse EN node " + node.ToString());
                        }
                    }
                }
                // need to log warning - not able to parse name as expected
                xmlToModelResult.AddHl7Error(new Hl7Error(Hl7ErrorCode.DATA_TYPE_ERROR, ErrorLevel.WARNING, "EN field has been handled as type "
                                                          + actualParserUsed, (XmlElement)node));
            }
            return(result);
        }
예제 #4
0
        private PlatformDate ParseNonNullNode(ParseContext context, XmlElement element, XmlToModelResult xmlToModelResult)
        {
            // TM - for V02R01, "width" property is allowed (PQ.TIME) - not including this here, as MB does not officially support that release
            PlatformDate result       = null;
            string       unparsedDate = GetAttributeValue(element, "value");

            if (StringUtils.IsBlank(unparsedDate))
            {
                xmlToModelResult.AddHl7Error(new Hl7Error(Hl7ErrorCode.DATA_TYPE_ERROR, "Timestamp value must be non-blank.", element));
            }
            else
            {
                try
                {
                    result = ParseDate(unparsedDate, GetAllDateFormats(StandardDataType.GetByTypeName(GetType(context)), context.GetVersion()
                                                                       ), context);
                    CheckForMissingTimezone(context, xmlToModelResult, result, unparsedDate, element);
                }
                catch (ArgumentException)
                {
                    result = TryEveryFormat(context, unparsedDate, element, xmlToModelResult);
                    if (result == null)
                    {
                        string message = "The timestamp " + unparsedDate + " in element " + XmlDescriber.DescribeSingleElement(element) + " cannot be parsed.";
                        xmlToModelResult.AddHl7Error(new Hl7Error(Hl7ErrorCode.DATA_TYPE_ERROR, message, element));
                    }
                }
            }
            return(result);
        }
예제 #5
0
        protected virtual GeneralTimingSpecification ParseNonNullNode(ParseContext context, XmlElement element, Type expectedReturnType
                                                                      , XmlToModelResult xmlResult)
        {
            GeneralTimingSpecification result     = null;
            IList <XmlElement>         components = FindComponents(element, xmlResult);

            if (components.Count == 2)
            {
                Interval <PlatformDate> duration  = ParseDuration(context, xmlResult, components[0]);
                PeriodicIntervalTime    frequency = ParseFrequency(context, xmlResult, components[1]);
                if (duration != null && frequency != null)
                {
                    result = new GeneralTimingSpecification(duration, frequency);
                }
                else
                {
                    if (duration == null)
                    {
                        xmlResult.AddHl7Error(new Hl7Error(Hl7ErrorCode.DATA_TYPE_ERROR, "Could not parse the duration portion of the GTS.BOUNDEDPIVL"
                                                           , components[0]));
                    }
                    if (frequency == null)
                    {
                        xmlResult.AddHl7Error(new Hl7Error(Hl7ErrorCode.DATA_TYPE_ERROR, "Could not parse the frequency portion of the GTS.BOUNDEDPIVL"
                                                           , components[1]));
                    }
                }
            }
            else
            {
                xmlResult.AddHl7Error(new Hl7Error(Hl7ErrorCode.DATA_TYPE_ERROR, System.String.Format("Expected to find 2 <comp> sub-elements, but found {0}"
                                                                                                      , components.Count), element));
            }
            return(result);
        }
예제 #6
0
        public virtual NullFlavor ParseNullNode()
        {
            string     attributeValue = GetAttributeValue(node, NULL_FLAVOR_ATTRIBUTE_NAME);
            NullFlavor nullFlavor     = CodeResolverRegistry.Lookup <NullFlavor>(attributeValue);

            if (ConformanceLevelUtil.IsMandatory(this.conformanceLevel, null))
            {
                xmlToModelResult.AddHl7Error(Hl7Error.CreateMandatoryAttributeIsNullError(NodeUtil.GetLocalOrTagName((XmlElement)node), GetAttributeValue
                                                                                              (node, NULL_FLAVOR_ATTRIBUTE_NAME), (XmlElement)node));
            }
            else
            {
                //      RM #15431 - strictly speaking, nullFlavors are not allowed for REQUIRED fields. However, jurisdictions often ignore this restriction.
                //      FIXME:  TM (see RM18424) - once MB has error levels implemented, this can be reinstated as a warning
                //		} else if (this.conformanceLevel != null && this.conformanceLevel == ConformanceLevel.REQUIRED) {
                //			xmlToModelResult.addHl7Error(Hl7Error.createRequiredAttributeIsNullError(
                //					NodeUtil.getLocalOrTagName((Element) node),
                //					getAttributeValue(node, NULL_FLAVOR_ATTRIBUTE_NAME),
                //					(Element) node));
                if (this.isAssociation && !StringUtils.Equals(GetAttributeValue(node, NULL_FLAVOR_XSI_NIL_ATTRIBUTE_NAME), "true"))
                {
                    if (!Ca.Infoway.Messagebuilder.BooleanUtils.ValueOf(Runtime.GetProperty(Ca.Infoway.Messagebuilder.Marshalling.HL7.Parser.NullFlavorHelper
                                                                                            .MB_SUPPRESS_XSI_NIL_ON_NULLFLAVOR)))
                    {
                        xmlToModelResult.AddHl7Error(Hl7Error.CreateNullFlavorMissingXsiNilError(NodeUtil.GetLocalOrTagName((XmlElement)node), (XmlElement
                                                                                                                                                )node));
                    }
                }
            }
            return(nullFlavor);
        }
예제 #7
0
        // Note that the behaviour for this datatype has not been fully defined by CHI. It is likely that the code below will need to be adjusted at some point.
        /// <exception cref="Ca.Infoway.Messagebuilder.Marshalling.HL7.XmlToModelTransformationException"></exception>
        protected override string ParseNonNullNode(ParseContext context, XmlNode node, BareANY parseResult, Type expectedReturnType
                                                   , XmlToModelResult xmlToModelResult)
        {
            StandardDataType type = StandardDataType.GetByTypeName(context);

            ValidateUnallowedAttributes(type, (XmlElement)node, xmlToModelResult, "compression");
            ValidateUnallowedAttributes(type, (XmlElement)node, xmlToModelResult, "language");
            ValidateUnallowedAttributes(type, (XmlElement)node, xmlToModelResult, "reference");
            ValidateUnallowedAttributes(type, (XmlElement)node, xmlToModelResult, "integrityCheck");
            ValidateUnallowedAttributes(type, (XmlElement)node, xmlToModelResult, "thumbnail");
            ValidateMaxChildCount(context, node, 1);
            if (!Ca.Infoway.Messagebuilder.Domainvalue.Basic.MediaType.XML_TEXT.CodeValue.Equals(GetAttributeValue(node, "mediaType")
                                                                                                 ))
            {
                xmlToModelResult.AddHl7Error(CreateHl7Error("Attribute mediaType must be included with a value of \"text/xml\" for ED.SIGNATURE"
                                                            , (XmlElement)node));
            }
            string  result        = null;
            XmlNode signatureNode = GetNamedChildNode(node, "signature");

            if (signatureNode == null || signatureNode.NodeType != System.Xml.XmlNodeType.Element)
            {
                xmlToModelResult.AddHl7Error(CreateHl7Error("Expected ED.SIGNATURE node to have a child element named signature", (XmlElement
                                                                                                                                   )node));
            }
            else
            {
                result = (string)this.stElementParser.Parse(context, signatureNode, xmlToModelResult).BareValue;
            }
            return(result);
        }
예제 #8
0
        private Boolean?GetInclusiveValue(string elementName, ParseContext context, XmlNode node, XmlToModelResult xmlToModelResult
                                          )
        {
            Boolean?    result     = null;
            XmlNodeList childNodes = node.ChildNodes;

            foreach (XmlNode child in new XmlNodeListIterable(childNodes))
            {
                if (elementName.EqualsIgnoreCase(child.Name))
                {
                    string inclusive = GetAttributeValue(child, "inclusive");
                    if (inclusive != null)
                    {
                        result = System.Convert.ToBoolean(inclusive);
                    }
                    if (inclusive != null && !"true".EqualsIgnoreCase(inclusive) && !"false".EqualsIgnoreCase(inclusive))
                    {
                        xmlToModelResult.AddHl7Error(new Hl7Error(Hl7ErrorCode.DATA_TYPE_ERROR, "The 'inclusive' attribute for URG." + elementName
                                                                  + " must be 'true' or 'false'", (XmlElement)node));
                    }
                    else
                    {
                        if (inclusive != null && !context.Type.StartsWith("URG<PQ."))
                        {
                            xmlToModelResult.AddHl7Error(new Hl7Error(Hl7ErrorCode.DATA_TYPE_ERROR, "The 'inclusive' attribute for URG." + elementName
                                                                      + " is not allowed for types of " + context.Type, (XmlElement)node));
                        }
                    }
                    break;
                }
            }
            return(result);
        }
예제 #9
0
        /// <exception cref="Ca.Infoway.Messagebuilder.Marshalling.HL7.XmlToModelTransformationException"></exception>
        protected override MbDate ParseNonNullNode(ParseContext context, XmlNode node, BareANY bareAny, Type expectedReturnType,
                                                   XmlToModelResult xmlToModelResult)
        {
            XmlElement element      = (XmlElement)node;
            MbDate     result       = null;
            string     unparsedDate = GetAttributeValue(node, "value");

            if (StringUtils.IsBlank(unparsedDate))
            {
                xmlToModelResult.AddHl7Error(new Hl7Error(Hl7ErrorCode.DATA_TYPE_ERROR, "Timestamp value must be non-blank.", element));
            }
            else
            {
                try
                {
                    PlatformDate parsedDate = ParseDate(unparsedDate, GetAllDateFormats(context), context);
                    result = (parsedDate == null ? null : new MbDate(parsedDate));
                }
                catch (ArgumentException)
                {
                    string message = "The timestamp " + unparsedDate + " in element " + XmlDescriber.DescribeSingleElement(element) + " cannot be parsed.";
                    xmlToModelResult.AddHl7Error(new Hl7Error(Hl7ErrorCode.DATA_TYPE_ERROR, message, element));
                }
                this.sxcmHelper.HandleOperator(element, context, xmlToModelResult, (ANYMetaData)bareAny);
            }
            return(result);
        }
예제 #10
0
        public virtual Code GetCorrespondingCode(string code, string codeSystem, Type expectedReturnType, XmlElement element, string
                                                 type, XmlToModelResult xmlToModelResult, bool relaxCodeSystemCheck, bool relaxCodeCheck)
        {
            Type codeType = GetReturnTypeAsCodeType(expectedReturnType);

            if (StandardDataType.CS.Type.Equals(type))
            {
                if (codeSystem != null)
                {
                    xmlToModelResult.AddHl7Error(new Hl7Error(Hl7ErrorCode.DATA_TYPE_ERROR, "CS should not include the 'codeSystem' property. ("
                                                              + XmlDescriber.DescribeSingleElement(element) + ")", element));
                }
            }
            else
            {
                if (StringUtils.IsNotBlank(code) && StringUtils.IsBlank(codeSystem))
                {
                    if (!relaxCodeSystemCheck)
                    {
                        xmlToModelResult.AddHl7Error(CreateMissingCodeSystemError(element, codeType, code));
                    }
                }
            }
            Code result = GetCode(codeType, code, codeSystem);

            // if a code is specified and there is no matching enum value for it,
            // something is seriously wrong
            if (StringUtils.IsNotBlank(code) && result == null && !relaxCodeCheck)
            {
                xmlToModelResult.AddHl7Error(CreateInvalidCodeError(element, codeType, code));
            }
            if (result == null && IsInterface(codeType))
            {
                //MBR-335: In some cases we have fixed values that are not part of the generated API and that have
                //values that do not conform to the expected return type. In this case, just fake up a value as
                //it will be discarded later in HL7SourceMapper. See PolicyActivity.GuarantorPerformerAssignedEntity
                //in ccda r1_1 message set for an example. i.e. GUAR is not a valid RoleClass
                if (relaxCodeCheck)
                {
                    result = WrapFixedCodeValue(code, codeSystem, codeType);
                }
                else
                {
                    // the following code will preserve the codeSystem even if the actual code can not be found
                    if (!StringUtils.IsEmpty(codeSystem))
                    {
                        result = FullCodeWrapper.Wrap(codeType, null, codeSystem);
                    }
                }
            }
            return(result);
        }
예제 #11
0
        /// <exception cref="Ca.Infoway.Messagebuilder.Marshalling.HL7.XmlToModelTransformationException"></exception>
        protected override CodedString <Code> ParseNonNullNode(ParseContext context, XmlNode node, BareANY result, Type expectedReturnType
                                                               , XmlToModelResult xmlToModelResult)
        {
            string value          = null;
            int    childNodeCount = node.ChildNodes.Count;

            if (childNodeCount == 0)
            {
                // this is an empty node, return empty string (null should have a null flavor attribute)
                value = AbstractSingleElementParser <CodedString <Code> > .EMPTY_STRING;
            }
            else
            {
                if (childNodeCount == 1)
                {
                    XmlNode childNode = node.FirstChild;
                    if (childNode.NodeType != System.Xml.XmlNodeType.Text)
                    {
                        xmlToModelResult.AddHl7Error(new Hl7Error(Hl7ErrorCode.DATA_TYPE_ERROR, "Expected SC node to have a text node", (XmlElement
                                                                                                                                         )node));
                    }
                    value = childNode.Value;
                }
                else
                {
                    xmlToModelResult.AddHl7Error(new Hl7Error(Hl7ErrorCode.DATA_TYPE_ERROR, "Expected SC node to have at most one child", (XmlElement
                                                                                                                                           )node));
                }
            }
            string code         = GetAttributeValue(node, "code");
            string codeSystem   = GetAttributeValue(node, "codeSystem");
            Code   lookedUpCode = null;

            if (StringUtils.IsNotBlank(code) && StringUtils.IsNotBlank(codeSystem))
            {
                lookedUpCode = this.codeLookupUtils.GetCorrespondingCode(code, codeSystem, expectedReturnType, (XmlElement)node, context.
                                                                         Type, xmlToModelResult);
            }
            string displayName       = GetAttributeValue(node, "displayName");
            string codeSystemName    = GetAttributeValue(node, "codeSystemName");
            string codeSystemVersion = GetAttributeValue(node, "codeSystemVersion");
            // TM - this cast may not work properly within .NET
            CodedString <Code> codedString = new CodedString <Code>(value, lookedUpCode, displayName, codeSystemName, codeSystemVersion
                                                                    );
            bool codeProvided       = StringUtils.IsNotBlank(code);
            bool codeSystemProvided = StringUtils.IsNotBlank(codeSystem);

            this.codedStringValidationUtils.ValidateCodedString(codedString, codeProvided, codeSystemProvided, (XmlElement)node, null
                                                                , xmlToModelResult);
            return(codedString);
        }
예제 #12
0
        private IList <XmlElement> FindComponents(XmlElement element, XmlToModelResult xmlToModelResult)
        {
            IList <XmlElement> result = new List <XmlElement>();
            XmlNodeList        list   = element.ChildNodes;

            if (list != null)
            {
                foreach (XmlNode node in new XmlNodeListIterable(list))
                {
                    if (node.NodeType != System.Xml.XmlNodeType.Element)
                    {
                    }
                    else
                    {
                        // skip it
                        if (StringUtils.Equals("comp", NodeUtil.GetLocalOrTagName((XmlElement)node)))
                        {
                            result.Add((XmlElement)node);
                        }
                        else
                        {
                            xmlToModelResult.AddHl7Error(new Hl7Error(Hl7ErrorCode.DATA_TYPE_ERROR, System.String.Format("Unexpected tag {0} in GTS.BOUNDEDPIVL"
                                                                                                                         , XmlDescriber.DescribeSingleElement((XmlElement)node)), (XmlElement)node));
                        }
                    }
                }
            }
            return(result);
        }
예제 #13
0
        private void ParseUseablePeriods(XmlNode node, XmlToModelResult xmlToModelResult, TelecommunicationAddress result, ParseContext
                                         context)
        {
            XmlNodeList childNodes = node.ChildNodes;

            foreach (XmlNode childNode in new XmlNodeListIterable(childNodes))
            {
                if (childNode is XmlElement)
                {
                    XmlElement useablePeriodElement = (XmlElement)childNode;
                    string     name = NodeUtil.GetLocalOrTagName(useablePeriodElement);
                    if ("useablePeriod".Equals(name))
                    {
                        BareANY tsAny  = tsR2ElementParser.Parse(TsContext(context), useablePeriodElement, xmlToModelResult);
                        MbDate  mbDate = (MbDate)tsAny.BareValue;
                        result.AddUseablePeriod(mbDate == null ? null : mbDate.Value, ((ANYMetaData)tsAny).Operator);
                    }
                    else
                    {
                        xmlToModelResult.AddHl7Error(new Hl7Error(Hl7ErrorCode.DATA_TYPE_ERROR, "Unexpected TEL child element: \"" + useablePeriodElement
                                                                  .Name + "\"", useablePeriodElement));
                    }
                }
            }
        }
예제 #14
0
 private void RecordTooManyDigitsBeforeDecimalError(string value, string type, XmlToModelResult result, XmlElement element
                                                    )
 {
     result.AddHl7Error(new Hl7Error(Hl7ErrorCode.DATA_TYPE_ERROR, "Value " + value + " of type " + type + " should have no more than "
                                     + MAX_DIGITS_BEFORE_DECIMAL + " digits before the decimal (" + XmlDescriber.DescribeSingleElement(element) + ")", element
                                     ));
 }
예제 #15
0
        // only checking II constraints for now
        /// <exception cref="Ca.Infoway.Messagebuilder.Marshalling.HL7.XmlToModelTransformationException"></exception>
        public override BareANY Parse(ParseContext context, IList <XmlNode> nodes, XmlToModelResult xmlToModelResult)
        {
            string subType             = GetSubType(context);
            ICollection <BareANY> list = GetCollectionType(context);

            ValidateCardinality(context, nodes, xmlToModelResult);
            foreach (XmlNode node in nodes)
            {
                string        actualType = DetermineActualType(node, subType, context.IsCda(), xmlToModelResult);
                ElementParser parser     = this.parserRegistry.Get(actualType);
                if (parser != null)
                {
                    BareANY result = parser.Parse(ParseContextImpl.Create(actualType, GetSubTypeAsModelType(context), context), ToList(node),
                                                  xmlToModelResult);
                    // constraints are *not* passed down with collections
                    if (result != null)
                    {
                        if (!StringUtils.Equals(subType, actualType))
                        {
                            result.DataType = StandardDataType.GetByTypeName(actualType);
                        }
                        if (list.Contains(result))
                        {
                            ResultAlreadyExistsInCollection(result, (XmlElement)node, xmlToModelResult);
                        }
                        list.Add(result);
                    }
                }
                else
                {
                    xmlToModelResult.AddHl7Error(new Hl7Error(Hl7ErrorCode.INTERNAL_ERROR, "No parser type found for " + actualType, (XmlElement
                                                                                                                                      )node));
                }
            }
            HandleConstraints(subType, list, context.GetConstraints(), nodes, xmlToModelResult);
            BareANY wrapResult = null;

            try
            {
                wrapResult = WrapWithHl7DataType(context.Type, subType, list, context);
            }
            catch (MarshallingException e)
            {
                xmlToModelResult.AddHl7Error(new Hl7Error(Hl7ErrorCode.INTERNAL_ERROR, e.Message, (string)null));
            }
            return(wrapResult);
        }
예제 #16
0
        private object DelegateToConcreteParser(ParseContext context, XmlNode node, BareANY hl7Result, XmlToModelResult xmlToModelResult
                                                )
        {
            object result             = null;
            string parentType         = context == null ? null : context.Type;
            string specializationType = ObtainSpecializationType(parentType, node, xmlToModelResult);

            if (StringUtils.IsNotBlank(specializationType))
            {
                string mappedSpecializationType = this.polymorphismHandler.MapCdaR1Type(StandardDataType.GetByTypeName(specializationType
                                                                                                                       ), context.IsCda());
                ElementParser elementParser = ParserRegistry.GetInstance().Get(mappedSpecializationType);
                if (elementParser == null || !IsValidTypeForAny(parentType, specializationType))
                {
                    xmlToModelResult.AddHl7Error(Hl7Error.CreateInvalidTypeError(specializationType, parentType, (XmlElement)node));
                }
                else
                {
                    BareANY parsedValue = elementParser.Parse(ParseContextImpl.CreateWithConstraints(mappedSpecializationType, DetermineReturnType
                                                                                                         (specializationType, GetReturnType(context)), context), Arrays.AsList(node), xmlToModelResult);
                    result = parsedValue.BareValue;
                    // Yes, this is a side effect of calling this method. If we don't do this then the actual type of the ANY.LAB (i.e. PQ.LAB) is lost.
                    hl7Result.DataType   = parsedValue.DataType;
                    hl7Result.NullFlavor = parsedValue.NullFlavor;
                    // preserve all metadata (yes, also not a great side effect); this will have to be adjusted whenever new metadata is added to a data type (extremely infrequently)
                    if (hl7Result is ANYMetaData && parsedValue is ANYMetaData)
                    {
                        ANYMetaData anyMetaDataResult = (ANYMetaData)hl7Result;
                        ANYMetaData anyMetaDataParsed = (ANYMetaData)parsedValue;
                        anyMetaDataResult.Language     = anyMetaDataParsed.Language;
                        anyMetaDataResult.DisplayName  = anyMetaDataParsed.DisplayName;
                        anyMetaDataResult.OriginalText = anyMetaDataParsed.OriginalText;
                        anyMetaDataResult.Translations.AddAll(anyMetaDataParsed.Translations);
                        anyMetaDataResult.IsCdata  = anyMetaDataParsed.IsCdata;
                        anyMetaDataResult.Operator = anyMetaDataParsed.Operator;
                        anyMetaDataResult.Unsorted = anyMetaDataParsed.Unsorted;
                    }
                }
            }
            else
            {
                xmlToModelResult.AddHl7Error(Hl7Error.CreateMissingMandatoryAttributeError(AbstractElementParser.SPECIALIZATION_TYPE, (XmlElement
                                                                                                                                       )node));
            }
            return(result);
        }
예제 #17
0
        public virtual void TestIsValid()
        {
            XmlToModelResult xmlResult = new XmlToModelResult();

            Assert.IsTrue(xmlResult.IsValid(), "is valid");
            xmlResult.AddHl7Error(new Hl7Error(Hl7ErrorCode.DATA_TYPE_ERROR, "monkey", "a.property.path"));
            Assert.IsFalse(xmlResult.IsValid(), "is not valid");
        }
예제 #18
0
        // do nothing; allow subclasses to override if necessary
        private void ValidateCardinality(ParseContext context, IList <XmlNode> nodes, XmlToModelResult xmlToModelResult)
        {
            int size = nodes.Count;
            int min  = (int)context.GetCardinality().Min;
            int max  = (int)context.GetCardinality().Max;

            if (size < min)
            {
                xmlToModelResult.AddHl7Error(new Hl7Error(Hl7ErrorCode.DATA_TYPE_ERROR, "Number of elements (" + size + ") is less than the specified minimum ("
                                                          + min + ")", GetFirst(nodes)));
            }
            if (size > max)
            {
                xmlToModelResult.AddHl7Error(new Hl7Error(Hl7ErrorCode.DATA_TYPE_ERROR, "Number of elements (" + size + ") is more than the specified maximum ("
                                                          + max + ")", GetFirst(nodes)));
            }
        }
예제 #19
0
 //	private void recordNotNegativeError(Element element, XmlToModelResult xmlToModelResult) {
 //		xmlToModelResult.addHl7Error(
 //				new Hl7Error(Hl7ErrorCode.DATA_TYPE_ERROR,
 //						"The attribute \"value\" must not be negative for INT.NONNEG. ("
 //						+ XmlDescriber.describeSingleElement(element)
 //						+ ")", element));
 //	}
 //
 private void RecordInvalidIntegerError(Int32?result, XmlElement element, bool mustBePositive, XmlToModelResult xmlToModelResult
                                        )
 {
     xmlToModelResult.AddHl7Error(new Hl7Error(Hl7ErrorCode.DATA_TYPE_ERROR, "The attribute \"value\" is not a valid integer: it cannot be negative "
                                               + (mustBePositive ? "or zero " : string.Empty) + "and must be digits only (maximum of 10), with a maximum value of " +
                                               int.MaxValue + "." + " The value may have been truncated; processing value as " + result + " (" + XmlDescriber.DescribeSingleElement
                                                   (element) + ")", element));
 }
예제 #20
0
 private void ValidateNonAllowedChildNode(XmlElement element, XmlToModelResult xmlToModelResult, string elementName)
 {
     if (GetNamedChildNode(element, elementName) != null)
     {
         xmlToModelResult.AddHl7Error(new Hl7Error(Hl7ErrorCode.DATA_TYPE_ERROR, "Periodic Interval (PIVL<TS.DATETIME>) does not allow the <"
                                                   + elementName + "> element", element));
     }
 }
예제 #21
0
 protected virtual void ValidateUnallowedAttributes(StandardDataType type, XmlElement node, XmlToModelResult result, string
                                                    attribute)
 {
     if (StringUtils.IsNotBlank(GetAttributeValue(node, attribute)))
     {
         result.AddHl7Error(new Hl7Error(Hl7ErrorCode.DATA_TYPE_ERROR, type.Type + " should not include the '" + attribute + "' property. ("
                                         + XmlDescriber.DescribeSingleElement(node) + ")", node));
     }
 }
예제 #22
0
        private TelecommunicationAddress ParseValue(XmlNode node, XmlToModelResult xmlToModelResult)
        {
            string value = GetAttributeValue(node, "value");

            if (StringUtils.IsBlank(value))
            {
                xmlToModelResult.AddHl7Error(new Hl7Error(Hl7ErrorCode.DATA_TYPE_ERROR, "TEL elements must have a value or a nullFlavor."
                                                          , (XmlElement)node));
            }
            // remove the // that appear after the colon if necessary
            // e.g. file://monkey
            value = value == null ? null : System.Text.RegularExpressions.Regex.Replace(value, "://", ":");
            // anything before the FIRST colon is the URL scheme. Anything after it is the address.
            int    colonIndex = value == null ? -1 : value.IndexOf(':');
            string address    = null;

            Ca.Infoway.Messagebuilder.Domainvalue.URLScheme urlScheme = null;
            if (colonIndex == -1)
            {
                address = value;
            }
            else
            {
                address = Ca.Infoway.Messagebuilder.StringUtils.Substring(value, colonIndex + 1);
                string urlSchemeString = Ca.Infoway.Messagebuilder.StringUtils.Substring(value, 0, colonIndex);
                urlScheme = CodeResolverRegistry.Lookup <Ca.Infoway.Messagebuilder.Domainvalue.URLScheme>(urlSchemeString);
                if (urlScheme == null)
                {
                    urlScheme = CodeResolverRegistry.Lookup <Ca.Infoway.Messagebuilder.Domainvalue.URLScheme>(urlSchemeString.ToLower());
                    if (urlScheme == null)
                    {
                        string message = "Unrecognized URL scheme '" + urlSchemeString + "' in element " + XmlDescriber.DescribePath(node);
                        xmlToModelResult.AddHl7Error(new Hl7Error(Hl7ErrorCode.DATA_TYPE_ERROR, message, (XmlElement)node));
                    }
                }
            }
            TelecommunicationAddress result = new TelecommunicationAddress();

            result.Address   = address;
            result.UrlScheme = urlScheme;
            return(result);
        }
예제 #23
0
        protected virtual void ValidateUnallowedChildNode(string type, XmlElement node, XmlToModelResult result, string childNodeName
                                                          )
        {
            XmlNode child = GetNamedChildNode(node, childNodeName);

            if (child != null)
            {
                result.AddHl7Error(new Hl7Error(Hl7ErrorCode.DATA_TYPE_ERROR, type + " should not include the '" + childNodeName + "' property. ("
                                                + XmlDescriber.DescribeSingleElement(node) + ")", node));
            }
        }
예제 #24
0
        /// <exception cref="Ca.Infoway.Messagebuilder.Marshalling.HL7.XmlToModelTransformationException"></exception>
        private string GetTextValue(XmlElement element, XmlToModelResult xmlToModelResult)
        {
            string result = NodeUtil.GetTextValue(element, true);

            if (StringUtils.IsBlank(result))
            {
                xmlToModelResult.AddHl7Error(new Hl7Error(Hl7ErrorCode.DATA_TYPE_ERROR, "Expected PN child node \"" + element.Name + "\" to have a text node"
                                                          , element));
            }
            return(result);
        }
예제 #25
0
        private void ValidateFixedValue(XmlToModelResult result, XmlElement element, XmlAttribute attributeNode, Relationship relationship
                                        )
        {
            string value = attributeNode.Value;

            if (!StringUtils.Equals(value, relationship.FixedValue))
            {
                result.AddHl7Error(new Hl7Error(Hl7ErrorCode.SYNTAX_ERROR, System.String.Format("Invalid attribute value: expected \"{0}\" but was \"{1}\" ({2})"
                                                                                                , relationship.FixedValue, value, XmlDescriber.DescribeSingleElement(element)), attributeNode));
            }
        }
예제 #26
0
        /// <exception cref="Ca.Infoway.Messagebuilder.Marshalling.HL7.XmlToModelTransformationException"></exception>
        protected virtual string GetMandatoryAttributeValue(XmlNode node, string attributeName, XmlToModelResult parsingResult)
        {
            string result = GetAttributeValue(node, attributeName);

            if (StringUtils.IsBlank(result))
            {
                parsingResult.AddHl7Error(new Hl7Error(Hl7ErrorCode.DATA_TYPE_ERROR, "Attribute " + attributeName + " is mandatory for node "
                                                       + XmlDescriber.DescribePath(node) + " (" + XmlDescriber.DescribeSingleElement((XmlElement)node) + ")", (XmlElement)node
                                                       ));
            }
            return(result);
        }
예제 #27
0
        protected override bool HasValidNullFlavorAttribute(ParseContext context, XmlNode node, XmlToModelResult result)
        {
            bool isBN       = StringUtils.Equals(context.Type, StandardDataType.BN.Type);
            bool hasValidNF = base.HasValidNullFlavorAttribute(context, node, result);

            if (isBN && hasValidNF)
            {
                result.AddHl7Error(new Hl7Error(Hl7ErrorCode.MANDATORY_FIELD_NOT_PROVIDED, "BN field may not have a nullFlavor", (XmlElement
                                                                                                                                  )node));
            }
            return(hasValidNF);
        }
예제 #28
0
        private Diff <PlatformDate> CreateDateDiff(ParseContext context, XmlElement width, XmlToModelResult xmlToModelResult)
        {
            Diff <PlatformDate> result = null;

            if (GetAttributeValue(width, NullFlavorHelper.NULL_FLAVOR_ATTRIBUTE_NAME) != null)
            {
                result = ParseNullWidthNode(width);
            }
            else
            {
                try
                {
                    StandardDataType diffType = StandardDataType.PQ_TIME;
                    ElementParser    parser   = ParserRegistry.GetInstance().Get(diffType);
                    if (parser != null)
                    {
                        ParseContext subContext = ParseContextImpl.Create(diffType.Type, typeof(PhysicalQuantity), Ca.Infoway.Messagebuilder.Xml.ConformanceLevel
                                                                          .POPULATED, Cardinality.Create("1"), context);
                        PhysicalQuantity quantity = (PhysicalQuantity)parser.Parse(subContext, Arrays.AsList((XmlNode)width), xmlToModelResult).BareValue;
                        // though in some PQ cases units can be null, this situation does not seem to make sense for PQ.TIME
                        if (quantity != null && quantity.Quantity != null && quantity.Unit != null)
                        {
                            result = new DateDiff(quantity);
                        }
                    }
                    else
                    {
                        xmlToModelResult.AddHl7Error(new Hl7Error(Hl7ErrorCode.DATA_TYPE_ERROR, "Cannot find a parser for " + diffType.Type, width
                                                                  ));
                    }
                }
                catch (XmlToModelTransformationException e)
                {
                    xmlToModelResult.AddHl7Error(new Hl7Error(Hl7ErrorCode.DATA_TYPE_ERROR, e.Message, width));
                }
            }
            return(result);
        }
예제 #29
0
        private ParseContext HandleSpecializationType(ParseContext context, XmlNode node, XmlToModelResult xmlToModelResult)
        {
            string specializationType = GetSpecializationType(node);

            if (specializationType == null)
            {
                // TM - RedMine issue 492 - there is some concern over MBT forcing a specialization type for abstract TS type TS_FULLDATEWITHTIME
                //    - I'm relaxing this validation for the time being (the formatter currently ignores specialization type completely)
                //    - (update: perhaps the real issue is that this was an IVL<TS.FULLDATEWITHTIME> and MB has a bug where inner types can't have specializationType set??)
                // TM - 16/10/2012 - should be able to set specialization type now (need to specify IVL_FULL_DATE_TIME as the specialization type for IVL<TS.FULLDATEWITHTIME>, for example)
                //                 - in a cowardly move, I have allowed for a system property to bypass this validation error
                if (Ca.Infoway.Messagebuilder.BooleanUtils.ValueOf(Runtime.GetProperty(TsDateFormats.ABSTRACT_TS_IGNORE_SPECIALIZATION_TYPE_ERROR_PROPERTY_NAME
                                                                                       )))
                {
                }
                else
                {
                    // do nothing - fall back to parsing through all allowable date formats for TS.FULLDATEWITHTIME
                    xmlToModelResult.AddHl7Error(Hl7Error.CreateMissingMandatoryAttributeError(AbstractElementParser.SPECIALIZATION_TYPE, (XmlElement
                                                                                                                                           )node));
                }
            }
            else
            {
                if (IsValidSpecializationType(specializationType))
                {
                    context = ParseContextImpl.Create(specializationType, context);
                }
                else
                {
                    // log error - fall back to parsing through all allowable date formats for TS.FULLDATEWITHTIME
                    xmlToModelResult.AddHl7Error(new Hl7Error(Hl7ErrorCode.DATA_TYPE_ERROR, "Invalid specialization type " + specializationType
                                                              + " (" + XmlDescriber.DescribeSingleElement((XmlElement)node) + ")", (XmlElement)node));
                }
            }
            return(context);
        }
예제 #30
0
        private TelecommunicationAddress ParseTelecommunicationAddress(XmlNode node, XmlToModelResult xmlToModelResult)
        {
            string value = GetAttributeValue(node, "value");

            if (StringUtils.IsBlank(value) && this.allowReference)
            {
                value = GetAttributeValue(node, "reference");
            }
            // remove the // that appear after the colon if necessary
            // e.g. file://monkey
            value = value == null ? null : System.Text.RegularExpressions.Regex.Replace(value, "://", ":");
            // anything before the FIRST colon is the URL scheme. Anything after it is the address.
            int    colonIndex = value == null ? -1 : value.IndexOf(':');
            string address    = null;

            Ca.Infoway.Messagebuilder.Domainvalue.URLScheme urlScheme = null;
            if (colonIndex == -1)
            {
                address = value;
            }
            else
            {
                address = Ca.Infoway.Messagebuilder.StringUtils.Substring(value, colonIndex + 1);
                string urlSchemeString = Ca.Infoway.Messagebuilder.StringUtils.Substring(value, 0, colonIndex);
                urlScheme = CodeResolverRegistry.Lookup <Ca.Infoway.Messagebuilder.Domainvalue.URLScheme>(urlSchemeString);
                if (urlScheme == null)
                {
                    string message = "Unrecognized URL scheme '" + urlSchemeString + "' in element " + XmlDescriber.DescribePath(node);
                    xmlToModelResult.AddHl7Error(new Hl7Error(Hl7ErrorCode.DATA_TYPE_ERROR, message, (XmlElement)node));
                }
            }
            TelecommunicationAddress result = new TelecommunicationAddress();

            result.Address   = address;
            result.UrlScheme = urlScheme;
            // handle address uses
            string addressUses = GetAttributeValue(node, "use");

            if (addressUses != null)
            {
                StringTokenizer tokenizer = new StringTokenizer(addressUses);
                while (tokenizer.HasMoreElements())
                {
                    result.AddAddressUse(CodeResolverRegistry.Lookup <Ca.Infoway.Messagebuilder.Domainvalue.TelecommunicationAddressUse>(tokenizer
                                                                                                                                         .NextToken()));
                }
            }
            return(result);
        }