rumx 0.0.8 → 0.1.0
Sign up to get free protection for your applications and to get access to all the features.
- 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
|