class Aio::Module::Loader

Constants

Reg_klass_filter
Reg_ruby_file

Attributes

module_manager[RW]

Public Class Methods

modules_path() click to toggle source

获取modules的路径

# File lib/aio/core/module_loader.rb, line 160
def self.modules_path
  local_path = Pathname.new(File.dirname(__FILE__)).realpath
  return File.join(local_path, "..", "..", "modules")
end
new(module_manager) click to toggle source
# File lib/aio/core/module_loader.rb, line 14
def initialize(module_manager)
        @module_manager = module_manager
end

Public Instance Methods

each_module_reference_name(path, opts={}) { |entry_descendant_path, module_type, module_layer_2, module_reference_name, module_klass_name| ... } click to toggle source

分析各个文件夹目录 目录格式 ~/aio/lib/modules/cisco/show_version.rb 目录格式 ~/aio/lib/modules/cmd/cisco/show_version.rb 目录格式包括了 cmd, input, output cmd 放置各个命令模块 input 放置各种输入方式的模块 output 放置各种输出方式的模块

# File lib/aio/core/module_loader.rb, line 25
def each_module_reference_name(path, opts={})
        ::Dir.foreach(path) do |entry|
                if entry.downcase == "." or entry.downcase == ".."
                        next
                end

                full_entry_path = ::File.join(path, entry)
                module_type = entry
                
                # 第一层目录结构,判断是否为cmd, input, output 的模块类型
                unless ::File.directory?(full_entry_path) and
                                                                module_manager.module_type_enable?(module_type)
                        next
                end

                # module_type = "cmd"
                # full_entry_path = "~/aio/lib/modules/cmd"

                full_entry_pathname = Pathname.new(full_entry_path)

                Find.find(full_entry_path) do |entry_descendant_path|
                        if File.directory?(entry_descendant_path)
                                next
                        end

                        # 判断是不是.rb 结尾,而不是 .rb.swp 结尾
                        unless vaild_ruby_file?(entry_descendant_path)
                                next
                        end

                        # entry_descendant_path 为ruby文件的完整绝对路径
                        entry_descendant_pathname = Pathname.new(entry_descendant_path)

                        # 获得 modules 的二级目录名称, cmd/cisco 中的cisco
                        # 或者 input/style 中的style
                        base, _i = entry_descendant_pathname.split
                        _i, module_layer_2 = base.split
                        module_layer_2 = module_layer_2.to_s

                        # 查询是否有效并且取得模块的类名
                        module_klass_name = get_module_klass_name(entry_descendant_pathname)
                        if module_klass_name.empty?
                                next
                        end

                        # 获得参考名
                        relative_entry_descendant_pathname = entry_descendant_pathname.relative_path_from(full_entry_pathname)
                        _i, relative_entry_descendant_pathname = relative_entry_descendant_pathname.split
                        relative_entry_descendant_path = relative_entry_descendant_pathname.to_s
                        module_reference_name = module_reference_name_from_path(relative_entry_descendant_path)

                        module_reference_name = [module_type, module_layer_2, module_reference_name].join("/")
                        yield entry_descendant_path, module_type, module_layer_2, module_reference_name, module_klass_name
                end

        end
end
get_module_klass_name(full_path) click to toggle source

取模块的类名,以便以后调用

# File lib/aio/core/module_loader.rb, line 84
def get_module_klass_name(full_path)
        fo = File.open(full_path)
        fo.each_line do |l|
                l = Aio::Base::Toolkit::String.safe(l)
                klass_name = Reg_klass_filter.match(l)
                if klass_name == nil
                        next
                end
                klass_name = klass_name[1].strip
                return klass_name
        end
        return ""
end
load_module(full_module_path, module_type,module_layer_2, module_reference_name, module_klass_name, opts={}) click to toggle source

真正加载处 并将模块全部实例化

# File lib/aio/core/module_loader.rb, line 134
def load_module(full_module_path, module_type,module_layer_2, module_reference_name, module_klass_name, opts={})

        begin
                require "#{full_module_path}"
                module_klass = ::Object::const_get(module_klass_name).new
        rescue Exception
                puts "[-]   Can not load module: #{full_module_path}"
                #puts caller
                return
        end
        @module_manager.add_module(full_module_path, module_type, module_layer_2, module_reference_name, module_klass)

        # 计数
        # count_by_module_type = {"cmd" => { "cisco" => 2 }, "input" => { "style" => 1 } }
        count_by_module_type = opts[:count_by_module_type]
        if count_by_module_type
                if !count_by_module_type[module_type]
                        count_by_module_type[module_type] = {}
                end

                count_by_module_type[module_type][module_layer_2] ||= 0
                count_by_module_type[module_type][module_layer_2] += 1
        end
end
load_modules(path, opts={}) click to toggle source

全局加载模块

# File lib/aio/core/module_loader.rb, line 111
def load_modules(path, opts={})
        count_by_module_type = {}

        each_module_reference_name(path, opts={}) do |full_module_path, module_type, module_layer_2, module_reference_name, module_klass_name|
                load_module(full_module_path, 
                                                                module_type,
                                                                module_layer_2,
                                                                module_reference_name,
                                                                module_klass_name,
                                                                {
                                #                                 :recalcuate_by_device_type => recalculate_by_device_type,
                                                                        :count_by_module_type => count_by_module_type,
                                                                }
                )
                                                                        
        end
        module_manager.notify({
                :count_by_module_type => count_by_module_type,
        })
end
module_reference_name_from_path(path) click to toggle source
# File lib/aio/core/module_loader.rb, line 98
def module_reference_name_from_path(path)
        path.gsub(Reg_ruby_file, '')
end
modules_path() click to toggle source

获取modules的路径

# File lib/aio/core/module_loader.rb, line 166
def modules_path
  self.class.modules_path
end
vaild_ruby_file?(path) click to toggle source

是否是有效的Ruby文件

# File lib/aio/core/module_loader.rb, line 103
def vaild_ruby_file?(path)
        if Reg_ruby_file.match(path)
                return true
        end
        return false
end