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,122 @@
|
|
|
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 'yaml'
|
|
35
|
+
require 'copland/configuration/yaml/parser'
|
|
36
|
+
|
|
37
|
+
module Copland
|
|
38
|
+
module Configuration
|
|
39
|
+
module YAML
|
|
40
|
+
|
|
41
|
+
# This is a visitor used during the initialization of a Registry. The
|
|
42
|
+
# Copland::Configuration::Loader class is the driver of the
|
|
43
|
+
# initialization process, and it delegates to visitors. This particular
|
|
44
|
+
# visitor looks for and processes YAML files that describe packages.
|
|
45
|
+
class Loader
|
|
46
|
+
|
|
47
|
+
# This is the name of the "configuration" yaml file, which allows
|
|
48
|
+
# parent directories to change certain properties of the processor when
|
|
49
|
+
# processing their children directories.
|
|
50
|
+
DEFAULT_YAML_CONFIG_FILE = "copland-config.yml"
|
|
51
|
+
|
|
52
|
+
# This is the default name of the package descriptor file.
|
|
53
|
+
DEFAULT_YAML_PACKAGE_FILE = "package.yml"
|
|
54
|
+
|
|
55
|
+
# Create a new YAML::Loader visitor object that feeds into the given
|
|
56
|
+
# Registry instance.
|
|
57
|
+
def initialize( registry, loader )
|
|
58
|
+
@parser = Parser.new( registry, loader )
|
|
59
|
+
@registry = registry
|
|
60
|
+
@visited = Hash.new
|
|
61
|
+
end
|
|
62
|
+
|
|
63
|
+
# This is invoked by the driver when a new directory needs to be
|
|
64
|
+
# visited. The options hash is returned, possibly modified.
|
|
65
|
+
def process_dir( directory, options )
|
|
66
|
+
options_filename = File.join( directory,
|
|
67
|
+
options[ :yaml_options_file ] ||
|
|
68
|
+
DEFAULT_YAML_CONFIG_FILE )
|
|
69
|
+
|
|
70
|
+
if File.exist?( options_filename )
|
|
71
|
+
options = parse_options_file( options_filename, options )
|
|
72
|
+
end
|
|
73
|
+
|
|
74
|
+
package_filename = File.join( directory,
|
|
75
|
+
options[ :yaml_package_file ] ||
|
|
76
|
+
DEFAULT_YAML_PACKAGE_FILE )
|
|
77
|
+
|
|
78
|
+
if !@visited[ package_filename ] && File.exist?( package_filename )
|
|
79
|
+
@visited[ package_filename ] = true
|
|
80
|
+
parse_package_file( package_filename, options )
|
|
81
|
+
end
|
|
82
|
+
|
|
83
|
+
return options
|
|
84
|
+
end
|
|
85
|
+
|
|
86
|
+
# Finalizes this visitor. This simply calls Registry#fixate!.
|
|
87
|
+
def finalize!
|
|
88
|
+
@registry.fixate! unless @registry.fixated?
|
|
89
|
+
end
|
|
90
|
+
|
|
91
|
+
# Parses a YAML-formated options file. The options hash is
|
|
92
|
+
# duplicated and returned, possibly modified.
|
|
93
|
+
def parse_options_file( options_filename, options )
|
|
94
|
+
yaml = ::YAML::load( File::read( options_filename ) )
|
|
95
|
+
|
|
96
|
+
options = options.dup
|
|
97
|
+
yaml.each_pair do |key, value|
|
|
98
|
+
case key
|
|
99
|
+
when "yaml-package-file"
|
|
100
|
+
options[ :yaml_package_file ] = value
|
|
101
|
+
when "default-service-model"
|
|
102
|
+
options[ :default_service_model ] = value
|
|
103
|
+
else
|
|
104
|
+
warn "invalid Copland configuration option in #{options_filename}: #{key}"
|
|
105
|
+
end
|
|
106
|
+
end
|
|
107
|
+
|
|
108
|
+
return options
|
|
109
|
+
end
|
|
110
|
+
private :parse_options_file
|
|
111
|
+
|
|
112
|
+
# Parses a YAML-formatted packag descriptor file. This delegates
|
|
113
|
+
# to Copland::Configuration::YAML::Parser#parse_file.
|
|
114
|
+
def parse_package_file( package_filename, options )
|
|
115
|
+
@parser.parse_file( package_filename, options )
|
|
116
|
+
end
|
|
117
|
+
private :parse_package_file
|
|
118
|
+
end
|
|
119
|
+
|
|
120
|
+
end
|
|
121
|
+
end
|
|
122
|
+
end
|
|
@@ -0,0 +1,125 @@
|
|
|
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/package'
|
|
36
|
+
require 'copland/configuration/yaml/service-point'
|
|
37
|
+
require 'copland/configuration/yaml/configuration-point'
|
|
38
|
+
require 'copland/configuration/yaml/utils'
|
|
39
|
+
|
|
40
|
+
module Copland
|
|
41
|
+
module Configuration
|
|
42
|
+
module YAML
|
|
43
|
+
|
|
44
|
+
# This delegate is responsible for processing a package descriptor
|
|
45
|
+
# into a Registry instance.
|
|
46
|
+
class PackageProcessor
|
|
47
|
+
include TypeValidator
|
|
48
|
+
|
|
49
|
+
# Creates a new PackageProcessor that feeds into the given Registry
|
|
50
|
+
# instance.
|
|
51
|
+
def initialize( registry, loader )
|
|
52
|
+
@registry = registry
|
|
53
|
+
@loader = loader
|
|
54
|
+
end
|
|
55
|
+
|
|
56
|
+
# The list of recognized key values in a package descriptor.
|
|
57
|
+
VALID_KEYS = [ "id", "description", "service-points",
|
|
58
|
+
"configuration-points", "contributions", "require" ]
|
|
59
|
+
|
|
60
|
+
# The list of required key values in a package descriptor.
|
|
61
|
+
REQUIRED_KEYS = [ "id" ]
|
|
62
|
+
|
|
63
|
+
# Process the package descriptor +doc+ into the active Registry
|
|
64
|
+
# instance. The +options+ parameter is used when processing service
|
|
65
|
+
# and configuration points within this package descriptor.
|
|
66
|
+
# The new Package instance is added directly to the registry.
|
|
67
|
+
def process( doc, options={} )
|
|
68
|
+
ensure_element_type "package definition", doc, Hash
|
|
69
|
+
validate_elements doc
|
|
70
|
+
|
|
71
|
+
package = Package.new( @registry, doc["id"] )
|
|
72
|
+
@registry.add_package package
|
|
73
|
+
|
|
74
|
+
doc.each_pair do |key, value|
|
|
75
|
+
case key
|
|
76
|
+
when "id"
|
|
77
|
+
# already discovered and handled above
|
|
78
|
+
|
|
79
|
+
when "description"
|
|
80
|
+
package.description = value
|
|
81
|
+
|
|
82
|
+
when "service-points"
|
|
83
|
+
ensure_element_type "service-points", value, Hash
|
|
84
|
+
processor = ServicePointProcessor.new( package, options )
|
|
85
|
+
|
|
86
|
+
value.each_pair do |name, definition|
|
|
87
|
+
point = processor.process name, definition
|
|
88
|
+
package.add_service_point point
|
|
89
|
+
end
|
|
90
|
+
|
|
91
|
+
when "configuration-points"
|
|
92
|
+
ensure_element_type "configuration-points", value, Hash
|
|
93
|
+
processor = ConfigurationPointProcessor.new( package, options )
|
|
94
|
+
|
|
95
|
+
value.each_pair do |name, definition|
|
|
96
|
+
point = processor.process name, definition
|
|
97
|
+
package.add_configuration_point point
|
|
98
|
+
end
|
|
99
|
+
|
|
100
|
+
when "contributions"
|
|
101
|
+
ensure_element_type "contributions", value, Hash
|
|
102
|
+
|
|
103
|
+
value.each_pair do |name, value|
|
|
104
|
+
package.add_pending_contribution name, value
|
|
105
|
+
end
|
|
106
|
+
|
|
107
|
+
when "require"
|
|
108
|
+
ensure_element_type "require", value, Array
|
|
109
|
+
value.each do |name|
|
|
110
|
+
@loader.use_library name
|
|
111
|
+
end
|
|
112
|
+
|
|
113
|
+
else
|
|
114
|
+
raise CoplandBug,
|
|
115
|
+
"[BUG] invalid element discovered too late:" +
|
|
116
|
+
key.inspect
|
|
117
|
+
end
|
|
118
|
+
end
|
|
119
|
+
end
|
|
120
|
+
|
|
121
|
+
end
|
|
122
|
+
|
|
123
|
+
end
|
|
124
|
+
end
|
|
125
|
+
end
|
|
@@ -0,0 +1,71 @@
|
|
|
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 'yaml'
|
|
35
|
+
require 'copland/configuration/yaml/package'
|
|
36
|
+
|
|
37
|
+
module Copland
|
|
38
|
+
module Configuration
|
|
39
|
+
module YAML
|
|
40
|
+
|
|
41
|
+
# Manages the parsing and processing of YAML input into package
|
|
42
|
+
# instances that can be added to a Registry.
|
|
43
|
+
class Parser
|
|
44
|
+
|
|
45
|
+
# Create a new parser that will feed into the given Registry
|
|
46
|
+
# instance.
|
|
47
|
+
def initialize( registry, loader )
|
|
48
|
+
@registry = registry
|
|
49
|
+
@package = PackageProcessor.new( @registry, loader )
|
|
50
|
+
end
|
|
51
|
+
|
|
52
|
+
# Parse the file with the given name. The options Hash is optional,
|
|
53
|
+
# and specifies values that determine how the parse occurs.
|
|
54
|
+
def parse_file( filename, options={} )
|
|
55
|
+
parse( File.read( filename ) )
|
|
56
|
+
end
|
|
57
|
+
|
|
58
|
+
# Parse the given +io+ parameter (which must be either an +IO+ object
|
|
59
|
+
# or a +String+). The options are passed through to the
|
|
60
|
+
# PackageProcessor instance.
|
|
61
|
+
def parse( io, options={} )
|
|
62
|
+
::YAML.load_documents( io ) do |doc|
|
|
63
|
+
@package.process doc, options
|
|
64
|
+
end
|
|
65
|
+
end
|
|
66
|
+
|
|
67
|
+
end
|
|
68
|
+
|
|
69
|
+
end
|
|
70
|
+
end
|
|
71
|
+
end
|
|
@@ -0,0 +1,165 @@
|
|
|
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/configuration/yaml/utils'
|
|
36
|
+
require 'copland/schema'
|
|
37
|
+
|
|
38
|
+
module Copland
|
|
39
|
+
module Configuration
|
|
40
|
+
module YAML
|
|
41
|
+
|
|
42
|
+
# This is the delegate assigned with the responsibility for processing
|
|
43
|
+
# schema elements.
|
|
44
|
+
class SchemaParser
|
|
45
|
+
include TypeValidator
|
|
46
|
+
|
|
47
|
+
# This is the list of keys recognized by this processor.
|
|
48
|
+
VALID_KEYS = [ "name", "class", "description", "definition", "type",
|
|
49
|
+
"required", "extend" ]
|
|
50
|
+
|
|
51
|
+
# This is the list of keys required by this processor.
|
|
52
|
+
REQUIRED_KEYS = []
|
|
53
|
+
|
|
54
|
+
# This is invoked when a schema element has been detected and needs to
|
|
55
|
+
# be processed. The given point is either a configuration point or a
|
|
56
|
+
# service point. The schema is returned.
|
|
57
|
+
def process( point, schema )
|
|
58
|
+
process_schema point, schema, "schema://"
|
|
59
|
+
end
|
|
60
|
+
|
|
61
|
+
# This is invoked recursively to process each node of the schema. If
|
|
62
|
+
# the schema is a string, then it is interpreted to be the name of
|
|
63
|
+
# an external schema.
|
|
64
|
+
def process_schema( point, schema, path )
|
|
65
|
+
return schema if schema.is_a?( String )
|
|
66
|
+
|
|
67
|
+
ensure_element_type path, schema, Hash
|
|
68
|
+
validate_elements schema, path
|
|
69
|
+
|
|
70
|
+
name = schema[ 'name' ]
|
|
71
|
+
processor = schema[ 'class' ]
|
|
72
|
+
required = schema[ 'required' ]
|
|
73
|
+
description = schema[ 'description' ]
|
|
74
|
+
definition = schema[ 'definition' ]
|
|
75
|
+
type = schema[ 'type' ]
|
|
76
|
+
extend = schema[ 'extend' ]
|
|
77
|
+
|
|
78
|
+
ensure_element_type( path + "/name", name, String ) if name
|
|
79
|
+
ensure_element_type( path + "/class", processor,
|
|
80
|
+
String ) if processor
|
|
81
|
+
ensure_element_type( path + "/description", description,
|
|
82
|
+
String ) if description
|
|
83
|
+
ensure_element_type( path + "/definition", definition,
|
|
84
|
+
Hash ) if definition
|
|
85
|
+
ensure_element_type( path + "/type", type,
|
|
86
|
+
String ) if type
|
|
87
|
+
ensure_element_type( path + "/extend", extend,
|
|
88
|
+
String ) if extend
|
|
89
|
+
|
|
90
|
+
unless [ nil, true, false ].include?( required )
|
|
91
|
+
raise ParserError,
|
|
92
|
+
"expected 'true' or 'false' value for #{path}/required, " +
|
|
93
|
+
"but got #{required.inspect}"
|
|
94
|
+
end
|
|
95
|
+
|
|
96
|
+
definition = process_definition( point, definition,
|
|
97
|
+
path + "/definition" )
|
|
98
|
+
type = process_type( definition, schema[ 'type' ], path + "/type" )
|
|
99
|
+
|
|
100
|
+
node = Schema.new( name,
|
|
101
|
+
processor,
|
|
102
|
+
description,
|
|
103
|
+
required,
|
|
104
|
+
type,
|
|
105
|
+
definition,
|
|
106
|
+
extend )
|
|
107
|
+
|
|
108
|
+
point.owner.add_schema node if node.name
|
|
109
|
+
node.owner = point.owner
|
|
110
|
+
|
|
111
|
+
return node
|
|
112
|
+
end
|
|
113
|
+
private :process_schema
|
|
114
|
+
|
|
115
|
+
# Processes the 'definition' portion of a schema.
|
|
116
|
+
def process_definition( point, definition, path )
|
|
117
|
+
return definition if definition.nil?
|
|
118
|
+
|
|
119
|
+
new_hash = Hash.new
|
|
120
|
+
definition.each_pair do |key, value|
|
|
121
|
+
new_hash[ key ] = process_schema( point, value,
|
|
122
|
+
path + "/" + key )
|
|
123
|
+
end
|
|
124
|
+
|
|
125
|
+
return new_hash
|
|
126
|
+
end
|
|
127
|
+
private :process_definition
|
|
128
|
+
|
|
129
|
+
# Processes the 'type' portion of a schema. If the type is invalid, or
|
|
130
|
+
# if it conflicts with the type of the definition, then an error is
|
|
131
|
+
# raised.
|
|
132
|
+
def process_type( definition, value, path )
|
|
133
|
+
if !value.nil? && value.downcase != "array" && !definition.nil?
|
|
134
|
+
raise ParserError,
|
|
135
|
+
"type must be 'array' or omitted when a subschema definition " +
|
|
136
|
+
"is provided"
|
|
137
|
+
end
|
|
138
|
+
|
|
139
|
+
value = "any" if value.nil? && definition.nil?
|
|
140
|
+
return value unless value
|
|
141
|
+
|
|
142
|
+
value.downcase!
|
|
143
|
+
|
|
144
|
+
[ "any",
|
|
145
|
+
"boolean",
|
|
146
|
+
"integer",
|
|
147
|
+
"real",
|
|
148
|
+
"service",
|
|
149
|
+
"log",
|
|
150
|
+
"configuration",
|
|
151
|
+
"string",
|
|
152
|
+
"hash",
|
|
153
|
+
"array" ].include?( value ) or
|
|
154
|
+
raise ParserError,
|
|
155
|
+
"invalid type #{value.inspect} at #{path}"
|
|
156
|
+
|
|
157
|
+
return value
|
|
158
|
+
end
|
|
159
|
+
private :process_type
|
|
160
|
+
|
|
161
|
+
end
|
|
162
|
+
|
|
163
|
+
end
|
|
164
|
+
end
|
|
165
|
+
end
|