activesupport 2.3.2 → 2.3.3
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.
- data/CHANGELOG +7 -0
- data/lib/active_support/cache.rb +14 -1
- data/lib/active_support/cache/mem_cache_store.rb +16 -10
- data/lib/active_support/cache/strategy/local_cache.rb +1 -1
- data/lib/active_support/core_ext/date/calculations.rb +1 -1
- data/lib/active_support/core_ext/hash/conversions.rb +13 -4
- data/lib/active_support/core_ext/kernel/debugger.rb +4 -2
- data/lib/active_support/core_ext/module/attribute_accessors.rb +2 -0
- data/lib/active_support/core_ext/module/delegation.rb +12 -3
- data/lib/active_support/core_ext/module/model_naming.rb +8 -6
- data/lib/active_support/core_ext/numeric/bytes.rb +15 -9
- data/lib/active_support/core_ext/string/access.rb +29 -5
- data/lib/active_support/duration.rb +4 -2
- data/lib/active_support/json.rb +1 -22
- data/lib/active_support/json/backends/jsongem.rb +38 -0
- data/lib/active_support/json/backends/yaml.rb +85 -0
- data/lib/active_support/json/decoding.rb +23 -72
- data/lib/active_support/json/encoders/date.rb +9 -8
- data/lib/active_support/json/encoders/date_time.rb +9 -8
- data/lib/active_support/json/encoders/enumerable.rb +14 -9
- data/lib/active_support/json/encoders/false_class.rb +4 -2
- data/lib/active_support/json/encoders/hash.rb +21 -11
- data/lib/active_support/json/encoders/nil_class.rb +4 -2
- data/lib/active_support/json/encoders/numeric.rb +16 -0
- data/lib/active_support/json/encoders/object.rb +6 -2
- data/lib/active_support/json/encoders/regexp.rb +4 -0
- data/lib/active_support/json/encoders/string.rb +5 -32
- data/lib/active_support/json/encoders/symbol.rb +2 -2
- data/lib/active_support/json/encoders/time.rb +9 -8
- data/lib/active_support/json/encoders/true_class.rb +4 -2
- data/lib/active_support/json/encoding.rb +80 -9
- data/lib/active_support/ordered_hash.rb +28 -0
- data/lib/active_support/test_case.rb +7 -7
- data/lib/active_support/testing/deprecation.rb +2 -0
- data/lib/active_support/time_with_zone.rb +9 -8
- data/lib/active_support/vendor.rb +6 -7
- data/lib/active_support/vendor/i18n-0.1.3/test/i18n_exceptions_test.rb +0 -1
- data/lib/active_support/vendor/i18n-0.1.3/test/i18n_test.rb +0 -1
- data/lib/active_support/vendor/i18n-0.1.3/test/simple_backend_test.rb +0 -1
- data/lib/active_support/vendor/{memcache-client-1.6.5 → memcache-client-1.7.4}/memcache.rb +242 -70
- data/lib/active_support/version.rb +1 -1
- data/lib/active_support/xml_mini/jdom.rb +162 -0
- metadata +10 -4
@@ -1,82 +1,33 @@
|
|
1
|
-
require '
|
2
|
-
require 'strscan'
|
1
|
+
require 'active_support/core_ext/module/attribute_accessors'
|
3
2
|
|
4
3
|
module ActiveSupport
|
4
|
+
# Look for and parse json strings that look like ISO 8601 times.
|
5
|
+
mattr_accessor :parse_json_times
|
6
|
+
|
5
7
|
module JSON
|
6
|
-
class ParseError < StandardError
|
7
|
-
end
|
8
|
-
|
9
8
|
class << self
|
10
|
-
|
11
|
-
def decode(json)
|
12
|
-
YAML.load(convert_json_to_yaml(json))
|
13
|
-
rescue ArgumentError => e
|
14
|
-
raise ParseError, "Invalid JSON string"
|
15
|
-
end
|
16
|
-
|
17
|
-
protected
|
18
|
-
# matches YAML-formatted dates
|
19
|
-
DATE_REGEX = /^(?:\d{4}-\d{2}-\d{2}|\d{4}-\d{1,2}-\d{1,2}[ \t]+\d{1,2}:\d{2}:\d{2}(\.[0-9]*)?(([ \t]*)Z|[-+]\d{2}?(:\d{2})?)?)$/
|
9
|
+
delegate :decode, :to => :backend
|
20
10
|
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
case char = scanner[1]
|
26
|
-
when '"', "'"
|
27
|
-
if !quoting
|
28
|
-
quoting = char
|
29
|
-
pos = scanner.pos
|
30
|
-
elsif quoting == char
|
31
|
-
if json[pos..scanner.pos-2] =~ DATE_REGEX
|
32
|
-
# found a date, track the exact positions of the quotes so we can remove them later.
|
33
|
-
# oh, and increment them for each current mark, each one is an extra padded space that bumps
|
34
|
-
# the position in the final YAML output
|
35
|
-
total_marks = marks.size
|
36
|
-
times << pos+total_marks << scanner.pos+total_marks
|
37
|
-
end
|
38
|
-
quoting = false
|
39
|
-
end
|
40
|
-
when ":",","
|
41
|
-
marks << scanner.pos - 1 unless quoting
|
42
|
-
end
|
43
|
-
end
|
11
|
+
def backend
|
12
|
+
self.backend = "Yaml" unless defined?(@backend)
|
13
|
+
@backend
|
14
|
+
end
|
44
15
|
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
'\\\\'
|
52
|
-
else
|
53
|
-
ustr
|
54
|
-
end
|
55
|
-
end
|
56
|
-
else
|
57
|
-
left_pos = [-1].push(*marks)
|
58
|
-
right_pos = marks << scanner.pos + scanner.rest_size
|
59
|
-
output = []
|
60
|
-
left_pos.each_with_index do |left, i|
|
61
|
-
scanner.pos = left.succ
|
62
|
-
output << scanner.peek(right_pos[i] - scanner.pos + 1).gsub(/\\([\\\/]|u[[:xdigit:]]{4})/) do
|
63
|
-
ustr = $1
|
64
|
-
if ustr.starts_with?('u')
|
65
|
-
[ustr[1..-1].to_i(16)].pack("U")
|
66
|
-
elsif ustr == '\\'
|
67
|
-
'\\\\'
|
68
|
-
else
|
69
|
-
ustr
|
70
|
-
end
|
71
|
-
end
|
72
|
-
end
|
73
|
-
output = output * " "
|
74
|
-
|
75
|
-
times.each { |i| output[i-1] = ' ' }
|
76
|
-
output.gsub!(/\\\//, '/')
|
77
|
-
output
|
78
|
-
end
|
16
|
+
def backend=(name)
|
17
|
+
if name.is_a?(Module)
|
18
|
+
@backend = name
|
19
|
+
else
|
20
|
+
require "active_support/json/backends/#{name.to_s.downcase}.rb"
|
21
|
+
@backend = ActiveSupport::JSON::Backends::const_get(name)
|
79
22
|
end
|
23
|
+
end
|
24
|
+
|
25
|
+
def with_backend(name)
|
26
|
+
old_backend, self.backend = backend, name
|
27
|
+
yield
|
28
|
+
ensure
|
29
|
+
self.backend = old_backend
|
30
|
+
end
|
80
31
|
end
|
81
32
|
end
|
82
33
|
end
|
@@ -1,21 +1,22 @@
|
|
1
1
|
class Date
|
2
|
-
#
|
3
|
-
#
|
2
|
+
# Coerces the date to a string for JSON encoding.
|
3
|
+
#
|
4
|
+
# ISO 8601 format is used if ActiveSupport::JSON::Encoding.use_standard_json_time_format is set.
|
4
5
|
#
|
5
6
|
# ==== Examples
|
6
7
|
#
|
7
|
-
# # With ActiveSupport.use_standard_json_time_format = true
|
8
|
+
# # With ActiveSupport::JSON::Encoding.use_standard_json_time_format = true
|
8
9
|
# Date.new(2005,2,1).to_json
|
9
10
|
# # => "2005-02-01"
|
10
11
|
#
|
11
|
-
# # With ActiveSupport.use_standard_json_time_format = false
|
12
|
+
# # With ActiveSupport::JSON::Encoding.use_standard_json_time_format = false
|
12
13
|
# Date.new(2005,2,1).to_json
|
13
14
|
# # => "2005/02/01"
|
14
|
-
def
|
15
|
-
if ActiveSupport.use_standard_json_time_format
|
16
|
-
|
15
|
+
def as_json(options = nil)
|
16
|
+
if ActiveSupport::JSON::Encoding.use_standard_json_time_format
|
17
|
+
strftime("%Y-%m-%d")
|
17
18
|
else
|
18
|
-
|
19
|
+
strftime("%Y/%m/%d")
|
19
20
|
end
|
20
21
|
end
|
21
22
|
end
|
@@ -1,21 +1,22 @@
|
|
1
1
|
class DateTime
|
2
|
-
#
|
3
|
-
#
|
2
|
+
# Coerces the datetime to a string for JSON encoding.
|
3
|
+
#
|
4
|
+
# ISO 8601 format is used if ActiveSupport::JSON::Encoding.use_standard_json_time_format is set.
|
4
5
|
#
|
5
6
|
# ==== Examples
|
6
7
|
#
|
7
|
-
# # With ActiveSupport.use_standard_json_time_format = true
|
8
|
+
# # With ActiveSupport::JSON::Encoding.use_standard_json_time_format = true
|
8
9
|
# DateTime.civil(2005,2,1,15,15,10).to_json
|
9
10
|
# # => "2005-02-01T15:15:10+00:00"
|
10
11
|
#
|
11
|
-
# # With ActiveSupport.use_standard_json_time_format = false
|
12
|
+
# # With ActiveSupport::JSON::Encoding.use_standard_json_time_format = false
|
12
13
|
# DateTime.civil(2005,2,1,15,15,10).to_json
|
13
14
|
# # => "2005/02/01 15:15:10 +0000"
|
14
|
-
def
|
15
|
-
if ActiveSupport.use_standard_json_time_format
|
16
|
-
xmlschema
|
15
|
+
def as_json(options = nil)
|
16
|
+
if ActiveSupport::JSON::Encoding.use_standard_json_time_format
|
17
|
+
xmlschema
|
17
18
|
else
|
18
|
-
strftime('
|
19
|
+
strftime('%Y/%m/%d %H:%M:%S %z')
|
19
20
|
end
|
20
21
|
end
|
21
22
|
end
|
@@ -1,12 +1,17 @@
|
|
1
1
|
module Enumerable
|
2
|
-
#
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
2
|
+
# Coerces the enumerable to an array for JSON encoding.
|
3
|
+
def as_json(options = nil) #:nodoc:
|
4
|
+
to_a
|
5
|
+
end
|
6
|
+
end
|
7
|
+
|
8
|
+
class Array
|
9
|
+
# Returns a JSON string representing the Array. +options+ are passed to each element.
|
10
|
+
def to_json(options = nil) #:nodoc:
|
11
|
+
"[#{map { |value| ActiveSupport::JSON.encode(value, options) } * ','}]"
|
12
|
+
end
|
13
|
+
|
14
|
+
def as_json(options = nil) #:nodoc:
|
15
|
+
self
|
11
16
|
end
|
12
17
|
end
|
@@ -1,3 +1,5 @@
|
|
1
|
+
require 'active_support/core_ext/array/wrapper'
|
2
|
+
|
1
3
|
class Hash
|
2
4
|
# Returns a JSON string representing the hash.
|
3
5
|
#
|
@@ -28,19 +30,27 @@ class Hash
|
|
28
30
|
# would pass the <tt>:include => :posts</tt> option to <tt>users</tt>,
|
29
31
|
# allowing the posts association in the User model to be converted to JSON
|
30
32
|
# as well.
|
31
|
-
def to_json(options =
|
32
|
-
|
33
|
-
|
34
|
-
if except = options[:except]
|
35
|
-
hash_keys = hash_keys - Array.wrap(except)
|
36
|
-
elsif only = options[:only]
|
37
|
-
hash_keys = hash_keys & Array.wrap(only)
|
38
|
-
end
|
33
|
+
def to_json(options = nil) #:nodoc:
|
34
|
+
hash = as_json(options)
|
39
35
|
|
40
36
|
result = '{'
|
41
|
-
result <<
|
42
|
-
"#{ActiveSupport::JSON.encode(key.to_s)}
|
43
|
-
end * ',
|
37
|
+
result << hash.map do |key, value|
|
38
|
+
"#{ActiveSupport::JSON.encode(key.to_s)}:#{ActiveSupport::JSON.encode(value, options)}"
|
39
|
+
end * ','
|
44
40
|
result << '}'
|
45
41
|
end
|
42
|
+
|
43
|
+
def as_json(options = nil) #:nodoc:
|
44
|
+
if options
|
45
|
+
if attrs = options[:except]
|
46
|
+
except(*Array.wrap(attrs))
|
47
|
+
elsif attrs = options[:only]
|
48
|
+
slice(*Array.wrap(attrs))
|
49
|
+
else
|
50
|
+
self
|
51
|
+
end
|
52
|
+
else
|
53
|
+
self
|
54
|
+
end
|
55
|
+
end
|
46
56
|
end
|
@@ -2,4 +2,20 @@ class Numeric
|
|
2
2
|
def to_json(options = nil) #:nodoc:
|
3
3
|
to_s
|
4
4
|
end
|
5
|
+
|
6
|
+
def as_json(options = nil) #:nodoc:
|
7
|
+
self
|
8
|
+
end
|
9
|
+
end
|
10
|
+
|
11
|
+
class Float
|
12
|
+
def to_json(options = nil) #:nodoc:
|
13
|
+
to_s
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
class Integer
|
18
|
+
def to_json(options = nil) #:nodoc:
|
19
|
+
to_s
|
20
|
+
end
|
5
21
|
end
|
@@ -1,6 +1,10 @@
|
|
1
1
|
class Object
|
2
2
|
# Dumps object in JSON (JavaScript Object Notation). See www.json.org for more info.
|
3
|
-
def to_json(options =
|
4
|
-
ActiveSupport::JSON.encode(
|
3
|
+
def to_json(options = nil)
|
4
|
+
ActiveSupport::JSON.encode(as_json(options))
|
5
|
+
end
|
6
|
+
|
7
|
+
def as_json(options = nil)
|
8
|
+
instance_values
|
5
9
|
end
|
6
10
|
end
|
@@ -1,36 +1,9 @@
|
|
1
|
-
module ActiveSupport
|
2
|
-
module JSON
|
3
|
-
module Encoding
|
4
|
-
mattr_accessor :escape_regex
|
5
|
-
|
6
|
-
ESCAPED_CHARS = {
|
7
|
-
"\010" => '\b',
|
8
|
-
"\f" => '\f',
|
9
|
-
"\n" => '\n',
|
10
|
-
"\r" => '\r',
|
11
|
-
"\t" => '\t',
|
12
|
-
'"' => '\"',
|
13
|
-
'\\' => '\\\\',
|
14
|
-
'>' => '\u003E',
|
15
|
-
'<' => '\u003C',
|
16
|
-
'&' => '\u0026'
|
17
|
-
}
|
18
|
-
end
|
19
|
-
end
|
20
|
-
end
|
21
|
-
|
22
|
-
ActiveSupport.escape_html_entities_in_json = true
|
23
|
-
|
24
1
|
class String
|
25
2
|
def to_json(options = nil) #:nodoc:
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
[\xE0-\xEF][\x80-\xBF]{2}|
|
32
|
-
[\xF0-\xF7][\x80-\xBF]{3})+/nx) { |s|
|
33
|
-
s.unpack("U*").pack("n*").unpack("H*")[0].gsub(/.{4}/, '\\\\u\&')
|
34
|
-
} + '"'
|
3
|
+
ActiveSupport::JSON::Encoding.escape(self)
|
4
|
+
end
|
5
|
+
|
6
|
+
def as_json(options = nil) #:nodoc:
|
7
|
+
self
|
35
8
|
end
|
36
9
|
end
|
@@ -1,21 +1,22 @@
|
|
1
1
|
class Time
|
2
|
-
#
|
3
|
-
#
|
2
|
+
# Coerces the time to a string for JSON encoding.
|
3
|
+
#
|
4
|
+
# ISO 8601 format is used if ActiveSupport::JSON::Encoding.use_standard_json_time_format is set.
|
4
5
|
#
|
5
6
|
# ==== Examples
|
6
7
|
#
|
7
|
-
# # With ActiveSupport.use_standard_json_time_format = true
|
8
|
+
# # With ActiveSupport::JSON::Encoding.use_standard_json_time_format = true
|
8
9
|
# Time.utc(2005,2,1,15,15,10).to_json
|
9
10
|
# # => "2005-02-01T15:15:10Z"
|
10
11
|
#
|
11
|
-
# # With ActiveSupport.use_standard_json_time_format = false
|
12
|
+
# # With ActiveSupport::JSON::Encoding.use_standard_json_time_format = false
|
12
13
|
# Time.utc(2005,2,1,15,15,10).to_json
|
13
14
|
# # => "2005/02/01 15:15:10 +0000"
|
14
|
-
def
|
15
|
-
if ActiveSupport.use_standard_json_time_format
|
16
|
-
xmlschema
|
15
|
+
def as_json(options = nil)
|
16
|
+
if ActiveSupport::JSON::Encoding.use_standard_json_time_format
|
17
|
+
xmlschema
|
17
18
|
else
|
18
|
-
%(
|
19
|
+
%(#{strftime("%Y/%m/%d %H:%M:%S")} #{formatted_offset(false)})
|
19
20
|
end
|
20
21
|
end
|
21
22
|
end
|
@@ -1,20 +1,91 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
require 'active_support/core_ext/module/delegation'
|
3
|
+
require 'active_support/deprecation'
|
4
|
+
|
1
5
|
module ActiveSupport
|
6
|
+
class << self
|
7
|
+
delegate :use_standard_json_time_format, :use_standard_json_time_format=,
|
8
|
+
:escape_html_entities_in_json, :escape_html_entities_in_json=,
|
9
|
+
:to => :'ActiveSupport::JSON::Encoding'
|
10
|
+
end
|
11
|
+
|
2
12
|
module JSON
|
3
|
-
|
13
|
+
# matches YAML-formatted dates
|
14
|
+
DATE_REGEX = /^(?:\d{4}-\d{2}-\d{2}|\d{4}-\d{1,2}-\d{1,2}[ \t]+\d{1,2}:\d{2}:\d{2}(\.[0-9]*)?(([ \t]*)Z|[-+]\d{2}?(:\d{2})?))$/
|
15
|
+
|
16
|
+
class << self
|
17
|
+
delegate :encode, :to => :'ActiveSupport::JSON::Encoding'
|
4
18
|
end
|
5
19
|
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
20
|
+
module Encoding #:nodoc:
|
21
|
+
class CircularReferenceError < StandardError
|
22
|
+
end
|
23
|
+
|
24
|
+
ESCAPED_CHARS = {
|
25
|
+
"\010" => '\b',
|
26
|
+
"\f" => '\f',
|
27
|
+
"\n" => '\n',
|
28
|
+
"\r" => '\r',
|
29
|
+
"\t" => '\t',
|
30
|
+
'"' => '\"',
|
31
|
+
'\\' => '\\\\',
|
32
|
+
'>' => '\u003E',
|
33
|
+
'<' => '\u003C',
|
34
|
+
'&' => '\u0026' }
|
35
|
+
|
36
|
+
class << self
|
37
|
+
# If true, use ISO 8601 format for dates and times. Otherwise, fall back to the Active Support legacy format.
|
38
|
+
attr_accessor :use_standard_json_time_format
|
39
|
+
|
40
|
+
attr_accessor :escape_regex
|
41
|
+
attr_reader :escape_html_entities_in_json
|
42
|
+
|
43
|
+
def escape_html_entities_in_json=(value)
|
44
|
+
self.escape_regex = \
|
45
|
+
if @escape_html_entities_in_json = value
|
46
|
+
/[\010\f\n\r\t"\\><&]/
|
47
|
+
else
|
48
|
+
/[\010\f\n\r\t"\\]/
|
49
|
+
end
|
50
|
+
end
|
51
|
+
|
52
|
+
def escape(string)
|
53
|
+
string = string.dup.force_encoding(::Encoding::BINARY) if string.respond_to?(:force_encoding)
|
54
|
+
json = string.
|
55
|
+
gsub(escape_regex) { |s| ESCAPED_CHARS[s] }.
|
56
|
+
gsub(/([\xC0-\xDF][\x80-\xBF]|
|
57
|
+
[\xE0-\xEF][\x80-\xBF]{2}|
|
58
|
+
[\xF0-\xF7][\x80-\xBF]{3})+/nx) { |s|
|
59
|
+
s.unpack("U*").pack("n*").unpack("H*")[0].gsub(/.{4}/n, '\\\\u\&')
|
60
|
+
}
|
61
|
+
%("#{json}")
|
62
|
+
end
|
63
|
+
|
64
|
+
# Converts a Ruby object into a JSON string.
|
65
|
+
def encode(value, options = nil)
|
66
|
+
options = {} unless Hash === options
|
67
|
+
seen = (options[:seen] ||= [])
|
68
|
+
raise CircularReferenceError, 'object references itself' if seen.include?(value)
|
69
|
+
seen << value
|
70
|
+
value.to_json(options)
|
71
|
+
ensure
|
72
|
+
seen.pop
|
73
|
+
end
|
74
|
+
end
|
75
|
+
|
76
|
+
self.escape_html_entities_in_json = true
|
14
77
|
end
|
78
|
+
|
79
|
+
CircularReferenceError = Deprecation::DeprecatedConstantProxy.new('ActiveSupport::JSON::CircularReferenceError', Encoding::CircularReferenceError)
|
15
80
|
end
|
16
81
|
end
|
17
82
|
|
83
|
+
# Hack to load json gem first so we can overwrite its to_json.
|
84
|
+
begin
|
85
|
+
require 'json'
|
86
|
+
rescue LoadError
|
87
|
+
end
|
88
|
+
|
18
89
|
require 'active_support/json/variable'
|
19
90
|
require 'active_support/json/encoders/date'
|
20
91
|
require 'active_support/json/encoders/date_time'
|