activesupport 2.3.5 → 3.0.0.beta3

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 (391) hide show
  1. data/CHANGELOG +66 -9
  2. data/lib/active_support/all.rb +2 -7
  3. data/lib/active_support/backtrace_cleaner.rb +31 -9
  4. data/lib/active_support/base64.rb +9 -0
  5. data/lib/active_support/basic_object.rb +7 -10
  6. data/lib/active_support/benchmarkable.rb +60 -0
  7. data/lib/active_support/buffered_logger.rb +14 -9
  8. data/lib/active_support/cache/compressed_mem_cache_store.rb +2 -0
  9. data/lib/active_support/cache/file_store.rb +35 -17
  10. data/lib/active_support/cache/mem_cache_store.rb +32 -23
  11. data/lib/active_support/cache/memory_store.rb +17 -10
  12. data/lib/active_support/cache/strategy/local_cache.rb +9 -1
  13. data/lib/active_support/cache.rb +75 -55
  14. data/lib/active_support/callbacks.rb +490 -169
  15. data/lib/active_support/concern.rb +29 -0
  16. data/lib/active_support/configurable.rb +35 -0
  17. data/lib/active_support/core_ext/array/access.rb +39 -46
  18. data/lib/active_support/core_ext/array/conversions.rb +145 -182
  19. data/lib/active_support/core_ext/array/extract_options.rb +26 -17
  20. data/lib/active_support/core_ext/array/grouping.rb +87 -93
  21. data/lib/active_support/core_ext/array/random_access.rb +4 -10
  22. data/lib/active_support/core_ext/array/uniq_by.rb +17 -0
  23. data/lib/active_support/core_ext/array/wrap.rb +22 -0
  24. data/lib/active_support/core_ext/array.rb +2 -10
  25. data/lib/active_support/core_ext/big_decimal/conversions.rb +27 -0
  26. data/lib/active_support/core_ext/big_decimal.rb +1 -0
  27. data/lib/active_support/core_ext/cgi/escape_skipping_slashes.rb +16 -20
  28. data/lib/active_support/core_ext/cgi.rb +0 -4
  29. data/lib/active_support/core_ext/class/attribute.rb +70 -0
  30. data/lib/active_support/core_ext/class/attribute_accessors.rb +40 -31
  31. data/lib/active_support/core_ext/class/delegating_attributes.rb +37 -40
  32. data/lib/active_support/core_ext/class/inheritable_attributes.rb +100 -11
  33. data/lib/active_support/core_ext/class/subclasses.rb +55 -0
  34. data/lib/active_support/core_ext/class.rb +1 -1
  35. data/lib/active_support/core_ext/date/acts_like.rb +8 -0
  36. data/lib/active_support/core_ext/date/calculations.rb +218 -228
  37. data/lib/active_support/core_ext/date/conversions.rb +87 -96
  38. data/lib/active_support/core_ext/date/freeze.rb +31 -0
  39. data/lib/active_support/core_ext/date_time/acts_like.rb +13 -0
  40. data/lib/active_support/core_ext/date_time/calculations.rb +97 -110
  41. data/lib/active_support/core_ext/date_time/conversions.rb +85 -85
  42. data/lib/active_support/core_ext/date_time/zones.rb +17 -0
  43. data/lib/active_support/core_ext/enumerable.rb +18 -13
  44. data/lib/active_support/core_ext/exception.rb +1 -43
  45. data/lib/active_support/core_ext/file/atomic.rb +35 -40
  46. data/lib/active_support/core_ext/file/path.rb +5 -0
  47. data/lib/active_support/core_ext/file.rb +0 -4
  48. data/lib/active_support/core_ext/float/rounding.rb +15 -20
  49. data/lib/active_support/core_ext/float.rb +0 -6
  50. data/lib/active_support/core_ext/hash/conversions.rb +255 -229
  51. data/lib/active_support/core_ext/hash/deep_merge.rb +12 -19
  52. data/lib/active_support/core_ext/hash/diff.rb +11 -17
  53. data/lib/active_support/core_ext/hash/except.rb +21 -22
  54. data/lib/active_support/core_ext/hash/indifferent_access.rb +8 -137
  55. data/lib/active_support/core_ext/hash/keys.rb +38 -45
  56. data/lib/active_support/core_ext/hash/reverse_merge.rb +25 -32
  57. data/lib/active_support/core_ext/hash/slice.rb +35 -37
  58. data/lib/active_support/core_ext/hash.rb +8 -14
  59. data/lib/active_support/core_ext/integer/inflections.rb +10 -16
  60. data/lib/active_support/core_ext/integer/multiple.rb +6 -0
  61. data/lib/active_support/core_ext/integer/time.rb +36 -42
  62. data/lib/active_support/core_ext/integer.rb +1 -7
  63. data/lib/active_support/core_ext/kernel/debugger.rb +1 -1
  64. data/lib/active_support/core_ext/kernel/reporting.rb +9 -7
  65. data/lib/active_support/core_ext/kernel/requires.rb +3 -1
  66. data/lib/active_support/core_ext/kernel/singleton_class.rb +13 -0
  67. data/lib/active_support/core_ext/kernel.rb +1 -1
  68. data/lib/active_support/core_ext/load_error.rb +16 -32
  69. data/lib/active_support/core_ext/logger.rb +3 -2
  70. data/lib/active_support/core_ext/module/aliasing.rb +64 -68
  71. data/lib/active_support/core_ext/module/anonymous.rb +24 -0
  72. data/lib/active_support/core_ext/module/attr_accessor_with_default.rb +1 -1
  73. data/lib/active_support/core_ext/module/attr_internal.rb +4 -4
  74. data/lib/active_support/core_ext/module/attribute_accessors.rb +48 -42
  75. data/lib/active_support/core_ext/module/delegation.rb +22 -11
  76. data/lib/active_support/core_ext/module/deprecation.rb +9 -0
  77. data/lib/active_support/core_ext/module/introspection.rb +77 -79
  78. data/lib/active_support/core_ext/module/method_names.rb +14 -0
  79. data/lib/active_support/core_ext/module/reachable.rb +10 -0
  80. data/lib/active_support/core_ext/module/remove_method.rb +6 -0
  81. data/lib/active_support/core_ext/module/synchronization.rb +4 -1
  82. data/lib/active_support/core_ext/module.rb +7 -18
  83. data/lib/active_support/core_ext/name_error.rb +3 -4
  84. data/lib/active_support/core_ext/numeric/bytes.rb +35 -41
  85. data/lib/active_support/core_ext/numeric/time.rb +70 -74
  86. data/lib/active_support/core_ext/numeric.rb +1 -8
  87. data/lib/active_support/core_ext/object/acts_like.rb +10 -0
  88. data/lib/active_support/core_ext/object/blank.rb +20 -2
  89. data/lib/active_support/core_ext/object/conversions.rb +4 -15
  90. data/lib/active_support/core_ext/object/duplicable.rb +65 -0
  91. data/lib/active_support/core_ext/object/extending.rb +8 -77
  92. data/lib/active_support/core_ext/object/instance_variables.rb +0 -7
  93. data/lib/active_support/core_ext/object/misc.rb +2 -90
  94. data/lib/active_support/core_ext/object/returning.rb +42 -0
  95. data/lib/active_support/core_ext/object/to_param.rb +49 -0
  96. data/lib/active_support/core_ext/object/to_query.rb +27 -0
  97. data/lib/active_support/core_ext/{try.rb → object/try.rb} +4 -4
  98. data/lib/active_support/core_ext/object/with_options.rb +24 -0
  99. data/lib/active_support/core_ext/object.rb +10 -2
  100. data/lib/active_support/core_ext/proc.rb +3 -1
  101. data/lib/active_support/core_ext/process/daemon.rb +17 -19
  102. data/lib/active_support/core_ext/range/blockless_step.rb +24 -27
  103. data/lib/active_support/core_ext/range/conversions.rb +17 -23
  104. data/lib/active_support/core_ext/range/include_range.rb +18 -27
  105. data/lib/active_support/core_ext/range/overlaps.rb +6 -13
  106. data/lib/active_support/core_ext/range.rb +2 -9
  107. data/lib/active_support/core_ext/regexp.rb +5 -0
  108. data/lib/active_support/core_ext/rexml.rb +12 -7
  109. data/lib/active_support/core_ext/string/access.rb +88 -95
  110. data/lib/active_support/core_ext/string/behavior.rb +6 -12
  111. data/lib/active_support/core_ext/string/conversions.rb +20 -21
  112. data/lib/active_support/core_ext/string/exclude.rb +6 -0
  113. data/lib/active_support/core_ext/string/filters.rb +17 -23
  114. data/lib/active_support/core_ext/string/inflections.rb +147 -154
  115. data/lib/active_support/core_ext/string/interpolation.rb +1 -0
  116. data/lib/active_support/core_ext/string/multibyte.rb +68 -74
  117. data/lib/active_support/core_ext/string/output_safety.rb +105 -44
  118. data/lib/active_support/core_ext/string/starts_ends_with.rb +3 -34
  119. data/lib/active_support/core_ext/string/xchar.rb +10 -3
  120. data/lib/active_support/core_ext/string.rb +6 -20
  121. data/lib/active_support/core_ext/time/acts_like.rb +8 -0
  122. data/lib/active_support/core_ext/time/calculations.rb +276 -299
  123. data/lib/active_support/core_ext/time/conversions.rb +79 -84
  124. data/lib/active_support/core_ext/time/marshal.rb +56 -0
  125. data/lib/active_support/core_ext/time/publicize_conversion_methods.rb +10 -0
  126. data/lib/active_support/core_ext/time/zones.rb +73 -81
  127. data/lib/active_support/core_ext/uri.rb +2 -1
  128. data/lib/active_support/core_ext.rb +2 -7
  129. data/lib/active_support/dependencies/autoload.rb +50 -0
  130. data/lib/active_support/dependencies.rb +168 -197
  131. data/lib/active_support/deprecation/behaviors.rb +38 -0
  132. data/lib/active_support/deprecation/method_wrappers.rb +29 -0
  133. data/lib/active_support/deprecation/proxy_wrappers.rb +74 -0
  134. data/lib/active_support/deprecation/reporting.rb +56 -0
  135. data/lib/active_support/deprecation.rb +9 -187
  136. data/lib/active_support/duration.rb +6 -2
  137. data/lib/active_support/hash_with_indifferent_access.rb +141 -0
  138. data/lib/active_support/i18n.rb +3 -0
  139. data/lib/active_support/inflections.rb +1 -1
  140. data/lib/active_support/inflector/inflections.rb +211 -0
  141. data/lib/active_support/inflector/methods.rb +141 -0
  142. data/lib/active_support/inflector/transliterate.rb +77 -0
  143. data/lib/active_support/inflector.rb +4 -403
  144. data/lib/active_support/json/backends/jsongem.rb +16 -10
  145. data/lib/active_support/json/backends/yajl.rb +40 -0
  146. data/lib/active_support/json/backends/yaml.rb +14 -8
  147. data/lib/active_support/json/decoding.rb +17 -1
  148. data/lib/active_support/json/encoding.rb +164 -35
  149. data/lib/active_support/json/variable.rb +4 -3
  150. data/lib/active_support/lazy_load_hooks.rb +17 -0
  151. data/lib/active_support/memoizable.rb +8 -5
  152. data/lib/active_support/message_encryptor.rb +1 -0
  153. data/lib/active_support/message_verifier.rb +12 -29
  154. data/lib/active_support/multibyte/chars.rb +88 -31
  155. data/lib/active_support/multibyte/unicode_database.rb +5 -5
  156. data/lib/active_support/multibyte/utils.rb +6 -7
  157. data/lib/active_support/multibyte.rb +11 -6
  158. data/lib/active_support/notifications/fanout.rb +83 -0
  159. data/lib/active_support/notifications/instrumenter.rb +50 -0
  160. data/lib/active_support/notifications.rb +81 -0
  161. data/lib/active_support/option_merger.rb +2 -0
  162. data/lib/active_support/ordered_hash.rb +28 -11
  163. data/lib/active_support/ordered_options.rb +9 -1
  164. data/lib/active_support/railtie.rb +64 -0
  165. data/lib/active_support/rescuable.rb +11 -6
  166. data/lib/active_support/ruby/shim.rb +21 -0
  167. data/lib/active_support/test_case.rb +10 -8
  168. data/lib/active_support/testing/assertions.rb +17 -0
  169. data/lib/active_support/testing/declarative.rb +31 -12
  170. data/lib/active_support/testing/deprecation.rb +8 -10
  171. data/lib/active_support/testing/isolation.rb +153 -0
  172. data/lib/active_support/testing/pending.rb +48 -0
  173. data/lib/active_support/testing/performance.rb +342 -339
  174. data/lib/active_support/testing/setup_and_teardown.rb +48 -31
  175. data/lib/active_support/time/autoload.rb +5 -0
  176. data/lib/active_support/time.rb +34 -0
  177. data/lib/active_support/time_with_zone.rb +18 -12
  178. data/lib/active_support/values/time_zone.rb +51 -68
  179. data/lib/active_support/version.rb +5 -4
  180. data/lib/active_support/whiny_nil.rb +5 -9
  181. data/lib/active_support/xml_mini/jdom.rb +13 -7
  182. data/lib/active_support/xml_mini/libxml.rb +38 -91
  183. data/lib/active_support/xml_mini/libxmlsax.rb +85 -0
  184. data/lib/active_support/xml_mini/nokogiri.rb +40 -31
  185. data/lib/active_support/xml_mini/nokogirisax.rb +83 -0
  186. data/lib/active_support/xml_mini/rexml.rb +30 -9
  187. data/lib/active_support/xml_mini.rb +2 -0
  188. data/lib/active_support.rb +46 -30
  189. metadata +136 -215
  190. data/lib/active_support/cache/drb_store.rb +0 -14
  191. data/lib/active_support/core_ext/array/wrapper.rb +0 -24
  192. data/lib/active_support/core_ext/base64/encoding.rb +0 -16
  193. data/lib/active_support/core_ext/base64.rb +0 -4
  194. data/lib/active_support/core_ext/bigdecimal/conversions.rb +0 -37
  195. data/lib/active_support/core_ext/bigdecimal.rb +0 -6
  196. data/lib/active_support/core_ext/blank.rb +0 -2
  197. data/lib/active_support/core_ext/class/removal.rb +0 -50
  198. data/lib/active_support/core_ext/date/behavior.rb +0 -42
  199. data/lib/active_support/core_ext/date.rb +0 -10
  200. data/lib/active_support/core_ext/date_time.rb +0 -12
  201. data/lib/active_support/core_ext/duplicable.rb +0 -43
  202. data/lib/active_support/core_ext/float/time.rb +0 -27
  203. data/lib/active_support/core_ext/integer/even_odd.rb +0 -29
  204. data/lib/active_support/core_ext/kernel/daemonizing.rb +0 -7
  205. data/lib/active_support/core_ext/module/inclusion.rb +0 -30
  206. data/lib/active_support/core_ext/module/loading.rb +0 -23
  207. data/lib/active_support/core_ext/module/model_naming.rb +0 -25
  208. data/lib/active_support/core_ext/numeric/conversions.rb +0 -19
  209. data/lib/active_support/core_ext/object/metaclass.rb +0 -13
  210. data/lib/active_support/core_ext/pathname/clean_within.rb +0 -14
  211. data/lib/active_support/core_ext/pathname.rb +0 -7
  212. data/lib/active_support/core_ext/string/bytesize.rb +0 -5
  213. data/lib/active_support/core_ext/string/iterators.rb +0 -23
  214. data/lib/active_support/core_ext/symbol.rb +0 -14
  215. data/lib/active_support/core_ext/time/behavior.rb +0 -13
  216. data/lib/active_support/core_ext/time.rb +0 -42
  217. data/lib/active_support/json/encoders/date.rb +0 -22
  218. data/lib/active_support/json/encoders/date_time.rb +0 -22
  219. data/lib/active_support/json/encoders/enumerable.rb +0 -17
  220. data/lib/active_support/json/encoders/false_class.rb +0 -7
  221. data/lib/active_support/json/encoders/hash.rb +0 -56
  222. data/lib/active_support/json/encoders/nil_class.rb +0 -7
  223. data/lib/active_support/json/encoders/numeric.rb +0 -21
  224. data/lib/active_support/json/encoders/object.rb +0 -10
  225. data/lib/active_support/json/encoders/regexp.rb +0 -9
  226. data/lib/active_support/json/encoders/string.rb +0 -9
  227. data/lib/active_support/json/encoders/symbol.rb +0 -5
  228. data/lib/active_support/json/encoders/time.rb +0 -22
  229. data/lib/active_support/json/encoders/true_class.rb +0 -7
  230. data/lib/active_support/vendor/builder-2.1.2/blankslate.rb +0 -113
  231. data/lib/active_support/vendor/builder-2.1.2/builder/blankslate.rb +0 -20
  232. data/lib/active_support/vendor/builder-2.1.2/builder/css.rb +0 -250
  233. data/lib/active_support/vendor/builder-2.1.2/builder/xchar.rb +0 -115
  234. data/lib/active_support/vendor/builder-2.1.2/builder/xmlbase.rb +0 -139
  235. data/lib/active_support/vendor/builder-2.1.2/builder/xmlevents.rb +0 -63
  236. data/lib/active_support/vendor/builder-2.1.2/builder/xmlmarkup.rb +0 -328
  237. data/lib/active_support/vendor/builder-2.1.2/builder.rb +0 -13
  238. data/lib/active_support/vendor/i18n-0.1.3/MIT-LICENSE +0 -20
  239. data/lib/active_support/vendor/i18n-0.1.3/README.textile +0 -20
  240. data/lib/active_support/vendor/i18n-0.1.3/Rakefile +0 -5
  241. data/lib/active_support/vendor/i18n-0.1.3/i18n.gemspec +0 -27
  242. data/lib/active_support/vendor/i18n-0.1.3/lib/i18n/backend/simple.rb +0 -214
  243. data/lib/active_support/vendor/i18n-0.1.3/lib/i18n/exceptions.rb +0 -53
  244. data/lib/active_support/vendor/i18n-0.1.3/lib/i18n.rb +0 -199
  245. data/lib/active_support/vendor/i18n-0.1.3/test/all.rb +0 -5
  246. data/lib/active_support/vendor/i18n-0.1.3/test/i18n_exceptions_test.rb +0 -99
  247. data/lib/active_support/vendor/i18n-0.1.3/test/i18n_test.rb +0 -124
  248. data/lib/active_support/vendor/i18n-0.1.3/test/locale/en.rb +0 -1
  249. data/lib/active_support/vendor/i18n-0.1.3/test/locale/en.yml +0 -3
  250. data/lib/active_support/vendor/i18n-0.1.3/test/simple_backend_test.rb +0 -567
  251. data/lib/active_support/vendor/memcache-client-1.7.4/memcache.rb +0 -1107
  252. data/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/data_timezone.rb +0 -47
  253. data/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/data_timezone_info.rb +0 -228
  254. data/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/Africa/Algiers.rb +0 -55
  255. data/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/Africa/Cairo.rb +0 -219
  256. data/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/Africa/Casablanca.rb +0 -40
  257. data/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/Africa/Harare.rb +0 -18
  258. data/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/Africa/Johannesburg.rb +0 -25
  259. data/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/Africa/Monrovia.rb +0 -22
  260. data/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/Africa/Nairobi.rb +0 -23
  261. data/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/America/Argentina/Buenos_Aires.rb +0 -166
  262. data/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/America/Argentina/San_Juan.rb +0 -86
  263. data/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/America/Bogota.rb +0 -23
  264. data/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/America/Caracas.rb +0 -23
  265. data/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/America/Chicago.rb +0 -283
  266. data/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/America/Chihuahua.rb +0 -136
  267. data/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/America/Denver.rb +0 -204
  268. data/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/America/Godthab.rb +0 -161
  269. data/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/America/Guatemala.rb +0 -27
  270. data/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/America/Halifax.rb +0 -274
  271. data/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/America/Indiana/Indianapolis.rb +0 -149
  272. data/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/America/Juneau.rb +0 -194
  273. data/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/America/La_Paz.rb +0 -22
  274. data/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/America/Lima.rb +0 -35
  275. data/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/America/Los_Angeles.rb +0 -232
  276. data/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/America/Mazatlan.rb +0 -139
  277. data/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/America/Mexico_City.rb +0 -144
  278. data/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/America/Monterrey.rb +0 -131
  279. data/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/America/New_York.rb +0 -282
  280. data/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/America/Phoenix.rb +0 -30
  281. data/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/America/Regina.rb +0 -74
  282. data/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/America/Santiago.rb +0 -205
  283. data/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/America/Sao_Paulo.rb +0 -171
  284. data/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/America/St_Johns.rb +0 -288
  285. data/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/America/Tijuana.rb +0 -196
  286. data/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/Asia/Almaty.rb +0 -67
  287. data/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/Asia/Baghdad.rb +0 -73
  288. data/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/Asia/Baku.rb +0 -161
  289. data/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/Asia/Bangkok.rb +0 -20
  290. data/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/Asia/Chongqing.rb +0 -33
  291. data/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/Asia/Colombo.rb +0 -30
  292. data/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/Asia/Dhaka.rb +0 -27
  293. data/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/Asia/Hong_Kong.rb +0 -87
  294. data/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/Asia/Irkutsk.rb +0 -165
  295. data/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/Asia/Jakarta.rb +0 -30
  296. data/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/Asia/Jerusalem.rb +0 -163
  297. data/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/Asia/Kabul.rb +0 -20
  298. data/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/Asia/Kamchatka.rb +0 -163
  299. data/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/Asia/Karachi.rb +0 -30
  300. data/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/Asia/Katmandu.rb +0 -20
  301. data/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/Asia/Kolkata.rb +0 -25
  302. data/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/Asia/Krasnoyarsk.rb +0 -163
  303. data/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/Asia/Kuala_Lumpur.rb +0 -31
  304. data/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/Asia/Kuwait.rb +0 -18
  305. data/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/Asia/Magadan.rb +0 -163
  306. data/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/Asia/Muscat.rb +0 -18
  307. data/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/Asia/Novosibirsk.rb +0 -164
  308. data/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/Asia/Rangoon.rb +0 -24
  309. data/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/Asia/Riyadh.rb +0 -18
  310. data/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/Asia/Seoul.rb +0 -34
  311. data/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/Asia/Shanghai.rb +0 -35
  312. data/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/Asia/Singapore.rb +0 -33
  313. data/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/Asia/Taipei.rb +0 -59
  314. data/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/Asia/Tashkent.rb +0 -47
  315. data/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/Asia/Tbilisi.rb +0 -78
  316. data/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/Asia/Tehran.rb +0 -121
  317. data/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/Asia/Tokyo.rb +0 -30
  318. data/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/Asia/Ulaanbaatar.rb +0 -65
  319. data/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/Asia/Urumqi.rb +0 -33
  320. data/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/Asia/Vladivostok.rb +0 -164
  321. data/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/Asia/Yakutsk.rb +0 -163
  322. data/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/Asia/Yekaterinburg.rb +0 -165
  323. data/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/Asia/Yerevan.rb +0 -165
  324. data/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/Atlantic/Azores.rb +0 -270
  325. data/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/Atlantic/Cape_Verde.rb +0 -23
  326. data/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/Atlantic/South_Georgia.rb +0 -18
  327. data/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/Australia/Adelaide.rb +0 -187
  328. data/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/Australia/Brisbane.rb +0 -35
  329. data/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/Australia/Darwin.rb +0 -29
  330. data/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/Australia/Hobart.rb +0 -193
  331. data/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/Australia/Melbourne.rb +0 -185
  332. data/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/Australia/Perth.rb +0 -37
  333. data/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/Australia/Sydney.rb +0 -185
  334. data/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/Etc/UTC.rb +0 -16
  335. data/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/Europe/Amsterdam.rb +0 -228
  336. data/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/Europe/Athens.rb +0 -185
  337. data/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/Europe/Belgrade.rb +0 -163
  338. data/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/Europe/Berlin.rb +0 -188
  339. data/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/Europe/Bratislava.rb +0 -13
  340. data/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/Europe/Brussels.rb +0 -232
  341. data/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/Europe/Bucharest.rb +0 -181
  342. data/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/Europe/Budapest.rb +0 -197
  343. data/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/Europe/Copenhagen.rb +0 -179
  344. data/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/Europe/Dublin.rb +0 -276
  345. data/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/Europe/Helsinki.rb +0 -163
  346. data/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/Europe/Istanbul.rb +0 -218
  347. data/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/Europe/Kiev.rb +0 -168
  348. data/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/Europe/Lisbon.rb +0 -268
  349. data/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/Europe/Ljubljana.rb +0 -13
  350. data/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/Europe/London.rb +0 -288
  351. data/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/Europe/Madrid.rb +0 -211
  352. data/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/Europe/Minsk.rb +0 -170
  353. data/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/Europe/Moscow.rb +0 -181
  354. data/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/Europe/Paris.rb +0 -232
  355. data/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/Europe/Prague.rb +0 -187
  356. data/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/Europe/Riga.rb +0 -176
  357. data/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/Europe/Rome.rb +0 -215
  358. data/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/Europe/Sarajevo.rb +0 -13
  359. data/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/Europe/Skopje.rb +0 -13
  360. data/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/Europe/Sofia.rb +0 -173
  361. data/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/Europe/Stockholm.rb +0 -165
  362. data/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/Europe/Tallinn.rb +0 -172
  363. data/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/Europe/Vienna.rb +0 -183
  364. data/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/Europe/Vilnius.rb +0 -170
  365. data/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/Europe/Warsaw.rb +0 -212
  366. data/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/Europe/Zagreb.rb +0 -13
  367. data/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/Pacific/Auckland.rb +0 -202
  368. data/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/Pacific/Fiji.rb +0 -23
  369. data/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/Pacific/Guam.rb +0 -22
  370. data/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/Pacific/Honolulu.rb +0 -28
  371. data/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/Pacific/Majuro.rb +0 -20
  372. data/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/Pacific/Midway.rb +0 -25
  373. data/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/Pacific/Noumea.rb +0 -25
  374. data/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/Pacific/Pago_Pago.rb +0 -26
  375. data/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/Pacific/Port_Moresby.rb +0 -20
  376. data/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/Pacific/Tongatapu.rb +0 -27
  377. data/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/info_timezone.rb +0 -52
  378. data/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/linked_timezone.rb +0 -51
  379. data/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/linked_timezone_info.rb +0 -44
  380. data/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/offset_rationals.rb +0 -98
  381. data/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/ruby_core_support.rb +0 -56
  382. data/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/time_or_datetime.rb +0 -292
  383. data/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/timezone.rb +0 -508
  384. data/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/timezone_definition.rb +0 -56
  385. data/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/timezone_info.rb +0 -40
  386. data/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/timezone_offset_info.rb +0 -94
  387. data/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/timezone_period.rb +0 -198
  388. data/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/timezone_transition_info.rb +0 -129
  389. data/lib/active_support/vendor/tzinfo-0.3.12/tzinfo.rb +0 -33
  390. data/lib/active_support/vendor.rb +0 -28
  391. data/lib/activesupport.rb +0 -2
@@ -1,247 +1,273 @@
1
- require 'date'
2
- require 'active_support/core_ext/module/attribute_accessors'
3
-
4
- module ActiveSupport #:nodoc:
5
- # these accessors are here because people using ActiveResource and REST to integrate with other systems
6
- # have to be able to control the default behavior of rename_key. dasherize_xml is set to true to emulate
7
- # existing behavior. In a future version it should be set to false by default.
8
- mattr_accessor :dasherize_xml
9
- mattr_accessor :camelize_xml
10
- self.dasherize_xml = true
11
- self.camelize_xml = false
12
- module CoreExtensions #:nodoc:
13
- module Hash #:nodoc:
14
- module Conversions
15
- # This module exists to decorate files deserialized using Hash.from_xml with
16
- # the <tt>original_filename</tt> and <tt>content_type</tt> methods.
17
- module FileLike #:nodoc:
18
- attr_writer :original_filename, :content_type
19
-
20
- def original_filename
21
- @original_filename || 'untitled'
22
- end
23
-
24
- def content_type
25
- @content_type || 'application/octet-stream'
26
- end
27
- end
1
+ require 'active_support/time'
2
+ require 'active_support/core_ext/array/wrap'
3
+ require 'active_support/core_ext/hash/reverse_merge'
4
+ require 'active_support/core_ext/object/blank'
5
+ require 'active_support/core_ext/string/inflections'
28
6
 
29
- XML_TYPE_NAMES = {
30
- "Symbol" => "symbol",
31
- "Fixnum" => "integer",
32
- "Bignum" => "integer",
33
- "BigDecimal" => "decimal",
34
- "Float" => "float",
35
- "TrueClass" => "boolean",
36
- "FalseClass" => "boolean",
37
- "Date" => "date",
38
- "DateTime" => "datetime",
39
- "Time" => "datetime",
40
- "ActiveSupport::TimeWithZone" => "datetime"
41
- } unless defined?(XML_TYPE_NAMES)
42
-
43
- XML_FORMATTING = {
44
- "symbol" => Proc.new { |symbol| symbol.to_s },
45
- "date" => Proc.new { |date| date.to_s(:db) },
46
- "datetime" => Proc.new { |time| time.xmlschema },
47
- "binary" => Proc.new { |binary| ActiveSupport::Base64.encode64(binary) },
48
- "yaml" => Proc.new { |yaml| yaml.to_yaml }
49
- } unless defined?(XML_FORMATTING)
50
-
51
- # TODO: use Time.xmlschema instead of Time.parse;
52
- # use regexp instead of Date.parse
53
- unless defined?(XML_PARSING)
54
- XML_PARSING = {
55
- "symbol" => Proc.new { |symbol| symbol.to_sym },
56
- "date" => Proc.new { |date| ::Date.parse(date) },
57
- "datetime" => Proc.new { |time| ::Time.parse(time).utc rescue ::DateTime.parse(time).utc },
58
- "integer" => Proc.new { |integer| integer.to_i },
59
- "float" => Proc.new { |float| float.to_f },
60
- "decimal" => Proc.new { |number| BigDecimal(number) },
61
- "boolean" => Proc.new { |boolean| %w(1 true).include?(boolean.strip) },
62
- "string" => Proc.new { |string| string.to_s },
63
- "yaml" => Proc.new { |yaml| YAML::load(yaml) rescue yaml },
64
- "base64Binary" => Proc.new { |bin| ActiveSupport::Base64.decode64(bin) },
65
- "file" => Proc.new do |file, entity|
66
- f = StringIO.new(ActiveSupport::Base64.decode64(file))
67
- f.extend(FileLike)
68
- f.original_filename = entity['name']
69
- f.content_type = entity['content_type']
70
- f
71
- end
72
- }
7
+ class Hash
8
+ # This module exists to decorate files deserialized using Hash.from_xml with
9
+ # the <tt>original_filename</tt> and <tt>content_type</tt> methods.
10
+ module FileLike #:nodoc:
11
+ attr_writer :original_filename, :content_type
73
12
 
74
- XML_PARSING.update(
75
- "double" => XML_PARSING["float"],
76
- "dateTime" => XML_PARSING["datetime"]
77
- )
78
- end
13
+ def original_filename
14
+ @original_filename || 'untitled'
15
+ end
79
16
 
80
- def self.included(klass)
81
- klass.extend(ClassMethods)
82
- end
17
+ def content_type
18
+ @content_type || 'application/octet-stream'
19
+ end
20
+ end
83
21
 
84
- # Converts a hash into a string suitable for use as a URL query string. An optional <tt>namespace</tt> can be
85
- # passed to enclose the param names (see example below).
86
- #
87
- # ==== Examples
88
- # { :name => 'David', :nationality => 'Danish' }.to_query # => "name=David&nationality=Danish"
89
- #
90
- # { :name => 'David', :nationality => 'Danish' }.to_query('user') # => "user%5Bname%5D=David&user%5Bnationality%5D=Danish"
91
- def to_query(namespace = nil)
92
- collect do |key, value|
93
- value.to_query(namespace ? "#{namespace}[#{key}]" : key)
94
- end.sort * '&'
95
- end
96
-
97
- alias_method :to_param, :to_query
98
-
99
- def to_xml(options = {})
100
- require 'builder' unless defined?(Builder)
101
-
102
- options = options.dup
103
- options[:indent] ||= 2
104
- options.reverse_merge!({ :builder => Builder::XmlMarkup.new(:indent => options[:indent]),
105
- :root => "hash" })
106
- options[:builder].instruct! unless options.delete(:skip_instruct)
107
- root = rename_key(options[:root].to_s, options)
108
-
109
- options[:builder].__send__(:method_missing, root) do
110
- each do |key, value|
111
- case value
112
- when ::Hash
113
- value.to_xml(options.merge({ :root => key, :skip_instruct => true }))
114
- when ::Array
115
- value.to_xml(options.merge({ :root => key, :children => key.to_s.singularize, :skip_instruct => true}))
116
- when ::Method, ::Proc
117
- # If the Method or Proc takes two arguments, then
118
- # pass the suggested child element name. This is
119
- # used if the Method or Proc will be operating over
120
- # multiple records and needs to create an containing
121
- # element that will contain the objects being
122
- # serialized.
123
- if 1 == value.arity
124
- value.call(options.merge({ :root => key, :skip_instruct => true }))
125
- else
126
- value.call(options.merge({ :root => key, :skip_instruct => true }), key.to_s.singularize)
127
- end
128
- else
129
- if value.respond_to?(:to_xml)
130
- value.to_xml(options.merge({ :root => key, :skip_instruct => true }))
131
- else
132
- type_name = XML_TYPE_NAMES[value.class.name]
133
-
134
- key = rename_key(key.to_s, options)
135
-
136
- attributes = options[:skip_types] || value.nil? || type_name.nil? ? { } : { :type => type_name }
137
- if value.nil?
138
- attributes[:nil] = true
139
- end
140
-
141
- options[:builder].tag!(key,
142
- XML_FORMATTING[type_name] ? XML_FORMATTING[type_name].call(value) : value,
143
- attributes
144
- )
145
- end
146
- end
147
- end
148
-
149
- yield options[:builder] if block_given?
150
- end
22
+ XML_TYPE_NAMES = {
23
+ "Symbol" => "symbol",
24
+ "Fixnum" => "integer",
25
+ "Bignum" => "integer",
26
+ "BigDecimal" => "decimal",
27
+ "Float" => "float",
28
+ "TrueClass" => "boolean",
29
+ "FalseClass" => "boolean",
30
+ "Date" => "date",
31
+ "DateTime" => "datetime",
32
+ "Time" => "datetime"
33
+ } unless defined?(XML_TYPE_NAMES)
151
34
 
152
- end
35
+ XML_FORMATTING = {
36
+ "symbol" => Proc.new { |symbol| symbol.to_s },
37
+ "date" => Proc.new { |date| date.to_s(:db) },
38
+ "datetime" => Proc.new { |time| time.xmlschema },
39
+ "binary" => Proc.new { |binary| ActiveSupport::Base64.encode64(binary) },
40
+ "yaml" => Proc.new { |yaml| yaml.to_yaml }
41
+ } unless defined?(XML_FORMATTING)
153
42
 
154
- def rename_key(key, options = {})
155
- camelize = options.has_key?(:camelize) ? options[:camelize] : ActiveSupport.camelize_xml
156
- dasherize = options.has_key?(:dasherize) ? options[:dasherize] : ActiveSupport.dasherize_xml
157
- key = key.camelize if camelize
158
- key = key.dasherize if dasherize
159
- key
160
- end
43
+ # TODO: use Time.xmlschema instead of Time.parse;
44
+ # use regexp instead of Date.parse
45
+ unless defined?(XML_PARSING)
46
+ XML_PARSING = {
47
+ "symbol" => Proc.new { |symbol| symbol.to_sym },
48
+ "date" => Proc.new { |date| ::Date.parse(date) },
49
+ "datetime" => Proc.new { |time| ::Time.parse(time).utc rescue ::DateTime.parse(time).utc },
50
+ "integer" => Proc.new { |integer| integer.to_i },
51
+ "float" => Proc.new { |float| float.to_f },
52
+ "decimal" => Proc.new { |number| BigDecimal(number) },
53
+ "boolean" => Proc.new { |boolean| %w(1 true).include?(boolean.strip) },
54
+ "string" => Proc.new { |string| string.to_s },
55
+ "yaml" => Proc.new { |yaml| YAML::load(yaml) rescue yaml },
56
+ "base64Binary" => Proc.new { |bin| ActiveSupport::Base64.decode64(bin) },
57
+ "binary" => Proc.new do |bin, entity|
58
+ case entity['encoding']
59
+ when 'base64'
60
+ ActiveSupport::Base64.decode64(bin)
61
+ # TODO: Add support for other encodings
62
+ else
63
+ bin
64
+ end
65
+ end,
66
+ "file" => Proc.new do |file, entity|
67
+ f = StringIO.new(ActiveSupport::Base64.decode64(file))
68
+ f.extend(FileLike)
69
+ f.original_filename = entity['name']
70
+ f.content_type = entity['content_type']
71
+ f
72
+ end
73
+ }
161
74
 
162
- module ClassMethods
163
- def from_xml(xml)
164
- typecast_xml_value(unrename_keys(XmlMini.parse(xml)))
165
- end
166
-
167
- private
168
- def typecast_xml_value(value)
169
- case value.class.to_s
170
- when 'Hash'
171
- if value['type'] == 'array'
172
- child_key, entries = value.detect { |k,v| k != 'type' } # child_key is throwaway
173
- if entries.nil? || (c = value['__content__'] && c.blank?)
174
- []
175
- else
176
- case entries.class.to_s # something weird with classes not matching here. maybe singleton methods breaking is_a?
177
- when "Array"
178
- entries.collect { |v| typecast_xml_value(v) }
179
- when "Hash"
180
- [typecast_xml_value(entries)]
181
- else
182
- raise "can't typecast #{entries.inspect}"
183
- end
184
- end
185
- elsif value.has_key?("__content__")
186
- content = value["__content__"]
187
- if parser = XML_PARSING[value["type"]]
188
- if parser.arity == 2
189
- XML_PARSING[value["type"]].call(content, value)
190
- else
191
- XML_PARSING[value["type"]].call(content)
192
- end
193
- else
194
- content
195
- end
196
- elsif value['type'] == 'string' && value['nil'] != 'true'
197
- ""
198
- # blank or nil parsed values are represented by nil
199
- elsif value.blank? || value['nil'] == 'true'
200
- nil
201
- # If the type is the only element which makes it then
202
- # this still makes the value nil, except if type is
203
- # a XML node(where type['value'] is a Hash)
204
- elsif value['type'] && value.size == 1 && !value['type'].is_a?(::Hash)
205
- nil
206
- else
207
- xml_value = value.inject({}) do |h,(k,v)|
208
- h[k] = typecast_xml_value(v)
209
- h
210
- end
211
-
212
- # Turn { :files => { :file => #<StringIO> } into { :files => #<StringIO> } so it is compatible with
213
- # how multipart uploaded files from HTML appear
214
- xml_value["file"].is_a?(StringIO) ? xml_value["file"] : xml_value
215
- end
216
- when 'Array'
217
- value.map! { |i| typecast_xml_value(i) }
218
- case value.length
219
- when 0 then nil
220
- when 1 then value.first
221
- else value
222
- end
223
- when 'String'
224
- value
225
- else
226
- raise "can't typecast #{value.class.name} - #{value.inspect}"
75
+ XML_PARSING.update(
76
+ "double" => XML_PARSING["float"],
77
+ "dateTime" => XML_PARSING["datetime"]
78
+ )
79
+ end
80
+
81
+ # Returns a string containing an XML representation of its receiver:
82
+ #
83
+ # {"foo" => 1, "bar" => 2}.to_xml
84
+ # # =>
85
+ # # <?xml version="1.0" encoding="UTF-8"?>
86
+ # # <hash>
87
+ # # <foo type="integer">1</foo>
88
+ # # <bar type="integer">2</bar>
89
+ # # </hash>
90
+ #
91
+ # To do so, the method loops over the pairs and builds nodes that depend on
92
+ # the _values_. Given a pair +key+, +value+:
93
+ #
94
+ # * If +value+ is a hash there's a recursive call with +key+ as <tt>:root</tt>.
95
+ #
96
+ # * If +value+ is an array there's a recursive call with +key+ as <tt>:root</tt>,
97
+ # and +key+ singularized as <tt>:children</tt>.
98
+ #
99
+ # * If +value+ is a callable object it must expect one or two arguments. Depending
100
+ # on the arity, the callable is invoked with the +options+ hash as first argument
101
+ # with +key+ as <tt>:root</tt>, and +key+ singularized as second argument. Its
102
+ # return value becomes a new node.
103
+ #
104
+ # * If +value+ responds to +to_xml+ the method is invoked with +key+ as <tt>:root</tt>.
105
+ #
106
+ # * Otherwise, a node with +key+ as tag is created with a string representation of
107
+ # +value+ as text node. If +value+ is +nil+ an attribute "nil" set to "true" is added.
108
+ # Unless the option <tt>:skip_types</tt> exists and is true, an attribute "type" is
109
+ # added as well according to the following mapping:
110
+ #
111
+ # XML_TYPE_NAMES = {
112
+ # "Symbol" => "symbol",
113
+ # "Fixnum" => "integer",
114
+ # "Bignum" => "integer",
115
+ # "BigDecimal" => "decimal",
116
+ # "Float" => "float",
117
+ # "TrueClass" => "boolean",
118
+ # "FalseClass" => "boolean",
119
+ # "Date" => "date",
120
+ # "DateTime" => "datetime",
121
+ # "Time" => "datetime"
122
+ # }
123
+ #
124
+ # By default the root node is "hash", but that's configurable via the <tt>:root</tt> option.
125
+ #
126
+ # The default XML builder is a fresh instance of <tt>Builder::XmlMarkup</tt>. You can
127
+ # configure your own builder with the <tt>:builder</tt> option. The method also accepts
128
+ # options like <tt>:dasherize</tt> and friends, they are forwarded to the builder.
129
+ def to_xml(options = {})
130
+ require 'builder' unless defined?(Builder)
131
+
132
+ options = options.dup
133
+ options[:indent] ||= 2
134
+ options.reverse_merge!({ :builder => Builder::XmlMarkup.new(:indent => options[:indent]),
135
+ :root => "hash" })
136
+ options[:builder].instruct! unless options.delete(:skip_instruct)
137
+ root = rename_key(options[:root].to_s, options)
138
+
139
+ options[:builder].__send__(:method_missing, root) do
140
+ each do |key, value|
141
+ case value
142
+ when ::Hash
143
+ value.to_xml(options.merge({ :root => key, :skip_instruct => true }))
144
+ when ::Array
145
+ value.to_xml(options.merge({ :root => key, :children => key.to_s.singularize, :skip_instruct => true}))
146
+ when ::Method, ::Proc
147
+ # If the Method or Proc takes two arguments, then
148
+ # pass the suggested child element name. This is
149
+ # used if the Method or Proc will be operating over
150
+ # multiple records and needs to create an containing
151
+ # element that will contain the objects being
152
+ # serialized.
153
+ if 1 == value.arity
154
+ value.call(options.merge({ :root => key, :skip_instruct => true }))
155
+ else
156
+ value.call(options.merge({ :root => key, :skip_instruct => true }), key.to_s.singularize)
157
+ end
158
+ else
159
+ if value.respond_to?(:to_xml)
160
+ value.to_xml(options.merge({ :root => key, :skip_instruct => true }))
161
+ else
162
+ type_name = XML_TYPE_NAMES[value.class.name]
163
+
164
+ key = rename_key(key.to_s, options)
165
+
166
+ attributes = options[:skip_types] || value.nil? || type_name.nil? ? { } : { :type => type_name }
167
+ if value.nil?
168
+ attributes[:nil] = true
227
169
  end
170
+
171
+ options[:builder].tag!(key,
172
+ XML_FORMATTING[type_name] ? XML_FORMATTING[type_name].call(value) : value,
173
+ attributes
174
+ )
228
175
  end
176
+ end
177
+ end
178
+
179
+ yield options[:builder] if block_given?
180
+ end
229
181
 
230
- def unrename_keys(params)
231
- case params.class.to_s
232
- when "Hash"
233
- params.inject({}) do |h,(k,v)|
234
- h[k.to_s.tr("-", "_")] = unrename_keys(v)
235
- h
236
- end
182
+ end
183
+
184
+ def rename_key(key, options = {})
185
+ camelize = options.has_key?(:camelize) && options[:camelize]
186
+ dasherize = !options.has_key?(:dasherize) || options[:dasherize]
187
+ key = key.camelize if camelize
188
+ dasherize ? key.dasherize : key
189
+ end
190
+
191
+ class << self
192
+ def from_xml(xml)
193
+ typecast_xml_value(unrename_keys(ActiveSupport::XmlMini.parse(xml)))
194
+ end
195
+
196
+ private
197
+ def typecast_xml_value(value)
198
+ case value.class.to_s
199
+ when 'Hash'
200
+ if value['type'] == 'array'
201
+ child_key, entries = Array.wrap(value.detect { |k,v| k != 'type' }) # child_key is throwaway
202
+ if entries.nil? || (c = value['__content__'] && c.blank?)
203
+ []
204
+ else
205
+ case entries.class.to_s # something weird with classes not matching here. maybe singleton methods breaking is_a?
237
206
  when "Array"
238
- params.map { |v| unrename_keys(v) }
207
+ entries.collect { |v| typecast_xml_value(v) }
208
+ when "Hash"
209
+ [typecast_xml_value(entries)]
210
+ else
211
+ raise "can't typecast #{entries.inspect}"
212
+ end
213
+ end
214
+ elsif value.has_key?("__content__")
215
+ content = value["__content__"]
216
+ if parser = XML_PARSING[value["type"]]
217
+ if parser.arity == 2
218
+ XML_PARSING[value["type"]].call(content, value)
239
219
  else
240
- params
220
+ XML_PARSING[value["type"]].call(content)
221
+ end
222
+ else
223
+ content
241
224
  end
225
+ elsif value['type'] == 'string' && value['nil'] != 'true'
226
+ ""
227
+ # blank or nil parsed values are represented by nil
228
+ elsif value.blank? || value['nil'] == 'true'
229
+ nil
230
+ # If the type is the only element which makes it then
231
+ # this still makes the value nil, except if type is
232
+ # a XML node(where type['value'] is a Hash)
233
+ elsif value['type'] && value.size == 1 && !value['type'].is_a?(::Hash)
234
+ nil
235
+ else
236
+ xml_value = value.inject({}) do |h,(k,v)|
237
+ h[k] = typecast_xml_value(v)
238
+ h
239
+ end
240
+
241
+ # Turn { :files => { :file => #<StringIO> } into { :files => #<StringIO> } so it is compatible with
242
+ # how multipart uploaded files from HTML appear
243
+ xml_value["file"].is_a?(StringIO) ? xml_value["file"] : xml_value
244
+ end
245
+ when 'Array'
246
+ value.map! { |i| typecast_xml_value(i) }
247
+ case value.length
248
+ when 0 then nil
249
+ when 1 then value.first
250
+ else value
242
251
  end
252
+ when 'String'
253
+ value
254
+ else
255
+ raise "can't typecast #{value.class.name} - #{value.inspect}"
256
+ end
257
+ end
258
+
259
+ def unrename_keys(params)
260
+ case params.class.to_s
261
+ when "Hash"
262
+ params.inject({}) do |h,(k,v)|
263
+ h[k.to_s.tr("-", "_")] = unrename_keys(v)
264
+ h
265
+ end
266
+ when "Array"
267
+ params.map { |v| unrename_keys(v) }
268
+ else
269
+ params
243
270
  end
244
271
  end
245
- end
246
272
  end
247
273
  end
@@ -1,23 +1,16 @@
1
- module ActiveSupport #:nodoc:
2
- module CoreExtensions #:nodoc:
3
- module Hash #:nodoc:
4
- # Allows for deep merging
5
- module DeepMerge
6
- # Returns a new hash with +self+ and +other_hash+ merged recursively.
7
- def deep_merge(other_hash)
8
- self.merge(other_hash) do |key, oldval, newval|
9
- oldval = oldval.to_hash if oldval.respond_to?(:to_hash)
10
- newval = newval.to_hash if newval.respond_to?(:to_hash)
11
- oldval.class.to_s == 'Hash' && newval.class.to_s == 'Hash' ? oldval.deep_merge(newval) : newval
12
- end
13
- end
1
+ class Hash
2
+ # Returns a new hash with +self+ and +other_hash+ merged recursively.
3
+ def deep_merge(other_hash)
4
+ dup.deep_merge!(other_hash)
5
+ end
14
6
 
15
- # Returns a new hash with +self+ and +other_hash+ merged recursively.
16
- # Modifies the receiver in place.
17
- def deep_merge!(other_hash)
18
- replace(deep_merge(other_hash))
19
- end
20
- end
7
+ # Returns a new hash with +self+ and +other_hash+ merged recursively.
8
+ # Modifies the receiver in place.
9
+ def deep_merge!(other_hash)
10
+ other_hash.each_pair do |k,v|
11
+ tv = self[k]
12
+ self[k] = tv.is_a?(Hash) && v.is_a?(Hash) ? tv.deep_merge(v) : v
21
13
  end
14
+ self
22
15
  end
23
16
  end
@@ -1,19 +1,13 @@
1
- module ActiveSupport #:nodoc:
2
- module CoreExtensions #:nodoc:
3
- module Hash #:nodoc:
4
- module Diff
5
- # Returns a hash that represents the difference between two hashes.
6
- #
7
- # Examples:
8
- #
9
- # {1 => 2}.diff(1 => 2) # => {}
10
- # {1 => 2}.diff(1 => 3) # => {1 => 2}
11
- # {}.diff(1 => 2) # => {1 => 2}
12
- # {1 => 2, 3 => 4}.diff(1 => 2) # => {3 => 4}
13
- def diff(h2)
14
- self.dup.delete_if { |k, v| h2[k] == v }.merge(h2.dup.delete_if { |k, v| self.has_key?(k) })
15
- end
16
- end
17
- end
1
+ class Hash
2
+ # Returns a hash that represents the difference between two hashes.
3
+ #
4
+ # Examples:
5
+ #
6
+ # {1 => 2}.diff(1 => 2) # => {}
7
+ # {1 => 2}.diff(1 => 3) # => {1 => 2}
8
+ # {}.diff(1 => 2) # => {1 => 2}
9
+ # {1 => 2, 3 => 4}.diff(1 => 2) # => {3 => 4}
10
+ def diff(h2)
11
+ dup.delete_if { |k, v| h2[k] == v }.merge!(h2.dup.delete_if { |k, v| has_key?(k) })
18
12
  end
19
13
  end
@@ -1,25 +1,24 @@
1
- require 'set'
2
-
3
- module ActiveSupport #:nodoc:
4
- module CoreExtensions #:nodoc:
5
- module Hash #:nodoc:
6
- # Return a hash that includes everything but the given keys. This is useful for
7
- # limiting a set of parameters to everything but a few known toggles:
8
- #
9
- # @person.update_attributes(params[:person].except(:admin))
10
- module Except
11
- # Returns a new hash without the given keys.
12
- def except(*keys)
13
- dup.except!(*keys)
14
- end
1
+ class Hash
2
+ # Return a hash that includes everything but the given keys. This is useful for
3
+ # limiting a set of parameters to everything but a few known toggles:
4
+ #
5
+ # @person.update_attributes(params[:person].except(:admin))
6
+ #
7
+ # If the receiver responds to +convert_key+, the method is called on each of the
8
+ # arguments. This allows +except+ to play nice with hashes with indifferent access
9
+ # for instance:
10
+ #
11
+ # {:a => 1}.with_indifferent_access.except(:a) # => {}
12
+ # {:a => 1}.with_indifferent_access.except("a") # => {}
13
+ #
14
+ def except(*keys)
15
+ dup.except!(*keys)
16
+ end
15
17
 
16
- # Replaces the hash without the given keys.
17
- def except!(*keys)
18
- keys.map! { |key| convert_key(key) } if respond_to?(:convert_key)
19
- keys.each { |key| delete(key) }
20
- self
21
- end
22
- end
23
- end
18
+ # Replaces the hash without the given keys.
19
+ def except!(*keys)
20
+ keys.map! { |key| convert_key(key) } if respond_to?(:convert_key)
21
+ keys.each { |key| delete(key) }
22
+ self
24
23
  end
25
24
  end