commit 9fca01408af69a7262b021c1ee5db1e512cbc0bb
Author: Marc Dequènes (Duck) <Duck@DuckCorp.org>
Date:   Fri Oct 16 02:16:21 2009 +0200

    [evol] improve config #12 (improved object definition check #3 + added aspect definition check)

diff --git a/data/ldap_shadows/schema/aspect.yaml b/data/ldap_shadows/schema/aspect.yaml
new file mode 100644
index 0000000..6bed14a
--- /dev/null
+++ b/data/ldap_shadows/schema/aspect.yaml
@@ -0,0 +1,40 @@
+---
+type: map
+mapping:
+  "mapping":
+    type: map
+    required: true
+    name: Mapping
+    mapping:
+      "classes":
+        type: seq
+        sequence:
+          - type: str
+      "depend_aspects":
+        type: seq
+        sequence:
+          - type: str
+  "presentation":
+    type: map
+    mapping:
+      "associated_attributes":
+        type: seq
+        sequence:
+          - type: str
+      "associated_relations":
+        type: seq
+        sequence:
+          - type: str
+  "relations":
+    type: map
+    mapping:
+      =:
+        type: map
+        name: RelationMapping
+        mapping:
+          "type": {type: str, required: true, enum: [belongs_to, has_many]}
+          "object": {type: str, required: true}
+          "foreign_key": {type: str, required: true}
+          "many": {type: str}
+          "primary_key": {type: str}
+
diff --git a/lib/ldap_shadows/controller.rb b/lib/ldap_shadows/controller.rb
index f4415c1..c7284be 100755
--- a/lib/ldap_shadows/controller.rb
+++ b/lib/ldap_shadows/controller.rb
@@ -57,11 +57,56 @@ module LdapShadows
       @shadow_config
     end
 
+    class LdapShadowsValidator < Kwalify::Validator
+      ## hook method called by Validator#validate()
+      def validate_hook(value, rule, path, errors)
+        msg_list = []
+
+        validate_hook_in(value, rule, path, msg_list)
+
+        msg_list.each do |msg|
+          errors << Kwalify::ValidationError.new(msg, path)
+        end
+      end
+
+      def validate_hook_relation(value, rule, path, msg_list)
+        extra_params = [:type, :object]
+
+        if value['type'] == 'belongs_to'
+          ne_params = value.keys.collect{|k| k.to_sym } - ActiveLdap::Associations::ClassMethods::VALID_BELONGS_TO_OPTIONS - extra_params
+          unless ne_params.empty?
+            msg_list << _("nonexisting relation mapping parameters (%s)") % ne_params.join(", ")
+          end
+        else
+          ne_params = value.keys.collect{|k| k.to_sym } - ActiveLdap::Associations::ClassMethods::VALID_HAS_MANY_OPTIONS - extra_params
+          unless ne_params.empty?
+            msg_list << _("nonexisting relation mapping parameters (%s)") % ne_params.join(", ")
+          end
+        end
+      end
+    end
+
+    class AspectValidator < LdapShadowsValidator
+      def validate_hook_in(value, rule, path, msg_list)
+        case rule.name
+        when 'RelationMapping'
+          validate_hook_relation(value, rule, path, msg_list)
+        end
+      end
+    end
+
     def set_aspect(aspect_name, aspect_def)
-      parser = Kwalify::Yaml::Parser.new
+      schema_name = 'aspect'
+      schema = load_schema(schema_name)
+
+      # validate config with schema
+      validator = AspectValidator.new(schema)
+      parser = Kwalify::Yaml::Parser.new(validator)
       aspect_def = parser.parse(aspect_def, aspect_name)
-      aspect_def.recursive_symbolize_keys!
+      raise_if_validation_errors("#{schema_name.capitalize} '#{aspect_name}'", parser.errors)
+
       aspect_name = aspect_name.to_sym
+      aspect_def.recursive_symbolize_keys!
       @aspects[aspect_name] = aspect_def
 
       filename = File.join(Config::CFG_DIR, "hooks", "aspects", aspect_name.to_s.downcase + ".rb")
@@ -94,11 +139,8 @@ module LdapShadows
       "LdapObject" + obj_name.to_s.capitalize
     end
 
-    class ObjectValidator < Kwalify::Validator
-      ## hook method called by Validator#validate()
-      def validate_hook(value, rule, path, errors)
-        msg_list = []
-
+    class ObjectValidator < LdapShadowsValidator
+      def validate_hook_in(value, rule, path, msg_list)
         case rule.name
         when 'Mapping'
           ne_params = value.keys.collect{|k| k.to_sym } - ActiveLdap::Base::VALID_LDAP_MAPPING_OPTIONS
@@ -107,29 +149,7 @@ module LdapShadows
           end
 
         when 'RelationMapping'
-          extra_params = [:type, :object]
-
-          if value['type'] == 'belongs_to'
-            ne_params = value.keys.collect{|k| k.to_sym } - ActiveLdap::Associations::ClassMethods::VALID_BELONGS_TO_OPTIONS - extra_params
-            unless ne_params.empty?
-              msg_list << _("nonexisting relation mapping parameters (%s)") % ne_params.join(", ")
-            end
-            unless value.has_key? 'many'
-              msg_list << _("a 'belongs_to' relation needs a 'many' parameter")
-            end
-          else
-            ne_params = value.keys.collect{|k| k.to_sym } - ActiveLdap::Associations::ClassMethods::VALID_HAS_MANY_OPTIONS - extra_params
-            unless ne_params.empty?
-              msg_list << _("nonexisting relation mapping parameters (%s)") % ne_params.join(", ")
-            end
-            unless value.has_key? 'primary_key'
-              msg_list << _("a 'has_many' relation needs a 'primary_key' parameter")
-            end
-          end
-        end
-
-        msg_list.each do |msg|
-          errors << Kwalify::ValidationError.new(msg, path)
+          validate_hook_relation(value, rule, path, msg_list)
         end
       end
     end
@@ -142,8 +162,7 @@ module LdapShadows
       validator = ObjectValidator.new(schema)
       parser = Kwalify::Yaml::Parser.new(validator)
       obj_def = parser.parse(obj_def, obj_name)
-      errors = parser.errors()
-      raise_if_validation_errors("#{schema_name.capitalize} '#{obj_name}'", errors)
+      raise_if_validation_errors("#{schema_name.capitalize} '#{obj_name}'", parser.errors)
 
       obj_name = obj_name.to_sym
       obj_def.recursive_symbolize_keys!
