fhir_stu3_models 3.1.1 → 3.2.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -39,11 +39,12 @@ module FHIR
39
39
  key = key.to_s
40
40
  meta = self.class::METADATA[key]
41
41
  next if meta.nil?
42
+
42
43
  local_name = key
43
44
  local_name = meta['local_name'] if meta['local_name']
44
45
  begin
45
46
  instance_variable_set("@#{local_name}", value)
46
- rescue
47
+ rescue StandardError
47
48
  # TODO: this appears to be a dead code branch
48
49
  nil
49
50
  end
@@ -86,7 +87,7 @@ module FHIR
86
87
  if child['resourceType'] && !klass::METADATA['resourceType']
87
88
  klass = begin
88
89
  FHIR::STU3.const_get(child['resourceType'])
89
- rescue => _exception
90
+ rescue StandardError => _e
90
91
  # TODO: this appears to be a dead code branch
91
92
  # TODO: should this log / re-raise the exception if encountered instead of silently swallowing it?
92
93
  FHIR::STU3.logger.error("Unable to identify embedded class #{child['resourceType']}\n#{exception.backtrace}")
@@ -95,10 +96,10 @@ module FHIR
95
96
  end
96
97
  begin
97
98
  obj = klass.new(child)
98
- rescue => exception
99
+ rescue StandardError => e
99
100
  # TODO: this appears to be a dead code branch
100
101
  # TODO: should this re-raise the exception if encountered instead of silently swallowing it?
101
- FHIR::STU3.logger.error("Unable to inflate embedded class #{klass}\n#{exception.backtrace}")
102
+ FHIR::STU3.logger.error("Unable to inflate embedded class #{klass}\n#{e.backtrace}")
102
103
  end
103
104
  obj
104
105
  end
@@ -7,7 +7,7 @@ module FHIR
7
7
  # This module includes methods to serialize or deserialize FHIR resources to and from JSON.
8
8
  #
9
9
 
10
- def to_json
10
+ def to_json(*_args)
11
11
  JSON.pretty_unparse(to_hash)
12
12
  end
13
13
 
@@ -18,7 +18,7 @@ module FHIR
18
18
  resource_type = hash['resourceType']
19
19
  klass = Module.const_get("FHIR::STU3::#{resource_type}")
20
20
  resource = klass.new(hash)
21
- rescue => e
21
+ rescue StandardError => e
22
22
  FHIR::STU3.logger.error("Failed to deserialize JSON:\n#{e.backtrace}")
23
23
  FHIR::STU3.logger.debug("JSON:\n#{json}")
24
24
  resource = nil
@@ -23,40 +23,39 @@ module FHIR
23
23
  to_hash.hash
24
24
  end
25
25
 
26
+ def respond_to_missing?(method_name, *)
27
+ (defined?(self.class::MULTIPLE_TYPES) && self.class::MULTIPLE_TYPES[method_name.to_s]) ||
28
+ (!@extension.nil? && !@extension.empty? && !find_extension(@extension, method_name).first.nil?) ||
29
+ (!@modifierExtension.nil? && !@modifierExtension.empty? && !find_extension(@modifierExtension, method_name).first.nil?) ||
30
+ super
31
+ end
32
+
26
33
  # allow two FHIR models to be compared for equality
27
34
  def ==(other)
28
35
  self.class == other.class && to_hash == other.to_hash
29
36
  end
30
37
  alias eql? ==
31
38
 
32
- def method_missing(method, *_args, &_block)
33
- if defined?(self.class::MULTIPLE_TYPES) && self.class::MULTIPLE_TYPES[method.to_s]
34
- self.class::MULTIPLE_TYPES[method.to_s].each do |type|
39
+ def method_missing(method_name, *_args, &_block)
40
+ if defined?(self.class::MULTIPLE_TYPES) && self.class::MULTIPLE_TYPES[method_name.to_s]
41
+ self.class::MULTIPLE_TYPES[method_name.to_s].each do |type|
35
42
  type[0] = type[0].upcase
36
- value = send("#{method}#{type}".to_sym)
43
+ value = send("#{method_name}#{type}".to_sym)
37
44
  return value unless value.nil?
38
45
  end
39
46
  return nil
40
47
  elsif !@extension.nil? && !@extension.empty?
41
- ext = @extension.select do |x|
42
- name = x.url.tr('-', '_').split('/').last
43
- anchor = name.split('#').last
44
- (method.to_s == name || method.to_s == anchor)
45
- end
46
- unless ext.first.nil?
47
- return ext.first.value.nil? ? ext.first : ext.first.value
48
+ desired_extension = find_extension(@extension, method_name)
49
+ unless desired_extension.first.nil?
50
+ return desired_extension.first.value.nil? ? desired_extension.first : desired_extension.first.value
48
51
  end
49
52
  elsif !@modifierExtension.nil? && !@modifierExtension.empty?
50
- ext = @modifierExtension.select do |x|
51
- name = x.url.tr('-', '_').split('/').last
52
- anchor = name.split('#').last
53
- (method.to_s == name || method.to_s == anchor)
54
- end
55
- unless ext.first.nil?
56
- return ext.first.value.nil? ? ext.first : ext.first.value
53
+ desired_extension = find_extension(@modifierExtension, method_name)
54
+ unless desired_extension.first.nil?
55
+ return desired_extension.first.value.nil? ? desired_extension.first : desired_extension.first.value
57
56
  end
58
57
  end
59
- raise NoMethodError.new("undefined method `#{method}' for #{self.class.name}", method)
58
+ raise NoMethodError.new("undefined method `#{method_name}' for #{self.class.name}", method_name)
60
59
  end
61
60
 
62
61
  def to_reference
@@ -142,14 +141,14 @@ module FHIR
142
141
  end # metadata.each
143
142
  # check multiple types
144
143
  multiple_types = begin
145
- self.class::MULTIPLE_TYPES
146
- rescue
147
- {}
148
- end
144
+ self.class::MULTIPLE_TYPES
145
+ rescue StandardError
146
+ {}
147
+ end
149
148
  multiple_types.each do |prefix, suffixes|
150
149
  present = []
151
150
  suffixes.each do |suffix|
152
- typename = "#{prefix}#{suffix[0].upcase}#{suffix[1..-1]}"
151
+ typename = "#{prefix}#{suffix[0].upcase}#{suffix[1..]}"
153
152
  # check which multiple data types are actually present, not just errors
154
153
  # actually, this might be allowed depending on cardinality
155
154
  value = instance_variable_get("@#{typename}")
@@ -158,8 +157,9 @@ module FHIR
158
157
  errors[prefix] = ["#{prefix}[x]: more than one type present."] if present.length > 1
159
158
  # remove errors for suffixes that are not present
160
159
  next unless present.length == 1
160
+
161
161
  suffixes.each do |suffix|
162
- typename = "#{prefix}#{suffix[0].upcase}#{suffix[1..-1]}"
162
+ typename = "#{prefix}#{suffix[0].upcase}#{suffix[1..]}"
163
163
  errors.delete(typename) unless present.include?(typename)
164
164
  end
165
165
  end
@@ -222,10 +222,12 @@ module FHIR
222
222
  # check binding
223
223
  next unless meta['binding']
224
224
  next unless meta['binding']['strength'] == 'required'
225
+
225
226
  the_codes = [v]
226
- if meta['type'] == 'Coding'
227
+ case meta['type']
228
+ when 'Coding'
227
229
  the_codes = [v.code]
228
- elsif meta['type'] == 'CodeableConcept'
230
+ when 'CodeableConcept'
229
231
  the_codes = v.coding.map(&:code).compact
230
232
  end
231
233
  has_valid_code = false
@@ -248,6 +250,7 @@ module FHIR
248
250
  def validate_reference_type(ref, meta, contained_here, errors)
249
251
  return unless ref.reference && meta['type_profiles']
250
252
  return if ref.reference.start_with?('urn:uuid:', 'urn:oid:')
253
+
251
254
  matches_one_profile = false
252
255
  meta['type_profiles'].each do |p|
253
256
  basetype = p.split('/').last
@@ -259,7 +262,7 @@ module FHIR
259
262
  matches_one_profile = true if meta['type_profiles'].include?('http://hl7.org/fhir/StructureDefinition/Resource')
260
263
  if !matches_one_profile && ref.reference.start_with?('#')
261
264
  # we need to look at the local contained resources
262
- r = contained_here.find { |x| x.id == ref.reference[1..-1] }
265
+ r = contained_here.find { |x| x.id == ref.reference[1..] }
263
266
  if !r.nil?
264
267
  meta['type_profiles'].each do |p|
265
268
  p = p.split('/').last
@@ -280,12 +283,13 @@ module FHIR
280
283
 
281
284
  def check_binding_uri(uri, value)
282
285
  valid = false
283
- if uri == 'http://hl7.org/fhir/ValueSet/content-type' || uri == 'http://www.rfc-editor.org/bcp/bcp13.txt'
286
+ case uri
287
+ when 'http://hl7.org/fhir/ValueSet/content-type', 'http://www.rfc-editor.org/bcp/bcp13.txt'
284
288
  matches = MIME::Types[value]
285
289
  json_or_xml = value.downcase.include?('xml') || value.downcase.include?('json')
286
290
  known_weird = ['text/cql', 'application/cql+text'].include?(value)
287
291
  valid = json_or_xml || known_weird || (!matches.nil? && !matches.empty?)
288
- elsif uri == 'http://hl7.org/fhir/ValueSet/languages' || uri == 'http://tools.ietf.org/html/bcp47'
292
+ when 'http://hl7.org/fhir/ValueSet/languages', 'http://tools.ietf.org/html/bcp47'
289
293
  has_region = !(value =~ /-/).nil?
290
294
  valid = !BCP47::Language.identify(value.downcase).nil? && (!has_region || !BCP47::Region.identify(value.upcase).nil?)
291
295
  else
@@ -315,7 +319,15 @@ module FHIR
315
319
  self
316
320
  end
317
321
 
318
- private :validate_reference_type, :check_binding_uri, :validate_field
322
+ def find_extension(extension_source, method_name)
323
+ extension_source.select do |extension|
324
+ name = extension.url.tr('-', '_').split('/').last
325
+ anchor = name.split('#').last
326
+ (method_name.to_s == name || method_name.to_s == anchor)
327
+ end
328
+ end
329
+
330
+ private :validate_reference_type, :check_binding_uri, :validate_field, :find_extension
319
331
  end
320
332
  end
321
333
  end
@@ -12,16 +12,17 @@ module FHIR
12
12
 
13
13
  # Remove entries that do not interest us: CompartmentDefinitions, OperationDefinitions, Conformance statements
14
14
  hash['entry'].select! do |entry|
15
- %w[StructureDefinition ValueSet CodeSystem SearchParameter].include? entry['resource']['resourceType']
15
+ ['StructureDefinition', 'ValueSet', 'CodeSystem', 'SearchParameter'].include? entry['resource']['resourceType']
16
16
  end
17
17
 
18
18
  # Remove unnecessary elements from the hash
19
19
  hash['entry'].each do |entry|
20
20
  next unless entry['resource']
21
- pre_process_structuredefinition(entry['resource']) if 'StructureDefinition' == entry['resource']['resourceType']
22
- pre_process_valueset(entry['resource']) if 'ValueSet' == entry['resource']['resourceType']
23
- pre_process_codesystem(entry['resource']) if 'CodeSystem' == entry['resource']['resourceType']
24
- pre_process_searchparam(entry['resource']) if 'SearchParameter' == entry['resource']['resourceType']
21
+
22
+ pre_process_structuredefinition(entry['resource']) if entry['resource']['resourceType'] == 'StructureDefinition'
23
+ pre_process_valueset(entry['resource']) if entry['resource']['resourceType'] == 'ValueSet'
24
+ pre_process_codesystem(entry['resource']) if entry['resource']['resourceType'] == 'CodeSystem'
25
+ pre_process_searchparam(entry['resource']) if entry['resource']['resourceType'] == 'SearchParameter'
25
26
  remove_fhir_comments(entry['resource'])
26
27
  end
27
28
 
@@ -35,26 +36,30 @@ module FHIR
35
36
 
36
37
  def self.pre_process_structuredefinition(hash)
37
38
  # Remove large HTML narratives and unused content
38
- %w[text publisher contact description requirements mapping].each { |key| hash.delete(key) }
39
+ ['text', 'publisher', 'contact', 'description', 'requirements', 'mapping'].each { |key| hash.delete(key) }
39
40
 
40
41
  # Remove unused descriptions within the snapshot and differential elements
41
- %w[snapshot differential].each do |key|
42
+ ['snapshot', 'differential'].each do |key|
42
43
  next unless hash[key]
44
+
43
45
  hash[key]['element'].each do |element|
44
- %w[short definition comments requirements alias mapping].each { |subkey| element.delete(subkey) }
46
+ ['short', 'definition', 'comments', 'requirements', 'alias', 'mapping'].each { |subkey| element.delete(subkey) }
45
47
  end
46
48
  end
47
49
  end
48
50
 
49
51
  def self.pre_process_valueset(hash)
50
52
  # Remove large HTML narratives and unused content
51
- %w[meta text publisher contact description requirements].each { |key| hash.delete(key) }
53
+ ['meta', 'text', 'publisher', 'contact', 'description', 'requirements'].each { |key| hash.delete(key) }
52
54
 
53
55
  return unless hash['compose']
54
- %w[include exclude].each do |key|
56
+
57
+ ['include', 'exclude'].each do |key|
55
58
  next unless hash['compose'][key]
59
+
56
60
  hash['compose'][key].each do |element|
57
61
  next unless element['concept']
62
+
58
63
  element['concept'].each do |concept|
59
64
  concept.delete('designation')
60
65
  end
@@ -64,16 +69,18 @@ module FHIR
64
69
 
65
70
  def self.pre_process_codesystem(hash)
66
71
  # Remove large HTML narratives and unused content
67
- %w[meta text publisher contact description requirements].each { |key| hash.delete(key) }
72
+ ['meta', 'text', 'publisher', 'contact', 'description', 'requirements'].each { |key| hash.delete(key) }
68
73
  return unless hash['concept']
74
+
69
75
  hash['concept'].each do |concept|
70
76
  pre_process_codesystem_concept(concept)
71
77
  end
72
78
  end
73
79
 
74
80
  def self.pre_process_codesystem_concept(hash)
75
- %w[extension definition designation].each { |key| hash.delete(key) }
81
+ ['extension', 'definition', 'designation'].each { |key| hash.delete(key) }
76
82
  return unless hash['concept']
83
+
77
84
  hash['concept'].each do |concept|
78
85
  pre_process_codesystem_concept(concept)
79
86
  end
@@ -81,15 +88,16 @@ module FHIR
81
88
 
82
89
  def self.pre_process_searchparam(hash)
83
90
  # Remove large HTML narratives and unused content
84
- %w[id url name date publisher contact description xpathUsage].each { |key| hash.delete(key) }
91
+ ['id', 'url', 'name', 'date', 'publisher', 'contact', 'description', 'xpathUsage'].each { |key| hash.delete(key) }
85
92
  end
86
93
 
87
94
  def self.remove_fhir_comments(hash)
88
95
  hash.delete('fhir_comments')
89
96
  hash.each do |_key, value|
90
- if value.is_a?(Hash)
97
+ case value
98
+ when Hash
91
99
  remove_fhir_comments(value)
92
- elsif value.is_a?(Array)
100
+ when Array
93
101
  value.each do |v|
94
102
  remove_fhir_comments(v) if v.is_a?(Hash)
95
103
  end
@@ -25,7 +25,7 @@ module FHIR
25
25
  # if hash contains resourceType
26
26
  # create a child node with the name==resourceType
27
27
  # fill that, and place the child under the above `node`
28
- if hash['resourceType'] && hash['resourceType'].is_a?(String)
28
+ if hash['resourceType'].is_a?(String)
29
29
  child_name = hash['resourceType']
30
30
  hash.delete('resourceType')
31
31
  child = hash_to_xml_node(child_name, hash, doc)
@@ -34,11 +34,13 @@ module FHIR
34
34
  end
35
35
 
36
36
  hash.each do |key, value|
37
- next if %w[extension modifierExtension].include?(name) && key == 'url'
37
+ next if ['extension', 'modifierExtension'].include?(name) && key == 'url'
38
38
  next if key == 'id' && !FHIR::STU3::RESOURCES.include?(name)
39
- if value.is_a?(Hash)
39
+
40
+ case value
41
+ when Hash
40
42
  node.add_child(hash_to_xml_node(key, value, doc))
41
- elsif value.is_a?(Array)
43
+ when Array
42
44
  value.each do |v|
43
45
  if v.is_a?(Hash)
44
46
  node.add_child(hash_to_xml_node(key, v, doc))
@@ -63,7 +65,7 @@ module FHIR
63
65
  node.add_child(child)
64
66
  end
65
67
  end
66
- node.set_attribute('url', hash['url']) if %w[extension modifierExtension].include?(name)
68
+ node.set_attribute('url', hash['url']) if ['extension', 'modifierExtension'].include?(name)
67
69
  node.set_attribute('id', hash['id']) if hash['id'] && !FHIR::STU3::RESOURCES.include?(name)
68
70
  node
69
71
  end
@@ -79,7 +81,7 @@ module FHIR
79
81
  resource_type = doc.root.name
80
82
  klass = Module.const_get("FHIR::STU3::#{resource_type}")
81
83
  resource = klass.new(hash)
82
- rescue => e
84
+ rescue StandardError => e
83
85
  FHIR::STU3.logger.error("Failed to deserialize XML:\n#{e.backtrace}")
84
86
  FHIR::STU3.logger.debug("XML:\n#{xml}")
85
87
  resource = nil
@@ -109,7 +111,7 @@ module FHIR
109
111
  end
110
112
  end
111
113
  end
112
- hash['url'] = node.get_attribute('url') if %w[extension modifierExtension].include?(node.name)
114
+ hash['url'] = node.get_attribute('url') if ['extension', 'modifierExtension'].include?(node.name)
113
115
  hash['id'] = node.get_attribute('id') if node.get_attribute('id') # Testscript fixture ids (applies to any BackboneElement)
114
116
  hash['resourceType'] = node.name if FHIR::STU3::RESOURCES.include?(node.name)
115
117
 
@@ -11,6 +11,7 @@ module FHIR
11
11
  end
12
12
  end
13
13
  return unless methods.include? new_method
14
+
14
15
  (class << self; self; end).instance_eval do
15
16
  define_method(old_method) do |*args, &block|
16
17
  message = "DEPRECATED: `#{old_method}` has been deprecated. Use `#{new_method}` instead. Called from #{caller.first}"
@@ -1,5 +1,6 @@
1
1
  require 'nokogiri'
2
2
  require 'logger'
3
+ require 'uri'
3
4
 
4
5
  module FHIR
5
6
  module STU3
@@ -12,7 +13,7 @@ module FHIR
12
13
  end
13
14
 
14
15
  def self.default_logger
15
- @default_logger ||= Logger.new(ENV['FHIR_LOGGER'] || STDOUT)
16
+ @default_logger ||= Logger.new(ENV['FHIR_LOGGER'] || $stdout)
16
17
  end
17
18
 
18
19
  def self.from_contents(contents)
@@ -35,11 +36,11 @@ module FHIR
35
36
  when 'string', 'markdown'
36
37
  value.is_a?(String)
37
38
  when 'decimal'
38
- !(value.to_s =~ /\A([-+]?([0]|([1-9][0-9]*))(\.[0-9]+)?)\Z/).nil?
39
+ !(value.to_s =~ /\A([-+]?(0|([1-9][0-9]*))(\.[0-9]+)?)\Z/).nil?
39
40
  when 'uri'
40
41
  begin
41
42
  !URI.parse(value).nil?
42
- rescue
43
+ rescue StandardError
43
44
  false
44
45
  end
45
46
  when 'base64binary'
@@ -48,7 +49,7 @@ module FHIR
48
49
  # whitespace is not significant so we strip it out before doing the regex so that we can be sure that
49
50
  # the number of characters is a multiple of 4.
50
51
  # https://tools.ietf.org/html/rfc4648
51
- !(value.to_s.gsub(/\s/, '') =~ %r{\A(|[0-9a-zA-Z\+=/]{4}+)\Z}).nil?
52
+ !(value.to_s.gsub(/\s/, '') =~ %r{\A(|[0-9a-zA-Z+=/]{4}+)\Z}).nil?
52
53
  when 'instant'
53
54
  formatted_value = value.respond_to?(:xmlschema) ? value.xmlschema : value.to_s
54
55
  !(formatted_value =~ /\A([0-9]{4}(-(0[1-9]|1[0-2])(-(0[0-9]|[1-2][0-9]|3[0-1])(T([01][0-9]|2[0-3]):[0-5][0-9]:[0-5][0-9](\.[0-9]+)?(Z|(\+|-)((0[0-9]|1[0-3]):[0-5][0-9]|14:00))))))\Z/).nil?
@@ -63,16 +64,16 @@ module FHIR
63
64
  when 'time'
64
65
  !(value.to_s =~ /\A(([01][0-9]|2[0-3]):[0-5][0-9]:[0-5][0-9](\.[0-9]+)?)\Z/).nil?
65
66
  when 'code'
66
- !(value.to_s =~ /\A[^\s]+([\s]?[^\s]+)*\Z/).nil?
67
+ !(value.to_s =~ /\A[^\s]+(\s?[^\s]+)*\Z/).nil?
67
68
  when 'oid'
68
69
  !(value.to_s =~ /\Aurn:oid:[0-2](\.[1-9]\d*)+\Z/).nil?
69
70
  when 'id'
70
- !(value.to_s =~ /\A[A-Za-z0-9\-\.]{1,64}\Z/).nil?
71
+ !(value.to_s =~ /\A[A-Za-z0-9\-.]{1,64}\Z/).nil?
71
72
  when 'xhtml'
72
73
  fragment = Nokogiri::HTML::DocumentFragment.parse(value)
73
74
  value.is_a?(String) && fragment.errors.size.zero?
74
75
  when 'unsignedint'
75
- !(value.to_s =~ /\A([0]|([1-9][0-9]*))\Z/).nil?
76
+ !(value.to_s =~ /\A(0|([1-9][0-9]*))\Z/).nil?
76
77
  when 'positiveint'
77
78
  !(value.to_s =~ /\A+?[1-9][0-9]*\Z/).nil?
78
79
  else
@@ -26,6 +26,7 @@ module FHIR
26
26
  def keep_children(whitelist = [])
27
27
  @marked_for_keeping = true if whitelist.include?(path)
28
28
  return unless @children
29
+
29
30
  @children.each do |child|
30
31
  child.keep_children(whitelist)
31
32
  end
@@ -33,14 +34,16 @@ module FHIR
33
34
 
34
35
  def sweep_children
35
36
  return unless @children
37
+
36
38
  @children.each(&:sweep_children)
37
- @children = @children.keep_if(&:marked_for_keeping)
39
+ @children.keep_if(&:marked_for_keeping)
38
40
  @marked_for_keeping = !@children.empty? || @marked_for_keeping
39
41
  end
40
42
 
41
43
  def print_children(spaces = 0)
42
44
  puts "#{' ' * spaces}+#{local_name || path}"
43
45
  return nil unless @children
46
+
44
47
  @children.each do |child|
45
48
  child.print_children(spaces + 2)
46
49
  end
@@ -60,7 +60,7 @@ module FHIR
60
60
  if json.is_a? String
61
61
  begin
62
62
  json = JSON.parse(json)
63
- rescue => e
63
+ rescue StandardError => e
64
64
  @errors << "Failed to parse JSON: #{e.message} %n #{h} %n #{e.backtrace.join("\n")}"
65
65
  return false
66
66
  end
@@ -100,13 +100,15 @@ module FHIR
100
100
  def get_json_nodes(json, path)
101
101
  results = []
102
102
  return [json] if path.nil?
103
+
103
104
  steps = path.split('.')
104
105
  steps.each.with_index do |step, index|
105
- if json.is_a? Hash
106
+ case json
107
+ when Hash
106
108
  json = json[step]
107
- elsif json.is_a? Array
109
+ when Array
108
110
  json.each do |e|
109
- results << get_json_nodes(e, steps[index..-1].join('.'))
111
+ results << get_json_nodes(e, steps[index..].join('.'))
110
112
  end
111
113
  return results.flatten!
112
114
  else
@@ -126,7 +128,7 @@ module FHIR
126
128
 
127
129
  def verify_element(element, json)
128
130
  path = element.local_name || element.path
129
- path = path[(@hierarchy.path.size + 1)..-1] if path.start_with? @hierarchy.path
131
+ path = path[(@hierarchy.path.size + 1)..] if path.start_with? @hierarchy.path
130
132
 
131
133
  if element.type && !element.type.empty?
132
134
  data_type_found = element.type.first.code
@@ -158,10 +160,11 @@ module FHIR
158
160
  verify_cardinality(element, nodes)
159
161
 
160
162
  return if nodes.empty?
163
+
161
164
  # Check the datatype for each node, only if the element has one declared, and it isn't the root element
162
165
  if !element.type.empty? && element.path != id
163
166
  # element.type not being empty implies data_type_found != nil, for valid profiles
164
- codeable_concept_pattern = element.pattern && element.pattern.is_a?(FHIR::STU3::CodeableConcept)
167
+ codeable_concept_pattern = element.pattern&.is_a?(FHIR::STU3::CodeableConcept)
165
168
  codeable_concept_binding = element.binding
166
169
  matching_pattern = false
167
170
  nodes.each do |value|
@@ -201,19 +204,20 @@ module FHIR
201
204
  end
202
205
  elsif data_type_found == 'CodeableConcept' && codeable_concept_binding
203
206
  binding_issues =
204
- if element.binding.strength == 'extensible'
207
+ case element.binding.strength
208
+ when 'extensible'
205
209
  @warnings
206
- elsif element.binding.strength == 'required'
210
+ when 'required'
207
211
  @errors
208
212
  else # e.g., example-strength or unspecified
209
213
  [] # Drop issues errors on the floor, in throwaway array
210
214
  end
211
215
 
212
- valueset_uri = element.binding && element.binding.valueSetReference && element.binding.valueSetReference.reference
216
+ valueset_uri = element.binding&.valueSetReference && element.binding.valueSetReference.reference
213
217
  vcc = FHIR::STU3::CodeableConcept.new(value)
214
218
  if valueset_uri && self.class.vs_validators[valueset_uri]
215
219
  check_fn = self.class.vs_validators[valueset_uri]
216
- has_valid_code = vcc.coding && vcc.coding.any? { |c| check_fn.call(c) }
220
+ has_valid_code = vcc.coding&.any? { |c| check_fn.call(c) }
217
221
  unless has_valid_code
218
222
  binding_issues << "#{describe_element(element)} has no codings from #{valueset_uri}. Codings evaluated: #{vcc.to_json}"
219
223
  end
@@ -262,13 +266,14 @@ module FHIR
262
266
  # elsewhere. There is no good way to determine "where" you should evaluate the expression.
263
267
  element.constraint.each do |constraint|
264
268
  next unless constraint.expression && !nodes.empty?
269
+
265
270
  nodes.each do |node|
266
271
  result = FluentPath::STU3.evaluate(constraint.expression, node)
267
272
  if !result && constraint.severity == 'error'
268
273
  @errors << "#{describe_element(element)}: FluentPath expression evaluates to false for #{name} invariant rule #{constraint.key}: #{constraint.human}"
269
274
  @errors << node.to_s
270
275
  end
271
- rescue
276
+ rescue StandardError
272
277
  @warnings << "#{describe_element(element)}: unable to evaluate FluentPath expression against JSON for #{name} invariant rule #{constraint.key}: #{constraint.human}"
273
278
  @warnings << node.to_s
274
279
  end
@@ -276,6 +281,7 @@ module FHIR
276
281
 
277
282
  # check children if the element has any
278
283
  return unless element.children
284
+
279
285
  nodes.each do |node|
280
286
  element.children.each do |child|
281
287
  verify_element(child, node)
@@ -310,7 +316,7 @@ module FHIR
310
316
  @errors += definition.errors
311
317
  @warnings += definition.warnings
312
318
  end
313
- rescue
319
+ rescue StandardError
314
320
  @errors << "Unable to verify #{data_type_code} as a FHIR Resource."
315
321
  end
316
322
  return ret_val
@@ -334,7 +340,7 @@ module FHIR
334
340
  @errors += definition.errors
335
341
  @warnings += definition.warnings
336
342
  end
337
- rescue
343
+ rescue StandardError
338
344
  @errors << "Unable to verify #{resource_type} as a FHIR Resource."
339
345
  end
340
346
  ret_val
@@ -360,7 +366,7 @@ module FHIR
360
366
  @errors += definition.errors
361
367
  @warnings += definition.warnings
362
368
  end
363
- rescue
369
+ rescue StandardError
364
370
  @errors << "Unable to verify #{data_type_code} as a FHIR type."
365
371
  end
366
372
  ret_val
@@ -378,13 +384,13 @@ module FHIR
378
384
 
379
385
  matching_type = 0
380
386
 
381
- if vs_uri == 'http://hl7.org/fhir/ValueSet/content-type' || vs_uri == 'http://www.rfc-editor.org/bcp/bcp13.txt'
387
+ if ['http://hl7.org/fhir/ValueSet/content-type', 'http://www.rfc-editor.org/bcp/bcp13.txt'].include?(vs_uri)
382
388
  matches = MIME::Types[value]
383
389
  if (matches.nil? || matches.size.zero?) && !some_type_of_xml_or_json?(value)
384
390
  @errors << "#{element.path} has invalid mime-type: '#{value}'"
385
391
  matching_type -= 1 if element.binding.strength == 'required'
386
392
  end
387
- elsif vs_uri == 'http://hl7.org/fhir/ValueSet/languages' || vs_uri == 'http://tools.ietf.org/html/bcp47'
393
+ elsif ['http://hl7.org/fhir/ValueSet/languages', 'http://tools.ietf.org/html/bcp47'].include?(vs_uri)
388
394
  has_region = !(value =~ /-/).nil?
389
395
  valid = !BCP47::Language.identify(value.downcase).nil? && (!has_region || !BCP47::Region.identify(value.upcase).nil?)
390
396
  unless valid
@@ -417,9 +423,10 @@ module FHIR
417
423
 
418
424
  def some_type_of_xml_or_json?(code)
419
425
  m = code.downcase
420
- return true if m == 'xml' || m == 'json'
426
+ return true if ['xml', 'json'].include?(m)
421
427
  return true if m.start_with?('application/', 'text/') && m.end_with?('json', 'xml')
422
428
  return true if m.start_with?('application/xml', 'text/xml', 'application/json', 'text/json')
429
+
423
430
  false
424
431
  end
425
432
  deprecate :is_some_type_of_xml_or_json, :some_type_of_xml_or_json?