Class: EDI::Diagram::NodeInstance

Inherits:
Object
  • Object
show all
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

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 .


404
405
406
407
408
409
410
411
# File 'lib/edi4r/diagrams.rb', line 404

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

#indexObject


434
# File 'lib/edi4r/diagrams.rb', line 434

def index;  node.index;  end

#inst_cntObject Also known as: rep

Returns the node's instance counter


415
416
417
# File 'lib/edi4r/diagrams.rb', line 415

def inst_cnt
  @coord.inst_cnt
end

#is_tnode?Boolean

true if this is a TNode (trigger node/segment)

Returns:

  • (Boolean)

456
457
458
# File 'lib/edi4r/diagrams.rb', line 456

def is_tnode?
  node.is_a? TNode
end

#levelObject

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.


439
440
441
442
443
# File 'lib/edi4r/diagrams.rb', line 439

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

#maxrepObject


433
# File 'lib/edi4r/diagrams.rb', line 433

def maxrep; node.maxrep; end

#nameObject

Delegate some getters to the underlying diagram node:

index, maxrep, name, status

431
# File 'lib/edi4r/diagrams.rb', line 431

def name;   node.name;   end

#nodeObject

Returns diagram node corresponding to this instance's co-ordinates


424
425
426
# File 'lib/edi4r/diagrams.rb', line 424

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:

  1. Search fails when trying to skip a required node

  2. Search fails if we hit the end of the diagram before a match

  3. We might need to loop through segment groups repeatedly!


473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
# File 'lib/edi4r/diagrams.rb', line 473

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
    # print "Looking for #{name} in #{self.name} @ level #{self.level}..."
    #
    # Case "match"
    #
    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_nameObject

Returns the branch name (segment group name)


447
448
449
450
451
452
453
# File 'lib/edi4r/diagrams.rb', line 447

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

#statusObject


432
# File 'lib/edi4r/diagrams.rb', line 432

def status; node.status; end