restful_objects 0.0.5 → 0.0.6
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/README.md +6 -2
- data/bin/restful_server +1 -1
- data/lib/restful_objects/domain_model/domain_model.rb +143 -0
- data/lib/restful_objects/{link_generator.rb → domain_model/helpers/link_generator.rb} +0 -0
- data/lib/restful_objects/{object.rb → domain_model/mixins/object.rb} +6 -2
- data/lib/restful_objects/{object_actions.rb → domain_model/mixins/object_actions.rb} +1 -0
- data/lib/restful_objects/{object_base.rb → domain_model/mixins/object_base.rb} +46 -13
- data/lib/restful_objects/{object_collections.rb → domain_model/mixins/object_collections.rb} +1 -0
- data/lib/restful_objects/{object_macros.rb → domain_model/mixins/object_macros.rb} +4 -3
- data/lib/restful_objects/{object_properties.rb → domain_model/mixins/object_properties.rb} +49 -7
- data/lib/restful_objects/{service.rb → domain_model/mixins/service.rb} +3 -2
- data/lib/restful_objects/{action_description.rb → domain_model/types/action_description.rb} +2 -0
- data/lib/restful_objects/{collection_description.rb → domain_model/types/collection_description.rb} +0 -0
- data/lib/restful_objects/{type.rb → domain_model/types/domain_type.rb} +28 -8
- data/lib/restful_objects/{parameter_description.rb → domain_model/types/parameter_description.rb} +0 -0
- data/lib/restful_objects/{parameter_description_list.rb → domain_model/types/parameter_description_list.rb} +3 -0
- data/lib/restful_objects/{property_description.rb → domain_model/types/property_description.rb} +23 -13
- data/lib/restful_objects/domain_model/user.rb +31 -0
- data/lib/restful_objects/router/base.rb +41 -0
- data/lib/restful_objects/router/domain_object_resources.rb +97 -0
- data/lib/restful_objects/router/domain_type_resources.rb +37 -0
- data/lib/restful_objects/router/supporting_resources.rb +39 -0
- data/lib/restful_objects/version.rb +1 -1
- data/lib/restful_objects.rb +3 -25
- data/spec/acceptance/generate_json_representations_spec.rb +102 -0
- data/spec/integration/domain-types_properties_spec.rb +76 -1
- data/spec/integration/domain_model_spec.rb +35 -0
- data/spec/spec_helper.rb +18 -3
- data/spec/unit/object_spec.rb +0 -73
- data/spec/unit/type_list_spec.rb +2 -2
- metadata +26 -26
- data/lib/restful_objects/action_list.rb +0 -17
- data/lib/restful_objects/collection_list.rb +0 -17
- data/lib/restful_objects/domain_model.rb +0 -83
- data/lib/restful_objects/http_response.rb +0 -11
- data/lib/restful_objects/object_list.rb +0 -16
- data/lib/restful_objects/property_list.rb +0 -17
- data/lib/restful_objects/server.rb +0 -131
- data/lib/restful_objects/service_list.rb +0 -55
- data/lib/restful_objects/type_list.rb +0 -30
- data/lib/restful_objects/user.rb +0 -30
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: acc457412078eadbb0d83af84afa695eb3abea02
|
4
|
+
data.tar.gz: 761377929fe4800901ee88b361cfe6b7e603a98e
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 197315bdd45d57a1dea3ab04593561893106582eb5b7bdbd8da84116b4abc992dbb1ffc2390b568ceb12ddf5f5d5afd2d585ea578bebc16485ae4adcea9edf6d
|
7
|
+
data.tar.gz: 8e73987857c84cababd5eaa857b67b38041d7f8691f9ae7826c09f5da2bd2d24065a4a3212af13860375d827cfac358d70b050405b109b0ef507f88378451243
|
data/README.md
CHANGED
@@ -49,13 +49,13 @@ end
|
|
49
49
|
- [Topological Sort Restful Objects server](https://github.com/vizcay/ro_topological_sort)
|
50
50
|
|
51
51
|
### How to install it?
|
52
|
-
|
52
|
+
If you have a Ruby environment (> 1.9.3) with RubyGems installed, simply run:
|
53
53
|
|
54
54
|
```shell
|
55
55
|
gem install restful_objects
|
56
56
|
```
|
57
57
|
|
58
|
-
or add
|
58
|
+
or add,
|
59
59
|
|
60
60
|
```ruby
|
61
61
|
gem 'restful_objects'
|
@@ -63,6 +63,10 @@ gem 'restful_objects'
|
|
63
63
|
|
64
64
|
to your's project Gemfile and 'bundle install' it.
|
65
65
|
|
66
|
+
If not, consider using Vagrant to setup a VM with all the dependencies and the latest version of the framework following the instructions here:
|
67
|
+
|
68
|
+
[https://github.com/vizcay/restful_objects_vagrant](https://github.com/vizcay/restful_objects_vagrant)
|
69
|
+
|
66
70
|
### Project Status
|
67
71
|
The source quality is at alpha state, and it was created mostly as a proof of concept. Still is has plenty of specs and a big percentage of the specification implemented, the grey areas are mostly related to errors and validations. It has been developed with MRI and hasn't been tested on other Ruby implementations.
|
68
72
|
|
data/bin/restful_server
CHANGED
@@ -0,0 +1,143 @@
|
|
1
|
+
require_relative 'helpers/link_generator'
|
2
|
+
require_relative 'user'
|
3
|
+
require_relative 'mixins/object'
|
4
|
+
require_relative 'mixins/service'
|
5
|
+
require_relative 'types/domain_type'
|
6
|
+
|
7
|
+
module RestfulObjects
|
8
|
+
class DomainModel
|
9
|
+
include LinkGenerator
|
10
|
+
|
11
|
+
attr_accessor :base_url, :compatible_mode
|
12
|
+
attr_reader :metadata_schema, :version, :user, :types, :services, :objects
|
13
|
+
|
14
|
+
def self.current
|
15
|
+
@current ||= DomainModel.new
|
16
|
+
end
|
17
|
+
|
18
|
+
def self.current=(value)
|
19
|
+
@current = value
|
20
|
+
end
|
21
|
+
|
22
|
+
def initialize
|
23
|
+
@base_url = 'http://localhost'
|
24
|
+
@metadata_schema = :selectable
|
25
|
+
@compatible_mode = false
|
26
|
+
@user = User.new(@base_url, 'anonymous')
|
27
|
+
@types = {}
|
28
|
+
@services = {}
|
29
|
+
@objects = {}
|
30
|
+
@services.instance_eval do
|
31
|
+
alias :base_accesor :[]
|
32
|
+
|
33
|
+
def [](key)
|
34
|
+
value = base_accesor(key)
|
35
|
+
if value.is_a?(Class)
|
36
|
+
value = value.new
|
37
|
+
self[key] = value
|
38
|
+
end
|
39
|
+
value
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
43
|
+
|
44
|
+
def register_object(instance)
|
45
|
+
@objects[instance.object_id] = instance
|
46
|
+
end
|
47
|
+
|
48
|
+
def register_service(service)
|
49
|
+
raise 'service registration should be done with a class' unless service.is_a?(Class)
|
50
|
+
@services[service.name] = service
|
51
|
+
end
|
52
|
+
|
53
|
+
def register_type(name)
|
54
|
+
@types[name] = DomainType.new(name)
|
55
|
+
end
|
56
|
+
|
57
|
+
def get_homepage
|
58
|
+
{ 'links' => [
|
59
|
+
link_to(:self, '/', :homepage),
|
60
|
+
link_to(:user, '/user', :user),
|
61
|
+
link_to(:services, '/services', :list),
|
62
|
+
link_to(:version, '/version', :version),
|
63
|
+
link_to(:domain_types, '/domain-types', :type_list)
|
64
|
+
],
|
65
|
+
'extensions' => {}
|
66
|
+
}.to_json
|
67
|
+
end
|
68
|
+
|
69
|
+
def get_version
|
70
|
+
{ 'links' => [
|
71
|
+
link_to(:self, '/version', :version),
|
72
|
+
link_to(:up, '/', :homepage),
|
73
|
+
],
|
74
|
+
'specVersion' => '1.0',
|
75
|
+
'optionalCapabilities' => {
|
76
|
+
'blobsClobs' => true,
|
77
|
+
'deleteObjects' => true,
|
78
|
+
'domainModel' => metadata_schema.to_s,
|
79
|
+
'protoPersistentObjects' => true,
|
80
|
+
'validateOnly' => false
|
81
|
+
},
|
82
|
+
'extensions' => {}
|
83
|
+
}.to_json
|
84
|
+
end
|
85
|
+
|
86
|
+
def get_user
|
87
|
+
@user.get_as_json
|
88
|
+
end
|
89
|
+
|
90
|
+
def get_services
|
91
|
+
{ 'links' => [
|
92
|
+
link_to(:self, '/services', :services),
|
93
|
+
link_to(:up, '/', :homepage),
|
94
|
+
],
|
95
|
+
'value' => services_generate_values,
|
96
|
+
'extensions' => { }
|
97
|
+
}.to_json
|
98
|
+
end
|
99
|
+
|
100
|
+
def get_type_list_representation
|
101
|
+
{ 'links' => [link_to(:self, '/domain-types', :type_list), link_to(:up, '/', :homepage)],
|
102
|
+
'value' => @types.map { |name| link_to(:domain_type, "/domain-types/#{name}", :domain_type) }
|
103
|
+
}.to_json
|
104
|
+
end
|
105
|
+
|
106
|
+
def metadata_schema=(value)
|
107
|
+
if not [:simple, :formal, :selectable].include?(value)
|
108
|
+
raise "invalid metadata schema, choose :simple, :formal or :selectable"
|
109
|
+
end
|
110
|
+
@metadata_schema = value
|
111
|
+
end
|
112
|
+
|
113
|
+
def reset
|
114
|
+
@base_url = 'http://localhost'
|
115
|
+
@user = nil
|
116
|
+
@types.clear
|
117
|
+
@services.clear
|
118
|
+
@objects.clear
|
119
|
+
end
|
120
|
+
|
121
|
+
def reset_objects
|
122
|
+
@objects.clear
|
123
|
+
end
|
124
|
+
|
125
|
+
private
|
126
|
+
|
127
|
+
def services_generate_values
|
128
|
+
services_ensure_all_created
|
129
|
+
values = []
|
130
|
+
@services.each do |name, service|
|
131
|
+
element = link_to(:service, "/services/#{name}", :object, service_id: name)
|
132
|
+
element['title'] = service.title
|
133
|
+
values << element
|
134
|
+
end
|
135
|
+
values
|
136
|
+
end
|
137
|
+
|
138
|
+
def services_ensure_all_created
|
139
|
+
@services.each { |name, value| @services[name] = value.new if value.is_a? Class }
|
140
|
+
end
|
141
|
+
end
|
142
|
+
end
|
143
|
+
|
File without changes
|
@@ -1,11 +1,15 @@
|
|
1
|
-
|
1
|
+
require_relative 'object_macros'
|
2
|
+
require_relative 'object_base'
|
3
|
+
require_relative 'object_properties'
|
4
|
+
require_relative 'object_collections'
|
5
|
+
require_relative 'object_actions'
|
2
6
|
|
3
7
|
module RestfulObjects
|
4
8
|
module Object
|
5
9
|
include LinkGenerator
|
6
10
|
|
7
11
|
def self.included(base)
|
8
|
-
RestfulObjects::DomainModel.current.
|
12
|
+
RestfulObjects::DomainModel.current.register_type(base.name)
|
9
13
|
|
10
14
|
base.class_eval do
|
11
15
|
extend ObjectMacros
|
@@ -1,5 +1,3 @@
|
|
1
|
-
# encoding: utf-8
|
2
|
-
|
3
1
|
module RestfulObjects
|
4
2
|
module ObjectBase
|
5
3
|
attr_accessor :is_service, :title
|
@@ -15,7 +13,7 @@ module RestfulObjects
|
|
15
13
|
end
|
16
14
|
|
17
15
|
def rs_register_in_model
|
18
|
-
rs_model.
|
16
|
+
rs_model.register_object(self) unless @is_service
|
19
17
|
end
|
20
18
|
|
21
19
|
def rs_model
|
@@ -27,15 +25,31 @@ module RestfulObjects
|
|
27
25
|
end
|
28
26
|
|
29
27
|
def get_representation
|
30
|
-
|
31
|
-
|
28
|
+
[200,
|
29
|
+
{ 'Content-Type' =>
|
30
|
+
"application/json;profile=\"urn:org.restfulobjects:repr-types/object\";x-ro-domain-type=\"#{rs_type.id}\"" },
|
31
|
+
representation.to_json]
|
32
|
+
end
|
33
|
+
|
34
|
+
def put_properties_and_get_representation(json)
|
35
|
+
properties = JSON.parse(json)
|
36
|
+
properties.each do |property, container|
|
37
|
+
raise 'property not exists' unless rs_model.types[self.class.name].properties.include?(property)
|
38
|
+
raise 'read-only property' if rs_model.types[self.class.name].properties[property].read_only
|
39
|
+
set_property_value(property, container['value'])
|
40
|
+
on_after_update if respond_to?(:on_after_update)
|
41
|
+
end
|
42
|
+
[200,
|
43
|
+
{ 'Content-Type' =>
|
44
|
+
"application/json;profile=\"urn:org.restfulobjects:repr-types/object\";x-ro-domain-type=\"#{rs_type.id}\"" },
|
45
|
+
representation(false).to_json]
|
32
46
|
end
|
33
47
|
|
34
48
|
def rs_instance_id
|
35
49
|
object_id
|
36
50
|
end
|
37
51
|
|
38
|
-
def representation
|
52
|
+
def representation(include_self_link = true)
|
39
53
|
representation = {
|
40
54
|
'title' => title,
|
41
55
|
'members' => generate_members,
|
@@ -45,10 +59,10 @@ module RestfulObjects
|
|
45
59
|
|
46
60
|
if not is_service
|
47
61
|
representation['instanceId'] = object_id.to_s
|
48
|
-
representation['links'] << link_to(:self, "/objects/#{self.class.name}/#{object_id}", :object)
|
62
|
+
representation['links'] << link_to(:self, "/objects/#{self.class.name}/#{object_id}", :object) if include_self_link
|
49
63
|
else
|
50
64
|
representation['serviceId'] = self.class.name
|
51
|
-
representation['links'] << link_to(:self, "/services/#{self.class.name}", :object)
|
65
|
+
representation['links'] << link_to(:self, "/services/#{self.class.name}", :object) if include_self_link
|
52
66
|
end
|
53
67
|
|
54
68
|
representation
|
@@ -62,17 +76,24 @@ module RestfulObjects
|
|
62
76
|
end
|
63
77
|
end
|
64
78
|
|
79
|
+
def get_property_rel_representation(property_name)
|
80
|
+
representation = link_to(:value, "/objects/#{self.class.name}/#{object_id}", :object, property: property_name)
|
81
|
+
representation['title'] = @title
|
82
|
+
representation
|
83
|
+
end
|
84
|
+
|
65
85
|
def rs_delete
|
66
86
|
on_before_delete if respond_to?(:on_before_delete)
|
67
87
|
@deleted = true
|
68
88
|
on_after_delete if respond_to?(:on_after_delete)
|
89
|
+
{}.to_json
|
69
90
|
end
|
70
91
|
|
71
92
|
def deleted?
|
72
93
|
@deleted
|
73
94
|
end
|
74
95
|
|
75
|
-
def encode_value(value, type)
|
96
|
+
def encode_value(value, type, property_name = '')
|
76
97
|
return nil if value.nil?
|
77
98
|
case type
|
78
99
|
when :string
|
@@ -88,7 +109,11 @@ module RestfulObjects
|
|
88
109
|
when :blob
|
89
110
|
Base64.encode64(value).strip
|
90
111
|
else
|
91
|
-
|
112
|
+
if value.respond_to?(:get_property_rel_representation)
|
113
|
+
value.get_property_rel_representation(property_name)
|
114
|
+
else
|
115
|
+
raise "encode_value unsupported property type: #{type}"
|
116
|
+
end
|
92
117
|
end
|
93
118
|
end
|
94
119
|
|
@@ -100,9 +125,9 @@ module RestfulObjects
|
|
100
125
|
when :int
|
101
126
|
value.to_i
|
102
127
|
when :bool
|
103
|
-
if
|
128
|
+
if [true, 'true'].include?(value)
|
104
129
|
true
|
105
|
-
elsif
|
130
|
+
elsif [false, 'false'].include?(value)
|
106
131
|
false
|
107
132
|
else
|
108
133
|
raise ArgumentError.new "invalid boolean value: #{value}"
|
@@ -118,8 +143,16 @@ module RestfulObjects
|
|
118
143
|
end
|
119
144
|
end
|
120
145
|
|
146
|
+
def ro_relative_url
|
147
|
+
"/objects/#{self.class.name}/#{self.object_id}"
|
148
|
+
end
|
149
|
+
|
150
|
+
def ro_absolute_url
|
151
|
+
RestfulObjects::DomainModel.current.base_url + ro_relative_url
|
152
|
+
end
|
153
|
+
|
121
154
|
def get_self_link
|
122
|
-
link_to(:self,
|
155
|
+
link_to(:self, ro_relative_url, :object)
|
123
156
|
end
|
124
157
|
end
|
125
158
|
end
|
@@ -1,7 +1,7 @@
|
|
1
1
|
module RestfulObjects
|
2
2
|
module ObjectMacros
|
3
3
|
def property(name, type, options = {})
|
4
|
-
RestfulObjects::DomainModel.current.types[self.name].
|
4
|
+
RestfulObjects::DomainModel.current.types[self.name].register_property(name.to_s, type, options)
|
5
5
|
if options[:read_only]
|
6
6
|
self.class_eval { attr_reader name }
|
7
7
|
else
|
@@ -23,13 +23,14 @@ module RestfulObjects
|
|
23
23
|
def collection(name, type, options = {})
|
24
24
|
type = type.name if type.is_a? Class
|
25
25
|
|
26
|
-
RestfulObjects::DomainModel.current.types[self.name].
|
26
|
+
RestfulObjects::DomainModel.current.types[self.name].register_collection(name.to_s, type, options)
|
27
27
|
|
28
28
|
self.class_eval { attr_reader name }
|
29
29
|
end
|
30
30
|
|
31
31
|
def action(name, options = {})
|
32
|
-
RestfulObjects::DomainModel.current.types[self.name].
|
32
|
+
RestfulObjects::DomainModel.current.types[self.name].register_action(name.to_s, options)
|
33
33
|
end
|
34
34
|
end
|
35
35
|
end
|
36
|
+
|
@@ -12,12 +12,26 @@ module RestfulObjects
|
|
12
12
|
'extensions' => property.metadata
|
13
13
|
}
|
14
14
|
|
15
|
-
|
15
|
+
if property.read_only
|
16
|
+
members[name]['disabledReason'] = property.disabled_reason
|
17
|
+
else
|
18
|
+
if self.respond_to?("#{name}_choices")
|
19
|
+
choices = self.send("#{name}_choices")
|
20
|
+
raise "value returned by #{name}_choices method should be an Array" unless choices.is_a?(Array)
|
21
|
+
if property_description(name).is_reference
|
22
|
+
choices_json = choices.map { |object| object.get_property_rel_representation(name) }
|
23
|
+
else
|
24
|
+
choices_json = choices.map { |value| decode_value(value, property_type(name)) }
|
25
|
+
end
|
26
|
+
members[name]['choices'] = choices_json
|
27
|
+
end
|
28
|
+
end
|
16
29
|
end
|
17
30
|
members
|
18
31
|
end
|
19
32
|
|
20
33
|
def get_property_as_json(property)
|
34
|
+
property = property.to_s if property.is_a?(Symbol)
|
21
35
|
raise "Property not exists" if not rs_model.types[self.class.name].properties.include?(property)
|
22
36
|
|
23
37
|
representation = {
|
@@ -36,6 +50,17 @@ module RestfulObjects
|
|
36
50
|
{ property: property, method: 'PUT', arguments: { 'value' => nil } }),
|
37
51
|
link_to(:clear, "/objects/#{self.class.name}/#{object_id}/properties/#{property}", :object_property,
|
38
52
|
{ property: property, method: 'DELETE'} ) ]
|
53
|
+
|
54
|
+
if self.respond_to?("#{property}_choices")
|
55
|
+
choices = self.send("#{property}_choices")
|
56
|
+
raise "value returned by #{property}_choices method should be an Array" unless choices.is_a?(Array)
|
57
|
+
if property_description(property).is_reference
|
58
|
+
choices_json = choices.map { |object| object.get_property_rel_representation(property) }
|
59
|
+
else
|
60
|
+
choices_json = choices.map { |value| decode_value(value, property_type(property)) }
|
61
|
+
end
|
62
|
+
representation[property]['choices'] = choices_json
|
63
|
+
end
|
39
64
|
else
|
40
65
|
representation[property]['disabledReason'] =
|
41
66
|
rs_model.types[self.class.name].properties[property].disabled_reason
|
@@ -45,12 +70,13 @@ module RestfulObjects
|
|
45
70
|
end
|
46
71
|
|
47
72
|
def put_property_as_json(property, json)
|
48
|
-
|
49
|
-
raise
|
73
|
+
property = property.to_s if property.is_a?(Symbol)
|
74
|
+
raise 'property not exists' unless rs_model.types[self.class.name].properties.include?(property)
|
75
|
+
raise 'read-only property' if rs_model.types[self.class.name].properties[property].read_only
|
50
76
|
|
51
77
|
value = JSON.parse(json)['value']
|
52
78
|
set_property_value(property, value)
|
53
|
-
on_after_update if respond_to?
|
79
|
+
on_after_update if respond_to?(:on_after_update)
|
54
80
|
get_property_as_json(property)
|
55
81
|
end
|
56
82
|
|
@@ -59,20 +85,36 @@ module RestfulObjects
|
|
59
85
|
raise "read-only property" if rs_model.types[self.class.name].properties[property].read_only
|
60
86
|
|
61
87
|
send("#{property}=".to_sym, nil)
|
62
|
-
on_after_update if respond_to?
|
88
|
+
on_after_update if respond_to?(:on_after_update)
|
63
89
|
get_property_as_json(property)
|
64
90
|
end
|
65
91
|
|
92
|
+
def property_description(property)
|
93
|
+
rs_model.types[self.class.name].properties[property]
|
94
|
+
end
|
95
|
+
|
66
96
|
def property_type(property)
|
67
97
|
rs_model.types[self.class.name].properties[property].return_type
|
68
98
|
end
|
69
99
|
|
70
100
|
def get_property_value(property)
|
71
|
-
encode_value(send(property.to_sym), property_type(property))
|
101
|
+
encode_value(send(property.to_sym), property_type(property), property)
|
72
102
|
end
|
73
103
|
|
74
104
|
def set_property_value(property, value)
|
75
|
-
|
105
|
+
if property_description(property).is_reference
|
106
|
+
href_value = value['href']
|
107
|
+
match = Regexp.new(".*/objects/(?<domain-type>\\w*)/(?<object-id>\\d*)").match(href_value)
|
108
|
+
raise "invalid property reference format: '#{href_value}'" if not match
|
109
|
+
domain_type = match['domain-type']
|
110
|
+
id = match['object-id'].to_i
|
111
|
+
raise "value does not exists" if not rs_model.objects.include?(id)
|
112
|
+
raise "domain-type does not exists" if not rs_model.types.include?(domain_type)
|
113
|
+
send "#{property}=".to_sym, rs_model.objects[id]
|
114
|
+
else
|
115
|
+
send "#{property}=".to_sym, decode_value(value, property_type(property))
|
116
|
+
end
|
76
117
|
end
|
77
118
|
end
|
78
119
|
end
|
120
|
+
|
@@ -3,7 +3,7 @@ module RestfulObjects
|
|
3
3
|
include LinkGenerator
|
4
4
|
|
5
5
|
def self.included(base)
|
6
|
-
RestfulObjects::DomainModel.current.
|
6
|
+
RestfulObjects::DomainModel.current.register_type(base.name)
|
7
7
|
|
8
8
|
base.class_eval do
|
9
9
|
extend ObjectMacros
|
@@ -15,7 +15,8 @@ module RestfulObjects
|
|
15
15
|
end
|
16
16
|
end
|
17
17
|
|
18
|
-
RestfulObjects::DomainModel.current.
|
18
|
+
RestfulObjects::DomainModel.current.register_service(base)
|
19
19
|
end
|
20
20
|
end
|
21
21
|
end
|
22
|
+
|
data/lib/restful_objects/{collection_description.rb → domain_model/types/collection_description.rb}
RENAMED
File without changes
|
@@ -1,19 +1,38 @@
|
|
1
|
+
require_relative 'property_description'
|
2
|
+
require_relative 'collection_description'
|
3
|
+
require_relative 'action_description'
|
4
|
+
|
1
5
|
module RestfulObjects
|
2
|
-
class
|
6
|
+
class DomainType
|
3
7
|
include LinkGenerator
|
4
8
|
|
5
9
|
attr_reader :id, :is_service, :properties, :collections, :actions
|
6
10
|
attr_accessor :friendly_name, :plural_name, :description
|
7
11
|
|
8
12
|
def initialize(id)
|
9
|
-
@id
|
10
|
-
@properties
|
11
|
-
@collections
|
12
|
-
@actions
|
13
|
-
@is_service
|
13
|
+
@id = id
|
14
|
+
@properties = {}
|
15
|
+
@collections = {}
|
16
|
+
@actions = {}
|
17
|
+
@is_service = false
|
14
18
|
@friendly_name = ''
|
15
|
-
@plural_name
|
16
|
-
@description
|
19
|
+
@plural_name = ''
|
20
|
+
@description = ''
|
21
|
+
end
|
22
|
+
|
23
|
+
def register_property(name, return_type, options = {})
|
24
|
+
options[:member_order] ||= @properties.count + 1
|
25
|
+
@properties[name] = PropertyDescription.new(name, @id, return_type, options)
|
26
|
+
end
|
27
|
+
|
28
|
+
def register_collection(name, type, options = {})
|
29
|
+
options[:member_order] ||= @collections.count + 1
|
30
|
+
@collections[name] = CollectionDescription.new(name, type, @id, options)
|
31
|
+
end
|
32
|
+
|
33
|
+
def register_action(name, options = {})
|
34
|
+
options[:member_order] ||= @actions.count + 1
|
35
|
+
@actions[name] = ActionDescription.new(name, @id, options)
|
17
36
|
end
|
18
37
|
|
19
38
|
def get_representation
|
@@ -108,3 +127,4 @@ module RestfulObjects
|
|
108
127
|
end
|
109
128
|
end
|
110
129
|
end
|
130
|
+
|
data/lib/restful_objects/{parameter_description.rb → domain_model/types/parameter_description.rb}
RENAMED
File without changes
|
data/lib/restful_objects/{property_description.rb → domain_model/types/property_description.rb}
RENAMED
@@ -2,23 +2,33 @@ module RestfulObjects
|
|
2
2
|
class PropertyDescription
|
3
3
|
include LinkGenerator
|
4
4
|
|
5
|
-
attr_accessor :id, :domain_type, :return_type, :friendly_name, :description, :optional, :read_only,
|
6
|
-
:max_length, :disabled_reason, :pattern
|
5
|
+
attr_accessor :id, :domain_type, :return_type, :is_reference, :friendly_name, :description, :optional, :read_only,
|
6
|
+
:member_order, :max_length, :disabled_reason, :pattern
|
7
7
|
|
8
8
|
def initialize(id, domain_type, return_type, options)
|
9
|
-
|
9
|
+
if return_type.is_a?(Hash)
|
10
|
+
raise "hash with :object key expected for property reference" unless return_type.has_key?(:object)
|
11
|
+
else
|
12
|
+
raise "property type #{return_type} usupported" if not [:string, :int, :bool, :decimal, :date, :blob].include?(return_type)
|
13
|
+
end
|
10
14
|
|
11
|
-
@id
|
12
|
-
@domain_type
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
15
|
+
@id = id
|
16
|
+
@domain_type = domain_type
|
17
|
+
if return_type.is_a?(Hash)
|
18
|
+
@return_type = return_type[:object]
|
19
|
+
@is_reference = true
|
20
|
+
else
|
21
|
+
@return_type = return_type
|
22
|
+
@is_reference = false
|
23
|
+
end
|
24
|
+
@friendly_name = options[:friendly_name] || id
|
25
|
+
@description = options[:description] || id
|
26
|
+
@optional = options[:optional].nil? ? true : options[:optional]
|
27
|
+
@read_only = options[:read_only].nil? ? false : options[:read_only]
|
28
|
+
@member_order = options[:member_order] || 1
|
29
|
+
@max_length = options[:max_length]
|
20
30
|
@disabled_reason = options[:disabled_reason] || 'read-only property' if read_only
|
21
|
-
@pattern
|
31
|
+
@pattern = options[:pattern]
|
22
32
|
end
|
23
33
|
|
24
34
|
def get_representation
|
@@ -0,0 +1,31 @@
|
|
1
|
+
module RestfulObjects
|
2
|
+
class User
|
3
|
+
include RestfulObjects::LinkGenerator
|
4
|
+
|
5
|
+
attr_reader :base_url, :user_name
|
6
|
+
attr_accessor :friendly_name, :email
|
7
|
+
|
8
|
+
def initialize(base_url, user_name)
|
9
|
+
@base_url = base_url
|
10
|
+
@user_name = user_name
|
11
|
+
@friendly_name = ''
|
12
|
+
@email = ''
|
13
|
+
@roles = []
|
14
|
+
end
|
15
|
+
|
16
|
+
def add_role(role)
|
17
|
+
@roles.push(role)
|
18
|
+
end
|
19
|
+
|
20
|
+
def get_as_json
|
21
|
+
{ 'links' => [ gen_link('self', '/user', 'user'), gen_link('up', '/', 'homepage') ],
|
22
|
+
'userName' => @user_name,
|
23
|
+
'friendlyName' => @friendly_name,
|
24
|
+
'email' => @email,
|
25
|
+
'roles' => @roles,
|
26
|
+
'extensions' => {}
|
27
|
+
}.to_json
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|