Class: Atom::Element

Inherits:
Hash
  • Object
show all
Defined in:
lib/atom/element.rb,
lib/atom/yaml.rb

Overview

The Class’ methods provide a DSL for describing Atom’s structure

(and more generally for describing simple namespaced XML)

Direct Known Subclasses

AttrEl, Author, Contributor, Entry, Feed, Service, Text, Workspace

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(name = nil) ⇒ Element

internal junk you probably don’t care about



134
135
136
137
138
139
140
141
142
143
144
# File 'lib/atom/element.rb', line 134

def initialize name = nil # :nodoc:
  @extensions = REXML::Element.new("extensions")
  @local_name = name

  self.class.elements.each do |name,kind,req|
    if kind.respond_to? :single?
      a = kind.new
      set(name, kind.new)
    end
  end
end

Instance Attribute Details

#baseObject

this element’s xml:base



58
59
60
# File 'lib/atom/element.rb', line 58

def base
  @base
end

#extensionsObject (readonly)

a REXML::Element that shares this element’s extension attributes and child elements



55
56
57
# File 'lib/atom/element.rb', line 55

def extensions
  @extensions
end

Class Method Details

.attrb(name, req = false) ⇒ Object

define an attribute



98
99
100
101
102
# File 'lib/atom/element.rb', line 98

def self.attrb(name, req = false) # :nodoc:
  @attrs ||= []

  @attrs << [name, req]
end

.attrsObject

this element’s attributes



61
62
63
# File 'lib/atom/element.rb', line 61

def self.attrs # :nodoc:
  @attrs || []
end

.define_accessor(name, kind) ⇒ Object

a little bit of magic



105
106
107
108
109
110
111
112
113
114
115
116
117
# File 'lib/atom/element.rb', line 105

def self.define_accessor(name,kind) # :nodoc:
  define_method "#{name}=".to_sym do |value|
    return unless value
    
    i = if kind.ancestors.member? Atom::Element
      kind.new(value, name.to_s)
    else
      kind.new(value)
    end
   
    set(name, i)
  end
end

.element(name, kind, req = false) ⇒ Object

define a child element



86
87
88
89
90
91
92
93
94
95
# File 'lib/atom/element.rb', line 86

def self.element(name, kind, req = false) # :nodoc:
  attr_reader name

  @elements ||= []
  @elements << [name, kind, req]

  unless kind.respond_to? :single?
    self.define_accessor(name,kind)
  end
end

.elementsObject

this element’s child elements



66
67
68
# File 'lib/atom/element.rb', line 66

def self.elements # :nodoc:
  @elements || []
end

.inherited(klass) ⇒ Object

copy defined elements and attributes so inheritance works



76
77
78
79
80
81
82
83
# File 'lib/atom/element.rb', line 76

def self.inherited klass # :nodoc:
  elements.each do |name, kind, req|
    klass.element name, kind, req
  end
  attrs.each do |name, req|
    klass.attrb name, req
  end
end

.requiredObject

required child elements



71
72
73
# File 'lib/atom/element.rb', line 71

def self.required # :nodoc:
  @elements.find { |name,kind,req| req }
end

Instance Method Details

#[](key) ⇒ Object

get the value of an attribute



120
121
122
123
124
# File 'lib/atom/element.rb', line 120

def [] key
  test_key key
   
  super
end

#[]=(key, value) ⇒ Object

set the value of an attribute



127
128
129
130
131
# File 'lib/atom/element.rb', line 127

def []= key, value
  test_key key

  super
end

#local_nameObject

eg. “feed” or “entry” or “updated” or “title” or …



147
148
149
# File 'lib/atom/element.rb', line 147

def local_name # :nodoc:
  @local_name || self.class.name.split("::").last.downcase
end

#taguriObject

:nodoc:



10
11
# File 'lib/atom/yaml.rb', line 10

def taguri # :nodoc:
end

#to_elementObject

convert to a REXML::Element (with no namespace)



152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
# File 'lib/atom/element.rb', line 152

def to_element 
  elem = REXML::Element.new(local_name)

  self.class.elements.each do |name,kind,req|
    v = get(name)
    next if v.nil?

    if v.respond_to? :to_element
      e = v.to_element
      e = [ e ] unless e.is_a? Array

      e.each do |bit|
        elem << bit
      end
    else
      e = REXML::Element.new(name.to_s, elem).text = get(name)
    end
  end

  self.class.attrs.each do |name,req|
    value = self[name.to_s]
    elem.attributes[name.to_s] = value if value
  end

  self.extensions.children.each do |element|
    elem << element.dup # otherwise they get removed from @extensions
  end

  if self.base and not self.base.empty?
    elem.attributes["xml:base"] = self.base
  end

  elem
end

#to_sObject

convert to an XML string



197
198
199
# File 'lib/atom/element.rb', line 197

def to_s
  to_xml.to_s
end

#to_xmlObject

convert to a REXML::Document (properly namespaced)



188
189
190
191
192
193
194
# File 'lib/atom/element.rb', line 188

def to_xml
  doc = REXML::Document.new
  root = to_element
  root.add_namespace Atom::NS
  doc << root
  doc
end

#to_yaml(opts = {}) ⇒ Object

:nodoc:



20
21
22
23
24
25
26
27
28
# File 'lib/atom/yaml.rb', line 20

def to_yaml( opts = {} ) # :nodoc:
  YAML::quick_emit( object_id, opts ) do |out|
    out.map( taguri, to_yaml_style ) do |map|
      self.to_yaml_properties.each do |m|
        map.add( m[1..-1], instance_variable_get( m ) )
      end
    end
  end
end

#to_yaml_propertiesObject

:nodoc:



13
14
15
16
17
18
# File 'lib/atom/yaml.rb', line 13

def to_yaml_properties # :nodoc:
  self.class.elements.find_all do |n,k,r|
    v = get(n)
    v and not (v.respond_to? :empty? and v.empty?)
  end.map { |n,k,r| "@#{n}" }
end