commit a24bc5b15ef38d0047f2624df1f195a63f48fc13
Author: Marc Dequènes (Duck) <Duck@DuckCorp.org>
Date:   Sun Jul 26 21:15:05 2009 +0200

    [evol] improved 'list' command

diff --git a/bin/shadowwalker b/bin/shadowwalker
index 050c01c..a20afb4 100755
--- a/bin/shadowwalker
+++ b/bin/shadowwalker
@@ -99,11 +99,12 @@ class ListCommand < Command
   def initialize
     super('list', false)
 
-    self.short_desc = "list items of an object"
-    self.usages_params = [
-                          "<object>",
+    self.short_desc = "list objects, and items/aspects/fields of an object"
+    self.usages_params = [  
                           ":objects",
-                          ":aspects <object>"
+                          "<object>",
+                          "<object> :aspects",
+                          "<object> :fields"
                          ]
   end
 
@@ -113,7 +114,7 @@ class ListCommand < Command
       exit 1
     end
 
-    obj_hdl = args.shift.singularize
+    obj_hdl = args.shift.downcase.singularize
     case obj_hdl
     when ':object'
       list = $ldapctl.objects
@@ -121,25 +122,6 @@ class ListCommand < Command
       list.each do |obj_name|
         puts "  - #{obj_name}"
       end
-    when ':aspect'
-      if args.empty?
-        STDERR.puts "syntax error: no sub-object name given"
-        exit 1
-      end
-
-      subobj_hdl = args.shift.singularize
-      obj_klass = $ldapctl.find_klass(subobj_hdl)
-      if obj_klass.nil?
-        STDERR.puts "No such object '#{obj_hdl}'."
-        exit 2
-      end
-
-      subobj_human_name = Translator.translate_object_name(subobj_hdl)
-      list = obj_klass.possible_aspects
-      puts "=== List of LDAP aspects of #{subobj_human_name.pluralize} (#{list.size}) ==="
-      list.each do |subobj_name|
-        puts "  - #{subobj_name}"
-      end
     else
       obj_klass = $ldapctl.find_klass(obj_hdl)
       if obj_klass.nil?
@@ -147,8 +129,44 @@ class ListCommand < Command
         exit 2
       end
 
-      obj_human_name = Translator.translate_object_name(obj_hdl)
-      Display.display_item_list("List of #{obj_human_name.pluralize}", obj_klass.find(:all))
+      if args.empty?
+        obj_human_name = Translator.translate_object_name(obj_hdl)
+        Display.display_item_list("List of #{obj_human_name.pluralize}", obj_klass.find(:all))
+      else
+        subobj_hdl = args.shift.downcase.singularize
+
+        obj_human_name = Translator.translate_object_name(obj_hdl)
+
+        case subobj_hdl
+        when ':aspect'
+          list = obj_klass.possible_aspects
+          puts "=== List of LDAP Aspects of #{obj_human_name.pluralize} (#{list.size}) ==="
+          list.each do |aspect|
+            str = Translator.translate_aspect_name(aspect)
+            str += " [#{aspect}]" if $program_options[:handles]
+            puts "  - #{str}"
+          end
+        when ':field'
+          list = obj_klass.possible_attributes
+          puts "=== List of LDAP Fields of #{obj_human_name.pluralize} (#{list.size}) ==="
+          list.each do |field|
+            str = Translator.translate_field_name(field)
+            str += " [#{field}]" if $program_options[:handles]
+            puts "  - #{str}"
+          end
+          obj_klass.possible_aspects.each do |aspect|
+            aspect_human_name = Translator.translate_aspect_name(aspect)
+            list = obj_klass.possible_attributes_for_aspect(aspect)
+            puts "--- Sublist of LDAP Fields for Aspect #{aspect_human_name} (#{list.size}) ---"
+            list.each do |field|
+              str = Translator.translate_field_name(field)
+              str += " [#{field}]" if $program_options[:handles]
+              puts "  - #{str}"
+            end
+          end
+        else
+        end
+      end
     end
   end
 end
diff --git a/lib/ldap_shadows/display_utils.rb b/lib/ldap_shadows/display_utils.rb
index 531aa2c..37901e1 100644
--- a/lib/ldap_shadows/display_utils.rb
+++ b/lib/ldap_shadows/display_utils.rb
@@ -99,12 +99,12 @@ module LdapShadows
       end
     end
 
-    def self.display_item_list(title, obj_list)
-      puts "=== #{title} (#{obj_list.size}) ==="
-      obj_list.each do |obj|
-        str = obj.human_name
-        str += " [#{obj.name}]" if $program_options[:handles]
-        str += ": #{obj.description}" unless obj.description.empty?
+    def self.display_item_list(title, item_list)
+      puts "=== #{title} (#{item_list.size}) ==="
+      item_list.each do |item|
+        str = item.human_name
+        str += " [#{item.name}]" if $program_options[:handles]
+        str += ": #{item.description}" unless item.description.empty?
         puts str
       end
     end
diff --git a/lib/ldap_shadows/object.rb b/lib/ldap_shadows/object.rb
index 76caf6a..28e84bd 100755
--- a/lib/ldap_shadows/object.rb
+++ b/lib/ldap_shadows/object.rb
@@ -155,7 +155,7 @@ module LdapShadows
       present_aspects
     end
 
-    def objectclasses_attr_list(objectclass_list)
+    def self.objectclasses_attr_list(objectclass_list)
       objectclass_list = [objectclass_list] unless objectclass_list.is_a? Array
       list = []
       objectclass_list.each do |objectclass|
@@ -166,6 +166,17 @@ module LdapShadows
       list
     end
 
+    def self.possible_attributes
+      klasses = self.required_classes
+      klasses += self.presentation[:optional_classes] if self.presentation.has_key?(:optional_classes)
+      self.objectclasses_attr_list(klasses)
+    end
+
+    def self.possible_attributes_for_aspect(aspect)
+      aspect_data = self.mapper.get_aspect(aspect)
+      self.objectclasses_attr_list(aspect_data[:mapping][:classes])
+    end
+
     def info_for_relation(rel)
       return nil unless self.relations.include?(rel)
 
@@ -215,7 +226,7 @@ module LdapShadows
         if self.class.presentation.has_key?(:associated_attributes)
           taken_attr_list += self.class.presentation[:associated_attributes]
         end
-        taken_attr_list += objectclasses_attr_list(self.required_classes + (self.class.presentation[:optional_classes] || []))
+        taken_attr_list += self.class.possible_attributes
       end
       taken_attr_list = taken_attr_list.uniq & attr_list
       obj_info = fetch_attributes_data(taken_attr_list, expert_attributes)
@@ -233,9 +244,7 @@ module LdapShadows
       # second pass to dispath the remaining attributes
       unless attr_list.empty?
         aspects.each do |aspect|
-          aspect_data = self.class.mapper.get_aspect(aspect)
-
-          taken_attr_list = (objectclasses_attr_list(aspect_data[:mapping][:classes]) & attr_list)
+          taken_attr_list = (self.class.possible_attributes_for_aspect(aspect) & attr_list)
           obj_aspects[aspect] ||= {}
           obj_aspects[aspect].merge!(fetch_attributes_data(taken_attr_list, expert_attributes))
           attr_list -= taken_attr_list
