Class: Blather::XMPPNode

Inherits:
Nokogiri::XML::Node show all
Defined in:
lib/blather/xmpp_node.rb

Overview

Base XML Node All XML classes subclass XMPPNode it allows the addition of helpers

Constant Summary collapse

BASE_NAMES =
%w[presence message iq].freeze
@@registrations =
{}

Class Method Summary collapse

Instance Method Summary collapse

Methods inherited from Nokogiri::XML::Node

#[]=, #attr_set, #find_first, #nokogiri_xpath, #xpath

Class Method Details

.class_from_registration(name, ns = nil) ⇒ Class?

Find the class to use given the name and namespace of a stanza

Parameters:

  • name (#to_s)

    the name to lookup

  • xmlns (String, nil)

    the namespace the node belongs to

Returns:

  • (Class, nil)

    the class appropriate for the name/ns combination



34
35
36
37
# File 'lib/blather/xmpp_node.rb', line 34

def self.class_from_registration(name, ns = nil)
  name = name.to_s
  @@registrations[[name, ns]]
end

.import(node) ⇒ Object

Import an XML::Node to the appropriate class

Looks up the class the node should be then creates it based on the elements of the XML::Node

Parameters:

  • node (XML::Node)

    the node to import

Returns:

  • the appropriate object based on the node name and namespace



45
46
47
48
49
50
51
52
53
# File 'lib/blather/xmpp_node.rb', line 45

def self.import(node)
  ns = (node.namespace.href if node.namespace)
  klass = class_from_registration(node.element_name, ns)
  if klass && klass != self
    klass.import(node)
  else
    new(node.element_name).inherit(node)
  end
end

.new(name = nil, doc = nil) ⇒ Object

Create a new Node object

not provided one will be created

Parameters:

  • name (String, nil) (defaults to: nil)

    the element name

  • doc (XML::Document, nil) (defaults to: nil)

    the document to attach the node to. If

Returns:

  • a new object with the registered name and namespace



61
62
63
64
65
66
67
68
# File 'lib/blather/xmpp_node.rb', line 61

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

Register a new stanza class to a name and/or namespace

This registers a namespace that is used when looking up the class name of the object to instantiate when a new stanza is received

Parameters:

  • name (#to_s)

    the name of the node

  • ns (String, nil) (defaults to: nil)

    the namespace the node belongs to



23
24
25
26
27
# File 'lib/blather/xmpp_node.rb', line 23

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) ⇒ String?

The content of the named node

Parameters:

  • name (String)

    the name or xpath of the node

  • ns (String, nil) (defaults to: nil)

    the namespace the node is in

Returns:

  • (String, nil)

    the content of the node



165
166
167
168
# File 'lib/blather/xmpp_node.rb', line 165

def content_from(name, ns = nil)
  child = xpath(name, ns).first
  child.content if child
end

#inherit(stanza) ⇒ self

Inherit the attributes and children of an XML::Node

Parameters:

  • stanza (XML::Node)

    the node to inherit

Returns:

  • (self)


193
194
195
196
197
198
199
200
201
202
# File 'lib/blather/xmpp_node.rb', line 193

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) ⇒ self

Inherit a set of attributes

Parameters:

  • attrs (Hash)

    a hash of attributes to set on the node

Returns:

  • (self)


208
209
210
211
# File 'lib/blather/xmpp_node.rb', line 208

def inherit_attrs(attrs)
  attrs.each  { |name, value| self[name] = value }
  self
end

#inspectObject



213
214
215
# File 'lib/blather/xmpp_node.rb', line 213

def inspect
  self.to_xml
end

#namespace=(ns) ⇒ Object #namespace=(ns) ⇒ Object #namespace=(namespaces) ⇒ Object

Attach a namespace to the node

Overloads:

  • #namespace=(ns) ⇒ Object

    Attach an already created XML::Namespace

    Parameters:

    • ns (XML::Namespace)

      the namespace object

  • #namespace=(ns) ⇒ Object

    Create a new namespace and attach it

    Parameters:

    • ns (String)

      the namespace uri

  • #namespace=(namespaces) ⇒ Object

    Createa and add new namespaces from a hash

    Parameters:

    • namespaces (Hash)

      a hash of prefix => uri pairs



120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
# File 'lib/blather/xmpp_node.rb', line 120

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_hrefXML::Namespace?

Helper method to get the node’s namespace

Returns:

  • (XML::Namespace, nil)

    The node’s namespace object if it exists



140
141
142
# File 'lib/blather/xmpp_node.rb', line 140

def namespace_href
  namespace.href if namespace
end

#nokogiri_namespace=Object



108
# File 'lib/blather/xmpp_node.rb', line 108

alias_method :nokogiri_namespace=, :namespace=

#read_attr(attr_name, to_call = nil) ⇒ Object

Helper method to read an attribute

the returned value

Parameters:

  • attr_name (#to_sym)

    the name of the attribute

  • to_call (String, Symbol, nil) (defaults to: nil)

    the name of the method to call on

Returns:

  • nil or the value



76
77
78
79
# File 'lib/blather/xmpp_node.rb', line 76

def read_attr(attr_name, to_call = nil)
  val = self[attr_name.to_sym]
  val && to_call ? val.__send__(to_call) : val
end

#read_content(node, to_call = nil) ⇒ Object

Helper method to read the content of a node

the returned value

Parameters:

  • node (#to_sym)

    the name of the node

  • to_call (String, Symbol, nil) (defaults to: nil)

    the name of the method to call on

Returns:

  • nil or the value



95
96
97
98
# File 'lib/blather/xmpp_node.rb', line 95

def read_content(node, to_call = nil)
  val = content_from node.to_sym
  val && to_call ? val.__send__(to_call) : val
end

#remove_child(name, ns = nil) ⇒ Object

Remove a child with the name and (optionally) namespace given

Parameters:

  • name (String)

    the name or xpath of the node to remove

  • ns (String, nil) (defaults to: nil)

    the namespace the node is in



148
149
150
151
# File 'lib/blather/xmpp_node.rb', line 148

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 regardless of namespace

Parameters:

  • name (String)

    the name of the nodes to remove



156
157
158
# File 'lib/blather/xmpp_node.rb', line 156

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

Parameters:

  • node (String)

    the name of the node to update/create

  • content (String, nil) (defaults to: nil)

    the content to set within the node



177
178
179
180
181
182
183
184
185
# File 'lib/blather/xmpp_node.rb', line 177

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_stanzaObject

Turn the object into a proper stanza

Returns:

  • a stanza object



103
104
105
# File 'lib/blather/xmpp_node.rb', line 103

def to_stanza
  self.class.import self
end

#write_attr(attr_name, value) ⇒ Object

Helper method to write a value to an attribute

Parameters:

  • attr_name (#to_sym)

    the name of the attribute

  • value (#to_s)

    the value to set the attribute to



85
86
87
# File 'lib/blather/xmpp_node.rb', line 85

def write_attr(attr_name, value)
  self[attr_name.to_sym] = value
end