Skip to content

Commit

Permalink
Add json_class support w/o JSON for most types
Browse files Browse the repository at this point in the history
  • Loading branch information
danielsdeleo committed Feb 11, 2013
1 parent ab0570b commit 4838812
Showing 1 changed file with 61 additions and 1 deletion.
62 changes: 61 additions & 1 deletion lib/chef/json_compat.rb
Expand Up @@ -24,6 +24,8 @@ class Chef
class JSONCompat
JSON_MAX_NESTING = 1000

JSON_CLASS = "json_class".freeze

class <<self
# See CHEF-1292/PL-538. Increase the max nesting for JSON, which defaults
# to 19, and isn't enough for some (for example, a Node within a Node)
Expand All @@ -38,7 +40,37 @@ def opts_add_max_nesting(opts)

# Just call the JSON gem's parse method with a modified :max_nesting field
def from_json(source, opts = {})
::JSON.parse(source, opts_add_max_nesting(opts))
obj = ::Yajl::Parser.parse(source)
if opts[:create_additions].nil? || opts[:create_additions]
map_to_rb_obj(obj)
else
obj
end
end

def map_to_rb_obj(json_obj)
res = case json_obj
when Hash
mapped_hash = map_hash_to_rb_obj(json_obj)
if json_obj.has_key?(JSON_CLASS) && (class_to_inflate = class_for_json_class(json_obj[JSON_CLASS]))
class_to_inflate.json_create(mapped_hash)
else
mapped_hash
end
when Array
json_obj.map {|e| map_to_rb_obj(e) }
else
json_obj
end
res
end

def map_hash_to_rb_obj(json_hash)
mapped_hash = {}
json_hash.each do |key, value|
mapped_hash[key] = map_to_rb_obj(value)
end
mapped_hash
end

def to_json(obj, opts = nil)
Expand All @@ -48,6 +80,34 @@ def to_json(obj, opts = nil)
def to_json_pretty(obj, opts = nil)
::JSON.pretty_generate(obj, opts_add_max_nesting(opts))
end

def class_for_json_class(json_class)
case json_class
when "Chef::ApiClient"
Chef::ApiClient
when "Chef::CookbookVersion"
Chef::CookbookVersion
when "Chef::DataBag"
Chef::DataBag
when "Chef::DataBagItem"
Chef::DataBagItem
when "Chef::Environment"
Chef::Environment
when "Chef::Node"
Chef::Node
when "Chef::Role"
Chef::Role
when "Chef::Sandbox"
false
when "Chef::Resource"
false
when "Chef::ResourceCollection"
Chef::ResourceCollection
else
raise ArgumentError, "Unsupported `json_class` type '#{json_class}'"
end
end

end
end
end

0 comments on commit 4838812

Please sign in to comment.