Class: EDI::Diagram::NodeInstance
- Inherits:
-
Object
- Object
- EDI::Diagram::NodeInstance
- Defined in:
- lib/edi4r/diagrams.rb
Overview
NodeInstance
A given segment of a real message instance needs an instance counter in addition to its location in the diagram. This applies recursively to all segment groups in which it is embedded. This class is equipped with the additional attributes (“co-ordinates”) of node instances.
We also use this class to determine the node instance of a segment when parsing a message. This is done in a sequential manner, starting from the current instance, by following the diagram branches up to the next matching segment tag/name.
Instance Method Summary collapse
- #index ⇒ Object
-
#initialize(diag) ⇒ NodeInstance
constructor
A new NodeInstance is inititialized to a “virtual” 0th node before the first real node of the diagramm referenced by
diag
. -
#inst_cnt ⇒ Object
(also: #rep)
Returns the node’s instance counter.
-
#is_tnode? ⇒ Boolean
true
if this is a TNode (trigger node/segment). -
#level ⇒ Object
Returns this node instance’s level in the diagram.
- #maxrep ⇒ Object
-
#name ⇒ Object
Delegate some getters to the underlying diagram node: index, maxrep, name, status.
-
#node ⇒ Object
Returns diagram node corresponding to this instance’s co-ordinates.
-
#seek!(seg) ⇒ Object
Main “workhorse”: Seek for next matching segment tag/name.
-
#sg_name ⇒ Object
Returns the branch name (segment group name).
- #status ⇒ Object
Constructor Details
#initialize(diag) ⇒ NodeInstance
A new NodeInstance is inititialized to a “virtual” 0th node before the first real node of the diagramm referenced by diag
.
461 462 463 464 465 466 467 468 |
# File 'lib/edi4r/diagrams.rb', line 461 def initialize( diag ) @diag = diag # Really needed later? # Init. to first segment of top branch, e.g. "UNH" or "EDI_DC40" @coord = NodeCoords.new(diag.branch, 0, 0) @coord_stack = [] @down_flag = false end |
Instance Method Details
#index ⇒ Object
491 |
# File 'lib/edi4r/diagrams.rb', line 491 def index; node.index; end |
#inst_cnt ⇒ Object Also known as: rep
Returns the node’s instance counter
472 473 474 |
# File 'lib/edi4r/diagrams.rb', line 472 def inst_cnt @coord.inst_cnt end |
#is_tnode? ⇒ Boolean
true
if this is a TNode (trigger node/segment)
513 514 515 |
# File 'lib/edi4r/diagrams.rb', line 513 def is_tnode? node.is_a? TNode end |
#level ⇒ Object
Returns this node instance’s level in the diagram. Note that special UN/EDIFACT rules about level 0 are acknowledged: level == 0 for mandatory SNode instances of the main branch with maxrep==1.
496 497 498 499 500 |
# File 'lib/edi4r/diagrams.rb', line 496 def level depth = @coord_stack.length+1 return 0 if depth == 1 and node.maxrep == 1 and node.required? and not is_tnode? # Special Level 0 case depth # Else: Level is depth of segment group stack + 1 (1 if no SG) end |
#maxrep ⇒ Object
490 |
# File 'lib/edi4r/diagrams.rb', line 490 def maxrep; node.maxrep; end |
#name ⇒ Object
Delegate some getters to the underlying diagram node:
index, maxrep, name, status
488 |
# File 'lib/edi4r/diagrams.rb', line 488 def name; node.name; end |
#node ⇒ Object
Returns diagram node corresponding to this instance’s co-ordinates
481 482 483 |
# File 'lib/edi4r/diagrams.rb', line 481 def node @coord.branch[@coord.offset] end |
#seek!(seg) ⇒ Object
Main “workhorse”: Seek for next matching segment tag/name
Starts at current location, follows the diagram downstream while searching for next matching segment.
Returns updated location (self) when found, nil otherwise.
Notes:
-
Search fails when trying to skip a required node
-
Search fails if we hit the end of the diagram before a match
-
We might need to loop through segment groups repeatedly!
530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 |
# File 'lib/edi4r/diagrams.rb', line 530 def seek!(seg) # Segment, Regexp or String expected name = (seg.is_a? EDI::Segment) ? seg.name : seg # name = (seg.is_a? String) ? seg : seg.name begin node = self.node # warn "Looking for #{name} in #{self.name} @ level #{self.level} while node.maxrep=#{node.maxrep}..." # # Case "match" # if node.nil? warn "#{name}: #{@coord.offset} #{@coord.branch.sg_name} #{@coord.branch.desc} #{@coord.branch.size}" raise "#{self}: no node!" end if name === node.name # == name # puts "match!" @coord.inst_cnt += 1 msg = "Segment #{name} at #{@coord.to_s}: More than #{node.maxrep}!" if @coord.inst_cnt > node.maxrep raise EDI::EDILookupError, msg else @down_flag = true if node.is_a? TNode return self# .node end end # # Missed a required node? # if node.required? and @coord.inst_cnt == 0 # @unmatched msg = "Missing required segment #{node.name} at #{@coord.to_s}\n" + \ " while looking for segment #{name}!" raise EDI::EDILookupError, msg end # puts end while self.next! # Already at top level - Error condition! raise "End of diagram exceeded!" end |
#sg_name ⇒ Object
Returns the branch name (segment group name)
504 505 506 507 508 509 510 |
# File 'lib/edi4r/diagrams.rb', line 504 def sg_name # (node.is_a? TNode) ? node.sg_name : nil if node.is_a? TNode return node.sg_name end @coord.branch.sg_name end |
#status ⇒ Object
489 |
# File 'lib/edi4r/diagrams.rb', line 489 def status; node.status; end |