restful_objects 0.0.2 → 0.0.3
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.
- checksums.yaml +8 -8
- data/README.md +3 -2
- data/bin/restful_server.rb +0 -0
- data/lib/restful_objects/action_description.rb +96 -82
- data/lib/restful_objects/action_list.rb +17 -17
- data/lib/restful_objects/collection_description.rb +47 -47
- data/lib/restful_objects/collection_list.rb +17 -17
- data/lib/restful_objects/domain_model.rb +83 -79
- data/lib/restful_objects/http_response.rb +11 -11
- data/lib/restful_objects/link_generator.rb +104 -104
- data/lib/restful_objects/object.rb +20 -20
- data/lib/restful_objects/object_actions.rb +134 -134
- data/lib/restful_objects/object_base.rb +10 -0
- data/lib/restful_objects/object_collections.rb +84 -84
- data/lib/restful_objects/object_list.rb +16 -16
- data/lib/restful_objects/object_macros.rb +35 -35
- data/lib/restful_objects/object_properties.rb +78 -78
- data/lib/restful_objects/parameter_description.rb +60 -60
- data/lib/restful_objects/parameter_description_list.rb +15 -15
- data/lib/restful_objects/property_description.rb +68 -68
- data/lib/restful_objects/property_list.rb +17 -17
- data/lib/restful_objects/service.rb +21 -21
- data/lib/restful_objects/service_list.rb +55 -55
- data/lib/restful_objects/type.rb +110 -110
- data/lib/restful_objects/type_list.rb +30 -30
- data/lib/restful_objects/user.rb +30 -30
- data/lib/restful_objects/version.rb +1 -1
- data/spec/integration/domain-types_actions_spec.rb +43 -43
- data/spec/integration/domain-types_collections_spec.rb +45 -45
- data/spec/integration/domain-types_properties_spec.rb +41 -41
- data/spec/integration/server-root_spec.rb +98 -98
- data/spec/spec_helper.rb +52 -52
- data/spec/unit/object_actions_spec.rb +380 -380
- data/spec/unit/object_collections_spec.rb +190 -190
- data/spec/unit/object_properties_spec.rb +215 -206
- data/spec/unit/object_spec.rb +228 -228
- data/spec/unit/service_spec.rb +125 -125
- data/spec/unit/type_list_spec.rb +37 -37
- metadata +2 -2
@@ -79,6 +79,8 @@ module RestfulObjects
|
|
79
79
|
value.to_s
|
80
80
|
when :int
|
81
81
|
value.to_i
|
82
|
+
when :bool
|
83
|
+
value.to_s
|
82
84
|
when :decimal
|
83
85
|
value.to_f
|
84
86
|
when :date
|
@@ -97,6 +99,14 @@ module RestfulObjects
|
|
97
99
|
value.to_s
|
98
100
|
when :int
|
99
101
|
value.to_i
|
102
|
+
when :bool
|
103
|
+
if value == 'true'
|
104
|
+
true
|
105
|
+
elsif value == 'false'
|
106
|
+
false
|
107
|
+
else
|
108
|
+
raise ArgumentError.new "invalid boolean value: #{value}"
|
109
|
+
end
|
100
110
|
when :decimal
|
101
111
|
Float(value)
|
102
112
|
when :date
|
@@ -1,84 +1,84 @@
|
|
1
|
-
module RestfulObjects
|
2
|
-
module ObjectCollections
|
3
|
-
def collections_members
|
4
|
-
members = {}
|
5
|
-
rs_type.collections.each do |name, collection|
|
6
|
-
members[name] = {
|
7
|
-
'memberType' => 'collection',
|
8
|
-
'size' => rs_type.collections.count,
|
9
|
-
'links' => [
|
10
|
-
link_to(:details, "/objects/#{self.class.name}/#{object_id}/collections/#{name}", :object_collection, collection: name)
|
11
|
-
],
|
12
|
-
'extensions' => collection.metadata
|
13
|
-
}
|
14
|
-
end
|
15
|
-
members
|
16
|
-
end
|
17
|
-
|
18
|
-
def get_collection_as_json(collection)
|
19
|
-
raise "collection not exists" if not rs_model.types[self.class.name].collections.include?(collection)
|
20
|
-
|
21
|
-
value = []
|
22
|
-
send(collection.to_sym).each do |object|
|
23
|
-
link = link_to(:value, "/objects/#{object.rs_type.id}/#{object.rs_instance_id}", :object, method: 'GET', collection: collection)
|
24
|
-
link['title'] = object.title
|
25
|
-
value << link
|
26
|
-
end
|
27
|
-
|
28
|
-
representation = {
|
29
|
-
'id' => collection,
|
30
|
-
'value' => value,
|
31
|
-
'links' => [
|
32
|
-
link_to(:self, "/objects/#{rs_type.id}/#{rs_instance_id}/collections/#{collection}", :object_collection),
|
33
|
-
link_to(:up, "/objects/#{rs_type.id}/#{rs_instance_id}", :object)
|
34
|
-
],
|
35
|
-
'extensions' => rs_type.collections[collection].metadata
|
36
|
-
}
|
37
|
-
|
38
|
-
if not rs_model.types[self.class.name].collections[collection].read_only then
|
39
|
-
add_to_link = link_to(:add_to, "/objects/#{rs_type.id}/#{rs_instance_id}/collections/#{collection}",
|
40
|
-
:object_collection, method: 'PUT', collection: collection)
|
41
|
-
add_to_link['arguments'] = { 'value' => nil }
|
42
|
-
remove_from_link = link_to(:remove_from, "/objects/#{rs_type.id}/#{rs_instance_id}/collections/#{collection}",
|
43
|
-
:object_collection, method: 'DELETE', collection: collection)
|
44
|
-
remove_from_link['arguments'] = { 'value' => nil }
|
45
|
-
representation['links'].concat [ add_to_link, remove_from_link ]
|
46
|
-
else
|
47
|
-
representation['disabledReason'] =
|
48
|
-
rs_model.types[self.class.name].collections[collection].disabled_reason
|
49
|
-
end
|
50
|
-
|
51
|
-
representation.to_json
|
52
|
-
end
|
53
|
-
|
54
|
-
def add_to_collection(collection, json)
|
55
|
-
raise "collection not exists" if not rs_model.types[self.class.name].collections.include?(collection)
|
56
|
-
href_value = JSON.parse(json)['value']['href']
|
57
|
-
match = Regexp.new(".*/objects/(?<domain-type>\\w*)/(?<object-id>\\d*)").match(href_value)
|
58
|
-
raise "Invalid request format" if not match
|
59
|
-
domain_type = match['domain-type']
|
60
|
-
id = match['object-id'].to_i
|
61
|
-
raise "Value does not exists" if not rs_model.objects.include?(id)
|
62
|
-
raise "Domain-type does not exists" if not rs_model.types.include?(domain_type)
|
63
|
-
|
64
|
-
send(collection.to_sym).push(rs_model.objects[id])
|
65
|
-
|
66
|
-
get_collection_as_json(collection)
|
67
|
-
end
|
68
|
-
|
69
|
-
def delete_from_collection(collection, json)
|
70
|
-
raise "collection not exists" if not rs_model.types[self.class.name].collections.include?(collection)
|
71
|
-
href_value = JSON.parse(json)['value']['href']
|
72
|
-
match = Regexp.new(".*/objects/(?<domain-type>\\w*)/(?<object-id>\\d*)").match(href_value)
|
73
|
-
raise "Invalid request format" if not match
|
74
|
-
domain_type = match['domain-type']
|
75
|
-
id = match['object-id'].to_i
|
76
|
-
raise "Value does not exists" if not rs_model.objects.include?(id)
|
77
|
-
raise "Domain-type does not exists" if not rs_model.types.include?(domain_type)
|
78
|
-
|
79
|
-
send(collection.to_sym).delete(rs_model.objects[id])
|
80
|
-
|
81
|
-
get_collection_as_json(collection)
|
82
|
-
end
|
83
|
-
end
|
84
|
-
end
|
1
|
+
module RestfulObjects
|
2
|
+
module ObjectCollections
|
3
|
+
def collections_members
|
4
|
+
members = {}
|
5
|
+
rs_type.collections.each do |name, collection|
|
6
|
+
members[name] = {
|
7
|
+
'memberType' => 'collection',
|
8
|
+
'size' => rs_type.collections.count,
|
9
|
+
'links' => [
|
10
|
+
link_to(:details, "/objects/#{self.class.name}/#{object_id}/collections/#{name}", :object_collection, collection: name)
|
11
|
+
],
|
12
|
+
'extensions' => collection.metadata
|
13
|
+
}
|
14
|
+
end
|
15
|
+
members
|
16
|
+
end
|
17
|
+
|
18
|
+
def get_collection_as_json(collection)
|
19
|
+
raise "collection not exists" if not rs_model.types[self.class.name].collections.include?(collection)
|
20
|
+
|
21
|
+
value = []
|
22
|
+
send(collection.to_sym).each do |object|
|
23
|
+
link = link_to(:value, "/objects/#{object.rs_type.id}/#{object.rs_instance_id}", :object, method: 'GET', collection: collection)
|
24
|
+
link['title'] = object.title
|
25
|
+
value << link
|
26
|
+
end
|
27
|
+
|
28
|
+
representation = {
|
29
|
+
'id' => collection,
|
30
|
+
'value' => value,
|
31
|
+
'links' => [
|
32
|
+
link_to(:self, "/objects/#{rs_type.id}/#{rs_instance_id}/collections/#{collection}", :object_collection),
|
33
|
+
link_to(:up, "/objects/#{rs_type.id}/#{rs_instance_id}", :object)
|
34
|
+
],
|
35
|
+
'extensions' => rs_type.collections[collection].metadata
|
36
|
+
}
|
37
|
+
|
38
|
+
if not rs_model.types[self.class.name].collections[collection].read_only then
|
39
|
+
add_to_link = link_to(:add_to, "/objects/#{rs_type.id}/#{rs_instance_id}/collections/#{collection}",
|
40
|
+
:object_collection, method: 'PUT', collection: collection)
|
41
|
+
add_to_link['arguments'] = { 'value' => nil }
|
42
|
+
remove_from_link = link_to(:remove_from, "/objects/#{rs_type.id}/#{rs_instance_id}/collections/#{collection}",
|
43
|
+
:object_collection, method: 'DELETE', collection: collection)
|
44
|
+
remove_from_link['arguments'] = { 'value' => nil }
|
45
|
+
representation['links'].concat [ add_to_link, remove_from_link ]
|
46
|
+
else
|
47
|
+
representation['disabledReason'] =
|
48
|
+
rs_model.types[self.class.name].collections[collection].disabled_reason
|
49
|
+
end
|
50
|
+
|
51
|
+
representation.to_json
|
52
|
+
end
|
53
|
+
|
54
|
+
def add_to_collection(collection, json)
|
55
|
+
raise "collection not exists" if not rs_model.types[self.class.name].collections.include?(collection)
|
56
|
+
href_value = JSON.parse(json)['value']['href']
|
57
|
+
match = Regexp.new(".*/objects/(?<domain-type>\\w*)/(?<object-id>\\d*)").match(href_value)
|
58
|
+
raise "Invalid request format" if not match
|
59
|
+
domain_type = match['domain-type']
|
60
|
+
id = match['object-id'].to_i
|
61
|
+
raise "Value does not exists" if not rs_model.objects.include?(id)
|
62
|
+
raise "Domain-type does not exists" if not rs_model.types.include?(domain_type)
|
63
|
+
|
64
|
+
send(collection.to_sym).push(rs_model.objects[id])
|
65
|
+
|
66
|
+
get_collection_as_json(collection)
|
67
|
+
end
|
68
|
+
|
69
|
+
def delete_from_collection(collection, json)
|
70
|
+
raise "collection not exists" if not rs_model.types[self.class.name].collections.include?(collection)
|
71
|
+
href_value = JSON.parse(json)['value']['href']
|
72
|
+
match = Regexp.new(".*/objects/(?<domain-type>\\w*)/(?<object-id>\\d*)").match(href_value)
|
73
|
+
raise "Invalid request format" if not match
|
74
|
+
domain_type = match['domain-type']
|
75
|
+
id = match['object-id'].to_i
|
76
|
+
raise "Value does not exists" if not rs_model.objects.include?(id)
|
77
|
+
raise "Domain-type does not exists" if not rs_model.types.include?(domain_type)
|
78
|
+
|
79
|
+
send(collection.to_sym).delete(rs_model.objects[id])
|
80
|
+
|
81
|
+
get_collection_as_json(collection)
|
82
|
+
end
|
83
|
+
end
|
84
|
+
end
|
@@ -1,16 +1,16 @@
|
|
1
|
-
module RestfulObjects
|
2
|
-
class ObjectList
|
3
|
-
extend Forwardable
|
4
|
-
|
5
|
-
def initialize(base_url)
|
6
|
-
@objects = Hash.new
|
7
|
-
@base_url = base_url
|
8
|
-
end
|
9
|
-
|
10
|
-
def register(instance, service = false)
|
11
|
-
@objects[instance.object_id] = instance
|
12
|
-
end
|
13
|
-
|
14
|
-
def_delegators :@objects, :[], :each, :include?, :count, :clear, :empty?, :keys, :values
|
15
|
-
end
|
16
|
-
end
|
1
|
+
module RestfulObjects
|
2
|
+
class ObjectList
|
3
|
+
extend Forwardable
|
4
|
+
|
5
|
+
def initialize(base_url)
|
6
|
+
@objects = Hash.new
|
7
|
+
@base_url = base_url
|
8
|
+
end
|
9
|
+
|
10
|
+
def register(instance, service = false)
|
11
|
+
@objects[instance.object_id] = instance
|
12
|
+
end
|
13
|
+
|
14
|
+
def_delegators :@objects, :[], :each, :include?, :count, :clear, :empty?, :keys, :values
|
15
|
+
end
|
16
|
+
end
|
@@ -1,35 +1,35 @@
|
|
1
|
-
module RestfulObjects
|
2
|
-
module ObjectMacros
|
3
|
-
def property(name, type, options = {})
|
4
|
-
RestfulObjects::DomainModel.current.types[self.name].properties.add(name.to_s, type, options)
|
5
|
-
if options[:read_only]
|
6
|
-
self.class_eval { attr_reader name }
|
7
|
-
else
|
8
|
-
if not options[:max_length]
|
9
|
-
self.class_eval { attr_accessor name }
|
10
|
-
else
|
11
|
-
self.class_eval do
|
12
|
-
attr_reader name
|
13
|
-
|
14
|
-
define_method "#{name}=".to_sym do |value|
|
15
|
-
raise "string max length exceeded" if value && value.length > options[:max_length]
|
16
|
-
instance_variable_set("@#{name}".to_sym, value)
|
17
|
-
end
|
18
|
-
end
|
19
|
-
end
|
20
|
-
end
|
21
|
-
end
|
22
|
-
|
23
|
-
def collection(name, type, options = {})
|
24
|
-
type = type.name if type.is_a? Class
|
25
|
-
|
26
|
-
RestfulObjects::DomainModel.current.types[self.name].collections.add(name.to_s, type, options)
|
27
|
-
|
28
|
-
self.class_eval { attr_reader name }
|
29
|
-
end
|
30
|
-
|
31
|
-
def action(name,
|
32
|
-
RestfulObjects::DomainModel.current.types[self.name].actions.add(name.to_s,
|
33
|
-
end
|
34
|
-
end
|
35
|
-
end
|
1
|
+
module RestfulObjects
|
2
|
+
module ObjectMacros
|
3
|
+
def property(name, type, options = {})
|
4
|
+
RestfulObjects::DomainModel.current.types[self.name].properties.add(name.to_s, type, options)
|
5
|
+
if options[:read_only]
|
6
|
+
self.class_eval { attr_reader name }
|
7
|
+
else
|
8
|
+
if not options[:max_length]
|
9
|
+
self.class_eval { attr_accessor name }
|
10
|
+
else
|
11
|
+
self.class_eval do
|
12
|
+
attr_reader name
|
13
|
+
|
14
|
+
define_method "#{name}=".to_sym do |value|
|
15
|
+
raise "string max length exceeded" if value && value.length > options[:max_length]
|
16
|
+
instance_variable_set("@#{name}".to_sym, value)
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
def collection(name, type, options = {})
|
24
|
+
type = type.name if type.is_a? Class
|
25
|
+
|
26
|
+
RestfulObjects::DomainModel.current.types[self.name].collections.add(name.to_s, type, options)
|
27
|
+
|
28
|
+
self.class_eval { attr_reader name }
|
29
|
+
end
|
30
|
+
|
31
|
+
def action(name, options = {})
|
32
|
+
RestfulObjects::DomainModel.current.types[self.name].actions.add(name.to_s, options)
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
@@ -1,78 +1,78 @@
|
|
1
|
-
module RestfulObjects
|
2
|
-
module ObjectProperties
|
3
|
-
def properties_members
|
4
|
-
members = {}
|
5
|
-
rs_type.properties.each do |name, property|
|
6
|
-
members[name] = {
|
7
|
-
'memberType' => 'property',
|
8
|
-
'value' => get_property_value(name),
|
9
|
-
'links' => [
|
10
|
-
link_to(:details, "/objects/#{self.class.name}/#{object_id}/properties/#{name}", :object_property, property: name)
|
11
|
-
],
|
12
|
-
'extensions' => property.metadata
|
13
|
-
}
|
14
|
-
|
15
|
-
members[name]['disabledReason'] = property.disabled_reason if property.read_only
|
16
|
-
end
|
17
|
-
members
|
18
|
-
end
|
19
|
-
|
20
|
-
def get_property_as_json(property)
|
21
|
-
raise "Property not exists" if not rs_model.types[self.class.name].properties.include?(property)
|
22
|
-
|
23
|
-
representation = {
|
24
|
-
property =>
|
25
|
-
{ 'value' => get_property_value(property),
|
26
|
-
'links' => [
|
27
|
-
link_to(:self, "/objects/#{self.class.name}/#{object_id}/properties/#{property}", :object_property),
|
28
|
-
link_to(:up, "/objects/#{self.class.name}/#{object_id}", :object) ],
|
29
|
-
'extensions' => rs_model.types[self.class.name].properties[property].metadata
|
30
|
-
}
|
31
|
-
}
|
32
|
-
|
33
|
-
if not rs_model.types[self.class.name].properties[property].read_only then
|
34
|
-
representation[property]['links'].concat [
|
35
|
-
link_to(:modify, "/objects/#{self.class.name}/#{object_id}/properties/#{property}", :object_property,
|
36
|
-
{ property: property, method: 'PUT', arguments: { 'value' => nil } }),
|
37
|
-
link_to(:clear, "/objects/#{self.class.name}/#{object_id}/properties/#{property}", :object_property,
|
38
|
-
{ property: property, method: 'DELETE'} ) ]
|
39
|
-
else
|
40
|
-
representation[property]['disabledReason'] =
|
41
|
-
rs_model.types[self.class.name].properties[property].disabled_reason
|
42
|
-
end
|
43
|
-
|
44
|
-
representation.to_json
|
45
|
-
end
|
46
|
-
|
47
|
-
def put_property_as_json(property, json)
|
48
|
-
raise "property not exists" if not rs_model.types[self.class.name].properties.include?(property)
|
49
|
-
raise "read-only property" if rs_model.types[self.class.name].properties[property].read_only
|
50
|
-
|
51
|
-
value = JSON.parse(json)['value']
|
52
|
-
set_property_value(property, value)
|
53
|
-
on_after_update if respond_to? :on_after_update
|
54
|
-
get_property_as_json(property)
|
55
|
-
end
|
56
|
-
|
57
|
-
def clear_property(property)
|
58
|
-
raise "property not exists" if not rs_model.types[self.class.name].properties.include?(property)
|
59
|
-
raise "read-only property" if rs_model.types[self.class.name].properties[property].read_only
|
60
|
-
|
61
|
-
send("#{property}=".to_sym, nil)
|
62
|
-
on_after_update if respond_to? :on_after_update
|
63
|
-
get_property_as_json(property)
|
64
|
-
end
|
65
|
-
|
66
|
-
def property_type(property)
|
67
|
-
rs_model.types[self.class.name].properties[property].return_type
|
68
|
-
end
|
69
|
-
|
70
|
-
def get_property_value(property)
|
71
|
-
encode_value(send(property.to_sym), property_type(property))
|
72
|
-
end
|
73
|
-
|
74
|
-
def set_property_value(property, value)
|
75
|
-
send("#{property}=".to_sym, decode_value(value, property_type(property)))
|
76
|
-
end
|
77
|
-
end
|
78
|
-
end
|
1
|
+
module RestfulObjects
|
2
|
+
module ObjectProperties
|
3
|
+
def properties_members
|
4
|
+
members = {}
|
5
|
+
rs_type.properties.each do |name, property|
|
6
|
+
members[name] = {
|
7
|
+
'memberType' => 'property',
|
8
|
+
'value' => get_property_value(name),
|
9
|
+
'links' => [
|
10
|
+
link_to(:details, "/objects/#{self.class.name}/#{object_id}/properties/#{name}", :object_property, property: name)
|
11
|
+
],
|
12
|
+
'extensions' => property.metadata
|
13
|
+
}
|
14
|
+
|
15
|
+
members[name]['disabledReason'] = property.disabled_reason if property.read_only
|
16
|
+
end
|
17
|
+
members
|
18
|
+
end
|
19
|
+
|
20
|
+
def get_property_as_json(property)
|
21
|
+
raise "Property not exists" if not rs_model.types[self.class.name].properties.include?(property)
|
22
|
+
|
23
|
+
representation = {
|
24
|
+
property =>
|
25
|
+
{ 'value' => get_property_value(property),
|
26
|
+
'links' => [
|
27
|
+
link_to(:self, "/objects/#{self.class.name}/#{object_id}/properties/#{property}", :object_property),
|
28
|
+
link_to(:up, "/objects/#{self.class.name}/#{object_id}", :object) ],
|
29
|
+
'extensions' => rs_model.types[self.class.name].properties[property].metadata
|
30
|
+
}
|
31
|
+
}
|
32
|
+
|
33
|
+
if not rs_model.types[self.class.name].properties[property].read_only then
|
34
|
+
representation[property]['links'].concat [
|
35
|
+
link_to(:modify, "/objects/#{self.class.name}/#{object_id}/properties/#{property}", :object_property,
|
36
|
+
{ property: property, method: 'PUT', arguments: { 'value' => nil } }),
|
37
|
+
link_to(:clear, "/objects/#{self.class.name}/#{object_id}/properties/#{property}", :object_property,
|
38
|
+
{ property: property, method: 'DELETE'} ) ]
|
39
|
+
else
|
40
|
+
representation[property]['disabledReason'] =
|
41
|
+
rs_model.types[self.class.name].properties[property].disabled_reason
|
42
|
+
end
|
43
|
+
|
44
|
+
representation.to_json
|
45
|
+
end
|
46
|
+
|
47
|
+
def put_property_as_json(property, json)
|
48
|
+
raise "property not exists" if not rs_model.types[self.class.name].properties.include?(property)
|
49
|
+
raise "read-only property" if rs_model.types[self.class.name].properties[property].read_only
|
50
|
+
|
51
|
+
value = JSON.parse(json)['value']
|
52
|
+
set_property_value(property, value)
|
53
|
+
on_after_update if respond_to? :on_after_update
|
54
|
+
get_property_as_json(property)
|
55
|
+
end
|
56
|
+
|
57
|
+
def clear_property(property)
|
58
|
+
raise "property not exists" if not rs_model.types[self.class.name].properties.include?(property)
|
59
|
+
raise "read-only property" if rs_model.types[self.class.name].properties[property].read_only
|
60
|
+
|
61
|
+
send("#{property}=".to_sym, nil)
|
62
|
+
on_after_update if respond_to? :on_after_update
|
63
|
+
get_property_as_json(property)
|
64
|
+
end
|
65
|
+
|
66
|
+
def property_type(property)
|
67
|
+
rs_model.types[self.class.name].properties[property].return_type
|
68
|
+
end
|
69
|
+
|
70
|
+
def get_property_value(property)
|
71
|
+
encode_value(send(property.to_sym), property_type(property))
|
72
|
+
end
|
73
|
+
|
74
|
+
def set_property_value(property, value)
|
75
|
+
send("#{property}=".to_sym, decode_value(value, property_type(property)))
|
76
|
+
end
|
77
|
+
end
|
78
|
+
end
|