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.
- data/genie-0.1.gem +0 -0
- data/genie-0.1/docs/classes/BasicCommand.html +249 -0
- data/genie-0.1/docs/classes/BasicCommand.src/M000070.html +18 -0
- data/genie-0.1/docs/classes/BasicCommand.src/M000071.html +18 -0
- data/genie-0.1/docs/classes/BasicCommand.src/M000072.html +18 -0
- data/genie-0.1/docs/classes/BasicCommand.src/M000073.html +18 -0
- data/genie-0.1/docs/classes/BasicCommand.src/M000074.html +16 -0
- data/genie-0.1/docs/classes/Command.html +277 -0
- data/genie-0.1/docs/classes/Command.src/M000052.html +20 -0
- data/genie-0.1/docs/classes/Command.src/M000053.html +18 -0
- data/genie-0.1/docs/classes/Command.src/M000054.html +20 -0
- data/genie-0.1/docs/classes/Command.src/M000055.html +20 -0
- data/genie-0.1/docs/classes/Command.src/M000056.html +18 -0
- data/genie-0.1/docs/classes/Command.src/M000057.html +18 -0
- data/genie-0.1/docs/classes/Command.src/M000058.html +23 -0
- data/genie-0.1/docs/classes/CommandMetainfo.html +362 -0
- data/genie-0.1/docs/classes/CommandMetainfo.src/M000042.html +18 -0
- data/genie-0.1/docs/classes/CommandMetainfo.src/M000043.html +18 -0
- data/genie-0.1/docs/classes/CommandMetainfo.src/M000044.html +19 -0
- data/genie-0.1/docs/classes/CommandMetainfo.src/M000045.html +25 -0
- data/genie-0.1/docs/classes/CommandMetainfo.src/M000046.html +21 -0
- data/genie-0.1/docs/classes/CommandMetainfo.src/M000047.html +21 -0
- data/genie-0.1/docs/classes/CompoundResult.html +359 -0
- data/genie-0.1/docs/classes/CompoundResult.src/M000075.html +18 -0
- data/genie-0.1/docs/classes/CompoundResult.src/M000076.html +18 -0
- data/genie-0.1/docs/classes/CompoundResult.src/M000078.html +18 -0
- data/genie-0.1/docs/classes/CompoundResult.src/M000079.html +18 -0
- data/genie-0.1/docs/classes/CompoundResult.src/M000080.html +18 -0
- data/genie-0.1/docs/classes/CompoundResult.src/M000082.html +18 -0
- data/genie-0.1/docs/classes/CompoundResult.src/M000084.html +20 -0
- data/genie-0.1/docs/classes/CompoundResult.src/M000085.html +18 -0
- data/genie-0.1/docs/classes/CompoundResult.src/M000086.html +18 -0
- data/genie-0.1/docs/classes/CompoundResult.src/M000087.html +20 -0
- data/genie-0.1/docs/classes/EntryProcessor.html +223 -0
- data/genie-0.1/docs/classes/EntryProcessor.src/M000008.html +18 -0
- data/genie-0.1/docs/classes/EntryProcessor.src/M000009.html +20 -0
- data/genie-0.1/docs/classes/EntryProcessor.src/M000010.html +18 -0
- data/genie-0.1/docs/classes/EntryProcessor.src/M000011.html +23 -0
- data/genie-0.1/docs/classes/Log4r.html +114 -0
- data/genie-0.1/docs/classes/Log4r/LogEvent.html +153 -0
- data/genie-0.1/docs/classes/Log4r/LogEvent.src/M000123.html +16 -0
- data/genie-0.1/docs/classes/NotifiedProcessor.html +155 -0
- data/genie-0.1/docs/classes/NotifiedProcessor.src/M000094.html +22 -0
- data/genie-0.1/docs/classes/NullTransactionController.html +191 -0
- data/genie-0.1/docs/classes/NullTransactionController.src/M000030.html +16 -0
- data/genie-0.1/docs/classes/NullTransactionController.src/M000031.html +16 -0
- data/genie-0.1/docs/classes/Object.html +154 -0
- data/genie-0.1/docs/classes/Object.src/M000103.html +16 -0
- data/genie-0.1/docs/classes/Periodic.html +564 -0
- data/genie-0.1/docs/classes/Periodic.src/M000124.html +26 -0
- data/genie-0.1/docs/classes/Periodic.src/M000125.html +21 -0
- data/genie-0.1/docs/classes/Periodic.src/M000126.html +18 -0
- data/genie-0.1/docs/classes/Periodic.src/M000127.html +18 -0
- data/genie-0.1/docs/classes/Periodic.src/M000128.html +31 -0
- data/genie-0.1/docs/classes/Periodic.src/M000129.html +30 -0
- data/genie-0.1/docs/classes/Periodic.src/M000130.html +18 -0
- data/genie-0.1/docs/classes/Periodic.src/M000131.html +18 -0
- data/genie-0.1/docs/classes/Periodic.src/M000132.html +16 -0
- data/genie-0.1/docs/classes/PollingProcessor.html +303 -0
- data/genie-0.1/docs/classes/PollingProcessor.src/M000088.html +23 -0
- data/genie-0.1/docs/classes/PollingProcessor.src/M000089.html +19 -0
- data/genie-0.1/docs/classes/PollingProcessor.src/M000091.html +22 -0
- data/genie-0.1/docs/classes/PollingProcessor.src/M000092.html +18 -0
- data/genie-0.1/docs/classes/PollingProcessor.src/M000093.html +18 -0
- data/genie-0.1/docs/classes/Queue.html +562 -0
- data/genie-0.1/docs/classes/Queue.src/M000104.html +22 -0
- data/genie-0.1/docs/classes/Queue.src/M000105.html +18 -0
- data/genie-0.1/docs/classes/Queue.src/M000106.html +18 -0
- data/genie-0.1/docs/classes/Queue.src/M000107.html +18 -0
- data/genie-0.1/docs/classes/Queue.src/M000108.html +21 -0
- data/genie-0.1/docs/classes/Queue.src/M000109.html +21 -0
- data/genie-0.1/docs/classes/Queue.src/M000110.html +22 -0
- data/genie-0.1/docs/classes/Queue.src/M000111.html +16 -0
- data/genie-0.1/docs/classes/Queue.src/M000112.html +18 -0
- data/genie-0.1/docs/classes/Queue.src/M000113.html +19 -0
- data/genie-0.1/docs/classes/Queue.src/M000114.html +23 -0
- data/genie-0.1/docs/classes/Queue.src/M000115.html +21 -0
- data/genie-0.1/docs/classes/Queue.src/M000116.html +19 -0
- data/genie-0.1/docs/classes/Queue.src/M000117.html +20 -0
- data/genie-0.1/docs/classes/Queue.src/M000118.html +25 -0
- data/genie-0.1/docs/classes/Queue.src/M000119.html +18 -0
- data/genie-0.1/docs/classes/Queue.src/M000120.html +22 -0
- data/genie-0.1/docs/classes/Queue.src/M000121.html +22 -0
- data/genie-0.1/docs/classes/Queue.src/M000122.html +20 -0
- data/genie-0.1/docs/classes/QueueDispatcher.html +247 -0
- data/genie-0.1/docs/classes/QueueDispatcher.src/M000048.html +18 -0
- data/genie-0.1/docs/classes/QueueDispatcher.src/M000049.html +21 -0
- data/genie-0.1/docs/classes/QueueDispatcher.src/M000050.html +18 -0
- data/genie-0.1/docs/classes/QueueDispatcher.src/M000051.html +32 -0
- data/genie-0.1/docs/classes/QueueEntry.html +522 -0
- data/genie-0.1/docs/classes/QueueEntry.src/M000012.html +21 -0
- data/genie-0.1/docs/classes/QueueEntry.src/M000013.html +18 -0
- data/genie-0.1/docs/classes/QueueEntry.src/M000014.html +18 -0
- data/genie-0.1/docs/classes/QueueEntry.src/M000015.html +18 -0
- data/genie-0.1/docs/classes/QueueEntry.src/M000017.html +16 -0
- data/genie-0.1/docs/classes/QueueEntry.src/M000018.html +19 -0
- data/genie-0.1/docs/classes/QueueEntry.src/M000020.html +19 -0
- data/genie-0.1/docs/classes/QueueEntry.src/M000022.html +19 -0
- data/genie-0.1/docs/classes/QueueEntry.src/M000023.html +21 -0
- data/genie-0.1/docs/classes/QueueEntry.src/M000024.html +19 -0
- data/genie-0.1/docs/classes/QueueEntry.src/M000025.html +18 -0
- data/genie-0.1/docs/classes/QueueEntry.src/M000026.html +18 -0
- data/genie-0.1/docs/classes/QueueEntry.src/M000028.html +18 -0
- data/genie-0.1/docs/classes/Result.html +289 -0
- data/genie-0.1/docs/classes/Result.src/M000063.html +20 -0
- data/genie-0.1/docs/classes/Result.src/M000064.html +18 -0
- data/genie-0.1/docs/classes/Result.src/M000066.html +18 -0
- data/genie-0.1/docs/classes/Result.src/M000068.html +18 -0
- data/genie-0.1/docs/classes/Result.src/M000069.html +19 -0
- data/genie-0.1/docs/classes/SemanticCommand.html +229 -0
- data/genie-0.1/docs/classes/SemanticCommand.src/M000059.html +19 -0
- data/genie-0.1/docs/classes/SemanticCommand.src/M000060.html +18 -0
- data/genie-0.1/docs/classes/SemanticCommand.src/M000061.html +18 -0
- data/genie-0.1/docs/classes/TransactionBundle.html +260 -0
- data/genie-0.1/docs/classes/TransactionBundle.src/M000001.html +18 -0
- data/genie-0.1/docs/classes/TransactionBundle.src/M000002.html +20 -0
- data/genie-0.1/docs/classes/TransactionBundle.src/M000003.html +20 -0
- data/genie-0.1/docs/classes/TransactionBundle.src/M000004.html +18 -0
- data/genie-0.1/docs/classes/TransactionBundle.src/M000005.html +18 -0
- data/genie-0.1/docs/classes/TransactionBundle.src/M000007.html +19 -0
- data/genie-0.1/docs/classes/UndoRedoCommand.html +308 -0
- data/genie-0.1/docs/classes/UndoRedoCommand.src/M000095.html +19 -0
- data/genie-0.1/docs/classes/UndoRedoCommand.src/M000096.html +16 -0
- data/genie-0.1/docs/classes/UndoRedoCommand.src/M000097.html +16 -0
- data/genie-0.1/docs/classes/UndoRedoCommand.src/M000098.html +16 -0
- data/genie-0.1/docs/classes/UndoRedoCommand.src/M000099.html +18 -0
- data/genie-0.1/docs/classes/UndoRedoCommand.src/M000101.html +18 -0
- data/genie-0.1/docs/classes/UndoRedoCommand.src/M000102.html +18 -0
- data/genie-0.1/docs/classes/UnitOfWork.html +322 -0
- data/genie-0.1/docs/classes/UnitOfWork.src/M000032.html +19 -0
- data/genie-0.1/docs/classes/UnitOfWork.src/M000033.html +18 -0
- data/genie-0.1/docs/classes/UnitOfWork.src/M000034.html +18 -0
- data/genie-0.1/docs/classes/UnitOfWork.src/M000035.html +18 -0
- data/genie-0.1/docs/classes/UnitOfWork.src/M000036.html +18 -0
- data/genie-0.1/docs/classes/UnitOfWork.src/M000037.html +18 -0
- data/genie-0.1/docs/classes/UnitOfWork.src/M000038.html +18 -0
- data/genie-0.1/docs/classes/UnitOfWork.src/M000039.html +18 -0
- data/genie-0.1/docs/classes/UnitOfWork.src/M000040.html +18 -0
- data/genie-0.1/docs/created.rid +1 -0
- data/genie-0.1/docs/dot/f_0.dot +14 -0
- data/genie-0.1/docs/dot/f_0.png +0 -0
- data/genie-0.1/docs/dot/f_1.dot +14 -0
- data/genie-0.1/docs/dot/f_1.png +0 -0
- data/genie-0.1/docs/dot/f_2.dot +14 -0
- data/genie-0.1/docs/dot/f_2.png +0 -0
- data/genie-0.1/docs/dot/f_3.dot +84 -0
- data/genie-0.1/docs/dot/f_3.png +0 -0
- data/genie-0.1/docs/dot/f_4.dot +14 -0
- data/genie-0.1/docs/dot/f_4.png +0 -0
- data/genie-0.1/docs/dot/f_5.dot +78 -0
- data/genie-0.1/docs/dot/f_5.png +0 -0
- data/genie-0.1/docs/dot/f_6.dot +50 -0
- data/genie-0.1/docs/dot/f_6.png +0 -0
- data/genie-0.1/docs/dot/f_7.dot +57 -0
- data/genie-0.1/docs/dot/f_7.png +0 -0
- data/genie-0.1/docs/dot/m_5_0.dot +30 -0
- data/genie-0.1/docs/dot/m_5_0.png +0 -0
- data/genie-0.1/docs/dot/m_7_0.dot +39 -0
- data/genie-0.1/docs/dot/m_7_0.png +0 -0
- data/genie-0.1/docs/files/License_txt.html +161 -0
- data/genie-0.1/docs/files/ReadMe_Amber_txt.html +491 -0
- data/genie-0.1/docs/files/ReadMe_txt.html +444 -0
- data/genie-0.1/docs/files/nist/genie/commands_rb.html +121 -0
- data/genie-0.1/docs/files/nist/genie/genie_rb.html +116 -0
- data/genie-0.1/docs/files/nist/genie/processors_rb.html +111 -0
- data/genie-0.1/docs/files/nist/genie/queues_rb.html +118 -0
- data/genie-0.1/docs/files/nist/genie/results_rb.html +117 -0
- data/genie-0.1/docs/fr_class_index.html +46 -0
- data/genie-0.1/docs/fr_file_index.html +34 -0
- data/genie-0.1/docs/fr_method_index.html +160 -0
- data/genie-0.1/docs/images/overview.jpg +0 -0
- data/genie-0.1/docs/index.html +24 -0
- data/genie-0.1/docs/rdoc-style.css +208 -0
- data/genie-0.1/lib/nist/genie/commands.rb +413 -0
- data/genie-0.1/lib/nist/genie/genie.rb +4 -0
- data/genie-0.1/lib/nist/genie/processors.rb +382 -0
- data/genie-0.1/lib/nist/genie/queues.rb +435 -0
- data/genie-0.1/lib/nist/genie/results.rb +113 -0
- data/genie-0.1/tests/helpers.rb +45 -0
- data/genie-0.1/tests/test_commands.rb +338 -0
- data/genie-0.1/tests/test_processors.rb +17 -0
- data/genie-0.1/tests/test_queues.rb +288 -0
- data/genie-0.1/tests/test_results.rb +37 -0
- data/trimurti-0.1.gem +0 -0
- data/trimurti-0.1/docs/classes/Array.html +176 -0
- data/trimurti-0.1/docs/classes/Array.src/M000005.html +19 -0
- data/trimurti-0.1/docs/classes/Array.src/M000006.html +19 -0
- data/trimurti-0.1/docs/classes/Asserter.html +136 -0
- data/trimurti-0.1/docs/classes/Brahma.html +360 -0
- data/trimurti-0.1/docs/classes/Brahma.src/M000029.html +21 -0
- data/trimurti-0.1/docs/classes/Brahma.src/M000030.html +20 -0
- data/trimurti-0.1/docs/classes/Brahma.src/M000031.html +36 -0
- data/trimurti-0.1/docs/classes/Brahma.src/M000032.html +18 -0
- data/trimurti-0.1/docs/classes/Brahma.src/M000033.html +20 -0
- data/trimurti-0.1/docs/classes/Brahma.src/M000034.html +21 -0
- data/trimurti-0.1/docs/classes/Brahma.src/M000035.html +25 -0
- data/trimurti-0.1/docs/classes/Brahma.src/M000036.html +22 -0
- data/trimurti-0.1/docs/classes/Brahma.src/M000037.html +22 -0
- data/trimurti-0.1/docs/classes/ComponentSpec.html +275 -0
- data/trimurti-0.1/docs/classes/ComponentSpec.src/M000001.html +21 -0
- data/trimurti-0.1/docs/classes/ComponentSpec.src/M000002.html +18 -0
- data/trimurti-0.1/docs/classes/DRb.html +165 -0
- data/trimurti-0.1/docs/classes/DRb.src/M000062.html +18 -0
- data/trimurti-0.1/docs/classes/DRb.src/M000063.html +18 -0
- data/trimurti-0.1/docs/classes/GUID.html +129 -0
- data/trimurti-0.1/docs/classes/Linda.html +444 -0
- data/trimurti-0.1/docs/classes/Linda.src/M000007.html +16 -0
- data/trimurti-0.1/docs/classes/Linda.src/M000008.html +16 -0
- data/trimurti-0.1/docs/classes/Linda.src/M000009.html +20 -0
- data/trimurti-0.1/docs/classes/Linda.src/M000010.html +16 -0
- data/trimurti-0.1/docs/classes/Linda.src/M000011.html +18 -0
- data/trimurti-0.1/docs/classes/Linda.src/M000012.html +21 -0
- data/trimurti-0.1/docs/classes/Linda.src/M000013.html +18 -0
- data/trimurti-0.1/docs/classes/Linda.src/M000014.html +18 -0
- data/trimurti-0.1/docs/classes/Linda.src/M000015.html +18 -0
- data/trimurti-0.1/docs/classes/Linda.src/M000016.html +18 -0
- data/trimurti-0.1/docs/classes/Linda.src/M000017.html +20 -0
- data/trimurti-0.1/docs/classes/Linda.src/M000018.html +20 -0
- data/trimurti-0.1/docs/classes/Object.html +153 -0
- data/trimurti-0.1/docs/classes/Object.src/M000021.html +18 -0
- data/trimurti-0.1/docs/classes/Plugins.html +174 -0
- data/trimurti-0.1/docs/classes/Plugins.src/M000024.html +32 -0
- data/trimurti-0.1/docs/classes/Plugins.src/M000025.html +32 -0
- data/trimurti-0.1/docs/classes/Plugins/Spec.html +267 -0
- data/trimurti-0.1/docs/classes/Plugins/Spec.src/M000026.html +22 -0
- data/trimurti-0.1/docs/classes/Plugins/Spec.src/M000027.html +18 -0
- data/trimurti-0.1/docs/classes/Plugins/Spec.src/M000028.html +20 -0
- data/trimurti-0.1/docs/classes/QBE_ID.html +147 -0
- data/trimurti-0.1/docs/classes/QBE_ID.src/M000059.html +18 -0
- data/trimurti-0.1/docs/classes/QueryByExample.html +270 -0
- data/trimurti-0.1/docs/classes/QueryByExample.src/M000054.html +17 -0
- data/trimurti-0.1/docs/classes/QueryByExample.src/M000055.html +17 -0
- data/trimurti-0.1/docs/classes/QueryByExample.src/M000056.html +17 -0
- data/trimurti-0.1/docs/classes/QueryByExample.src/M000057.html +17 -0
- data/trimurti-0.1/docs/classes/QueryByExample.src/M000058.html +17 -0
- data/trimurti-0.1/docs/classes/Shiva.html +159 -0
- data/trimurti-0.1/docs/classes/Shiva.src/M000060.html +18 -0
- data/trimurti-0.1/docs/classes/Shiva.src/M000061.html +19 -0
- data/trimurti-0.1/docs/classes/String.html +176 -0
- data/trimurti-0.1/docs/classes/String.src/M000022.html +16 -0
- data/trimurti-0.1/docs/classes/String.src/M000023.html +16 -0
- data/trimurti-0.1/docs/classes/Symbol.html +176 -0
- data/trimurti-0.1/docs/classes/Symbol.src/M000003.html +16 -0
- data/trimurti-0.1/docs/classes/Symbol.src/M000004.html +16 -0
- data/trimurti-0.1/docs/classes/Trimurti.html +189 -0
- data/trimurti-0.1/docs/classes/Trimurti.src/M000019.html +16 -0
- data/trimurti-0.1/docs/classes/Trimurti.src/M000020.html +16 -0
- data/trimurti-0.1/docs/classes/Vishnu.html +563 -0
- data/trimurti-0.1/docs/classes/Vishnu.src/M000038.html +18 -0
- data/trimurti-0.1/docs/classes/Vishnu.src/M000039.html +18 -0
- data/trimurti-0.1/docs/classes/Vishnu.src/M000040.html +18 -0
- data/trimurti-0.1/docs/classes/Vishnu.src/M000041.html +22 -0
- data/trimurti-0.1/docs/classes/Vishnu.src/M000042.html +23 -0
- data/trimurti-0.1/docs/classes/Vishnu.src/M000043.html +24 -0
- data/trimurti-0.1/docs/classes/Vishnu.src/M000044.html +24 -0
- data/trimurti-0.1/docs/classes/Vishnu.src/M000045.html +18 -0
- data/trimurti-0.1/docs/classes/Vishnu.src/M000046.html +22 -0
- data/trimurti-0.1/docs/classes/Vishnu.src/M000047.html +20 -0
- data/trimurti-0.1/docs/classes/Vishnu.src/M000048.html +18 -0
- data/trimurti-0.1/docs/classes/Vishnu.src/M000049.html +22 -0
- data/trimurti-0.1/docs/classes/Vishnu.src/M000050.html +20 -0
- data/trimurti-0.1/docs/classes/Vishnu.src/M000051.html +19 -0
- data/trimurti-0.1/docs/classes/Vishnu.src/M000052.html +30 -0
- data/trimurti-0.1/docs/classes/Vishnu.src/M000053.html +21 -0
- data/trimurti-0.1/docs/created.rid +1 -0
- data/trimurti-0.1/docs/dot/f_0.dot +14 -0
- data/trimurti-0.1/docs/dot/f_0.png +0 -0
- data/trimurti-0.1/docs/dot/f_1.dot +14 -0
- data/trimurti-0.1/docs/dot/f_1.png +0 -0
- data/trimurti-0.1/docs/dot/f_2.dot +14 -0
- data/trimurti-0.1/docs/dot/f_2.png +0 -0
- data/trimurti-0.1/docs/dot/f_3.dot +39 -0
- data/trimurti-0.1/docs/dot/f_3.png +0 -0
- data/trimurti-0.1/docs/dot/f_4.dot +39 -0
- data/trimurti-0.1/docs/dot/f_4.png +0 -0
- data/trimurti-0.1/docs/dot/f_5.dot +69 -0
- data/trimurti-0.1/docs/dot/f_5.png +0 -0
- data/trimurti-0.1/docs/dot/f_6.dot +149 -0
- data/trimurti-0.1/docs/dot/f_6.png +0 -0
- data/trimurti-0.1/docs/dot/m_3_0.dot +30 -0
- data/trimurti-0.1/docs/dot/m_3_0.png +0 -0
- data/trimurti-0.1/docs/dot/m_4_0.dot +39 -0
- data/trimurti-0.1/docs/dot/m_4_0.png +0 -0
- data/trimurti-0.1/docs/dot/m_5_0.dot +40 -0
- data/trimurti-0.1/docs/dot/m_5_0.png +0 -0
- data/trimurti-0.1/docs/dot/m_5_1.dot +30 -0
- data/trimurti-0.1/docs/dot/m_5_1.png +0 -0
- data/trimurti-0.1/docs/dot/m_6_0.dot +40 -0
- data/trimurti-0.1/docs/dot/m_6_0.png +0 -0
- data/trimurti-0.1/docs/dot/m_6_1.dot +30 -0
- data/trimurti-0.1/docs/dot/m_6_1.png +0 -0
- data/trimurti-0.1/docs/dot/m_6_2.dot +30 -0
- data/trimurti-0.1/docs/dot/m_6_2.png +0 -0
- data/trimurti-0.1/docs/files/License_txt.html +132 -0
- data/trimurti-0.1/docs/files/ReadMe_Amber_txt.html +491 -0
- data/trimurti-0.1/docs/files/ReadMe_txt.html +694 -0
- data/trimurti-0.1/docs/files/nist/trimurti/linda_rb.html +129 -0
- data/trimurti-0.1/docs/files/nist/trimurti/plugins_rb.html +129 -0
- data/trimurti-0.1/docs/files/nist/trimurti/queryByExample_rb.html +128 -0
- data/trimurti-0.1/docs/files/nist/trimurti/trimurti_rb.html +151 -0
- data/trimurti-0.1/docs/fr_class_index.html +43 -0
- data/trimurti-0.1/docs/fr_file_index.html +33 -0
- data/trimurti-0.1/docs/fr_method_index.html +89 -0
- data/trimurti-0.1/docs/images/overview.jpg +0 -0
- data/trimurti-0.1/docs/index.html +24 -0
- data/trimurti-0.1/docs/rdoc-style.css +208 -0
- data/trimurti-0.1/lib/nist/trimurti/linda.rb +163 -0
- data/trimurti-0.1/lib/nist/trimurti/plugins.rb +107 -0
- data/trimurti-0.1/lib/nist/trimurti/queryByExample.rb +81 -0
- data/trimurti-0.1/lib/nist/trimurti/trimurti.rb +433 -0
- data/trimurti-0.1/tests/test_linda.rb +111 -0
- data/trimurti-0.1/tests/test_trimurti.rb +247 -0
- 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
|