Project

General

Profile

« Previous | Next » 

Revision c331fe49

Added by Marc Dequènes over 14 years ago

  • ID c331fe496ad1561adfb5d9c0ef3e7554e9a0a5ff

[evol] rework how object/aspect classes are generated and ensure each shadow materials is in a proper container (to allow loading multiple shadows)

View differences:

lib/ldap_shadows/shadow.rb
require 'jcode'
require 'active_ldap'
require 'ldap_shadows/activeldap_fixes'
require 'facets/metaid'
require 'ldap_shadows/object'
require 'ldap_shadows/aspect'
module LdapShadows
module Shadows
end
class Shadow
attr_reader :name
def initialize(name)
@name = name
LdapShadows::LdapObject.shadow = self
@config = Config.instance
# cannot use anonymous modules/classes, as active_ldap needs named classes for relations
module_name = "Shadow" + name.capitalize
@container = LdapShadows::Shadows.module_eval(<<-EOS)
module #{module_name}; self; end
EOS
@objects = {}
@object_definitions = {}
@aspects = {}
# TODO: should replace @aspects properly one day
......
def add_aspect(aspect_name, aspect_def_raw)
aspect_def = @config.parse_and_validate(aspect_name, 'aspect', aspect_def_raw)
aspect_name = aspect_name.to_sym
@aspects[aspect_name] = aspect_def
klass_name = "LdapAspect" + aspect_name.to_s.capitalize
klass_content = @config.load_hook_content(@name, 'aspect', aspect_name)
klass_name = "LdapAspect" + aspect_name.to_s.capitalize
begin
Aspects.module_eval(<<-EOS)
class #{klass_name} < LdapAspect
#{klass_content}
end
klass = @container.module_eval(<<-EOS)
class #{klass_name} < LdapAspect; self; end
EOS
klass.instance_variable_set(:@handle, aspect_name)
klass.instance_variable_set(:@shadow, self)
klass.meta_eval do
attr_reader :handle, :shadow
end
klass.class_eval(klass_content) unless klass_content.nil?
rescue
raise PreProcessingError, _("Could not load Aspect plugin '%s'") % aspect_name
raise PreProcessingError, _("Could not load Aspect plugin '%s': %s") % [aspect_name, $!]
end
@aspects2[aspect_name] = Aspects.const_get(klass_name)
@aspects[aspect_name.to_sym] = aspect_def
@aspects2[aspect_name] = klass
end
def get_aspect(aspect_name)
......
end
def get_aspect_klass(aspect_name)
@aspects2[aspect_name.to_sym]
end
def self.object_name_to_klass_name(object_name)
"LdapObject" + object_name.to_s.capitalize
@aspects2[aspect_name]
end
def add_object(object_name, object_def_raw)
object_def = @config.parse_and_validate(object_name, 'object', object_def_raw)
object_name = object_name.to_sym
klass_name = self.class.object_name_to_klass_name(object_name)
klass_name = "LdapObject" + object_name.to_s.capitalize
klass_content = @config.load_hook_content(@name, 'object', object_name)
# create class
Objects.module_eval(<<-EOS)
class #{klass_name} < LdapObject
#{klass_content}
begin
klass = @container.module_eval(<<-EOS)
class #{klass_name} < LdapObject; self; end
EOS
klass.instance_variable_set(:@handle, object_name)
klass.instance_variable_set(:@shadow, self)
klass.meta_eval do
attr_reader :handle, :shadow
end
EOS
klass.class_eval(klass_content) unless klass_content.nil?
rescue
raise PreProcessingError, _("Could not load Object plugin '%s': %s") % [object_name, $!]
end
# configure class
klass = find_klass(object_name)
klass.handle = object_name
klass.presentation = object_def[:presentation]
klass.shadow = self
klass.ldap_mapping object_def[:mapping]
# store definition for later relations processing
@object_definitions[object_name] = object_def
@object_definitions[object_name.to_sym] = object_def
@objects[object_name] = klass
end
def find_klass(object_name)
klass_name = self.class.object_name_to_klass_name(object_name)
return nil unless Objects.const_defined?(klass_name)
Objects.const_get(klass_name)
@objects[object_name.to_s]
end
# run it _once_ when all objects are loaded
......
end
def objects
@object_definitions.keys.collect{|key| key.to_s }.sort
@objects.keys.sort
end
end
# default location for mapped objects
module Objects
end
# default location for mapped aspects
module Aspects
end
end

Also available in: Unified diff