/// <summary>Adds a code system to 'codeSystem'.</summary> /// <param name="values"> [in,out] The values.</param> /// <param name="codeSystem">The code system.</param> /// <param name="comp"> The component.</param> private void AddCodeSystem( ref Dictionary <string, FhirConcept> values, FhirCodeSystem codeSystem, FhirValueSetComposition comp) { if (comp.Concepts != null) { AddConcepts(ref values, comp.Concepts); return; } if (comp.Filters != null) { ApplyFilteredConcepts(ref values, codeSystem, comp.Filters, true, false); return; } AddFromNode( ref values, codeSystem.RootConcept, false, true, false, string.Empty, null, null, null); }
/// <summary>Adds a filtered concepts.</summary> /// <exception cref="ArgumentNullException">Thrown when one or more required arguments are null.</exception> /// <param name="values"> [in,out] The values.</param> /// <param name="codeSystem">The code system.</param> /// <param name="filters"> Specifies the filters.</param> /// <param name="include"> True to include, false to exclude.</param> /// <param name="exclude"> True to exclude, false to include.</param> private static void ApplyFilteredConcepts( ref Dictionary <string, FhirConcept> values, FhirCodeSystem codeSystem, List <FhirValueSetFilter> filters, bool include, bool exclude) { if (codeSystem == null) { throw new ArgumentNullException(nameof(codeSystem)); } if ((filters == null) || (filters.Count == 0)) { throw new ArgumentNullException(nameof(filters)); } if (include && exclude) { #pragma warning disable CA1303 // Do not pass literals as localized parameters throw new Exception("Cannot include and exclude the same filters!"); #pragma warning restore CA1303 // Do not pass literals as localized parameters } if ((!include) && (!exclude)) { #pragma warning disable CA1303 // Do not pass literals as localized parameters throw new Exception("Must either include or exclude for filters!"); #pragma warning restore CA1303 // Do not pass literals as localized parameters } string startingCode = string.Empty; bool includeSelf = false; bool includeChildren = false; bool includeParents = false; string exclusionKey = string.Empty; Regex regex = null; HashSet <string> inclusionSet = null; HashSet <string> exclusionSet = null; int maxRecusrions = -1; List <KeyValuePair <string, string> > filterProperties = new List <KeyValuePair <string, string> >(); foreach (FhirValueSetFilter filter in filters) { string filterKey = $"{filter.Property}:{filter.Operation}"; switch (filterKey) { case "concept:=": startingCode = filter.Value; includeSelf = true; includeChildren = false; includeParents = false; break; case "concept:is-a": startingCode = filter.Value; includeSelf = true; includeChildren = true; includeParents = false; break; case "concept:descendent-of": startingCode = filter.Value; includeSelf = false; includeChildren = true; includeParents = false; break; case "concept:is-not-a": exclusionKey = filter.Value; break; case "concept:regex": regex = new Regex(filter.Value); break; case "concept:in": inclusionSet = new HashSet <string>(); string[] inculsions = filter.Value.Split(','); foreach (string value in inculsions) { inclusionSet.Add(value); } break; case "concept:not-in": exclusionSet = new HashSet <string>(); string[] exclusions = filter.Value.Split(','); foreach (string value in exclusions) { exclusionSet.Add(value); } break; case "concept:generalizes": startingCode = filter.Value; includeSelf = true; includeChildren = false; includeParents = true; break; case "parent:=": startingCode = filter.Value; includeSelf = false; includeChildren = true; includeParents = false; maxRecusrions = 1; break; case "child:=": startingCode = filter.Value; includeSelf = false; includeChildren = false; includeParents = true; maxRecusrions = 1; break; // ignore these case "acme-plasma:=": return; case "concept:exists": default: if (filter.Operation == "=") { filterProperties.Add(new KeyValuePair <string, string>(filter.Property, filter.Value)); includeSelf = true; includeChildren = true; includeParents = false; continue; } throw new NotImplementedException($"Unhandled filter: {filterKey}"); } } FhirConceptTreeNode startingNode = codeSystem.RootConcept; if ((!string.IsNullOrEmpty(startingCode)) && codeSystem.ContainsConcept(startingCode)) { startingNode = codeSystem[startingCode]; } if (include) { AddFromNode( ref values, startingNode, includeSelf, includeChildren, includeParents, exclusionKey, regex, inclusionSet, exclusionSet, maxRecusrions, filterProperties); } if (exclude) { RemoveFromNode( ref values, startingNode, includeSelf, includeChildren, includeParents, exclusionKey, regex, inclusionSet, exclusionSet, maxRecusrions, filterProperties); } }