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,116 @@
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/service-point'
35
+ require 'copland/configuration/errors'
36
+ require 'copland/configuration/yaml/implementor'
37
+ require 'copland/configuration/yaml/interceptor'
38
+ require 'copland/configuration/yaml/listener'
39
+ require 'copland/configuration/yaml/schema'
40
+ require 'copland/configuration/yaml/utils'
41
+
42
+ module Copland
43
+ module Configuration
44
+ module YAML
45
+
46
+ # This is the delgate that is responsible for processing the input
47
+ # describing a service point.
48
+ class ServicePointProcessor
49
+ include TypeValidator
50
+
51
+ # Create a new ServicePointProcessor that feeds into the given
52
+ # package instance. The +options+ parameter is given to every new
53
+ # service point as it is created.
54
+ def initialize( package, options={} )
55
+ @package = package
56
+ @options = options
57
+ @implementor = ImplementorProcessor.new
58
+ @interceptor = InterceptorProcessor.new
59
+ @listener = ListenerProcessor.new
60
+ @schema = SchemaParser.new
61
+ end
62
+
63
+ # The list of valid keys that may exist on the input.
64
+ VALID_KEYS = [ "description", "model", "implementor",
65
+ "interceptors", "listen-to", "schema" ]
66
+
67
+ # The list of required keys that must exist on the input.
68
+ REQUIRED_KEYS = [ "implementor" ]
69
+
70
+ # Create a new service point with the given name and populate it with
71
+ # data as described by the +doc+ parameter. The new service point is
72
+ # returned.
73
+ def process( name, doc )
74
+ ensure_element_type "service-point", doc, Hash
75
+ validate_elements doc
76
+
77
+ point = ServicePoint.new( @package, name, @options )
78
+ doc.each_pair do |key, value|
79
+ case key
80
+ when "description"
81
+ point.description = value
82
+
83
+ when "model"
84
+ point.use_service_model value
85
+
86
+ when "implementor"
87
+ @implementor.process( point, value )
88
+
89
+ when "interceptors"
90
+ ensure_element_type "interceptors", value, Array
91
+ value.each do |definition|
92
+ @interceptor.process( point, definition )
93
+ end
94
+
95
+ when "listen-to"
96
+ ensure_element_type "listen-to", value, Array
97
+ value.each do |definition|
98
+ @listener.process( point, definition )
99
+ end
100
+
101
+ when "schema"
102
+ point.schema = @schema.process( point, value )
103
+
104
+ else
105
+ raise CoplandBug, "[BUG] invalid key discovered too late: #{key.inspect}"
106
+ end
107
+ end
108
+
109
+ return point
110
+ end
111
+
112
+ end
113
+
114
+ end
115
+ end
116
+ end
@@ -0,0 +1,82 @@
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
+
36
+ module Copland
37
+ module Configuration
38
+ module YAML
39
+
40
+ # This module implements type validation routines that are used by most
41
+ # of the classes in the Copland::Configuration::YAML module.
42
+ module TypeValidator
43
+
44
+ # Ensures that the given +element+ (identified by the given +name+) is
45
+ # indeed an instance of the given +klass+. If it is not, a ParserError
46
+ # is raised.
47
+ def ensure_element_type( name, element, klass )
48
+ unless element.is_a?( klass )
49
+ raise ParserError,
50
+ "#{name.inspect} must be of type #{klass}, " +
51
+ "not #{element.class}",
52
+ caller[1..-1]
53
+ end
54
+ end
55
+
56
+ # This requires that the +VALID_KEYS+ and +REQUIRED_KEYS+ constants have
57
+ # been set in the including class. Then, it tests to see if the given
58
+ # +hash+ includes any values other than those that are defined in
59
+ # +VALID_KEYS+, or whether any keys in +REQUIRED_KEYS+ are missing from
60
+ # +hash+. If either condition is true, a ParserError is raised. If
61
+ # +path+ is given, it describes the location of the element (for error
62
+ # reporting).
63
+ def validate_elements( hash, path="" )
64
+ path = " at #{path}" if path
65
+ invalid_keys = hash.keys - self.class::VALID_KEYS
66
+ unless invalid_keys.empty?
67
+ raise ParserError,
68
+ "invalid elements(s)#{path}: #{invalid_keys.inspect}"
69
+ end
70
+
71
+ missing_keys = self.class::REQUIRED_KEYS - hash.keys
72
+ unless missing_keys.empty?
73
+ raise ParserError,
74
+ "missing element(s)#{path}: #{missing_keys.inspect}"
75
+ end
76
+ end
77
+
78
+ end
79
+
80
+ end
81
+ end
82
+ end
@@ -0,0 +1,144 @@
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/errors'
35
+ require 'copland/utils'
36
+
37
+ module Copland
38
+
39
+ # The DefaultSchemaProcessor is the default processor class used for
40
+ # processing (validating and pre-processing) schema elements.
41
+ class DefaultSchemaProcessor
42
+
43
+ # Validates the given +data+ against the given +schema+. +owner+ is the
44
+ # object associated with the schema, and +client" is the object associated
45
+ # with the data. If +path+ is given, it specifies the path up to the
46
+ # current schema element (for error reporting purposes).
47
+ #
48
+ # If this method returns, then the validation succeeded. Otherwise, it will
49
+ # raise a ValidationException.
50
+ def validate( owner, client, schema, data, path="/" )
51
+ return unless schema.definition
52
+ schema_keys = schema.definition.keys
53
+ data = data.value if data.respond_to?( :type_id )
54
+ data_keys = data.keys
55
+
56
+ extra_keys = data_keys - schema_keys
57
+ unless extra_keys.empty?
58
+ validation_error owner, client, path,
59
+ "illegal parameter(s) #{extra_keys.inspect}"
60
+ end
61
+
62
+ schema.definition.each_pair do |key, subschema|
63
+ subpath = path + ( path[-1] == ?/ ? "" : "/" ) + key
64
+
65
+ if data[key]
66
+ validate_type owner,
67
+ client,
68
+ subschema.type,
69
+ data[key],
70
+ subpath
71
+
72
+ subschema.validate owner,
73
+ client,
74
+ data[key],
75
+ subpath
76
+
77
+ elsif subschema.required
78
+ validation_error owner, client, path,
79
+ "required parameter #{key.inspect} missing"
80
+ end
81
+ end
82
+ end
83
+
84
+ # Pre-processes the +data+, possibly in conjuction with the +schema+. The
85
+ # parameters are identical to those given for #validate. The default
86
+ # implementation simply calls Copland::translate_value on the +data+,
87
+ # using +client+ as the reference value.
88
+ #
89
+ # The primary purpose of this call is to convert/translate values to their
90
+ # actual types, like "!!service service.name" values.
91
+ def process( owner, client, schema, data, path="/" )
92
+ return Copland::translate_value( client.owner.registry,
93
+ client.owner,
94
+ client,
95
+ data )
96
+ end
97
+
98
+ # Used internally to ensure that the given +data+ element is of the
99
+ # +type+ specified. If it isn't, a ValidationException is raised.
100
+ def validate_type( owner, client, type, data, path )
101
+ return unless type && type != "any"
102
+
103
+ if data.respond_to?( :type_id )
104
+ type_id = data.type_id
105
+ else
106
+ case data
107
+ when String then type_id = "string"
108
+ when Integer then type_id = "integer"
109
+ when Float then type_id = "real"
110
+ when Hash then type_id = "hash"
111
+ when Array then type_id = "array"
112
+ when Symbol then type_id = "symbol"
113
+ when true, false then type_id = "boolean"
114
+ else
115
+ type_id = "unknown (#{data.class})"
116
+ end
117
+ end
118
+
119
+ if type_id == "hash" && type == "array"
120
+ # special case: the data is an array, but the type in the schema is a
121
+ # hash. This should be interpreted to mean that the hash is the
122
+ # subschema for each element of the array.
123
+ return
124
+ end
125
+
126
+ unless type_id == type
127
+ validation_error owner, client, path,
128
+ "expected type #{type}, got #{type_id}"
129
+ end
130
+ end
131
+ private :validate_type
132
+
133
+ # A convenience method for raising ValidationException errors.
134
+ def validation_error( owner, client, path, msg )
135
+ raise ValidationException,
136
+ "at #{path} in #{owner.full_name} for #{client.full_name}: " +
137
+ msg,
138
+ caller[1..-1]
139
+ end
140
+ private :validation_error
141
+
142
+ end
143
+
144
+ end
@@ -0,0 +1,82 @@
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
+ module Copland
35
+
36
+ # The base exception class for all Copland errors.
37
+ class CoplandException < StandardError; end
38
+
39
+ # This specialized exception is used for reporting "bug" conditions.
40
+ class CoplandBug < CoplandException; end
41
+
42
+ # Used when reporting the absense of a package that was requested.
43
+ class PackageNotFound < CoplandException; end
44
+
45
+ # Used when reporting the absense of a service point that was requested.
46
+ class ServicePointNotFound < CoplandException; end
47
+
48
+ # Used when reporting the absense of a configuration point that was
49
+ # requested.
50
+ class ConfigurationPointNotFound < CoplandException; end
51
+
52
+ # Used when reporting the absense of a schema that was requested.
53
+ class SchemaNotFound < CoplandException; end
54
+
55
+ # Used when an ordering (of interceptors, or autoload services) could not be
56
+ # honored due to conflicting ordering preferences.
57
+ class OrderingException < CoplandException; end
58
+
59
+ # Used when reporting the invocation of a disallowed operation.
60
+ class DisallowedOperationException < CoplandException; end
61
+
62
+ # Used when reporting the absense of a pool (in the ClassFactory) that was
63
+ # requested.
64
+ class NoSuchPoolException < CoplandException; end
65
+
66
+ # Used when reporting the absense of a class that was requested via the
67
+ # ClassFactory.
68
+ class NoSuchRegisteredClassException < CoplandException; end
69
+
70
+ # Used when a package is added to the registry and a package with the same
71
+ # name already exists.
72
+ class DuplicatePackageError < CoplandException; end
73
+
74
+ # Used when a service point (or similar entity) is defined without an
75
+ # implementation (ie, instantiator, or some such).
76
+ class MissingImplementationException < CoplandException; end
77
+
78
+ # Used when a validation fails, such as validating parameter data against a
79
+ # schema.
80
+ class ValidationException < CoplandException; end
81
+
82
+ 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
+ module Copland
35
+
36
+ # Any service implementation that wishes to be able to alert other services
37
+ # of events may mixin this module. If it does not, it may still be used as an
38
+ # event producer as long as it implements:
39
+ #
40
+ # # The #add_listener method
41
+ # # A notification method that invokes some listener method on each listener,
42
+ # which method must be called "on_#{event_name}" and must accept the
43
+ # producer as the first argument.
44
+ module EventProducer
45
+
46
+ # Add the given listener to this producer's list of listeners. A listener
47
+ # may be added multiple times.
48
+ def add_listener( listener )
49
+ ( @listeners ||= [] ).push listener
50
+ self
51
+ end
52
+
53
+ # Remove the given listener from the producer's list of listeners. If the
54
+ # listener does not exist in the listener list, nothing happens. If it
55
+ # exists more than once, only the first instance is removed.
56
+ def remove_listener( listener )
57
+ @listeners.delete listener if @listeners
58
+ self
59
+ end
60
+
61
+ # Iterates over each listener in the list. It first makes a copy of the
62
+ # list and then iterates over the copy, so it essentially iterates over
63
+ # a snapshot of the listener list. This makes its behavior deterministic
64
+ # when dealing with multiple threads of control.
65
+ def each_listener
66
+ return unless @listeners
67
+ @listeners.dup.each do |listener|
68
+ yield listener
69
+ end
70
+ self
71
+ end
72
+
73
+ # Signals the listeners that some event has occurred. The +event+ method
74
+ # should be either a String or a Symbol. Each listener is then queried
75
+ # to see if they respond to a method called "on_#{event}", and if they
76
+ # do, they are sent that message, along with the producer and the argument
77
+ # list. If they don't respond to "on_#{event}", they are then asked if
78
+ # they respond to "on_any_event", if they do, they are sent that message,
79
+ # along with the producer, the event, and the argument list.
80
+ def fire_event( event, *args )
81
+ method = "on_#{event.to_s}"
82
+ general_method = "on_any_event"
83
+ each_listener do |listener|
84
+ if listener.respond_to?( method )
85
+ listener.__send__( method, self, *args )
86
+ elsif listener.respond_to?( general_method )
87
+ listener.__send__( general_method, self, event, *args )
88
+ end
89
+ end
90
+ self
91
+ end
92
+
93
+ end
94
+
95
+ end