Module: Objectify::Xml::Dsl

Defined in:
lib/objectify_xml/dsl.rb

Class Method Summary collapse

Instance Method Summary collapse

Class Method Details

.extended(target) ⇒ Object



4
5
6
# File 'lib/objectify_xml/dsl.rb', line 4

def self.extended(target)
  target.init
end

Instance Method Details

#attribute(name, qualified_name = nil, collection = false) ⇒ Object

Define a simple attribute or collection of simple attributes. This method can be used if the desired attribute name is different from the xml element name by specifying a qualified name.



60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
# File 'lib/objectify_xml/dsl.rb', line 60

def attribute(name, qualified_name = nil, collection = false)
  name = name.to_s.underscore
  @qualified_attributes[qualified_name] = name if qualified_name
  @collections << (qualified_name || name).to_s if collection
  @attributes << name unless qualified_name
  module_eval %{
    def #{name}=(value)
      @attributes['#{name}'] = value
    end
    def #{name}
      @attributes['#{name}']#{ collection ? ' ||= []' : '' }
    end
  }
  name
end

#attribute_type(qualified_name) ⇒ Object

Returns the attribute type associated to an element name if any.

Searches up the defining object’s namespace to the root namespace for the definition of the constant.



142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
# File 'lib/objectify_xml/dsl.rb', line 142

def attribute_type(qualified_name)
  type = @types[qualified_name]
  if type and not type.is_a? Class
    type_name = type.to_s
    type = nil
    # Try to search the current object's namespace explicitly
    sections = self.name.split(/::/)
    while sections.length > 1
      sections.pop
      begin
        sections.push(type_name)
        type = sections.join('::').constantize
        break
      rescue
        sections.pop
      end
    end
    if type.nil?
      type = type_name.constantize rescue nil
    end
    if type.nil?
      raise "Unable to instantiate the constant '#{ type_name }'."
    end
    @types[qualified_name] = type
  end
  type
end

#attributes(*names) ⇒ Object

Define a list of simple attributes.



52
53
54
55
# File 'lib/objectify_xml/dsl.rb', line 52

def attributes(*names)
  names.each { |n| attribute n }
  @attributes + @qualified_attributes.keys
end

#collection?(qualified_name) ⇒ Boolean

Used internally to determine whether an element is represented by a collection.

Returns:

  • (Boolean)


178
179
180
# File 'lib/objectify_xml/dsl.rb', line 178

def collection?(qualified_name)
  @collections.include?(qualified_name)
end

#default_namespace(url) ⇒ Object

Specify the url of the default namespace.



124
125
126
# File 'lib/objectify_xml/dsl.rb', line 124

def default_namespace(url)
  @namespaces[''] = url
end

#find_attribute(qualified_name, namespace, name) ⇒ Object

Used internally to find the name of an attribute based on the name of the xml element.



78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
# File 'lib/objectify_xml/dsl.rb', line 78

def find_attribute(qualified_name, namespace, name)
  if qname = @qualified_attributes[qualified_name]
    return qname
  end
  names = []
  plural = collection?(qualified_name)
  if plural
    if namespace
      names << "#{ namespace }_#{ name.pluralize }"
    end
    names << name.pluralize
  end
  if namespace
    names << "#{ namespace }_#{ name }"
  end
  names << name
  names.map { |n| n.underscore }.find do |n|
    @attributes.include? n.underscore
  end
end

#find_namespace(name = '') ⇒ Object

Return the url (if any) associated with a namespace.



134
135
136
# File 'lib/objectify_xml/dsl.rb', line 134

def find_namespace(name = '')
  @namespaces[name]
end

#flatten(qualified_name) ⇒ Object

Specify that an element should be recursed into while still associating its child elements with the current object.



101
102
103
# File 'lib/objectify_xml/dsl.rb', line 101

def flatten(qualified_name)
  @flatten << qualified_name.to_s
end

#flatten?(qualified_name) ⇒ Boolean

Used internally to determine whether an element has been flattened.

Returns:

  • (Boolean)


106
107
108
# File 'lib/objectify_xml/dsl.rb', line 106

def flatten?(qualified_name)
  @flatten.include? qualified_name
end

#has_many(name, type, qualified_name) ⇒ Object

Define an attribute as a collection of typed associations. The type should be derived from either DocumentParser or ElementParser.

If the type has not yet been defined at the point that the declaration is made, a String or Symbol may be used and will be instantiated from the scope that the declaration is made in.



46
47
48
49
# File 'lib/objectify_xml/dsl.rb', line 46

def has_many(name, type, qualified_name)
  set_type(qualified_name, type)
  attribute name, qualified_name, true
end

#has_one(name, type, qualified_name) ⇒ Object

Define a typed association attribute. The type should be derived from either DocumentParser or ElementParser.

If the type has not yet been defined at the point that the declaration is made, a String or Symbol may be used and will be looked up from the scope that the declaration is made in.



35
36
37
38
# File 'lib/objectify_xml/dsl.rb', line 35

def has_one(name, type, qualified_name)
  set_type(qualified_name, type)
  attribute name, qualified_name
end

#initObject

Initializes required metadata variables when the module is included in a class or a class is inherited.



10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
# File 'lib/objectify_xml/dsl.rb', line 10

def init
  parent = ancestors[1]
  unless /^Objectify::(Xml|ElementParser|DocumentParser)$/ =~ parent.name
    @collections = parent.instance_variable_get('@collections').clone || []
    @attributes = parent.instance_variable_get('@attributes').clone || []
    @qualified_attributes = parent.instance_variable_get('@qualified_attributes').clone || {}
    @flatten = parent.instance_variable_get('@flatten').clone || []
    @namespaces = parent.instance_variable_get('@namespaces').clone || {}
    @types = parent.instance_variable_get('@types').clone || {}
  else
    @collections = []
    @attributes = []
    @qualified_attributes = {}
    @flatten = []
    @namespaces = {}
    @types = {}
  end
end

#metadataObject

Return the object’s metadata for testing and debugging purposes.



183
184
185
186
187
188
189
190
# File 'lib/objectify_xml/dsl.rb', line 183

def 
  { :attributes => @attributes, 
    :qualified_attributes => @qualified_attributes, 
    :collections => @collections, 
    :flatten => @flatten, 
    :namespaces => @namespaces, 
    :types => @types }
end

#namespace(name = nil, url = nil) ⇒ Object

Specify a namespace with its url.



129
130
131
# File 'lib/objectify_xml/dsl.rb', line 129

def namespace(name = nil, url = nil)
  @namespaces[name.to_s] = url
end

#namespace?(namespace) ⇒ Boolean

Used internally to determine whether a namespace is supported.

Returns:

  • (Boolean)


111
112
113
# File 'lib/objectify_xml/dsl.rb', line 111

def namespace?(namespace)
  @namespaces.keys.include? namespace
end

#namespaces(*namespaces) ⇒ Object

Specify a list of supported namespaces.



116
117
118
119
120
121
# File 'lib/objectify_xml/dsl.rb', line 116

def namespaces(*namespaces)
  namespaces.each do |ns|
    namespace ns
  end
  @namespaces
end

#set_type(qualified_name, type) ⇒ Object

Sets the associated type of an attribute. Generally used only internally via has_one or has_many.



172
173
174
# File 'lib/objectify_xml/dsl.rb', line 172

def set_type(qualified_name, type)
  @types[qualified_name] = type
end