rumx 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (70) hide show
  1. data/History.md +6 -0
  2. data/LICENSE.txt +201 -0
  3. data/README.md +107 -0
  4. data/Rakefile +23 -0
  5. data/examples/bean_list/README +2 -0
  6. data/examples/bean_list/config.ru +9 -0
  7. data/examples/bean_list/my_bean.rb +35 -0
  8. data/examples/embedded/README +2 -0
  9. data/examples/embedded/config.ru +9 -0
  10. data/examples/embedded/my_bean.rb +23 -0
  11. data/examples/embedded/my_embedded_bean.rb +22 -0
  12. data/examples/list/README +2 -0
  13. data/examples/list/config.ru +9 -0
  14. data/examples/list/my_bean.rb +28 -0
  15. data/examples/simple/README +2 -0
  16. data/examples/simple/config.ru +11 -0
  17. data/examples/simple/my_bean.rb +36 -0
  18. data/examples/timer/README +7 -0
  19. data/examples/timer/config.ru +9 -0
  20. data/examples/timer/my_bean.rb +28 -0
  21. data/lib/rumx/argument.rb +11 -0
  22. data/lib/rumx/attribute.rb +38 -0
  23. data/lib/rumx/bean.rb +484 -0
  24. data/lib/rumx/beans/folder.rb +9 -0
  25. data/lib/rumx/beans/message.rb +16 -0
  26. data/lib/rumx/beans/timer.rb +75 -0
  27. data/lib/rumx/beans.rb +3 -0
  28. data/lib/rumx/operation.rb +26 -0
  29. data/lib/rumx/server/public/_lib/jquery.cookie.js +96 -0
  30. data/lib/rumx/server/public/_lib/jquery.hotkeys.js +99 -0
  31. data/lib/rumx/server/public/_lib/jquery.js +18 -0
  32. data/lib/rumx/server/public/attribute_test.html +148 -0
  33. data/lib/rumx/server/public/jquery-ui-1.8.16.custom.min.js +132 -0
  34. data/lib/rumx/server/public/jquery.jstree.js +4551 -0
  35. data/lib/rumx/server/public/jquery.layout.min-1.2.0.js +80 -0
  36. data/lib/rumx/server/public/themes/apple/bg.jpg +0 -0
  37. data/lib/rumx/server/public/themes/apple/d.png +0 -0
  38. data/lib/rumx/server/public/themes/apple/dot_for_ie.gif +0 -0
  39. data/lib/rumx/server/public/themes/apple/style.css +61 -0
  40. data/lib/rumx/server/public/themes/apple/throbber.gif +0 -0
  41. data/lib/rumx/server/public/themes/classic/d.gif +0 -0
  42. data/lib/rumx/server/public/themes/classic/d.png +0 -0
  43. data/lib/rumx/server/public/themes/classic/dot_for_ie.gif +0 -0
  44. data/lib/rumx/server/public/themes/classic/style.css +77 -0
  45. data/lib/rumx/server/public/themes/classic/throbber.gif +0 -0
  46. data/lib/rumx/server/public/themes/default/d.gif +0 -0
  47. data/lib/rumx/server/public/themes/default/d.png +0 -0
  48. data/lib/rumx/server/public/themes/default/style.css +74 -0
  49. data/lib/rumx/server/public/themes/default/throbber.gif +0 -0
  50. data/lib/rumx/server/public/themes/default-rtl/d.gif +0 -0
  51. data/lib/rumx/server/public/themes/default-rtl/d.png +0 -0
  52. data/lib/rumx/server/public/themes/default-rtl/dots.gif +0 -0
  53. data/lib/rumx/server/public/themes/default-rtl/style.css +84 -0
  54. data/lib/rumx/server/public/themes/default-rtl/throbber.gif +0 -0
  55. data/lib/rumx/server/views/attribute_value_tag.haml +4 -0
  56. data/lib/rumx/server/views/content_attribute.haml +35 -0
  57. data/lib/rumx/server/views/content_attributes.haml +31 -0
  58. data/lib/rumx/server/views/content_operation.haml +39 -0
  59. data/lib/rumx/server/views/content_operations.haml +36 -0
  60. data/lib/rumx/server/views/index.haml +1 -0
  61. data/lib/rumx/server/views/layout.haml +18 -0
  62. data/lib/rumx/server/views/link_to_content.haml +1 -0
  63. data/lib/rumx/server/views/tree.haml +11 -0
  64. data/lib/rumx/server/views/tree_bean.haml +6 -0
  65. data/lib/rumx/server/views/tree_bean_attributes.haml +6 -0
  66. data/lib/rumx/server/views/tree_bean_operations.haml +6 -0
  67. data/lib/rumx/server.rb +185 -0
  68. data/lib/rumx/type.rb +36 -0
  69. data/lib/rumx.rb +7 -0
  70. metadata +123 -0
data/lib/rumx/bean.rb ADDED
@@ -0,0 +1,484 @@
1
+ module Rumx
2
+ # Defines a Rumx bean that allows access to the defined attributes and operations.
3
+ # All public instance methods are prefixed with "bean_" to try to avoid collisions.
4
+ module Bean
5
+ module ClassMethods
6
+
7
+ def bean_reader(name, type, description, options={})
8
+ bean_add_attribute(Attribute.new(name, type, description, true, false, options))
9
+ end
10
+
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
+ def bean_list_reader(name, type, description, options={})
16
+ bean_add_list_attribute(Attribute.new(name, type, description, true, false, options))
17
+ end
18
+
19
+ def bean_attr_reader(name, type, description, options={})
20
+ attr_reader(name)
21
+ bean_reader(name, type, description, options)
22
+ end
23
+
24
+ def bean_list_attr_reader(name, type, description, options={})
25
+ attr_reader(name)
26
+ bean_list_reader(name, type, description, options)
27
+ end
28
+
29
+ def bean_writer(name, type, description, options={})
30
+ bean_add_attribute(Attribute.new(name, type, description, false, true, options))
31
+ end
32
+
33
+ def bean_list_writer(name, type, description, options={})
34
+ bean_add_list_attribute(Attribute.new(name, type, description, false, true, options))
35
+ end
36
+
37
+ def bean_attr_writer(name, type, description, options={})
38
+ attr_writer(name)
39
+ bean_writer(name, type, description, options)
40
+ end
41
+
42
+ def bean_list_attr_writer(name, type, description, options={})
43
+ attr_writer(name)
44
+ bean_list_writer(name, type, description, options)
45
+ end
46
+
47
+ def bean_accessor(name, type, description, options={})
48
+ bean_add_attribute(Attribute.new(name, type, description, true, true, options))
49
+ end
50
+
51
+ def bean_list_accessor(name, type, description, options={})
52
+ bean_add_list_attribute(Attribute.new(name, type, description, true, true, options))
53
+ end
54
+
55
+ def bean_attr_accessor(name, type, description, options={})
56
+ attr_accessor(name)
57
+ bean_accessor(name, type, description, options)
58
+ end
59
+
60
+ def bean_list_attr_accessor(name, type, description, options={})
61
+ attr_accessor(name)
62
+ bean_list_accessor(name, type, description, options)
63
+ end
64
+
65
+ def bean_embed(name, description)
66
+ # We're going to ignore description (for now)
67
+ bean_embeds << name.to_sym
68
+ end
69
+
70
+ def bean_attr_embed(name, description)
71
+ attr_reader(name)
72
+ bean_embed(name, description)
73
+ end
74
+
75
+ def bean_embed_list(name, description)
76
+ # We're going to ignore description (for now)
77
+ bean_embed_lists << name.to_sym
78
+ end
79
+
80
+ def bean_attr_embed_list(name, description)
81
+ attr_reader(name)
82
+ bean_embed_list(name, description)
83
+ end
84
+
85
+ #bean_operation :my_operation, :string, 'My operation', [
86
+ # [ :arg_int, :int, 'An int argument' ],
87
+ # [ :arg_float, :float, 'A float argument' ],
88
+ # [ :arg_string, :string, 'A string argument' ]
89
+ #]
90
+ def bean_operation(name, type, description, args)
91
+ arguments = args.map do |arg|
92
+ raise 'Invalid bean_operation format' unless arg.kind_of?(Array) && arg.size == 3
93
+ Argument.new(*arg)
94
+ end
95
+ @operations ||= []
96
+ @operations << Operation.new(name, type, description, arguments)
97
+ end
98
+
99
+ #######
100
+ # private - TODO: Local helper methods, how should I designate them as private or just nodoc them?
101
+ #######
102
+
103
+ def bean_add_attribute(attribute)
104
+ @attributes ||= []
105
+ @attributes << attribute
106
+ end
107
+
108
+ def bean_add_list_attribute(attribute)
109
+ @list_attributes ||= []
110
+ @list_attributes << attribute
111
+ end
112
+
113
+ def bean_attributes
114
+ attributes = []
115
+ self.ancestors.reverse_each do |mod|
116
+ attributes += mod.bean_attributes_local if mod.include?(Rumx::Bean)
117
+ end
118
+ return attributes
119
+ end
120
+
121
+ def bean_list_attributes
122
+ attributes = []
123
+ self.ancestors.reverse_each do |mod|
124
+ attributes += mod.bean_list_attributes_local if mod.include?(Rumx::Bean)
125
+ end
126
+ return attributes
127
+ end
128
+
129
+ def bean_attributes_local
130
+ @attributes ||= []
131
+ end
132
+
133
+ def bean_list_attributes_local
134
+ @list_attributes ||= []
135
+ end
136
+
137
+ def bean_operations
138
+ operations = []
139
+ self.ancestors.reverse_each do |mod|
140
+ operations += mod.bean_operations_local if mod.include?(Rumx::Bean)
141
+ end
142
+ return operations
143
+ end
144
+
145
+ def bean_operations_local
146
+ @operations ||= []
147
+ end
148
+
149
+ def bean_embeds
150
+ @embeds ||= []
151
+ end
152
+
153
+ def bean_embed_lists
154
+ @embed_lists ||= []
155
+ end
156
+ end
157
+
158
+ def self.included(base)
159
+ base.extend(ClassMethods)
160
+ end
161
+
162
+ def self.root
163
+ @root ||= Beans::Folder.new
164
+ end
165
+
166
+ def self.find(name_array)
167
+ bean = root
168
+ until name_array.empty?
169
+ name = name_array.shift.to_sym
170
+ child_bean = bean.bean_children[name]
171
+ if !child_bean && bean.class.bean_embeds.include?(name)
172
+ child_bean = bean.send(name)
173
+ end
174
+ if !child_bean && bean.class.bean_embed_lists.include?(name)
175
+ list = bean.send(name)
176
+ if list
177
+ index = name_array.shift
178
+ child_bean = list[index.to_i] if index && index.match(/\d+/)
179
+ end
180
+ end
181
+ return nil unless child_bean
182
+ bean = child_bean
183
+ end
184
+ return bean
185
+ end
186
+
187
+ # Return [bean, attribute, param_name, value] list or nil if not found
188
+ def self.find_attribute(name_array)
189
+ name = name_array.pop
190
+ # If it's a list attribute
191
+ if name.match(/^\d+$/)
192
+ index = name.to_i
193
+ name = name_array.pop
194
+ bean = Bean.find(name_array)
195
+ return nil unless bean
196
+ name = name.to_sym
197
+ bean.class.bean_list_attributes.each do |attribute|
198
+ if name == attribute.name
199
+ obj = bean.send(attribute.name)
200
+ if obj
201
+ param_name = "#{attribute.name}[#{index}]"
202
+ return [bean, attribute, param_name, attribute.get_index_value(obj, index)]
203
+ end
204
+ end
205
+ end
206
+ # else just a regular attribute
207
+ else
208
+ bean = Bean.find(name_array)
209
+ return nil unless bean
210
+ name = name.to_sym
211
+ bean.class.bean_attributes.each do |attribute|
212
+ if name == attribute.name
213
+ return [bean, attribute, attribute.name, attribute.get_value(bean)]
214
+ end
215
+ end
216
+ end
217
+ return nil
218
+ end
219
+
220
+ # Return [bean, operation] pair or nil if not found
221
+ def self.find_operation(name_array)
222
+ name = name_array.pop
223
+ bean = Bean.find(name_array)
224
+ return nil unless bean
225
+ name = name.to_sym
226
+ bean.class.bean_operations.each do |operation|
227
+ return [bean, operation] if name == operation.name
228
+ end
229
+ return nil
230
+ end
231
+
232
+ # Mutex for synchronization of attributes/operations
233
+ def bean_mutex
234
+ # TBD: How to initialize this in a module and avoid race condition?
235
+ @mutex || Mutex.new
236
+ end
237
+
238
+ # Synchronize access to attributes and operations
239
+ def bean_synchronize
240
+ bean_mutex.synchronize do
241
+ yield
242
+ end
243
+ end
244
+
245
+ def bean_children
246
+ @bean_children ||= {}
247
+ end
248
+
249
+ def bean_add_child(name, child_bean)
250
+ # TBD - Should I mutex protect this? All beans would normally be registered during the code initialization process
251
+ raise "Error trying to add #{name} to embedded bean" if @bean_is_embedded
252
+ bean_children[name.to_sym] = child_bean
253
+ end
254
+
255
+ def bean_remove_child(name)
256
+ bean_children.delete(name.to_sym)
257
+ end
258
+
259
+ def bean_has_attributes?
260
+ return true unless self.class.bean_attributes.empty? && self.class.bean_list_attributes.empty?
261
+ self.class.bean_embeds.each do |name|
262
+ bean = send(name)
263
+ return true if bean && bean.bean_has_attributes?
264
+ end
265
+ self.class.bean_embed_lists.each do |list_name|
266
+ list = send(list_name)
267
+ if list
268
+ list.each do |bean|
269
+ return true if bean.bean_has_attributes?
270
+ end
271
+ end
272
+ end
273
+ return false
274
+ end
275
+
276
+ def bean_get_attributes(rel_path=nil, param_name=nil, &block)
277
+ bean_synchronize do
278
+ do_bean_get_attributes(rel_path, param_name, &block)
279
+ end
280
+ end
281
+
282
+ def bean_set_attributes(params)
283
+ bean_synchronize do
284
+ do_bean_set_attributes(params)
285
+ end
286
+ end
287
+
288
+ def bean_get_and_set_attributes(params, rel_path=nil, param_name=nil, &block)
289
+ bean_synchronize do
290
+ val = do_bean_get_attributes(rel_path, param_name, &block)
291
+ do_bean_set_attributes(params)
292
+ val
293
+ end
294
+ end
295
+
296
+ def bean_set_and_get_attributes(params, rel_path=nil, param_name=nil, &block)
297
+ bean_synchronize do
298
+ do_bean_set_attributes(params)
299
+ do_bean_get_attributes(rel_path, param_name, &block)
300
+ end
301
+ end
302
+
303
+ def bean_has_operations?
304
+ return true unless self.class.bean_operations.empty?
305
+ self.class.bean_embeds.each do |name|
306
+ bean = send(name)
307
+ return true if bean && bean.bean_has_operations?
308
+ end
309
+ self.class.bean_embed_lists.each do |list_name|
310
+ list = send(list_name)
311
+ if list
312
+ list.each do |bean|
313
+ return true if bean.bean_has_operations?
314
+ end
315
+ end
316
+ end
317
+ return false
318
+ end
319
+
320
+ def bean_each_operation(rel_path=nil, &block)
321
+ self.class.bean_operations.each do |operation|
322
+ yield operation, bean_join_rel_path(rel_path, operation.name.to_s)
323
+ end
324
+ self.class.bean_embeds.each do |name|
325
+ bean = send(name)
326
+ bean.bean_each_operation(bean_join_rel_path(rel_path, name), &block) if bean
327
+ end
328
+ self.class.bean_embed_lists.each do |name|
329
+ list = send(name)
330
+ if list
331
+ list_rel_path = bean_join_rel_path(rel_path, name)
332
+ list.each_with_index do |bean, i|
333
+ bean.bean_each_operation(bean_join_rel_path(list_rel_path, i.to_s), &block)
334
+ end
335
+ end
336
+ end
337
+ end
338
+
339
+ #########
340
+ protected
341
+ #########
342
+
343
+ # Allow extenders to save changes, etc. if attribute values change
344
+ def bean_attributes_changed
345
+ end
346
+
347
+ #######
348
+ private
349
+ #######
350
+
351
+ # Separate call in case we're already mutex locked
352
+ def do_bean_get_attributes(rel_path, param_name, &block)
353
+ return do_bean_get_attributes_json unless block_given?
354
+ self.class.bean_attributes.each do |attribute|
355
+ yield attribute, attribute.get_value(self), bean_join_rel_path(rel_path, attribute.name.to_s), bean_join_param_name(param_name, attribute.name.to_s)
356
+ end
357
+ self.class.bean_list_attributes.each do |attribute|
358
+ obj = send(attribute.name)
359
+ if obj
360
+ new_rel_path = bean_join_rel_path(rel_path, attribute.name.to_s)
361
+ new_param_name = bean_join_param_name(param_name, attribute.name.to_s)
362
+ obj.each_index do |i|
363
+ yield attribute, attribute.get_index_value(obj, i), "#{new_rel_path}/#{i}", "#{new_param_name}[#{i}]"
364
+ end
365
+ end
366
+ end
367
+ self.class.bean_embeds.each do |name|
368
+ bean = send(name)
369
+ bean.bean_get_attributes(bean_join_rel_path(rel_path, name), bean_join_param_name(param_name, name), &block) if bean
370
+ end
371
+ self.class.bean_embed_lists.each do |name|
372
+ list = send(name)
373
+ if list
374
+ list_rel_path = bean_join_rel_path(rel_path, name)
375
+ list_param_name = bean_join_param_name(param_name, name)
376
+ list.each_with_index do |bean, i|
377
+ 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)
378
+ end
379
+ end
380
+ end
381
+ end
382
+
383
+ def do_bean_get_attributes_json
384
+ hash = {}
385
+ self.class.bean_attributes.each do |attribute|
386
+ hash[attribute.name] = attribute.get_value(self)
387
+ end
388
+ self.class.bean_list_attributes.each do |attribute|
389
+ hash[attribute.name] = attribute.get_value(self)
390
+ end
391
+ self.class.bean_embeds.each do |name|
392
+ bean = send(name)
393
+ hash[name] = bean.bean_get_attributes if bean
394
+ end
395
+ self.class.bean_embed_lists.each do |name|
396
+ list = send(name)
397
+ if list
398
+ hash[name] = list.map {|bean| bean.bean_get_attributes}
399
+ end
400
+ end
401
+ return hash
402
+ end
403
+
404
+ # Separate call in case we're already mutex locked
405
+ def do_bean_set_attributes(params)
406
+ return if !params || params.empty?
407
+ changed = false
408
+ self.class.bean_attributes.each do |attribute|
409
+ if attribute.allow_write
410
+ if params.has_key?(attribute.name)
411
+ attribute.set_value(self, params[attribute.name])
412
+ changed = true
413
+ elsif params.has_key?(attribute.name.to_s)
414
+ attribute.set_value(self, params[attribute.name.to_s])
415
+ changed = true
416
+ end
417
+ end
418
+ end
419
+ self.class.bean_list_attributes.each do |attribute|
420
+ if attribute.allow_write
421
+ obj = send(attribute.name)
422
+ sub_params = params[attribute.name] || params[attribute.name.to_s]
423
+ raise "Can't assign value for nil list attribute" if !obj && sub_params
424
+ if sub_params
425
+ # TODO: Allow array?
426
+ raise "Invalid param for #{attribute.name}" unless sub_params.kind_of?(Hash)
427
+ max_size = attribute[:max_size]
428
+ if max_size
429
+ if max_size.kind_of?(Symbol)
430
+ max_size = send(max_size)
431
+ end
432
+ else
433
+ # Default to current size of the list if unset
434
+ max_size = obj.size
435
+ end
436
+ sub_params.each do |index, value|
437
+ if index.to_i < max_size
438
+ attribute.set_index_value(obj, index.to_i, value)
439
+ changed = true
440
+ end
441
+ end
442
+ end
443
+ end
444
+ end
445
+ self.class.bean_embeds.each do |name|
446
+ bean = send(name)
447
+ if bean
448
+ embedded_params = params[name]
449
+ bean.bean_set_attributes(embedded_params)
450
+ changed = true
451
+ end
452
+ end
453
+ self.class.bean_embed_lists.each do |name|
454
+ list = send(name)
455
+ if list
456
+ list_params = params[name]
457
+ if list_params
458
+ list.each_with_index do |bean, i|
459
+ bean.bean_set_attributes(list_params[i] || list_params[i.to_s])
460
+ end
461
+ changed = true
462
+ end
463
+ end
464
+ end
465
+ bean_attributes_changed if changed
466
+ end
467
+
468
+ def bean_join_rel_path(parent_rel_path, name)
469
+ if parent_rel_path
470
+ "#{parent_rel_path}/#{name}"
471
+ else
472
+ name.to_s
473
+ end
474
+ end
475
+
476
+ def bean_join_param_name(parent_param_name, name)
477
+ if parent_param_name
478
+ "#{parent_param_name}[#{name}]"
479
+ else
480
+ name.to_s
481
+ end
482
+ end
483
+ end
484
+ end
@@ -0,0 +1,9 @@
1
+ module Rumx
2
+ module Beans
3
+ # Bean that contains child beans. Since all beans have this functionality, this is
4
+ # essentially just a Bean that has no attributes or operations.
5
+ class Folder
6
+ include Bean
7
+ end
8
+ end
9
+ end
@@ -0,0 +1,16 @@
1
+ module Rumx
2
+ module Beans
3
+ class Message
4
+ include ::Rumx::Bean
5
+
6
+ bean_attr_reader :message, :string, 'Message'
7
+ # TODO: create time and date types
8
+ bean_attr_reader :time, :string, 'Time that the message occurred'
9
+
10
+ def initialize(message, time=nil)
11
+ @message = message
12
+ @time = (time || Time.now).to_s
13
+ end
14
+ end
15
+ end
16
+ end
@@ -0,0 +1,75 @@
1
+ module Rumx
2
+ module Beans
3
+ class Timer
4
+ include Bean
5
+
6
+ bean_attr_reader :total_count, :integer, 'Number of times the measured block has run'
7
+ bean_attr_reader :error_count, :integer, 'Number of times the measured block has raised an exception'
8
+ bean_attr_reader :total_time, :float, 'Total time in msec for all the runs of the timed instruction'
9
+ bean_attr_reader :max_time, :float, 'The maximum time for all the runs of the timed instruction'
10
+ bean_attr_reader :min_time, :float, 'The minimum time for all the runs of the timed instruction'
11
+ bean_attr_reader :last_time, :float, 'The time for the last run of the timed instruction'
12
+ bean_reader :avg_time, :float, 'The average time for all runs of the timed instruction'
13
+ bean_writer :reset, :boolean, 'Reset the times and counts to zero (Note that last_time and errors are not reset)'
14
+ bean_attr_embed_list :errors, 'List of the last occurring errors'
15
+
16
+ def initialize(opts={})
17
+ # Force initialization of Bean#bean_mutex to avoid race condition (See bean.rb)
18
+ bean_mutex
19
+ @last_time = 0.0
20
+ self.reset = true
21
+ @errors = []
22
+ @max_errors = (opts[:max_errors] || 1).to_i
23
+ end
24
+
25
+ def reset=(val)
26
+ if val
27
+ @total_count = 0
28
+ @error_count = 0
29
+ @min_time = nil
30
+ @max_time = 0.0
31
+ @total_time = 0.0
32
+ end
33
+ end
34
+
35
+ def measure(prefix='')
36
+ start_time = Time.now
37
+ begin
38
+ yield
39
+ ensure
40
+ current_time = Time.now.to_f - start_time.to_f
41
+ bean_synchronize do
42
+ @last_time = current_time
43
+ @total_count += 1
44
+ @total_time += current_time
45
+ @min_time = current_time if !@min_time || current_time < @min_time
46
+ @max_time = current_time if current_time > @max_time
47
+ end
48
+ end
49
+ return current_time
50
+ rescue Exception => e
51
+ bean_synchronize do
52
+ @error_count += 1
53
+ @errors << Message.new(e.message)
54
+ @errors.shift while @errors.size > @max_errors
55
+ end
56
+ raise
57
+ end
58
+
59
+ def min_time
60
+ @min_time || 0.0
61
+ end
62
+
63
+ def avg_time
64
+ # Do the best we can w/o mutexing
65
+ count, time = @total_count, @total_time
66
+ return 0.0 if count == 0
67
+ time / count
68
+ end
69
+
70
+ def to_s
71
+ "total_count=#{@total_count} min=#{('%.1f' % min_time)}ms max=#{('%.1f' % max_time)}ms avg=#{('%.1f' % avg_time)}ms"
72
+ end
73
+ end
74
+ end
75
+ end
data/lib/rumx/beans.rb ADDED
@@ -0,0 +1,3 @@
1
+ require 'rumx/beans/folder'
2
+ require 'rumx/beans/message'
3
+ require 'rumx/beans/timer'
@@ -0,0 +1,26 @@
1
+ module Rumx
2
+ class Operation
3
+ attr_reader :name, :type, :description, :arguments
4
+
5
+ def initialize(name, type_name, description, arguments)
6
+ @name = name.to_sym
7
+ @type = Type.find(type_name)
8
+ @description = description
9
+ @arguments = arguments
10
+ end
11
+
12
+ def run(bean, argument_hash)
13
+ args = @arguments.map do |argument|
14
+ if argument_hash.has_key?(argument.name)
15
+ value = argument_hash[argument.name]
16
+ elsif argument_hash.has_key?(argument.name.to_s)
17
+ value = argument_hash[argument.name.to_s]
18
+ else
19
+ raise "No value for argument #{argument.name}"
20
+ end
21
+ argument.type.string_to_value(value)
22
+ end
23
+ bean.send(self.name, *args)
24
+ end
25
+ end
26
+ end