merb-core 0.9.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (246) hide show
  1. data/LICENSE +20 -0
  2. data/README +21 -0
  3. data/Rakefile +285 -0
  4. data/TODO +0 -0
  5. data/bin/merb +8 -0
  6. data/bin/merb-specs +5 -0
  7. data/docs/bootloading.dox +57 -0
  8. data/docs/documentation_standards +40 -0
  9. data/docs/new_render_api +51 -0
  10. data/lib/merb-core.rb +304 -0
  11. data/lib/merb-core/autoload.rb +29 -0
  12. data/lib/merb-core/bootloader.rb +601 -0
  13. data/lib/merb-core/config.rb +284 -0
  14. data/lib/merb-core/constants.rb +43 -0
  15. data/lib/merb-core/controller/abstract_controller.rb +531 -0
  16. data/lib/merb-core/controller/exceptions.rb +257 -0
  17. data/lib/merb-core/controller/merb_controller.rb +214 -0
  18. data/lib/merb-core/controller/mime.rb +88 -0
  19. data/lib/merb-core/controller/mixins/controller.rb +262 -0
  20. data/lib/merb-core/controller/mixins/render.rb +324 -0
  21. data/lib/merb-core/controller/mixins/responder.rb +464 -0
  22. data/lib/merb-core/controller/template.rb +205 -0
  23. data/lib/merb-core/core_ext.rb +12 -0
  24. data/lib/merb-core/core_ext/class.rb +192 -0
  25. data/lib/merb-core/core_ext/hash.rb +422 -0
  26. data/lib/merb-core/core_ext/kernel.rb +304 -0
  27. data/lib/merb-core/core_ext/mash.rb +154 -0
  28. data/lib/merb-core/core_ext/object.rb +136 -0
  29. data/lib/merb-core/core_ext/object_space.rb +14 -0
  30. data/lib/merb-core/core_ext/rubygems.rb +28 -0
  31. data/lib/merb-core/core_ext/set.rb +41 -0
  32. data/lib/merb-core/core_ext/string.rb +69 -0
  33. data/lib/merb-core/dispatch/cookies.rb +92 -0
  34. data/lib/merb-core/dispatch/dispatcher.rb +233 -0
  35. data/lib/merb-core/dispatch/exceptions.html.erb +297 -0
  36. data/lib/merb-core/dispatch/request.rb +560 -0
  37. data/lib/merb-core/dispatch/router.rb +141 -0
  38. data/lib/merb-core/dispatch/router/behavior.rb +777 -0
  39. data/lib/merb-core/dispatch/router/cached_proc.rb +52 -0
  40. data/lib/merb-core/dispatch/router/route.rb +212 -0
  41. data/lib/merb-core/dispatch/session.rb +28 -0
  42. data/lib/merb-core/dispatch/session/cookie.rb +166 -0
  43. data/lib/merb-core/dispatch/session/memcached.rb +161 -0
  44. data/lib/merb-core/dispatch/session/memory.rb +234 -0
  45. data/lib/merb-core/gem_ext/erubis.rb +19 -0
  46. data/lib/merb-core/logger.rb +230 -0
  47. data/lib/merb-core/plugins.rb +25 -0
  48. data/lib/merb-core/rack.rb +15 -0
  49. data/lib/merb-core/rack/adapter.rb +42 -0
  50. data/lib/merb-core/rack/adapter/ebb.rb +22 -0
  51. data/lib/merb-core/rack/adapter/evented_mongrel.rb +24 -0
  52. data/lib/merb-core/rack/adapter/fcgi.rb +16 -0
  53. data/lib/merb-core/rack/adapter/irb.rb +108 -0
  54. data/lib/merb-core/rack/adapter/mongrel.rb +25 -0
  55. data/lib/merb-core/rack/adapter/runner.rb +27 -0
  56. data/lib/merb-core/rack/adapter/thin.rb +27 -0
  57. data/lib/merb-core/rack/adapter/webrick.rb +35 -0
  58. data/lib/merb-core/rack/application.rb +77 -0
  59. data/lib/merb-core/rack/handler/mongrel.rb +97 -0
  60. data/lib/merb-core/server.rb +184 -0
  61. data/lib/merb-core/test.rb +10 -0
  62. data/lib/merb-core/test/helpers.rb +9 -0
  63. data/lib/merb-core/test/helpers/controller_helper.rb +8 -0
  64. data/lib/merb-core/test/helpers/multipart_request_helper.rb +175 -0
  65. data/lib/merb-core/test/helpers/request_helper.rb +257 -0
  66. data/lib/merb-core/test/helpers/route_helper.rb +33 -0
  67. data/lib/merb-core/test/helpers/view_helper.rb +121 -0
  68. data/lib/merb-core/test/matchers.rb +9 -0
  69. data/lib/merb-core/test/matchers/controller_matchers.rb +269 -0
  70. data/lib/merb-core/test/matchers/route_matchers.rb +136 -0
  71. data/lib/merb-core/test/matchers/view_matchers.rb +293 -0
  72. data/lib/merb-core/test/run_specs.rb +38 -0
  73. data/lib/merb-core/test/tasks/spectasks.rb +39 -0
  74. data/lib/merb-core/test/test_ext/hpricot.rb +32 -0
  75. data/lib/merb-core/test/test_ext/object.rb +14 -0
  76. data/lib/merb-core/vendor/facets.rb +2 -0
  77. data/lib/merb-core/vendor/facets/dictionary.rb +433 -0
  78. data/lib/merb-core/vendor/facets/inflect.rb +211 -0
  79. data/lib/merb-core/version.rb +11 -0
  80. data/spec/private/config/adapter_spec.rb +32 -0
  81. data/spec/private/config/config_spec.rb +139 -0
  82. data/spec/private/config/environment_spec.rb +13 -0
  83. data/spec/private/config/spec_helper.rb +1 -0
  84. data/spec/private/core_ext/hash_spec.rb +506 -0
  85. data/spec/private/core_ext/kernel_spec.rb +46 -0
  86. data/spec/private/core_ext/object_spec.rb +39 -0
  87. data/spec/private/core_ext/set_spec.rb +26 -0
  88. data/spec/private/core_ext/string_spec.rb +9 -0
  89. data/spec/private/dispatch/cookies_spec.rb +107 -0
  90. data/spec/private/dispatch/dispatch_spec.rb +26 -0
  91. data/spec/private/dispatch/fixture/app/controllers/application.rb +4 -0
  92. data/spec/private/dispatch/fixture/app/controllers/exceptions.rb +27 -0
  93. data/spec/private/dispatch/fixture/app/controllers/foo.rb +21 -0
  94. data/spec/private/dispatch/fixture/app/helpers/global_helpers.rb +8 -0
  95. data/spec/private/dispatch/fixture/app/views/exeptions/client_error.html.erb +37 -0
  96. data/spec/private/dispatch/fixture/app/views/exeptions/internal_server_error.html.erb +216 -0
  97. data/spec/private/dispatch/fixture/app/views/exeptions/not_acceptable.html.erb +38 -0
  98. data/spec/private/dispatch/fixture/app/views/exeptions/not_found.html.erb +40 -0
  99. data/spec/private/dispatch/fixture/app/views/foo/bar.html.erb +0 -0
  100. data/spec/private/dispatch/fixture/app/views/layout/application.html.erb +11 -0
  101. data/spec/private/dispatch/fixture/config/environments/development.rb +6 -0
  102. data/spec/private/dispatch/fixture/config/environments/production.rb +5 -0
  103. data/spec/private/dispatch/fixture/config/environments/test.rb +6 -0
  104. data/spec/private/dispatch/fixture/config/init.rb +45 -0
  105. data/spec/private/dispatch/fixture/config/rack.rb +1 -0
  106. data/spec/private/dispatch/fixture/config/router.rb +35 -0
  107. data/spec/private/dispatch/fixture/log/development.log +1 -0
  108. data/spec/private/dispatch/fixture/log/merb.4000.pid +1 -0
  109. data/spec/private/dispatch/fixture/log/merb_test.log +2040 -0
  110. data/spec/private/dispatch/fixture/log/production.log +1 -0
  111. data/spec/private/dispatch/fixture/merb.4000.pid +1 -0
  112. data/spec/private/dispatch/fixture/public/images/merb.jpg +0 -0
  113. data/spec/private/dispatch/fixture/public/merb.fcgi +4 -0
  114. data/spec/private/dispatch/fixture/public/stylesheets/master.css +119 -0
  115. data/spec/private/dispatch/route_params_spec.rb +24 -0
  116. data/spec/private/dispatch/spec_helper.rb +1 -0
  117. data/spec/private/plugins/plugin_spec.rb +81 -0
  118. data/spec/private/rack/application_spec.rb +43 -0
  119. data/spec/public/DEFINITIONS +11 -0
  120. data/spec/public/abstract_controller/controllers/alt_views/layout/application.erb +1 -0
  121. data/spec/public/abstract_controller/controllers/alt_views/layout/merb/test/fixtures/abstract/render_string_controller_layout.erb +1 -0
  122. data/spec/public/abstract_controller/controllers/alt_views/layout/merb/test/fixtures/abstract/render_template_controller_layout.erb +1 -0
  123. data/spec/public/abstract_controller/controllers/alt_views/merb/test/fixtures/abstract/display_object_with_multiple_roots/index.erb +1 -0
  124. data/spec/public/abstract_controller/controllers/alt_views/merb/test/fixtures/abstract/display_object_with_multiple_roots/show.erb +1 -0
  125. data/spec/public/abstract_controller/controllers/alt_views/merb/test/fixtures/abstract/render_template_multiple_roots/index.erb +1 -0
  126. data/spec/public/abstract_controller/controllers/alt_views/partial/basic_partial_with_multiple_roots/_partial.erb +1 -0
  127. data/spec/public/abstract_controller/controllers/alt_views/render_template_multiple_roots_and_custom_location/index.erb +1 -0
  128. data/spec/public/abstract_controller/controllers/alt_views/render_template_multiple_roots_inherited/index.erb +1 -0
  129. data/spec/public/abstract_controller/controllers/display.rb +54 -0
  130. data/spec/public/abstract_controller/controllers/filters.rb +167 -0
  131. data/spec/public/abstract_controller/controllers/helpers.rb +31 -0
  132. data/spec/public/abstract_controller/controllers/partial.rb +106 -0
  133. data/spec/public/abstract_controller/controllers/render.rb +86 -0
  134. data/spec/public/abstract_controller/controllers/views/helpers/capture/index.erb +1 -0
  135. data/spec/public/abstract_controller/controllers/views/helpers/concat/index.erb +1 -0
  136. data/spec/public/abstract_controller/controllers/views/layout/alt.erb +1 -0
  137. data/spec/public/abstract_controller/controllers/views/layout/custom.erb +1 -0
  138. data/spec/public/abstract_controller/controllers/views/merb/test/fixtures/abstract/display_object/index.erb +1 -0
  139. data/spec/public/abstract_controller/controllers/views/merb/test/fixtures/abstract/display_object_with_action/new.erb +1 -0
  140. data/spec/public/abstract_controller/controllers/views/merb/test/fixtures/abstract/render_template/index.erb +1 -0
  141. data/spec/public/abstract_controller/controllers/views/merb/test/fixtures/abstract/render_template_app_layout/index.erb +0 -0
  142. data/spec/public/abstract_controller/controllers/views/merb/test/fixtures/abstract/render_template_custom_layout/index.erb +1 -0
  143. data/spec/public/abstract_controller/controllers/views/merb/test/fixtures/abstract/render_template_multiple_roots/index.erb +1 -0
  144. data/spec/public/abstract_controller/controllers/views/merb/test/fixtures/abstract/render_template_multiple_roots/show.erb +1 -0
  145. data/spec/public/abstract_controller/controllers/views/partial/another_directory/_partial.erb +1 -0
  146. data/spec/public/abstract_controller/controllers/views/partial/basic_partial/_partial.erb +1 -0
  147. data/spec/public/abstract_controller/controllers/views/partial/basic_partial/index.erb +1 -0
  148. data/spec/public/abstract_controller/controllers/views/partial/basic_partial_with_multiple_roots/index.erb +1 -0
  149. data/spec/public/abstract_controller/controllers/views/partial/nested_partial/_first.erb +1 -0
  150. data/spec/public/abstract_controller/controllers/views/partial/nested_partial/_second.erb +1 -0
  151. data/spec/public/abstract_controller/controllers/views/partial/nested_partial/index.erb +1 -0
  152. data/spec/public/abstract_controller/controllers/views/partial/partial_in_another_directory/index.erb +1 -0
  153. data/spec/public/abstract_controller/controllers/views/partial/partial_with_both/_collection.erb +1 -0
  154. data/spec/public/abstract_controller/controllers/views/partial/partial_with_both/index.erb +1 -0
  155. data/spec/public/abstract_controller/controllers/views/partial/partial_with_collections/_collection.erb +1 -0
  156. data/spec/public/abstract_controller/controllers/views/partial/partial_with_collections/index.erb +1 -0
  157. data/spec/public/abstract_controller/controllers/views/partial/partial_with_collections_and_as/_collection.erb +1 -0
  158. data/spec/public/abstract_controller/controllers/views/partial/partial_with_collections_and_as/index.erb +1 -0
  159. data/spec/public/abstract_controller/controllers/views/partial/partial_with_locals/_variables.erb +1 -0
  160. data/spec/public/abstract_controller/controllers/views/partial/partial_with_locals/index.erb +1 -0
  161. data/spec/public/abstract_controller/controllers/views/partial/partial_with_with_and_locals/_both.erb +1 -0
  162. data/spec/public/abstract_controller/controllers/views/partial/partial_with_with_and_locals/index.erb +1 -0
  163. data/spec/public/abstract_controller/controllers/views/partial/with_as_partial/_with_partial.erb +1 -0
  164. data/spec/public/abstract_controller/controllers/views/partial/with_as_partial/index.erb +1 -0
  165. data/spec/public/abstract_controller/controllers/views/partial/with_nil_partial/_with_partial.erb +1 -0
  166. data/spec/public/abstract_controller/controllers/views/partial/with_nil_partial/index.erb +1 -0
  167. data/spec/public/abstract_controller/controllers/views/partial/with_partial/_with_partial.erb +1 -0
  168. data/spec/public/abstract_controller/controllers/views/partial/with_partial/index.erb +1 -0
  169. data/spec/public/abstract_controller/controllers/views/test_display/foo.html.erb +1 -0
  170. data/spec/public/abstract_controller/controllers/views/test_render/foo.html.erb +0 -0
  171. data/spec/public/abstract_controller/controllers/views/wonderful/index.erb +1 -0
  172. data/spec/public/abstract_controller/display_spec.rb +33 -0
  173. data/spec/public/abstract_controller/filter_spec.rb +80 -0
  174. data/spec/public/abstract_controller/helper_spec.rb +13 -0
  175. data/spec/public/abstract_controller/partial_spec.rb +53 -0
  176. data/spec/public/abstract_controller/render_spec.rb +70 -0
  177. data/spec/public/abstract_controller/spec_helper.rb +27 -0
  178. data/spec/public/boot_loader/boot_loader_spec.rb +33 -0
  179. data/spec/public/boot_loader/spec_helper.rb +1 -0
  180. data/spec/public/controller/base_spec.rb +31 -0
  181. data/spec/public/controller/controllers/base.rb +41 -0
  182. data/spec/public/controller/controllers/display.rb +40 -0
  183. data/spec/public/controller/controllers/responder.rb +67 -0
  184. data/spec/public/controller/controllers/url.rb +7 -0
  185. data/spec/public/controller/controllers/views/layout/custom.html.erb +1 -0
  186. data/spec/public/controller/controllers/views/merb/test/fixtures/controllers/class_provides/index.html.erb +1 -0
  187. data/spec/public/controller/controllers/views/merb/test/fixtures/controllers/class_provides/index.xml.erb +1 -0
  188. data/spec/public/controller/controllers/views/merb/test/fixtures/controllers/display_with_template/index.html.erb +1 -0
  189. data/spec/public/controller/controllers/views/merb/test/fixtures/controllers/html_default/index.html.erb +1 -0
  190. data/spec/public/controller/controllers/views/merb/test/fixtures/controllers/layout/custom.html.erb +1 -0
  191. data/spec/public/controller/controllers/views/merb/test/fixtures/controllers/local_provides/index.html.erb +1 -0
  192. data/spec/public/controller/controllers/views/merb/test/fixtures/controllers/local_provides/index.xml.erb +1 -0
  193. data/spec/public/controller/controllers/views/merb/test/fixtures/controllers/multi_provides/index.html.erb +1 -0
  194. data/spec/public/controller/controllers/views/merb/test/fixtures/controllers/multi_provides/index.js.erb +1 -0
  195. data/spec/public/controller/display_spec.rb +34 -0
  196. data/spec/public/controller/log/merb.4000.pid +1 -0
  197. data/spec/public/controller/responder_spec.rb +95 -0
  198. data/spec/public/controller/spec_helper.rb +9 -0
  199. data/spec/public/controller/url_spec.rb +152 -0
  200. data/spec/public/directory_structure/directory/app/controllers/application.rb +3 -0
  201. data/spec/public/directory_structure/directory/app/controllers/base.rb +13 -0
  202. data/spec/public/directory_structure/directory/app/controllers/custom.rb +19 -0
  203. data/spec/public/directory_structure/directory/app/views/base/template.html.erb +1 -0
  204. data/spec/public/directory_structure/directory/app/views/wonderful/template.erb +1 -0
  205. data/spec/public/directory_structure/directory/config/router.rb +3 -0
  206. data/spec/public/directory_structure/directory/log/merb.4000.pid +1 -0
  207. data/spec/public/directory_structure/directory/log/merb_test.log +265 -0
  208. data/spec/public/directory_structure/directory/merb.4000.pid +1 -0
  209. data/spec/public/directory_structure/directory_spec.rb +44 -0
  210. data/spec/public/logger/logger_spec.rb +175 -0
  211. data/spec/public/logger/spec_helper.rb +1 -0
  212. data/spec/public/reloading/directory/app/controllers/application.rb +3 -0
  213. data/spec/public/reloading/directory/app/controllers/reload.rb +6 -0
  214. data/spec/public/reloading/directory/config/init.rb +2 -0
  215. data/spec/public/reloading/directory/log/merb.4000.pid +1 -0
  216. data/spec/public/reloading/directory/log/merb_test.log +59 -0
  217. data/spec/public/reloading/directory/merb.4000.pid +1 -0
  218. data/spec/public/reloading/reload_spec.rb +80 -0
  219. data/spec/public/request/multipart_spec.rb +15 -0
  220. data/spec/public/request/request_spec.rb +207 -0
  221. data/spec/public/router/default_spec.rb +21 -0
  222. data/spec/public/router/deferred_spec.rb +22 -0
  223. data/spec/public/router/namespace_spec.rb +113 -0
  224. data/spec/public/router/nested_resources_spec.rb +34 -0
  225. data/spec/public/router/resource_spec.rb +45 -0
  226. data/spec/public/router/resources_spec.rb +57 -0
  227. data/spec/public/router/spec_helper.rb +72 -0
  228. data/spec/public/router/special_spec.rb +44 -0
  229. data/spec/public/router/string_spec.rb +61 -0
  230. data/spec/public/template/template_spec.rb +92 -0
  231. data/spec/public/template/templates/error.html.erb +2 -0
  232. data/spec/public/template/templates/template.html.erb +1 -0
  233. data/spec/public/template/templates/template.html.myt +1 -0
  234. data/spec/public/test/controller_matchers_spec.rb +378 -0
  235. data/spec/public/test/controllers/controller_assertion_mock.rb +7 -0
  236. data/spec/public/test/controllers/dispatch_controller.rb +11 -0
  237. data/spec/public/test/controllers/spec_helper_controller.rb +30 -0
  238. data/spec/public/test/multipart_request_helper_spec.rb +159 -0
  239. data/spec/public/test/multipart_upload_text_file.txt +1 -0
  240. data/spec/public/test/request_helper_spec.rb +153 -0
  241. data/spec/public/test/route_helper_spec.rb +54 -0
  242. data/spec/public/test/route_matchers_spec.rb +133 -0
  243. data/spec/public/test/view_helper_spec.rb +96 -0
  244. data/spec/public/test/view_matchers_spec.rb +107 -0
  245. data/spec/spec_helper.rb +71 -0
  246. metadata +488 -0
@@ -0,0 +1,257 @@
1
+ module Merb
2
+ # ControllerExceptions are a way of simplifying controller code by placing
3
+ # exceptional logic back into the MVC pattern.
4
+ #
5
+ # When a ControllerException is raised within your application merb will
6
+ # attempt to re-route the request to your Exceptions controller to render
7
+ # the error in a friendly mannor.
8
+ #
9
+ # For example you might have an action in your app that raises NotFound
10
+ # if a some resource was not available
11
+ #
12
+
13
+ # def show
14
+ # product = Product.find(params[:id])
15
+ # raise NotFound if product.nil?
16
+ # [...]
17
+ # end
18
+ #
19
+ # This would halt execution of your action and re-route it over to your
20
+ # Exceptions controller which might look something like
21
+ #
22
+ # class Exceptions < Application
23
+
24
+ # def not_found
25
+ # render :layout => :none
26
+ # end
27
+ # end
28
+ #
29
+ # As usual the not_found action will look for a template in
30
+ # app/views/exceptions/not_found.html.erb
31
+ #
32
+ # Note: All standard ControllerExceptions have an HTTP status code associated
33
+ # with them which is sent to the browser when the action it is rendered.
34
+ #
35
+ # Note: If you do not specifiy how to handle raised ControllerExceptions
36
+ # or an unhandlable exception occurs within your customised exception action
37
+ # then they will be rendered using the built-in error template
38
+ # in development mode this "built in" template will show stack-traces for
39
+ # any of the ServerError family of exceptions (you can force the stack-trace
40
+ # to display in production mode using the :exception_details config option in
41
+ # merb.yml)
42
+ #
43
+ #
44
+ # ==== Internal Exceptions
45
+ #
46
+ # Any other rogue errors (not ControllerExceptions) that occur during the
47
+ # execution of you app will be converted into the ControllerException
48
+ # InternalServerError, and like all ControllerExceptions can be caught
49
+ # on your Exceptions controller.
50
+ #
51
+ # InternalServerErrors return status 500, a common use for cusomizing this
52
+ # action might be to send emails to the development team, warning that their
53
+ # application have exploded. Mock example:
54
+ #
55
+
56
+ # def internal_server_error
57
+ # MySpecialMailer.deliver(
58
+ # "team@cowboys.com",
59
+ # "Exception occured at #{Time.now}",
60
+ # params[:exception])
61
+ # render :inline => 'Something is wrong, but the team are on it!'
62
+ # end
63
+ #
64
+ # Note: The special param[:exception] is available in all Exception actions
65
+ # and contains the ControllerException that was raised (this is handy if
66
+ # you want to display the associated message or display more detailed info)
67
+ #
68
+ #
69
+ # ==== Extending ControllerExceptions
70
+ #
71
+ # To extend the use of the ControllerExceptions one may extend any of the
72
+ # HTTPError classes.
73
+ #
74
+ # As an example we can create an exception called AdminAccessRequired.
75
+ #
76
+ # class AdminAccessRequired < Merb::ControllerExceptions::Unauthorized; end
77
+ #
78
+ # Add the required action to our Exceptions controller
79
+ #
80
+ # class Exceptions < Application
81
+
82
+ # def admin_access_required
83
+ # render
84
+ # end
85
+ # end
86
+ #
87
+ # In app/views/exceptions/admin_access_required.rhtml
88
+ #
89
+ # <h1>You're not an administrator!</h1>
90
+ # <p>You tried to access <%= @tried_to_access %> but that URL is
91
+ # restricted to administrators.</p>
92
+ #
93
+ module ControllerExceptions #:nodoc: all
94
+
95
+ # Mapping of status code names to their numeric value.
96
+ STATUS_CODES = {}
97
+
98
+ class Base < StandardError #:doc:
99
+
100
+ # ==== Returns
101
+ # String:: The snake cased name of the error without the namespace.
102
+ def name; self.class.name; end
103
+
104
+ # ==== Returns
105
+ # String:: The snake cased name of the class without the namespace.
106
+ def self.name
107
+ to_s.snake_case.split('::').last
108
+ end
109
+
110
+ # Makes it possible to pass a status-code class to render :status.
111
+ #
112
+ # ==== Returns
113
+ # Fixnum:: The status code of this exception.
114
+ def self.to_i
115
+ STATUS
116
+ end
117
+
118
+ # Registers any subclasses with status codes for easy lookup by
119
+ # set_status in Merb::Controller.
120
+ #
121
+ # Inheritance ensures this method gets inherited by any subclasses, so
122
+ # it goes all the way down the chain of inheritance.
123
+ #
124
+ # ==== Parameters
125
+ #
126
+ # subclass<Merb::ControllerExceptions::Base>::
127
+ # The Exception class that is inheriting from Merb::ControllerExceptions::Base
128
+ def self.inherited(subclass)
129
+ if subclass.const_defined?(:STATUS)
130
+ STATUS_CODES[subclass.name.snake_case.to_sym] = subclass.const_get(:STATUS)
131
+ end
132
+ end
133
+ end
134
+
135
+ class Informational < Merb::ControllerExceptions::Base; end
136
+
137
+ class Continue < Merb::ControllerExceptions::Informational; STATUS = 100; end
138
+
139
+ class SwitchingProtocols < Merb::ControllerExceptions::Informational; STATUS = 101; end
140
+
141
+ class Successful < Merb::ControllerExceptions::Base; end
142
+
143
+ class OK < Merb::ControllerExceptions::Successful; STATUS = 200; end
144
+
145
+ class Created < Merb::ControllerExceptions::Successful; STATUS = 201; end
146
+
147
+ class Accepted < Merb::ControllerExceptions::Successful; STATUS = 202; end
148
+
149
+ class NonAuthoritativeInformation < Merb::ControllerExceptions::Successful; STATUS = 203; end
150
+
151
+ class NoContent < Merb::ControllerExceptions::Successful; STATUS = 204; end
152
+
153
+ class ResetContent < Merb::ControllerExceptions::Successful; STATUS = 205; end
154
+
155
+ class PartialContent < Merb::ControllerExceptions::Successful; STATUS = 206; end
156
+
157
+ class Redirection < Merb::ControllerExceptions::Base; end
158
+
159
+ class MultipleChoices < Merb::ControllerExceptions::Redirection; STATUS = 300; end
160
+
161
+ class MovedPermanently < Merb::ControllerExceptions::Redirection; STATUS = 301; end
162
+
163
+ class MovedTemporarily < Merb::ControllerExceptions::Redirection; STATUS = 302; end
164
+
165
+ class SeeOther < Merb::ControllerExceptions::Redirection; STATUS = 303; end
166
+
167
+ class NotModified < Merb::ControllerExceptions::Redirection; STATUS = 304; end
168
+
169
+ class UseProxy < Merb::ControllerExceptions::Redirection; STATUS = 305; end
170
+
171
+ class TemporaryRedirect < Merb::ControllerExceptions::Redirection; STATUS = 307; end
172
+
173
+ class ClientError < Merb::ControllerExceptions::Base; end
174
+
175
+ class BadRequest < Merb::ControllerExceptions::ClientError; STATUS = 400; end
176
+
177
+ class MultiPartParseError < Merb::ControllerExceptions::BadRequest; end
178
+
179
+ class Unauthorized < Merb::ControllerExceptions::ClientError; STATUS = 401; end
180
+
181
+ class PaymentRequired < Merb::ControllerExceptions::ClientError; STATUS = 402; end
182
+
183
+ class Forbidden < Merb::ControllerExceptions::ClientError; STATUS = 403; end
184
+
185
+ class NotFound < Merb::ControllerExceptions::ClientError; STATUS = 404; end
186
+
187
+ class ActionNotFound < Merb::ControllerExceptions::NotFound; end
188
+
189
+ class TemplateNotFound < Merb::ControllerExceptions::NotFound; end
190
+
191
+ class LayoutNotFound < Merb::ControllerExceptions::NotFound; end
192
+
193
+ class MethodNotAllowed < Merb::ControllerExceptions::ClientError; STATUS = 405; end
194
+
195
+ class NotAcceptable < Merb::ControllerExceptions::ClientError; STATUS = 406; end
196
+
197
+ class ProxyAuthenticationRequired < Merb::ControllerExceptions::ClientError; STATUS = 407; end
198
+
199
+ class RequestTimeout < Merb::ControllerExceptions::ClientError; STATUS = 408; end
200
+
201
+ class Conflict < Merb::ControllerExceptions::ClientError; STATUS = 409; end
202
+
203
+ class Gone < Merb::ControllerExceptions::ClientError; STATUS = 410; end
204
+
205
+ class LengthRequired < Merb::ControllerExceptions::ClientError; STATUS = 411; end
206
+
207
+ class PreconditionFailed < Merb::ControllerExceptions::ClientError; STATUS = 412; end
208
+
209
+ class RequestEntityTooLarge < Merb::ControllerExceptions::ClientError; STATUS = 413; end
210
+
211
+ class RequestURITooLarge < Merb::ControllerExceptions::ClientError; STATUS = 414; end
212
+
213
+ class UnsupportedMediaType < Merb::ControllerExceptions::ClientError; STATUS = 415; end
214
+
215
+ class RequestRangeNotSatisfiable < Merb::ControllerExceptions::ClientError; STATUS = 416; end
216
+
217
+ class ExpectationFailed < Merb::ControllerExceptions::ClientError; STATUS = 417; end
218
+
219
+ class ServerError < Merb::ControllerExceptions::Base; end
220
+
221
+ class NotImplemented < Merb::ControllerExceptions::ServerError; STATUS = 501; end
222
+
223
+ class BadGateway < Merb::ControllerExceptions::ServerError; STATUS = 502; end
224
+
225
+ class ServiceUnavailable < Merb::ControllerExceptions::ServerError; STATUS = 503; end
226
+
227
+ class GatewayTimeout < Merb::ControllerExceptions::ServerError; STATUS = 504; end
228
+
229
+ class HTTPVersionNotSupported < Merb::ControllerExceptions::ServerError; STATUS = 505; end
230
+
231
+ class InternalServerError < Merb::ControllerExceptions::ServerError #:doc:
232
+ STATUS = 500
233
+ # DEFAULT_TEMPLATE = ::Merb::Dispatcher::DEFAULT_ERROR_TEMPLATE
234
+ def initialize(exception = nil)
235
+ @exception = exception
236
+ @coderay = CodeRay rescue nil
237
+ end
238
+
239
+ def backtrace
240
+ @exception ? @exception.backtrace : backtrace
241
+ end
242
+
243
+ def message
244
+ @exception ? @exception.message : message
245
+ end
246
+ end
247
+ end
248
+
249
+ # Required to show exceptions in the log file
250
+ #
251
+ # e<Exception>:: The exception that a message is being generated for
252
+ def self.exception(e) #:nodoc:
253
+ "#{ e.message } - (#{ e.class })\n" <<
254
+ "#{(e.backtrace or []).join("\n")}"
255
+ end
256
+
257
+ end
@@ -0,0 +1,214 @@
1
+ class Merb::Controller < Merb::AbstractController
2
+
3
+ class_inheritable_accessor :_hidden_actions, :_shown_actions
4
+ cattr_accessor :_subclasses, :_session_id_key, :_session_secret_key, :_session_expiry
5
+ self._subclasses = Set.new
6
+
7
+ def self.subclasses_list() _subclasses end
8
+
9
+ self._session_secret_key = nil
10
+ self._session_id_key = Merb::Config[:session_id_key] || '_session_id'
11
+ self._session_expiry = Merb::Config[:session_expiry] || Merb::Const::WEEK * 2
12
+
13
+ include Merb::ResponderMixin
14
+ include Merb::ControllerMixin
15
+
16
+ attr_accessor :route
17
+
18
+ class << self
19
+
20
+ # ==== Parameters
21
+ # klass<Merb::Controller>::
22
+ # The Merb::Controller inheriting from the base class.
23
+ def inherited(klass)
24
+ _subclasses << klass.to_s
25
+ self._template_root = Merb.dir_for(:view) unless self._template_root
26
+ super
27
+ end
28
+
29
+ # Hide each of the given methods from being callable as actions.
30
+ #
31
+ # ==== Parameters
32
+ # *names<~to-s>:: Actions that should be added to the list.
33
+ #
34
+ # ==== Returns
35
+ # Array[String]::
36
+ # An array of actions that should not be possible to dispatch to.
37
+ #
38
+ #---
39
+ # @public
40
+ def hide_action(*names)
41
+ self._hidden_actions = self._hidden_actions | names.map { |n| n.to_s }
42
+ end
43
+
44
+ # Makes each of the given methods being callable as actions. You can use
45
+ # this to make methods included from modules callable as actions.
46
+ #
47
+ # ==== Parameters
48
+ # *names<~to-s>:: Actions that should be added to the list.
49
+ #
50
+ # ==== Returns
51
+ # Array[String]::
52
+ # An array of actions that should be dispatched to even if they would not
53
+ # otherwise be.
54
+ #
55
+ # ==== Example
56
+ # module Foo
57
+ # def self.included(base)
58
+ # base.show_action(:foo)
59
+ # end
60
+ #
61
+ # def foo
62
+ # # some actiony stuff
63
+ # end
64
+ #
65
+ # def foo_helper
66
+ # # this should not be an action
67
+ # end
68
+ # end
69
+ #
70
+ #---
71
+ # @public
72
+ def show_action(*names)
73
+ self._shown_actions = self._shown_actions | names.map {|n| n.to_s}
74
+ end
75
+
76
+ # This list of actions that should not be callable.
77
+ #
78
+ # ==== Returns
79
+ # Array[String]:: An array of actions that should not be dispatchable.
80
+ def _hidden_actions
81
+ actions = read_inheritable_attribute(:_hidden_actions)
82
+ actions ? actions : write_inheritable_attribute(:_hidden_actions, [])
83
+ end
84
+
85
+ # This list of actions that should be callable.
86
+ #
87
+ # ==== Returns
88
+ # Array[String]::
89
+ # An array of actions that should be dispatched to even if they would not
90
+ # otherwise be.
91
+ def _shown_actions
92
+ actions = read_inheritable_attribute(:_shown_actions)
93
+ actions ? actions : write_inheritable_attribute(:_shown_actions, [])
94
+ end
95
+
96
+ # The list of actions that are callable, after taking defaults,
97
+ # _hidden_actions and _shown_actions into consideration. It is calculated
98
+ # once, the first time an action is dispatched for this controller.
99
+ #
100
+ # ==== Returns
101
+ # Array[String]:: A list of actions that should be callable.
102
+ def callable_actions
103
+ unless @callable_actions
104
+ callables = []
105
+ klass = self
106
+ begin
107
+ callables << (klass.public_instance_methods(false) + klass._shown_actions) - klass._hidden_actions
108
+ klass = klass.superclass
109
+ end until klass == Merb::Controller || klass == Object
110
+ @callable_actions = Merb::SimpleSet.new(callables.flatten)
111
+ end
112
+ @callable_actions
113
+ end
114
+
115
+ end
116
+
117
+ # The location to look for a template for a particular controller, action,
118
+ # and mime-type. This is overridden from AbstractController, which defines a
119
+ # version of this that does not involve mime-types.
120
+ #
121
+ # ==== Parameters
122
+ # action<~to_s>:: The name of the action that will be rendered.
123
+ # type<~to_s>::
124
+ # The mime-type of the template that will be rendered. Defaults to nil.
125
+ # controller<~to_s>::
126
+ # The name of the controller that will be rendered. Defaults to
127
+ # controller_name.
128
+ #
129
+ # ==== Note
130
+ # By default, this renders ":controller/:action.:type". To change this,
131
+ # override it in your application class or in individual controllers.
132
+ #
133
+ #---
134
+ # @public
135
+ def _template_location(action, type = nil, controller = controller_name)
136
+ "#{controller}/#{action}.#{type}"
137
+ end
138
+
139
+ # Build a new controller.
140
+ #
141
+ # Sets the variables that came in through the dispatch as available to
142
+ # the controller.
143
+ #
144
+ # This method uses the :session_id_cookie_only and :query_string_whitelist
145
+ # configuration options. See CONFIG for more details.
146
+ #
147
+ # ==== Parameters
148
+ # request<Merb::Request>:: The Merb::Request that came in from Mongrel.
149
+ # status<Integer>:: An integer code for the status. Defaults to 200.
150
+ # headers<Hash{header => value}>::
151
+ # A hash of headers to start the controller with. These headers can be
152
+ # overridden later by the #headers method.
153
+ #---
154
+ # @semipublic
155
+ def initialize(request, status=200, headers={'Content-Type' => 'text/html; charset=utf-8'})
156
+ super()
157
+ @request, @status, @headers = request, status, headers
158
+ end
159
+
160
+ # Dispatch the action.
161
+ #
162
+ # ==== Parameters
163
+ # action<~to_s>:: An action to dispatch to. Defaults to :index.
164
+ #
165
+ # ==== Returns
166
+ # String:: The string sent to the logger for time spent.
167
+ #
168
+ # ==== Raises
169
+ # ActionNotFound:: The requested action was not found in class.
170
+ #---
171
+ # @semipublic
172
+ def _dispatch(action=:index)
173
+ start = Time.now
174
+ if self.class.callable_actions.include?(action.to_s)
175
+ super(action)
176
+ else
177
+ raise ActionNotFound, "Action '#{action}' was not found in #{self.class}"
178
+ end
179
+ @_benchmarks[:action_time] = Time.now - start
180
+ end
181
+
182
+ attr_reader :request, :headers
183
+ attr_accessor :status
184
+
185
+ # ==== Returns
186
+ # Hash:: The parameters from the request object
187
+ def params() request.params end
188
+
189
+ # ==== Returns
190
+ # Merb::Cookies::
191
+ # A new Merb::Cookies instance representing the cookies that came in
192
+ # from the request object
193
+ #
194
+ # ==== Note
195
+ # Headers are passed into the cookie object so that you can do:
196
+ # cookies[:foo] = "bar"
197
+ def cookies() @_cookies ||= _setup_cookies end
198
+
199
+ # ==== Returns
200
+ # Hash:: The session that was extracted from the request object.
201
+ def session() request.session end
202
+
203
+ private
204
+
205
+ # Create a default cookie jar, and pre-set a fixation cookie
206
+ # if fixation is enabled
207
+ def _setup_cookies
208
+ cookies = ::Merb::Cookies.new(request.cookies, @headers)
209
+ if request.params.key?(_session_id_key) && route.allow_fixation?
210
+ cookies[_session_id_key] = request.params[_session_id_key]
211
+ end
212
+ cookies
213
+ end
214
+ end