rumx 0.0.8 → 0.1.0
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.
- data/History.md +28 -0
- data/README.md +8 -6
- data/examples/bean_hash/README +2 -0
- data/examples/bean_hash/config.ru +9 -0
- data/examples/bean_hash/my_bean.rb +44 -0
- data/examples/bean_list/my_bean.rb +3 -3
- data/examples/embedded/my_bean.rb +3 -2
- data/examples/hash/README +2 -0
- data/examples/hash/config.ru +9 -0
- data/examples/hash/my_bean.rb +30 -0
- data/examples/list/my_bean.rb +5 -2
- data/examples/monitor_script/README +8 -0
- data/examples/monitor_script/rumx_attributes +67 -0
- data/examples/simple/config.ru +3 -1
- data/examples/simple/my_other_bean.rb +11 -0
- data/examples/timer/README +1 -1
- data/examples/timer/my_bean.rb +2 -1
- data/examples/timer_hash/README +2 -0
- data/examples/timer_hash/config.ru +9 -0
- data/examples/timer_hash/my_bean.rb +29 -0
- data/lib/rumx.rb +5 -0
- data/lib/rumx/attribute.rb +26 -17
- data/lib/rumx/attribute_info.rb +12 -0
- data/lib/rumx/bean.rb +146 -248
- data/lib/rumx/beans.rb +2 -0
- data/lib/rumx/beans/error.rb +1 -1
- data/lib/rumx/beans/hash.rb +34 -0
- data/lib/rumx/beans/timer.rb +2 -2
- data/lib/rumx/beans/timer_and_error.rb +1 -1
- data/lib/rumx/beans/timer_hash.rb +9 -0
- data/lib/rumx/hash_attribute.rb +39 -0
- data/lib/rumx/hash_bean.rb +55 -0
- data/lib/rumx/list_attribute.rb +65 -0
- data/lib/rumx/list_bean.rb +52 -0
- data/lib/rumx/server.rb +65 -69
- data/lib/rumx/server/views/attribute_value_tag.haml +3 -3
- data/lib/rumx/server/views/content_attributes.haml +4 -4
- data/lib/rumx/server/views/content_operations.haml +2 -2
- data/lib/rumx/server/views/tree_bean_attributes.haml +0 -4
- data/lib/rumx/server/views/tree_bean_operations.haml +2 -2
- data/lib/rumx/type.rb +15 -7
- metadata +21 -3
- data/lib/rumx/server/views/content_attribute.haml +0 -35
data/lib/rumx/bean.rb
CHANGED
@@ -1,19 +1,23 @@
|
|
1
|
+
require 'monitor'
|
2
|
+
|
1
3
|
module Rumx
|
2
4
|
# Defines a Rumx bean that allows access to the defined attributes and operations.
|
3
5
|
# All public instance methods are prefixed with "bean_" to try to avoid collisions.
|
4
6
|
module Bean
|
5
7
|
module ClassMethods
|
6
8
|
|
9
|
+
# options
|
10
|
+
# type => :list
|
11
|
+
# list_type - type of each list element
|
12
|
+
# max_size - the max size the list can be indexed for setting. Can be an integer or
|
13
|
+
# a symbol that represents an attribute or method of the bean. Defaults to the
|
14
|
+
# current size of the list.
|
7
15
|
def bean_reader(name, type, description, options={})
|
8
|
-
bean_add_attribute(
|
16
|
+
bean_add_attribute(name, type, description, true, false, options)
|
9
17
|
end
|
10
18
|
|
11
|
-
# options
|
12
|
-
# max_size - the max size the list can be indexed for setting. Can be an integer or
|
13
|
-
# a symbol that represents an attribute or method of the bean. Defaults to the
|
14
|
-
# current size of the list.
|
15
19
|
def bean_list_reader(name, type, description, options={})
|
16
|
-
|
20
|
+
raise "bean_list_reader no longer used, instead use 'bean_reader :#{name}, :list, #{description.inspect}, #{options.merge(:list_type => type).inspect}'"
|
17
21
|
end
|
18
22
|
|
19
23
|
def bean_attr_reader(name, type, description, options={})
|
@@ -22,16 +26,15 @@ module Rumx
|
|
22
26
|
end
|
23
27
|
|
24
28
|
def bean_list_attr_reader(name, type, description, options={})
|
25
|
-
|
26
|
-
bean_list_reader(name, type, description, options)
|
29
|
+
raise "bean_list_attr_reader no longer used, instead use 'bean_attr_reader :#{name}, :list, #{description.inspect}, #{options.merge(:list_type => type).inspect}'"
|
27
30
|
end
|
28
31
|
|
29
32
|
def bean_writer(name, type, description, options={})
|
30
|
-
bean_add_attribute(
|
33
|
+
bean_add_attribute(name, type, description, false, true, options)
|
31
34
|
end
|
32
35
|
|
33
36
|
def bean_list_writer(name, type, description, options={})
|
34
|
-
|
37
|
+
raise "bean_list_writer no longer used, instead use 'bean_writer :#{name}, :list, #{description.inspect}, #{options.merge(:list_type => type).inspect}'"
|
35
38
|
end
|
36
39
|
|
37
40
|
def bean_attr_writer(name, type, description, options={})
|
@@ -40,16 +43,15 @@ module Rumx
|
|
40
43
|
end
|
41
44
|
|
42
45
|
def bean_list_attr_writer(name, type, description, options={})
|
43
|
-
|
44
|
-
bean_list_writer(name, type, description, options)
|
46
|
+
raise "bean_list_attr_writer no longer used, instead use 'bean_attr_writer :#{name}, :list, #{description.inspect}, #{options.merge(:list_type => type).inspect}'"
|
45
47
|
end
|
46
48
|
|
47
49
|
def bean_accessor(name, type, description, options={})
|
48
|
-
bean_add_attribute(
|
50
|
+
bean_add_attribute(name, type, description, true, true, options)
|
49
51
|
end
|
50
52
|
|
51
53
|
def bean_list_accessor(name, type, description, options={})
|
52
|
-
|
54
|
+
raise "bean_list_accessor no longer used, instead use 'bean_accessor :#{name}, :list, #{description.inspect}, #{options.merge(:list_type => type).inspect}'"
|
53
55
|
end
|
54
56
|
|
55
57
|
def bean_attr_accessor(name, type, description, options={})
|
@@ -58,28 +60,23 @@ module Rumx
|
|
58
60
|
end
|
59
61
|
|
60
62
|
def bean_list_attr_accessor(name, type, description, options={})
|
61
|
-
|
62
|
-
bean_list_accessor(name, type, description, options)
|
63
|
+
raise "bean_list_attr_accessor no longer used, instead use 'bean_attr_accessor :#{name}, :list, #{description.inspect}, #{options.merge(:list_type => type).inspect}'"
|
63
64
|
end
|
64
65
|
|
65
66
|
def bean_embed(name, description)
|
66
|
-
|
67
|
-
bean_embeds_local << name.to_sym
|
67
|
+
raise "bean_embed no longer used, instead use 'bean_reader :#{name}, :bean, #{description.inspect}'"
|
68
68
|
end
|
69
69
|
|
70
70
|
def bean_attr_embed(name, description)
|
71
|
-
|
72
|
-
bean_embed(name, description)
|
71
|
+
raise "bean_attr_embed no longer used, instead use 'bean_attr_reader :#{name}, :bean, #{description.inspect}'"
|
73
72
|
end
|
74
73
|
|
75
74
|
def bean_embed_list(name, description)
|
76
|
-
|
77
|
-
bean_embed_lists_local << name.to_sym
|
75
|
+
raise "bean_embed_list no longer used, instead use 'bean_attr_reader :#{name}, :list, #{description.inspect}, :list_type => :bean'"
|
78
76
|
end
|
79
77
|
|
80
78
|
def bean_attr_embed_list(name, description)
|
81
|
-
|
82
|
-
bean_embed_list(name, description)
|
79
|
+
raise "bean_attr_embed_list no longer used, instead use 'bean_attr_reader :#{name}, :list, #{description.inspect}, :list_type => :bean'"
|
83
80
|
end
|
84
81
|
|
85
82
|
#bean_operation :my_operation, :string, 'My operation', [
|
@@ -99,12 +96,18 @@ module Rumx
|
|
99
96
|
# private - TODO: Local helper methods, how should I designate them as private or just nodoc them?
|
100
97
|
#######
|
101
98
|
|
102
|
-
def bean_add_attribute(
|
103
|
-
|
104
|
-
|
105
|
-
|
106
|
-
|
107
|
-
|
99
|
+
def bean_add_attribute(name, type_name, description, allow_read, allow_write, options)
|
100
|
+
# Dummy up the things that are defined like attributes but are really beans
|
101
|
+
if type_name == :bean
|
102
|
+
bean_embeds_local[name.to_sym] = nil
|
103
|
+
elsif type_name == :list && options[:list_type] == :bean
|
104
|
+
bean_embeds_local[name.to_sym] = ListBean
|
105
|
+
elsif type_name == :hash && options[:hash_type] == :bean
|
106
|
+
bean_embeds_local[name.to_sym] = HashBean
|
107
|
+
else
|
108
|
+
type = Type.find(type_name)
|
109
|
+
bean_attributes_local << type.create_attribute(name, description, allow_read, allow_write, options)
|
110
|
+
end
|
108
111
|
end
|
109
112
|
|
110
113
|
def bean_attributes
|
@@ -115,22 +118,10 @@ module Rumx
|
|
115
118
|
return attributes
|
116
119
|
end
|
117
120
|
|
118
|
-
def bean_list_attributes
|
119
|
-
attributes = []
|
120
|
-
self.ancestors.reverse_each do |mod|
|
121
|
-
attributes += mod.bean_list_attributes_local if mod.include?(Rumx::Bean)
|
122
|
-
end
|
123
|
-
return attributes
|
124
|
-
end
|
125
|
-
|
126
121
|
def bean_attributes_local
|
127
122
|
@attributes ||= []
|
128
123
|
end
|
129
124
|
|
130
|
-
def bean_list_attributes_local
|
131
|
-
@list_attributes ||= []
|
132
|
-
end
|
133
|
-
|
134
125
|
def bean_operations
|
135
126
|
operations = []
|
136
127
|
self.ancestors.reverse_each do |mod|
|
@@ -144,27 +135,16 @@ module Rumx
|
|
144
135
|
end
|
145
136
|
|
146
137
|
def bean_embeds
|
147
|
-
embeds =
|
138
|
+
embeds = {}
|
139
|
+
# Merge in all the module embeds that are beans
|
148
140
|
self.ancestors.reverse_each do |mod|
|
149
|
-
embeds
|
141
|
+
embeds = embeds.merge(mod.bean_embeds_local) if mod.include?(Rumx::Bean)
|
150
142
|
end
|
151
143
|
return embeds
|
152
144
|
end
|
153
145
|
|
154
|
-
def bean_embed_lists
|
155
|
-
embed_lists = []
|
156
|
-
self.ancestors.reverse_each do |mod|
|
157
|
-
embed_lists += mod.bean_embed_lists_local if mod.include?(Rumx::Bean)
|
158
|
-
end
|
159
|
-
return embed_lists
|
160
|
-
end
|
161
|
-
|
162
146
|
def bean_embeds_local
|
163
|
-
@embeds ||=
|
164
|
-
end
|
165
|
-
|
166
|
-
def bean_embed_lists_local
|
167
|
-
@embed_lists ||= []
|
147
|
+
@embeds ||= {}
|
168
148
|
end
|
169
149
|
|
170
150
|
end
|
@@ -178,29 +158,13 @@ module Rumx
|
|
178
158
|
end
|
179
159
|
|
180
160
|
def self.find(name_array)
|
181
|
-
|
182
|
-
until name_array.empty?
|
183
|
-
name = name_array.shift.to_sym
|
184
|
-
child_bean = bean.bean_children[name]
|
185
|
-
if !child_bean && bean.class.bean_embeds.include?(name)
|
186
|
-
child_bean = bean.send(name)
|
187
|
-
end
|
188
|
-
if !child_bean && bean.class.bean_embed_lists.include?(name)
|
189
|
-
list = bean.send(name)
|
190
|
-
if list
|
191
|
-
index = name_array.shift
|
192
|
-
child_bean = list[index.to_i] if index && index.match(/\d+/)
|
193
|
-
end
|
194
|
-
end
|
195
|
-
return nil unless child_bean
|
196
|
-
bean = child_bean
|
197
|
-
end
|
198
|
-
return bean
|
161
|
+
root.bean_find(name_array)
|
199
162
|
end
|
200
163
|
|
201
164
|
# Return [bean, attribute, param_name, value] list or nil if not found
|
202
165
|
def self.find_attribute(name_array)
|
203
|
-
|
166
|
+
attribute_name = name_array.last
|
167
|
+
name_array = name_array[0..-2]
|
204
168
|
# If it's a list attribute
|
205
169
|
if name.match(/^\d+$/)
|
206
170
|
index = name.to_i
|
@@ -208,15 +172,6 @@ module Rumx
|
|
208
172
|
bean = Bean.find(name_array)
|
209
173
|
return nil unless bean
|
210
174
|
name = name.to_sym
|
211
|
-
bean.class.bean_list_attributes.each do |attribute|
|
212
|
-
if name == attribute.name
|
213
|
-
obj = bean.send(attribute.name)
|
214
|
-
if obj
|
215
|
-
param_name = "#{attribute.name}[#{index}]"
|
216
|
-
return [bean, attribute, param_name, attribute.get_index_value(obj, index)]
|
217
|
-
end
|
218
|
-
end
|
219
|
-
end
|
220
175
|
# else just a regular attribute
|
221
176
|
else
|
222
177
|
bean = Bean.find(name_array)
|
@@ -243,53 +198,105 @@ module Rumx
|
|
243
198
|
return nil
|
244
199
|
end
|
245
200
|
|
246
|
-
#
|
247
|
-
def
|
248
|
-
#
|
249
|
-
@
|
201
|
+
# Monitor for synchronization of attributes/operations
|
202
|
+
def bean_monitor
|
203
|
+
# TODO: How to initialize this in a module and avoid race condition?
|
204
|
+
@monitor ||= Monitor.new
|
250
205
|
end
|
251
206
|
|
252
207
|
# Synchronize access to attributes and operations
|
253
208
|
def bean_synchronize
|
254
|
-
|
209
|
+
bean_monitor.synchronize do
|
255
210
|
yield
|
256
211
|
end
|
257
212
|
end
|
258
213
|
|
259
214
|
def bean_children
|
215
|
+
# TODO: How to initialize this in a module and avoid race condition?
|
260
216
|
@bean_children ||= {}
|
261
217
|
end
|
262
218
|
|
263
219
|
def bean_add_child(name, child_bean)
|
264
|
-
|
265
|
-
|
266
|
-
|
220
|
+
bean_synchronize do
|
221
|
+
bean_children[name.to_sym] = child_bean
|
222
|
+
end
|
267
223
|
end
|
268
224
|
|
269
225
|
def bean_remove_child(name)
|
270
|
-
|
226
|
+
bean_synchronize do
|
227
|
+
bean_children.delete(name.to_sym)
|
228
|
+
end
|
271
229
|
end
|
272
230
|
|
273
|
-
|
274
|
-
|
275
|
-
self
|
276
|
-
|
277
|
-
|
231
|
+
# Find the bean
|
232
|
+
def bean_find(name_array, index = 0)
|
233
|
+
return self if index == name_array.size
|
234
|
+
name = name_array[index].to_sym
|
235
|
+
child_bean = bean_children[name] || bean_embedded(name)
|
236
|
+
return nil unless child_bean
|
237
|
+
return child_bean.bean_find(name_array, index+1)
|
238
|
+
end
|
239
|
+
|
240
|
+
def bean_each(ancestry=[], &block)
|
241
|
+
yield self, ancestry
|
242
|
+
bean_each_child_recursive(ancestry) do |child_bean, child_ancestry|
|
243
|
+
yield child_bean, child_ancestry
|
278
244
|
end
|
279
|
-
|
280
|
-
|
281
|
-
|
282
|
-
|
283
|
-
|
284
|
-
|
245
|
+
end
|
246
|
+
|
247
|
+
def bean_each_child_recursive(ancestry, &block)
|
248
|
+
child_ancestry = ancestry.dup
|
249
|
+
# Save some object creation
|
250
|
+
child_index = child_ancestry.size
|
251
|
+
bean_each_child do |name, bean|
|
252
|
+
child_ancestry[child_index] = name
|
253
|
+
bean.bean_each(child_ancestry, &block)
|
254
|
+
end
|
255
|
+
end
|
256
|
+
|
257
|
+
# Call the block for each direct child of this bean (includes the bean_children and the embedded beans)
|
258
|
+
def bean_each_child(&block)
|
259
|
+
bean_children.each do |name, bean|
|
260
|
+
yield name, bean
|
261
|
+
end
|
262
|
+
bean_each_embedded_child do |name, bean|
|
263
|
+
yield name, bean
|
264
|
+
end
|
265
|
+
end
|
266
|
+
|
267
|
+
# Call the block for all the embedded beans
|
268
|
+
def bean_each_embedded_child(&block)
|
269
|
+
self.class.bean_embeds.each do |name, bean_klass|
|
270
|
+
bean = send(name)
|
271
|
+
if bean
|
272
|
+
# bean_klass is either ListBean or HashBean, otherwise we already have our bean
|
273
|
+
bean = bean_klass.new(bean) if bean_klass
|
274
|
+
yield name, bean
|
285
275
|
end
|
286
276
|
end
|
277
|
+
end
|
278
|
+
|
279
|
+
def bean_embedded(name)
|
280
|
+
return nil unless self.class.bean_embeds.key?(name)
|
281
|
+
bean = send(name)
|
282
|
+
if bean
|
283
|
+
bean_klass = self.class.bean_embeds[name]
|
284
|
+
bean = bean_klass.new(bean) if bean_klass
|
285
|
+
end
|
286
|
+
return bean
|
287
|
+
end
|
288
|
+
|
289
|
+
def bean_has_attributes?
|
290
|
+
return true unless self.class.bean_attributes.empty?
|
291
|
+
bean_each_embedded_child do |name, bean|
|
292
|
+
return true if bean.bean_has_attributes?
|
293
|
+
end
|
287
294
|
return false
|
288
295
|
end
|
289
296
|
|
290
|
-
def bean_get_attributes(
|
297
|
+
def bean_get_attributes(ancestry=[], &block)
|
291
298
|
bean_synchronize do
|
292
|
-
do_bean_get_attributes(
|
299
|
+
do_bean_get_attributes(ancestry, &block)
|
293
300
|
end
|
294
301
|
end
|
295
302
|
|
@@ -299,53 +306,38 @@ module Rumx
|
|
299
306
|
end
|
300
307
|
end
|
301
308
|
|
302
|
-
def bean_get_and_set_attributes(params,
|
309
|
+
def bean_get_and_set_attributes(params, ancestry=[], &block)
|
303
310
|
bean_synchronize do
|
304
|
-
val = do_bean_get_attributes(
|
311
|
+
val = do_bean_get_attributes(ancestry, &block)
|
305
312
|
do_bean_set_attributes(params)
|
306
313
|
val
|
307
314
|
end
|
308
315
|
end
|
309
316
|
|
310
|
-
def bean_set_and_get_attributes(params,
|
317
|
+
def bean_set_and_get_attributes(params, ancestry=[], &block)
|
311
318
|
bean_synchronize do
|
312
319
|
do_bean_set_attributes(params)
|
313
|
-
do_bean_get_attributes(
|
320
|
+
do_bean_get_attributes(ancestry, &block)
|
314
321
|
end
|
315
322
|
end
|
316
323
|
|
317
324
|
def bean_has_operations?
|
318
|
-
|
319
|
-
self.class.bean_embeds.each do |name|
|
320
|
-
bean = send(name)
|
321
|
-
return true if bean && bean.bean_has_operations?
|
322
|
-
end
|
323
|
-
self.class.bean_embed_lists.each do |list_name|
|
324
|
-
list = send(list_name)
|
325
|
-
if list
|
326
|
-
list.each do |bean|
|
327
|
-
return true if bean.bean_has_operations?
|
328
|
-
end
|
329
|
-
end
|
330
|
-
end
|
331
|
-
return false
|
325
|
+
!self.class.bean_operations.empty?
|
332
326
|
end
|
333
327
|
|
334
|
-
def bean_each_operation(
|
328
|
+
def bean_each_operation(&block)
|
335
329
|
self.class.bean_operations.each do |operation|
|
336
|
-
yield operation
|
330
|
+
yield operation
|
337
331
|
end
|
338
|
-
|
339
|
-
|
340
|
-
|
341
|
-
|
342
|
-
|
343
|
-
|
344
|
-
|
345
|
-
|
346
|
-
|
347
|
-
bean.bean_each_operation(bean_join_rel_path(list_rel_path, i.to_s), &block)
|
348
|
-
end
|
332
|
+
end
|
333
|
+
|
334
|
+
def bean_each_operation_recursive(&block)
|
335
|
+
bean_each do |bean, ancestry|
|
336
|
+
operation_ancestry = ancestry.dup
|
337
|
+
index = operation_ancestry.size
|
338
|
+
bean.class.bean_operations.each do |operation|
|
339
|
+
operation_ancestry[index] = operation.name
|
340
|
+
yield operation, operation_ancestry
|
349
341
|
end
|
350
342
|
end
|
351
343
|
end
|
@@ -358,39 +350,18 @@ module Rumx
|
|
358
350
|
def bean_attributes_changed
|
359
351
|
end
|
360
352
|
|
361
|
-
|
362
|
-
|
363
|
-
#######
|
364
|
-
|
365
|
-
# Separate call in case we're already mutex locked
|
366
|
-
def do_bean_get_attributes(rel_path, param_name, &block)
|
353
|
+
# Separate call in case we're already monitor locked
|
354
|
+
def do_bean_get_attributes(ancestry, &block)
|
367
355
|
return do_bean_get_attributes_json unless block_given?
|
368
356
|
self.class.bean_attributes.each do |attribute|
|
369
|
-
|
370
|
-
end
|
371
|
-
self.class.bean_list_attributes.each do |attribute|
|
372
|
-
obj = send(attribute.name)
|
373
|
-
if obj
|
374
|
-
new_rel_path = bean_join_rel_path(rel_path, attribute.name.to_s)
|
375
|
-
new_param_name = bean_join_param_name(param_name, attribute.name.to_s)
|
376
|
-
obj.each_index do |i|
|
377
|
-
yield attribute, attribute.get_index_value(obj, i), "#{new_rel_path}/#{i}", "#{new_param_name}[#{i}]"
|
378
|
-
end
|
379
|
-
end
|
357
|
+
attribute.each_attribute_info(self, ancestry) {|attribute_info| yield attribute_info}
|
380
358
|
end
|
381
|
-
|
382
|
-
|
383
|
-
|
384
|
-
|
385
|
-
|
386
|
-
|
387
|
-
if list
|
388
|
-
list_rel_path = bean_join_rel_path(rel_path, name)
|
389
|
-
list_param_name = bean_join_param_name(param_name, name)
|
390
|
-
list.each_with_index do |bean, i|
|
391
|
-
bean.bean_get_attributes(bean_join_rel_path(list_rel_path, i.to_s), bean_join_param_name(list_param_name, i.to_s), &block)
|
392
|
-
end
|
393
|
-
end
|
359
|
+
child_ancestry = ancestry.dup
|
360
|
+
# Save some object creation
|
361
|
+
child_index = child_ancestry.size
|
362
|
+
bean_each_child do |name, bean|
|
363
|
+
child_ancestry[child_index] = name
|
364
|
+
bean.bean_get_attributes(child_ancestry, &block)
|
394
365
|
end
|
395
366
|
end
|
396
367
|
|
@@ -399,100 +370,27 @@ module Rumx
|
|
399
370
|
self.class.bean_attributes.each do |attribute|
|
400
371
|
hash[attribute.name] = attribute.get_value(self)
|
401
372
|
end
|
402
|
-
|
403
|
-
hash[
|
404
|
-
end
|
405
|
-
self.class.bean_embeds.each do |name|
|
406
|
-
bean = send(name)
|
407
|
-
hash[name] = bean.bean_get_attributes if bean
|
408
|
-
end
|
409
|
-
self.class.bean_embed_lists.each do |name|
|
410
|
-
list = send(name)
|
411
|
-
if list
|
412
|
-
hash[name] = list.map {|bean| bean.bean_get_attributes}
|
413
|
-
end
|
373
|
+
bean_each_child do |name, bean|
|
374
|
+
hash[name] = bean.bean_get_attributes
|
414
375
|
end
|
415
376
|
return hash
|
416
377
|
end
|
417
378
|
|
418
|
-
# Separate call in case we're already
|
379
|
+
# Separate call in case we're already monitor locked
|
419
380
|
def do_bean_set_attributes(params)
|
420
381
|
return if !params || params.empty?
|
421
382
|
changed = false
|
422
383
|
self.class.bean_attributes.each do |attribute|
|
423
|
-
if attribute.
|
424
|
-
if params.has_key?(attribute.name)
|
425
|
-
attribute.set_value(self, params[attribute.name])
|
426
|
-
changed = true
|
427
|
-
elsif params.has_key?(attribute.name.to_s)
|
428
|
-
attribute.set_value(self, params[attribute.name.to_s])
|
429
|
-
changed = true
|
430
|
-
end
|
431
|
-
end
|
432
|
-
end
|
433
|
-
self.class.bean_list_attributes.each do |attribute|
|
434
|
-
if attribute.allow_write
|
435
|
-
obj = send(attribute.name)
|
436
|
-
sub_params = params[attribute.name] || params[attribute.name.to_s]
|
437
|
-
raise "Can't assign value for nil list attribute" if !obj && sub_params
|
438
|
-
if sub_params
|
439
|
-
# TODO: Allow array?
|
440
|
-
raise "Invalid param for #{attribute.name}" unless sub_params.kind_of?(Hash)
|
441
|
-
max_size = attribute[:max_size]
|
442
|
-
if max_size
|
443
|
-
if max_size.kind_of?(Symbol)
|
444
|
-
max_size = send(max_size)
|
445
|
-
end
|
446
|
-
else
|
447
|
-
# Default to current size of the list if unset
|
448
|
-
max_size = obj.size
|
449
|
-
end
|
450
|
-
sub_params.each do |index, value|
|
451
|
-
if index.to_i < max_size
|
452
|
-
attribute.set_index_value(obj, index.to_i, value)
|
453
|
-
changed = true
|
454
|
-
end
|
455
|
-
end
|
456
|
-
end
|
457
|
-
end
|
384
|
+
changed = true if attribute.write?(self, params)
|
458
385
|
end
|
459
|
-
|
460
|
-
|
461
|
-
if
|
462
|
-
embedded_params = params[name]
|
386
|
+
bean_each_child do |name, bean|
|
387
|
+
embedded_params = params[name] || params[name.to_s]
|
388
|
+
if embedded_params && !embedded_params.empty?
|
463
389
|
bean.bean_set_attributes(embedded_params)
|
464
390
|
changed = true
|
465
391
|
end
|
466
392
|
end
|
467
|
-
self.class.bean_embed_lists.each do |name|
|
468
|
-
list = send(name)
|
469
|
-
if list
|
470
|
-
list_params = params[name]
|
471
|
-
if list_params
|
472
|
-
list.each_with_index do |bean, i|
|
473
|
-
bean.bean_set_attributes(list_params[i] || list_params[i.to_s])
|
474
|
-
end
|
475
|
-
changed = true
|
476
|
-
end
|
477
|
-
end
|
478
|
-
end
|
479
393
|
bean_attributes_changed if changed
|
480
394
|
end
|
481
|
-
|
482
|
-
def bean_join_rel_path(parent_rel_path, name)
|
483
|
-
if parent_rel_path
|
484
|
-
"#{parent_rel_path}/#{name}"
|
485
|
-
else
|
486
|
-
name.to_s
|
487
|
-
end
|
488
|
-
end
|
489
|
-
|
490
|
-
def bean_join_param_name(parent_param_name, name)
|
491
|
-
if parent_param_name
|
492
|
-
"#{parent_param_name}[#{name}]"
|
493
|
-
else
|
494
|
-
name.to_s
|
495
|
-
end
|
496
|
-
end
|
497
395
|
end
|
498
396
|
end
|