class Webgen::Tree

Represents a tree of nodes.

Attributes

dummy_root[R]

The dummy root.

This is the default node that gets created when the Tree is created so that the real root node can be treated like any other node. It has only one child, namely the real root node of the tree.

node_access[R]

Direct access to the hashes for node resolving.

Only use this for reading purposes! If you just want to get a specific node for an alcn/acn/destination path, use node instead.

website[R]

The website to which the Tree object belongs.

Public Class Methods

new(website) click to toggle source

Create a new Tree object for the website.

# File lib/webgen/tree.rb, line 26
def initialize(website)
  @website = website
  @node_access = {:alcn => {}, :acn => {}, :dest_path => {}, :translation_key => {}}
  @dummy_root = Node.new(self, '', '')
end

Public Instance Methods

[](path) click to toggle source

Access a node via its :alcn.

# File lib/webgen/tree.rb, line 38
def [](path)
  @node_access[:alcn][path]
end
delete_node(node) click to toggle source

Delete the node and all of its children from the tree.

The message :before_node_deleted is sent with the to-be-deleted node before the node is actually deleted from the tree.

# File lib/webgen/tree.rb, line 127
def delete_node(node)
  return if node.nil? || !node.kind_of?(Node) || node == @dummy_root

  node.children.dup.each {|child| delete_node(child)}

  @website.blackboard.dispatch_msg(:before_node_deleted, node)
  node.parent.children.delete(node)
  @node_access[:alcn].delete(node.alcn)
  @node_access[:acn][node.acn].delete(node)
  @node_access[:translation_key][translation_key(node)].delete(node)
  @node_access[:dest_path].delete(node.dest_path) unless node.meta_info['no_output']
end
node(path, type = :alcn) click to toggle source

Access a node via a path of a specific type.

If type is :alcn (default) then path has to be an absolute localized canonical name, if type is acn then path has to be an absolute canonical name and if type is :dest_path then path needs to be a destination path.

Returns the requested Node or nil if such a node does not exist.

# File lib/webgen/tree.rb, line 49
def node(path, type = :alcn)
  case type
  when :alcn then @node_access[type][path]
  when :acn then @node_access[type][path] && @node_access[type][path].first
  when :dest_path then @node_access[type][path]
  else
    raise ArgumentError, "Unknown type '#{type}' for resolving path <#{path}>"
  end
end
register_node(node) click to toggle source

Utility method called by Node#initialize. This method should not be used directly!

# File lib/webgen/tree.rb, line 100
def register_node(node)
  if @node_access[:alcn].has_key?(node.alcn)
    raise "Can't have two nodes with same alcn: #{node}"
  else
    @node_access[:alcn][node.alcn] = node
  end
  (@node_access[:acn][node.acn] ||= []) << node
  (@node_access[:translation_key][translation_key(node)] ||= []) << node
  if node.meta_info['no_output']
    # ignore node dest path
  elsif @node_access[:dest_path].has_key?(node.dest_path)
    raise "Can't have two nodes with same destination path: #{node.dest_path}"
  else
    @node_access[:dest_path][node.dest_path] = node
  end
end
resolve_node(path, lang, msg_on_failure = false) click to toggle source

Return the node representing the given path which can be an alcn/acn/destination path (name resolution is done in the specified order). The path has to be absolute, i.e. starting with a slash.

If the path is an alcn and a node is found, it is returned. If the path is an acn, the correct localized node according to lang is returned or if no such node exists but an unlocalized version does, the unlocalized node is returned. If the path is a destination path, the node with this destination path is returned.

If no node is found for the given path or if the path is invalid, nil is returned and, if msg_on_failure is true, the message :node_resolution_failed (with parameters path and lang) is dispatched.

# File lib/webgen/tree.rb, line 71
def resolve_node(path, lang, msg_on_failure = false)
  node = self.node(path, :alcn)
  if !node || node.acn == path
    (node = (self.node(path, :acn) || self.node(path + '/', :acn))) && (node = translate_node(node, lang))
  end
  node = self.node(path, :dest_path) if !node
  @website.blackboard.dispatch_msg(:node_resolution_failed, path, lang) if !node && msg_on_failure
  node
end
root() click to toggle source

The real root node of the tree.

# File lib/webgen/tree.rb, line 33
def root
  @dummy_root.children.first
end
translate_node(node, lang) click to toggle source

Return the translation of the node to the language lang or, if no such node exists, an unlocalized version of the node. If no such node is found either, nil is returned.

# File lib/webgen/tree.rb, line 83
def translate_node(node, lang)
  avail = @node_access[:translation_key][translation_key(node)]
  avail.find do |n|
    n = n.parent while n.is_fragment?
    n.lang == lang
  end || avail.find do |n|
    n = n.parent while n.is_fragment?
    n.lang.nil?
  end
end
translations(node) click to toggle source

Return all translations of the node.

# File lib/webgen/tree.rb, line 95
def translations(node)
  @node_access[:translation_key][translation_key(node)].dup
end

Private Instance Methods

translation_key(node) click to toggle source

Return the translation key for the node.

# File lib/webgen/tree.rb, line 118
def translation_key(node)
  node.meta_info['translation_key'] || node.acn
end