Class: Blather::XMPPNode
- Inherits:
-
Nokogiri::XML::Node
- Object
- Nokogiri::XML::Node
- Blather::XMPPNode
- Defined in:
- lib/blather/xmpp_node.rb
Overview
Base XML Node All XML classes subclass XMPPNode it allows the addition of helpers
Direct Known Subclasses
Stanza, Stanza::DiscoInfo::Feature, Stanza::DiscoInfo::Identity, Stanza::DiscoItems::Item, Stanza::Iq::Roster::RosterItem, Stanza::PubSubItem
Constant Summary collapse
- BASE_NAMES =
%w[presence message iq].freeze
- @@registrations =
{}
Class Method Summary collapse
-
.attribute_accessor(*syms) ⇒ Object
Provides an attribute accessor helper combining
attribute_reader
andattribute_writer
. -
.attribute_reader(*syms) ⇒ Object
Provides an attribute reader helper.
-
.attribute_writer(*syms) ⇒ Object
Provides an attribute writer helper.
-
.class_from_registration(name, xmlns) ⇒ Object
Find the class to use given the name and namespace of a stanza.
-
.content_attr_accessor(method, conversion = nil, node = nil) ⇒ Object
Provides a quick way of building
content_attr_reader
andcontent_attr_writer
for the same method and node. -
.content_attr_reader(method, conversion = nil, node = nil) ⇒ Object
Provides a content reader helper that returns the content of a node
method
is the method to createconversion
is a method to call on the content before sending it backnode
is the name of the content node (this defaults to the method name). -
.content_attr_writer(method, node = nil) ⇒ Object
Provides a content writer helper that creates or updates the content of a node
method
is the method to createnode
is the name of the node to create (defaults to the method name). -
.import(node) ⇒ Object
Looks up the class to use then instantiates an object of that class and imports all the
node
‘s attributes and children into it. -
.new(name = nil, doc = nil) ⇒ Object
Automatically sets the namespace registered by the subclass.
-
.register(name, ns = nil) ⇒ Object
Lets a subclass register itself.
Instance Method Summary collapse
-
#content_from(name, ns = nil) ⇒ Object
Pull the content from a child.
-
#inherit(stanza) ⇒ Object
Inherit all of
stanza
‘s attributes and children. -
#inherit_attrs(attrs) ⇒ Object
Inherit only
stanza
‘s attributes. - #namespace=(namespaces) ⇒ Object
- #namespace_href ⇒ Object
- #nokogiri_namespace= ⇒ Object
-
#remove_child(name, ns = nil) ⇒ Object
Remove a child with the name and (optionally) namespace given.
-
#remove_children(name) ⇒ Object
Remove all children with a given name.
-
#set_content_for(node, content = nil) ⇒ Object
Sets the content for the specified node.
-
#to_stanza ⇒ Object
Quickway of turning itself into a proper object.
Methods inherited from Nokogiri::XML::Node
#[]=, #attr_set, #find_first, #nokogiri_xpath, #xpath
Class Method Details
.attribute_accessor(*syms) ⇒ Object
Provides an attribute accessor helper combining attribute_reader
and attribute_writer
class Node
attribute_accessor :type
attribute_accessor :name, :to_sym => false
end
n = Node.new
n.type = 'foo'
n.type == :foo
n.name = 'bar'
n.name == 'bar'
110 111 112 113 |
# File 'lib/blather/xmpp_node.rb', line 110 def self.attribute_accessor(*syms) attribute_reader *syms attribute_writer *syms end |
.attribute_reader(*syms) ⇒ Object
Provides an attribute reader helper. Default behavior is to conver the values of the attribute into a symbol. This can be turned off by passing :to_sym => false
class Node
attribute_reader :type
attribute_reader :name, :to_sym => false
end
n = Node.new
n[:type] = 'foo'
n.type == :foo
n[:name] = 'bar'
n.name == 'bar'
62 63 64 65 66 67 68 69 70 71 72 73 |
# File 'lib/blather/xmpp_node.rb', line 62 def self.attribute_reader(*syms) opts = syms.last.is_a?(Hash) ? syms.pop : {} convert_str = "val.#{opts[:call]} if val" if opts[:call] syms.flatten.each do |sym| class_eval(<<-END, __FILE__, __LINE__) def #{sym} val = self[:#{sym}] #{convert_str} end END end end |
.attribute_writer(*syms) ⇒ Object
Provides an attribute writer helper.
class Node
attribute_writer :type
end
n = Node.new
n.type = 'foo'
n[:type] == 'foo'
85 86 87 88 89 90 91 92 93 94 |
# File 'lib/blather/xmpp_node.rb', line 85 def self.attribute_writer(*syms) syms.flatten.each do |sym| next if sym.is_a?(Hash) class_eval(<<-END, __FILE__, __LINE__) def #{sym}=(value) self[:#{sym}] = value end END end end |
.class_from_registration(name, xmlns) ⇒ Object
Find the class to use given the name and namespace of a stanza
29 30 31 32 |
# File 'lib/blather/xmpp_node.rb', line 29 def self.class_from_registration(name, xmlns) name = name.to_s @@registrations[[name, xmlns]] || @@registrations[[name, nil]] end |
.content_attr_accessor(method, conversion = nil, node = nil) ⇒ Object
Provides a quick way of building content_attr_reader
and content_attr_writer
for the same method and node
169 170 171 172 |
# File 'lib/blather/xmpp_node.rb', line 169 def self.content_attr_accessor(method, conversion = nil, node = nil) content_attr_reader method, conversion, node content_attr_writer method, node end |
.content_attr_reader(method, conversion = nil, node = nil) ⇒ Object
Provides a content reader helper that returns the content of a node method
is the method to create conversion
is a method to call on the content before sending it back node
is the name of the content node (this defaults to the method name)
class Node
content_attr_reader :body
content_attr_reader :type, :to_sym
content_attr_reader :id, :to_i, :identity
end
n = Node.new 'foo'
n.to_s == "<foo><body>foobarbaz</body><type>error</type><identity>1000</identity></foo>"
n.body == 'foobarbaz'
n.type == :error
n.id == 1000
132 133 134 135 136 137 138 139 140 141 |
# File 'lib/blather/xmpp_node.rb', line 132 def self.content_attr_reader(method, conversion = nil, node = nil) node ||= method conversion = "val.#{conversion} if val.respond_to?(:#{conversion})" if conversion class_eval(<<-END, __FILE__, __LINE__) def #{method} val = content_from :#{node} #{conversion} end END end |
.content_attr_writer(method, node = nil) ⇒ Object
Provides a content writer helper that creates or updates the content of a node method
is the method to create node
is the name of the node to create (defaults to the method name)
class Node
content_attr_writer :body
content_attr_writer :id, :identity
end
n = Node.new 'foo'
n.body = 'thebodytext'
n.id = 'id-text'
n.to_s == '<foo><body>thebodytext</body><identity>id-text</identity></foo>'
157 158 159 160 161 162 163 164 |
# File 'lib/blather/xmpp_node.rb', line 157 def self.content_attr_writer(method, node = nil) node ||= method class_eval(<<-END, __FILE__, __LINE__) def #{method}=(val) set_content_for :#{node}, val end END end |
.import(node) ⇒ Object
Looks up the class to use then instantiates an object of that class and imports all the node
‘s attributes and children into it.
38 39 40 41 42 43 44 45 |
# File 'lib/blather/xmpp_node.rb', line 38 def self.import(node) klass = class_from_registration(node.element_name, (node.namespace.href if node.namespace)) if klass && klass != self klass.import(node) else new(node.element_name).inherit(node) end end |
.new(name = nil, doc = nil) ⇒ Object
Automatically sets the namespace registered by the subclass
176 177 178 179 180 181 182 183 |
# File 'lib/blather/xmpp_node.rb', line 176 def self.new(name = nil, doc = nil) name ||= self.registered_name node = super name.to_s, (doc || Nokogiri::XML::Document.new) node.document.root = node unless doc node.namespace = self.registered_ns unless BASE_NAMES.include?(name.to_s) node end |
.register(name, ns = nil) ⇒ Object
Lets a subclass register itself
This registers a namespace that is used when looking up the class name of the object to instantiate when a new stanza is received
21 22 23 24 25 |
# File 'lib/blather/xmpp_node.rb', line 21 def self.register(name, ns = nil) self.registered_name = name.to_s self.registered_ns = ns @@registrations[[self.registered_name, self.registered_ns]] = self end |
Instance Method Details
#content_from(name, ns = nil) ⇒ Object
Pull the content from a child
228 229 230 231 |
# File 'lib/blather/xmpp_node.rb', line 228 def content_from(name, ns = nil) child = xpath(name, ns).first child.content if child end |
#inherit(stanza) ⇒ Object
Inherit all of stanza
‘s attributes and children
251 252 253 254 255 256 257 258 259 260 |
# File 'lib/blather/xmpp_node.rb', line 251 def inherit(stanza) set_namespace stanza.namespace if stanza.namespace inherit_attrs stanza.attributes stanza.children.each do |c| self << (n = c.dup) ns = n.namespace_definitions.find { |ns| ns.prefix == c.namespace.prefix } n.namespace = ns if ns end self end |
#inherit_attrs(attrs) ⇒ Object
Inherit only stanza
‘s attributes
264 265 266 267 |
# File 'lib/blather/xmpp_node.rb', line 264 def inherit_attrs(attrs) attrs.each { |name, value| self[name] = value } self end |
#namespace=(namespaces) ⇒ Object
192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 |
# File 'lib/blather/xmpp_node.rb', line 192 def namespace=(namespaces) case namespaces when Nokogiri::XML::Namespace self.nokogiri_namespace = namespaces when String self.add_namespace nil, namespaces when Hash if ns = namespaces.delete(nil) self.add_namespace nil, ns end namespaces.each do |p, n| ns = self.add_namespace p, n self.nokogiri_namespace = ns end end end |
#namespace_href ⇒ Object
209 210 211 |
# File 'lib/blather/xmpp_node.rb', line 209 def namespace_href namespace.href if namespace end |
#nokogiri_namespace= ⇒ Object
191 |
# File 'lib/blather/xmpp_node.rb', line 191 alias_method :nokogiri_namespace=, :namespace= |
#remove_child(name, ns = nil) ⇒ Object
Remove a child with the name and (optionally) namespace given
215 216 217 218 |
# File 'lib/blather/xmpp_node.rb', line 215 def remove_child(name, ns = nil) child = xpath(name, ns).first child.remove if child end |
#remove_children(name) ⇒ Object
Remove all children with a given name
222 223 224 |
# File 'lib/blather/xmpp_node.rb', line 222 def remove_children(name) xpath("./*[local-name()='#{name}']").remove end |
#set_content_for(node, content = nil) ⇒ Object
Sets the content for the specified node. If the node exists it is updated. If not a new node is created If the node exists and the content is nil, the node will be removed entirely
237 238 239 240 241 242 243 244 245 |
# File 'lib/blather/xmpp_node.rb', line 237 def set_content_for(node, content = nil) if content child = xpath(node).first self << (child = XMPPNode.new(node, self.document)) unless child child.content = content else remove_child node end end |
#to_stanza ⇒ Object
Quickway of turning itself into a proper object
187 188 189 |
# File 'lib/blather/xmpp_node.rb', line 187 def to_stanza self.class.import self end |