lib/merb/merb_dispatcher.rb in merb-0.3.4 vs lib/merb/merb_dispatcher.rb in merb-0.3.7

- old
+ new

@@ -9,35 +9,40 @@ @@use_mutex = val end @@mutex = Mutex.new @@use_mutex = ::Merb::Server.use_mutex - # This is where we grab the incoming request REQUEST_URI - # and use that in the merb routematcher to determine - # which controller and method to run. - # returns a 2 element tuple of: - # [controller, action] + # This is where we grab the incoming request REQUEST_URI and use that in + # the merb RouteMatcher to determine which controller and method to run. + # Returns a 2 element tuple of: [controller, action] def handle(request, response) - request_uri = request.params[Mongrel::Const::REQUEST_URI] + start = Time.now + + request_uri = request.params[Merb::Const::REQUEST_URI] request_uri.sub!(path_prefix, '') if path_prefix route = route_path(request_uri) allowed = route.delete(:allowed) rest = route.delete(:rest) + namespace = route.delete(:namespace) + + cont = namespace ? "#{namespace}/#{route[:controller]}" : route[:controller] + + klass = resolve_controller(cont) + controller = klass.build(request.body, request.params, route, response) - controller = instantiate_controller(route[:controller], request.body, request.params, route, response) - if rest method = controller.request.method if allowed.keys.include?(method) && action = allowed[method] controller.params[:action] = action else - raise Merb::RestfulMethodNotAllowed.new(method, allowed) + raise Merb::HTTPMethodNotAllowed.new(method, allowed) end else action = route[:action] end + controller._benchmarks[:setup_time] = Time.now - start if @@use_mutex @@mutex.synchronize { controller.dispatch(action) } else @@ -50,23 +55,26 @@ path = path.sub(/\/+/, '/').sub(/\?.*$/, '') path = path[0..-2] if (path[-1] == ?/) && path.size > 1 Merb::Router.match(path) end - # take a controller class name string and reload or require - # the right controller file then CamelCase it and turn it - # into a new object passing in the request and response. - # this is where your Merb::Controller is instantiated. - def instantiate_controller(controller_name, req, env, params, res) - if !File.exist?(DIST_ROOT+"/app/controllers/#{controller_name.snake_case}.rb") - raise "Bad controller! #{controller_name.snake_case}" + # Take a controller class name string and reload or require the right + # controller file then CamelCase it and return the class object. + def resolve_controller(controller_name) + segments = controller_name.split('/').map{|s| s.snake_case} + path = "#{DIST_ROOT}/app/controllers/#{controller_name}.rb" + cnt = segments.map{|s| s.camel_case }.join('::') + + if !File.exist?(path) + raise "Bad controller! #{cnt}" end unless $TESTING + begin - unless MERB_ENV == 'production' - Object.send(:remove_const, controller_name.camel_case.intern) rescue nil - load(controller_name.snake_case + '.rb') + if MERB_ENV == 'development' + Object.send(:remove_const, cnt) rescue nil + load(path) end - return Object.const_get( controller_name.camel_case ).new(req, env, params, res) + return Object.full_const_get(cnt) rescue RuntimeError warn "Error getting instance of '#{controller_name.camel_case}': #{$!}" raise $! end end \ No newline at end of file