deltacloud-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From lut...@redhat.com
Subject [PATCH 5/7] CIMI: add collection support to model DSL
Date Wed, 10 Oct 2012 21:41:55 GMT
From: David Lutterkort <lutter@redhat.com>

We reuse the CIMI::Model::Collection class that is also used for toplevel
collections. With that, we won't need special purpose XXXCollection
classes.
---
 server/lib/cimi/models/base.rb       |    3 ++
 server/lib/cimi/models/collection.rb |    6 ++-
 server/lib/cimi/models/schema.rb     |   53 ++++++++++++++++++++++++++++++---
 3 files changed, 55 insertions(+), 7 deletions(-)

diff --git a/server/lib/cimi/models/base.rb b/server/lib/cimi/models/base.rb
index 2a27a8f..2e66694 100644
--- a/server/lib/cimi/models/base.rb
+++ b/server/lib/cimi/models/base.rb
@@ -66,6 +66,9 @@ require 'json'
 #   [array(name, opts, &block)]
 #     An array of structured subobjects; the block defines the schema of
 #     the subobjects.
+#   [collection(name, opts)]
+#     A collection of associated objects; use the +:class+ option to
+#     specify the type of the collection entries
 
 module CIMI::Model
 
diff --git a/server/lib/cimi/models/collection.rb b/server/lib/cimi/models/collection.rb
index cae5e69..86fa09b 100644
--- a/server/lib/cimi/models/collection.rb
+++ b/server/lib/cimi/models/collection.rb
@@ -17,7 +17,7 @@ module CIMI::Model
   class Collection < Base
 
     class << self
-      attr_accessor :entry_name
+      attr_accessor :entry_name, :embedded
     end
 
     # Make sure the base schema gets cloned
@@ -49,14 +49,16 @@ module CIMI::Model
       "Collection"
     end
 
-    def self.generate(model_class)
+    def self.generate(model_class, opts = {})
       model_name = model_class.name.split("::").last
       coll_class = Class.new(CIMI::Model::Collection)
       CIMI::Model.const_set(:"#{model_name}Collection", coll_class)
       coll_class.entry_name = model_name.underscore.pluralize.to_sym
+      coll_class.embedded = opts[:embedded]
       entry_schema = model_class.schema
       coll_class.instance_eval do
         text :count
+        scalar :href if opts[:embedded]
         array self.entry_name, :schema => entry_schema, :xml_name => model_name
         array :operations do
           scalar :rel, :href
diff --git a/server/lib/cimi/models/schema.rb b/server/lib/cimi/models/schema.rb
index e679b2e..cf8381a 100644
--- a/server/lib/cimi/models/schema.rb
+++ b/server/lib/cimi/models/schema.rb
@@ -216,6 +216,49 @@ class CIMI::Model::Schema
     end
   end
 
+  class Collection < Attribute
+    def initialize(name, opts = {})
+      super(name, opts)
+      unless opts[:class]
+        raise "Specify the class of collection entries using :class"
+      end
+      @collection_class = CIMI::Model::Collection.generate(opts[:class], :embedded =>
true)
+    end
+
+    def from_xml(xml, model)
+      model[name] = @collection_class.schema.from_xml(xml[xml_name].first, {})
+    end
+
+    def from_json(json, model)
+      model[name] = @collection_class.schema.from_json(json[json_name], {})
+    end
+
+    def to_xml(model, xml)
+      if model[name].count.nil?
+        xml[xml_name] = { "href" => model[name].href }
+      else
+        xml[xml_name] = @collection_class.schema.to_xml(model[name])
+      end
+    end
+
+    def to_json(model, json)
+      if model[name].count.nil?
+        json[json_name] = { "href" => model[name].href }
+      else
+        json[json_name] = @collection_class.schema.to_json(model[name])
+      end
+    end
+
+    # Convert a Hash or Array to an instance of the collection class
+    def convert(value)
+      if value.is_a?(::Array)
+        @collection_class.new(:entries => value)
+      else
+        @collection_class.new(value || {})
+      end
+    end
+  end
+
   #
   # The actual Schema class
   #
@@ -226,6 +269,10 @@ class CIMI::Model::Schema
     @attributes = []
   end
 
+  def collections
+    @attributes.select { |a| a.is_a?(Collection) }
+  end
+
   def convert(name, value)
     attr = @attributes.find { |a| a.name == name }
     raise "Unknown attribute #{name}" unless attr
@@ -303,11 +350,7 @@ class CIMI::Model::Schema
     end
 
     def collection(name, opts={})
-      text :count
-
-      array :operations do
-        scalar :rel, :href
-      end
+      add_attributes!([name, opts], Collection)
     end
   end
 
-- 
1.7.7.6


Mime
View raw message