tennpipes-base 3.6.6
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/LICENSE.txt +20 -0
- data/README.rdoc +294 -0
- data/Rakefile +1 -0
- data/bin/tennpipes +8 -0
- data/lib/tennpipes-base.rb +196 -0
- data/lib/tennpipes-base/application.rb +175 -0
- data/lib/tennpipes-base/application/application_setup.rb +202 -0
- data/lib/tennpipes-base/application/authenticity_token.rb +25 -0
- data/lib/tennpipes-base/application/flash.rb +229 -0
- data/lib/tennpipes-base/application/params_protection.rb +129 -0
- data/lib/tennpipes-base/application/routing.rb +1002 -0
- data/lib/tennpipes-base/application/show_exceptions.rb +50 -0
- data/lib/tennpipes-base/caller.rb +53 -0
- data/lib/tennpipes-base/cli/adapter.rb +33 -0
- data/lib/tennpipes-base/cli/base.rb +105 -0
- data/lib/tennpipes-base/cli/console.rb +20 -0
- data/lib/tennpipes-base/cli/launcher.rb +103 -0
- data/lib/tennpipes-base/cli/rake.rb +50 -0
- data/lib/tennpipes-base/cli/rake_tasks.rb +72 -0
- data/lib/tennpipes-base/command.rb +38 -0
- data/lib/tennpipes-base/ext/sinatra.rb +29 -0
- data/lib/tennpipes-base/filter.rb +52 -0
- data/lib/tennpipes-base/images/404.png +0 -0
- data/lib/tennpipes-base/images/500.png +0 -0
- data/lib/tennpipes-base/loader.rb +202 -0
- data/lib/tennpipes-base/logger.rb +492 -0
- data/lib/tennpipes-base/module.rb +58 -0
- data/lib/tennpipes-base/mounter.rb +308 -0
- data/lib/tennpipes-base/path_router.rb +119 -0
- data/lib/tennpipes-base/path_router/compiler.rb +110 -0
- data/lib/tennpipes-base/path_router/error_handler.rb +8 -0
- data/lib/tennpipes-base/path_router/matcher.rb +123 -0
- data/lib/tennpipes-base/path_router/route.rb +169 -0
- data/lib/tennpipes-base/reloader.rb +309 -0
- data/lib/tennpipes-base/reloader/rack.rb +26 -0
- data/lib/tennpipes-base/reloader/storage.rb +55 -0
- data/lib/tennpipes-base/router.rb +98 -0
- data/lib/tennpipes-base/server.rb +119 -0
- data/lib/tennpipes-base/tasks.rb +21 -0
- data/lib/tennpipes-base/version.rb +20 -0
- data/lib/tennpipes-base/version.rb~ +20 -0
- data/test/fixtures/app_gem/Gemfile +4 -0
- data/test/fixtures/app_gem/app/app.rb +3 -0
- data/test/fixtures/app_gem/app_gem.gemspec +17 -0
- data/test/fixtures/app_gem/lib/app_gem.rb +7 -0
- data/test/fixtures/app_gem/lib/app_gem/version.rb +3 -0
- data/test/fixtures/apps/complex.rb +32 -0
- data/test/fixtures/apps/demo_app.rb +7 -0
- data/test/fixtures/apps/demo_demo.rb +7 -0
- data/test/fixtures/apps/demo_project/api/app.rb +7 -0
- data/test/fixtures/apps/demo_project/api/lib/api_lib.rb +3 -0
- data/test/fixtures/apps/demo_project/app.rb +7 -0
- data/test/fixtures/apps/external_apps/fake_lib.rb +1 -0
- data/test/fixtures/apps/external_apps/fake_root.rb +2 -0
- data/test/fixtures/apps/helpers/class_methods_helpers.rb +4 -0
- data/test/fixtures/apps/helpers/instance_methods_helpers.rb +4 -0
- data/test/fixtures/apps/helpers/support.rb +1 -0
- data/test/fixtures/apps/helpers/system_helpers.rb +8 -0
- data/test/fixtures/apps/kiq.rb +3 -0
- data/test/fixtures/apps/lib/myklass.rb +2 -0
- data/test/fixtures/apps/lib/myklass/mysubklass.rb +4 -0
- data/test/fixtures/apps/models/child.rb +2 -0
- data/test/fixtures/apps/models/parent.rb +5 -0
- data/test/fixtures/apps/mountable_apps/rack_apps.rb +15 -0
- data/test/fixtures/apps/mountable_apps/static.html +1 -0
- data/test/fixtures/apps/precompiled_app.rb +19 -0
- data/test/fixtures/apps/simple.rb +32 -0
- data/test/fixtures/apps/static.rb +10 -0
- data/test/fixtures/apps/system.rb +13 -0
- data/test/fixtures/apps/system_class_methods_demo.rb +7 -0
- data/test/fixtures/apps/system_instance_methods_demo.rb +7 -0
- data/test/fixtures/dependencies/a.rb +9 -0
- data/test/fixtures/dependencies/b.rb +4 -0
- data/test/fixtures/dependencies/c.rb +1 -0
- data/test/fixtures/dependencies/circular/e.rb +13 -0
- data/test/fixtures/dependencies/circular/f.rb +2 -0
- data/test/fixtures/dependencies/circular/g.rb +2 -0
- data/test/fixtures/dependencies/d.rb +4 -0
- data/test/fixtures/reloadable_apps/external/app/app.rb +6 -0
- data/test/fixtures/reloadable_apps/external/app/controllers/base.rb +6 -0
- data/test/fixtures/reloadable_apps/main/app.rb +10 -0
- data/test/helper.rb +30 -0
- data/test/test_application.rb +185 -0
- data/test/test_core.rb +93 -0
- data/test/test_csrf_protection.rb +208 -0
- data/test/test_dependencies.rb +57 -0
- data/test/test_filters.rb +389 -0
- data/test/test_flash.rb +168 -0
- data/test/test_locale.rb +21 -0
- data/test/test_logger.rb +295 -0
- data/test/test_mounter.rb +302 -0
- data/test/test_params_protection.rb +195 -0
- data/test/test_reloader_complex.rb +74 -0
- data/test/test_reloader_external.rb +21 -0
- data/test/test_reloader_simple.rb +101 -0
- data/test/test_reloader_system.rb +113 -0
- data/test/test_restful_routing.rb +33 -0
- data/test/test_router.rb +281 -0
- data/test/test_routing.rb +2328 -0
- metadata +301 -0
@@ -0,0 +1,58 @@
|
|
1
|
+
module Tennpipes
|
2
|
+
module Module
|
3
|
+
attr_accessor :root
|
4
|
+
|
5
|
+
##
|
6
|
+
# Register this module as being loaded from a gem. This automatically
|
7
|
+
# sets the root and therefore the dependency paths correctly.
|
8
|
+
#
|
9
|
+
# @param [String] name
|
10
|
+
# The name of the gem. Has to be the name as stated in the gemspec.
|
11
|
+
#
|
12
|
+
# @returns the gems root.
|
13
|
+
def gem!(name)
|
14
|
+
self.root = Tennpipes.gem(name, self)
|
15
|
+
end
|
16
|
+
|
17
|
+
##
|
18
|
+
# Helper method for file references within a Tennpipes module.
|
19
|
+
#
|
20
|
+
# @param [Array<String>] args
|
21
|
+
# The directories to join to {Module.root}.
|
22
|
+
#
|
23
|
+
# @return [String]
|
24
|
+
# The absolute path.
|
25
|
+
#
|
26
|
+
# @example
|
27
|
+
# module MyModule
|
28
|
+
# extend Tennpipes::Module
|
29
|
+
# gem! 'my_gem'
|
30
|
+
# end
|
31
|
+
# Module.root!
|
32
|
+
def root(*args)
|
33
|
+
File.expand_path(File.join(@root, *args))
|
34
|
+
end
|
35
|
+
|
36
|
+
##
|
37
|
+
# Returns the list of path globs to load as dependencies.
|
38
|
+
# Appends custom dependency patterns to the be loaded for Tennpipes.
|
39
|
+
#
|
40
|
+
# @return [Array<String>]
|
41
|
+
# The dependency paths.
|
42
|
+
#
|
43
|
+
# @example
|
44
|
+
# module MyModule
|
45
|
+
# extend Tennpipes::Module
|
46
|
+
# gem! 'my_gem'
|
47
|
+
# end
|
48
|
+
#
|
49
|
+
# Module.dependency_paths << "#{MyModule.root}/uploaders/*.rb"
|
50
|
+
#
|
51
|
+
def dependency_paths
|
52
|
+
[
|
53
|
+
"#{root}/lib/**/*.rb", "#{root}/shared/lib/**/*.rb",
|
54
|
+
"#{root}/models/**/*.rb", "#{root}/shared/models/**/*.rb"
|
55
|
+
]
|
56
|
+
end
|
57
|
+
end
|
58
|
+
end
|
@@ -0,0 +1,308 @@
|
|
1
|
+
require 'delegate'
|
2
|
+
|
3
|
+
module Tennpipes
|
4
|
+
##
|
5
|
+
# Represents a particular mounted Tennpipes application.
|
6
|
+
# Stores the name of the application (app folder name) and url mount path.
|
7
|
+
#
|
8
|
+
# @example
|
9
|
+
# Mounter.new("blog_app", :app_class => "Blog").to("/blog")
|
10
|
+
# Mounter.new("blog_app", :app_file => "/path/to/blog/app.rb").to("/blog")
|
11
|
+
#
|
12
|
+
class Mounter
|
13
|
+
DEFAULT_CASCADE = [404, 405]
|
14
|
+
class MounterException < RuntimeError
|
15
|
+
end
|
16
|
+
|
17
|
+
class ApplicationWrapper < SimpleDelegator
|
18
|
+
attr_accessor :uri_root
|
19
|
+
attr_writer :public_folder
|
20
|
+
|
21
|
+
def initialize(app, options = {})
|
22
|
+
@options = options
|
23
|
+
super(app)
|
24
|
+
end
|
25
|
+
|
26
|
+
def dependencies
|
27
|
+
@__dependencies ||= Dir["#{root}/**/*.rb"]
|
28
|
+
end
|
29
|
+
|
30
|
+
def prerequisites
|
31
|
+
@__prerequisites ||= []
|
32
|
+
end
|
33
|
+
|
34
|
+
def app_file
|
35
|
+
return @__app_file if @__app_file
|
36
|
+
obj = __getobj__
|
37
|
+
@__app_file = obj.respond_to?(:app_file) ? obj.app_file : @options[:app_file]
|
38
|
+
end
|
39
|
+
|
40
|
+
def root
|
41
|
+
return @__root if @__root
|
42
|
+
obj = __getobj__
|
43
|
+
@__root = obj.respond_to?(:root) ? obj.root : File.expand_path("#{app_file}/../")
|
44
|
+
end
|
45
|
+
|
46
|
+
def public_folder
|
47
|
+
return @public_folder if @public_folder
|
48
|
+
obj = __getobj__
|
49
|
+
@public_folder = obj.respond_to?(:public_folder) ? obj.public_folder : ""
|
50
|
+
end
|
51
|
+
|
52
|
+
def app_name
|
53
|
+
@__app_name ||= @options[:app_name] || __getobj__.to_s.underscore.to_sym
|
54
|
+
end
|
55
|
+
|
56
|
+
def setup_application!
|
57
|
+
@configured ||=
|
58
|
+
begin
|
59
|
+
$LOAD_PATH.concat(prerequisites)
|
60
|
+
Tennpipes.require_dependencies(dependencies, :force => true) if root.start_with?(Tennpipes.root)
|
61
|
+
true
|
62
|
+
end
|
63
|
+
end
|
64
|
+
end
|
65
|
+
|
66
|
+
attr_accessor :name, :uri_root, :app_file, :app_class, :app_root, :app_obj, :app_host, :cascade
|
67
|
+
|
68
|
+
##
|
69
|
+
# @param [String, Tennpipes::Application] name
|
70
|
+
# The app name or the {Tennpipes::Application} class.
|
71
|
+
#
|
72
|
+
# @param [Hash] options
|
73
|
+
# @option options [Symbol] :app_class (Detected from name)
|
74
|
+
# @option options [Symbol] :app_file (Automatically detected)
|
75
|
+
# @option options [Symbol] :app_obj (Detected)
|
76
|
+
# @option options [Symbol] :app_root (Directory of :app_file)
|
77
|
+
# @option options [Symbol] :gem The gem to load the app from (Detected from name)
|
78
|
+
#
|
79
|
+
def initialize(name, options={})
|
80
|
+
@name = name.to_s
|
81
|
+
@app_class = options[:app_class] || @name.camelize
|
82
|
+
@gem = options[:gem] || @app_class.split("::").first.underscore
|
83
|
+
@app_file = options[:app_file] || locate_app_file
|
84
|
+
@app_obj = options[:app_obj] || app_constant || locate_app_object
|
85
|
+
ensure_app_file! || ensure_app_object!
|
86
|
+
@app_obj = ApplicationWrapper.new(@app_obj, options) unless tennpipes_application?
|
87
|
+
@app_root = options[:app_root] || (@app_obj.respond_to?(:root) && @app_obj.root || File.dirname(@app_file))
|
88
|
+
@uri_root = "/"
|
89
|
+
@cascade = options[:cascade] ? true == options[:cascade] ? DEFAULT_CASCADE.dup : Array(options[:cascade]) : []
|
90
|
+
Tennpipes::Reloader.exclude_constants << @app_class
|
91
|
+
end
|
92
|
+
|
93
|
+
def tennpipes_application?
|
94
|
+
@app_obj.ancestors.include?(Tennpipes::Application)
|
95
|
+
rescue NameError
|
96
|
+
false
|
97
|
+
end
|
98
|
+
|
99
|
+
##
|
100
|
+
# Registers the mounted application onto Tennpipes.
|
101
|
+
#
|
102
|
+
# @param [String] mount_url
|
103
|
+
# Path where we mount the app.
|
104
|
+
#
|
105
|
+
# @example
|
106
|
+
# Mounter.new("blog_app").to("/blog")
|
107
|
+
#
|
108
|
+
def to(mount_url)
|
109
|
+
@uri_root = mount_url
|
110
|
+
Tennpipes.insert_mounted_app(self)
|
111
|
+
self
|
112
|
+
end
|
113
|
+
|
114
|
+
##
|
115
|
+
# Registers the mounted application onto Tennpipes for the given host.
|
116
|
+
#
|
117
|
+
# @param [String] mount_host
|
118
|
+
# Host name.
|
119
|
+
#
|
120
|
+
# @example
|
121
|
+
# Mounter.new("blog_app").to("/blog").host("blog.tennpipes.org")
|
122
|
+
# Mounter.new("blog_app").host("blog.tennpipes.org")
|
123
|
+
# Mounter.new("catch_all").host(/.*\.tennpipes.org/)
|
124
|
+
#
|
125
|
+
def host(mount_host)
|
126
|
+
@app_host = mount_host
|
127
|
+
Tennpipes.insert_mounted_app(self)
|
128
|
+
self
|
129
|
+
end
|
130
|
+
|
131
|
+
##
|
132
|
+
# Maps Tennpipes application onto a Tennpipes::Router.
|
133
|
+
# For use in constructing a Rack application.
|
134
|
+
#
|
135
|
+
# @param [Tennpipes::Router]
|
136
|
+
#
|
137
|
+
# @return [Tennpipes::Router]
|
138
|
+
#
|
139
|
+
# @example
|
140
|
+
# @app.map_onto(router)
|
141
|
+
#
|
142
|
+
def map_onto(router)
|
143
|
+
app_data = self
|
144
|
+
app_obj = @app_obj
|
145
|
+
if tennpipes_application?
|
146
|
+
app_obj.set :uri_root, app_data.uri_root
|
147
|
+
app_obj.set :app_name, app_data.app_obj.app_name.to_s
|
148
|
+
app_obj.set :app_file, app_data.app_file unless File.exist?(app_obj.app_file)
|
149
|
+
app_obj.set :root, app_data.app_root unless app_data.app_root.blank?
|
150
|
+
app_obj.set :public_folder, Tennpipes.root('public', app_data.uri_root) unless File.exist?(app_obj.public_folder)
|
151
|
+
app_obj.set :static, File.exist?(app_obj.public_folder) if app_obj.nil?
|
152
|
+
app_obj.set :cascade, app_data.cascade
|
153
|
+
else
|
154
|
+
app_obj.uri_root = app_data.uri_root
|
155
|
+
app_obj.public_folder = Tennpipes.root('public', app_data.uri_root) unless File.exist?(app_obj.public_folder)
|
156
|
+
end
|
157
|
+
app_obj.setup_application! # Initializes the app here with above settings.
|
158
|
+
router.map(:to => app_obj, :path => app_data.uri_root, :host => app_data.app_host)
|
159
|
+
end
|
160
|
+
|
161
|
+
###
|
162
|
+
# Returns the route objects for the mounted application.
|
163
|
+
#
|
164
|
+
def routes
|
165
|
+
app_obj.routes
|
166
|
+
end
|
167
|
+
|
168
|
+
###
|
169
|
+
# Returns the basic route information for each named route.
|
170
|
+
#
|
171
|
+
# @return [Array]
|
172
|
+
# Array of routes.
|
173
|
+
#
|
174
|
+
def named_routes
|
175
|
+
app_obj.routes.map { |route|
|
176
|
+
route_name = route.name.to_s
|
177
|
+
route_name =
|
178
|
+
if route.controller
|
179
|
+
route_name.split(" ", 2).map{|name| ":#{name}" }.join(", ")
|
180
|
+
else
|
181
|
+
":#{route_name}"
|
182
|
+
end
|
183
|
+
name_array = "(#{route_name})"
|
184
|
+
request_method = route.request_methods.first
|
185
|
+
next if route.name.blank? || request_method == 'HEAD'
|
186
|
+
original_path = route.original_path.is_a?(Regexp) ? route.original_path.inspect : route.original_path
|
187
|
+
full_path = File.join(uri_root, original_path)
|
188
|
+
OpenStruct.new(:verb => request_method, :identifier => route.name, :name => name_array, :path => full_path)
|
189
|
+
}.compact
|
190
|
+
end
|
191
|
+
|
192
|
+
##
|
193
|
+
# Makes two Mounters equal if they have the same name and uri_root.
|
194
|
+
#
|
195
|
+
# @param [Tennpipes::Mounter] other
|
196
|
+
#
|
197
|
+
def ==(other)
|
198
|
+
other.is_a?(Mounter) && self.app_class == other.app_class && self.uri_root == other.uri_root
|
199
|
+
end
|
200
|
+
|
201
|
+
##
|
202
|
+
# @return [Tennpipes::Application]
|
203
|
+
# the class object for the app if defined, nil otherwise.
|
204
|
+
#
|
205
|
+
def app_constant
|
206
|
+
klass = Object
|
207
|
+
for piece in app_class.split("::")
|
208
|
+
piece = piece.to_sym
|
209
|
+
if klass.const_defined?(piece, false)
|
210
|
+
klass = klass.const_get(piece)
|
211
|
+
else
|
212
|
+
return
|
213
|
+
end
|
214
|
+
end
|
215
|
+
klass
|
216
|
+
end
|
217
|
+
|
218
|
+
protected
|
219
|
+
##
|
220
|
+
# Locates and requires the file to load the app constant.
|
221
|
+
#
|
222
|
+
def locate_app_object
|
223
|
+
@_app_object ||= begin
|
224
|
+
ensure_app_file!
|
225
|
+
Tennpipes.require_dependencies(app_file)
|
226
|
+
app_constant
|
227
|
+
end
|
228
|
+
end
|
229
|
+
|
230
|
+
##
|
231
|
+
# Returns the determined location of the mounted application main file.
|
232
|
+
#
|
233
|
+
def locate_app_file
|
234
|
+
candidates = []
|
235
|
+
candidates << app_constant.app_file if app_constant.respond_to?(:app_file) && File.exist?(app_constant.app_file.to_s)
|
236
|
+
candidates << Tennpipes.first_caller if File.identical?(Tennpipes.first_caller.to_s, Tennpipes.called_from.to_s)
|
237
|
+
candidates << Tennpipes.mounted_root(name.downcase, "app.rb")
|
238
|
+
simple_name = name.split("::").last.downcase
|
239
|
+
mod_name = name.split("::")[0..-2].join("::")
|
240
|
+
Tennpipes.modules.each do |mod|
|
241
|
+
if mod.name == mod_name
|
242
|
+
candidates << mod.root(simple_name, "app.rb")
|
243
|
+
end
|
244
|
+
end
|
245
|
+
candidates << Tennpipes.root("app", "app.rb")
|
246
|
+
candidates.find { |candidate| File.exist?(candidate) }
|
247
|
+
end
|
248
|
+
|
249
|
+
###
|
250
|
+
# Raises an exception unless app_file is located properly.
|
251
|
+
#
|
252
|
+
def ensure_app_file!
|
253
|
+
message = "Unable to locate source file for app '#{app_class}', try with :app_file => '/path/app.rb'"
|
254
|
+
raise MounterException, message unless @app_file
|
255
|
+
end
|
256
|
+
|
257
|
+
###
|
258
|
+
# Raises an exception unless app_obj is defined properly.
|
259
|
+
#
|
260
|
+
def ensure_app_object!
|
261
|
+
message = "Unable to locate app for '#{app_class}', try with :app_class => 'MyAppClass'"
|
262
|
+
raise MounterException, message unless @app_obj
|
263
|
+
end
|
264
|
+
end
|
265
|
+
|
266
|
+
class << self
|
267
|
+
attr_writer :mounted_root # Set root directory where tennpipes searches mounted apps
|
268
|
+
|
269
|
+
##
|
270
|
+
# @param [Array] args
|
271
|
+
#
|
272
|
+
# @return [String]
|
273
|
+
# the root to the mounted apps base directory.
|
274
|
+
#
|
275
|
+
def mounted_root(*args)
|
276
|
+
Tennpipes.root(@mounted_root ||= "", *args)
|
277
|
+
end
|
278
|
+
|
279
|
+
##
|
280
|
+
# @return [Array]
|
281
|
+
# the mounted tennpipes applications (MountedApp objects)
|
282
|
+
#
|
283
|
+
def mounted_apps
|
284
|
+
@mounted_apps ||= []
|
285
|
+
end
|
286
|
+
|
287
|
+
##
|
288
|
+
# Inserts a Mounter object into the mounted applications (avoids duplicates).
|
289
|
+
#
|
290
|
+
# @param [Tennpipes::Mounter] mounter
|
291
|
+
#
|
292
|
+
def insert_mounted_app(mounter)
|
293
|
+
Tennpipes.mounted_apps.push(mounter) unless Tennpipes.mounted_apps.include?(mounter)
|
294
|
+
end
|
295
|
+
|
296
|
+
##
|
297
|
+
# Mounts a new sub-application onto Tennpipes project.
|
298
|
+
#
|
299
|
+
# @see Tennpipes::Mounter#new
|
300
|
+
#
|
301
|
+
# @example
|
302
|
+
# Tennpipes.mount("blog_app").to("/blog")
|
303
|
+
#
|
304
|
+
def mount(name, options={})
|
305
|
+
Mounter.new(name, options)
|
306
|
+
end
|
307
|
+
end
|
308
|
+
end
|
@@ -0,0 +1,119 @@
|
|
1
|
+
require 'tennpipes-base/path_router/error_handler'
|
2
|
+
require 'tennpipes-base/path_router/route'
|
3
|
+
require 'tennpipes-base/path_router/matcher'
|
4
|
+
require 'tennpipes-base/path_router/compiler'
|
5
|
+
|
6
|
+
module Tennpipes
|
7
|
+
##
|
8
|
+
# Provides an HTTP router for use in path routing.
|
9
|
+
#
|
10
|
+
module PathRouter
|
11
|
+
##
|
12
|
+
# Constructs an instance of PathRouter::Router.
|
13
|
+
#
|
14
|
+
def self.new
|
15
|
+
Router.new
|
16
|
+
end
|
17
|
+
|
18
|
+
class Router
|
19
|
+
attr_reader :current_order, :routes, :engine
|
20
|
+
|
21
|
+
##
|
22
|
+
# Constructs an instance of PathRouter::Router.
|
23
|
+
#
|
24
|
+
def initialize
|
25
|
+
reset!
|
26
|
+
end
|
27
|
+
|
28
|
+
##
|
29
|
+
# Adds a new route to routes.
|
30
|
+
#
|
31
|
+
def add(verb, path, options = {}, &block)
|
32
|
+
route = Route.new(path, verb, options, &block)
|
33
|
+
route.router = self
|
34
|
+
@routes << route
|
35
|
+
route
|
36
|
+
end
|
37
|
+
|
38
|
+
##
|
39
|
+
# Returns all routes which are matched with the condition
|
40
|
+
#
|
41
|
+
def call(request, &block)
|
42
|
+
prepare! unless prepared?
|
43
|
+
@engine.call_by_request(request, &block)
|
44
|
+
end
|
45
|
+
|
46
|
+
##
|
47
|
+
# Returns all routes which are matched with the condition without block
|
48
|
+
#
|
49
|
+
def recognize(request_or_env)
|
50
|
+
prepare! unless prepared?
|
51
|
+
@engine.find_by(request_or_env)
|
52
|
+
end
|
53
|
+
|
54
|
+
##
|
55
|
+
# Finds a path which is matched with conditions from arguments
|
56
|
+
#
|
57
|
+
def path(name, *args)
|
58
|
+
params = args.extract_options!
|
59
|
+
@routes.each do |route|
|
60
|
+
next unless route.name == name
|
61
|
+
matcher = route.matcher
|
62
|
+
params_for_expand = params.dup
|
63
|
+
if !args.empty? && matcher.mustermann?
|
64
|
+
matcher.names.each_with_index do |matcher_name, index|
|
65
|
+
params_for_expand[matcher_name.to_sym] ||= args[index]
|
66
|
+
end
|
67
|
+
end
|
68
|
+
return matcher.mustermann? ? matcher.expand(params_for_expand) : route.path_for_generation
|
69
|
+
end
|
70
|
+
fail InvalidRouteException
|
71
|
+
end
|
72
|
+
|
73
|
+
##
|
74
|
+
# Recognizes route and expanded params from a path.
|
75
|
+
#
|
76
|
+
def recognize_path(path_info)
|
77
|
+
prepare! unless prepared?
|
78
|
+
route = @engine.find_by_pattern(path_info).first
|
79
|
+
[route.name, route.params_for(path_info, {})]
|
80
|
+
end
|
81
|
+
|
82
|
+
##
|
83
|
+
# Resets all routes, current order and preparation.
|
84
|
+
#
|
85
|
+
def reset!
|
86
|
+
@routes = []
|
87
|
+
@current_order = 0
|
88
|
+
@prepared = nil
|
89
|
+
end
|
90
|
+
|
91
|
+
##
|
92
|
+
# Increments the order.
|
93
|
+
#
|
94
|
+
def increment_order
|
95
|
+
@current_order += 1
|
96
|
+
end
|
97
|
+
|
98
|
+
##
|
99
|
+
# Constructs an instance of PathRouter::Compiler,
|
100
|
+
# and sorts all routes by using the order.
|
101
|
+
#
|
102
|
+
def prepare!
|
103
|
+
@engine = Compiler.new(@routes)
|
104
|
+
@prepared = true
|
105
|
+
return if @current_order.zero?
|
106
|
+
@routes.sort_by!(&:order)
|
107
|
+
end
|
108
|
+
|
109
|
+
private
|
110
|
+
|
111
|
+
##
|
112
|
+
# Returns true if the router has been prepared.
|
113
|
+
#
|
114
|
+
def prepared?
|
115
|
+
!!@prepared
|
116
|
+
end
|
117
|
+
end
|
118
|
+
end
|
119
|
+
end
|