Class: Anorexic::Route

Inherits:
Object
  • Object
show all
Defined in:
lib/anorexic/handlers/route.rb

Overview

this class holds the route and matching logic that will normally be used for HTTP handling it is used internally and documentation is present for development and edge users.

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(path, controller, params = {}, &block) ⇒ Route

the initialize method accepts a Regexp or a String and creates the path object.

Regexp paths will be left unchanged

a string can be either a simple string `“/users”` or a string with paramaters: `“/static/:required/(:optional)/(:optional_with_format)[d]*/:optional_2”`


60
61
62
63
64
# File 'lib/anorexic/handlers/route.rb', line 60

def initialize path, controller, params={}, &block
	@path_sections , @params = false, params
	initialize_path path
	initialize_controller controller, block
end

Instance Attribute Details

#controllerObject (readonly)

the controller that answers the request on this path (if exists).


9
10
11
# File 'lib/anorexic/handlers/route.rb', line 9

def controller
  @controller
end

#paramsObject (readonly)

the parameters for the router and service that were used to create the service, router and host.


13
14
15
# File 'lib/anorexic/handlers/route.rb', line 13

def params
  @params
end

#pathObject (readonly)

the Regexp that will be used to match the request.


7
8
9
# File 'lib/anorexic/handlers/route.rb', line 7

def path
  @path
end

#procObject (readonly)

the proc that answers the request on this path (if exists).


11
12
13
# File 'lib/anorexic/handlers/route.rb', line 11

def proc
  @proc
end

Instance Method Details

#call(request) ⇒ Object

handles Rack requests (dresses up as Rack).


37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
# File 'lib/anorexic/handlers/route.rb', line 37

def call request
	fill_paramaters = match request.path_info
	return false unless fill_paramaters
	fill_paramaters.each {|k,v| HTTP.add_param_to_hash k, v, request.params }
	response = HTTPResponse.new request
	if controller
		ret = controller.new(request, response, params)._route_path_to_methods_and_set_the_response_
		return response if ret
	elsif proc
		ret = proc.call(request, response)
		return response if ret
	elsif controller == false
		request.path_info = path.match(request.path_info).to_a.last
	end
	return false
end

#initialize_controller(controller, block) ⇒ Object

initializes the controller, by inheriting the class into an Anorexic controller subclass (with the Anorexic::ControllerMagic injected).

Proc objects are currently passed through without any change - as Proc routes are assumed to handle themselves correctly.


70
71
72
73
74
75
76
# File 'lib/anorexic/handlers/route.rb', line 70

def initialize_controller controller, block
	@controller, @proc = controller, block
	if controller.is_a?(Class)
		# add controller magic
		@controller = self.class.make_controller_magic controller
	end
end

#initialize_path(path) ⇒ Object

initializes the path by converting the string into a Regexp and noting any parameters that might need to be extracted for RESTful routes.


80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
# File 'lib/anorexic/handlers/route.rb', line 80

def initialize_path path
	@fill_paramaters = {}
	if path.is_a? Regexp
		@path = path
	elsif path.is_a? String
		# prep used prameters
		param_num = 0
		section_search = "([\\/][^\\/]*)"
		optional_section_search = "([\\/][^\\/]*)?"
		@path = '^'

		# prep path string
		# path = path.gsub(/(^\/)|(\/$)/, '')

		# scan for the '/' divider
		# (split path string only when the '/' is not inside a {} regexp)
		# level = 0
		# scn = StringScanner.new(path)
		# while scn.matched != ''
		# 	scn.scan_until /[^\\][\/\{\}]|$/
		# 	case scn.matched
		# 	when '{'
		# 		level += 1
		# 	when '}'
		# 		level -= 1
		# 	when '/'
		# 		split_pos ||= []
		# 		split_pos << scn.pos if level == 0
		# 	end
		# end

		# prep path string and split it where the '/' charected is unescaped.
		path = path.gsub(/(^\/)|(\/$)/, '').gsub(/([^\\])\//, '\1 - /').split ' - /'
		@path_sections = path.length
		path.each do |section|
			if section == '*'
				# create catch all
				@path << "(.*)"
				# finish
				@path = /#{@path}$/
				return

			# check for routes formatted: /:paramater - required paramaters
			elsif section.match /^\:([^\(\)\{\}\:]*)$/
				#create a simple section catcher
			 	@path << section_search
			 	# add paramater recognition value
			 	@fill_paramaters[param_num += 1] = section.match(/^\:([^\(\)\{\}\:]*)$/)[1]

			# check for routes formatted: /:paramater{regexp} - required paramaters
			elsif section.match /^\:([^\(\)\{\}\:\/]*)\{(.*)\}$/
				#create a simple section catcher
			 	@path << (  "(\/(" +  section.match(/^\:([^\(\)\{\}\:\/]*)\{(.*)\}$/)[2] + "))"  )
			 	# add paramater recognition value
			 	@fill_paramaters[param_num += 1] = section.match(/^\:([^\(\)\{\}\:\/]*)\{(.*)\}$/)[1]
			 	param_num += 1 # we are using two spaces

			# check for routes formatted: /(:paramater) - optional paramaters
			elsif section.match /^\(\:([^\(\)\{\}\:]*)\)$/
				#create a optional section catcher
			 	@path << optional_section_search
			 	# add paramater recognition value
			 	@fill_paramaters[param_num += 1] = section.match(/^\(\:([^\(\)\{\}\:]*)\)$/)[1]

			# check for routes formatted: /(:paramater){regexp} - optional paramaters
			elsif section.match /^\(\:([^\(\)\{\}\:]*)\)\{(.*)\}$/
				#create a optional section catcher
			 	@path << (  "(\/(" +  section.match(/^\(\:([^\(\)\{\}\:]*)\)\{(.*)\}$/)[2] + "))?"  )
			 	# add paramater recognition value
			 	@fill_paramaters[param_num += 1] = section.match(/^\(\:([^\(\)\{\}\:]*)\)\{(.*)\}$/)[1]
			 	param_num += 1 # we are using two spaces

			else
				@path << "\/"
				@path << section
			end
		end
		unless @fill_paramaters.values.include?("id")
			@path << optional_section_search
			@fill_paramaters[param_num += 1] = "id"
		end
		@path = /#{@path}$/
	else
		raise "Path cannot be initialized - path must be either a string or a regular experssion."
	end	
	return
end

#match(path) ⇒ Object

this performs the match and assigns the paramaters, if required.


169
170
171
172
173
174
175
176
177
178
179
180
181
182
# File 'lib/anorexic/handlers/route.rb', line 169

def match path
	hash = {}
	m = nil
	# unless @fill_paramaters.values.include?("format")
	# 	if (m = path.match /([^\.]*)\.([^\.\/]+)$/)
	# 		HTTP.add_param_to_hash 'format', m[2], hash
	# 		path = m[1]
	# 	end
	# end
	m = @path.match path
	return false unless m
	@fill_paramaters.each { |k, v| hash[v] = m[k][1..-1] if m[k] && m[k] != '/' }
	hash
end

#on_request(request) ⇒ Object

lets the route answer the request. returns false if no response has been sent.


16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
# File 'lib/anorexic/handlers/route.rb', line 16

def on_request request
	fill_paramaters = match request.path
	return false unless fill_paramaters
	fill_paramaters.each {|k,v| HTTP.add_param_to_hash k, v, request.params }
	response = HTTPResponse.new request
	if controller
		ret = controller.new(request, response, params)._route_path_to_methods_and_set_the_response_
		response.try_finish if ret
		return ret
	elsif proc
		ret = proc.call(request, response)
		# response << ret if ret.is_a?(String)
		response.try_finish if ret
		return ret
	elsif controller == false
		request.path = path.match(request.path).to_a.last
	end
	return false
end