class TemplateGenerator
Constants
- COMP
use xml tags as symbols for name of collections
- COMPONENT
- DATAVALUES
xml tags used in MWB schemas
- SUB
- SUBCOMPONENT
- USAGES_OPT
- USAGES_REQ
list of usages to be picked up, other ignored @@USAGES = ['R','RE']
Public Class Methods
new(tempalte_path, pp)
click to toggle source
initialise template generator with the path to template xml (MWB) and parcers
# File lib/ez7gen/service/template_generator.rb, line 25 def initialize(tempalte_path, pp) # parse template TODO: refactor if not needed on class level move to 'build_template_metadata' text = File.path(tempalte_path) @xml = Ox.parse(IO.read(text)) #If there are multiple profile parsers, instantiate a generators for each @fieldGenerators = {} # helper parser for lookup in the other schema # when generating segments for custom (not base) ex VAZ2.4 the field generator will have to look in both schemas # to resolve types and coded tables value. # we will assign the other schema parser as a helper parser pp.each{|profileName, parser| helper_parser = pp.select{|key, value| key != profileName } helper_parser = (helper_parser.empty?) ? nil: helper_parser.values.first # a = TypeAwareFieldGenerator.new( parser, helper_parser) #@fieldGenerators[profileName] = a @fieldGenerators[profileName] = TypeAwareFieldGenerator.new( parser, helper_parser) } end
Public Instance Methods
build_metadata(useExVal)
click to toggle source
using MWB profiles build collection of message metadata, to use for building a message
# File lib/ez7gen/service/template_generator.rb, line 131 def build_metadata(useExVal) meta = {} segments = [] # list of segments # In the event of Subgroups of Segments defined in the template, find them and allow # groups only once for simplicity. if( @xml.HL7v2xConformanceProfile.HL7v2xStaticDef.locate('SegGroup')) then nodes = @xml.HL7v2xConformanceProfile.HL7v2xStaticDef.nodes nodes.each{|node| if (node.value == "Segment") then segments << node elsif (node.value == "SegGroup")then segments << node.locate('Segment') end } segments.flatten! else segments = @xml.HL7v2xConformanceProfile.HL7v2xStaticDef.locate('Segment') end segments.each{|seg| fields = [] seg.locate('Field').each_with_index { |f,idx | # if (@@USAGES.include?(f.Usage)) if use?(f.Usage) f.attributes.merge!(:Pos => idx) fields << get_metadata(f,useExVal) end } meta[seg.attributes[:Name]] = fields } return meta end
build_partial_field_data(item)
click to toggle source
convert
# File lib/ez7gen/service/template_generator.rb, line 113 def build_partial_field_data(item) # use the Example Value 'ExValue' defined in the xml file instead if(item[:ExValue]) then return item[:ExValue] end # convert attributes from MWB into Ensemble and use the attrs = {} # strip leading zeros from table name, MWB format. if (item[:Table]) then attrs[:codetable]= item[:Table].sub(/^0+/, '') end if (item[:Length]) then attrs[:max_length]= item[:Length] end if (item[:Name]) then attrs[:description] = item[:Name] end if (item[:Datatype]) then attrs[:datatype] = item[:Datatype] end # return genereated field # use primary field generator, as templates only work for custom schema. @fieldGenerators[PRIMARY].method(attrs[:datatype]).call(attrs, true) end
generate(message, useExVal)
click to toggle source
build hl7 message using template as guideline def generate(message, template, parsers, isGroup=false)
# File lib/ez7gen/service/template_generator.rb, line 50 def generate(message, useExVal) # read MWB xml file into collection of metadata for each segment metadata = build_metadata(useExVal) # segment names segments = metadata.keys # add each segment to message using template metadata segments.each{|segName| meta = metadata[segName] processed = process_partials(meta) message << generate_segment(segName, processed) } return message end
generate_segment(segmentName, attributes, idx=nil)
click to toggle source
generate a segment using Ensemble schema
# File lib/ez7gen/service/template_generator.rb, line 68 def generate_segment(segmentName, attributes, idx=nil) # elements = generate_segment_elements(segmentName, attributes) attributes.unshift(get_name_without_base(segmentName)) # elements = generate_segment_elements(segmentName, attributes) # overrite ids for sequential repeating segments # elements[@@SET_ID_PIECE] = handle_set_id(segmentName, attributes, idx) || elements[@@SET_ID_PIECE] #generate segment using elements if(segmentName == 'MSH') attributes.slice!(1) # one = two.first + two.last # attributes.insert(1,one) end return HL7::Message::Segment::Default.new(attributes) end
get_metadata(partial, useExVal)
click to toggle source
parse template xml file into collection
# File lib/ez7gen/service/template_generator.rb, line 171 def get_metadata(partial, useExVal) element = partial.locate(COMPONENT) # first look for DataValues example if it's there use it and stop looking any farther. if(useExVal && (element.empty?) && !partial.locate(DATAVALUES).empty?) exVal = partial.locate(DATAVALUES).first.attributes partial.attributes.merge!(exVal) return partial.attributes end # continue looking for subcomponents element = (element.empty?) ? partial.locate(SUBCOMPONENT) : element if(!element.empty?) sub = [] element.each_with_index { |el, idx| if (use?(el[:Usage])) # required or optional el.attributes.merge!(:Pos => idx) sub << get_metadata(el, useExVal) end } if(!sub.empty?) subElementName = (element.first.value.downcase).intern # subcomponent or component partial.attributes[subElementName] = sub end end return partial.attributes end
process_partials(item)
click to toggle source
working with template hash brake field metadata to components and then to subcomponents
# File lib/ez7gen/service/template_generator.rb, line 85 def process_partials(item) partials = [] # process each sub type if(item.kind_of? Array) item.each{|subType| # at this level we have components or subcomponents coll = subType[SUB] || subType # if subcomponents found process again unit = process_partials(coll) flag = (subType[SUB]) ? @@SUB : @@HAT partials[subType[:Pos].to_i] = unit.join(flag) } else # check for components first and then subcomponents coll = item[COMP] || item[SUB] if(coll) partials << process_partials(coll) else partials << build_partial_field_data(item) end end return partials end
use?(usage)
click to toggle source
# File lib/ez7gen/service/template_generator.rb, line 207 def use?(usage) # check for required field/compnent/subcomponent: R # if not toss a coin for optional (required or empty): RE (required or empty) return (USAGES_REQ.include?(usage)) ? true : (USAGES_OPT.include?(usage) && [true,false].sample) end