Class: Archimate::FileFormats::Sax::Document

Inherits:
Nokogiri::XML::SAX::Document
  • Object
show all
Defined in:
lib/archimate/file_formats/sax/document.rb

Overview

SaxStack implements a stack like processor to maintain context during SAX processing of XML documents. It provides the means for a handler for a SAX event to raise events to handlers further up the stack and to query ancestor handlers.

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(handler_factory) ⇒ Document

Returns a new instance of Document.



16
17
18
19
20
21
# File 'lib/archimate/file_formats/sax/document.rb', line 16

def initialize(handler_factory)
  super()
  @handler_factory = handler_factory
  @stack = []
  @model = nil
end

Instance Attribute Details

#handler_factoryObject (readonly)

Returns the value of attribute handler_factory.



14
15
16
# File 'lib/archimate/file_formats/sax/document.rb', line 14

def handler_factory
  @handler_factory
end

#modelObject (readonly)

Returns the value of attribute model.



13
14
15
# File 'lib/archimate/file_formats/sax/document.rb', line 13

def model
  @model
end

Instance Method Details

#characters(string) ⇒ Object



58
59
60
# File 'lib/archimate/file_formats/sax/document.rb', line 58

def characters(string)
  current_handler.characters(string)
end

#current_handlerObject



54
55
56
# File 'lib/archimate/file_formats/sax/document.rb', line 54

def current_handler
  @stack.first
end

#end_element(_name) ⇒ Object

Handler is completed. Fires any of the handlers events and pops the handler off of the stack.

See #push regarding why #shift is used instead of #pop



50
51
52
# File 'lib/archimate/file_formats/sax/document.rb', line 50

def end_element(_name)
  fire(@stack.shift.complete)
end

#fire(events) ⇒ Object

Fire an event up the stack. Events are received at each handler until a handler returns nil or false.

Parameters:

  • events (Array<SaxEvent>)

    zero or more Events to bubble up the stack



66
67
68
69
70
71
72
73
74
75
76
# File 'lib/archimate/file_formats/sax/document.rb', line 66

def fire(events)
  Array(events).each do |event|
    if event.sym == :on_model
      @model = event.args
    else
      @stack.take_while do |target|
        target.send(event.sym, event.args, event.source)
      end
    end
  end
end

#start_element(name, attrs = []) ⇒ Object

Push a handler onto the stack.

create an instance of the correct builder for this element push it onto the @stack

Note: #unshift is used here rather than #push in the underlying implementation because I want events to flow from last-in to first-in when they are fired and this lets be use #take_while without reversing the stack array.

Parameters:

  • obj (SaxHandler)

    Handler to push on the stack



39
40
41
42
43
44
# File 'lib/archimate/file_formats/sax/document.rb', line 39

def start_element(name, attrs = [])
  cls = handler_factory.handler_for(name, attrs)
  @stack.unshift(
    cls.new(name, attrs, @stack.first)
  )
end