apipierails3 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (171) hide show
  1. checksums.yaml +17 -0
  2. data/.gitignore +14 -0
  3. data/.rspec +2 -0
  4. data/.travis.yml +27 -0
  5. data/APACHE-LICENSE-2.0 +202 -0
  6. data/CHANGELOG.md +469 -0
  7. data/Gemfile +1 -0
  8. data/Gemfile.rails32 +6 -0
  9. data/Gemfile.rails41 +6 -0
  10. data/Gemfile.rails42 +11 -0
  11. data/Gemfile.rails50 +6 -0
  12. data/Gemfile.rails51 +7 -0
  13. data/MIT-LICENSE +20 -0
  14. data/NOTICE +4 -0
  15. data/PROPOSAL_FOR_RESPONSE_DESCRIPTIONS.md +244 -0
  16. data/README.rst +1874 -0
  17. data/Rakefile +13 -0
  18. data/apipierails3.gemspec +27 -0
  19. data/app/controllers/apipie/apipies_controller.rb +199 -0
  20. data/app/helpers/apipie_helper.rb +10 -0
  21. data/app/public/apipie/javascripts/apipie.js +6 -0
  22. data/app/public/apipie/javascripts/bundled/bootstrap-collapse.js +138 -0
  23. data/app/public/apipie/javascripts/bundled/bootstrap.js +1726 -0
  24. data/app/public/apipie/javascripts/bundled/jquery.js +5 -0
  25. data/app/public/apipie/javascripts/bundled/prettify.js +28 -0
  26. data/app/public/apipie/stylesheets/application.css +7 -0
  27. data/app/public/apipie/stylesheets/bundled/bootstrap-responsive.min.css +12 -0
  28. data/app/public/apipie/stylesheets/bundled/bootstrap.min.css +689 -0
  29. data/app/public/apipie/stylesheets/bundled/prettify.css +30 -0
  30. data/app/views/apipie/apipies/_disqus.html.erb +13 -0
  31. data/app/views/apipie/apipies/_errors.html.erb +23 -0
  32. data/app/views/apipie/apipies/_headers.html.erb +26 -0
  33. data/app/views/apipie/apipies/_languages.erb +6 -0
  34. data/app/views/apipie/apipies/_metadata.erb +1 -0
  35. data/app/views/apipie/apipies/_method_detail.erb +61 -0
  36. data/app/views/apipie/apipies/_params.html.erb +42 -0
  37. data/app/views/apipie/apipies/_params_plain.html.erb +20 -0
  38. data/app/views/apipie/apipies/apipie_404.html.erb +17 -0
  39. data/app/views/apipie/apipies/apipie_checksum.json.erb +1 -0
  40. data/app/views/apipie/apipies/getting_started.html.erb +6 -0
  41. data/app/views/apipie/apipies/index.html.erb +56 -0
  42. data/app/views/apipie/apipies/method.html.erb +41 -0
  43. data/app/views/apipie/apipies/plain.html.erb +77 -0
  44. data/app/views/apipie/apipies/resource.html.erb +80 -0
  45. data/app/views/apipie/apipies/static.html.erb +103 -0
  46. data/app/views/layouts/apipie/apipie.html.erb +27 -0
  47. data/config/locales/de.yml +28 -0
  48. data/config/locales/en.yml +32 -0
  49. data/config/locales/es.yml +28 -0
  50. data/config/locales/fr.yml +31 -0
  51. data/config/locales/it.yml +31 -0
  52. data/config/locales/ja.yml +31 -0
  53. data/config/locales/pl.yml +28 -0
  54. data/config/locales/pt-BR.yml +28 -0
  55. data/config/locales/ru.yml +28 -0
  56. data/config/locales/tr.yml +28 -0
  57. data/config/locales/zh-CN.yml +28 -0
  58. data/config/locales/zh-TW.yml +28 -0
  59. data/images/screenshot-1.png +0 -0
  60. data/images/screenshot-2.png +0 -0
  61. data/lib/apipie/apipie_module.rb +83 -0
  62. data/lib/apipie/application.rb +462 -0
  63. data/lib/apipie/configuration.rb +186 -0
  64. data/lib/apipie/dsl_definition.rb +607 -0
  65. data/lib/apipie/error_description.rb +44 -0
  66. data/lib/apipie/errors.rb +86 -0
  67. data/lib/apipie/extractor.rb +177 -0
  68. data/lib/apipie/extractor/collector.rb +117 -0
  69. data/lib/apipie/extractor/recorder.rb +166 -0
  70. data/lib/apipie/extractor/writer.rb +454 -0
  71. data/lib/apipie/helpers.rb +73 -0
  72. data/lib/apipie/markup.rb +48 -0
  73. data/lib/apipie/method_description.rb +273 -0
  74. data/lib/apipie/middleware/checksum_in_headers.rb +35 -0
  75. data/lib/apipie/param_description.rb +280 -0
  76. data/lib/apipie/railtie.rb +9 -0
  77. data/lib/apipie/resource_description.rb +124 -0
  78. data/lib/apipie/response_description.rb +131 -0
  79. data/lib/apipie/response_description_adapter.rb +200 -0
  80. data/lib/apipie/routes_formatter.rb +33 -0
  81. data/lib/apipie/routing.rb +16 -0
  82. data/lib/apipie/rspec/response_validation_helper.rb +192 -0
  83. data/lib/apipie/see_description.rb +39 -0
  84. data/lib/apipie/static_dispatcher.rb +69 -0
  85. data/lib/apipie/swagger_generator.rb +707 -0
  86. data/lib/apipie/tag_list_description.rb +11 -0
  87. data/lib/apipie/validator.rb +526 -0
  88. data/lib/apipie/version.rb +3 -0
  89. data/lib/apipierails3.rb +25 -0
  90. data/lib/generators/apipie/install/README +6 -0
  91. data/lib/generators/apipie/install/install_generator.rb +25 -0
  92. data/lib/generators/apipie/install/templates/initializer.rb.erb +7 -0
  93. data/lib/generators/apipie/views_generator.rb +11 -0
  94. data/lib/tasks/apipie.rake +345 -0
  95. data/rel-eng/packages/.readme +3 -0
  96. data/rel-eng/packages/rubygem-apipie-rails +1 -0
  97. data/rel-eng/tito.props +5 -0
  98. data/spec/controllers/api/v1/architectures_controller_spec.rb +29 -0
  99. data/spec/controllers/api/v2/architectures_controller_spec.rb +12 -0
  100. data/spec/controllers/api/v2/nested/resources_controller_spec.rb +11 -0
  101. data/spec/controllers/apipies_controller_spec.rb +273 -0
  102. data/spec/controllers/concerns_controller_spec.rb +42 -0
  103. data/spec/controllers/extended_controller_spec.rb +11 -0
  104. data/spec/controllers/users_controller_spec.rb +740 -0
  105. data/spec/dummy/Rakefile +7 -0
  106. data/spec/dummy/app/controllers/api/base_controller.rb +4 -0
  107. data/spec/dummy/app/controllers/api/v1/architectures_controller.rb +43 -0
  108. data/spec/dummy/app/controllers/api/v1/base_controller.rb +11 -0
  109. data/spec/dummy/app/controllers/api/v2/architectures_controller.rb +30 -0
  110. data/spec/dummy/app/controllers/api/v2/base_controller.rb +11 -0
  111. data/spec/dummy/app/controllers/api/v2/nested/architectures_controller.rb +32 -0
  112. data/spec/dummy/app/controllers/api/v2/nested/resources_controller.rb +33 -0
  113. data/spec/dummy/app/controllers/application_controller.rb +18 -0
  114. data/spec/dummy/app/controllers/concerns/extending_concern.rb +11 -0
  115. data/spec/dummy/app/controllers/concerns/sample_controller.rb +41 -0
  116. data/spec/dummy/app/controllers/concerns_controller.rb +8 -0
  117. data/spec/dummy/app/controllers/extended_controller.rb +14 -0
  118. data/spec/dummy/app/controllers/files_controller.rb +5 -0
  119. data/spec/dummy/app/controllers/overridden_concerns_controller.rb +31 -0
  120. data/spec/dummy/app/controllers/pets_controller.rb +408 -0
  121. data/spec/dummy/app/controllers/pets_using_auto_views_controller.rb +73 -0
  122. data/spec/dummy/app/controllers/pets_using_self_describing_classes_controller.rb +95 -0
  123. data/spec/dummy/app/controllers/tagged_cats_controller.rb +32 -0
  124. data/spec/dummy/app/controllers/tagged_dogs_controller.rb +15 -0
  125. data/spec/dummy/app/controllers/twitter_example_controller.rb +307 -0
  126. data/spec/dummy/app/controllers/users_controller.rb +297 -0
  127. data/spec/dummy/app/views/layouts/application.html.erb +21 -0
  128. data/spec/dummy/config.ru +4 -0
  129. data/spec/dummy/config/application.rb +49 -0
  130. data/spec/dummy/config/boot.rb +10 -0
  131. data/spec/dummy/config/database.yml +21 -0
  132. data/spec/dummy/config/environment.rb +8 -0
  133. data/spec/dummy/config/environments/development.rb +28 -0
  134. data/spec/dummy/config/environments/production.rb +52 -0
  135. data/spec/dummy/config/environments/test.rb +38 -0
  136. data/spec/dummy/config/initializers/apipie.rb +110 -0
  137. data/spec/dummy/config/initializers/backtrace_silencers.rb +7 -0
  138. data/spec/dummy/config/initializers/inflections.rb +10 -0
  139. data/spec/dummy/config/initializers/mime_types.rb +5 -0
  140. data/spec/dummy/config/initializers/secret_token.rb +8 -0
  141. data/spec/dummy/config/initializers/session_store.rb +8 -0
  142. data/spec/dummy/config/locales/en.yml +5 -0
  143. data/spec/dummy/config/routes.rb +51 -0
  144. data/spec/dummy/db/.gitkeep +0 -0
  145. data/spec/dummy/doc/apipie_examples.json +1 -0
  146. data/spec/dummy/doc/users/desc_from_file.md +1 -0
  147. data/spec/dummy/public/404.html +26 -0
  148. data/spec/dummy/public/422.html +26 -0
  149. data/spec/dummy/public/500.html +26 -0
  150. data/spec/dummy/public/favicon.ico +0 -0
  151. data/spec/dummy/public/stylesheets/.gitkeep +0 -0
  152. data/spec/dummy/script/rails +6 -0
  153. data/spec/lib/application_spec.rb +49 -0
  154. data/spec/lib/extractor/extractor_spec.rb +9 -0
  155. data/spec/lib/extractor/middleware_spec.rb +44 -0
  156. data/spec/lib/extractor/writer_spec.rb +110 -0
  157. data/spec/lib/file_handler_spec.rb +18 -0
  158. data/spec/lib/method_description_spec.rb +98 -0
  159. data/spec/lib/param_description_spec.rb +345 -0
  160. data/spec/lib/param_group_spec.rb +60 -0
  161. data/spec/lib/rake_spec.rb +71 -0
  162. data/spec/lib/resource_description_spec.rb +48 -0
  163. data/spec/lib/swagger/openapi_2_0_schema.json +1607 -0
  164. data/spec/lib/swagger/rake_swagger_spec.rb +139 -0
  165. data/spec/lib/swagger/response_validation_spec.rb +104 -0
  166. data/spec/lib/swagger/swagger_dsl_spec.rb +658 -0
  167. data/spec/lib/validator_spec.rb +113 -0
  168. data/spec/lib/validators/array_validator_spec.rb +85 -0
  169. data/spec/spec_helper.rb +109 -0
  170. data/spec/support/rake.rb +21 -0
  171. metadata +415 -0
@@ -0,0 +1,28 @@
1
+ 'zh-TW':
2
+ apipie:
3
+ resources: 資源
4
+ resource: 資源
5
+ description: 描述
6
+ no_docs_found: 沒有找到文檔
7
+ no_docs_found_descr: 沒有找到文檔。
8
+ follow_instructions_html: 點擊 %{href} 查看描述。
9
+ follow_instructions_href: 高級指導
10
+ oops: Oops!!
11
+ resource_not_found_html: 沒有找到資源 %{resource} 。
12
+ method_not_found_html: 沒有找到資源 %{resource} 的方法 %{method} 。
13
+ goto_homepage_html: 試圖訪問 %{href}
14
+ goto_homepage_href: "%{app_name} API 文檔主頁"
15
+ required: 必填
16
+ optional: 選填
17
+ nil_allowed: 允許空值
18
+ param_name: 參數名字
19
+ params: 參數
20
+ examples: 示例
21
+ metadata: 元數據
22
+ errors: 錯誤
23
+ supported_formats: 支持格式
24
+ enable_javascript_html: 瀏覽 %{comments_href}前請允許執行 JavaScript 。
25
+ comments_powered_by_disqus: 評論技術支持 %{disqus}
26
+ api_documentation: API 文檔
27
+ headers: 頭部
28
+ header_name: 頭部名字
Binary file
Binary file
@@ -0,0 +1,83 @@
1
+ require "apipie/helpers"
2
+ require "apipie/application"
3
+
4
+ module Apipie
5
+ extend Apipie::Helpers
6
+
7
+ def self.app
8
+ @application ||= Apipie::Application.new
9
+ end
10
+
11
+ def self.to_json(version = nil, resource_name = nil, method_name = nil, lang = nil)
12
+ version ||= Apipie.configuration.default_version
13
+ app.to_json(version, resource_name, method_name, lang)
14
+ end
15
+
16
+ def self.to_swagger_json(version = nil, resource_name = nil, method_name = nil, lang = nil, clear_warnings=true)
17
+ version ||= Apipie.configuration.default_version
18
+ app.to_swagger_json(version, resource_name, method_name, lang, clear_warnings)
19
+ end
20
+
21
+ def self.json_schema_for_method_response(controller_name, method_name, return_code, allow_nulls)
22
+ # note: this does not support versions (only the default version is queried)!
23
+ version ||= Apipie.configuration.default_version
24
+ app.json_schema_for_method_response(version, controller_name, method_name, return_code, allow_nulls)
25
+ end
26
+
27
+ def self.json_schema_for_self_describing_class(cls, allow_nulls=true)
28
+ app.json_schema_for_self_describing_class(cls, allow_nulls)
29
+ end
30
+
31
+
32
+ # all calls delegated to Apipie::Application instance
33
+ def self.method_missing(method, *args, &block)
34
+ app.respond_to?(method) ? app.send(method, *args, &block) : super
35
+ end
36
+
37
+ def self.configure
38
+ yield configuration
39
+ end
40
+
41
+ def self.configuration
42
+ @configuration ||= Configuration.new
43
+ end
44
+
45
+ def self.debug(message)
46
+ puts message if Apipie.configuration.debug
47
+ end
48
+
49
+ # get application description for given or default version
50
+ def self.app_info(version = nil, lang = nil)
51
+ info = if app_info_version_valid? version
52
+ translate(self.configuration.app_info[version], lang)
53
+ elsif app_info_version_valid? Apipie.configuration.default_version
54
+ translate(self.configuration.app_info[Apipie.configuration.default_version], lang)
55
+ else
56
+ "Another API description"
57
+ end
58
+
59
+ Apipie.markup_to_html info
60
+ end
61
+
62
+ def self.api_base_url(version = nil)
63
+ if api_base_url_version_valid? version
64
+ self.configuration.api_base_url[version]
65
+ elsif api_base_url_version_valid? Apipie.configuration.default_version
66
+ self.configuration.api_base_url[Apipie.configuration.default_version]
67
+ else
68
+ "/api"
69
+ end
70
+ end
71
+
72
+ def self.app_info_version_valid?(version)
73
+ version && self.configuration.app_info.has_key?(version)
74
+ end
75
+
76
+ def self.api_base_url_version_valid?(version)
77
+ version && self.configuration.api_base_url.has_key?(version)
78
+ end
79
+
80
+ def self.record(record)
81
+ Apipie::Extractor.start record
82
+ end
83
+ end
@@ -0,0 +1,462 @@
1
+ require 'apipie/static_dispatcher'
2
+ require 'apipie/routes_formatter'
3
+ require 'yaml'
4
+ require 'digest/sha1'
5
+ require 'json'
6
+
7
+ module Apipie
8
+
9
+ class Application
10
+ # we need engine just for serving static assets
11
+ class Engine < Rails::Engine
12
+ initializer "static assets", :before => :build_middleware_stack do |app|
13
+ app.middleware.use ::Apipie::StaticDispatcher, "#{root}/app/public"
14
+ end
15
+ end
16
+
17
+ attr_reader :resource_descriptions
18
+
19
+ def initialize
20
+ super
21
+ init_env
22
+ end
23
+
24
+ def available_versions
25
+ @resource_descriptions.keys.sort
26
+ end
27
+
28
+ def set_resource_id(controller, resource_id)
29
+ @controller_to_resource_id[controller] = resource_id
30
+ end
31
+
32
+ def rails_routes(route_set = nil)
33
+ if route_set.nil? && @rails_routes
34
+ return @rails_routes
35
+ end
36
+ route_set ||= Rails.application.routes
37
+ # ensure routes are loaded
38
+ Rails.application.reload_routes! unless Rails.application.routes.routes.any?
39
+
40
+ flatten_routes = []
41
+
42
+ route_set.routes.each do |route|
43
+ if route.app.respond_to?(:routes) && route.app.routes.is_a?(ActionDispatch::Routing::RouteSet)
44
+ # recursively go though the moutned engines
45
+ flatten_routes.concat(rails_routes(route.app.routes))
46
+ else
47
+ flatten_routes << route
48
+ end
49
+ end
50
+
51
+ @rails_routes = flatten_routes
52
+ end
53
+
54
+ # the app might be nested when using contraints, namespaces etc.
55
+ # this method does in depth search for the route controller
56
+ def route_app_controller(app, route, visited_apps = [])
57
+ if route.defaults[:controller]
58
+ controller_name = "#{route.defaults[:controller]}_controller".camelize
59
+ controller_name.safe_constantize
60
+ end
61
+ end
62
+
63
+ def routes_for_action(controller, method, args)
64
+ routes = rails_routes.select do |route|
65
+ controller == route_app_controller(route.app, route) &&
66
+ method.to_s == route.defaults[:action]
67
+ end
68
+
69
+ Apipie.configuration.routes_formatter.format_routes(routes, args)
70
+ end
71
+
72
+ # create new method api description
73
+ def define_method_description(controller, method_name, dsl_data)
74
+ return if ignored?(controller, method_name)
75
+ ret_method_description = nil
76
+
77
+ versions = dsl_data[:api_versions] || []
78
+ versions = controller_versions(controller) if versions.empty?
79
+
80
+ versions.each do |version|
81
+ resource_name_with_version = "#{version}##{get_resource_name(controller)}"
82
+ resource_description = get_resource_description(resource_name_with_version)
83
+
84
+ if resource_description.nil?
85
+ resource_description = define_resource_description(controller, version)
86
+ end
87
+
88
+ method_description = Apipie::MethodDescription.new(method_name, resource_description, dsl_data)
89
+
90
+ # we create separate method description for each version in
91
+ # case the method belongs to more versions. We return just one
92
+ # becuase the version doesn't matter for the purpose it's used
93
+ # (to wrap the original version with validators)
94
+ ret_method_description ||= method_description
95
+ resource_description.add_method_description(method_description)
96
+ end
97
+
98
+ return ret_method_description
99
+ end
100
+
101
+ # create new resource api description
102
+ def define_resource_description(controller, version, dsl_data = nil)
103
+ return if ignored?(controller)
104
+
105
+ resource_name = get_resource_name(controller)
106
+ resource_description = @resource_descriptions[version][resource_name]
107
+ if resource_description
108
+ # we already defined the description somewhere (probably in
109
+ # some method. Updating just meta data from dsl
110
+ resource_description.update_from_dsl_data(dsl_data) if dsl_data
111
+ else
112
+ resource_description = Apipie::ResourceDescription.new(controller, resource_name, dsl_data, version)
113
+
114
+ Apipie.debug("@resource_descriptions[#{version}][#{resource_name}] = #{resource_description}")
115
+ @resource_descriptions[version][resource_name] ||= resource_description
116
+ end
117
+
118
+ return resource_description
119
+ end
120
+
121
+ # recursively searches what versions has the controller specified in
122
+ # resource_description? It's used to derivate the default value of
123
+ # versions for methods.
124
+ def controller_versions(controller)
125
+ ret = @controller_versions[controller.to_s]
126
+ return ret unless ret.empty?
127
+ if controller == ActionController::Base || controller.nil?
128
+ return [Apipie.configuration.default_version]
129
+ else
130
+ return controller_versions(controller.to_s.constantize.superclass)
131
+ end
132
+ end
133
+
134
+ def set_controller_versions(controller, versions)
135
+ @controller_versions[controller.to_s] = versions
136
+ end
137
+
138
+ def add_param_group(controller, name, &block)
139
+ key = "#{controller.name}##{name}"
140
+ @param_groups[key] = block
141
+ end
142
+
143
+ def get_param_group(controller, name)
144
+ key = "#{controller.name}##{name}"
145
+ if @param_groups.has_key?(key)
146
+ return @param_groups[key]
147
+ else
148
+ raise "param group #{key} not defined"
149
+ end
150
+ end
151
+
152
+ # get api for given method
153
+ #
154
+ # There are two ways how this method can be used:
155
+ # 1) Specify both parameters
156
+ # resource_name:
157
+ # controller class - UsersController
158
+ # string with resource name (plural) and version - "v1#users"
159
+ # method_name: name of the method (string or symbol)
160
+ #
161
+ # 2) Specify only first parameter:
162
+ # resource_name: string containing both resource and method name joined
163
+ # with '#' symbol.
164
+ # - "users#create" get default version
165
+ # - "v2#users#create" get specific version
166
+ def get_method_description(resource_name, method_name = nil)
167
+ if resource_name.is_a?(String)
168
+ crumbs = resource_name.split('#')
169
+ if method_name.nil?
170
+ method_name = crumbs.pop
171
+ end
172
+ resource_name = crumbs.join("#")
173
+ resource_description = get_resource_description(resource_name)
174
+ elsif resource_name.respond_to? :apipie_resource_descriptions
175
+ resource_description = get_resource_description(resource_name)
176
+ else
177
+ raise ArgumentError.new("Resource #{resource_name} does not exists.")
178
+ end
179
+ unless resource_description.nil?
180
+ resource_description.method_description(method_name.to_sym)
181
+ end
182
+ end
183
+ alias :[] :get_method_description
184
+
185
+ # options:
186
+ # => "users"
187
+ # => "v2#users"
188
+ # => V2::UsersController
189
+ def get_resource_description(resource, version = nil)
190
+ if resource.is_a?(String)
191
+ crumbs = resource.split('#')
192
+ if crumbs.size == 2
193
+ version = crumbs.first
194
+ end
195
+ version ||= Apipie.configuration.default_version
196
+ if @resource_descriptions.has_key?(version)
197
+ return @resource_descriptions[version][crumbs.last]
198
+ end
199
+ else
200
+ resource_name = get_resource_name(resource)
201
+ if version
202
+ resource_name = "#{version}##{resource_name}"
203
+ end
204
+
205
+ if resource_name.nil?
206
+ return nil
207
+ end
208
+ resource_description = get_resource_description(resource_name)
209
+ if resource_description && resource_description.controller.to_s == resource.to_s
210
+ return resource_description
211
+ end
212
+ end
213
+ end
214
+
215
+ # get all versions of resource description
216
+ def get_resource_descriptions(resource)
217
+ available_versions.map do |version|
218
+ get_resource_description(resource, version)
219
+ end.compact
220
+ end
221
+
222
+ # get all versions of method description
223
+ def get_method_descriptions(resource, method)
224
+ get_resource_descriptions(resource).map do |resource_description|
225
+ resource_description.method_description(method.to_sym)
226
+ end.compact
227
+ end
228
+
229
+ def remove_method_description(resource, versions, method_name)
230
+ versions.each do |version|
231
+ resource = get_resource_name(resource)
232
+ if resource_description = get_resource_description("#{version}##{resource}")
233
+ resource_description.remove_method_description(method_name)
234
+ end
235
+ end
236
+ end
237
+
238
+ # initialize variables for gathering dsl data
239
+ def init_env
240
+ @resource_descriptions ||= HashWithIndifferentAccess.new { |h, version| h[version] = {} }
241
+ @controller_to_resource_id ||= {}
242
+ @param_groups ||= {}
243
+ @swagger_generator = Apipie::SwaggerGenerator.new(self)
244
+
245
+ # what versions does the controller belong in (specified by resource_description)?
246
+ @controller_versions ||= Hash.new { |h, controller| h[controller.to_s] = [] }
247
+ end
248
+
249
+ def recorded_examples
250
+ return @recorded_examples if @recorded_examples
251
+ @recorded_examples = Apipie::Extractor::Writer.load_recorded_examples
252
+ end
253
+
254
+ def reload_examples
255
+ @recorded_examples = nil
256
+ end
257
+
258
+ def json_schema_for_method_response(version, controller_name, method_name, return_code, allow_nulls)
259
+ method = @resource_descriptions[version][controller_name].method_description(method_name)
260
+ raise NoDocumentedMethod.new(controller_name, method_name) if method.nil?
261
+ @swagger_generator.json_schema_for_method_response(method, return_code, allow_nulls)
262
+ end
263
+
264
+ def json_schema_for_self_describing_class(cls, allow_nulls)
265
+ @swagger_generator.json_schema_for_self_describing_class(cls, allow_nulls)
266
+ end
267
+
268
+ def to_swagger_json(version, resource_name, method_name, lang, clear_warnings=false)
269
+ return unless valid_search_args?(version, resource_name, method_name)
270
+
271
+ # if resource_name is blank, take just resources which have some methods because
272
+ # we dont want to show eg ApplicationController as resource
273
+ # otherwise, take only the specified resource
274
+ _resources = resource_descriptions[version].inject({}) do |result, (k,v)|
275
+ if resource_name.blank?
276
+ result[k] = v unless v._methods.blank?
277
+ else
278
+ result[k] = v if k == resource_name
279
+ end
280
+ result
281
+ end
282
+
283
+ @swagger_generator.generate_from_resources(version,_resources, method_name, lang, clear_warnings)
284
+ end
285
+
286
+ def to_json(version, resource_name, method_name, lang)
287
+
288
+ return unless valid_search_args?(version, resource_name, method_name)
289
+
290
+ _resources = if resource_name.blank?
291
+ # take just resources which have some methods because
292
+ # we dont want to show eg ApplicationController as resource
293
+ resource_descriptions[version].inject({}) do |result, (k,v)|
294
+ result[k] = v.to_json(nil, lang) unless v._methods.blank?
295
+ result
296
+ end
297
+ else
298
+ [@resource_descriptions[version][resource_name].to_json(method_name, lang)]
299
+ end
300
+
301
+ url_args = Apipie.configuration.version_in_url ? version : ''
302
+
303
+ {
304
+ :docs => {
305
+ :name => Apipie.configuration.app_name,
306
+ :info => Apipie.app_info(version, lang),
307
+ :copyright => Apipie.configuration.copyright,
308
+ :doc_url => Apipie.full_url(url_args),
309
+ :api_url => Apipie.api_base_url(version),
310
+ :resources => _resources
311
+ }
312
+ }
313
+ end
314
+
315
+ def api_controllers_paths
316
+ Dir.glob(Apipie.configuration.api_controllers_matcher)
317
+ end
318
+
319
+ def reload_documentation
320
+ # don't load translated strings, we'll translate them later
321
+ old_locale = locale
322
+ locale = Apipie.configuration.default_locale
323
+
324
+ rails_mark_classes_for_reload
325
+
326
+ api_controllers_paths.each do |f|
327
+ load_controller_from_file f
328
+ end
329
+ @checksum = nil if Apipie.configuration.update_checksum
330
+
331
+ locale = old_locale
332
+ end
333
+
334
+ def load_documentation
335
+ if !@documentation_loaded || Apipie.configuration.reload_controllers?
336
+ Apipie.reload_documentation
337
+ @documentation_loaded = true
338
+ end
339
+ end
340
+
341
+ def compute_checksum
342
+ if Apipie.configuration.use_cache?
343
+ file_base = File.join(Apipie.configuration.cache_dir, Apipie.configuration.doc_base_url)
344
+ all_docs = {}
345
+ Dir.glob(file_base + '/*.json').sort.each do |f|
346
+ all_docs[File.basename(f, '.json')] = JSON.parse(File.read(f))
347
+ end
348
+ else
349
+ load_documentation if available_versions == []
350
+ all_docs = Apipie.available_versions.inject({}) do |all, version|
351
+ all.update(version => Apipie.to_json(version))
352
+ end
353
+ end
354
+ Digest::SHA1.hexdigest(JSON.dump(all_docs))
355
+ end
356
+
357
+ def checksum
358
+ @checksum ||= compute_checksum
359
+ end
360
+
361
+ # Is there a reason to interpret the DSL for this run?
362
+ # with specific setting for some environment there is no reason the dsl
363
+ # should be interpreted (e.g. no validations and doc from cache)
364
+ def active_dsl?
365
+ Apipie.configuration.validate? || ! Apipie.configuration.use_cache? || Apipie.configuration.force_dsl?
366
+ end
367
+
368
+ def get_resource_name(klass)
369
+ if klass.class == String
370
+ klass
371
+ elsif @controller_to_resource_id.has_key?(klass)
372
+ @controller_to_resource_id[klass]
373
+ elsif Apipie.configuration.namespaced_resources? && klass.respond_to?(:controller_path)
374
+ return nil if klass == ActionController::Base
375
+ path = klass.controller_path
376
+ path.gsub(version_prefix(klass), "").gsub("/", "-")
377
+ elsif klass.respond_to?(:controller_name)
378
+ return nil if klass == ActionController::Base
379
+ klass.controller_name
380
+ else
381
+ raise "Apipie: Can not resolve resource #{klass} name."
382
+ end
383
+ end
384
+
385
+ def locale
386
+ Apipie.configuration.locale.call(nil) if Apipie.configuration.locale
387
+ end
388
+
389
+ def locale=(locale)
390
+ Apipie.configuration.locale.call(locale) if Apipie.configuration.locale
391
+ end
392
+
393
+ def translate(str, locale)
394
+ if Apipie.configuration.translate
395
+ Apipie.configuration.translate.call(str, locale)
396
+ else
397
+ str
398
+ end
399
+ end
400
+
401
+ private
402
+
403
+ # Make sure that the version/resource_name/method_name are valid combination
404
+ # resource_name and method_name can be nil
405
+ def valid_search_args?(version, resource_name, method_name)
406
+ return false unless self.resource_descriptions.has_key?(version)
407
+ if resource_name
408
+ return false unless self.resource_descriptions[version].has_key?(resource_name)
409
+ if method_name
410
+ resource_description = self.resource_descriptions[version][resource_name]
411
+ return false unless resource_description.valid_method_name?(method_name)
412
+ end
413
+ end
414
+ return true
415
+ end
416
+
417
+ def version_prefix(klass)
418
+ version = controller_versions(klass.to_s).first
419
+ base_url = get_base_url(version)
420
+ return "/" if base_url.blank?
421
+ base_url[1..-1] + "/"
422
+ end
423
+
424
+ def get_base_url(version)
425
+ Apipie.configuration.api_base_url[version]
426
+ end
427
+
428
+ def get_resource_version(resource_description)
429
+ if resource_description.respond_to? :_version
430
+ resource_description._version
431
+ else
432
+ Apipie.configuration.default_version
433
+ end
434
+ end
435
+
436
+ def load_controller_from_file(controller_file)
437
+ controller_class_name = controller_file.gsub(/\A.*\/app\/controllers\//,"").gsub(/\.\w*\Z/,"").camelize
438
+ controller_class_name.constantize
439
+ end
440
+
441
+ def ignored?(controller, method = nil)
442
+ ignored = Apipie.configuration.ignored
443
+ return true if ignored.include?(controller.name)
444
+ return true if ignored.include?("#{controller.name}##{method}")
445
+ end
446
+
447
+ # Since Rails 3.2, the classes are reloaded only on file change.
448
+ # We need to reload all the controller classes to rebuild the
449
+ # docs, therefore we just force to reload all the code. This
450
+ # happens only when reload_controllers is set to true and only
451
+ # when showing the documentation.
452
+ #
453
+ # If cache_classes is set to false, it does nothing,
454
+ # as this would break loading of the controllers.
455
+ def rails_mark_classes_for_reload
456
+ init_env
457
+ reload_examples
458
+ end
459
+
460
+
461
+ end
462
+ end