Class: Inferno::Entities::IG
- Defined in:
- lib/inferno/entities/ig.rb
Overview
IG is a wrapper class around the relevant concepts inside an IG. Not everything within an IG is currently used by Inferno.
Constant Summary collapse
- ATTRIBUTES =
[ :id, :resources_by_type, :examples, :source_path ].freeze
- FILES_TO_SKIP =
These files aren't FHIR resources
['package.json', 'validation-summary.json'].freeze
Class Method Summary collapse
- .extract_package_id(ig_resource) ⇒ Object
- .from_directory(ig_directory) ⇒ Object
- .from_file(ig_path, standalone_resources_directory: nil) ⇒ IG
- .from_tgz(ig_path) ⇒ Object
- .skip_item?(relative_path, is_directory) ⇒ Boolean
Instance Method Summary collapse
- #capability_statement(mode = 'server') ⇒ Object
- #code_system_by_url(url) ⇒ Object
- #extensions ⇒ Object
- #handle_resource(resource, relative_path) ⇒ Object
- #ig_resource ⇒ Object
-
#initialize(**params) ⇒ IG
constructor
A new instance of IG.
-
#merge_standalone_resources(directory) ⇒ self
Merge in loose FHIR resource files from a directory that isn't part of the IG package itself, eg author-maintained resources (extra examples, local SearchParameter overrides, etc) that a test kit generator keeps alongside a downloaded package.
- #profile_by_url(url) ⇒ Object
- #profiles ⇒ Object
- #resource_for_profile(url) ⇒ Object
- #value_set_by_url(url) ⇒ Object
- #value_sets ⇒ Object
Methods inherited from Entity
Constructor Details
#initialize(**params) ⇒ IG
Returns a new instance of IG.
24 25 26 27 28 |
# File 'lib/inferno/entities/ig.rb', line 24 def initialize(**params) super(params, ATTRIBUTES) @resources_by_type ||= Hash.new { |hash, key| hash[key] = [] } @examples = [] end |
Class Method Details
.extract_package_id(ig_resource) ⇒ Object
168 169 170 |
# File 'lib/inferno/entities/ig.rb', line 168 def self.extract_package_id(ig_resource) "#{ig_resource.id}##{ig_resource.version || 'current'}" end |
.from_directory(ig_directory) ⇒ Object
87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 |
# File 'lib/inferno/entities/ig.rb', line 87 def self.from_directory(ig_directory) ig = IG.new ig_path = Pathname.new(ig_directory) Dir.glob("#{ig_path}/**/*") do |f| relative_path = Pathname.new(f).relative_path_from(ig_path).to_s next if skip_item?(relative_path, File.directory?(f)) begin resource = FHIR::Json.from_json(File.read(f)) next if resource.nil? ig.handle_resource(resource, relative_path) rescue StandardError next end end ig.id = extract_package_id(ig.ig_resource) ig.source_path = ig_directory ig end |
.from_file(ig_path, standalone_resources_directory: nil) ⇒ IG
37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 |
# File 'lib/inferno/entities/ig.rb', line 37 def self.from_file(ig_path, standalone_resources_directory: nil) raise "#{ig_path} does not exist" unless File.exist?(ig_path) # fhir_models by default logs the entire content of non-FHIR files # which could be things like a package.json original_logger = FHIR.logger FHIR.logger = Logger.new('/dev/null') ig = if File.directory?(ig_path) from_directory(ig_path) elsif ig_path.end_with? '.tgz' from_tgz(ig_path) else raise "Unable to load #{ig_path} as it does not appear to be a directory or a .tgz file" end ig.merge_standalone_resources(standalone_resources_directory) if standalone_resources_directory ig ensure FHIR.logger = original_logger if defined? original_logger end |
.from_tgz(ig_path) ⇒ Object
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 |
# File 'lib/inferno/entities/ig.rb', line 61 def self.from_tgz(ig_path) tar = Gem::Package::TarReader.new( Zlib::GzipReader.open(ig_path) ) ig = IG.new tar.each do |entry| next if skip_item?(entry.full_name, entry.directory?) begin resource = FHIR::Json.from_json(entry.read) next if resource.nil? ig.handle_resource(resource, entry.full_name) rescue StandardError next end end ig.id = extract_package_id(ig.ig_resource) ig.source_path = ig_path ig end |
.skip_item?(relative_path, is_directory) ⇒ Boolean
114 115 116 117 118 119 120 121 122 123 124 125 126 127 |
# File 'lib/inferno/entities/ig.rb', line 114 def self.skip_item?(relative_path, is_directory) return true if is_directory file_name = relative_path.split('/').last return true unless file_name.end_with? '.json' return true unless relative_path.start_with? 'package/' return true if file_name.start_with? '.' # ignore hidden files return true if file_name.end_with? '.openapi.json' return true if FILES_TO_SKIP.include? file_name false end |
Instance Method Details
#capability_statement(mode = 'server') ⇒ Object
184 185 186 187 188 |
# File 'lib/inferno/entities/ig.rb', line 184 def capability_statement(mode = 'server') resources_by_type['CapabilityStatement'].find do |capability_statement_resource| capability_statement_resource.rest.any? { |r| r.mode == mode } end end |
#code_system_by_url(url) ⇒ Object
206 207 208 |
# File 'lib/inferno/entities/ig.rb', line 206 def code_system_by_url(url) resources_by_type['CodeSystem'].find { |system| system.url == url } end |
#extensions ⇒ Object
180 181 182 |
# File 'lib/inferno/entities/ig.rb', line 180 def extensions resources_by_type['StructureDefinition'].filter { |sd| sd.type == 'Extension' } end |
#handle_resource(resource, relative_path) ⇒ Object
129 130 131 132 133 134 135 |
# File 'lib/inferno/entities/ig.rb', line 129 def handle_resource(resource, relative_path) if relative_path.start_with? 'package/example' examples << resource else resources_by_type[resource.resourceType] << resource end end |
#ig_resource ⇒ Object
190 191 192 |
# File 'lib/inferno/entities/ig.rb', line 190 def ig_resource resources_by_type['ImplementationGuide'].first end |
#merge_standalone_resources(directory) ⇒ self
Merge in loose FHIR resource files from a directory that isn't part of the IG package itself, eg author-maintained resources (extra examples, local SearchParameter overrides, etc) that a test kit generator keeps alongside a downloaded package. Files that aren't valid FHIR resources are skipped. Does nothing if the directory doesn't exist.
Files are classified the same way as within an IG package: those under a package/example
subdirectory are added to #examples, everything else (including files directly in
directory) is added to #resources_by_type.
148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 |
# File 'lib/inferno/entities/ig.rb', line 148 def merge_standalone_resources(directory) return self unless File.directory?(directory) base_path = Pathname.new(directory) Dir.glob(File.join(directory, '**', '*.json')).each do |file_path| relative_path = Pathname.new(file_path).relative_path_from(base_path).to_s begin resource = FHIR::Json.from_json(File.read(file_path)) next if resource.nil? rescue StandardError next end handle_resource(resource, relative_path) end self end |
#profile_by_url(url) ⇒ Object
194 195 196 |
# File 'lib/inferno/entities/ig.rb', line 194 def profile_by_url(url) profiles.find { |profile| profile.url == url } end |
#profiles ⇒ Object
176 177 178 |
# File 'lib/inferno/entities/ig.rb', line 176 def profiles resources_by_type['StructureDefinition'].filter { |sd| sd.type != 'Extension' } end |
#resource_for_profile(url) ⇒ Object
198 199 200 |
# File 'lib/inferno/entities/ig.rb', line 198 def resource_for_profile(url) profiles.find { |profile| profile.url == url }.type end |
#value_set_by_url(url) ⇒ Object
202 203 204 |
# File 'lib/inferno/entities/ig.rb', line 202 def value_set_by_url(url) resources_by_type['ValueSet'].find { |profile| profile.url == url } end |
#value_sets ⇒ Object
172 173 174 |
# File 'lib/inferno/entities/ig.rb', line 172 def value_sets resources_by_type['ValueSet'] end |