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.
- data/doc/README +88 -0
- data/doc/manual-html/chapter-1.html +454 -0
- data/doc/manual-html/chapter-10.html +399 -0
- data/doc/manual-html/chapter-11.html +600 -0
- data/doc/manual-html/chapter-12.html +406 -0
- data/doc/manual-html/chapter-2.html +382 -0
- data/doc/manual-html/chapter-3.html +424 -0
- data/doc/manual-html/chapter-4.html +432 -0
- data/doc/manual-html/chapter-5.html +381 -0
- data/doc/manual-html/chapter-6.html +364 -0
- data/doc/manual-html/chapter-7.html +434 -0
- data/doc/manual-html/chapter-8.html +373 -0
- data/doc/manual-html/chapter-9.html +324 -0
- data/doc/manual-html/copland.png +0 -0
- data/doc/manual-html/index.html +331 -0
- data/doc/manual-html/manual.css +179 -0
- data/doc/manual-html/tutorial-1.html +407 -0
- data/doc/manual-html/tutorial-2.html +451 -0
- data/doc/manual-html/tutorial-3.html +484 -0
- data/doc/manual-html/tutorial-4.html +446 -0
- data/doc/manual-html/tutorial-5.html +520 -0
- data/doc/manual/chapter.erb +18 -0
- data/doc/manual/example.erb +18 -0
- data/doc/manual/img/copland.png +0 -0
- data/doc/manual/index.erb +30 -0
- data/doc/manual/manual.css +179 -0
- data/doc/manual/manual.rb +239 -0
- data/doc/manual/manual.yml +2643 -0
- data/doc/manual/page.erb +102 -0
- data/doc/manual/tutorial.erb +30 -0
- data/doc/packages/copland.html +764 -0
- data/doc/packages/copland.lib.html +439 -0
- data/doc/packages/copland.remote.html +2096 -0
- data/doc/packages/copland.webrick.html +925 -0
- data/doc/packages/index.html +49 -0
- data/doc/packages/packrat.css +125 -0
- data/examples/calc/calc.rb +47 -0
- data/examples/calc/package.yml +35 -0
- data/examples/calc/services.rb +74 -0
- data/examples/solitaire-cipher/README +11 -0
- data/examples/solitaire-cipher/Rakefile +57 -0
- data/examples/solitaire-cipher/bin/main.rb +14 -0
- data/examples/solitaire-cipher/lib/cipher.rb +230 -0
- data/examples/solitaire-cipher/lib/cli.rb +24 -0
- data/examples/solitaire-cipher/lib/package.yml +106 -0
- data/examples/solitaire-cipher/test/tc_deck.rb +30 -0
- data/examples/solitaire-cipher/test/tc_key-stream.rb +19 -0
- data/examples/solitaire-cipher/test/tc_keying-algorithms.rb +31 -0
- data/examples/solitaire-cipher/test/tc_solitaire-cipher.rb +66 -0
- data/examples/solitaire-cipher/test/tc_unkeyed-algorithm.rb +17 -0
- data/examples/solitaire-cipher/test/tests.rb +2 -0
- data/lib/copland.rb +56 -0
- data/lib/copland/class-factory.rb +95 -0
- data/lib/copland/configuration-point.rb +38 -0
- data/lib/copland/configuration-point/common.rb +203 -0
- data/lib/copland/configuration-point/errors.rb +44 -0
- data/lib/copland/configuration-point/list.rb +59 -0
- data/lib/copland/configuration-point/map.rb +59 -0
- data/lib/copland/configuration/errors.rb +43 -0
- data/lib/copland/configuration/loader.rb +113 -0
- data/lib/copland/configuration/yaml/configuration-point.rb +87 -0
- data/lib/copland/configuration/yaml/implementor.rb +134 -0
- data/lib/copland/configuration/yaml/interceptor.rb +63 -0
- data/lib/copland/configuration/yaml/listener.rb +56 -0
- data/lib/copland/configuration/yaml/loader.rb +122 -0
- data/lib/copland/configuration/yaml/package.rb +125 -0
- data/lib/copland/configuration/yaml/parser.rb +71 -0
- data/lib/copland/configuration/yaml/schema.rb +165 -0
- data/lib/copland/configuration/yaml/service-point.rb +116 -0
- data/lib/copland/configuration/yaml/utils.rb +82 -0
- data/lib/copland/default-schema-processor.rb +144 -0
- data/lib/copland/errors.rb +82 -0
- data/lib/copland/event-producer.rb +95 -0
- data/lib/copland/impl/builder-factory.rb +112 -0
- data/lib/copland/impl/copland-config.yml +1 -0
- data/lib/copland/impl/include-exclude.rb +140 -0
- data/lib/copland/impl/logging-interceptor.rb +106 -0
- data/lib/copland/impl/package.yml +217 -0
- data/lib/copland/impl/startup.rb +116 -0
- data/lib/copland/impl/symbol-source-manager.rb +131 -0
- data/lib/copland/impl/symbol-source.rb +63 -0
- data/lib/copland/instantiator.rb +38 -0
- data/lib/copland/instantiator/abstract.rb +91 -0
- data/lib/copland/instantiator/complex.rb +96 -0
- data/lib/copland/instantiator/identity.rb +58 -0
- data/lib/copland/instantiator/simple.rb +68 -0
- data/lib/copland/interceptor-chain.rb +166 -0
- data/lib/copland/interceptor.rb +139 -0
- data/lib/copland/log-factory.rb +206 -0
- data/lib/copland/models.rb +39 -0
- data/lib/copland/models/abstract.rb +78 -0
- data/lib/copland/models/prototype-deferred.rb +58 -0
- data/lib/copland/models/prototype.rb +58 -0
- data/lib/copland/models/proxy.rb +100 -0
- data/lib/copland/models/singleton-deferred.rb +59 -0
- data/lib/copland/models/singleton.rb +77 -0
- data/lib/copland/models/threaded.rb +65 -0
- data/lib/copland/ordering.rb +123 -0
- data/lib/copland/package.rb +246 -0
- data/lib/copland/registry.rb +368 -0
- data/lib/copland/schema.rb +206 -0
- data/lib/copland/service-point.rb +282 -0
- data/lib/copland/utils.rb +221 -0
- data/lib/copland/version.rb +47 -0
- data/test/conf-test/list-bad-key.yml +30 -0
- data/test/conf-test/list-bad-missing.yml +28 -0
- data/test/conf-test/list-bad-type.yml +28 -0
- data/test/conf-test/list-good.yml +29 -0
- data/test/conf-test/map-bad-key.yml +25 -0
- data/test/conf-test/map-bad-missing.yml +24 -0
- data/test/conf-test/map-bad-type.yml +23 -0
- data/test/conf-test/map-good.yml +25 -0
- data/test/configuration-point/package.yml +52 -0
- data/test/configuration/yaml/config/copland-config.yml +2 -0
- data/test/configuration/yaml/config/module.yml +2 -0
- data/test/configuration/yaml/config/subdir/copland-config.yml +2 -0
- data/test/configuration/yaml/config/subdir/package.yml +4 -0
- data/test/configuration/yaml/defaults/package.yml +5 -0
- data/test/configuration/yaml/defaults/subdir/package.yml +4 -0
- data/test/configuration/yaml/tc_config-loader.rb +86 -0
- data/test/configuration/yaml/tc_configuration-point-processor.rb +134 -0
- data/test/configuration/yaml/tc_implementor-processor.rb +104 -0
- data/test/configuration/yaml/tc_interceptor-processor.rb +85 -0
- data/test/configuration/yaml/tc_listener-processor.rb +69 -0
- data/test/configuration/yaml/tc_loader.rb +74 -0
- data/test/configuration/yaml/tc_package-processor.rb +120 -0
- data/test/configuration/yaml/tc_parser.rb +94 -0
- data/test/configuration/yaml/tc_schema-parser.rb +160 -0
- data/test/configuration/yaml/tc_service-point-processor.rb +104 -0
- data/test/configuration/yaml/tc_type-validator.rb +90 -0
- data/test/custom-logger.yml +3 -0
- data/test/impl/logging/package.yml +44 -0
- data/test/impl/logging/services.rb +84 -0
- data/test/impl/startup/package.yml +46 -0
- data/test/impl/startup/services.rb +47 -0
- data/test/impl/symbols/package.yml +24 -0
- data/test/impl/symbols/services.rb +38 -0
- data/test/impl/tc_builder-factory.rb +173 -0
- data/test/impl/tc_logging-interceptor.rb +148 -0
- data/test/impl/tc_startup.rb +59 -0
- data/test/impl/tc_symbol-sources.rb +61 -0
- data/test/logger.yml +6 -0
- data/test/mock.rb +201 -0
- data/test/schema/bad-package.yml +65 -0
- data/test/schema/package.yml +102 -0
- data/test/schema/services.rb +5 -0
- data/test/services/package.yml +79 -0
- data/test/services/simple.rb +87 -0
- data/test/tc_class-factory.rb +93 -0
- data/test/tc_complex-instantiator.rb +107 -0
- data/test/tc_configuration-point-contrib.rb +74 -0
- data/test/tc_configuration-point-schema.rb +122 -0
- data/test/tc_configuration-point.rb +91 -0
- data/test/tc_default-schema-processor.rb +297 -0
- data/test/tc_identity-instantiator.rb +61 -0
- data/test/tc_interceptors.rb +84 -0
- data/test/tc_logger.rb +131 -0
- data/test/tc_models.rb +176 -0
- data/test/tc_package.rb +165 -0
- data/test/tc_proxy.rb +65 -0
- data/test/tc_registry.rb +141 -0
- data/test/tc_schema.rb +78 -0
- data/test/tc_service-point.rb +178 -0
- data/test/tc_service.rb +70 -0
- data/test/tc_simple-instantiator.rb +61 -0
- data/test/tests.rb +93 -0
- data/tutorial/01/main.rb +7 -0
- data/tutorial/01/package.yml +8 -0
- data/tutorial/01/tutorial.rb +7 -0
- data/tutorial/02/main.rb +10 -0
- data/tutorial/02/package.yml +27 -0
- data/tutorial/02/tutorial.rb +46 -0
- data/tutorial/03/main.rb +24 -0
- data/tutorial/03/package.yml +29 -0
- data/tutorial/03/tutorial.rb +48 -0
- data/tutorial/04/main.rb +24 -0
- data/tutorial/04/package.yml +35 -0
- data/tutorial/04/tutorial.rb +48 -0
- data/tutorial/05/functions/package.yml +16 -0
- data/tutorial/05/functions/services.rb +15 -0
- data/tutorial/05/main.rb +10 -0
- data/tutorial/05/package.yml +35 -0
- data/tutorial/05/tutorial.rb +53 -0
- 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
|