Class: SWS::DefinitionParser

Inherits:
Object
  • Object
show all
Includes:
Singleton
Defined in:
lib/sws/parsers.rb

Overview

Class that retrieves definition of the component from .sws and/or .api files. Parsed definitions are cached to avoid unnecessary overhead.

Instance Method Summary collapse

Constructor Details

#initializeDefinitionParser



12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
# File 'lib/sws/parsers.rb', line 12

def initialize ()
  
  # .sws file cache
  @sws_cache = Hash.new do |hash,filename|
    $log_sws_parser.debug( "Parsing .sws #{filename}" )
    hash[filename] = YAML::load( File.open( filename ) ) #sws_parse( filename )
  end

  # .api file cache
  @api_cache = Hash.new do |hash,filename|
    $log_sws_parser.debug( "Parsing .api #{filename}" )
    hash[filename] = YAML::load( File.open( filename ) )
  end

end

Instance Method Details

#component_for_token_with_parent(token, parent) ⇒ Object

Most important method of the class - returns Component object for given token in given parent component. Does it by parsing parent definition file and looking for definition of Component with given token name. When the definition is found, new Component object with proper slots and definition (again retrieved from file and parsed) is created.



34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
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
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
# File 'lib/sws/parsers.rb', line 34

def component_for_token_with_parent ( token, parent )

  
  # Element to find - component definition
  component_definition = nil
  
  # Definition is looked for in parent component recursively - up to the
  # topmost component
  next_parent = parent

  name = token.sws_name
  
  loop do 
  
    $log_sws_parser.debug( "Looking for #{name} in #{next_parent}" )
    
    # Because this is the parent (so it has children) we don't have to check
    # if the .sws file is present
    parent_definition = @sws_cache[ next_parent.definition_filename ]
    
    # Definition of component looked for in parent definition - if not
    # found, the parent's parent will be searched
    # FIXME: this will surely work incorrectly when 2 nested components have
    # subcomponents of the same name!
    component_definition = parent_definition[name]
    
    if ( component_definition != nil ) 
      break
    elsif ( next_parent.parent != nil ) 
      next_parent = next_parent.parent
    else
      raise( "Definiton for component #{name} not found!" )
    end
    
  end  

  $log_sws_parser.debug( "Definition found" )
  
  # Create Component object using component_definition hash
  class_name = component_definition[ "_class" ]
  unless( class_name )
    raise( "Cannot find _class attribute for component #{token.sws_name}" )
  end
  component = Component.create( class_name, parent.request, name.dup(), parent )
  component.definition_component = next_parent
  component.html_attrs = token.attributes
  
  slots = Hash.new
  
  if ( component.api_filename != nil )
    @api_cache[ component.api_filename ].each_pair do |slot_name, slot_attrs|

      slot = Slot.new( component, slot_name )
      slot.bind( component_definition[slot_name] )

      if ( slot_attrs )
        slot.default = slot_attrs["default"]
        slot.required = slot_attrs["required"]
        slot.settable = slot_attrs["settable"]
      end

      slots[slot_name] = slot
    end
  end
  
  component.slots = slots
  component.synchronize_slots()
  return component
  
end