class VCloudSdk::Xml::Wrapper

Public Class Methods

new(xml, ns = nil, ns_definitions = nil) click to toggle source

Because we are wrapping individual nodes in a wrapper and turning them into XML docs, we need to preserve the namespace information with each node

# File lib/ruby_vcloud_sdk/xml/wrapper.rb, line 63
def initialize(xml, ns = nil, ns_definitions = nil)
  if xml.is_a?(Nokogiri::XML::Document)
    @doc = xml
    @root = @doc.root
  else
    @root = xml
  end
  if ns
    @ns = ns
  else
    @ns = @root.namespace
  end

  # Use (server) supplied prefixes defaulting to the preset ones for
  # those not specified.
  @doc_namespaces = ns_definitions.nil? ? [] :
    Array.new(ns_definitions)
  if @root.namespace_definitions
    @doc_namespaces.concat(@root.namespace_definitions)
  end
end

Public Instance Methods

==(other) click to toggle source
# File lib/ruby_vcloud_sdk/xml/wrapper.rb, line 230
def ==(other)
  @root.to_s == other.node.to_s
end
[](attr) click to toggle source

There seem to be a Nokogiri bug such that attribute’s namespace prefixes are ignored. For example, to return an attribute named vcloud:capacity, use “capacity”, not “vcloud:capacity”.

# File lib/ruby_vcloud_sdk/xml/wrapper.rb, line 209
def [](attr)
  @root[attr]
end
[]=(attr, value) click to toggle source
# File lib/ruby_vcloud_sdk/xml/wrapper.rb, line 218
def []=(attr, value)
  @root[attr] = value
end
add_child( child, namespace_prefix = nil, namespace_href = nil, parent = @root) click to toggle source
# File lib/ruby_vcloud_sdk/xml/wrapper.rb, line 243
def add_child(
      child,
      namespace_prefix = nil,
      namespace_href = nil,
      parent = @root)
  if child.is_a? Wrapper
    @root.add_child(child.node)
  elsif child.is_a? String
    node = Nokogiri::XML::Node.new(child, parent)
    set_namespace(node, namespace_prefix, namespace_href)
    parent.add_child(node)
  else
    fail CpiError, "Cannot add child.  Unknown object passed in."
  end
end
attribute(name) click to toggle source

get the attribute regardless what namespace the attribute has

# File lib/ruby_vcloud_sdk/xml/wrapper.rb, line 214
def attribute(name)
  @root.attribute(name)
end
content() click to toggle source
# File lib/ruby_vcloud_sdk/xml/wrapper.rb, line 222
def content
  @root.content
end
content=(value) click to toggle source
# File lib/ruby_vcloud_sdk/xml/wrapper.rb, line 226
def content=(value)
  @root.content = value
end
create_child(tag, namespace_prefix = nil, namespace_href = nil) click to toggle source

Creates a child node but does not add it to the document. Used when a new child node has to be in a specific location or order.

# File lib/ruby_vcloud_sdk/xml/wrapper.rb, line 261
def create_child(tag,
                 namespace_prefix = nil,
                 namespace_href = nil)
  node = Nokogiri::XML::Node.new(tag, @root)
  set_namespace(node, namespace_prefix, namespace_href)
  node
end
create_qualified_name(name, href) click to toggle source
# File lib/ruby_vcloud_sdk/xml/wrapper.rb, line 177
def create_qualified_name(name, href)
  namespace_wanted = nil
  ns_wanted_no_prefix = nil
  # Do it this way so the namespaces are searched in the order they are
  # added.  The first one is the one closest to the node, while the ones
  # at the document root are the last.
  @doc_namespaces.each do |ns|
    if ns.href == href
      if ns.prefix.nil?
        ns_wanted_no_prefix = ns
      else
        namespace_wanted = ns
        break
      end
    end
  end
  namespace_wanted = ns_wanted_no_prefix unless namespace_wanted
  fail CpiError,
       "Namespace #{href} not found." unless namespace_wanted
  ns_prefix = namespace_wanted.prefix.nil? ? "xmlns" :
    namespace_wanted.prefix
  "#{ns_prefix}:#{name}"
end
create_xpath_query(type_name, attrs = nil, only_immediate = false, namespace = VCLOUD_NAMESPACE) click to toggle source
# File lib/ruby_vcloud_sdk/xml/wrapper.rb, line 161
def create_xpath_query(type_name, attrs = nil, only_immediate = false,
    namespace = VCLOUD_NAMESPACE)
  qualified_name = create_qualified_name(type_name, namespace)
  depth_prefix = only_immediate ? nil : ".//"
  if attrs && attrs.length > 0
    attrs_list = []
    attrs.each do |k, v|
      attrs_list.push(%Q[@#{k}="#{v}"])
    end

    "#{depth_prefix}#{qualified_name}[#{attrs_list.join(" and ")}]"
  else
    "#{depth_prefix}#{qualified_name}"
  end
end
doc_namespaces() click to toggle source
# File lib/ruby_vcloud_sdk/xml/wrapper.rb, line 85
def doc_namespaces
  @doc_namespaces
end
get_nodes(type_name, attrs = nil, only_immediate = false, namespace = VCLOUD_NAMESPACE) click to toggle source
# File lib/ruby_vcloud_sdk/xml/wrapper.rb, line 201
def get_nodes(type_name, attrs = nil, only_immediate = false,
    namespace = VCLOUD_NAMESPACE)
  xpath(create_xpath_query(type_name, attrs, only_immediate, namespace))
end
href() click to toggle source
# File lib/ruby_vcloud_sdk/xml/wrapper.rb, line 93
def href
  @root["href"]
end
href=(href) click to toggle source
# File lib/ruby_vcloud_sdk/xml/wrapper.rb, line 97
def href=(href)
  @root["href"] = href
end
href_id() click to toggle source
# File lib/ruby_vcloud_sdk/xml/wrapper.rb, line 101
def href_id
  # Sample href: "https://10.147.0.0/api/org/a3783d64-0b9b-42d6-93cf-23bb08ec5520"
  URI.parse(href).path.split('/')[-1]
end
name() click to toggle source
# File lib/ruby_vcloud_sdk/xml/wrapper.rb, line 106
def name
  @root["name"]
end
name=(name) click to toggle source
# File lib/ruby_vcloud_sdk/xml/wrapper.rb, line 110
def name=(name)
  @root["name"] = name
end
running_tasks() click to toggle source
# File lib/ruby_vcloud_sdk/xml/wrapper.rb, line 156
def running_tasks
  get_nodes(XML_TYPE[:TASK],
            { status: TASK_STATUS[:RUNNING] })
end
to_s() click to toggle source
# File lib/ruby_vcloud_sdk/xml/wrapper.rb, line 234
def to_s
  add_namespaces
    .to_xml
    .each_line
    .reduce("") do |xml, line|
    xml.concat(line.sub(/^\s+$/, ""))
  end
end
type() click to toggle source
# File lib/ruby_vcloud_sdk/xml/wrapper.rb, line 118
def type
  @root["type"]
end
type=(type) click to toggle source
# File lib/ruby_vcloud_sdk/xml/wrapper.rb, line 122
def type=(type)
  @root["type"] = type
end
urn() click to toggle source
# File lib/ruby_vcloud_sdk/xml/wrapper.rb, line 114
def urn
  @root["id"]
end
xpath(*args) click to toggle source
# File lib/ruby_vcloud_sdk/xml/wrapper.rb, line 89
def xpath(*args)
  WrapperFactory.wrap_nodes(@root.xpath(*args), @ns, @doc_namespaces)
end

Protected Instance Methods

namespace() click to toggle source
# File lib/ruby_vcloud_sdk/xml/wrapper.rb, line 275
def namespace
  @ns
end
namespace_definitions() click to toggle source
# File lib/ruby_vcloud_sdk/xml/wrapper.rb, line 279
def namespace_definitions
  @doc_namespaces
end
node() click to toggle source
# File lib/ruby_vcloud_sdk/xml/wrapper.rb, line 271
def node
  @root
end

Private Instance Methods

add_namespaces() click to toggle source
# File lib/ruby_vcloud_sdk/xml/wrapper.rb, line 285
def add_namespaces
  clone = @root.clone

  # This is a workaround for a Nokogiri bug.  If you add a namespace
  # with a nil for prefix, i.e. the namespace following xmlns, Nokogiri
  # will remove the original namespace and assume you are setting a new
  # namespace for the node.
  default_ns = clone.namespace

  @doc_namespaces.each do |ns|
    clone.add_namespace_definition(ns.prefix, ns.href)
  end
  clone.namespace = default_ns
  clone
end
ovf_namespace_prefix() click to toggle source
# File lib/ruby_vcloud_sdk/xml/wrapper.rb, line 320
def ovf_namespace_prefix
  return @ovf_namespace_prefix if @ovf_namespace_prefix
  namespace = namespace_definitions.find { |ns| ns.href == OVF }
  fail VCloudSdk::CloudError,
       "Namespace of href '#{OVF}' is not found" if namespace.nil?

  @ovf_namespace_prefix = namespace.prefix
end
set_namespace(node, namespace_prefix, namespace_href) click to toggle source
# File lib/ruby_vcloud_sdk/xml/wrapper.rb, line 301
def set_namespace(node, namespace_prefix, namespace_href)
  if namespace_prefix.nil? && namespace_href.nil?
    return
  elsif namespace_prefix.nil? || namespace_href.nil?
    fail CpiError,
         "Namespace prefix must both be nil or defined together."
  end

  if !node.namespace.nil? &&
    node.namespace.prefix == namespace_prefix &&
    node.namespace.href == namespace_href
    return
  end

  ns = node.add_namespace_definition(namespace_prefix,
                                     namespace_href)
  node.namespace = ns
end