# coding: utf-8 module UzuUzu # # # class Application # attr_accessor :name # attr_accessor :config_file # attr_accessor :environments # attr_accessor :controllers # attr_accessor :before_filters # attr_accessor :after_filters # attr_accessor :helpers # attr_accessor :views # attr_accessor :servicies # # # def self.current ::Thread.current[:application] end # # # def initialize(options={}) ::Thread.current[:application] = self options.each do |key, value| case(key) when :name, 'name' @name = value when :config, 'config' @config_file = value end end if options.kind_of?(Hash) @name ||= :uzuuzu @environments = Environments.new(@config_file) ::UzuUzu.apps[@name] = self yield self if block_given? end # initialize def self.controllers @@controllers ||= [Controller] end def controllers @controllers ||= self.class.controllers.clone end def self.before_filters @@before_filters ||= [Controller.method(:before_all)] end def before_filters @before_filters ||= self.class.before_filters.clone end def self.after_filters @@after_filters ||= [Controller.method(:after_all)] end def after_filters @after_filters ||= self.class.after_filters.clone end def self.helpers @@helpers ||= [ Helper::Controller, Helper::Form, Helper::Jquery, Helper::Localize, Helper::Renderer, Helper::Route, Helper::XHtml ] end def helpers @helpers ||= self.class.helpers.clone end def self.views @@views ||= ['./view'] end def views @views ||= self.class.views.clone end def self.services @@services ||= [] end def services @services ||= self.class.services.clone end # # # def call(env) Thread.current[:application] = self request = UzuUzu::Request.new(env) response = UzuUzu::Response.new clazz = find_controller(env) if clazz.blank? di_thread(request, response, nil, nil, nil, nil, nil) return not_found(response) end is_send = false action_return = nil render = nil clazz.reverse.each do |map| controller_class = map[:clazz] query = map[:query] route = map[:route] controller = controller_class.new helper = Helper::Helper.new include_helper(helper) action, query = find_action(controller, query) di_thread(request, response, controller, helper, action, query, route) next if action.blank? is_send = true action_return = send_action(request, response, controller, action, query) if response.body.blank? render = helper.render(action) end break end unless is_send return not_found(response) end if response.status == 200 and response.body.blank? response.write render || action_return end response.finish end # call # # # def find_controller(env) classies = [] request_paths = env['PATH_INFO'].split('/') request_paths.shift if request_paths[0].blank? controllers.each do |c| if request_paths.size == 0 add_classies(classies, c, 'Index', env['SCRIPT_NAME'], request_paths) end request_paths.each_with_index do |request_path, index| next if request_path.blank? c_str = request_path.camel_case route = "#{request_paths[0...index].join('/')}" if route.blank? route = "#{env['SCRIPT_NAME']}" else route = "#{env['SCRIPT_NAME']}/#{route}" end query = request_paths[index..-1] add_classies(classies, c, 'Index', route, query) next if c_str == 'Index' route = "#{env['SCRIPT_NAME']}/#{request_paths[0..index].join('/')}" query = request_paths[(index+1)..-1] _c = add_classies(classies, c, c_str, route, query) if _c c = _c else break end end end classies end # find_controller def add_classies(classies, c, c_str, route, query) _c = nil begin if c.const_defined?(c_str) _c = c.const_get(c_str) classies << {:clazz => _c, :route => route, :query => query} elsif c.const_defined?("#{c_str}Controller") classies << {:clazz => c.const_get("#{c_str}Controller"), :route => route, :query => query} end rescue NameError => e end _c end # # # def include_helper(helper) helpers.each do |h| helper.extend(h) end end # include_helper # # # def di_thread(request, response, controller, helper, action, query, route) current = ::Thread.current current[:request] = request current[:response] = response current[:controller] = controller current[:helper] = helper current[:action] = action current[:query] = query current[:route] = route end # di_thread # # # def find_action(controller, query) action = nil index_flag = false query[-1] = query[-1].sub(/\.\w+$/, '') if query && query[-1] if query[0] && controller.respond_to?(query[0]) action = query.shift end if action.nil? && controller.respond_to?(:index) action = 'index' end unless action.nil? arity = controller.method(action).arity owner = controller.method(action).owner unless controller.method(action).owner == controller.class index_flag = true if controller.respond_to?(:use_actions) controller.actions.each do |use_action| if use_action.to_s == action.to_s index_flag = false end end end end unless (arity >= 0 && query.size == arity) || (arity < 0 && query.size >= ((-1 * arity)-1)) index_flag = true end if index_flag && !(action == 'index') && controller.respond_to?(:index) query.unshift(action) action = 'index' end if controller.respond_to?(action) arity = controller.method(action).arity unless (arity >= 0 && query.size == arity) || (arity < 0 && query.size >= ((-1 * arity)-1)) action = nil end else action = nil end end [action, query] end # find_action # # # def send_action(request, response, controller, action, query) value = nil catch(:finish) do before_filters.each do |filter| filter.call if filter.respond_to?(:call) end controller.send(:before) if controller.respond_to?(:before) controller.send("before_#{action}") if controller.respond_to?("before_#{action}") value = controller.send(action, *query) end catch(:finish) do controller.send("after_#{action}") if controller.respond_to?("after_#{action}") end catch(:finish) do controller.send(:after) if controller.respond_to?(:after) end after_filters.reverse.each do |filter| catch(:finish) do filter.call if filter.respond_to?(:call) end end value end # send_action def not_found(response) catch(:finish) do response.redirect("/error/404") end response.finish end end # Application end # UzuUzu