occi-core 4.0.0.alpha.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/.gitignore +15 -0
- data/.rspec +1 -0
- data/.travis.yml +43 -0
- data/.yardopts +1 -0
- data/AUTHORS +9 -0
- data/Gemfile +11 -0
- data/LICENSE +13 -0
- data/README.md +212 -0
- data/Rakefile +28 -0
- data/config/occi.yml +4 -0
- data/ext/mkrf_conf.rb +35 -0
- data/lib/occi/collection.rb +192 -0
- data/lib/occi/core/action.rb +32 -0
- data/lib/occi/core/action_instance.rb +38 -0
- data/lib/occi/core/actions.rb +20 -0
- data/lib/occi/core/attribute.rb +99 -0
- data/lib/occi/core/attributes.rb +172 -0
- data/lib/occi/core/categories.rb +51 -0
- data/lib/occi/core/category.rb +153 -0
- data/lib/occi/core/entities.rb +47 -0
- data/lib/occi/core/entity.rb +264 -0
- data/lib/occi/core/kind.rb +58 -0
- data/lib/occi/core/kinds.rb +22 -0
- data/lib/occi/core/link.rb +95 -0
- data/lib/occi/core/links.rb +34 -0
- data/lib/occi/core/mixin.rb +55 -0
- data/lib/occi/core/mixins.rb +41 -0
- data/lib/occi/core/properties.rb +35 -0
- data/lib/occi/core/related.rb +7 -0
- data/lib/occi/core/resource.rb +78 -0
- data/lib/occi/core/resources.rb +14 -0
- data/lib/occi/core.rb +31 -0
- data/lib/occi/helpers/inspect.rb +12 -0
- data/lib/occi/infrastructure/compute.rb +122 -0
- data/lib/occi/infrastructure/network/ipnetwork.rb +27 -0
- data/lib/occi/infrastructure/network.rb +107 -0
- data/lib/occi/infrastructure/networkinterface/ipnetworkinterface.rb +27 -0
- data/lib/occi/infrastructure/networkinterface.rb +103 -0
- data/lib/occi/infrastructure/os_tpl.rb +19 -0
- data/lib/occi/infrastructure/resource_tpl.rb +19 -0
- data/lib/occi/infrastructure/storage.rb +61 -0
- data/lib/occi/infrastructure/storagelink.rb +56 -0
- data/lib/occi/infrastructure.rb +25 -0
- data/lib/occi/log.rb +66 -0
- data/lib/occi/model.rb +86 -0
- data/lib/occi/parser/json.rb +34 -0
- data/lib/occi/parser/ova.rb +35 -0
- data/lib/occi/parser/ovf.rb +154 -0
- data/lib/occi/parser/text.rb +234 -0
- data/lib/occi/parser/xml.rb +18 -0
- data/lib/occi/parser.rb +78 -0
- data/lib/occi/settings.rb +9 -0
- data/lib/occi/version.rb +3 -0
- data/lib/occi-core.rb +50 -0
- data/occi-core.gemspec +36 -0
- data/spec/occi/collection_spec.rb +38 -0
- data/spec/occi/core/attribute_spec.rb +0 -0
- data/spec/occi/core/attributes_spec.rb +42 -0
- data/spec/occi/core/categories_spec.rb +27 -0
- data/spec/occi/core/category_spec.rb +38 -0
- data/spec/occi/core/entity_spec.rb +46 -0
- data/spec/occi/core/resource_spec.rb +18 -0
- data/spec/occi/infrastructure/compute_spec.rb +29 -0
- data/spec/occi/log_spec.rb +14 -0
- data/spec/occi/model_spec.rb +50 -0
- data/spec/occi/parser/text_spec.rb +31 -0
- data/spec/occi/parser_spec.rb +114 -0
- data/spec/occi/test.json +33 -0
- data/spec/occi/test.ova +0 -0
- data/spec/occi/test.ovf +198 -0
- data/spec/spec_helper.rb +25 -0
- 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,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
|