occi-core 4.0.0.alpha.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (73) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +15 -0
  3. data/.rspec +1 -0
  4. data/.travis.yml +43 -0
  5. data/.yardopts +1 -0
  6. data/AUTHORS +9 -0
  7. data/Gemfile +11 -0
  8. data/LICENSE +13 -0
  9. data/README.md +212 -0
  10. data/Rakefile +28 -0
  11. data/config/occi.yml +4 -0
  12. data/ext/mkrf_conf.rb +35 -0
  13. data/lib/occi/collection.rb +192 -0
  14. data/lib/occi/core/action.rb +32 -0
  15. data/lib/occi/core/action_instance.rb +38 -0
  16. data/lib/occi/core/actions.rb +20 -0
  17. data/lib/occi/core/attribute.rb +99 -0
  18. data/lib/occi/core/attributes.rb +172 -0
  19. data/lib/occi/core/categories.rb +51 -0
  20. data/lib/occi/core/category.rb +153 -0
  21. data/lib/occi/core/entities.rb +47 -0
  22. data/lib/occi/core/entity.rb +264 -0
  23. data/lib/occi/core/kind.rb +58 -0
  24. data/lib/occi/core/kinds.rb +22 -0
  25. data/lib/occi/core/link.rb +95 -0
  26. data/lib/occi/core/links.rb +34 -0
  27. data/lib/occi/core/mixin.rb +55 -0
  28. data/lib/occi/core/mixins.rb +41 -0
  29. data/lib/occi/core/properties.rb +35 -0
  30. data/lib/occi/core/related.rb +7 -0
  31. data/lib/occi/core/resource.rb +78 -0
  32. data/lib/occi/core/resources.rb +14 -0
  33. data/lib/occi/core.rb +31 -0
  34. data/lib/occi/helpers/inspect.rb +12 -0
  35. data/lib/occi/infrastructure/compute.rb +122 -0
  36. data/lib/occi/infrastructure/network/ipnetwork.rb +27 -0
  37. data/lib/occi/infrastructure/network.rb +107 -0
  38. data/lib/occi/infrastructure/networkinterface/ipnetworkinterface.rb +27 -0
  39. data/lib/occi/infrastructure/networkinterface.rb +103 -0
  40. data/lib/occi/infrastructure/os_tpl.rb +19 -0
  41. data/lib/occi/infrastructure/resource_tpl.rb +19 -0
  42. data/lib/occi/infrastructure/storage.rb +61 -0
  43. data/lib/occi/infrastructure/storagelink.rb +56 -0
  44. data/lib/occi/infrastructure.rb +25 -0
  45. data/lib/occi/log.rb +66 -0
  46. data/lib/occi/model.rb +86 -0
  47. data/lib/occi/parser/json.rb +34 -0
  48. data/lib/occi/parser/ova.rb +35 -0
  49. data/lib/occi/parser/ovf.rb +154 -0
  50. data/lib/occi/parser/text.rb +234 -0
  51. data/lib/occi/parser/xml.rb +18 -0
  52. data/lib/occi/parser.rb +78 -0
  53. data/lib/occi/settings.rb +9 -0
  54. data/lib/occi/version.rb +3 -0
  55. data/lib/occi-core.rb +50 -0
  56. data/occi-core.gemspec +36 -0
  57. data/spec/occi/collection_spec.rb +38 -0
  58. data/spec/occi/core/attribute_spec.rb +0 -0
  59. data/spec/occi/core/attributes_spec.rb +42 -0
  60. data/spec/occi/core/categories_spec.rb +27 -0
  61. data/spec/occi/core/category_spec.rb +38 -0
  62. data/spec/occi/core/entity_spec.rb +46 -0
  63. data/spec/occi/core/resource_spec.rb +18 -0
  64. data/spec/occi/infrastructure/compute_spec.rb +29 -0
  65. data/spec/occi/log_spec.rb +14 -0
  66. data/spec/occi/model_spec.rb +50 -0
  67. data/spec/occi/parser/text_spec.rb +31 -0
  68. data/spec/occi/parser_spec.rb +114 -0
  69. data/spec/occi/test.json +33 -0
  70. data/spec/occi/test.ova +0 -0
  71. data/spec/occi/test.ovf +198 -0
  72. data/spec/spec_helper.rb +25 -0
  73. metadata +304 -0
@@ -0,0 +1,264 @@
1
+ module Occi
2
+ module Core
3
+ class Entity
4
+
5
+ include Occi::Helpers::Inspect
6
+
7
+ attr_accessor :mixins, :attributes, :actions, :id, :model, :kind, :location
8
+
9
+ class_attribute :kind, :mixins, :attributes, :actions
10
+
11
+ self.mixins = Occi::Core::Mixins.new
12
+
13
+ self.attributes = Occi::Core::Attributes.new
14
+ self.attributes['occi.core.id'] = {:pattern => '[a-f0-9]{8}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{12}'}
15
+ self.attributes['occi.core.title'] = {:mutable => true}
16
+
17
+ self.kind = Occi::Core::Kind.new scheme='http://schemas.ogf.org/occi/core#',
18
+ term='entity',
19
+ title='entity',
20
+ attributes=self.attributes
21
+
22
+ # @return [String]
23
+ def self.type_identifier
24
+ self.kind.type_identifier
25
+ end
26
+
27
+ # @param [Array] args list of arguments
28
+ # @return [Object] new instance of this class
29
+ def self.new(*args)
30
+ if args.size > 0
31
+ type_identifier = args[0].to_s
32
+ related = [self.kind]
33
+ else
34
+ type_identifier = self.kind.type_identifier
35
+ related = nil
36
+ end
37
+ scheme, term = type_identifier.split '#'
38
+
39
+ klass = Occi::Core::Kind.get_class scheme, term, related
40
+
41
+ object = klass.allocate
42
+ object.send :initialize, *args
43
+ object
44
+ end
45
+
46
+ def self.attribute_properties
47
+ attributes = Occi::Core::Attributes.new self.attributes
48
+ attributes.merge! Occi::Core::Attributes.new(self.superclass.attribute_properties) if self < Occi::Core::Entity
49
+ attributes
50
+ end
51
+
52
+ def attribute_properties
53
+ attributes = self.class.attribute_properties
54
+ @mixins.collect {|mixin| attributes.merge! Occi::Core::Attributes.new(mixin.attributes)}
55
+ attributes
56
+ end
57
+
58
+ # @param [String] kind
59
+ # @param [String] mixins
60
+ # @param [Occi::Core::Attributes] attributes
61
+ # @param [Occi::Core::Actions] actions
62
+ # @return [Occi::Core::Entity]
63
+ def initialize(kind = self.kind, mixins=[], attributes={}, actions=[], location=nil)
64
+ @kind = self.class.kind.clone
65
+ @mixins = Occi::Core::Mixins.new mixins
66
+ @mixins.entity = self
67
+ attributes = self.class.attribute_properties if attributes.blank?
68
+ if attributes.kind_of? Occi::Core::Attributes
69
+ @attributes = attributes.convert
70
+ else
71
+ @attributes = Occi::Core::Attributes.new attributes
72
+ end
73
+ @actions = Occi::Core::Actions.new actions
74
+ @location = location
75
+ end
76
+
77
+ # @return [Occi::Core::Kind]
78
+ def kind
79
+ @kind
80
+ end
81
+
82
+ # @param [Occi::Core::Kind,String] kind
83
+ # @return [Occi::Core::Kind]
84
+ def kind=(kind)
85
+ if kind.kind_of? String
86
+ scheme, term = kind.split '#'
87
+ kind = Occi::Core::Category.get_class scheme, term
88
+ end
89
+ @kind = kind
90
+ end
91
+
92
+ # @param [Array] mixins
93
+ def mixins=(mixins)
94
+ @mixins = Occi::Core::Mixins.new mixins
95
+ @mixins.entity = self
96
+ @mixins
97
+ end
98
+
99
+ # @param [Occi::Core::Attributes] attributes
100
+ def attributes=(attributes)
101
+ @attributes = Occi::Core::Attributes.new attributes
102
+ end
103
+
104
+ # @param [Occi::Core::Actions] actions
105
+ def actions=(actions)
106
+ @actions = Occi::Core::Actions.new actions
107
+ end
108
+
109
+ # set id for entity
110
+ # @param [UUIDTools::UUID] id
111
+ def id=(id)
112
+ @attributes.occi!.core!.id = id
113
+ @id = id
114
+ end
115
+
116
+ # @return [UUIDTools::UUID] id of the entity
117
+ def id
118
+ @id ||= @attributes.occi.core.id if @attributes.occi.core if @attributes.occi
119
+ @id
120
+ end
121
+
122
+ # set title attribute for entity
123
+ # @param [String] title
124
+ def title=(title)
125
+ @attributes.occi!.core!.title = title
126
+ end
127
+
128
+ # @return [String] title attribute of entity
129
+ def title
130
+ @attributes.occi.core.title if @attributes.occi.core if @attributes.occi
131
+ end
132
+
133
+ # @param [Occi::Model] model
134
+ # @return [Occi::Model]
135
+ def model=(model)
136
+ @model = model
137
+ @kind = (model.get_by_id(@kind.type_identifier) || @kind)
138
+ @kind.entities << self
139
+ @mixins.model = model
140
+ @mixins.each { |mixin| mixin.entities << self }
141
+ @actions.model = model
142
+ end
143
+
144
+ # set location attribute of entity
145
+ # @param [String] location
146
+ def location=(location)
147
+ @location = location
148
+ end
149
+
150
+ # @return [String] location of the entity
151
+ def location
152
+ return @location if @location
153
+ kind.location + id.gsub('urn:uuid:', '') if id
154
+ end
155
+
156
+ # check attributes against their definitions and set defaults
157
+ # @param [Occi::Model] model representation of the Occi model to check the attributes against
158
+ def check
159
+ raise "No model associated" unless @model
160
+ definitions = model.get_by_id(@kind.to_s).attributes
161
+ @mixins.each do |mixin_id|
162
+ mixin = model.get_by_id(mixin_id)
163
+ next if mixin.nil?
164
+ definitions.merge!(mixin.attributes) if mixin.attributes
165
+ end if @mixins
166
+
167
+ @attributes = Entity.check(@attributes, definitions) if definitions
168
+ end
169
+
170
+ # @param [Occi::Core::Attributes] attributes
171
+ # @param [Occi::Core::Attributes] definitions
172
+ # @param [true,false] set_defaults
173
+ # @return [Occi::Core::Attributes] attributes with their defaults set
174
+ def self.check(attributes, definitions, set_defaults=false)
175
+ attributes = Occi::Core::Attributes.new(attributes)
176
+ definitions.each_key do |key|
177
+ next if definitions.key?(key[1..-1])
178
+ if definitions[key].kind_of? Occi::Core::Attributes
179
+ attributes[key] = check(attributes[key], definitions[key])
180
+ else
181
+ properties = definitions[key]
182
+ value = attributes[key]
183
+ value ||= properties.default if set_defaults or properties.required?
184
+ raise "required attribute #{key} not found" if value.nil? && properties.required?
185
+ next if value.blank? and not properties.required?
186
+ case properties.type
187
+ when 'number'
188
+ raise "attribute #{key} value #{value} from class #{value.class.name} does not match attribute property type #{properties.type}" unless value.kind_of?(Numeric)
189
+ when 'boolean'
190
+ raise "attribute #{key} value #{value} from class #{value.class.name} does not match attribute property type #{properties.type}" unless !!value == value
191
+ when 'string'
192
+ raise "attribute #{key} with value #{value} from class #{value.class.name} does not match attribute property type #{properties.type}" unless value.kind_of?(String)
193
+ else
194
+ raise "property type #{properties.type} is not one of the allowed types number, boolean or string"
195
+ end
196
+ Occi::Log.warn "attribute #{key} with value #{value} does not match pattern #{properties.pattern}" if value.to_s.scan(Regexp.new(properties.pattern)).blank? if properties.pattern
197
+ attributes[key] = value
198
+ end
199
+ end
200
+ attributes.delete_if { |_, v| v.blank? } # remove empty attributes
201
+ attributes
202
+ end
203
+
204
+ # @param [Hash] options
205
+ # @return [Hashie::Mash] json representation
206
+ def as_json(options={})
207
+ entity = Hashie::Mash.new
208
+ entity.kind = @kind.to_s if @kind
209
+ entity.mixins = @mixins.join(' ').split(' ') if @mixins.any?
210
+ entity.actions = @actions if @actions.any?
211
+ entity.attributes = @attributes.as_json if @attributes.as_json.any?
212
+ entity.id = id.to_s if id
213
+ entity
214
+ end
215
+
216
+ # @return [String] text representation
217
+ def to_text
218
+ text = 'Category: ' + self.kind.term + ';scheme=' + self.kind.scheme.inspect + ';class="kind"'
219
+ @mixins.each do |mixin|
220
+ scheme, term = mixin.to_s.split('#')
221
+ scheme << '#'
222
+ text << "\n" + 'Category: ' + term + ';scheme=' + scheme.inspect + ';class="mixin"'
223
+ end
224
+ @attributes.names.each_pair do |name, value|
225
+ value = value.inspect
226
+ text << "\n" + 'X-OCCI-Attribute: ' + name + '=' + value
227
+ end
228
+ @actions.each do |action|
229
+ _, term = action.split('#')
230
+ text << "\n" + 'Link: <' + self.location + '?action=' + term + '>;rel=' + action.inspect
231
+ end
232
+ text
233
+ end
234
+
235
+ # @return [Hash] hash containing the HTTP headers of the text/occi rendering
236
+ def to_header
237
+ header = Hashie::Mash.new
238
+ header['Category'] = self.kind.term + ';scheme=' + self.kind.scheme.inspect + ';class="kind"'
239
+ @mixins.each do |mixin|
240
+ scheme, term = mixin.to_s.split('#')
241
+ scheme << '#'
242
+ header['Category'] += ',' + term + ';scheme=' + scheme.inspect + ';class="mixin"'
243
+ end
244
+ attributes = []
245
+ @attributes.names.each_pair do |name, value|
246
+ attributes << name + '=' + value.inspect
247
+ end
248
+ header['X-OCCI-Attribute'] = attributes.join(',') if attributes.any?
249
+ links = []
250
+ @actions.each do |action|
251
+ _, term = action.split('#')
252
+ links << self.location + '?action=' + term + '>;rel=' + action.inspect
253
+ end
254
+ header
255
+ end
256
+
257
+ # @return [String] string representation of entity is its location
258
+ def to_s
259
+ self.location
260
+ end
261
+
262
+ end
263
+ end
264
+ end
@@ -0,0 +1,58 @@
1
+ module Occi
2
+ module Core
3
+ class Kind < Occi::Core::Category
4
+
5
+ attr_accessor :entities, :related, :actions, :location
6
+
7
+ # @param [String ] scheme
8
+ # @param [String] term
9
+ # @param [String] title
10
+ # @param [Hash] attributes
11
+ # @param [Array] related
12
+ # @param [Array] actions
13
+ def initialize(scheme='http://schemas.ogf.org/occi/core#',
14
+ term='kind',
15
+ title=nil,
16
+ attributes=Occi::Core::Attributes.new,
17
+ related=Occi::Core::Related.new,
18
+ actions=Occi::Core::Actions.new,
19
+ location=nil)
20
+ super(scheme, term, title, attributes)
21
+ @related = Occi::Core::Related.new(related)
22
+ @actions = Occi::Core::Actions.new(actions)
23
+ @entities = Occi::Core::Entities.new
24
+ location.blank? ? @location = '/' + term + '/' : @location = location
25
+ end
26
+
27
+ def entity_type
28
+ self.class.get_class @scheme, @term, @related
29
+ end
30
+
31
+ def location
32
+ @location.clone
33
+ end
34
+
35
+ # @param [Hash] options
36
+ # @return [Hashie::Mash] json representation
37
+ def as_json(options={})
38
+ kind = Hashie::Mash.new
39
+ kind.related = @related.join(' ').split(' ') if @related.any?
40
+ kind.actions = @actions.join(' ').split(' ') if @actions.any?
41
+ kind.location = @location if @location
42
+ kind.merge! super
43
+ kind
44
+ end
45
+
46
+ # @return [String] string representation of the kind
47
+ def to_string
48
+ string = super
49
+ string << ';rel=' + @related.join(' ').inspect if @related.any?
50
+ string << ';location=' + self.location.inspect
51
+ string << ';attributes=' + @attributes.names.keys.join(' ').inspect if @attributes.any?
52
+ string << ';actions=' + @actions.join(' ').inspect if @actions.any?
53
+ string
54
+ end
55
+
56
+ end
57
+ end
58
+ end
@@ -0,0 +1,22 @@
1
+ module Occi
2
+ module Core
3
+ class Kinds < Occi::Core::Categories
4
+
5
+ private
6
+
7
+ def convert(category)
8
+ category = super category
9
+
10
+ if category.kind_of? String
11
+ scheme, term = category.split '#'
12
+ scheme += '#'
13
+
14
+ klass = Occi::Core::Category.get_class scheme, term, [Occi::Core::Kind.new]
15
+ category = klass.kind
16
+ end
17
+ category
18
+ end
19
+
20
+ end
21
+ end
22
+ end
@@ -0,0 +1,95 @@
1
+ module Occi
2
+ module Core
3
+ class Link < Occi::Core::Entity
4
+
5
+ attr_accessor :rel, :source, :target
6
+
7
+ self.attributes['occi.core.target'] = {:mutable => true}
8
+ self.attributes['occi.core.source'] = {:mutable => true}
9
+
10
+ self.kind = Occi::Core::Kind.new scheme='http://schemas.ogf.org/occi/core#',
11
+ term='link',
12
+ title='link',
13
+ attributes=self.attributes,
14
+ related=Occi::Core::Related.new << Occi::Core::Entity.kind
15
+
16
+ # @param [String] kind
17
+ # @param [String] mixins
18
+ # @param [Occi::Core::Attributes] attributes
19
+ # @param [Array] actions
20
+ # @param [String] rel
21
+ # @param [String,Occi::Core::Entity] target
22
+ # @param [String,Occi::Core::Entity] source
23
+ def initialize(kind=self.kind, mixins=[], attributes={}, actions=[], rel=Occi::Core::Link.type_identifier, target=nil, source=nil, location=nil)
24
+ super(kind, mixins, attributes, actions, location)
25
+ scheme, term = rel.to_s.split('#')
26
+ @rel = Occi::Core::Category.get_class(scheme, term).kind if scheme && term
27
+ @source = source if source
28
+ @target = target
29
+ end
30
+
31
+ # @return [String] target attribute of the link
32
+ def target
33
+ @target ||= self.attributes.occi.core.target if @attributes.occi.core if @attributes.occi
34
+ @target
35
+ end
36
+
37
+ # set target attribute of link
38
+ # @param [String] target
39
+ def target=(target)
40
+ @target = target
41
+ end
42
+
43
+ # @return [String] source attribute of the link
44
+ def source
45
+ @source ||= self.attributes.occi.core.source if @attributes.occi.core if @attributes.occi
46
+ @source
47
+ end
48
+
49
+ # set source attribute of link
50
+ # @param [String] source
51
+ def source=(source)
52
+ @source = source
53
+ end
54
+
55
+ # @param [Occi::Model] model
56
+ def check
57
+ raise "rel must be provided" unless @rel
58
+ super
59
+ end
60
+
61
+ # @param [Hash] options
62
+ # @return [Hashie::Mash] json representation
63
+ def as_json(options={})
64
+ link = super
65
+ link.rel = @rel.to_s if @rel
66
+ link.source = self.source.to_s if self.source.to_s
67
+ link.target = self.target.to_s if self.target
68
+ link
69
+ end
70
+
71
+ # @return [String] text representation of link reference
72
+ def to_string
73
+ string = '<' + self.target.to_s + '>'
74
+ string << ';rel=' + @rel.to_s.inspect
75
+ string << ';self=' + self.location.inspect if self.location
76
+ categories = [@kind] + @mixins.join(',').split(',')
77
+ string << ';category=' + categories.join(' ').inspect
78
+ @attributes.names.each_pair do |name, value|
79
+ value = value.inspect
80
+ string << ';' + name + '=' + value
81
+ end
82
+ string << ';occi.core.target=' + self.target.to_s.inspect
83
+ string << ';occi.core.source=' + self.source.to_s.inspect unless self.source.blank?
84
+
85
+ string
86
+ end
87
+
88
+ # @return [String] text representation of link
89
+ def to_text_link
90
+ 'Link: ' + self.to_string
91
+ end
92
+
93
+ end
94
+ end
95
+ end
@@ -0,0 +1,34 @@
1
+ module Occi
2
+ module Core
3
+ class Links < Occi::Core::Entities
4
+
5
+ def initialize(links=[])
6
+ links.collect! {|link| convert link} if links
7
+ super links
8
+ end
9
+
10
+ def <<(link)
11
+ super convert link
12
+ end
13
+
14
+ def create(*args)
15
+ link = Occi::Core::Link.new(*args)
16
+ link.model = @model
17
+ self << link
18
+ link
19
+ end
20
+
21
+ private
22
+
23
+ def convert(link)
24
+ if link.kind_of? String
25
+ target = link
26
+ link = Occi::Core::Link.new
27
+ link.target = target
28
+ end
29
+ link
30
+ end
31
+
32
+ end
33
+ end
34
+ end
@@ -0,0 +1,55 @@
1
+ module Occi
2
+ module Core
3
+ class Mixin < Occi::Core::Category
4
+
5
+ attr_accessor :entities, :related, :actions, :location
6
+
7
+ # @param [String ] scheme
8
+ # @param [String] term
9
+ # @param [String] title
10
+ # @param [Occi::Core::Attributes,Hash,NilClass] attributes
11
+ # @param [Occi::Core::Categories,Hash,NilClass] related
12
+ # @param [Occi::Core::Actions,Hash,NilClass] actions
13
+ def initialize(scheme='http://schemas.ogf.org/occi/core#',
14
+ term='mixin',
15
+ title=nil,
16
+ attributes=Occi::Core::Attributes.new,
17
+ related=Occi::Core::Related.new,
18
+ actions=Occi::Core::Actions.new,
19
+ location='')
20
+
21
+ super(scheme, term, title, attributes)
22
+ @related = Occi::Core::Related.new(related)
23
+ @actions = Occi::Core::Actions.new(actions)
24
+ @entities = Occi::Core::Entities.new
25
+ location.blank? ? @location = '/mixins/' + term + '/' : @location = location
26
+ end
27
+
28
+ def location
29
+ @location.clone
30
+ end
31
+
32
+ # @param [Hash] options
33
+ # @return [Hashie::Mash] json representation
34
+ def as_json(options={ })
35
+ mixin = Hashie::Mash.new
36
+ mixin.related = @related.join(' ').split(' ') if @related.any?
37
+ mixin.actions = @actions if @actions.any?
38
+ mixin.location = @location if @location
39
+ mixin.merge! super
40
+ mixin
41
+ end
42
+
43
+ # @return [String] text representation
44
+ def to_string
45
+ string = super
46
+ string << ';rel=' + @related.join(' ').inspect if @related.any?
47
+ string << ';location=' + self.location.inspect
48
+ string << ';attributes=' + @attributes.names.keys.join(' ').inspect if @attributes.any?
49
+ string << ';actions=' + @actions.join(' ').inspect if @actions.any?
50
+ string
51
+ end
52
+
53
+ end
54
+ end
55
+ end
@@ -0,0 +1,41 @@
1
+ module Occi
2
+ module Core
3
+ class Mixins < Occi::Core::Categories
4
+
5
+ attr_accessor :entity
6
+
7
+ def entity=(entity)
8
+ self.each { |mixin| entity.attributes.merge! mixin.attributes.convert }
9
+ @entity = entity
10
+ end
11
+
12
+ def remove(mixin)
13
+ mixin = convert mixin
14
+ @entity.attributes.remove mixin.attributes
15
+ self.delete mixin
16
+ end
17
+
18
+ def <<(mixin)
19
+ mixin = convert mixin
20
+ @entity.attributes.merge! mixin.attributes.convert if @entity
21
+ super mixin
22
+ end
23
+
24
+ private
25
+
26
+ def convert(category)
27
+ category = super category
28
+
29
+ if category.kind_of? String
30
+ scheme, term = category.split '#'
31
+ scheme += '#'
32
+
33
+ klass = Occi::Core::Category.get_class scheme, term, [Occi::Core::Mixin.new]
34
+ category = klass.new(scheme, term)
35
+ end
36
+ category
37
+ end
38
+
39
+ end
40
+ end
41
+ end
@@ -0,0 +1,35 @@
1
+ module Occi
2
+ module Core
3
+ class Properties
4
+
5
+ include Occi::Helpers::Inspect
6
+
7
+ attr_accessor :default, :type, :required, :mutable, :pattern, :description
8
+ alias_method :required?, :required
9
+ alias_method :mutable?, :mutable
10
+
11
+ # @param [Hash] properties
12
+ # @param [Hash] default
13
+ def initialize(properties={})
14
+ self.default = properties[:default]
15
+ self.type = properties[:type] ||= 'string'
16
+ self.required = properties[:required] ||= false
17
+ self.mutable = properties[:mutable] ||= false
18
+ self.pattern = properties[:pattern] ||= '.*'
19
+ self.description = properties[:description]
20
+ end
21
+
22
+ def as_json(options={})
23
+ hash = Hashie::Mash.new
24
+ hash.default = self.default if self.default
25
+ hash.type = self.type if self.type
26
+ hash.required = self.required if self.required
27
+ hash.mutable = self.mutable if self.mutable
28
+ hash.pattern = self.pattern if self.pattern
29
+ hash.description = self.description if self.description
30
+ hash
31
+ end
32
+
33
+ end
34
+ end
35
+ end
@@ -0,0 +1,7 @@
1
+ module Occi
2
+ module Core
3
+ class Related < Occi::Core::Categories
4
+
5
+ end
6
+ end
7
+ end
@@ -0,0 +1,78 @@
1
+ module Occi
2
+ module Core
3
+ class Resource < Occi::Core::Entity
4
+
5
+ attr_accessor :links
6
+
7
+ self.attributes = Occi::Core::Attributes.new
8
+
9
+ self.attributes['occi.core.summary'] = {:mutable => true}
10
+
11
+ self.kind = Occi::Core::Kind.new scheme='http://schemas.ogf.org/occi/core#',
12
+ term='resource',
13
+ title='resource',
14
+ attributes=self.attributes,
15
+ related=Occi::Core::Related.new << Occi::Core::Entity.kind
16
+
17
+ # @param [String] kind
18
+ # @param [Array] mixins
19
+ # @param [Occi::Core::Attributes,Hash] attributes
20
+ # @param [Array] links
21
+ # @return [Occi::Core::Resource]
22
+ def initialize(kind=self.kind, mixins=[], attributes={}, actions=[], links=[], location=nil)
23
+ super(kind, mixins, attributes, actions, location)
24
+ @links = Occi::Core::Links.new(links)
25
+ end
26
+
27
+ def model=(model)
28
+ super model
29
+ @links.model = model
30
+ end
31
+
32
+ # @return [String] summary attribute of the resource
33
+ def summary
34
+ self.attributes.occi.core.summary if @attributes.occi.core if @attributes.occi
35
+ end
36
+
37
+ # set summary attribute of resource
38
+ # @param [String] summary
39
+ def summary=(summary)
40
+ self.attributes.occi!.core!.summary = summary
41
+ end
42
+
43
+ def link(target, kind=Occi::Core::Link.kind, mixins=[], attributes=Occi::Core::Attributes.new, rel=Occi::Core::Resource.type_identifier)
44
+ link = kind.entity_type.new
45
+ link.rel = rel
46
+ link.attributes = attributes
47
+ link.target = target
48
+ link.source = self
49
+ link.mixins = mixins
50
+ @links << link
51
+ link
52
+ end
53
+
54
+ # @return [String] text representation
55
+ def to_text
56
+ text = super
57
+ @links.each { |link| text << "\n" + link.to_text_link }
58
+ text
59
+ end
60
+
61
+ # @return [Hash] hash containing the HTTP headers of the text/occi rendering
62
+ def to_header
63
+ header = super
64
+ header['Links'] = @links.join(',')
65
+ end
66
+
67
+ # @param [Hash] options
68
+ # @return [Hashie::Mash] link as Hashie::Mash to be parsed into a JSON object
69
+ def as_json(options={})
70
+ resource = super
71
+ link_strings = @links.collect { |link| link.to_s if link.to_s }.compact
72
+ resource.links = link_strings unless link_strings.empty?
73
+ resource
74
+ end
75
+
76
+ end
77
+ end
78
+ end