copland 0.8.0

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 (184) hide show
  1. data/doc/README +88 -0
  2. data/doc/manual-html/chapter-1.html +454 -0
  3. data/doc/manual-html/chapter-10.html +399 -0
  4. data/doc/manual-html/chapter-11.html +600 -0
  5. data/doc/manual-html/chapter-12.html +406 -0
  6. data/doc/manual-html/chapter-2.html +382 -0
  7. data/doc/manual-html/chapter-3.html +424 -0
  8. data/doc/manual-html/chapter-4.html +432 -0
  9. data/doc/manual-html/chapter-5.html +381 -0
  10. data/doc/manual-html/chapter-6.html +364 -0
  11. data/doc/manual-html/chapter-7.html +434 -0
  12. data/doc/manual-html/chapter-8.html +373 -0
  13. data/doc/manual-html/chapter-9.html +324 -0
  14. data/doc/manual-html/copland.png +0 -0
  15. data/doc/manual-html/index.html +331 -0
  16. data/doc/manual-html/manual.css +179 -0
  17. data/doc/manual-html/tutorial-1.html +407 -0
  18. data/doc/manual-html/tutorial-2.html +451 -0
  19. data/doc/manual-html/tutorial-3.html +484 -0
  20. data/doc/manual-html/tutorial-4.html +446 -0
  21. data/doc/manual-html/tutorial-5.html +520 -0
  22. data/doc/manual/chapter.erb +18 -0
  23. data/doc/manual/example.erb +18 -0
  24. data/doc/manual/img/copland.png +0 -0
  25. data/doc/manual/index.erb +30 -0
  26. data/doc/manual/manual.css +179 -0
  27. data/doc/manual/manual.rb +239 -0
  28. data/doc/manual/manual.yml +2643 -0
  29. data/doc/manual/page.erb +102 -0
  30. data/doc/manual/tutorial.erb +30 -0
  31. data/doc/packages/copland.html +764 -0
  32. data/doc/packages/copland.lib.html +439 -0
  33. data/doc/packages/copland.remote.html +2096 -0
  34. data/doc/packages/copland.webrick.html +925 -0
  35. data/doc/packages/index.html +49 -0
  36. data/doc/packages/packrat.css +125 -0
  37. data/examples/calc/calc.rb +47 -0
  38. data/examples/calc/package.yml +35 -0
  39. data/examples/calc/services.rb +74 -0
  40. data/examples/solitaire-cipher/README +11 -0
  41. data/examples/solitaire-cipher/Rakefile +57 -0
  42. data/examples/solitaire-cipher/bin/main.rb +14 -0
  43. data/examples/solitaire-cipher/lib/cipher.rb +230 -0
  44. data/examples/solitaire-cipher/lib/cli.rb +24 -0
  45. data/examples/solitaire-cipher/lib/package.yml +106 -0
  46. data/examples/solitaire-cipher/test/tc_deck.rb +30 -0
  47. data/examples/solitaire-cipher/test/tc_key-stream.rb +19 -0
  48. data/examples/solitaire-cipher/test/tc_keying-algorithms.rb +31 -0
  49. data/examples/solitaire-cipher/test/tc_solitaire-cipher.rb +66 -0
  50. data/examples/solitaire-cipher/test/tc_unkeyed-algorithm.rb +17 -0
  51. data/examples/solitaire-cipher/test/tests.rb +2 -0
  52. data/lib/copland.rb +56 -0
  53. data/lib/copland/class-factory.rb +95 -0
  54. data/lib/copland/configuration-point.rb +38 -0
  55. data/lib/copland/configuration-point/common.rb +203 -0
  56. data/lib/copland/configuration-point/errors.rb +44 -0
  57. data/lib/copland/configuration-point/list.rb +59 -0
  58. data/lib/copland/configuration-point/map.rb +59 -0
  59. data/lib/copland/configuration/errors.rb +43 -0
  60. data/lib/copland/configuration/loader.rb +113 -0
  61. data/lib/copland/configuration/yaml/configuration-point.rb +87 -0
  62. data/lib/copland/configuration/yaml/implementor.rb +134 -0
  63. data/lib/copland/configuration/yaml/interceptor.rb +63 -0
  64. data/lib/copland/configuration/yaml/listener.rb +56 -0
  65. data/lib/copland/configuration/yaml/loader.rb +122 -0
  66. data/lib/copland/configuration/yaml/package.rb +125 -0
  67. data/lib/copland/configuration/yaml/parser.rb +71 -0
  68. data/lib/copland/configuration/yaml/schema.rb +165 -0
  69. data/lib/copland/configuration/yaml/service-point.rb +116 -0
  70. data/lib/copland/configuration/yaml/utils.rb +82 -0
  71. data/lib/copland/default-schema-processor.rb +144 -0
  72. data/lib/copland/errors.rb +82 -0
  73. data/lib/copland/event-producer.rb +95 -0
  74. data/lib/copland/impl/builder-factory.rb +112 -0
  75. data/lib/copland/impl/copland-config.yml +1 -0
  76. data/lib/copland/impl/include-exclude.rb +140 -0
  77. data/lib/copland/impl/logging-interceptor.rb +106 -0
  78. data/lib/copland/impl/package.yml +217 -0
  79. data/lib/copland/impl/startup.rb +116 -0
  80. data/lib/copland/impl/symbol-source-manager.rb +131 -0
  81. data/lib/copland/impl/symbol-source.rb +63 -0
  82. data/lib/copland/instantiator.rb +38 -0
  83. data/lib/copland/instantiator/abstract.rb +91 -0
  84. data/lib/copland/instantiator/complex.rb +96 -0
  85. data/lib/copland/instantiator/identity.rb +58 -0
  86. data/lib/copland/instantiator/simple.rb +68 -0
  87. data/lib/copland/interceptor-chain.rb +166 -0
  88. data/lib/copland/interceptor.rb +139 -0
  89. data/lib/copland/log-factory.rb +206 -0
  90. data/lib/copland/models.rb +39 -0
  91. data/lib/copland/models/abstract.rb +78 -0
  92. data/lib/copland/models/prototype-deferred.rb +58 -0
  93. data/lib/copland/models/prototype.rb +58 -0
  94. data/lib/copland/models/proxy.rb +100 -0
  95. data/lib/copland/models/singleton-deferred.rb +59 -0
  96. data/lib/copland/models/singleton.rb +77 -0
  97. data/lib/copland/models/threaded.rb +65 -0
  98. data/lib/copland/ordering.rb +123 -0
  99. data/lib/copland/package.rb +246 -0
  100. data/lib/copland/registry.rb +368 -0
  101. data/lib/copland/schema.rb +206 -0
  102. data/lib/copland/service-point.rb +282 -0
  103. data/lib/copland/utils.rb +221 -0
  104. data/lib/copland/version.rb +47 -0
  105. data/test/conf-test/list-bad-key.yml +30 -0
  106. data/test/conf-test/list-bad-missing.yml +28 -0
  107. data/test/conf-test/list-bad-type.yml +28 -0
  108. data/test/conf-test/list-good.yml +29 -0
  109. data/test/conf-test/map-bad-key.yml +25 -0
  110. data/test/conf-test/map-bad-missing.yml +24 -0
  111. data/test/conf-test/map-bad-type.yml +23 -0
  112. data/test/conf-test/map-good.yml +25 -0
  113. data/test/configuration-point/package.yml +52 -0
  114. data/test/configuration/yaml/config/copland-config.yml +2 -0
  115. data/test/configuration/yaml/config/module.yml +2 -0
  116. data/test/configuration/yaml/config/subdir/copland-config.yml +2 -0
  117. data/test/configuration/yaml/config/subdir/package.yml +4 -0
  118. data/test/configuration/yaml/defaults/package.yml +5 -0
  119. data/test/configuration/yaml/defaults/subdir/package.yml +4 -0
  120. data/test/configuration/yaml/tc_config-loader.rb +86 -0
  121. data/test/configuration/yaml/tc_configuration-point-processor.rb +134 -0
  122. data/test/configuration/yaml/tc_implementor-processor.rb +104 -0
  123. data/test/configuration/yaml/tc_interceptor-processor.rb +85 -0
  124. data/test/configuration/yaml/tc_listener-processor.rb +69 -0
  125. data/test/configuration/yaml/tc_loader.rb +74 -0
  126. data/test/configuration/yaml/tc_package-processor.rb +120 -0
  127. data/test/configuration/yaml/tc_parser.rb +94 -0
  128. data/test/configuration/yaml/tc_schema-parser.rb +160 -0
  129. data/test/configuration/yaml/tc_service-point-processor.rb +104 -0
  130. data/test/configuration/yaml/tc_type-validator.rb +90 -0
  131. data/test/custom-logger.yml +3 -0
  132. data/test/impl/logging/package.yml +44 -0
  133. data/test/impl/logging/services.rb +84 -0
  134. data/test/impl/startup/package.yml +46 -0
  135. data/test/impl/startup/services.rb +47 -0
  136. data/test/impl/symbols/package.yml +24 -0
  137. data/test/impl/symbols/services.rb +38 -0
  138. data/test/impl/tc_builder-factory.rb +173 -0
  139. data/test/impl/tc_logging-interceptor.rb +148 -0
  140. data/test/impl/tc_startup.rb +59 -0
  141. data/test/impl/tc_symbol-sources.rb +61 -0
  142. data/test/logger.yml +6 -0
  143. data/test/mock.rb +201 -0
  144. data/test/schema/bad-package.yml +65 -0
  145. data/test/schema/package.yml +102 -0
  146. data/test/schema/services.rb +5 -0
  147. data/test/services/package.yml +79 -0
  148. data/test/services/simple.rb +87 -0
  149. data/test/tc_class-factory.rb +93 -0
  150. data/test/tc_complex-instantiator.rb +107 -0
  151. data/test/tc_configuration-point-contrib.rb +74 -0
  152. data/test/tc_configuration-point-schema.rb +122 -0
  153. data/test/tc_configuration-point.rb +91 -0
  154. data/test/tc_default-schema-processor.rb +297 -0
  155. data/test/tc_identity-instantiator.rb +61 -0
  156. data/test/tc_interceptors.rb +84 -0
  157. data/test/tc_logger.rb +131 -0
  158. data/test/tc_models.rb +176 -0
  159. data/test/tc_package.rb +165 -0
  160. data/test/tc_proxy.rb +65 -0
  161. data/test/tc_registry.rb +141 -0
  162. data/test/tc_schema.rb +78 -0
  163. data/test/tc_service-point.rb +178 -0
  164. data/test/tc_service.rb +70 -0
  165. data/test/tc_simple-instantiator.rb +61 -0
  166. data/test/tests.rb +93 -0
  167. data/tutorial/01/main.rb +7 -0
  168. data/tutorial/01/package.yml +8 -0
  169. data/tutorial/01/tutorial.rb +7 -0
  170. data/tutorial/02/main.rb +10 -0
  171. data/tutorial/02/package.yml +27 -0
  172. data/tutorial/02/tutorial.rb +46 -0
  173. data/tutorial/03/main.rb +24 -0
  174. data/tutorial/03/package.yml +29 -0
  175. data/tutorial/03/tutorial.rb +48 -0
  176. data/tutorial/04/main.rb +24 -0
  177. data/tutorial/04/package.yml +35 -0
  178. data/tutorial/04/tutorial.rb +48 -0
  179. data/tutorial/05/functions/package.yml +16 -0
  180. data/tutorial/05/functions/services.rb +15 -0
  181. data/tutorial/05/main.rb +10 -0
  182. data/tutorial/05/package.yml +35 -0
  183. data/tutorial/05/tutorial.rb +53 -0
  184. metadata +260 -0
@@ -0,0 +1,24 @@
1
+ class CLI
2
+
3
+ ENCRYPTED = /^([A-Z]{5} )*[A-Z]{5}$/
4
+
5
+ attr_writer :cipher
6
+ attr_writer :options
7
+
8
+ def run
9
+ return unless @options.run_app?
10
+
11
+ @cipher.use_algorithm @options.keying_algorithm
12
+
13
+ @options.strings.each do |arg|
14
+ if arg =~ ENCRYPTED
15
+ puts arg.inspect
16
+ puts " (decrypt)--> #{@cipher.decrypt(arg).inspect}"
17
+ else
18
+ puts arg.inspect
19
+ puts " (encrypt)--> #{@cipher.encrypt(arg).inspect}"
20
+ end
21
+ end
22
+ end
23
+
24
+ end
@@ -0,0 +1,106 @@
1
+ ---
2
+ id: solitaire.cipher
3
+ description: >-
4
+ The services needed to implement a command-line version of the solitaire
5
+ cipher. This is in fulfillment of Ruby Quiz 1: "The Solitaire Cipher".
6
+
7
+ service-points:
8
+
9
+ CLI:
10
+ description: >-
11
+ The command-line interface required by the quiz. Ideally, this would
12
+ be put in a package of its own, leaving the more general-purpose
13
+ services in this package, but for the quiz...let's not go TOO overboard
14
+ on this...
15
+ model: singleton
16
+ implementor:
17
+ factory: copland.BuilderFactory
18
+ class: cli/CLI
19
+ properties:
20
+ cipher: !!service SolitaireCipher
21
+ options: !!service Options
22
+
23
+ KeyingAlgorithms:
24
+ description: >-
25
+ This service helps provide keying algorithms. It is backed by the
26
+ configuration point of the same name, but provides a little more "extra"
27
+ functionality than an unadorned configuration point.
28
+ implementor:
29
+ factory: copland.BuilderFactory
30
+ class: cipher/KeyingAlgorithms
31
+ properties:
32
+ algorithms: !!configuration KeyingAlgorithms
33
+ registry: !!service copland.Registry
34
+
35
+ KeyStream:
36
+ description: >-
37
+ Represents a keystream. It may be used as an iterator to obtain
38
+ subsequent letters from the keystream.
39
+ model: prototype
40
+ implementor:
41
+ factory: copland.BuilderFactory
42
+ class: cipher/KeyStream
43
+ properties:
44
+ deck: !!service Deck
45
+
46
+ SolitaireCipher:
47
+ description: >-
48
+ The implementation of the solitaire cipher. This handles both encryption
49
+ and decryption.
50
+ model: prototype
51
+ implementor:
52
+ factory: copland.BuilderFactory
53
+ class: cipher/SolitaireCipher
54
+ parameters:
55
+ - !!service UnkeyedAlgorithm
56
+ properties:
57
+ algorithms: !!service KeyingAlgorithms
58
+ stream: !!service KeyStream
59
+
60
+ UnkeyedAlgorithm:
61
+ description: >-
62
+ The default keying algorithm, which is really no algorithm at all. It
63
+ does nothing to the deck, leaving it in its unkeyed form.
64
+ implementor: cipher/UnkeyedAlgorithm
65
+
66
+ BackwardsAlgorithm:
67
+ description: >-
68
+ Keys the deck by ordering the cards in reverse unkeyed order.
69
+ implementor: cipher/BackwardsAlgorithm
70
+
71
+ ShuffleAlgorithm:
72
+ description: >-
73
+ Just for demonstration, and certainly not required by the quiz. This
74
+ keying algorithm just shuffles the deck, using a specific number to
75
+ seed the random number generator, for repeatability.
76
+ implementor:
77
+ factory: copland.BuilderFactory
78
+ class: cipher/ShuffleAlgorithm
79
+ properties:
80
+ options: !!service Options
81
+
82
+ Options:
83
+ description: >-
84
+ Represents the options given to the application, either via the command
85
+ line or some other way.
86
+ implementor: cipher/Options
87
+
88
+ Deck:
89
+ model: prototype-deferred
90
+ description: Implements a deck of cards for the solitaire cipher.
91
+ implementor: cipher/Deck
92
+
93
+ configuration-points:
94
+
95
+ KeyingAlgorithms:
96
+ type: map
97
+ description: >-
98
+ The map of available algorithms to use when keying a deck. Each algorithm
99
+ that is added must be the (fully-qualified) name of a service.
100
+
101
+ contributions:
102
+
103
+ KeyingAlgorithms:
104
+ unkeyed: solitaire.cipher.UnkeyedAlgorithm
105
+ shuffle: solitaire.cipher.ShuffleAlgorithm
106
+ reverse: solitaire.cipher.BackwardsAlgorithm
@@ -0,0 +1,30 @@
1
+ $: << File.join( File.dirname( __FILE__ ), "..", "lib" )
2
+ require 'test/unit'
3
+ require 'cipher'
4
+
5
+ class TC_Deck < Test::Unit::TestCase
6
+
7
+ def setup
8
+ @deck = Deck.new
9
+ end
10
+
11
+ def test_content
12
+ expected = (1..52).to_a + [ "A", "B" ]
13
+ assert_equal expected, @deck.to_a
14
+ end
15
+
16
+ def test_shuffle
17
+ @deck.cipher_shuffle!
18
+ expected = (2..52).to_a + [ "A", "B", 1 ]
19
+ assert_equal expected, @deck.to_a
20
+ end
21
+
22
+ def test_letter
23
+ expected = %w{ D W J nil X H Y R F D G }
24
+ expected.each do |expected_letter|
25
+ @deck.cipher_shuffle!
26
+ assert_equal expected_letter, @deck.cipher_letter || "nil"
27
+ end
28
+ end
29
+
30
+ end
@@ -0,0 +1,19 @@
1
+ $: << File.join( File.dirname( __FILE__ ), "..", "lib" )
2
+ require 'test/unit'
3
+ require 'cipher'
4
+
5
+ class TC_KeyStream < Test::Unit::TestCase
6
+
7
+ def setup
8
+ @stream = KeyStream.new
9
+ @stream.deck = Deck.new
10
+ end
11
+
12
+ def test_next
13
+ expected = %w{ D W J X H Y R F D G }
14
+ expected.each do |expected_letter|
15
+ assert_equal expected_letter, @stream.next
16
+ end
17
+ end
18
+
19
+ end
@@ -0,0 +1,31 @@
1
+ $: << File.join( File.dirname( __FILE__ ), "..", "lib" )
2
+ require 'test/unit'
3
+ require 'cipher'
4
+
5
+ class TC_KeyingAlgorithms < Test::Unit::TestCase
6
+
7
+ class MockRegistry
8
+ def service( name )
9
+ return "found" if name == "something.mock"
10
+ return nil
11
+ end
12
+ end
13
+
14
+ def setup
15
+ @algorithms = KeyingAlgorithms.new
16
+ @algorithms.algorithms = { "mock" => "something.mock" }
17
+ @algorithms.registry = MockRegistry.new
18
+ end
19
+
20
+ def test_get_not_found
21
+ assert_raise( RuntimeError ) do
22
+ @algorithms.get( "bogus" )
23
+ end
24
+ end
25
+
26
+ def test_get_found
27
+ svc = @algorithms.get( "mock" )
28
+ assert_equal svc, "found"
29
+ end
30
+
31
+ end
@@ -0,0 +1,66 @@
1
+ $: << File.join( File.dirname( __FILE__ ), "..", "lib" )
2
+ require 'test/unit'
3
+ require 'cipher'
4
+
5
+ class TC_SolitaireCipher < Test::Unit::TestCase
6
+
7
+ class MockAlgorithms
8
+ def get( name )
9
+ MockAlgorithm.new
10
+ end
11
+ end
12
+
13
+ class MockDeck
14
+ def cipher_shuffle!
15
+ end
16
+
17
+ def cipher_letter
18
+ "X"
19
+ end
20
+ end
21
+
22
+ class MockAlgorithm
23
+ def new_deck
24
+ MockDeck.new
25
+ end
26
+ end
27
+
28
+ def setup
29
+ @cipher = SolitaireCipher.new( UnkeyedAlgorithm.new )
30
+ @cipher.algorithms = MockAlgorithms.new
31
+ @cipher.stream = KeyStream.new
32
+ end
33
+
34
+ def test_use_algorithm
35
+ @cipher.use_algorithm "mock"
36
+ assert_equal "FCJJM", @cipher.encrypt( "HELLO" )
37
+ assert_equal "JGNNQ", @cipher.decrypt( "HELLO" )
38
+ end
39
+
40
+ def test_encrypt
41
+ msg = "Code in Ruby! Live longer."
42
+ expected = "GLNCQ MJAFF FVOMB JIYCB"
43
+ assert_equal expected, @cipher.encrypt( msg )
44
+ end
45
+
46
+ def test_decrypt_bad
47
+ assert_raise( RuntimeError ) do
48
+ @cipher.decrypt( "not good" )
49
+ end
50
+
51
+ assert_raise( RuntimeError ) do
52
+ @cipher.decrypt( "BOGUS 12345" )
53
+ end
54
+ end
55
+
56
+ def test_decrypt_good
57
+ msg = "CLEPK HHNIY CFPWH FDFEH"
58
+ expected = "YOURCIPHERISWORKINGX"
59
+ assert_equal expected, @cipher.decrypt( msg )
60
+
61
+ msg = "ABVAW LWZSY OORYK DUPVH"
62
+ expected = "WELCOMETORUBYQUIZXXX"
63
+ assert_equal expected, @cipher.decrypt( msg )
64
+ end
65
+
66
+ end
@@ -0,0 +1,17 @@
1
+ $: << File.join( File.dirname( __FILE__ ), "..", "lib" )
2
+ require 'test/unit'
3
+ require 'cipher'
4
+
5
+ class TC_UnkeyedAlgorithm < Test::Unit::TestCase
6
+
7
+ def setup
8
+ @algo = UnkeyedAlgorithm.new
9
+ end
10
+
11
+ def test_new_deck
12
+ expected = (1..52).to_a + [ "A", "B" ]
13
+ deck = @algo.new_deck
14
+ assert_equal expected, deck.to_a
15
+ end
16
+
17
+ end
@@ -0,0 +1,2 @@
1
+ Dir.chdir File.dirname( __FILE__ )
2
+ Dir["tc_*.rb"].each { |test| load test }
@@ -0,0 +1,56 @@
1
+ #--
2
+ # =============================================================================
3
+ # Copyright (c) 2004, Jamis Buck (jgb3@email.byu.edu)
4
+ # All rights reserved.
5
+ #
6
+ # Redistribution and use in source and binary forms, with or without
7
+ # modification, are permitted provided that the following conditions are met:
8
+ #
9
+ # * Redistributions of source code must retain the above copyright notice,
10
+ # this list of conditions and the following disclaimer.
11
+ #
12
+ # * Redistributions in binary form must reproduce the above copyright
13
+ # notice, this list of conditions and the following disclaimer in the
14
+ # documentation and/or other materials provided with the distribution.
15
+ #
16
+ # * The names of its contributors may not be used to endorse or promote
17
+ # products derived from this software without specific prior written
18
+ # permission.
19
+ #
20
+ # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
21
+ # AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
22
+ # IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
23
+ # ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
24
+ # LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
25
+ # CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
26
+ # SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
27
+ # INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
28
+ # CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
29
+ # ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
30
+ # POSSIBILITY OF SUCH DAMAGE.
31
+ # =============================================================================
32
+ #++
33
+
34
+ require 'copland/configuration/errors'
35
+ require 'copland/errors'
36
+ require 'copland/registry'
37
+ require 'copland/version'
38
+
39
+ module Copland
40
+
41
+ # The map of library 'require' names to the package descriptor search paths
42
+ # that they define.
43
+ LIBRARIES = Hash.new { |h,k| h[k] = Array.new }
44
+
45
+ # The name of the "core" Copland library. This will always be loaded by
46
+ # default, but we define a library name to keep things consistent. Also to
47
+ # allow packages to explicitly require it, if they desire.
48
+ LIBRARY_NAME = "copland"
49
+
50
+ # The search paths of the core Copland library.
51
+ SEARCH_PATHS = [ File.join( File.dirname( __FILE__ ), "copland", "impl" ) ]
52
+
53
+ # Tell Copland how to find it's core services.
54
+ LIBRARIES[ LIBRARY_NAME ] = SEARCH_PATHS
55
+
56
+ end
@@ -0,0 +1,95 @@
1
+ #--
2
+ # =============================================================================
3
+ # Copyright (c) 2004, Jamis Buck (jgb3@email.byu.edu)
4
+ # All rights reserved.
5
+ #
6
+ # Redistribution and use in source and binary forms, with or without
7
+ # modification, are permitted provided that the following conditions are met:
8
+ #
9
+ # * Redistributions of source code must retain the above copyright notice,
10
+ # this list of conditions and the following disclaimer.
11
+ #
12
+ # * Redistributions in binary form must reproduce the above copyright
13
+ # notice, this list of conditions and the following disclaimer in the
14
+ # documentation and/or other materials provided with the distribution.
15
+ #
16
+ # * The names of its contributors may not be used to endorse or promote
17
+ # products derived from this software without specific prior written
18
+ # permission.
19
+ #
20
+ # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
21
+ # AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
22
+ # IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
23
+ # ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
24
+ # LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
25
+ # CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
26
+ # SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
27
+ # INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
28
+ # CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
29
+ # ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
30
+ # POSSIBILITY OF SUCH DAMAGE.
31
+ # =============================================================================
32
+ #++
33
+
34
+ require 'singleton'
35
+
36
+ module Copland
37
+
38
+ # This factory class provides an interface for instantiating a variety
39
+ # of different kinds of classes. It uses the concept of a "pool" to allow
40
+ # different functional groupings of classes to be separated within the
41
+ # factory. Thus, this is _the_ factory class for all classes in Copland,
42
+ # including configuration points, instantiators, and service models.
43
+ class ClassFactory
44
+ include Singleton
45
+
46
+ # Create a new ClassFactory. By default, it defines no pools.
47
+ def initialize
48
+ @pools = Hash.new
49
+ @constructors = Hash.new
50
+ end
51
+
52
+ # Define a new pool with the given name. If a block is given, it should
53
+ # accept at least one parameter (the klass to instantiate) and should
54
+ # return an instance of that class. Additional parameters may be
55
+ # passed to the block, with the intent that they may be used to initialize
56
+ # the new object somehow.
57
+ def create_pool( name, &block )
58
+ block ||= proc { |k,*args| k.new( *args ) }
59
+ @pools[ name ] = Hash.new
60
+ @constructors[ name ] = block
61
+ end
62
+
63
+ # Retreive a reference to the pool with the given name. If no such pool
64
+ # exists, a NoSuchPoolException will be raised.
65
+ def get_pool( name )
66
+ pool = @pools[ name ]
67
+ raise NoSuchPoolException, name unless pool
68
+ return pool
69
+ end
70
+
71
+ # Register the given klass with the class factory, in the given pool, with
72
+ # the given name. If the given pool does not exist, a NoSuchPoolException
73
+ # will be raised.
74
+ def register( pool_name, name, klass )
75
+ pool = get_pool( pool_name )
76
+ pool[ name ] = klass
77
+ end
78
+
79
+ # Return a new instance of the class registered under the given name in the
80
+ # given pool. If any additional arguments are given to the method, they
81
+ # will be passed to the constructor used to instantiate the class.
82
+ def get( pool_name, name, *args )
83
+ pool = get_pool( pool_name )
84
+
85
+ klass = pool[ name ]
86
+ raise NoSuchRegisteredClassException, "#{pool_name}:#{name}" unless klass
87
+
88
+ constructor = @constructors[ pool_name ]
89
+
90
+ return constructor.call( klass, *args )
91
+ end
92
+
93
+ end
94
+
95
+ end