ruote-maestrodev 2.2.1

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.
Files changed (265) hide show
  1. data/CHANGELOG.txt +290 -0
  2. data/CREDITS.txt +99 -0
  3. data/LICENSE.txt +21 -0
  4. data/README.rdoc +88 -0
  5. data/Rakefile +108 -0
  6. data/TODO.txt +488 -0
  7. data/lib/ruote.rb +7 -0
  8. data/lib/ruote/context.rb +194 -0
  9. data/lib/ruote/engine.rb +1062 -0
  10. data/lib/ruote/engine/process_error.rb +122 -0
  11. data/lib/ruote/engine/process_status.rb +448 -0
  12. data/lib/ruote/exp/command.rb +87 -0
  13. data/lib/ruote/exp/commanded.rb +69 -0
  14. data/lib/ruote/exp/condition.rb +227 -0
  15. data/lib/ruote/exp/fe_add_branches.rb +138 -0
  16. data/lib/ruote/exp/fe_apply.rb +154 -0
  17. data/lib/ruote/exp/fe_cancel_process.rb +78 -0
  18. data/lib/ruote/exp/fe_command.rb +156 -0
  19. data/lib/ruote/exp/fe_concurrence.rb +321 -0
  20. data/lib/ruote/exp/fe_concurrent_iterator.rb +219 -0
  21. data/lib/ruote/exp/fe_cron.rb +141 -0
  22. data/lib/ruote/exp/fe_cursor.rb +324 -0
  23. data/lib/ruote/exp/fe_define.rb +112 -0
  24. data/lib/ruote/exp/fe_echo.rb +60 -0
  25. data/lib/ruote/exp/fe_equals.rb +115 -0
  26. data/lib/ruote/exp/fe_error.rb +82 -0
  27. data/lib/ruote/exp/fe_filter.rb +648 -0
  28. data/lib/ruote/exp/fe_forget.rb +88 -0
  29. data/lib/ruote/exp/fe_given.rb +154 -0
  30. data/lib/ruote/exp/fe_if.rb +127 -0
  31. data/lib/ruote/exp/fe_inc.rb +205 -0
  32. data/lib/ruote/exp/fe_iterator.rb +234 -0
  33. data/lib/ruote/exp/fe_let.rb +75 -0
  34. data/lib/ruote/exp/fe_listen.rb +304 -0
  35. data/lib/ruote/exp/fe_lose.rb +110 -0
  36. data/lib/ruote/exp/fe_noop.rb +45 -0
  37. data/lib/ruote/exp/fe_once.rb +215 -0
  38. data/lib/ruote/exp/fe_participant.rb +287 -0
  39. data/lib/ruote/exp/fe_read.rb +69 -0
  40. data/lib/ruote/exp/fe_redo.rb +82 -0
  41. data/lib/ruote/exp/fe_ref.rb +152 -0
  42. data/lib/ruote/exp/fe_registerp.rb +110 -0
  43. data/lib/ruote/exp/fe_reserve.rb +126 -0
  44. data/lib/ruote/exp/fe_restore.rb +102 -0
  45. data/lib/ruote/exp/fe_save.rb +72 -0
  46. data/lib/ruote/exp/fe_sequence.rb +59 -0
  47. data/lib/ruote/exp/fe_set.rb +154 -0
  48. data/lib/ruote/exp/fe_subprocess.rb +211 -0
  49. data/lib/ruote/exp/fe_that.rb +92 -0
  50. data/lib/ruote/exp/fe_undo.rb +67 -0
  51. data/lib/ruote/exp/fe_unregisterp.rb +69 -0
  52. data/lib/ruote/exp/fe_wait.rb +95 -0
  53. data/lib/ruote/exp/flowexpression.rb +886 -0
  54. data/lib/ruote/exp/iterator.rb +81 -0
  55. data/lib/ruote/exp/merge.rb +118 -0
  56. data/lib/ruote/exp/ro_attributes.rb +212 -0
  57. data/lib/ruote/exp/ro_filters.rb +136 -0
  58. data/lib/ruote/exp/ro_persist.rb +154 -0
  59. data/lib/ruote/exp/ro_variables.rb +189 -0
  60. data/lib/ruote/exp/ro_vf.rb +68 -0
  61. data/lib/ruote/fei.rb +260 -0
  62. data/lib/ruote/id/mnemo_wfid_generator.rb +43 -0
  63. data/lib/ruote/id/wfid_generator.rb +81 -0
  64. data/lib/ruote/log/default_history.rb +122 -0
  65. data/lib/ruote/log/pretty.rb +176 -0
  66. data/lib/ruote/log/storage_history.rb +159 -0
  67. data/lib/ruote/log/test_logger.rb +208 -0
  68. data/lib/ruote/log/wait_logger.rb +64 -0
  69. data/lib/ruote/part/block_participant.rb +137 -0
  70. data/lib/ruote/part/code_participant.rb +81 -0
  71. data/lib/ruote/part/engine_participant.rb +189 -0
  72. data/lib/ruote/part/local_participant.rb +138 -0
  73. data/lib/ruote/part/no_op_participant.rb +60 -0
  74. data/lib/ruote/part/null_participant.rb +54 -0
  75. data/lib/ruote/part/rev_participant.rb +169 -0
  76. data/lib/ruote/part/smtp_participant.rb +116 -0
  77. data/lib/ruote/part/storage_participant.rb +392 -0
  78. data/lib/ruote/part/template.rb +84 -0
  79. data/lib/ruote/participant.rb +7 -0
  80. data/lib/ruote/reader.rb +278 -0
  81. data/lib/ruote/reader/json.rb +49 -0
  82. data/lib/ruote/reader/radial.rb +290 -0
  83. data/lib/ruote/reader/ruby_dsl.rb +186 -0
  84. data/lib/ruote/reader/xml.rb +99 -0
  85. data/lib/ruote/receiver/base.rb +212 -0
  86. data/lib/ruote/storage/base.rb +364 -0
  87. data/lib/ruote/storage/composite_storage.rb +121 -0
  88. data/lib/ruote/storage/fs_storage.rb +139 -0
  89. data/lib/ruote/storage/hash_storage.rb +211 -0
  90. data/lib/ruote/svc/dispatch_pool.rb +158 -0
  91. data/lib/ruote/svc/dollar_sub.rb +298 -0
  92. data/lib/ruote/svc/error_handler.rb +138 -0
  93. data/lib/ruote/svc/expression_map.rb +97 -0
  94. data/lib/ruote/svc/participant_list.rb +397 -0
  95. data/lib/ruote/svc/tracker.rb +172 -0
  96. data/lib/ruote/svc/treechecker.rb +141 -0
  97. data/lib/ruote/tree_dot.rb +85 -0
  98. data/lib/ruote/util/filter.rb +525 -0
  99. data/lib/ruote/util/hashdot.rb +79 -0
  100. data/lib/ruote/util/look.rb +128 -0
  101. data/lib/ruote/util/lookup.rb +127 -0
  102. data/lib/ruote/util/misc.rb +167 -0
  103. data/lib/ruote/util/ometa.rb +71 -0
  104. data/lib/ruote/util/serializer.rb +103 -0
  105. data/lib/ruote/util/subprocess.rb +88 -0
  106. data/lib/ruote/util/time.rb +100 -0
  107. data/lib/ruote/util/tree.rb +58 -0
  108. data/lib/ruote/version.rb +29 -0
  109. data/lib/ruote/worker.rb +386 -0
  110. data/lib/ruote/workitem.rb +394 -0
  111. data/phil.txt +14 -0
  112. data/ruote.gemspec +44 -0
  113. data/test/bm/ci.rb +55 -0
  114. data/test/bm/ici.rb +71 -0
  115. data/test/bm/juuman.rb +54 -0
  116. data/test/bm/launch_bench.rb +37 -0
  117. data/test/bm/load_26c.rb +97 -0
  118. data/test/bm/mega.rb +64 -0
  119. data/test/bm/seq_thousand.rb +31 -0
  120. data/test/bm/t.rb +35 -0
  121. data/test/functional/base.rb +247 -0
  122. data/test/functional/concurrent_base.rb +98 -0
  123. data/test/functional/crunner.rb +31 -0
  124. data/test/functional/ct_0_concurrence.rb +65 -0
  125. data/test/functional/ct_1_iterator.rb +67 -0
  126. data/test/functional/ct_2_cancel.rb +81 -0
  127. data/test/functional/eft_0_process_definition.rb +65 -0
  128. data/test/functional/eft_10_cancel_process.rb +46 -0
  129. data/test/functional/eft_11_wait.rb +109 -0
  130. data/test/functional/eft_12_listen.rb +500 -0
  131. data/test/functional/eft_13_iterator.rb +342 -0
  132. data/test/functional/eft_14_cursor.rb +456 -0
  133. data/test/functional/eft_15_loop.rb +69 -0
  134. data/test/functional/eft_16_if.rb +183 -0
  135. data/test/functional/eft_17_equals.rb +55 -0
  136. data/test/functional/eft_18_concurrent_iterator.rb +410 -0
  137. data/test/functional/eft_19_reserve.rb +136 -0
  138. data/test/functional/eft_1_echo.rb +68 -0
  139. data/test/functional/eft_20_save.rb +116 -0
  140. data/test/functional/eft_21_restore.rb +61 -0
  141. data/test/functional/eft_22_noop.rb +28 -0
  142. data/test/functional/eft_23_apply.rb +168 -0
  143. data/test/functional/eft_24_add_branches.rb +98 -0
  144. data/test/functional/eft_25_command.rb +28 -0
  145. data/test/functional/eft_26_error.rb +77 -0
  146. data/test/functional/eft_27_inc.rb +280 -0
  147. data/test/functional/eft_28_once.rb +135 -0
  148. data/test/functional/eft_29_cron.rb +64 -0
  149. data/test/functional/eft_2_sequence.rb +58 -0
  150. data/test/functional/eft_30_ref.rb +155 -0
  151. data/test/functional/eft_31_registerp.rb +130 -0
  152. data/test/functional/eft_32_lose.rb +93 -0
  153. data/test/functional/eft_33_let.rb +31 -0
  154. data/test/functional/eft_34_given.rb +123 -0
  155. data/test/functional/eft_35_filter.rb +375 -0
  156. data/test/functional/eft_36_read.rb +95 -0
  157. data/test/functional/eft_3_participant.rb +149 -0
  158. data/test/functional/eft_4_set.rb +296 -0
  159. data/test/functional/eft_5_subprocess.rb +163 -0
  160. data/test/functional/eft_6_concurrence.rb +304 -0
  161. data/test/functional/eft_7_forget.rb +61 -0
  162. data/test/functional/eft_8_undo.rb +114 -0
  163. data/test/functional/eft_9_redo.rb +138 -0
  164. data/test/functional/ft_0_worker.rb +65 -0
  165. data/test/functional/ft_10_dollar.rb +304 -0
  166. data/test/functional/ft_11_recursion.rb +109 -0
  167. data/test/functional/ft_12_launchitem.rb +43 -0
  168. data/test/functional/ft_13_variables.rb +151 -0
  169. data/test/functional/ft_14_re_apply.rb +324 -0
  170. data/test/functional/ft_15_timeout.rb +226 -0
  171. data/test/functional/ft_16_participant_params.rb +98 -0
  172. data/test/functional/ft_17_conditional.rb +102 -0
  173. data/test/functional/ft_18_kill.rb +138 -0
  174. data/test/functional/ft_19_participant_code.rb +67 -0
  175. data/test/functional/ft_1_process_status.rb +796 -0
  176. data/test/functional/ft_20_storage_participant.rb +543 -0
  177. data/test/functional/ft_21_forget.rb +153 -0
  178. data/test/functional/ft_22_process_definitions.rb +90 -0
  179. data/test/functional/ft_23_load_defs.rb +79 -0
  180. data/test/functional/ft_24_block_participant.rb +235 -0
  181. data/test/functional/ft_25_receiver.rb +207 -0
  182. data/test/functional/ft_26_participant_rtimeout.rb +179 -0
  183. data/test/functional/ft_27_var_indirection.rb +128 -0
  184. data/test/functional/ft_28_null_noop_participants.rb +51 -0
  185. data/test/functional/ft_29_part_template.rb +60 -0
  186. data/test/functional/ft_2_errors.rb +380 -0
  187. data/test/functional/ft_30_smtp_participant.rb +122 -0
  188. data/test/functional/ft_31_part_blocking.rb +72 -0
  189. data/test/functional/ft_33_participant_subprocess_priority.rb +32 -0
  190. data/test/functional/ft_34_cursor_rewind.rb +101 -0
  191. data/test/functional/ft_35_add_service.rb +56 -0
  192. data/test/functional/ft_36_storage_history.rb +150 -0
  193. data/test/functional/ft_37_default_history.rb +109 -0
  194. data/test/functional/ft_38_participant_more.rb +193 -0
  195. data/test/functional/ft_39_wait_for.rb +136 -0
  196. data/test/functional/ft_3_participant_registration.rb +574 -0
  197. data/test/functional/ft_40_wait_logger.rb +62 -0
  198. data/test/functional/ft_41_participants.rb +91 -0
  199. data/test/functional/ft_42_storage_copy.rb +71 -0
  200. data/test/functional/ft_43_participant_on_reply.rb +87 -0
  201. data/test/functional/ft_44_var_participant.rb +35 -0
  202. data/test/functional/ft_45_participant_accept.rb +64 -0
  203. data/test/functional/ft_46_launch_single.rb +83 -0
  204. data/test/functional/ft_47_wfid_generator.rb +54 -0
  205. data/test/functional/ft_48_lose.rb +112 -0
  206. data/test/functional/ft_49_engine_on_error.rb +201 -0
  207. data/test/functional/ft_4_cancel.rb +132 -0
  208. data/test/functional/ft_50_engine_config.rb +22 -0
  209. data/test/functional/ft_51_misc.rb +67 -0
  210. data/test/functional/ft_52_case.rb +134 -0
  211. data/test/functional/ft_53_engine_on_terminate.rb +95 -0
  212. data/test/functional/ft_54_patterns.rb +104 -0
  213. data/test/functional/ft_55_engine_participant.rb +303 -0
  214. data/test/functional/ft_56_filter_attribute.rb +259 -0
  215. data/test/functional/ft_57_rev_participant.rb +252 -0
  216. data/test/functional/ft_58_workitem.rb +69 -0
  217. data/test/functional/ft_59_pause.rb +343 -0
  218. data/test/functional/ft_5_on_error.rb +384 -0
  219. data/test/functional/ft_60_code_participant.rb +45 -0
  220. data/test/functional/ft_61_trailing_fields.rb +34 -0
  221. data/test/functional/ft_62_exp_name_and_dollar_substitution.rb +35 -0
  222. data/test/functional/ft_6_on_cancel.rb +221 -0
  223. data/test/functional/ft_7_tags.rb +177 -0
  224. data/test/functional/ft_8_participant_consumption.rb +124 -0
  225. data/test/functional/ft_9_subprocesses.rb +146 -0
  226. data/test/functional/restart_base.rb +34 -0
  227. data/test/functional/rt_0_wait.rb +55 -0
  228. data/test/functional/rt_1_listen.rb +56 -0
  229. data/test/functional/rt_2_errors.rb +56 -0
  230. data/test/functional/rt_3_once.rb +70 -0
  231. data/test/functional/rt_4_cron.rb +64 -0
  232. data/test/functional/rt_5_timeout.rb +60 -0
  233. data/test/functional/rtest.rb +8 -0
  234. data/test/functional/storage_helper.rb +93 -0
  235. data/test/functional/test.rb +44 -0
  236. data/test/functional/vertical.rb +46 -0
  237. data/test/path_helper.rb +15 -0
  238. data/test/test.rb +13 -0
  239. data/test/test_helper.rb +28 -0
  240. data/test/unit/storage.rb +428 -0
  241. data/test/unit/storages.rb +37 -0
  242. data/test/unit/test.rb +28 -0
  243. data/test/unit/ut_0_ruby_reader.rb +223 -0
  244. data/test/unit/ut_11_lookup.rb +122 -0
  245. data/test/unit/ut_13_serializer.rb +65 -0
  246. data/test/unit/ut_14_is_uri.rb +28 -0
  247. data/test/unit/ut_15_util.rb +57 -0
  248. data/test/unit/ut_16_reader.rb +225 -0
  249. data/test/unit/ut_18_engine.rb +47 -0
  250. data/test/unit/ut_19_part_template.rb +86 -0
  251. data/test/unit/ut_1_fei.rb +165 -0
  252. data/test/unit/ut_20_composite_storage.rb +74 -0
  253. data/test/unit/ut_21_svc_participant_list.rb +46 -0
  254. data/test/unit/ut_22_filter.rb +1094 -0
  255. data/test/unit/ut_23_svc_tracker.rb +48 -0
  256. data/test/unit/ut_24_radial_reader.rb +332 -0
  257. data/test/unit/ut_25_merge.rb +113 -0
  258. data/test/unit/ut_3_wait_logger.rb +39 -0
  259. data/test/unit/ut_4_expmap.rb +20 -0
  260. data/test/unit/ut_5_tree.rb +54 -0
  261. data/test/unit/ut_6_condition.rb +303 -0
  262. data/test/unit/ut_7_workitem.rb +99 -0
  263. data/test/unit/ut_8_tree_to_dot.rb +72 -0
  264. data/test/unit/ut_9_xml_reader.rb +61 -0
  265. metadata +504 -0
@@ -0,0 +1,79 @@
1
+ #--
2
+ # Copyright (c) 2005-2011, John Mettraux, jmettraux@gmail.com
3
+ #
4
+ # Permission is hereby granted, free of charge, to any person obtaining a copy
5
+ # of this software and associated documentation files (the "Software"), to deal
6
+ # in the Software without restriction, including without limitation the rights
7
+ # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8
+ # copies of the Software, and to permit persons to whom the Software is
9
+ # furnished to do so, subject to the following conditions:
10
+ #
11
+ # The above copyright notice and this permission notice shall be included in
12
+ # all copies or substantial portions of the Software.
13
+ #
14
+ # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15
+ # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16
+ # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17
+ # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18
+ # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19
+ # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
20
+ # THE SOFTWARE.
21
+ #
22
+ # Made in Japan.
23
+ #++
24
+
25
+
26
+ module Ruote
27
+
28
+ module HashDot
29
+
30
+ def method_missing(m, *args)
31
+
32
+ m = m.to_s
33
+
34
+ if m[-1, 1] == '='
35
+
36
+ val = args.first
37
+ self[m[0..-2]] = val
38
+
39
+ return val
40
+ end
41
+
42
+ self[m]
43
+ end
44
+
45
+ def dump
46
+
47
+ s = "~~ h ~~\n"
48
+ each do |k, v|
49
+ s << " * '#{k}' => "
50
+ s << v.inspect
51
+ s << "\n"
52
+ end
53
+ s << "~~ . ~~"
54
+ end
55
+
56
+ #--
57
+ # Useful when debugging some 'stack too deep' issue
58
+ #
59
+ #def self.included(target)
60
+ # raise target.to_s unless target.to_s.match(/\bHash\b/)
61
+ #end
62
+ #++
63
+ end
64
+
65
+ module WithH
66
+
67
+ def self.included(target)
68
+
69
+ def target.h_reader(*names)
70
+ names.each do |name|
71
+ define_method(name) do
72
+ @h[name.to_s]
73
+ end
74
+ end
75
+ end
76
+ end
77
+ end
78
+ end
79
+
@@ -0,0 +1,128 @@
1
+ #--
2
+ # Copyright (c) 2005-2011, John Mettraux, jmettraux@gmail.com
3
+ #
4
+ # Permission is hereby granted, free of charge, to any person obtaining a copy
5
+ # of this software and associated documentation files (the "Software"), to deal
6
+ # in the Software without restriction, including without limitation the rights
7
+ # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8
+ # copies of the Software, and to permit persons to whom the Software is
9
+ # furnished to do so, subject to the following conditions:
10
+ #
11
+ # The above copyright notice and this permission notice shall be included in
12
+ # all copies or substantial portions of the Software.
13
+ #
14
+ # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15
+ # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16
+ # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17
+ # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18
+ # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19
+ # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
20
+ # THE SOFTWARE.
21
+ #
22
+ # Made in Japan.
23
+ #++
24
+
25
+
26
+ module Ruote
27
+
28
+ #
29
+ # Some methods for looking at system/runtime things.
30
+ #
31
+ module Look
32
+
33
+ def self.lsof
34
+
35
+ `lsof -p #{$$}`
36
+ end
37
+
38
+ def self.dump_lsof
39
+
40
+ result = lsof
41
+
42
+ puts '= lsof =' + '=' * 71
43
+ puts result
44
+ puts result.split("\n").size
45
+ puts '=' * 80
46
+ end
47
+
48
+ def self.dump_lsof_count
49
+
50
+ puts '= lsof count =' + '=' * 65
51
+ puts lsof.split("\n").size
52
+ puts '=' * 80
53
+ end
54
+ end
55
+
56
+ #
57
+ # Some utilities for mem usage analysis
58
+ #
59
+ module Mem
60
+
61
+ # Returns a Hash : classname => [ count, maxsize, totalsize, avgsize ]
62
+ #
63
+ # The relative size of an object is computed with Marshal.dump(o).size
64
+ #
65
+ # This uses ObjectSpace.
66
+ #
67
+ # see http://www.ruby-forum.com/topic/186339 for better options.
68
+ #
69
+ def self.count
70
+
71
+ uninteresting = [
72
+ Array, String, Hash, Set, Module, Range, Float, Bignum
73
+ ]
74
+
75
+ h = {}
76
+
77
+ ObjectSpace.each_object do |o|
78
+
79
+ next if uninteresting.include?(o.class)
80
+
81
+ stats = h[o.class.to_s] ||= [ 0, 0, 0 ]
82
+ size = (Marshal.dump(o).size rescue 1)
83
+
84
+ stats[0] += 1
85
+ stats[1] = size if size > stats[1]
86
+ stats[2] += size
87
+ end
88
+
89
+ a = h.to_a
90
+ a.each { |k, v| v << v[2] / v[0] }
91
+
92
+ a.sort { |x, y| x.last[1] <=> y.last[1] }.reverse
93
+ end
94
+
95
+ # Very naive : does a "ps aux | grep pid".
96
+ #
97
+ # Returns a hash like this one :
98
+ #
99
+ # {
100
+ # :user => "jmettraux",
101
+ # :pid => "1100",
102
+ # :cpu => "73.0",
103
+ # :mem => "0.8",
104
+ # :vsz => "2472732",
105
+ # :rss => "35308",
106
+ # :tt => "s001",
107
+ # :stat => "S+",
108
+ # :started => "8:55PM",
109
+ # :time => "0:01.05",
110
+ # :command => "ruby start.rb"
111
+ # }
112
+ #
113
+ def self.ps
114
+
115
+ s = `ps aux | egrep '^.+ +#{$$} '`.split(' ')
116
+ s[10] = s[10..-1].join(' ') # the command
117
+
118
+ h = {}
119
+
120
+ %w[
121
+ user pid cpu mem vsz rss tt stat started time command
122
+ ].each_with_index { |k, i| h[k.to_sym] = s[i] }
123
+
124
+ h
125
+ end
126
+ end
127
+ end
128
+
@@ -0,0 +1,127 @@
1
+ #--
2
+ # Copyright (c) 2005-2011, John Mettraux, jmettraux@gmail.com
3
+ #
4
+ # Permission is hereby granted, free of charge, to any person obtaining a copy
5
+ # of this software and associated documentation files (the "Software"), to deal
6
+ # in the Software without restriction, including without limitation the rights
7
+ # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8
+ # copies of the Software, and to permit persons to whom the Software is
9
+ # furnished to do so, subject to the following conditions:
10
+ #
11
+ # The above copyright notice and this permission notice shall be included in
12
+ # all copies or substantial portions of the Software.
13
+ #
14
+ # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15
+ # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16
+ # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17
+ # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18
+ # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19
+ # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
20
+ # THE SOFTWARE.
21
+ #
22
+ # Made in Japan.
23
+ #++
24
+
25
+
26
+ module Ruote
27
+
28
+ # h = { 'a' => { 'b' => [ 1, 3, 4 ] } }
29
+ #
30
+ # p Ruote.lookup(h, 'a.b.1') # => 3
31
+ #
32
+ def Ruote.lookup(collection, key, container_lookup=false)
33
+
34
+ return collection if key == '.'
35
+
36
+ key, rest = pop_key(key)
37
+ value = fetch(collection, key)
38
+
39
+ return [ key, collection ] if container_lookup && rest.size == 0
40
+ return [ rest.first, value ] if container_lookup && rest.size == 1
41
+ return value if rest.size == 0
42
+ return nil if value == nil
43
+
44
+ lookup(value, rest, container_lookup)
45
+ end
46
+
47
+ # h = { 'customer' => { 'name' => 'alpha' } }
48
+ #
49
+ # Ruote.set(h, 'customer.name', 'bravo')
50
+ #
51
+ # h #=> { 'customer' => { 'name' => 'bravo' } }
52
+ #
53
+ def Ruote.set(collection, key, value)
54
+
55
+ k, c = lookup(collection, key, true)
56
+
57
+ if c
58
+ k = k.to_i if c.is_a?(Array)
59
+ c[k] = value
60
+ else
61
+ collection[key] = value
62
+ end
63
+ end
64
+
65
+ # h = { 'customer' => { 'name' => 'alpha', 'rank' => '1st' } }
66
+ # r = Ruote.unset(h, 'customer.rank')
67
+ #
68
+ # h # => { 'customer' => { 'name' => 'alpha' } }
69
+ # r # => '1st'
70
+ #
71
+ def Ruote.unset(collection, key)
72
+
73
+ k, c = lookup(collection, key, true)
74
+
75
+ if c.nil?
76
+ collection.delete(key)
77
+ elsif c.is_a?(Array)
78
+ c.delete_at(Integer(k)) rescue nil
79
+ elsif c.is_a?(Hash)
80
+ c.delete(k)
81
+ else
82
+ nil
83
+ end
84
+ end
85
+
86
+ protected # well...
87
+
88
+ # Pops the first key in a path key.
89
+ #
90
+ # Ruote.pop_key('a.b.c') # => 'a'
91
+ # Ruote.pop_key('1.2.3') # => 1
92
+ #
93
+ # (note the narrowing to an int that happens)
94
+ #
95
+ def Ruote.pop_key(key)
96
+
97
+ ks = key.is_a?(String) ? key.split('.') : key
98
+
99
+ [ narrow_key(ks.first), ks[1..-1] ]
100
+ end
101
+
102
+ # Attempts at turning a key into an integer, if it fails returns the
103
+ # original key.
104
+ #
105
+ def Ruote.narrow_key(key)
106
+
107
+ Integer(key) rescue key
108
+ end
109
+
110
+ # Given a collection and a key returns the corresponding value
111
+ #
112
+ # Ruote.fetch([ 12, 13, 24 ], 1) # => 13
113
+ # Ruote.fetch({ '1' => 13 }, 1) # => 13
114
+ # Ruote.fetch({ 1 => 13 }, 1) # => 13
115
+ #
116
+ def Ruote.fetch(collection, key)
117
+
118
+ value = (collection[key] rescue nil)
119
+
120
+ if value == nil and key.is_a?(Fixnum)
121
+ (collection[key.to_s] rescue nil)
122
+ else
123
+ value
124
+ end
125
+ end
126
+ end
127
+
@@ -0,0 +1,167 @@
1
+ #--
2
+ # Copyright (c) 2005-2011, John Mettraux, jmettraux@gmail.com
3
+ #
4
+ # Permission is hereby granted, free of charge, to any person obtaining a copy
5
+ # of this software and associated documentation files (the "Software"), to deal
6
+ # in the Software without restriction, including without limitation the rights
7
+ # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8
+ # copies of the Software, and to permit persons to whom the Software is
9
+ # furnished to do so, subject to the following conditions:
10
+ #
11
+ # The above copyright notice and this permission notice shall be included in
12
+ # all copies or substantial portions of the Software.
13
+ #
14
+ # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15
+ # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16
+ # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17
+ # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18
+ # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19
+ # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
20
+ # THE SOFTWARE.
21
+ #
22
+ # Made in Japan.
23
+ #++
24
+
25
+
26
+ module Ruote
27
+
28
+ # Will be set to true if the Ruby runtime is on Windows
29
+ #
30
+ WIN = (RUBY_PLATFORM.match(/mswin|mingw/) != nil)
31
+
32
+ # Will be set to true if the Ruby runtime is JRuby
33
+ #
34
+ JAVA = (RUBY_PLATFORM.match(/java/) != nil)
35
+
36
+ # Prints the current call stack to stdout
37
+ #
38
+ def self.p_caller(*msg)
39
+
40
+ puts
41
+ puts " == #{msg.inspect} =="
42
+ caller(1).each { |l| puts " #{l}" }
43
+ puts
44
+ end
45
+
46
+ # Deep object duplication
47
+ #
48
+ def self.fulldup(object)
49
+
50
+ return object.fulldup if object.respond_to?(:fulldup)
51
+ # trusting client objects providing a fulldup() implementation
52
+ # Tomaso Tosolini 2007.12.11
53
+
54
+ begin
55
+ return Marshal.load(Marshal.dump(object))
56
+ # as soon as possible try to use that Marshal technique
57
+ # it's quite fast
58
+ rescue TypeError => te
59
+ end
60
+
61
+ #if object.is_a?(REXML::Element)
62
+ # d = REXML::Document.new object.to_s
63
+ # return d if object.kind_of?(REXML::Document)
64
+ # return d.root
65
+ #end
66
+ # avoiding "TypeError: singleton can't be dumped"
67
+
68
+ o = object.class.allocate
69
+
70
+ # some kind of collection ?
71
+
72
+ if object.is_a?(Array)
73
+ object.each { |i| o << fulldup(i) }
74
+ elsif object.is_a?(Hash)
75
+ object.each { |k, v| o[fulldup(k)] = fulldup(v) }
76
+ end
77
+
78
+ # duplicate the attributes of the object
79
+
80
+ object.instance_variables.each do |v|
81
+ value = object.instance_variable_get(v)
82
+ value = fulldup(value)
83
+ begin
84
+ o.instance_variable_set(v, value)
85
+ rescue => e
86
+ # ignore, must be readonly
87
+ end
88
+ end
89
+
90
+ o
91
+ end
92
+
93
+ # Returns true if the string seems to correpond to a URI
94
+ #
95
+ # TODO : wouldn't it be better to simply use URI.parse() ?
96
+ #
97
+ def self.is_uri?(s)
98
+
99
+ s && (s.index('/') || s.match(/\.[^ ]+$/))
100
+ end
101
+
102
+ # Returns a neutralized version of s, suitable as a filename.
103
+ #
104
+ def self.neutralize(s)
105
+
106
+ s.to_s.strip.gsub(/[ \/:;\*\\\+\?]/, '_')
107
+ end
108
+
109
+ # Tries to return an Integer or a Float from the given input. Returns
110
+ #
111
+ def self.narrow_to_number(o)
112
+
113
+ return o if [ Fixnum, Bignum, Float ].include?(o.class)
114
+
115
+ s = o.to_s
116
+
117
+ (s.index('.') ? Float(s) : Integer(s)) rescue nil
118
+ end
119
+
120
+ # (simpler than the one from active_support)
121
+ #
122
+ def self.constantize(s)
123
+
124
+ s.split('::').inject(Object) { |c, n| n == '' ? c : c.const_get(n) }
125
+ end
126
+
127
+ # Makes sure all they keys in the given hash are turned into strings
128
+ # in the resulting hash.
129
+ #
130
+ def self.keys_to_s(h)
131
+
132
+ h.inject({}) { |h, (k, v)| h[k.to_s] = v; h }
133
+ end
134
+
135
+ # # Upon receiving something like
136
+ # #
137
+ # # "(?-mix:nada)"
138
+ # #
139
+ # # will return
140
+ # #
141
+ # # /nada/
142
+ # #
143
+ # def self.regex_from_s(s)
144
+ #
145
+ # if s.is_a?(String) && m = s.match(/^\(\?-mix:(.+)\)$/)
146
+ # Regexp.new(m[1])
147
+ # else
148
+ # nil
149
+ # end
150
+ # end
151
+
152
+ REGEX_IN_STRING = /^\s*\/(.*)\/\s*$/
153
+
154
+ # regex_or_s("/nada/") #==> /nada/
155
+ # regex_or_s("nada") #==> "nada"
156
+ # regex_or_s(/nada/) #==> /nada/
157
+ #
158
+ def self.regex_or_s(s)
159
+
160
+ if s.is_a?(String) && m = REGEX_IN_STRING.match(s)
161
+ Regexp.new(m[1])
162
+ else
163
+ s
164
+ end
165
+ end
166
+ end
167
+