commit fe5321583c8106fea27459cdd67b852b00075c8d
Author: Marc Dequènes (Duck) <Duck@DuckCorp.org>
Date:   Sun Oct 18 22:45:22 2009 +0200

    [evol] improve tree display, and move code out of shadowwalker

diff --git a/bin/shadowwalker b/bin/shadowwalker
index 4485f7b..8a40863 100755
--- a/bin/shadowwalker
+++ b/bin/shadowwalker
@@ -314,39 +314,7 @@ class TreeCommand < Command
       search_base = loc_item.dn
     end
 
-    if $program_options[:tree_all_objects]
-      dn_list = ActiveLdap::Base.search(:base => search_base, :scope => :sub, :attributes => ['']).collect do |entry|
-        ActiveLdap::DistinguishedName.parse(entry.first)
-      end
-    else
-      dn_list = []
-      sconfig = $shadow.get_config()
-
-      (sconfig[:presentation][:tree_objects] || []).each do |obj_hdl|
-        obj_klass = $shadow.get_object(obj_hdl.downcase)
-        unless obj_klass
-          raise PreProcessingError, _("Location object '%s' not defined") % obj_hdl
-        end
-
-        obj_klass.find(:all, :base => search_base, :scope => :sub).each do |obj|
-          dn_list << obj.dn_obj
-        end
-      end
-    end
-
-    base_dn = ActiveLdap::DistinguishedName.parse(Elements::LdapObject.base)
-
-    tree = {}
-    dn_list.each do |dn|
-      ptree = tree
-      pdn = nil
-      (dn - base_dn).to_s.split(',').reverse.each do |pdn|
-        ptree[pdn] = {} unless ptree.has_key?(pdn)
-        ptree = ptree[pdn]
-      end
-      ptree = nil
-    end
-    tree = {base_dn => tree}
+    tree = $shadow.tree(search_base, $program_options[:debug], $program_options[:tree_all_objects])
 
     Display.display_hash_tree(tree, 0)
   end
diff --git a/lib/ldap_shadows/shadow.rb b/lib/ldap_shadows/shadow.rb
index 453c0c7..2ceaa8e 100755
--- a/lib/ldap_shadows/shadow.rb
+++ b/lib/ldap_shadows/shadow.rb
@@ -92,6 +92,78 @@ module LdapShadows
       @container_elements['aspect'].keys.sort
     end
 
+    def tree(search_base, raw = false, all_objects = false)
+      item_list = {}
+      if all_objects
+        # does not work well...
+        #Elements::LdapObject.find(:all, :base => search_base, :scope => :sub, :attributes => ['']).each do |item|
+        #  item_list[item.dn_obj] = item
+        #end
+        ActiveLdap::Base.find(:all, :base => search_base, :scope => :sub, :attributes => ['']).each do |item|
+           item_list[ActiveLdap::DistinguishedName.parse(item.dn)]= item
+        end
+      else
+        (self.get_config[:presentation][:tree_objects] || []).each do |obj_hdl|
+          obj_klass = get_object(obj_hdl.downcase)
+          unless obj_klass
+            raise PreProcessingError, _("Tree object '%s' not defined") % obj_hdl
+          end
+
+          obj_klass.find(:all, :base => search_base, :scope => :sub).each do |item|
+            item_list[item.dn_obj] = item
+          end
+        end
+      end
+
+      raw_tree = {}
+      tree = {}
+
+      base_dn = ActiveLdap::DistinguishedName.parse(Elements::LdapObject.base)
+      dn_list = item_list.keys
+
+      dn_list.each do |dn|
+        p_raw_tree = raw_tree
+        p_tree = tree
+
+        p_dn = nil
+        p_item = nil
+        current_dn_parts = [base_dn.to_s]
+        (dn - base_dn).to_s.split(',').reverse.each do |p_dn|
+          unless raw
+            current_dn_parts.unshift p_dn
+            current_dn = ActiveLdap::DistinguishedName.parse(current_dn_parts.join(","))
+            current_item = item_list[current_dn]
+            if current_item
+              p_item = Elements::LdapObject.raw_item_info(self, item_list[current_dn])[:name]
+            else
+              # fallback
+              p_item = p_dn
+            end
+          end
+
+          unless p_raw_tree.has_key?(p_dn)
+            p_raw_tree[p_dn] = {}
+            p_tree[p_item] = {} unless raw
+          end
+
+          p_raw_tree = p_raw_tree[p_dn]
+          p_tree = p_tree[p_item] unless raw
+        end
+
+        p_raw_tree = nil
+        p_tree = nil
+      end
+
+      if raw
+        res = {base_dn.to_s => raw_tree}
+      else
+        base_obj = ActiveLdap::Base.find(:first, :base => base_dn.to_s, :scope => :base, :attributes => [])
+        res = {Elements::LdapObject.raw_item_info(self, base_obj)[:name] => tree}
+      end
+
+      res
+    end
+
     protected
 
     def add_container_element(e_type, e_name, e_def_raw)
