Class: RubyXL::OOXMLObject

Inherits:
Object
  • Object
show all
Defined in:
lib/rubyXL/objects/ooxml_object.rb

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(params = {}) ⇒ OOXMLObject

Returns a new instance of OOXMLObject.



80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
# File 'lib/rubyXL/objects/ooxml_object.rb', line 80

def initialize(params = {})
  obtain_class_variable(:@@ooxml_attributes).each_key { |k| instance_variable_set("@#{k}", params[k]) }
  obtain_class_variable(:@@ooxml_child_nodes).each_pair { |k, v|

    initial_value =
      if params.has_key?(v[:accessor]) then params[v[:accessor]]
      elsif v[:is_array] then []
      else nil
      end

    instance_variable_set("@#{v[:accessor]}", initial_value)
  }

  instance_variable_set("@count", 0) if obtain_class_variable(:@@ooxml_countable, false)
end

Class Method Details

.define_attribute(attr_name, attr_type, extra_params = {}) ⇒ Object



24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
# File 'lib/rubyXL/objects/ooxml_object.rb', line 24

def self.define_attribute(attr_name, attr_type, extra_params = {})
  attrs = obtain_class_variable(:@@ooxml_attributes)

  accessor = extra_params[:accessor] || accessorize(attr_name)

  attrs[accessor] = {
    :attr_name  => attr_name.to_s,
    :attr_type  => attr_type,
    :optional   => !extra_params[:required], 
    :default    => extra_params[:default],
    :validation => extra_params[:values]
  }

  self.send(:attr_accessor, accessor)
end

.define_child_node(klass, extra_params = {}) ⇒ Object



40
41
42
43
44
45
46
47
48
49
50
51
52
# File 'lib/rubyXL/objects/ooxml_object.rb', line 40

def self.define_child_node(klass, extra_params = {})
  child_nodes = obtain_class_variable(:@@ooxml_child_nodes)
  child_node_name = (extra_params[:node_name] || klass.class_variable_get(:@@ooxml_tag_name)).to_s
  accessor = (extra_params[:accessor] || accessorize(child_node_name)).to_sym

  child_nodes[child_node_name] = { 
    :class => klass,
    :is_array => extra_params[:collection],
    :accessor => accessor
  }

  self.send(:attr_accessor, accessor)
end

.define_element_name(v) ⇒ Object



54
55
56
# File 'lib/rubyXL/objects/ooxml_object.rb', line 54

def self.define_element_name(v)
  self.class_variable_set(:@@ooxml_tag_name, v)
end

.obtain_class_variable(var_name, default = {}) ⇒ Object

Throughout this class, setting class variables through explicit method calls rather than by directly addressing the name of the variable because of context issues: addressing variable by name creates it in the context of defining class, while calling the setter/getter method addresses it in the context of descendant class, which is what we need.



11
12
13
14
15
16
17
# File 'lib/rubyXL/objects/ooxml_object.rb', line 11

def self.obtain_class_variable(var_name, default = {})
  if class_variable_defined?(var_name) then 
    self.class_variable_get(var_name)
  else
    self.class_variable_set(var_name, default)
  end
end

.parse(node) ⇒ Object



96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
# File 'lib/rubyXL/objects/ooxml_object.rb', line 96

def self.parse(node)
  obj = self.new

  obtain_class_variable(:@@ooxml_attributes).each_pair { |k, v|

    raw_value = if v[:attr_name] == '_' then node.text
                else
                  attr = node.attributes[v[:attr_name]]
                  attr && attr.value
                end
                
    val = raw_value &&
            case v[:attr_type]
            when :int    then Integer(raw_value)
            when :float  then Float(raw_value)
            when :string then raw_value
            when :sqref  then RubyXL::Sqref.new(raw_value)
            when :ref    then RubyXL::Reference.new(raw_value)
            when :bool   then ['1', 'true'].include?(raw_value)
            end              

    obj.send("#{k}=", val)
  }

  known_child_nodes = obtain_class_variable(:@@ooxml_child_nodes)

  unless known_child_nodes.empty?
    node.element_children.each { |child_node|
      child_node_name = child_node.name
      child_node_params = known_child_nodes[child_node_name]
      raise "Unknown child node: #{child_node_name}" if child_node_params.nil?
      parsed_object = child_node_params[:class].parse(child_node)
      if child_node_params[:is_array] then obj.send(child_node_params[:accessor]) << parsed_object
      else obj.send("#{child_node_params[:accessor]}=", parsed_object)
      end
    }
  end

  obj
end

.set_countableObject



58
59
60
61
# File 'lib/rubyXL/objects/ooxml_object.rb', line 58

def self.set_countable
  self.class_variable_set(:@@ooxml_countable, true)
  self.send(:attr_accessor, :count)
end

Instance Method Details

#dupObject



137
138
139
140
141
# File 'lib/rubyXL/objects/ooxml_object.rb', line 137

def dup
  new_copy = super
  new_copy.count = 0 if obtain_class_variable(:@@ooxml_countable, false)
  new_copy
end

#write_xml(xml, node_name_override = nil) ⇒ Object



63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
# File 'lib/rubyXL/objects/ooxml_object.rb', line 63

def write_xml(xml, node_name_override = nil)
  before_write_xml if self.respond_to?(:before_write_xml)
  attrs = prepare_attributes
  element_text = attrs.delete('_')
  elem = xml.create_element(node_name_override || obtain_class_variable(:@@ooxml_tag_name), attrs, element_text)
  child_nodes = obtain_class_variable(:@@ooxml_child_nodes)
  child_nodes.each_pair { |child_node_name, child_node_params|
    obj = self.send(child_node_params[:accessor])
    unless obj.nil?
      if child_node_params[:is_array] then obj.each { |item| elem << item.write_xml(xml) }
      else elem << obj.write_xml(xml, child_node_name)
      end
    end
  }
  elem
end