module Icss::ReceiverModel::ActsAsCatalog::ClassMethods
Public Class Methods
Include ActAsLoadable for file receivers Declare and initialize registry class/module variable to hash Set after_receiver(:register) for classes to register their objects
# File lib/icss/receiver_model/acts_as_catalog.rb, line 35 def self.extended(base) base.class_eval do if is_a?(Class) include Icss::ReceiverModel::ActsAsLoadable::ClassMethods class_attribute :registry class_attribute :_catalog_loaded after_receive(:register) do |hsh| register(self) end elsif is_a?(Module) mattr_accessor :registry mattr_accessor :_catalog_loaded end self.registry = Hash.new end end
Public Instance Methods
Basic ActiveRecord inspired methods Name can include wildcards(*) for simple searching
- example: geo.*.location.* matches anything with a namespace starting with 'geo' and containing 'location'
# File lib/icss/receiver_model/acts_as_catalog.rb, line 68 def all(name='*') find(:all, name) end
ActiveRecord inspired find method Params:
1. :all, :first, :last, or registry identifier(ignores wildcards to force exact match) 2. registry name with wildcards(*) - example: geo.*.location.*
# File lib/icss/receiver_model/acts_as_catalog.rb, line 88 def find(name_or_find_type, name='*') if !self._catalog_loaded self._catalog_loaded = true load_catalog(true) end method_name = case name_or_find_type when :all then :to_a when :first then :first when :last then :last else # If exact match not in registry, try looking in file catalog result = (find_in_registry(name_or_find_type, :exact_match => true) || load_files_from_catalog(name_or_find_type, :exact_match => true)) raise Icss::NotFoundError, "Cannot find #{name_or_find_type}" if result.nil? return result end # If not in registry, try looking in file catalog (find_in_registry(name) || load_files_from_catalog(name)).send method_name end
# File lib/icss/receiver_model/acts_as_catalog.rb, line 72 def first(name='*') find(:first, name) end
# File lib/icss/receiver_model/acts_as_catalog.rb, line 76 def last(name='*') find(:last, name) end
# File lib/icss/receiver_model/acts_as_catalog.rb, line 109 def load_from_catalog(fullname) filepath = fullname.to_s.gsub(/(\.icss\.yaml)?$/,'').gsub(/\./, '/') filenames = catalog_filenames(filepath, ['']) filenames.map{|filename| receive_from_file(filename) }.compact end
Add object to registry using fullname method as the identifier
# File lib/icss/receiver_model/acts_as_catalog.rb, line 56 def register(obj) registry[obj.fullname] = obj end
Private Instance Methods
Expand filenames to full paths using catalog_root, catalog_sections, and provided filename modded by JD: 8/17/16 to fix ruby 2.2+ issue with circular reference arguments
# File lib/icss/receiver_model/acts_as_catalog.rb, line 152 def catalog_filenames(filename='*',catalog_sections_arg=:default) catalog_sections_arg = catalog_sections if catalog_sections_arg == :default catalog_sections_arg.collect{ |section| Dir[File.join(Settings[:catalog_root], section, filename + '.icss.yaml')] }.flatten end
Search registry for matching objects Return single object for exact_match=true
# File lib/icss/receiver_model/acts_as_catalog.rb, line 120 def find_in_registry(name, args={}) return registry[name] if args.symbolize_keys[:exact_match] name = name.to_s.gsub('*', '[^\./]*').gsub(/\.\//, '\.').gsub(/\*$/, '.+') if name.include?('*') name_regexp = Regexp.new("^#{name}$", true) registry.select{|k, v| k.match(name_regexp) }.values end
# File lib/icss/receiver_model/acts_as_catalog.rb, line 168 def flush_registry registry.clear end
Conditional empty registry and load all found files
# File lib/icss/receiver_model/acts_as_catalog.rb, line 163 def load_catalog(flush=false) flush_registry if flush load_files_from_catalog('*') end
Load files from catalog files Namespaces used to correspond to directories Load single file for exact_match=true
# File lib/icss/receiver_model/acts_as_catalog.rb, line 133 def load_files_from_catalog(name, args={}) # don't do anything if name is invalid format if args.symbolize_keys[:exact_match] filename = catalog_filenames(name.to_s.gsub(/\./, '/'))[0] receive_from_file(filename) if filename elsif /\A([A-Za-z_\*]\w*\.?)+\Z/ === name filename = name.to_s.gsub(/(\.icss\.yaml)?$/,'').gsub(/\./, '/').gsub(/\*$/, '**/*') filenames = catalog_filenames(filename) filenames.collect{|filename| receive_from_file(filename) } unless filenames.empty? end # Return object/s from registry after loading files # Useful for unexpected file contents / protocols containing many types find_in_registry(name, args) end