activesupport 6.0.0

Sign up to get free protection for your applications and to get access to all the features.

Potentially problematic release.


This version of activesupport might be problematic. Click here for more details.

Files changed (250) hide show
  1. checksums.yaml +7 -0
  2. data/CHANGELOG.md +572 -0
  3. data/MIT-LICENSE +20 -0
  4. data/README.rdoc +40 -0
  5. data/lib/active_support.rb +96 -0
  6. data/lib/active_support/actionable_error.rb +48 -0
  7. data/lib/active_support/all.rb +5 -0
  8. data/lib/active_support/array_inquirer.rb +48 -0
  9. data/lib/active_support/backtrace_cleaner.rb +132 -0
  10. data/lib/active_support/benchmarkable.rb +51 -0
  11. data/lib/active_support/builder.rb +8 -0
  12. data/lib/active_support/cache.rb +830 -0
  13. data/lib/active_support/cache/file_store.rb +196 -0
  14. data/lib/active_support/cache/mem_cache_store.rb +212 -0
  15. data/lib/active_support/cache/memory_store.rb +174 -0
  16. data/lib/active_support/cache/null_store.rb +48 -0
  17. data/lib/active_support/cache/redis_cache_store.rb +488 -0
  18. data/lib/active_support/cache/strategy/local_cache.rb +194 -0
  19. data/lib/active_support/cache/strategy/local_cache_middleware.rb +45 -0
  20. data/lib/active_support/callbacks.rb +856 -0
  21. data/lib/active_support/concern.rb +171 -0
  22. data/lib/active_support/concurrency/load_interlock_aware_monitor.rb +17 -0
  23. data/lib/active_support/concurrency/share_lock.rb +227 -0
  24. data/lib/active_support/configurable.rb +146 -0
  25. data/lib/active_support/core_ext.rb +5 -0
  26. data/lib/active_support/core_ext/array.rb +9 -0
  27. data/lib/active_support/core_ext/array/access.rb +104 -0
  28. data/lib/active_support/core_ext/array/conversions.rb +213 -0
  29. data/lib/active_support/core_ext/array/extract.rb +21 -0
  30. data/lib/active_support/core_ext/array/extract_options.rb +31 -0
  31. data/lib/active_support/core_ext/array/grouping.rb +109 -0
  32. data/lib/active_support/core_ext/array/inquiry.rb +19 -0
  33. data/lib/active_support/core_ext/array/prepend_and_append.rb +5 -0
  34. data/lib/active_support/core_ext/array/wrap.rb +48 -0
  35. data/lib/active_support/core_ext/benchmark.rb +16 -0
  36. data/lib/active_support/core_ext/big_decimal.rb +3 -0
  37. data/lib/active_support/core_ext/big_decimal/conversions.rb +14 -0
  38. data/lib/active_support/core_ext/class.rb +4 -0
  39. data/lib/active_support/core_ext/class/attribute.rb +141 -0
  40. data/lib/active_support/core_ext/class/attribute_accessors.rb +6 -0
  41. data/lib/active_support/core_ext/class/subclasses.rb +54 -0
  42. data/lib/active_support/core_ext/date.rb +7 -0
  43. data/lib/active_support/core_ext/date/acts_like.rb +10 -0
  44. data/lib/active_support/core_ext/date/blank.rb +14 -0
  45. data/lib/active_support/core_ext/date/calculations.rb +146 -0
  46. data/lib/active_support/core_ext/date/conversions.rb +96 -0
  47. data/lib/active_support/core_ext/date/zones.rb +8 -0
  48. data/lib/active_support/core_ext/date_and_time/calculations.rb +351 -0
  49. data/lib/active_support/core_ext/date_and_time/compatibility.rb +16 -0
  50. data/lib/active_support/core_ext/date_and_time/zones.rb +41 -0
  51. data/lib/active_support/core_ext/date_time.rb +7 -0
  52. data/lib/active_support/core_ext/date_time/acts_like.rb +16 -0
  53. data/lib/active_support/core_ext/date_time/blank.rb +14 -0
  54. data/lib/active_support/core_ext/date_time/calculations.rb +211 -0
  55. data/lib/active_support/core_ext/date_time/compatibility.rb +18 -0
  56. data/lib/active_support/core_ext/date_time/conversions.rb +107 -0
  57. data/lib/active_support/core_ext/digest.rb +3 -0
  58. data/lib/active_support/core_ext/digest/uuid.rb +53 -0
  59. data/lib/active_support/core_ext/enumerable.rb +188 -0
  60. data/lib/active_support/core_ext/file.rb +3 -0
  61. data/lib/active_support/core_ext/file/atomic.rb +70 -0
  62. data/lib/active_support/core_ext/hash.rb +10 -0
  63. data/lib/active_support/core_ext/hash/compact.rb +5 -0
  64. data/lib/active_support/core_ext/hash/conversions.rb +263 -0
  65. data/lib/active_support/core_ext/hash/deep_merge.rb +34 -0
  66. data/lib/active_support/core_ext/hash/deep_transform_values.rb +46 -0
  67. data/lib/active_support/core_ext/hash/except.rb +24 -0
  68. data/lib/active_support/core_ext/hash/indifferent_access.rb +24 -0
  69. data/lib/active_support/core_ext/hash/keys.rb +143 -0
  70. data/lib/active_support/core_ext/hash/reverse_merge.rb +25 -0
  71. data/lib/active_support/core_ext/hash/slice.rb +26 -0
  72. data/lib/active_support/core_ext/hash/transform_values.rb +5 -0
  73. data/lib/active_support/core_ext/integer.rb +5 -0
  74. data/lib/active_support/core_ext/integer/inflections.rb +31 -0
  75. data/lib/active_support/core_ext/integer/multiple.rb +12 -0
  76. data/lib/active_support/core_ext/integer/time.rb +22 -0
  77. data/lib/active_support/core_ext/kernel.rb +5 -0
  78. data/lib/active_support/core_ext/kernel/concern.rb +14 -0
  79. data/lib/active_support/core_ext/kernel/reporting.rb +45 -0
  80. data/lib/active_support/core_ext/kernel/singleton_class.rb +8 -0
  81. data/lib/active_support/core_ext/load_error.rb +9 -0
  82. data/lib/active_support/core_ext/marshal.rb +24 -0
  83. data/lib/active_support/core_ext/module.rb +13 -0
  84. data/lib/active_support/core_ext/module/aliasing.rb +31 -0
  85. data/lib/active_support/core_ext/module/anonymous.rb +30 -0
  86. data/lib/active_support/core_ext/module/attr_internal.rb +38 -0
  87. data/lib/active_support/core_ext/module/attribute_accessors.rb +212 -0
  88. data/lib/active_support/core_ext/module/attribute_accessors_per_thread.rb +144 -0
  89. data/lib/active_support/core_ext/module/concerning.rb +134 -0
  90. data/lib/active_support/core_ext/module/delegation.rb +313 -0
  91. data/lib/active_support/core_ext/module/deprecation.rb +25 -0
  92. data/lib/active_support/core_ext/module/introspection.rb +86 -0
  93. data/lib/active_support/core_ext/module/reachable.rb +6 -0
  94. data/lib/active_support/core_ext/module/redefine_method.rb +40 -0
  95. data/lib/active_support/core_ext/module/remove_method.rb +17 -0
  96. data/lib/active_support/core_ext/name_error.rb +38 -0
  97. data/lib/active_support/core_ext/numeric.rb +5 -0
  98. data/lib/active_support/core_ext/numeric/bytes.rb +66 -0
  99. data/lib/active_support/core_ext/numeric/conversions.rb +136 -0
  100. data/lib/active_support/core_ext/numeric/inquiry.rb +5 -0
  101. data/lib/active_support/core_ext/numeric/time.rb +66 -0
  102. data/lib/active_support/core_ext/object.rb +16 -0
  103. data/lib/active_support/core_ext/object/acts_like.rb +21 -0
  104. data/lib/active_support/core_ext/object/blank.rb +155 -0
  105. data/lib/active_support/core_ext/object/conversions.rb +6 -0
  106. data/lib/active_support/core_ext/object/deep_dup.rb +55 -0
  107. data/lib/active_support/core_ext/object/duplicable.rb +49 -0
  108. data/lib/active_support/core_ext/object/inclusion.rb +29 -0
  109. data/lib/active_support/core_ext/object/instance_variables.rb +30 -0
  110. data/lib/active_support/core_ext/object/json.rb +228 -0
  111. data/lib/active_support/core_ext/object/to_param.rb +3 -0
  112. data/lib/active_support/core_ext/object/to_query.rb +89 -0
  113. data/lib/active_support/core_ext/object/try.rb +156 -0
  114. data/lib/active_support/core_ext/object/with_options.rb +82 -0
  115. data/lib/active_support/core_ext/range.rb +7 -0
  116. data/lib/active_support/core_ext/range/compare_range.rb +70 -0
  117. data/lib/active_support/core_ext/range/conversions.rb +41 -0
  118. data/lib/active_support/core_ext/range/each.rb +25 -0
  119. data/lib/active_support/core_ext/range/include_range.rb +9 -0
  120. data/lib/active_support/core_ext/range/include_time_with_zone.rb +23 -0
  121. data/lib/active_support/core_ext/range/overlaps.rb +10 -0
  122. data/lib/active_support/core_ext/regexp.rb +7 -0
  123. data/lib/active_support/core_ext/securerandom.rb +45 -0
  124. data/lib/active_support/core_ext/string.rb +15 -0
  125. data/lib/active_support/core_ext/string/access.rb +114 -0
  126. data/lib/active_support/core_ext/string/behavior.rb +8 -0
  127. data/lib/active_support/core_ext/string/conversions.rb +59 -0
  128. data/lib/active_support/core_ext/string/exclude.rb +13 -0
  129. data/lib/active_support/core_ext/string/filters.rb +145 -0
  130. data/lib/active_support/core_ext/string/indent.rb +45 -0
  131. data/lib/active_support/core_ext/string/inflections.rb +259 -0
  132. data/lib/active_support/core_ext/string/inquiry.rb +15 -0
  133. data/lib/active_support/core_ext/string/multibyte.rb +58 -0
  134. data/lib/active_support/core_ext/string/output_safety.rb +314 -0
  135. data/lib/active_support/core_ext/string/starts_ends_with.rb +6 -0
  136. data/lib/active_support/core_ext/string/strip.rb +27 -0
  137. data/lib/active_support/core_ext/string/zones.rb +16 -0
  138. data/lib/active_support/core_ext/time.rb +7 -0
  139. data/lib/active_support/core_ext/time/acts_like.rb +10 -0
  140. data/lib/active_support/core_ext/time/calculations.rb +344 -0
  141. data/lib/active_support/core_ext/time/compatibility.rb +16 -0
  142. data/lib/active_support/core_ext/time/conversions.rb +72 -0
  143. data/lib/active_support/core_ext/time/zones.rb +113 -0
  144. data/lib/active_support/core_ext/uri.rb +25 -0
  145. data/lib/active_support/current_attributes.rb +203 -0
  146. data/lib/active_support/dependencies.rb +806 -0
  147. data/lib/active_support/dependencies/autoload.rb +79 -0
  148. data/lib/active_support/dependencies/interlock.rb +57 -0
  149. data/lib/active_support/dependencies/zeitwerk_integration.rb +110 -0
  150. data/lib/active_support/deprecation.rb +46 -0
  151. data/lib/active_support/deprecation/behaviors.rb +109 -0
  152. data/lib/active_support/deprecation/constant_accessor.rb +52 -0
  153. data/lib/active_support/deprecation/instance_delegator.rb +39 -0
  154. data/lib/active_support/deprecation/method_wrappers.rb +78 -0
  155. data/lib/active_support/deprecation/proxy_wrappers.rb +173 -0
  156. data/lib/active_support/deprecation/reporting.rb +114 -0
  157. data/lib/active_support/descendants_tracker.rb +109 -0
  158. data/lib/active_support/digest.rb +20 -0
  159. data/lib/active_support/duration.rb +433 -0
  160. data/lib/active_support/duration/iso8601_parser.rb +124 -0
  161. data/lib/active_support/duration/iso8601_serializer.rb +54 -0
  162. data/lib/active_support/encrypted_configuration.rb +45 -0
  163. data/lib/active_support/encrypted_file.rb +100 -0
  164. data/lib/active_support/evented_file_update_checker.rb +235 -0
  165. data/lib/active_support/execution_wrapper.rb +129 -0
  166. data/lib/active_support/executor.rb +8 -0
  167. data/lib/active_support/file_update_checker.rb +163 -0
  168. data/lib/active_support/gem_version.rb +17 -0
  169. data/lib/active_support/gzip.rb +38 -0
  170. data/lib/active_support/hash_with_indifferent_access.rb +399 -0
  171. data/lib/active_support/i18n.rb +16 -0
  172. data/lib/active_support/i18n_railtie.rb +126 -0
  173. data/lib/active_support/inflections.rb +72 -0
  174. data/lib/active_support/inflector.rb +9 -0
  175. data/lib/active_support/inflector/inflections.rb +257 -0
  176. data/lib/active_support/inflector/methods.rb +398 -0
  177. data/lib/active_support/inflector/transliterate.rb +147 -0
  178. data/lib/active_support/json.rb +4 -0
  179. data/lib/active_support/json/decoding.rb +76 -0
  180. data/lib/active_support/json/encoding.rb +134 -0
  181. data/lib/active_support/key_generator.rb +41 -0
  182. data/lib/active_support/lazy_load_hooks.rb +82 -0
  183. data/lib/active_support/locale/en.rb +31 -0
  184. data/lib/active_support/locale/en.yml +135 -0
  185. data/lib/active_support/log_subscriber.rb +135 -0
  186. data/lib/active_support/log_subscriber/test_helper.rb +106 -0
  187. data/lib/active_support/logger.rb +93 -0
  188. data/lib/active_support/logger_silence.rb +45 -0
  189. data/lib/active_support/logger_thread_safe_level.rb +56 -0
  190. data/lib/active_support/message_encryptor.rb +227 -0
  191. data/lib/active_support/message_verifier.rb +205 -0
  192. data/lib/active_support/messages/metadata.rb +71 -0
  193. data/lib/active_support/messages/rotation_configuration.rb +22 -0
  194. data/lib/active_support/messages/rotator.rb +56 -0
  195. data/lib/active_support/multibyte.rb +23 -0
  196. data/lib/active_support/multibyte/chars.rb +216 -0
  197. data/lib/active_support/multibyte/unicode.rb +157 -0
  198. data/lib/active_support/notifications.rb +253 -0
  199. data/lib/active_support/notifications/fanout.rb +244 -0
  200. data/lib/active_support/notifications/instrumenter.rb +164 -0
  201. data/lib/active_support/number_helper.rb +378 -0
  202. data/lib/active_support/number_helper/number_converter.rb +184 -0
  203. data/lib/active_support/number_helper/number_to_currency_converter.rb +46 -0
  204. data/lib/active_support/number_helper/number_to_delimited_converter.rb +31 -0
  205. data/lib/active_support/number_helper/number_to_human_converter.rb +70 -0
  206. data/lib/active_support/number_helper/number_to_human_size_converter.rb +61 -0
  207. data/lib/active_support/number_helper/number_to_percentage_converter.rb +16 -0
  208. data/lib/active_support/number_helper/number_to_phone_converter.rb +60 -0
  209. data/lib/active_support/number_helper/number_to_rounded_converter.rb +56 -0
  210. data/lib/active_support/number_helper/rounding_helper.rb +66 -0
  211. data/lib/active_support/option_merger.rb +27 -0
  212. data/lib/active_support/ordered_hash.rb +50 -0
  213. data/lib/active_support/ordered_options.rb +85 -0
  214. data/lib/active_support/parameter_filter.rb +129 -0
  215. data/lib/active_support/per_thread_registry.rb +60 -0
  216. data/lib/active_support/proxy_object.rb +15 -0
  217. data/lib/active_support/rails.rb +29 -0
  218. data/lib/active_support/railtie.rb +80 -0
  219. data/lib/active_support/reloader.rb +130 -0
  220. data/lib/active_support/rescuable.rb +174 -0
  221. data/lib/active_support/security_utils.rb +31 -0
  222. data/lib/active_support/string_inquirer.rb +34 -0
  223. data/lib/active_support/subscriber.rb +169 -0
  224. data/lib/active_support/tagged_logging.rb +88 -0
  225. data/lib/active_support/test_case.rb +163 -0
  226. data/lib/active_support/testing/assertions.rb +228 -0
  227. data/lib/active_support/testing/autorun.rb +7 -0
  228. data/lib/active_support/testing/constant_lookup.rb +51 -0
  229. data/lib/active_support/testing/declarative.rb +28 -0
  230. data/lib/active_support/testing/deprecation.rb +38 -0
  231. data/lib/active_support/testing/file_fixtures.rb +38 -0
  232. data/lib/active_support/testing/isolation.rb +110 -0
  233. data/lib/active_support/testing/method_call_assertions.rb +70 -0
  234. data/lib/active_support/testing/parallelization.rb +128 -0
  235. data/lib/active_support/testing/setup_and_teardown.rb +55 -0
  236. data/lib/active_support/testing/stream.rb +44 -0
  237. data/lib/active_support/testing/tagged_logging.rb +27 -0
  238. data/lib/active_support/testing/time_helpers.rb +200 -0
  239. data/lib/active_support/time.rb +20 -0
  240. data/lib/active_support/time_with_zone.rb +561 -0
  241. data/lib/active_support/values/time_zone.rb +570 -0
  242. data/lib/active_support/version.rb +10 -0
  243. data/lib/active_support/xml_mini.rb +202 -0
  244. data/lib/active_support/xml_mini/jdom.rb +183 -0
  245. data/lib/active_support/xml_mini/libxml.rb +80 -0
  246. data/lib/active_support/xml_mini/libxmlsax.rb +83 -0
  247. data/lib/active_support/xml_mini/nokogiri.rb +83 -0
  248. data/lib/active_support/xml_mini/nokogirisax.rb +86 -0
  249. data/lib/active_support/xml_mini/rexml.rb +130 -0
  250. metadata +385 -0
@@ -0,0 +1,10 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative "gem_version"
4
+
5
+ module ActiveSupport
6
+ # Returns the version of the currently loaded ActiveSupport as a <tt>Gem::Version</tt>
7
+ def self.version
8
+ gem_version
9
+ end
10
+ end
@@ -0,0 +1,202 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "time"
4
+ require "base64"
5
+ require "bigdecimal"
6
+ require "bigdecimal/util"
7
+ require "active_support/core_ext/module/delegation"
8
+ require "active_support/core_ext/string/inflections"
9
+ require "active_support/core_ext/date_time/calculations"
10
+
11
+ module ActiveSupport
12
+ # = XmlMini
13
+ #
14
+ # To use the much faster libxml parser:
15
+ # gem 'libxml-ruby', '=0.9.7'
16
+ # XmlMini.backend = 'LibXML'
17
+ module XmlMini
18
+ extend self
19
+
20
+ # This module decorates files deserialized using Hash.from_xml with
21
+ # the <tt>original_filename</tt> and <tt>content_type</tt> methods.
22
+ module FileLike #:nodoc:
23
+ attr_writer :original_filename, :content_type
24
+
25
+ def original_filename
26
+ @original_filename || "untitled"
27
+ end
28
+
29
+ def content_type
30
+ @content_type || "application/octet-stream"
31
+ end
32
+ end
33
+
34
+ DEFAULT_ENCODINGS = {
35
+ "binary" => "base64"
36
+ } unless defined?(DEFAULT_ENCODINGS)
37
+
38
+ unless defined?(TYPE_NAMES)
39
+ TYPE_NAMES = {
40
+ "Symbol" => "symbol",
41
+ "Integer" => "integer",
42
+ "BigDecimal" => "decimal",
43
+ "Float" => "float",
44
+ "TrueClass" => "boolean",
45
+ "FalseClass" => "boolean",
46
+ "Date" => "date",
47
+ "DateTime" => "dateTime",
48
+ "Time" => "dateTime",
49
+ "Array" => "array",
50
+ "Hash" => "hash"
51
+ }
52
+ end
53
+
54
+ FORMATTING = {
55
+ "symbol" => Proc.new { |symbol| symbol.to_s },
56
+ "date" => Proc.new { |date| date.to_s(:db) },
57
+ "dateTime" => Proc.new { |time| time.xmlschema },
58
+ "binary" => Proc.new { |binary| ::Base64.encode64(binary) },
59
+ "yaml" => Proc.new { |yaml| yaml.to_yaml }
60
+ } unless defined?(FORMATTING)
61
+
62
+ # TODO use regexp instead of Date.parse
63
+ unless defined?(PARSING)
64
+ PARSING = {
65
+ "symbol" => Proc.new { |symbol| symbol.to_s.to_sym },
66
+ "date" => Proc.new { |date| ::Date.parse(date) },
67
+ "datetime" => Proc.new { |time| Time.xmlschema(time).utc rescue ::DateTime.parse(time).utc },
68
+ "integer" => Proc.new { |integer| integer.to_i },
69
+ "float" => Proc.new { |float| float.to_f },
70
+ "decimal" => Proc.new do |number|
71
+ if String === number
72
+ number.to_d
73
+ else
74
+ BigDecimal(number)
75
+ end
76
+ end,
77
+ "boolean" => Proc.new { |boolean| %w(1 true).include?(boolean.to_s.strip) },
78
+ "string" => Proc.new { |string| string.to_s },
79
+ "yaml" => Proc.new { |yaml| YAML.load(yaml) rescue yaml },
80
+ "base64Binary" => Proc.new { |bin| ::Base64.decode64(bin) },
81
+ "binary" => Proc.new { |bin, entity| _parse_binary(bin, entity) },
82
+ "file" => Proc.new { |file, entity| _parse_file(file, entity) }
83
+ }
84
+
85
+ PARSING.update(
86
+ "double" => PARSING["float"],
87
+ "dateTime" => PARSING["datetime"]
88
+ )
89
+ end
90
+
91
+ attr_accessor :depth
92
+ self.depth = 100
93
+
94
+ delegate :parse, to: :backend
95
+
96
+ def backend
97
+ current_thread_backend || @backend
98
+ end
99
+
100
+ def backend=(name)
101
+ backend = name && cast_backend_name_to_module(name)
102
+ self.current_thread_backend = backend if current_thread_backend
103
+ @backend = backend
104
+ end
105
+
106
+ def with_backend(name)
107
+ old_backend = current_thread_backend
108
+ self.current_thread_backend = name && cast_backend_name_to_module(name)
109
+ yield
110
+ ensure
111
+ self.current_thread_backend = old_backend
112
+ end
113
+
114
+ def to_tag(key, value, options)
115
+ type_name = options.delete(:type)
116
+ merged_options = options.merge(root: key, skip_instruct: true)
117
+
118
+ if value.is_a?(::Method) || value.is_a?(::Proc)
119
+ if value.arity == 1
120
+ value.call(merged_options)
121
+ else
122
+ value.call(merged_options, key.to_s.singularize)
123
+ end
124
+ elsif value.respond_to?(:to_xml)
125
+ value.to_xml(merged_options)
126
+ else
127
+ type_name ||= TYPE_NAMES[value.class.name]
128
+ type_name ||= value.class.name if value && !value.respond_to?(:to_str)
129
+ type_name = type_name.to_s if type_name
130
+ type_name = "dateTime" if type_name == "datetime"
131
+
132
+ key = rename_key(key.to_s, options)
133
+
134
+ attributes = options[:skip_types] || type_name.nil? ? {} : { type: type_name }
135
+ attributes[:nil] = true if value.nil?
136
+
137
+ encoding = options[:encoding] || DEFAULT_ENCODINGS[type_name]
138
+ attributes[:encoding] = encoding if encoding
139
+
140
+ formatted_value = FORMATTING[type_name] && !value.nil? ?
141
+ FORMATTING[type_name].call(value) : value
142
+
143
+ options[:builder].tag!(key, formatted_value, attributes)
144
+ end
145
+ end
146
+
147
+ def rename_key(key, options = {})
148
+ camelize = options[:camelize]
149
+ dasherize = !options.has_key?(:dasherize) || options[:dasherize]
150
+ if camelize
151
+ key = true == camelize ? key.camelize : key.camelize(camelize)
152
+ end
153
+ key = _dasherize(key) if dasherize
154
+ key
155
+ end
156
+
157
+ private
158
+
159
+ def _dasherize(key)
160
+ # $2 must be a non-greedy regex for this to work
161
+ left, middle, right = /\A(_*)(.*?)(_*)\Z/.match(key.strip)[1, 3]
162
+ "#{left}#{middle.tr('_ ', '--')}#{right}"
163
+ end
164
+
165
+ # TODO: Add support for other encodings
166
+ def _parse_binary(bin, entity)
167
+ case entity["encoding"]
168
+ when "base64"
169
+ ::Base64.decode64(bin)
170
+ else
171
+ bin
172
+ end
173
+ end
174
+
175
+ def _parse_file(file, entity)
176
+ f = StringIO.new(::Base64.decode64(file))
177
+ f.extend(FileLike)
178
+ f.original_filename = entity["name"]
179
+ f.content_type = entity["content_type"]
180
+ f
181
+ end
182
+
183
+ def current_thread_backend
184
+ Thread.current[:xml_mini_backend]
185
+ end
186
+
187
+ def current_thread_backend=(name)
188
+ Thread.current[:xml_mini_backend] = name && cast_backend_name_to_module(name)
189
+ end
190
+
191
+ def cast_backend_name_to_module(name)
192
+ if name.is_a?(Module)
193
+ name
194
+ else
195
+ require "active_support/xml_mini/#{name.downcase}"
196
+ ActiveSupport.const_get("XmlMini_#{name}")
197
+ end
198
+ end
199
+ end
200
+
201
+ XmlMini.backend = "REXML"
202
+ end
@@ -0,0 +1,183 @@
1
+ # frozen_string_literal: true
2
+
3
+ raise "JRuby is required to use the JDOM backend for XmlMini" unless RUBY_PLATFORM.include?("java")
4
+
5
+ require "jruby"
6
+ include Java
7
+
8
+ require "active_support/core_ext/object/blank"
9
+
10
+ java_import javax.xml.parsers.DocumentBuilder unless defined? DocumentBuilder
11
+ java_import javax.xml.parsers.DocumentBuilderFactory unless defined? DocumentBuilderFactory
12
+ java_import java.io.StringReader unless defined? StringReader
13
+ java_import org.xml.sax.InputSource unless defined? InputSource
14
+ java_import org.xml.sax.Attributes unless defined? Attributes
15
+ java_import org.w3c.dom.Node unless defined? Node
16
+
17
+ module ActiveSupport
18
+ module XmlMini_JDOM #:nodoc:
19
+ extend self
20
+
21
+ CONTENT_KEY = "__content__"
22
+
23
+ NODE_TYPE_NAMES = %w{ATTRIBUTE_NODE CDATA_SECTION_NODE COMMENT_NODE DOCUMENT_FRAGMENT_NODE
24
+ DOCUMENT_NODE DOCUMENT_TYPE_NODE ELEMENT_NODE ENTITY_NODE ENTITY_REFERENCE_NODE NOTATION_NODE
25
+ PROCESSING_INSTRUCTION_NODE TEXT_NODE}
26
+
27
+ node_type_map = {}
28
+ NODE_TYPE_NAMES.each { |type| node_type_map[Node.send(type)] = type }
29
+
30
+ # Parse an XML Document string or IO into a simple hash using Java's jdom.
31
+ # data::
32
+ # XML Document string or IO to parse
33
+ def parse(data)
34
+ if data.respond_to?(:read)
35
+ data = data.read
36
+ end
37
+
38
+ if data.blank?
39
+ {}
40
+ else
41
+ @dbf = DocumentBuilderFactory.new_instance
42
+ # secure processing of java xml
43
+ # https://archive.is/9xcQQ
44
+ @dbf.setFeature("http://apache.org/xml/features/nonvalidating/load-external-dtd", false)
45
+ @dbf.setFeature("http://xml.org/sax/features/external-general-entities", false)
46
+ @dbf.setFeature("http://xml.org/sax/features/external-parameter-entities", false)
47
+ @dbf.setFeature(javax.xml.XMLConstants::FEATURE_SECURE_PROCESSING, true)
48
+ xml_string_reader = StringReader.new(data)
49
+ xml_input_source = InputSource.new(xml_string_reader)
50
+ doc = @dbf.new_document_builder.parse(xml_input_source)
51
+ merge_element!({ CONTENT_KEY => "" }, doc.document_element, XmlMini.depth)
52
+ end
53
+ end
54
+
55
+ private
56
+
57
+ # Convert an XML element and merge into the hash
58
+ #
59
+ # hash::
60
+ # Hash to merge the converted element into.
61
+ # element::
62
+ # XML element to merge into hash
63
+ def merge_element!(hash, element, depth)
64
+ raise "Document too deep!" if depth == 0
65
+ delete_empty(hash)
66
+ merge!(hash, element.tag_name, collapse(element, depth))
67
+ end
68
+
69
+ def delete_empty(hash)
70
+ hash.delete(CONTENT_KEY) if hash[CONTENT_KEY] == ""
71
+ end
72
+
73
+ # Actually converts an XML document element into a data structure.
74
+ #
75
+ # element::
76
+ # The document element to be collapsed.
77
+ def collapse(element, depth)
78
+ hash = get_attributes(element)
79
+
80
+ child_nodes = element.child_nodes
81
+ if child_nodes.length > 0
82
+ (0...child_nodes.length).each do |i|
83
+ child = child_nodes.item(i)
84
+ merge_element!(hash, child, depth - 1) unless child.node_type == Node.TEXT_NODE
85
+ end
86
+ merge_texts!(hash, element) unless empty_content?(element)
87
+ hash
88
+ else
89
+ merge_texts!(hash, element)
90
+ end
91
+ end
92
+
93
+ # Merge all the texts of an element into the hash
94
+ #
95
+ # hash::
96
+ # Hash to add the converted element to.
97
+ # element::
98
+ # XML element whose texts are to me merged into the hash
99
+ def merge_texts!(hash, element)
100
+ delete_empty(hash)
101
+ text_children = texts(element)
102
+ if text_children.join.empty?
103
+ hash
104
+ else
105
+ # must use value to prevent double-escaping
106
+ merge!(hash, CONTENT_KEY, text_children.join)
107
+ end
108
+ end
109
+
110
+ # Adds a new key/value pair to an existing Hash. If the key to be added
111
+ # already exists and the existing value associated with key is not
112
+ # an Array, it will be wrapped in an Array. Then the new value is
113
+ # appended to that Array.
114
+ #
115
+ # hash::
116
+ # Hash to add key/value pair to.
117
+ # key::
118
+ # Key to be added.
119
+ # value::
120
+ # Value to be associated with key.
121
+ def merge!(hash, key, value)
122
+ if hash.has_key?(key)
123
+ if hash[key].instance_of?(Array)
124
+ hash[key] << value
125
+ else
126
+ hash[key] = [hash[key], value]
127
+ end
128
+ elsif value.instance_of?(Array)
129
+ hash[key] = [value]
130
+ else
131
+ hash[key] = value
132
+ end
133
+ hash
134
+ end
135
+
136
+ # Converts the attributes array of an XML element into a hash.
137
+ # Returns an empty Hash if node has no attributes.
138
+ #
139
+ # element::
140
+ # XML element to extract attributes from.
141
+ def get_attributes(element)
142
+ attribute_hash = {}
143
+ attributes = element.attributes
144
+ (0...attributes.length).each do |i|
145
+ attribute_hash[CONTENT_KEY] ||= ""
146
+ attribute_hash[attributes.item(i).name] = attributes.item(i).value
147
+ end
148
+ attribute_hash
149
+ end
150
+
151
+ # Determines if a document element has text content
152
+ #
153
+ # element::
154
+ # XML element to be checked.
155
+ def texts(element)
156
+ texts = []
157
+ child_nodes = element.child_nodes
158
+ (0...child_nodes.length).each do |i|
159
+ item = child_nodes.item(i)
160
+ if item.node_type == Node.TEXT_NODE
161
+ texts << item.get_data
162
+ end
163
+ end
164
+ texts
165
+ end
166
+
167
+ # Determines if a document element has text content
168
+ #
169
+ # element::
170
+ # XML element to be checked.
171
+ def empty_content?(element)
172
+ text = +""
173
+ child_nodes = element.child_nodes
174
+ (0...child_nodes.length).each do |i|
175
+ item = child_nodes.item(i)
176
+ if item.node_type == Node.TEXT_NODE
177
+ text << item.get_data.strip
178
+ end
179
+ end
180
+ text.strip.length == 0
181
+ end
182
+ end
183
+ end
@@ -0,0 +1,80 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "libxml"
4
+ require "active_support/core_ext/object/blank"
5
+ require "stringio"
6
+
7
+ module ActiveSupport
8
+ module XmlMini_LibXML #:nodoc:
9
+ extend self
10
+
11
+ # Parse an XML Document string or IO into a simple hash using libxml.
12
+ # data::
13
+ # XML Document string or IO to parse
14
+ def parse(data)
15
+ if !data.respond_to?(:read)
16
+ data = StringIO.new(data || "")
17
+ end
18
+
19
+ if data.eof?
20
+ {}
21
+ else
22
+ LibXML::XML::Parser.io(data).parse.to_hash
23
+ end
24
+ end
25
+ end
26
+ end
27
+
28
+ module LibXML #:nodoc:
29
+ module Conversions #:nodoc:
30
+ module Document #:nodoc:
31
+ def to_hash
32
+ root.to_hash
33
+ end
34
+ end
35
+
36
+ module Node #:nodoc:
37
+ CONTENT_ROOT = "__content__"
38
+
39
+ # Convert XML document to hash.
40
+ #
41
+ # hash::
42
+ # Hash to merge the converted element into.
43
+ def to_hash(hash = {})
44
+ node_hash = {}
45
+
46
+ # Insert node hash into parent hash correctly.
47
+ case hash[name]
48
+ when Array then hash[name] << node_hash
49
+ when Hash then hash[name] = [hash[name], node_hash]
50
+ when nil then hash[name] = node_hash
51
+ end
52
+
53
+ # Handle child elements
54
+ each_child do |c|
55
+ if c.element?
56
+ c.to_hash(node_hash)
57
+ elsif c.text? || c.cdata?
58
+ node_hash[CONTENT_ROOT] ||= +""
59
+ node_hash[CONTENT_ROOT] << c.content
60
+ end
61
+ end
62
+
63
+ # Remove content node if it is blank
64
+ if node_hash.length > 1 && node_hash[CONTENT_ROOT].blank?
65
+ node_hash.delete(CONTENT_ROOT)
66
+ end
67
+
68
+ # Handle attributes
69
+ each_attr { |a| node_hash[a.name] = a.value }
70
+
71
+ hash
72
+ end
73
+ end
74
+ end
75
+ end
76
+
77
+ # :enddoc:
78
+
79
+ LibXML::XML::Document.include(LibXML::Conversions::Document)
80
+ LibXML::XML::Node.include(LibXML::Conversions::Node)