Module: FHIR::CommonStructureDefinitionCompare
- Extended by:
- Deprecate
- Included in:
- R4::StructureDefinitionCompare, R4B::StructureDefinitionCompare, R5::StructureDefinitionCompare
- Defined in:
- lib/fhir_models/fhir_ext/common_structure_definition_compare.rb
Overview
Extend StructureDefinition for profile comparison code
Instance Method Summary collapse
-
#compatible?(another_definition) ⇒ Boolean
Checks whether or not “another_definition” is compatible with this definition.
- #get_element_by_path(path, elements = snapshot.element) ⇒ Object
- #get_extension(extension, elements = snapshot.element) ⇒ Object
Methods included from Deprecate
Instance Method Details
#compatible?(another_definition) ⇒ Boolean
Checks whether or not “another_definition” is compatible with this definition. If they have conflicting elements, restrictions, bindings, modifying extensions, etc.
12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 |
# File 'lib/fhir_models/fhir_ext/common_structure_definition_compare.rb', line 12 def compatible?(another_definition) @errors = [] @warnings = [] @finding = FHIR::StructureDefinitionFinding.new @finding.resourceType = snapshot.element[0].path @finding.profileIdA = id @finding.profileIdB = another_definition.id if another_definition.respond_to?(:id) if !(another_definition.is_a? versioned_fhir_module::StructureDefinition) @errors << @finding.error('', '', 'Not a StructureDefinition', 'StructureDefinition', another_definition.class.name.to_s) return false elsif another_definition.snapshot.element[0].path != snapshot.element[0].path @errors << @finding.error('', '', 'Incompatible resourceType', @finding.resourceType, another_definition.snapshot.element[0].path.to_s) return false end left_elements = Array.new(snapshot.element) right_elements = Array.new(another_definition.snapshot.element) left_paths = left_elements.map(&:path) right_paths = right_elements.map(&:path) # StructureDefinitions don't always include all base attributes (for example, of a ContactPoint) # if nothing is modified from the base definition, so we have to add them in if they are missing. base_definition = versioned_fhir_module::Definitions.get_resource_definition(snapshot.element[0].path) base_elements = base_definition.snapshot.element left_missing = right_paths - left_paths # left_missing_roots = left_missing.map{|e| e.split('.')[0..-2].join('.') }.uniq add_missing_elements(id, left_missing, left_elements, base_elements) right_missing = left_paths - right_paths # right_missing_roots = right_missing.map{|e| e.split('.')[0..-2].join('.') }.uniq add_missing_elements(another_definition.id, right_missing, right_elements, base_elements) # update paths left_paths = left_elements.map(&:path) right_paths = right_elements.map(&:path) # recalculate the missing attributes left_missing = right_paths - left_paths right_missing = left_paths - right_paths # generate warnings for missing fields (ignoring extensions) left_missing.each do |e| next if e.include? 'extension' elem = get_element_by_path(e, right_elements) if !elem.min.nil? && elem.min.positive? @errors << @finding.error(e, 'min', 'Missing REQUIRED element', 'Missing', elem.min.to_s) elsif elem.isModifier == true @errors << @finding.error(e, 'isModifier', 'Missing MODIFIER element', 'Missing', elem.isModifier.to_s) else @warnings << @finding.warning(e, '', 'Missing element', 'Missing', 'Defined') end end right_missing.each do |e| next if e.include? 'extension' elem = get_element_by_path(e, left_elements) if !elem.min.nil? && elem.min.positive? @errors << @finding.error(e, 'min', 'Missing REQUIRED element', elem.min.to_s, 'Missing') elsif elem.isModifier == true @errors << @finding.error(e, 'isModifier', 'Missing MODIFIER element', elem.isModifier.to_s, 'Missing') else @warnings << @finding.warning(e, '', 'Missing element', 'Defined', 'Missing') end end left_extensions = [] right_extensions = [] # compare elements, starting with the elements in this definition left_elements.each do |x| if x.path.include? 'extension' # handle extensions separately left_extensions << x else y = get_element_by_path(x.path, right_elements) compare_element_definitions(x, y, another_definition) end end # now compare elements defined in the other definition, if we haven't already looked at them right_elements.each do |y| if y.path.include? 'extension' # handle extensions separately right_extensions << y elsif left_missing.include? y.path x = get_element_by_path(y.path, left_elements) compare_element_definitions(x, y, another_definition) end end # finally, compare the extensions. checked_extensions = [] left_extensions.each do |x| y = get_extension(x.name, right_extensions) unless y.nil? # both profiles share an extension with the same name checked_extensions << x.name compare_extension_definition(x, y, another_definition) end y = get_extension(x.type[0].profile, right_extensions) next unless !y.nil? && x.name != y.name # both profiles share the same extension definition but with a different name checked_extensions << x.name checked_extensions << y.name compare_element_definitions(x, y, another_definition) end right_extensions.each do |y| next if checked_extensions.include?(y.name) x = get_extension(y.name, left_extensions) unless x.nil? # both profiles share an extension with the same name checked_extensions << y.name compare_extension_definition(x, y, another_definition) end x = get_extension(y.type[0].profile, left_extensions) next unless !x.nil? && x.name != y.name && !checked_extensions.include?(x.name) # both profiles share the same extension definition but with a different name checked_extensions << x.name checked_extensions << y.name compare_element_definitions(x, y, another_definition) end @errors.flatten! @warnings.flatten! @errors.size.zero? end |
#get_element_by_path(path, elements = snapshot.element) ⇒ Object
147 148 149 |
# File 'lib/fhir_models/fhir_ext/common_structure_definition_compare.rb', line 147 def get_element_by_path(path, elements = snapshot.element) elements.detect { |element| element.path == path } end |
#get_extension(extension, elements = snapshot.element) ⇒ Object
151 152 153 154 155 156 157 158 |
# File 'lib/fhir_models/fhir_ext/common_structure_definition_compare.rb', line 151 def get_extension(extension, elements = snapshot.element) elements.each do |element| if element.path.include?('extension') || element.type.map(&:code).include?('Extension') return element if element.name == extension || element.type.map(&:profile).include?(extension) end end nil end |