module Icss::ReceiverModel::ActsAsCatalog::ClassMethods

Public Class Methods

extended(base) click to toggle source

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

all(name='*') click to toggle source

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
find(name_or_find_type, name='*') click to toggle source

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
first(name='*') click to toggle source
# File lib/icss/receiver_model/acts_as_catalog.rb, line 72
def first(name='*')
  find(:first, name)
end
last(name='*') click to toggle source
# File lib/icss/receiver_model/acts_as_catalog.rb, line 76
def last(name='*')
  find(:last, name)
end
load_from_catalog(fullname) click to toggle source
# 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
register(obj) click to toggle source

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

catalog_filenames(filename='*',catalog_sections_arg=:default) click to toggle source

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
find_in_registry(name, args={}) click to toggle source

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
flush_registry() click to toggle source
# File lib/icss/receiver_model/acts_as_catalog.rb, line 168
def flush_registry
  registry.clear
end
load_catalog(flush=false) click to toggle source

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(name, args={}) click to toggle source

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