require 'iowa/dispatchers/StandardDispatcher' require 'iowa/classifier' module Iowa module Dispatchers # This is the same as the StandardDispatcher except that it uses a trie # based classifier instead of a hash for the simple matches. # Syntax for defining a map file is the same as the StandardDispatcher, # as well, except that order matters when passing the arguments to the # Classifier. The change in syntax to accomodate that is just to put # the :map elements into an array, as an array of hashes, instead of as # a single hash. For example, instead of this: # # /: A # /funds: B # /funds/: C # /funds/portfolio.html: D # # Do this: # # - /: A # - /funds: B # - /funds/: C # - /funds/portfolio.html: D # class StandardDispatcherWithClassifier < Iowa::Dispatchers::StandardDispatcher def initialize(*args) @mutex = Mutex.new @mapfileMTime = Time.at(1) @next_check = Time.at(1) if args[0].respond_to?(:[]) if args[0].kind_of?(::Hash) oargs = args[0] args = Iowa::Hash.new args.step_merge!(oargs) end args.stringify_keys! if args.respond_to? :stringify_keys! @mapfile = args[Cmapfile].to_s != '' ? args[Cmapfile] : nil @poll_interval = args['poll_interval'] ? args['poll_interval'] : 30 @path_map = populate_classifier(args['map'] || []) @rewrites = RuleSet.new(args['rewrites'] || []) @secondary_rewrites = RuleSet.new(args['secondary_rewrites'] || []) else @mapfile = args[0] @poll_interval = args[1] ? args[1] : 30 @path_map = populate_classifier(args[2] || []) @rewrites = RuleSet.new(args[3] || []) @secondary_rewrites = RuleSet.new(args[4] || []) end raise(NoMapFile, "The mapfile (#{@mapfile}) does not appear to exist.") if !FileTest.exist?(@mapfile.to_s) if @mapfile @mapfile ||= 'mapfile.map' if FileTest.exist?('mapfile.map') check_mapfile @mapfile end def populate_classifier(args) cl = Iowa::Classifier.new args.each do |arghash| next unless arghash.respond_to?(:each_pair) arghash.each_pair {|k,v| cl[k] = v} end cl end def load_mapfile raw_data = {} File.open(@mapfile) do |mf| rd = YAML::load(mf) break unless rd.respond_to?(:has_key?) raw_data = Iowa::Hash.new raw_data.step_merge!(rd) raw_data.symbolify_keys! rs = raw_data.has_key?(:rewrites) ? raw_data[:rewrites] : [] @rewrites = RuleSet.new(rs) rs = (raw_data.respond_to?(:[]) and raw_data.has_key?(:secondary_rewrites)) ? raw_data[:secondary_rewrites] : [] @secondary_rewrites = RuleSet.new(rs) @path_map = (raw_data.respond_to?(:[]) and raw_data.has_key?(:map)) ? populate_classifier(raw_data[:map]) : [] if raw_data.respond_to?(:delete) raw_data.delete(:rewrites) raw_data.delete(:secondary_rewrites) raw_data.delete(:map) end raw_data.each {|k,v| @path_map[k] = v if (k.class.is_a?(String) and v.class.is_a?(String))} @mapfileMTime = mf.mtime end end end end end