genie 0.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 (313) hide show
  1. data/genie-0.1.gem +0 -0
  2. data/genie-0.1/docs/classes/BasicCommand.html +249 -0
  3. data/genie-0.1/docs/classes/BasicCommand.src/M000070.html +18 -0
  4. data/genie-0.1/docs/classes/BasicCommand.src/M000071.html +18 -0
  5. data/genie-0.1/docs/classes/BasicCommand.src/M000072.html +18 -0
  6. data/genie-0.1/docs/classes/BasicCommand.src/M000073.html +18 -0
  7. data/genie-0.1/docs/classes/BasicCommand.src/M000074.html +16 -0
  8. data/genie-0.1/docs/classes/Command.html +277 -0
  9. data/genie-0.1/docs/classes/Command.src/M000052.html +20 -0
  10. data/genie-0.1/docs/classes/Command.src/M000053.html +18 -0
  11. data/genie-0.1/docs/classes/Command.src/M000054.html +20 -0
  12. data/genie-0.1/docs/classes/Command.src/M000055.html +20 -0
  13. data/genie-0.1/docs/classes/Command.src/M000056.html +18 -0
  14. data/genie-0.1/docs/classes/Command.src/M000057.html +18 -0
  15. data/genie-0.1/docs/classes/Command.src/M000058.html +23 -0
  16. data/genie-0.1/docs/classes/CommandMetainfo.html +362 -0
  17. data/genie-0.1/docs/classes/CommandMetainfo.src/M000042.html +18 -0
  18. data/genie-0.1/docs/classes/CommandMetainfo.src/M000043.html +18 -0
  19. data/genie-0.1/docs/classes/CommandMetainfo.src/M000044.html +19 -0
  20. data/genie-0.1/docs/classes/CommandMetainfo.src/M000045.html +25 -0
  21. data/genie-0.1/docs/classes/CommandMetainfo.src/M000046.html +21 -0
  22. data/genie-0.1/docs/classes/CommandMetainfo.src/M000047.html +21 -0
  23. data/genie-0.1/docs/classes/CompoundResult.html +359 -0
  24. data/genie-0.1/docs/classes/CompoundResult.src/M000075.html +18 -0
  25. data/genie-0.1/docs/classes/CompoundResult.src/M000076.html +18 -0
  26. data/genie-0.1/docs/classes/CompoundResult.src/M000078.html +18 -0
  27. data/genie-0.1/docs/classes/CompoundResult.src/M000079.html +18 -0
  28. data/genie-0.1/docs/classes/CompoundResult.src/M000080.html +18 -0
  29. data/genie-0.1/docs/classes/CompoundResult.src/M000082.html +18 -0
  30. data/genie-0.1/docs/classes/CompoundResult.src/M000084.html +20 -0
  31. data/genie-0.1/docs/classes/CompoundResult.src/M000085.html +18 -0
  32. data/genie-0.1/docs/classes/CompoundResult.src/M000086.html +18 -0
  33. data/genie-0.1/docs/classes/CompoundResult.src/M000087.html +20 -0
  34. data/genie-0.1/docs/classes/EntryProcessor.html +223 -0
  35. data/genie-0.1/docs/classes/EntryProcessor.src/M000008.html +18 -0
  36. data/genie-0.1/docs/classes/EntryProcessor.src/M000009.html +20 -0
  37. data/genie-0.1/docs/classes/EntryProcessor.src/M000010.html +18 -0
  38. data/genie-0.1/docs/classes/EntryProcessor.src/M000011.html +23 -0
  39. data/genie-0.1/docs/classes/Log4r.html +114 -0
  40. data/genie-0.1/docs/classes/Log4r/LogEvent.html +153 -0
  41. data/genie-0.1/docs/classes/Log4r/LogEvent.src/M000123.html +16 -0
  42. data/genie-0.1/docs/classes/NotifiedProcessor.html +155 -0
  43. data/genie-0.1/docs/classes/NotifiedProcessor.src/M000094.html +22 -0
  44. data/genie-0.1/docs/classes/NullTransactionController.html +191 -0
  45. data/genie-0.1/docs/classes/NullTransactionController.src/M000030.html +16 -0
  46. data/genie-0.1/docs/classes/NullTransactionController.src/M000031.html +16 -0
  47. data/genie-0.1/docs/classes/Object.html +154 -0
  48. data/genie-0.1/docs/classes/Object.src/M000103.html +16 -0
  49. data/genie-0.1/docs/classes/Periodic.html +564 -0
  50. data/genie-0.1/docs/classes/Periodic.src/M000124.html +26 -0
  51. data/genie-0.1/docs/classes/Periodic.src/M000125.html +21 -0
  52. data/genie-0.1/docs/classes/Periodic.src/M000126.html +18 -0
  53. data/genie-0.1/docs/classes/Periodic.src/M000127.html +18 -0
  54. data/genie-0.1/docs/classes/Periodic.src/M000128.html +31 -0
  55. data/genie-0.1/docs/classes/Periodic.src/M000129.html +30 -0
  56. data/genie-0.1/docs/classes/Periodic.src/M000130.html +18 -0
  57. data/genie-0.1/docs/classes/Periodic.src/M000131.html +18 -0
  58. data/genie-0.1/docs/classes/Periodic.src/M000132.html +16 -0
  59. data/genie-0.1/docs/classes/PollingProcessor.html +303 -0
  60. data/genie-0.1/docs/classes/PollingProcessor.src/M000088.html +23 -0
  61. data/genie-0.1/docs/classes/PollingProcessor.src/M000089.html +19 -0
  62. data/genie-0.1/docs/classes/PollingProcessor.src/M000091.html +22 -0
  63. data/genie-0.1/docs/classes/PollingProcessor.src/M000092.html +18 -0
  64. data/genie-0.1/docs/classes/PollingProcessor.src/M000093.html +18 -0
  65. data/genie-0.1/docs/classes/Queue.html +562 -0
  66. data/genie-0.1/docs/classes/Queue.src/M000104.html +22 -0
  67. data/genie-0.1/docs/classes/Queue.src/M000105.html +18 -0
  68. data/genie-0.1/docs/classes/Queue.src/M000106.html +18 -0
  69. data/genie-0.1/docs/classes/Queue.src/M000107.html +18 -0
  70. data/genie-0.1/docs/classes/Queue.src/M000108.html +21 -0
  71. data/genie-0.1/docs/classes/Queue.src/M000109.html +21 -0
  72. data/genie-0.1/docs/classes/Queue.src/M000110.html +22 -0
  73. data/genie-0.1/docs/classes/Queue.src/M000111.html +16 -0
  74. data/genie-0.1/docs/classes/Queue.src/M000112.html +18 -0
  75. data/genie-0.1/docs/classes/Queue.src/M000113.html +19 -0
  76. data/genie-0.1/docs/classes/Queue.src/M000114.html +23 -0
  77. data/genie-0.1/docs/classes/Queue.src/M000115.html +21 -0
  78. data/genie-0.1/docs/classes/Queue.src/M000116.html +19 -0
  79. data/genie-0.1/docs/classes/Queue.src/M000117.html +20 -0
  80. data/genie-0.1/docs/classes/Queue.src/M000118.html +25 -0
  81. data/genie-0.1/docs/classes/Queue.src/M000119.html +18 -0
  82. data/genie-0.1/docs/classes/Queue.src/M000120.html +22 -0
  83. data/genie-0.1/docs/classes/Queue.src/M000121.html +22 -0
  84. data/genie-0.1/docs/classes/Queue.src/M000122.html +20 -0
  85. data/genie-0.1/docs/classes/QueueDispatcher.html +247 -0
  86. data/genie-0.1/docs/classes/QueueDispatcher.src/M000048.html +18 -0
  87. data/genie-0.1/docs/classes/QueueDispatcher.src/M000049.html +21 -0
  88. data/genie-0.1/docs/classes/QueueDispatcher.src/M000050.html +18 -0
  89. data/genie-0.1/docs/classes/QueueDispatcher.src/M000051.html +32 -0
  90. data/genie-0.1/docs/classes/QueueEntry.html +522 -0
  91. data/genie-0.1/docs/classes/QueueEntry.src/M000012.html +21 -0
  92. data/genie-0.1/docs/classes/QueueEntry.src/M000013.html +18 -0
  93. data/genie-0.1/docs/classes/QueueEntry.src/M000014.html +18 -0
  94. data/genie-0.1/docs/classes/QueueEntry.src/M000015.html +18 -0
  95. data/genie-0.1/docs/classes/QueueEntry.src/M000017.html +16 -0
  96. data/genie-0.1/docs/classes/QueueEntry.src/M000018.html +19 -0
  97. data/genie-0.1/docs/classes/QueueEntry.src/M000020.html +19 -0
  98. data/genie-0.1/docs/classes/QueueEntry.src/M000022.html +19 -0
  99. data/genie-0.1/docs/classes/QueueEntry.src/M000023.html +21 -0
  100. data/genie-0.1/docs/classes/QueueEntry.src/M000024.html +19 -0
  101. data/genie-0.1/docs/classes/QueueEntry.src/M000025.html +18 -0
  102. data/genie-0.1/docs/classes/QueueEntry.src/M000026.html +18 -0
  103. data/genie-0.1/docs/classes/QueueEntry.src/M000028.html +18 -0
  104. data/genie-0.1/docs/classes/Result.html +289 -0
  105. data/genie-0.1/docs/classes/Result.src/M000063.html +20 -0
  106. data/genie-0.1/docs/classes/Result.src/M000064.html +18 -0
  107. data/genie-0.1/docs/classes/Result.src/M000066.html +18 -0
  108. data/genie-0.1/docs/classes/Result.src/M000068.html +18 -0
  109. data/genie-0.1/docs/classes/Result.src/M000069.html +19 -0
  110. data/genie-0.1/docs/classes/SemanticCommand.html +229 -0
  111. data/genie-0.1/docs/classes/SemanticCommand.src/M000059.html +19 -0
  112. data/genie-0.1/docs/classes/SemanticCommand.src/M000060.html +18 -0
  113. data/genie-0.1/docs/classes/SemanticCommand.src/M000061.html +18 -0
  114. data/genie-0.1/docs/classes/TransactionBundle.html +260 -0
  115. data/genie-0.1/docs/classes/TransactionBundle.src/M000001.html +18 -0
  116. data/genie-0.1/docs/classes/TransactionBundle.src/M000002.html +20 -0
  117. data/genie-0.1/docs/classes/TransactionBundle.src/M000003.html +20 -0
  118. data/genie-0.1/docs/classes/TransactionBundle.src/M000004.html +18 -0
  119. data/genie-0.1/docs/classes/TransactionBundle.src/M000005.html +18 -0
  120. data/genie-0.1/docs/classes/TransactionBundle.src/M000007.html +19 -0
  121. data/genie-0.1/docs/classes/UndoRedoCommand.html +308 -0
  122. data/genie-0.1/docs/classes/UndoRedoCommand.src/M000095.html +19 -0
  123. data/genie-0.1/docs/classes/UndoRedoCommand.src/M000096.html +16 -0
  124. data/genie-0.1/docs/classes/UndoRedoCommand.src/M000097.html +16 -0
  125. data/genie-0.1/docs/classes/UndoRedoCommand.src/M000098.html +16 -0
  126. data/genie-0.1/docs/classes/UndoRedoCommand.src/M000099.html +18 -0
  127. data/genie-0.1/docs/classes/UndoRedoCommand.src/M000101.html +18 -0
  128. data/genie-0.1/docs/classes/UndoRedoCommand.src/M000102.html +18 -0
  129. data/genie-0.1/docs/classes/UnitOfWork.html +322 -0
  130. data/genie-0.1/docs/classes/UnitOfWork.src/M000032.html +19 -0
  131. data/genie-0.1/docs/classes/UnitOfWork.src/M000033.html +18 -0
  132. data/genie-0.1/docs/classes/UnitOfWork.src/M000034.html +18 -0
  133. data/genie-0.1/docs/classes/UnitOfWork.src/M000035.html +18 -0
  134. data/genie-0.1/docs/classes/UnitOfWork.src/M000036.html +18 -0
  135. data/genie-0.1/docs/classes/UnitOfWork.src/M000037.html +18 -0
  136. data/genie-0.1/docs/classes/UnitOfWork.src/M000038.html +18 -0
  137. data/genie-0.1/docs/classes/UnitOfWork.src/M000039.html +18 -0
  138. data/genie-0.1/docs/classes/UnitOfWork.src/M000040.html +18 -0
  139. data/genie-0.1/docs/created.rid +1 -0
  140. data/genie-0.1/docs/dot/f_0.dot +14 -0
  141. data/genie-0.1/docs/dot/f_0.png +0 -0
  142. data/genie-0.1/docs/dot/f_1.dot +14 -0
  143. data/genie-0.1/docs/dot/f_1.png +0 -0
  144. data/genie-0.1/docs/dot/f_2.dot +14 -0
  145. data/genie-0.1/docs/dot/f_2.png +0 -0
  146. data/genie-0.1/docs/dot/f_3.dot +84 -0
  147. data/genie-0.1/docs/dot/f_3.png +0 -0
  148. data/genie-0.1/docs/dot/f_4.dot +14 -0
  149. data/genie-0.1/docs/dot/f_4.png +0 -0
  150. data/genie-0.1/docs/dot/f_5.dot +78 -0
  151. data/genie-0.1/docs/dot/f_5.png +0 -0
  152. data/genie-0.1/docs/dot/f_6.dot +50 -0
  153. data/genie-0.1/docs/dot/f_6.png +0 -0
  154. data/genie-0.1/docs/dot/f_7.dot +57 -0
  155. data/genie-0.1/docs/dot/f_7.png +0 -0
  156. data/genie-0.1/docs/dot/m_5_0.dot +30 -0
  157. data/genie-0.1/docs/dot/m_5_0.png +0 -0
  158. data/genie-0.1/docs/dot/m_7_0.dot +39 -0
  159. data/genie-0.1/docs/dot/m_7_0.png +0 -0
  160. data/genie-0.1/docs/files/License_txt.html +161 -0
  161. data/genie-0.1/docs/files/ReadMe_Amber_txt.html +491 -0
  162. data/genie-0.1/docs/files/ReadMe_txt.html +444 -0
  163. data/genie-0.1/docs/files/nist/genie/commands_rb.html +121 -0
  164. data/genie-0.1/docs/files/nist/genie/genie_rb.html +116 -0
  165. data/genie-0.1/docs/files/nist/genie/processors_rb.html +111 -0
  166. data/genie-0.1/docs/files/nist/genie/queues_rb.html +118 -0
  167. data/genie-0.1/docs/files/nist/genie/results_rb.html +117 -0
  168. data/genie-0.1/docs/fr_class_index.html +46 -0
  169. data/genie-0.1/docs/fr_file_index.html +34 -0
  170. data/genie-0.1/docs/fr_method_index.html +160 -0
  171. data/genie-0.1/docs/images/overview.jpg +0 -0
  172. data/genie-0.1/docs/index.html +24 -0
  173. data/genie-0.1/docs/rdoc-style.css +208 -0
  174. data/genie-0.1/lib/nist/genie/commands.rb +413 -0
  175. data/genie-0.1/lib/nist/genie/genie.rb +4 -0
  176. data/genie-0.1/lib/nist/genie/processors.rb +382 -0
  177. data/genie-0.1/lib/nist/genie/queues.rb +435 -0
  178. data/genie-0.1/lib/nist/genie/results.rb +113 -0
  179. data/genie-0.1/tests/helpers.rb +45 -0
  180. data/genie-0.1/tests/test_commands.rb +338 -0
  181. data/genie-0.1/tests/test_processors.rb +17 -0
  182. data/genie-0.1/tests/test_queues.rb +288 -0
  183. data/genie-0.1/tests/test_results.rb +37 -0
  184. data/trimurti-0.1.gem +0 -0
  185. data/trimurti-0.1/docs/classes/Array.html +176 -0
  186. data/trimurti-0.1/docs/classes/Array.src/M000005.html +19 -0
  187. data/trimurti-0.1/docs/classes/Array.src/M000006.html +19 -0
  188. data/trimurti-0.1/docs/classes/Asserter.html +136 -0
  189. data/trimurti-0.1/docs/classes/Brahma.html +360 -0
  190. data/trimurti-0.1/docs/classes/Brahma.src/M000029.html +21 -0
  191. data/trimurti-0.1/docs/classes/Brahma.src/M000030.html +20 -0
  192. data/trimurti-0.1/docs/classes/Brahma.src/M000031.html +36 -0
  193. data/trimurti-0.1/docs/classes/Brahma.src/M000032.html +18 -0
  194. data/trimurti-0.1/docs/classes/Brahma.src/M000033.html +20 -0
  195. data/trimurti-0.1/docs/classes/Brahma.src/M000034.html +21 -0
  196. data/trimurti-0.1/docs/classes/Brahma.src/M000035.html +25 -0
  197. data/trimurti-0.1/docs/classes/Brahma.src/M000036.html +22 -0
  198. data/trimurti-0.1/docs/classes/Brahma.src/M000037.html +22 -0
  199. data/trimurti-0.1/docs/classes/ComponentSpec.html +275 -0
  200. data/trimurti-0.1/docs/classes/ComponentSpec.src/M000001.html +21 -0
  201. data/trimurti-0.1/docs/classes/ComponentSpec.src/M000002.html +18 -0
  202. data/trimurti-0.1/docs/classes/DRb.html +165 -0
  203. data/trimurti-0.1/docs/classes/DRb.src/M000062.html +18 -0
  204. data/trimurti-0.1/docs/classes/DRb.src/M000063.html +18 -0
  205. data/trimurti-0.1/docs/classes/GUID.html +129 -0
  206. data/trimurti-0.1/docs/classes/Linda.html +444 -0
  207. data/trimurti-0.1/docs/classes/Linda.src/M000007.html +16 -0
  208. data/trimurti-0.1/docs/classes/Linda.src/M000008.html +16 -0
  209. data/trimurti-0.1/docs/classes/Linda.src/M000009.html +20 -0
  210. data/trimurti-0.1/docs/classes/Linda.src/M000010.html +16 -0
  211. data/trimurti-0.1/docs/classes/Linda.src/M000011.html +18 -0
  212. data/trimurti-0.1/docs/classes/Linda.src/M000012.html +21 -0
  213. data/trimurti-0.1/docs/classes/Linda.src/M000013.html +18 -0
  214. data/trimurti-0.1/docs/classes/Linda.src/M000014.html +18 -0
  215. data/trimurti-0.1/docs/classes/Linda.src/M000015.html +18 -0
  216. data/trimurti-0.1/docs/classes/Linda.src/M000016.html +18 -0
  217. data/trimurti-0.1/docs/classes/Linda.src/M000017.html +20 -0
  218. data/trimurti-0.1/docs/classes/Linda.src/M000018.html +20 -0
  219. data/trimurti-0.1/docs/classes/Object.html +153 -0
  220. data/trimurti-0.1/docs/classes/Object.src/M000021.html +18 -0
  221. data/trimurti-0.1/docs/classes/Plugins.html +174 -0
  222. data/trimurti-0.1/docs/classes/Plugins.src/M000024.html +32 -0
  223. data/trimurti-0.1/docs/classes/Plugins.src/M000025.html +32 -0
  224. data/trimurti-0.1/docs/classes/Plugins/Spec.html +267 -0
  225. data/trimurti-0.1/docs/classes/Plugins/Spec.src/M000026.html +22 -0
  226. data/trimurti-0.1/docs/classes/Plugins/Spec.src/M000027.html +18 -0
  227. data/trimurti-0.1/docs/classes/Plugins/Spec.src/M000028.html +20 -0
  228. data/trimurti-0.1/docs/classes/QBE_ID.html +147 -0
  229. data/trimurti-0.1/docs/classes/QBE_ID.src/M000059.html +18 -0
  230. data/trimurti-0.1/docs/classes/QueryByExample.html +270 -0
  231. data/trimurti-0.1/docs/classes/QueryByExample.src/M000054.html +17 -0
  232. data/trimurti-0.1/docs/classes/QueryByExample.src/M000055.html +17 -0
  233. data/trimurti-0.1/docs/classes/QueryByExample.src/M000056.html +17 -0
  234. data/trimurti-0.1/docs/classes/QueryByExample.src/M000057.html +17 -0
  235. data/trimurti-0.1/docs/classes/QueryByExample.src/M000058.html +17 -0
  236. data/trimurti-0.1/docs/classes/Shiva.html +159 -0
  237. data/trimurti-0.1/docs/classes/Shiva.src/M000060.html +18 -0
  238. data/trimurti-0.1/docs/classes/Shiva.src/M000061.html +19 -0
  239. data/trimurti-0.1/docs/classes/String.html +176 -0
  240. data/trimurti-0.1/docs/classes/String.src/M000022.html +16 -0
  241. data/trimurti-0.1/docs/classes/String.src/M000023.html +16 -0
  242. data/trimurti-0.1/docs/classes/Symbol.html +176 -0
  243. data/trimurti-0.1/docs/classes/Symbol.src/M000003.html +16 -0
  244. data/trimurti-0.1/docs/classes/Symbol.src/M000004.html +16 -0
  245. data/trimurti-0.1/docs/classes/Trimurti.html +189 -0
  246. data/trimurti-0.1/docs/classes/Trimurti.src/M000019.html +16 -0
  247. data/trimurti-0.1/docs/classes/Trimurti.src/M000020.html +16 -0
  248. data/trimurti-0.1/docs/classes/Vishnu.html +563 -0
  249. data/trimurti-0.1/docs/classes/Vishnu.src/M000038.html +18 -0
  250. data/trimurti-0.1/docs/classes/Vishnu.src/M000039.html +18 -0
  251. data/trimurti-0.1/docs/classes/Vishnu.src/M000040.html +18 -0
  252. data/trimurti-0.1/docs/classes/Vishnu.src/M000041.html +22 -0
  253. data/trimurti-0.1/docs/classes/Vishnu.src/M000042.html +23 -0
  254. data/trimurti-0.1/docs/classes/Vishnu.src/M000043.html +24 -0
  255. data/trimurti-0.1/docs/classes/Vishnu.src/M000044.html +24 -0
  256. data/trimurti-0.1/docs/classes/Vishnu.src/M000045.html +18 -0
  257. data/trimurti-0.1/docs/classes/Vishnu.src/M000046.html +22 -0
  258. data/trimurti-0.1/docs/classes/Vishnu.src/M000047.html +20 -0
  259. data/trimurti-0.1/docs/classes/Vishnu.src/M000048.html +18 -0
  260. data/trimurti-0.1/docs/classes/Vishnu.src/M000049.html +22 -0
  261. data/trimurti-0.1/docs/classes/Vishnu.src/M000050.html +20 -0
  262. data/trimurti-0.1/docs/classes/Vishnu.src/M000051.html +19 -0
  263. data/trimurti-0.1/docs/classes/Vishnu.src/M000052.html +30 -0
  264. data/trimurti-0.1/docs/classes/Vishnu.src/M000053.html +21 -0
  265. data/trimurti-0.1/docs/created.rid +1 -0
  266. data/trimurti-0.1/docs/dot/f_0.dot +14 -0
  267. data/trimurti-0.1/docs/dot/f_0.png +0 -0
  268. data/trimurti-0.1/docs/dot/f_1.dot +14 -0
  269. data/trimurti-0.1/docs/dot/f_1.png +0 -0
  270. data/trimurti-0.1/docs/dot/f_2.dot +14 -0
  271. data/trimurti-0.1/docs/dot/f_2.png +0 -0
  272. data/trimurti-0.1/docs/dot/f_3.dot +39 -0
  273. data/trimurti-0.1/docs/dot/f_3.png +0 -0
  274. data/trimurti-0.1/docs/dot/f_4.dot +39 -0
  275. data/trimurti-0.1/docs/dot/f_4.png +0 -0
  276. data/trimurti-0.1/docs/dot/f_5.dot +69 -0
  277. data/trimurti-0.1/docs/dot/f_5.png +0 -0
  278. data/trimurti-0.1/docs/dot/f_6.dot +149 -0
  279. data/trimurti-0.1/docs/dot/f_6.png +0 -0
  280. data/trimurti-0.1/docs/dot/m_3_0.dot +30 -0
  281. data/trimurti-0.1/docs/dot/m_3_0.png +0 -0
  282. data/trimurti-0.1/docs/dot/m_4_0.dot +39 -0
  283. data/trimurti-0.1/docs/dot/m_4_0.png +0 -0
  284. data/trimurti-0.1/docs/dot/m_5_0.dot +40 -0
  285. data/trimurti-0.1/docs/dot/m_5_0.png +0 -0
  286. data/trimurti-0.1/docs/dot/m_5_1.dot +30 -0
  287. data/trimurti-0.1/docs/dot/m_5_1.png +0 -0
  288. data/trimurti-0.1/docs/dot/m_6_0.dot +40 -0
  289. data/trimurti-0.1/docs/dot/m_6_0.png +0 -0
  290. data/trimurti-0.1/docs/dot/m_6_1.dot +30 -0
  291. data/trimurti-0.1/docs/dot/m_6_1.png +0 -0
  292. data/trimurti-0.1/docs/dot/m_6_2.dot +30 -0
  293. data/trimurti-0.1/docs/dot/m_6_2.png +0 -0
  294. data/trimurti-0.1/docs/files/License_txt.html +132 -0
  295. data/trimurti-0.1/docs/files/ReadMe_Amber_txt.html +491 -0
  296. data/trimurti-0.1/docs/files/ReadMe_txt.html +694 -0
  297. data/trimurti-0.1/docs/files/nist/trimurti/linda_rb.html +129 -0
  298. data/trimurti-0.1/docs/files/nist/trimurti/plugins_rb.html +129 -0
  299. data/trimurti-0.1/docs/files/nist/trimurti/queryByExample_rb.html +128 -0
  300. data/trimurti-0.1/docs/files/nist/trimurti/trimurti_rb.html +151 -0
  301. data/trimurti-0.1/docs/fr_class_index.html +43 -0
  302. data/trimurti-0.1/docs/fr_file_index.html +33 -0
  303. data/trimurti-0.1/docs/fr_method_index.html +89 -0
  304. data/trimurti-0.1/docs/images/overview.jpg +0 -0
  305. data/trimurti-0.1/docs/index.html +24 -0
  306. data/trimurti-0.1/docs/rdoc-style.css +208 -0
  307. data/trimurti-0.1/lib/nist/trimurti/linda.rb +163 -0
  308. data/trimurti-0.1/lib/nist/trimurti/plugins.rb +107 -0
  309. data/trimurti-0.1/lib/nist/trimurti/queryByExample.rb +81 -0
  310. data/trimurti-0.1/lib/nist/trimurti/trimurti.rb +433 -0
  311. data/trimurti-0.1/tests/test_linda.rb +111 -0
  312. data/trimurti-0.1/tests/test_trimurti.rb +247 -0
  313. metadata +467 -0
@@ -0,0 +1,107 @@
1
+ =begin rdoc
2
+ This file includes code to find plugins, load them, and
3
+ help integrate them into an application.
4
+
5
+ For an overview and an example of use, see ReadMe.txt[link:files/ReadMe_txt.html].
6
+
7
+ Author: A. Griesser
8
+ =end
9
+
10
+ require 'rbtree'
11
+
12
+ # An Array of Plugins::Spec instances.
13
+ # The use of this global is optional:
14
+ # see the documentation for file plugins.rb
15
+ # for alternatives.
16
+ $PLUGINS = Array.new
17
+
18
+ module Plugins
19
+
20
+ # Provides information an application can use to:
21
+ # * Initialize the plugin
22
+ # * Add the plugin to a menu
23
+ # * Describe the pugin in an "About..." dialog
24
+ # Intended to be passed to the application through the $PLUGINS global.
25
+ class Spec
26
+ # Identifies the plugin
27
+ attr_accessor :name
28
+ # Who wrote the plugin
29
+ attr_accessor :author
30
+ # A String describing the plugin. Can be to be nil.
31
+ attr_accessor :description
32
+ # A Hash with:
33
+ # * keys are menu labels
34
+ # * values depend on the application in which the plugin is to be embedded
35
+ attr_accessor :actions
36
+ # A proc the application can use to initialize the plugin. can be nil.
37
+ attr_accessor :init_proc
38
+ # Name and Author are required Strings. Description can be nil.
39
+ # Actions must be a Hash, but it can be empty.
40
+ def initialize(name, author, description=nil, actions=RBTree.new, init_proc=nil)
41
+ self.name=name
42
+ self.author=author
43
+ self.description=description
44
+ self.actions=actions
45
+ self.init_proc=init_proc
46
+ end
47
+ # Calls the init_proc. Any arguments provided are passed on to the init_proc.
48
+ # Plugin developers need to know what arguments the appliction will use.
49
+ def init(*args)
50
+ init_proc.call(*args) if init_proc
51
+ end
52
+ # Returns a String representation of the plugin, suitable for use in an "About..." dialog.
53
+ def to_s(str=String.new)
54
+ str << name << ' plugin written by ' << author << '.'
55
+ str << "\n" << description if description
56
+ str
57
+ end
58
+ end # Spec
59
+
60
+ # Looks in all the $LOAD_PATH search roots for files matching pluginGlob.
61
+ # PluginGlob can be a String or an Array of Strings.
62
+ # Returns a possibly empty Array of paths local to one of the search roots.
63
+ # Suffix defines extensions to remove: see File.basename
64
+ def find_on_load_path(pluginGlob, suffix='.*')
65
+ answer = []
66
+ case pluginGlob
67
+ when String
68
+ local_path = File.dirname(pluginGlob)
69
+ answer = $LOAD_PATH.collect {|root|
70
+ sought = File.join(root, pluginGlob)
71
+ globMatches = Dir.glob(sought)
72
+ globMatches.collect {|f| File.join(local_path, File.basename(f, suffix)) }
73
+ }
74
+ when Array
75
+ answer = pluginGlob.collect {|relPath| plugin_dirs(relPath) }
76
+ else
77
+ raise "Incomprehensible argument to plugins (should be String or Array, was #{pluginGlob.class.name})"
78
+ end
79
+ answer.flatten.uniq.sort
80
+ end
81
+
82
+ # Loads (via 'require') all the plugins described by pluginGlob,
83
+ # so long as the plugin is in accessable from the $LOAD_PATH.
84
+ # Returns the Array of local paths to plugins (with extensions removed).
85
+ # PluginGlob can be a String or an Array of Strings.
86
+ # Takes an optional one-argument block, which is executed
87
+ # after every load.
88
+ def require_plugins(pluginGlob, io=STDOUT)
89
+ parts = find_on_load_path(pluginGlob)
90
+ io << "\n"
91
+ if parts.empty?
92
+ io << "\nDid not find any plugins matching #{pluginGlob.inspect}"
93
+ io.flush if io.respond_to?(:flush)
94
+ return parts
95
+ end
96
+ parts.each {|part|
97
+ io << "\nRequiring plugin: '#{part}'"
98
+ io.flush if io.respond_to?(:flush)
99
+ require part
100
+ next unless block_given?
101
+ yield(self, part)
102
+ }
103
+ return parts
104
+ end
105
+
106
+
107
+ end # Plugins
@@ -0,0 +1,81 @@
1
+
2
+ # For an overview and an example of use, see ReadMe.txt[link:files/ReadMe_txt.html].
3
+ #
4
+ # Author: A. Griesser
5
+
6
+ require 'nist/common/rubyToolsDay'
7
+ require 'nist/common/guid'
8
+
9
+ # This module lets you find objects with specified attributes. To perform a query:
10
+ # 1. Instantate an 'example' object of the class you are looking for
11
+ # 2. Set (to the query values) whatever attributes you are querying on.
12
+ # 3. Call query, passing the example as the argument.
13
+ # If you only want a single result, you can instad call retrieve instead.
14
+ #
15
+ # UNDER CONSTRUCTION.
16
+ #
17
+ # Room for improvement:
18
+ # * Queries are not aware of the inheritance hierarchy.
19
+ # * Performance not tested: may not scale well (depends on Rinda implementation).
20
+ # * None of these methods are thread safe.
21
+ module QueryByExample
22
+ include Vishnu
23
+
24
+
25
+ # attribute_values(shouldSort=false, answer=Array.new, ignoredVars=nil, onlyVars=nil)
26
+
27
+ # Creates and stores into the repository a record corresponding to the argument
28
+ def create(thing)
29
+ end
30
+
31
+ # Returns an Array of repository records that match 'thing'.
32
+ # (empty if not matches). If deRef is true, instead returns the
33
+ # array of objects described by the records.
34
+ def retrieve(thing, deRef=true)
35
+ end
36
+
37
+ # Returns the registered object with the specified qbeID
38
+ # (nil if there is no such object).
39
+ def find(qbeID)
40
+ end
41
+
42
+ # Update the repository record corresponding to the argument.
43
+ # Returns a Boolean, true if successful. If there is no
44
+ # corresponding record, returns the result of evaluating
45
+ # an optional block. The optional block may add the argument
46
+ # to the repository, may raise an exception, or just return
47
+ # something. If the optional block is not present, returns false.
48
+ def update(thing)
49
+ end
50
+
51
+ # Remove from the repository the record corresponding to 'thing'
52
+ # Returns the record. If deRef is true, instead returns the object
53
+ # described by the record. Silently returns nil if there is no record
54
+ # corresponding to 'thing'.
55
+ def delete(thing, deRef=true)
56
+ end
57
+
58
+ end # QueryByExample
59
+
60
+
61
+ class Object
62
+ # Literals resolve to themselves. All objects are literals,
63
+ # unless they are instances of the class used to represent ids.
64
+ # The ID classes should override this method by including QBE_ID.
65
+ def resolve_within(container)
66
+ self
67
+ end
68
+ end
69
+
70
+ # Mix this into classes that can act like ids.
71
+ module QBE_ID
72
+ # Since this is an id rather than a literal,
73
+ # look up (in the container) the thing to which this correspondes.
74
+ def resolve_within(container)
75
+ container.find(self)
76
+ end
77
+ end
78
+
79
+ class GUID
80
+ include QBE_ID
81
+ end # GIUD
@@ -0,0 +1,433 @@
1
+
2
+ # For an overview and an example of use, see ReadMe.txt[link:files/ReadMe_txt.html].
3
+ #
4
+ # Author: A. Griesser
5
+
6
+ require 'nist/common/log'
7
+ require 'nist/trimurti/plugins'
8
+ require 'nist/trimurti/linda'
9
+ require 'yaml'
10
+ require 'test/unit/assertions'
11
+
12
+
13
+ class Asserter
14
+ include Test::Unit::Assertions
15
+ end
16
+ ASSERTER = Asserter.new
17
+
18
+ class Symbol
19
+ # Receiver specifies API
20
+ def to_service_spec; [nil, nil, self]; end
21
+ # Receiver specifies name
22
+ def to_component_spec; [self.to_s, nil]; end
23
+ end
24
+
25
+ class String
26
+ # Receiver specifies name
27
+ def to_service_spec; [self, nil, nil]; end
28
+ # Receiver specifies name
29
+ def to_component_spec; [self, nil]; end
30
+ end
31
+
32
+ class Array
33
+ # Must be [name, host, symbol]
34
+ def to_service_spec
35
+ ASSERTER.assert_equal(3, size, 'Service spec must be in form: [name, host, symbol] (see Brahma#service)')
36
+ self
37
+ end
38
+ # Must be [name, host]
39
+ def to_component_spec
40
+ ASSERTER.assert_equal(2, size, 'Component spec must be in form: [name, host] (see Brahma#component)')
41
+ self
42
+ end
43
+ end
44
+
45
+
46
+ # ######################################################################
47
+
48
+ # Vishnu preserves registries of components and services.
49
+ module Vishnu
50
+
51
+ attr_accessor :linda
52
+
53
+ def initialize(is_local=true)
54
+ self.linda = Linda.new(is_local)
55
+ end
56
+
57
+ # Returns a String, the name of the computer the method executes on.
58
+ def gethostname
59
+ linda.gethostname
60
+ end
61
+
62
+ # Register 'thing' of specified type under specified name
63
+ def register(type, name, thing, *more)
64
+ linda.put(type, name, thing, *more)
65
+ end
66
+
67
+ # Register a component. 'provides' is an Array of Symbols specifying service APIs provided.
68
+ # Needs is a Hash with:
69
+ # * Key is a Symbol, the setter for a service the componnent requires
70
+ # * Value responds to to_service_spec (it specifies some other component)
71
+ # Component definition Tuples look like this:
72
+ # [:component, name, component, hostname, provides, needs, life_cycle]
73
+ def register_component(name, component, provides, needs={}, life_cycle={})
74
+ ASSERTER.assert_kind_of(Array, provides, "The 'provides' argument to Linda#register_component must be an Array")
75
+ ASSERTER.assert_kind_of(Hash, needs, "The 'needs' argument to Linda#register_component must be a Hash")
76
+ ASSERTER.assert_kind_of(Hash, life_cycle, "The 'life_cycle' argument to Linda#register_component must be a Hash")
77
+ component = _create(life_cycle) unless component
78
+ register(:component, name, component, gethostname, provides, needs, life_cycle)
79
+ end
80
+
81
+ # Register a service provider.
82
+ # Provides is an Array of Symbols, each naming a service offered by the provider.
83
+ # Service tuples look like this:
84
+ # [:service, name, provider, hostname, symbol]
85
+ def register_service(name, provider, provides)
86
+ provides.each {|symbol|
87
+ # For alternative implementation, see task :rinda_register_simplified in Ambrose
88
+ # This is not compatable: tuple fields are different.
89
+ register(:service, name, provider, gethostname, symbol)
90
+ }
91
+ # Ok to terminate (server state has been updated)
92
+ end
93
+
94
+ # Appends registered components to the argument, which can be a String or IO.
95
+ # Returns the argument.
96
+ def show_components(io=STDOUT)
97
+ tuples = component_tuples
98
+ return io << "\nNo components are registered. " unless tuples
99
+ io << "\nAll registered components (Name, host, provides, needs, life_cycle):"
100
+ tuples.each {|tuple|
101
+ io << "\n\t#{tuple[1].inspect}\t#{tuple[3].inspect}\t#{tuple[4].inspect}\t#{tuple[5].inspect}\t#{tuple[6].inspect}"
102
+ }
103
+ io << "\n"
104
+ end
105
+
106
+ # Appends registered services to the argument, which can be a String or IO.
107
+ # Returns the argument.
108
+ def show_services(io=STDOUT)
109
+ tuples = service_tuples
110
+ return io << "\nNo services are registered. " unless tuples
111
+ io << "\nAll registered services (name, host, provides):"
112
+ tuples.each {|tuple|
113
+ io << "\n\t#{tuple[1].inspect}\t#{tuple[3].inspect}\t#{tuple[4].inspect}"
114
+ }
115
+ io << "\n"
116
+ end
117
+
118
+ # Finds Tuples describing components.
119
+ # Arguments can be:
120
+ # * nil if you don't care what the value should be
121
+ # * A Regexp if you want to select a matching pattern.
122
+ # This returns a (possibly empty) Array of matching Tuples
123
+ def component_tuples(name=nil, host=nil)
124
+ linda.rd_all(:component, name, nil, host, nil, nil, nil)
125
+ end
126
+
127
+ # Find a Tuple describing a component.
128
+ # arguments can be:
129
+ # * nil if you don't care what the value is
130
+ # * A Regexp if you want to select a matching pattern.
131
+ # This returns:
132
+ # * a Tuple describing a matching component (the local host is prefered)
133
+ # * nil if there is no matching tuple
134
+ def component_tuple(name=nil, host=nil, symbol=nil)
135
+ h = host || gethostname
136
+ tuples = component_tuples(name, h)
137
+ tuples = component_tuples(name, nil) if tuples.empty? && !host
138
+ return nil unless tuples
139
+ tuples[0]
140
+ end
141
+
142
+ # Find a specific component.
143
+ # arguments can be:
144
+ # * nil if you don't care what the value is
145
+ # * A Regexp if you want to select a matching pattern.
146
+ # This returns:
147
+ # * a component with a matching Tuple (the local host is prefered)
148
+ # * nil if there is no matching tuple
149
+ def component(name=nil, host=nil)
150
+ tuple = component_tuple(name, host)
151
+ return nil unless tuple
152
+ tuple[2]
153
+ end
154
+
155
+ # Finds Tuples describing services.
156
+ # Arguments can be:
157
+ # * nil if you don't care what the value should be
158
+ # * A Regexp if you want to select a matching pattern.
159
+ # This returns a (possibly empty) Array of matching Tuples
160
+ def service_tuples(name=nil, host=nil, symbol=nil )
161
+ linda.rd_all(:service, name, nil, host, symbol)
162
+ end
163
+
164
+ # Find a Tuple describing a service.
165
+ # arguments can be:
166
+ # * nil if you don't care what the value is
167
+ # * A Regexp if you want to select a matching pattern.
168
+ # This returns:
169
+ # * a Tuple describing a matching provider (the local host is prefered)
170
+ # * nil if there is no matching tuple
171
+ def service_tuple(name=nil, host=nil, symbol=nil)
172
+ h = host || gethostname
173
+ tuples = service_tuples(name, h, symbol )
174
+ tuples = service_tuples(name, nil, symbol ) if tuples.empty? && !host
175
+ return nil unless tuples
176
+ tuples[0]
177
+ end
178
+
179
+ # Find a specific service.
180
+ # arguments can be:
181
+ # * nil if you don't care what the value is
182
+ # * A Regexp if you want to select a matching pattern.
183
+ # This returns:
184
+ # * a provider with a matching Tuple (the local host is prefered)
185
+ # * nil if there is no matching tuple
186
+ # Usually only the symbol is necessary: the other arguments are
187
+ # present for consistency with other methods (and those rare
188
+ # times when you really do need to specify them).
189
+ def service(name=nil, host=nil, symbol=nil)
190
+ tuple = service_tuple(name, host, symbol)
191
+ return nil unless tuple
192
+ tuple[2]
193
+ end
194
+
195
+
196
+ # Execute the code String (which may contain a 'component' local),
197
+ # returning the result of this evaluation. Returns nil if the
198
+ # code string is nil.
199
+ def apply(code, component)
200
+ return nil unless code
201
+ eval(code)
202
+ end
203
+
204
+ # For each component, apply the life_cycle[selector] code.
205
+ def life_cycle(selector)
206
+ tuples = component_tuples
207
+ problems = Array.new
208
+ tuples.each {|tuple|
209
+ component = tuple[2]
210
+ life_cyc = tuple[6]
211
+ begin
212
+ apply(life_cyc[selector], component)
213
+ rescue
214
+ problems << $!
215
+ end
216
+ }
217
+ return if problems.empty?
218
+ raise "Problems connecting components: #{problems.join(', ')}"
219
+ end
220
+
221
+
222
+ # Gets the :create code from the life_cycle_hash, and executes it.
223
+ # Fails if unable to create component.
224
+ def _create(life_cycle_hash)
225
+ fail 'Can not create component: no life_cycle Hash' unless life_cycle_hash
226
+ instantiation_code = life_cycle_hash[:create]
227
+ fail 'Can not create component: life_cycle Hash is missing :create.' unless instantiation_code
228
+ apply(instantiation_code, nil)
229
+ end
230
+
231
+ end # Vishnu
232
+
233
+ # ######################################################################
234
+
235
+ # Brahma creates applications from components and services.
236
+ module Brahma
237
+ include Vishnu
238
+
239
+ # Register the services of specified component.
240
+ # Each service shares the name of its component.
241
+ def register_component_services(componentTuple)
242
+ name = componentTuple[1]
243
+ component = componentTuple[2]
244
+ provided = componentTuple[4]
245
+ register_service(name, component, provided)
246
+ end
247
+
248
+ # Register the services of every previously registered component
249
+ def register_services
250
+ component_tuples.each {|tuple|
251
+ register_component_services(tuple)
252
+ }
253
+ end
254
+
255
+ # For each component, get the services it needs, and set them.
256
+ def connect_services
257
+ tuples = component_tuples
258
+ problems = Array.new
259
+ tuples.each {|tuple|
260
+ name = tuple[1]
261
+ component = tuple[2]
262
+ needs = tuple[5]
263
+ needs.each {|setter, svc_api|
264
+ provider = service(*svc_api.to_service_spec)
265
+ unless provider
266
+ problems << "Component <#{name}> needs, but couldn't find, service #{svc_api.inspect}"
267
+ next
268
+ end
269
+ err = _connect(component, name, setter, provider)
270
+ problems << err if err
271
+ }
272
+ }
273
+ return if problems.empty?
274
+ joint = "\n"
275
+ fail "Problem(s) (#{problems.size.to_s}) connecting components: \n#{problems.join(joint)}"
276
+ end
277
+
278
+ # For each component, evaluate the life_cycle[:start] code.
279
+ def start_components
280
+ life_cycle(:start)
281
+ end
282
+
283
+ # Assembles the application from registered components by:
284
+ # * Registering all the services provided by the components
285
+ # * Connecting service consumers to service providers.
286
+ # * Starting the components
287
+ def assemble
288
+ register_services
289
+ connect_services
290
+ start_components
291
+ end
292
+
293
+ # Returns nil if successful, an error String if a problem occured.
294
+ def _connect(component, name, setter, provider)
295
+ component.send(setter, provider )
296
+ return nil
297
+ rescue
298
+ return "Error providing service to <#{name}> using <#{setter}>: #{$!}"
299
+ end
300
+
301
+ # Registers components described in a YAML file.
302
+ # Does not register the services contained in the components, and
303
+ # does not hook together the service providers and consumers.
304
+ # Source can be
305
+ # * A String naming a file containing a YAML serialization (if isFilename=true)
306
+ # * A String containing a YAML serialization (if isFilename=false)
307
+ # * An IO streaming over a YAML serialization (if isFilename=false)
308
+ # In any case, the YAML serialization must contain an Array of ComponentSpec instances.
309
+ def from_yaml(source, isFilename=true)
310
+ source = File.open(source) if isFilename
311
+ specs = YAML.load(source)
312
+ errors = specs.collect {|spec| create_registered_component(spec) }
313
+ errors.flatten!
314
+ errors.compact!
315
+ return if errors.empty?
316
+ sep = "\n"
317
+ raise "Error(s) creating or registering components: #{errors.join(sep)}"
318
+ end
319
+
320
+
321
+
322
+ # Creates component:
323
+ # * Uses 'require' to load any necessary source
324
+ # * Executes life_cycle[:create] code
325
+ # * Sets compSpec.component
326
+ def create_component(componentSpec)
327
+ componentSpec.require_source
328
+ answer = _create(componentSpec.life_cycle)
329
+ raise "Attempt to instantiate component resulted in nil: #{componentSpec.inspect}" unless answer
330
+ componentSpec.component= answer
331
+ answer
332
+ end
333
+
334
+ # Creates and registers component:
335
+ # * Uses 'require' to load any necessary source
336
+ # * Executes life_cycle[:create] code
337
+ # * Sets compSpec.component
338
+ # * Registers the component
339
+ # Returns nil or an error String.
340
+ def create_registered_component(compSpec)
341
+ create_component(compSpec)
342
+ register_component(compSpec.name, compSpec.component, compSpec.provides, compSpec.needs, compSpec.life_cycle )
343
+ return nil
344
+ rescue
345
+ return "Error creating component #{compSpec.inspect}: #{$!}"
346
+ end
347
+
348
+ end # Brahma
349
+
350
+ # ######################################################################
351
+
352
+ # Shiva shuts down and destroys (in an orderly fashion) applications
353
+ # built from components and services.
354
+ module Shiva
355
+
356
+ def stop_components
357
+ life_cycle(:stop)
358
+ end
359
+
360
+ def destroy_components(stop=true)
361
+ stop_components if stop
362
+ life_cycle(:destroy)
363
+ end
364
+
365
+ end # Shiva
366
+
367
+ # ######################################################################
368
+
369
+ # A class that provides all the functionality of Vishnu, Brahma, and Shiva,
370
+ # for use when mixins are not required. The behaviors are available on both instance
371
+ # side, and the class side (through a lazy-initialized default_instance).
372
+ class Trimurti
373
+ include Plugins
374
+ include Brahma
375
+ include Shiva
376
+
377
+ @@default_instance=nil
378
+ def self.default_instance; @@default_instance || @@default_instance=self.new; end
379
+ def self.default_instance=(inst); @@default_instance=inst; end
380
+
381
+ forward_reflect_except(:default_instance, Trimurti)
382
+
383
+ end # Trimurti
384
+
385
+ # ######################################################################
386
+
387
+
388
+ # Describes a Component that can be managed by Vishnu/Brahma.
389
+ # Can be unmarshalled by Yaml to register a Component.
390
+ class ComponentSpec
391
+
392
+ # A String identifying the instance
393
+ attr_accessor :name
394
+
395
+ # Not marshalled
396
+ attr_accessor :component
397
+
398
+ # An Array of file names that are loaded by 'require' before instantiation
399
+ attr_accessor :required_source
400
+
401
+ # A Hash that specifies how to manage the component's life cycle. Only the
402
+ # :create key is required.
403
+ # * Keys are Symbols that specify life cycle events. The following keys are valid:
404
+ # * :create - Instantiate the component
405
+ # * :start - Activate all services
406
+ # * :stop - Turn off all services
407
+ # * :destroy - Discard references to other components
408
+ # * Values are Strings that specify behaviors that is to occur at life cyle events.
409
+ attr_accessor :life_cycle
410
+
411
+ # An Array of Symbols, each naming a collection of methods provided by the instance
412
+ attr_accessor :provides
413
+
414
+ # A Hash that describes how to provided necessary services to the instance:
415
+ # * Key is a name of a method (on the component) that takes one argument (the service provider)
416
+ # * Value is either:
417
+ # * a Symbol that identifies the required API
418
+ # * an Array containing the 3 arguments to Brahman#service
419
+ attr_accessor :needs
420
+
421
+ # Load (via 'require') all the source code needed by the component.
422
+ def require_source
423
+ required_source.each {|src|
424
+ print "\nComponentSpec #{name} is requiring #{src} "; STDOUT.flush
425
+ require src
426
+ }
427
+ end
428
+
429
+ def to_yaml_properties
430
+ ['@name', '@required_source', '@provides', '@needs', '@life_cycle']
431
+ end
432
+
433
+ end # ComponentSpec