Class: OM::XML::TermBuilder::Builder

Inherits:
Object
  • Object
show all
Defined in:
lib/om/xml/term_builder.rb

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(name, terminology_builder = nil) ⇒ Builder

Returns a new instance of Builder.


16
17
18
19
20
21
# File 'lib/om/xml/term_builder.rb', line 16

def initialize(name, terminology_builder=nil)
  @name = name.to_sym
  @terminology_builder = terminology_builder
  @settings = {:required=>false, :type=>:string}
  @children = {}
end

Instance Attribute Details

#childrenObject

Returns the value of attribute children


14
15
16
# File 'lib/om/xml/term_builder.rb', line 14

def children
  @children
end

#nameObject

Returns the value of attribute name


14
15
16
# File 'lib/om/xml/term_builder.rb', line 14

def name
  @name
end

#settingsObject

Returns the value of attribute settings


14
15
16
# File 'lib/om/xml/term_builder.rb', line 14

def settings
  @settings
end

#terminology_builderObject

Returns the value of attribute terminology_builder


14
15
16
# File 'lib/om/xml/term_builder.rb', line 14

def terminology_builder
  @terminology_builder
end

Instance Method Details

#add_child(child) ⇒ Object


23
24
25
# File 'lib/om/xml/term_builder.rb', line 23

def add_child(child)
  @children[child.name] = child
end

#attributes=(val) ⇒ Object


137
138
139
# File 'lib/om/xml/term_builder.rb', line 137

def attributes= val
  @settings[:attributes] = val
end

#build(terminology = nil) ⇒ Object

Builds a new OM::XML::Term based on the Builder object's current settings If no path has been provided, uses the Builder object's name as the term's path Recursively builds any children, appending the results as children of the Term that's being built.

Parameters:


94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
# File 'lib/om/xml/term_builder.rb', line 94

def build(terminology=nil)
  self.resolve_refs!
  if settings.has_key?(:proxy)
    term = OM::XML::NamedTermProxy.new(self.name, self.settings[:proxy], terminology, self.settings)
  else
    term = OM::XML::Term.new(self.name, {}, terminology)

    self.settings.each do |name, values|
      if term.respond_to?(name.to_s+"=")
        term.instance_variable_set("@#{name}", values)
      end
    end
    @children.each_value do |child|
      term.add_child child.build(terminology)
    end
    term.generate_xpath_queries!
  end

  return term
end

#default_content_path=(val) ⇒ Object


157
158
159
# File 'lib/om/xml/term_builder.rb', line 157

def default_content_path= val
  @settings[:default_content_path] = val
end

#index_as=(val) ⇒ Object


125
126
127
# File 'lib/om/xml/term_builder.rb', line 125

def index_as= val
  @settings[:index_as] = val
end

#lookup_refs(nodes_visited = []) ⇒ Object


31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
# File 'lib/om/xml/term_builder.rb', line 31

def lookup_refs(nodes_visited=[])
  result = []
  if @settings[:ref]
    # Fail if we do not have terminology builder
    if self.terminology_builder.nil?
      raise "Cannot perform lookup_ref for the #{self.name} builder.  It doesn't have a reference to any terminology builder"
    end
    target = self.terminology_builder.retrieve_term_builder(*@settings[:ref])

    # Fail on circular references and return an intelligible error message
    if nodes_visited.include?(target)
      nodes_visited << self
      nodes_visited << target
      trail = ""
      nodes_visited.each_with_index do |node, z|
        trail << node.name.inspect
        unless z == nodes_visited.length-1
          trail << " => "
        end
      end
      raise OM::XML::Terminology::CircularReferenceError, "Circular reference in Terminology: #{trail}"
    end
    result << target
    result.concat( target.lookup_refs(nodes_visited << self) )
  end
  return result
end

#path=(val) ⇒ Object


149
150
151
# File 'lib/om/xml/term_builder.rb', line 149

def path= val
  @settings[:path] = val
end

#proxy=(val) ⇒ Object


141
142
143
# File 'lib/om/xml/term_builder.rb', line 141

def proxy= val
  @settings[:proxy] = val
end

#ref=(val) ⇒ Object


133
134
135
# File 'lib/om/xml/term_builder.rb', line 133

def ref= val
  @settings[:ref] = val
end

#required=(val) ⇒ Object


129
130
131
# File 'lib/om/xml/term_builder.rb', line 129

def required= val
  @settings[:required] = val
end

#resolve_refs!Object

If a :ref value has been set, looks up the target of that ref and merges the target's settings & children with the current builder's settings & children operates recursively, so it is possible to apply refs that in turn refer to other nodes.


61
62
63
64
65
66
67
68
69
70
71
72
73
# File 'lib/om/xml/term_builder.rb', line 61

def resolve_refs!
  name_of_last_ref = nil
  lookup_refs.each_with_index do |ref,z|
    @settings = two_layer_merge(@settings, ref.settings)
    @children.merge!(ref.children)
    name_of_last_ref = ref.name
  end
  if @settings[:path].nil? && !name_of_last_ref.nil?
    @settings[:path] = name_of_last_ref.to_s
  end
  @settings.delete :ref
  return self
end

#retrieve_child(child_name) ⇒ Object


27
28
29
# File 'lib/om/xml/term_builder.rb', line 27

def retrieve_child(child_name)
  child = @children.fetch(child_name, nil)
end

#root_term=(val) ⇒ Object


121
122
123
# File 'lib/om/xml/term_builder.rb', line 121

def root_term= val
  @settings[:is_root_term] = val
end

#two_layer_merge(downstream_hash, upstream_hash) ⇒ Object

Returns a new Hash that merges downstream_hash with upstream_hash similar to calling upstream_hash.merge(downstream_hash) only it also merges any internal values that are themselves Hashes.


78
79
80
81
82
83
84
85
86
87
88
# File 'lib/om/xml/term_builder.rb', line 78

def two_layer_merge(downstream_hash, upstream_hash)
  up = upstream_hash.dup
  dn = downstream_hash.dup
  up.each_pair do |setting_name, value|
    if value.kind_of?(Hash) && downstream_hash.has_key?(setting_name)
      dn[setting_name] = value.merge(downstream_hash[setting_name])
      up.delete(setting_name)
    end
  end
  return up.merge(dn)
end

#type(value) ⇒ Object

We have to add this method so it will play nice with ruby 1.8.7


116
117
118
119
# File 'lib/om/xml/term_builder.rb', line 116

def type value
  @settings[:type] = value
  return self
end

#type=(val) ⇒ Object


145
146
147
# File 'lib/om/xml/term_builder.rb', line 145

def type= val
  @settings[:type] = val
end

#variant_of=(val) ⇒ Object


153
154
155
# File 'lib/om/xml/term_builder.rb', line 153

def variant_of= val
  @settings[:variant_of] = val
end