diff options
author | tyler-ball <tyleraball@gmail.com> | 2014-10-13 10:50:24 -0500 |
---|---|---|
committer | tyler-ball <tyleraball@gmail.com> | 2014-10-16 10:33:02 -0500 |
commit | 43e8d8b751293bf1eb03b69e6dc3c2c621154ed4 (patch) | |
tree | d3816573c99ea3c11530b849b7e6bb50223e62a3 /lib/chef/resource_collection.rb | |
parent | b2f47460c7036f94e1bed1ca23f4d18409374af2 (diff) | |
download | chef-43e8d8b751293bf1eb03b69e6dc3c2c621154ed4.tar.gz |
Finishing all code changes to split resource collection into 2 data containers
Diffstat (limited to 'lib/chef/resource_collection.rb')
-rw-r--r-- | lib/chef/resource_collection.rb | 148 |
1 files changed, 26 insertions, 122 deletions
diff --git a/lib/chef/resource_collection.rb b/lib/chef/resource_collection.rb index 2cac42703e..f62245686a 100644 --- a/lib/chef/resource_collection.rb +++ b/lib/chef/resource_collection.rb @@ -19,148 +19,52 @@ require 'chef/resource_set' require 'chef/resource_list' +require 'chef/resource_collection/resource_collection_serialization' +## +# TODO add class documentation class Chef class ResourceCollection + include ResourceCollectionSerialization + + attr_reader :resource_set, :resource_list def initialize @resource_set = ResourceSet.new @resource_list = ResourceList.new end - # TODO proxy all calls with - # http://simonecarletti.com/blog/2010/05/understanding-ruby-and-rails-proxy-patter-delegation-and-basicobject/ - # TODO fundamentally we want to write objects into 2 different data containers. We can proxy reads, but it is # much harder to proxy writes through 1 object. - def all_resources - @resource_list.all_resources - end - - def [](index) - @resource_list[index] - end - - def []=(index, arg) - @resource_list[index] = arg - end - - def <<(*args) - @resource_list.send(:<<, *args) - end - - # 'push' is an alias method to << - alias_method :push, :<< - - def insert(resource) - @resource_list.insert(resource) - end - - def insert_at(insert_at_index, *resources) - @resource_list.insert_at(insert_at_index, *resources) - end - - def insert_as(resource_type, instance_name, resource) - # TODO how does this compete with the above 2 methods? How do I combine them? - @resource_set.insert_as(resource_type, instance_name, resource) - end - - def each - @resource_list.each - end - - def execute_each_resource(&resource_exec_block) - @resource_list.execute_each_resource(&resource_exec_block) - end - - def each_index - @resource_list.each_index - end - - def empty? - @resources_list.empty? - end - - def lookup(resource_type, instance_name) - @resource_set.lookup(resource_type, instance_name) - end - - def find(*args) - @resource_list.find(*args) - end + # TODO insert calls we might need? + # :insert, :insert_at, :[]=, :<<, :push + # :insert_as - # resources is a poorly named, but we have to maintain it for back - # compat. - alias_method :resources, :find + # TODO when there were 2 resources with the same key in resource_set, how do we handle notifications since they get copied? + # Did the old class only keep the last seen reference? - private + # TODO do we need to implement a dup method? Run_context was shallowly copying resource_collection before - def find_resource_by_hash(arg) - results = Array.new - arg.each do |resource_name, name_list| - names = name_list.kind_of?(Array) ? name_list : [ name_list ] - names.each do |name| - res_name = "#{resource_name.to_s}[#{name}]" - results << lookup(res_name) - end - end - return results - end + RESOURCE_LIST_METHODS = Enumerable.instance_methods + + [:all_resources, :[], :each, :execute_each_resource, :each_index, :empty?] + RESOURCE_SET_METHODS = [:lookup, :find, :resources] - def find_resource_by_string(arg) - results = Array.new - case arg - when MULTIPLE_RESOURCE_MATCH - resource_type = $1 - arg =~ /^.+\[(.+)\]$/ - resource_list = $1 - resource_list.split(",").each do |name| - resource_name = "#{resource_type}[#{name}]" - results << lookup(resource_name) - end - when SINGLE_RESOURCE_MATCH - resource_type = $1 - name = $2 - resource_name = "#{resource_type}[#{name}]" - results << lookup(resource_name) - else - raise ArgumentError, "Bad string format #{arg}, you must have a string like resource_type[name]!" - end - return results + def method_missing(name, *args, &block) + if RESOURCE_LIST_METHODS.include?(name) + proxy = @resource_list + elsif RESOURCE_SET_METHODS.include?(name) + proxy = @resource_set + else + raise NoMethodError.new("ResourceCollection does not proxy `#{name}`", name, args) end - - def is_chef_resource(arg) - unless arg.kind_of?(Chef::Resource) - raise ArgumentError, "Cannot insert a #{arg.class} into a resource collection: must be a subclass of Chef::Resource" - end - true + if block + proxy.send(name, *args, &block) + else + proxy.send(name, *args) end - end - module ResourceCollectionSerialization - # Serialize this object as a hash - def to_hash - instance_vars = Hash.new - self.instance_variables.each do |iv| - instance_vars[iv] = self.instance_variable_get(iv) - end - { - 'json_class' => self.class.name, - 'instance_vars' => instance_vars - } end - def to_json(*a) - Chef::JSONCompat.to_json(to_hash, *a) - end - - def self.json_create(o) - collection = self.new() - o["instance_vars"].each do |k,v| - collection.instance_variable_set(k.to_sym, v) - end - collection - end end end |