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,112 @@
|
|
|
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
|
+
require 'singleton'
|
|
37
|
+
|
|
38
|
+
module Copland
|
|
39
|
+
module Implementation
|
|
40
|
+
|
|
41
|
+
# This is the implementation of the BuilderFactory service. It constructs
|
|
42
|
+
# service implementations and wires services together automatically, as
|
|
43
|
+
# determined by their dependencies in the configuration files.
|
|
44
|
+
class BuilderFactory
|
|
45
|
+
|
|
46
|
+
# This is the list of patterns that are recognized as "setter" methods.
|
|
47
|
+
# These are used when determining how to set properties.
|
|
48
|
+
SETTERS = [ "%s=", "set_%s" ]
|
|
49
|
+
|
|
50
|
+
# This is the factory method used to construct new services. Based
|
|
51
|
+
# on the +parms+ argument, the new service is instantiated, initialized,
|
|
52
|
+
# and returned.
|
|
53
|
+
def create_instance( point, parms )
|
|
54
|
+
ensure_log( point )
|
|
55
|
+
|
|
56
|
+
klass = Copland::get_class( parms['class'] )
|
|
57
|
+
|
|
58
|
+
args = ( parms['parameters'] || [] )
|
|
59
|
+
|
|
60
|
+
if klass.include?( Singleton )
|
|
61
|
+
if args.length > 0
|
|
62
|
+
raise CoplandException,
|
|
63
|
+
"Singleton instances cannot have constructor parameters"
|
|
64
|
+
end
|
|
65
|
+
obj = klass.instance
|
|
66
|
+
else
|
|
67
|
+
obj = klass.new( *args )
|
|
68
|
+
end
|
|
69
|
+
|
|
70
|
+
if parms['properties']
|
|
71
|
+
parms['properties'].each_pair do |name, value|
|
|
72
|
+
catch( :property_set ) do
|
|
73
|
+
SETTERS.each do |pattern|
|
|
74
|
+
setter = pattern % name
|
|
75
|
+
if obj.respond_to?( setter )
|
|
76
|
+
obj.__send__( setter, value )
|
|
77
|
+
throw :property_set
|
|
78
|
+
end
|
|
79
|
+
end
|
|
80
|
+
|
|
81
|
+
@log.warn "no setter for #{name.inspect} found on " +
|
|
82
|
+
"#{klass} (#{point.full_name})"
|
|
83
|
+
obj.instance_variable_set "@#{name}".intern, value
|
|
84
|
+
end
|
|
85
|
+
end
|
|
86
|
+
end
|
|
87
|
+
|
|
88
|
+
if parms['invoke']
|
|
89
|
+
parms['invoke'].each_pair do |name, value|
|
|
90
|
+
obj.__send__( name, *( value || [] ) )
|
|
91
|
+
end
|
|
92
|
+
end
|
|
93
|
+
|
|
94
|
+
initialize_method = parms[ 'initialize-method' ] ||
|
|
95
|
+
"initialize_service"
|
|
96
|
+
|
|
97
|
+
if obj.respond_to?( initialize_method )
|
|
98
|
+
obj.__send__( initialize_method )
|
|
99
|
+
end
|
|
100
|
+
|
|
101
|
+
return obj
|
|
102
|
+
end
|
|
103
|
+
|
|
104
|
+
def ensure_log( point )
|
|
105
|
+
return if @log
|
|
106
|
+
@log = point.owner.registry.logs.get( "copland.BuilderFactory" )
|
|
107
|
+
end
|
|
108
|
+
|
|
109
|
+
end
|
|
110
|
+
|
|
111
|
+
end
|
|
112
|
+
end
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
yaml-package-file: package.yml
|
|
@@ -0,0 +1,140 @@
|
|
|
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
|
+
|
|
36
|
+
module Copland
|
|
37
|
+
module Implementation
|
|
38
|
+
|
|
39
|
+
# A simple structure for representing a single include/exclude pattern.
|
|
40
|
+
IncludeExcludePattern = Struct.new( :name, :comparitor, :arity )
|
|
41
|
+
|
|
42
|
+
# A module encapsulating the factory end of a service with include/exclude
|
|
43
|
+
# functionality. Such functionality involves a schema with include and
|
|
44
|
+
# exclude elements, each of which must be an array of method names that
|
|
45
|
+
# should be included or excluded. See the IncludeExclude module for more
|
|
46
|
+
# info.
|
|
47
|
+
module IncludeExcludeFactory
|
|
48
|
+
|
|
49
|
+
# This is the regular expression for parsing elements in an include or
|
|
50
|
+
# exclude array.
|
|
51
|
+
PATTERN = /^
|
|
52
|
+
(.*?) (?# this matches the method name pattern)
|
|
53
|
+
(?: (?# begin optional arity section)
|
|
54
|
+
\( (?# begin parenthesized section)
|
|
55
|
+
([<=>])? (?# optional comparator character)
|
|
56
|
+
(\d+) (?# arity specification)
|
|
57
|
+
\) (?# end parenthesized section)
|
|
58
|
+
)? (?# end optional arity section)
|
|
59
|
+
$/x
|
|
60
|
+
|
|
61
|
+
# This is a utility function for converting an array of strings
|
|
62
|
+
# representing method name patterns, into an array of
|
|
63
|
+
# IncludeExcludePattern instances.
|
|
64
|
+
def build_map( array )
|
|
65
|
+
( array || [] ).map do |pattern|
|
|
66
|
+
unless pattern =~ PATTERN
|
|
67
|
+
raise CoplandException,
|
|
68
|
+
"invalid logging interceptor method pattern: #{pattern.inspect}"
|
|
69
|
+
end
|
|
70
|
+
|
|
71
|
+
name = $1
|
|
72
|
+
comparitor = $2
|
|
73
|
+
arity = ( $3 || -1 ).to_i
|
|
74
|
+
|
|
75
|
+
comparitor ||= ">" if arity < 0
|
|
76
|
+
comparitor ||= "="
|
|
77
|
+
|
|
78
|
+
IncludeExcludePattern.new( Regexp.new( "^" + name + "$" ),
|
|
79
|
+
comparitor,
|
|
80
|
+
arity )
|
|
81
|
+
end
|
|
82
|
+
end
|
|
83
|
+
|
|
84
|
+
end
|
|
85
|
+
|
|
86
|
+
# This module encapsulates the service end of a service with
|
|
87
|
+
# include/exclude functionality.
|
|
88
|
+
module IncludeExclude
|
|
89
|
+
|
|
90
|
+
# Returns +false+ if the given context object "matches" any of the
|
|
91
|
+
# exclude patterns without matching any of the include patterns.
|
|
92
|
+
# The context object must respond to the <tt>:sym</tt> and
|
|
93
|
+
# <tt>:args</tt> messages, where <tt>:sym</tt> is a symbol identifying
|
|
94
|
+
# the method being matched, and <tt>:args</tt> is an array of
|
|
95
|
+
# arguments that will be sent to that method.
|
|
96
|
+
def match( context )
|
|
97
|
+
match = true
|
|
98
|
+
|
|
99
|
+
@excludes.each do |pattern|
|
|
100
|
+
if match_pattern( context, pattern )
|
|
101
|
+
match = false
|
|
102
|
+
break
|
|
103
|
+
end
|
|
104
|
+
end
|
|
105
|
+
|
|
106
|
+
unless match
|
|
107
|
+
@includes.each do |pattern|
|
|
108
|
+
if match_pattern( context, pattern )
|
|
109
|
+
match = true
|
|
110
|
+
break
|
|
111
|
+
end
|
|
112
|
+
end
|
|
113
|
+
end
|
|
114
|
+
|
|
115
|
+
return match
|
|
116
|
+
end
|
|
117
|
+
private :match
|
|
118
|
+
|
|
119
|
+
# Returns +true+ if the given context matches the given pattern, and
|
|
120
|
+
# +false+ otherwise.
|
|
121
|
+
def match_pattern( context, pattern )
|
|
122
|
+
if context.sym.to_s =~ pattern.name
|
|
123
|
+
case pattern.comparitor
|
|
124
|
+
when "<"
|
|
125
|
+
return context.args.length < pattern.arity
|
|
126
|
+
when ">"
|
|
127
|
+
return context.args.length > pattern.arity
|
|
128
|
+
when "="
|
|
129
|
+
return context.args.length == pattern.arity
|
|
130
|
+
end
|
|
131
|
+
end
|
|
132
|
+
|
|
133
|
+
return false
|
|
134
|
+
end
|
|
135
|
+
private :match_pattern
|
|
136
|
+
|
|
137
|
+
end
|
|
138
|
+
|
|
139
|
+
end
|
|
140
|
+
end
|
|
@@ -0,0 +1,106 @@
|
|
|
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/impl/include-exclude'
|
|
35
|
+
|
|
36
|
+
module Copland
|
|
37
|
+
module Implementation
|
|
38
|
+
|
|
39
|
+
# This is the implementation of the service factory that provides
|
|
40
|
+
# instances of logging interceptors. It includes the IncludeExcludeFactory
|
|
41
|
+
# functionality.
|
|
42
|
+
class LoggingInterceptorFactory
|
|
43
|
+
include IncludeExcludeFactory
|
|
44
|
+
|
|
45
|
+
# Returns a new LoggingInterceptor instance, initialized with the given
|
|
46
|
+
# parameters.
|
|
47
|
+
def create_instance( point, parms )
|
|
48
|
+
includes = build_map( parms[ "include" ] )
|
|
49
|
+
excludes = build_map( parms[ "exclude" ] )
|
|
50
|
+
|
|
51
|
+
return LoggingInterceptor.new( point, includes, excludes )
|
|
52
|
+
end
|
|
53
|
+
|
|
54
|
+
end
|
|
55
|
+
|
|
56
|
+
# A LoggingInterceptor is an interceptor object that logs method
|
|
57
|
+
# invocations and exceptions. It includes the IncludeExclude functionality.
|
|
58
|
+
class LoggingInterceptor
|
|
59
|
+
include IncludeExclude
|
|
60
|
+
|
|
61
|
+
# The log used by this interceptor to log messages.
|
|
62
|
+
attr_reader :log
|
|
63
|
+
|
|
64
|
+
# The array of patterns of methods to log.
|
|
65
|
+
attr_reader :includes
|
|
66
|
+
|
|
67
|
+
# The array of patterns of methods to _not_ log.
|
|
68
|
+
attr_reader :excludes
|
|
69
|
+
|
|
70
|
+
# Create a new LoggingInterceptor for the given service point, with the
|
|
71
|
+
# given list of include and exclude patterns. The logger object will be
|
|
72
|
+
# created as well, named with the service point's full name.
|
|
73
|
+
def initialize( point, includes, excludes )
|
|
74
|
+
@log = point.owner.registry.logs.get( point.full_name )
|
|
75
|
+
@includes = includes
|
|
76
|
+
@excludes = excludes
|
|
77
|
+
end
|
|
78
|
+
|
|
79
|
+
# Processes a method invocation context. If the current log has debugging
|
|
80
|
+
# activated, and the requested method is not excluded by the
|
|
81
|
+
# interceptor's exclude and include patterns, then a message will be
|
|
82
|
+
# written for the method's invocation, its return code, and any exception
|
|
83
|
+
# that is thrown.
|
|
84
|
+
def process( chain, context )
|
|
85
|
+
if @log.debug? && match( context )
|
|
86
|
+
args = context.args.map { |i| i.inspect } .join( ', ' )
|
|
87
|
+
@log.debug "#{context.sym}( #{args} )"
|
|
88
|
+
|
|
89
|
+
begin
|
|
90
|
+
result = chain.process_next( context )
|
|
91
|
+
rescue Exception => e
|
|
92
|
+
@log.debug "#{context.sym} raised #{e.message.inspect} (#{e.class})"
|
|
93
|
+
raise
|
|
94
|
+
end
|
|
95
|
+
|
|
96
|
+
@log.debug "#{context.sym} => #{result.inspect}"
|
|
97
|
+
return result
|
|
98
|
+
else
|
|
99
|
+
return chain.process_next( context )
|
|
100
|
+
end
|
|
101
|
+
end
|
|
102
|
+
|
|
103
|
+
end
|
|
104
|
+
|
|
105
|
+
end
|
|
106
|
+
end
|
|
@@ -0,0 +1,217 @@
|
|
|
1
|
+
---
|
|
2
|
+
id: copland
|
|
3
|
+
description: >-
|
|
4
|
+
The copland package is the standard package defined by the Copland
|
|
5
|
+
distribution. It includes the core services and interceptors, such as the
|
|
6
|
+
BuilderFactory and the LoggingInterceptor.
|
|
7
|
+
|
|
8
|
+
configuration-points:
|
|
9
|
+
|
|
10
|
+
SymbolSources:
|
|
11
|
+
type: list
|
|
12
|
+
description: >-
|
|
13
|
+
This is a list of services or objects that can be queried to provide
|
|
14
|
+
symbols. Packages may contribute additional symbol sources to this
|
|
15
|
+
list. Additionally, the sources may be given an explicit order in
|
|
16
|
+
which they will be queried for symbols, allowing some sources to take
|
|
17
|
+
precendence over others.
|
|
18
|
+
schema:
|
|
19
|
+
definition:
|
|
20
|
+
source:
|
|
21
|
+
type: any
|
|
22
|
+
required: true
|
|
23
|
+
description: >-
|
|
24
|
+
The implementor of the symbol source that is being contributed.
|
|
25
|
+
It must be the name of a class, or an instance of a service.
|
|
26
|
+
name:
|
|
27
|
+
type: string
|
|
28
|
+
description: >-
|
|
29
|
+
The name given to this symbol source. This allows it to be
|
|
30
|
+
referenced in other sources' before and after lists.
|
|
31
|
+
before:
|
|
32
|
+
type: array
|
|
33
|
+
description: >-
|
|
34
|
+
A list of symbol sources to be queried after this source.
|
|
35
|
+
after:
|
|
36
|
+
type: array
|
|
37
|
+
description: >-
|
|
38
|
+
A list of symbol sources to be queried before this source.
|
|
39
|
+
|
|
40
|
+
FactoryDefaults:
|
|
41
|
+
type: map
|
|
42
|
+
description: >-
|
|
43
|
+
This symbol source configuration point allows packages to define "factory
|
|
44
|
+
defaults" for various substitution symbols that they export.
|
|
45
|
+
|
|
46
|
+
ApplicationDefaults:
|
|
47
|
+
type: map
|
|
48
|
+
description: >-
|
|
49
|
+
This symbol source configuration point allows packages to override
|
|
50
|
+
factory default values (see the FactoryDefaults configuration point).
|
|
51
|
+
|
|
52
|
+
Startup:
|
|
53
|
+
type: list
|
|
54
|
+
description: >-
|
|
55
|
+
This is the data source for the Startup service. This allows services
|
|
56
|
+
to register themselves to be automatically started when the registry
|
|
57
|
+
has finished initializing. Services may also register their preferred
|
|
58
|
+
ordering for startup.
|
|
59
|
+
schema:
|
|
60
|
+
name: ClientDefinition
|
|
61
|
+
definition:
|
|
62
|
+
service:
|
|
63
|
+
type: string
|
|
64
|
+
required: true
|
|
65
|
+
description: The (full) name of the client service.
|
|
66
|
+
enabled:
|
|
67
|
+
type: boolean
|
|
68
|
+
description: Whether or not the service should be notified.
|
|
69
|
+
before:
|
|
70
|
+
type: array
|
|
71
|
+
description: >-
|
|
72
|
+
A list of other service names that should be notified after this
|
|
73
|
+
service.
|
|
74
|
+
after:
|
|
75
|
+
type: array
|
|
76
|
+
description: >-
|
|
77
|
+
A list of other service names that should be notified before this
|
|
78
|
+
service.
|
|
79
|
+
|
|
80
|
+
service-points:
|
|
81
|
+
|
|
82
|
+
FactoryDefaults:
|
|
83
|
+
model: singleton
|
|
84
|
+
description: >-
|
|
85
|
+
The service point that provides access to the FactoryDefaults
|
|
86
|
+
configuration point.
|
|
87
|
+
implementor:
|
|
88
|
+
class: copland/impl/symbol-source/Copland::Implementation::SymbolSource
|
|
89
|
+
properties:
|
|
90
|
+
defaults: !!configuration FactoryDefaults
|
|
91
|
+
|
|
92
|
+
ApplicationDefaults:
|
|
93
|
+
model: singleton
|
|
94
|
+
description: >-
|
|
95
|
+
The service point that provides access to the ApplicationDefaults
|
|
96
|
+
configuration point.
|
|
97
|
+
implementor:
|
|
98
|
+
class: copland/impl/symbol-source/Copland::Implementation::SymbolSource
|
|
99
|
+
properties:
|
|
100
|
+
defaults: !!configuration ApplicationDefaults
|
|
101
|
+
|
|
102
|
+
SymbolSourceManager:
|
|
103
|
+
model: singleton
|
|
104
|
+
description: >-
|
|
105
|
+
The service that manages all contributed symbol sources, and which may be
|
|
106
|
+
queried to obtain values known by any of them.
|
|
107
|
+
implementor:
|
|
108
|
+
class: copland/impl/symbol-source-manager/Copland::Implementation::SymbolSourceManager
|
|
109
|
+
parameters:
|
|
110
|
+
- !!configuration SymbolSources
|
|
111
|
+
|
|
112
|
+
BuilderFactory:
|
|
113
|
+
implementor:
|
|
114
|
+
copland/impl/builder-factory/Copland::Implementation::BuilderFactory
|
|
115
|
+
model: singleton
|
|
116
|
+
description: >-
|
|
117
|
+
Used to construct a service from a class name and optional constructor
|
|
118
|
+
parameters and properties.
|
|
119
|
+
schema:
|
|
120
|
+
definition:
|
|
121
|
+
class:
|
|
122
|
+
required: true
|
|
123
|
+
type: string
|
|
124
|
+
description: >-
|
|
125
|
+
The path description of the class to instantiate. This takes the
|
|
126
|
+
form "path/to/file/Full::Class::Name". Then, "require" will be
|
|
127
|
+
invoked on the "path/to/file" portion, and the class itself will
|
|
128
|
+
then be resolved. If the class includes the Singleton module,
|
|
129
|
+
the singleton instance will be correctly resolved; in this case,
|
|
130
|
+
it is an error to specify construction parameters.
|
|
131
|
+
parameters:
|
|
132
|
+
type: array
|
|
133
|
+
description: >-
|
|
134
|
+
A list of values that should be passed (in order) to the
|
|
135
|
+
constructor of the class. It is illegal to specify this value if
|
|
136
|
+
the class includes the Singleton module.
|
|
137
|
+
properties:
|
|
138
|
+
type: hash
|
|
139
|
+
description: >-
|
|
140
|
+
A hash of property-name/value pairs that describe the properties
|
|
141
|
+
to set on the instantiated object. Assignment occurs as follows:
|
|
142
|
+
first, a setter is searched for, either "name=" or "set_name".
|
|
143
|
+
If one is found, it is used to set the property. If no such
|
|
144
|
+
setter exists, the property is set directly using
|
|
145
|
+
"instance_variable_set".
|
|
146
|
+
invoke:
|
|
147
|
+
type: hash
|
|
148
|
+
description: >-
|
|
149
|
+
A hash of method-name/parameter pairs, where the value of each
|
|
150
|
+
pair is an array of parameters to pass to the method. These
|
|
151
|
+
methods will be invoked in no particular order, after all
|
|
152
|
+
properties have been assigned.
|
|
153
|
+
initialize-method:
|
|
154
|
+
type: string
|
|
155
|
+
description: >-
|
|
156
|
+
This describes the name of the method to invoke when the service
|
|
157
|
+
has been completely instantiated (and all properties wired into
|
|
158
|
+
it). This defaults to "initialize_service". If the method does not
|
|
159
|
+
exist, then nothing is invoked.
|
|
160
|
+
|
|
161
|
+
LoggingInterceptor:
|
|
162
|
+
implementor:
|
|
163
|
+
copland/impl/logging-interceptor/Copland::Implementation::LoggingInterceptorFactory
|
|
164
|
+
description: >-
|
|
165
|
+
An interceptor that adds logging to a service. Log entries are created
|
|
166
|
+
for all method calls (on enter and exit) and for any raised exceptions.
|
|
167
|
+
By default, all methods implemented by the service are included for
|
|
168
|
+
logging, and may only be excluded by using the 'exclude' element.
|
|
169
|
+
Anything matching any of the exclusion patterns will not be logged,
|
|
170
|
+
unless it also matches an 'include' pattern.
|
|
171
|
+
model: singleton
|
|
172
|
+
schema:
|
|
173
|
+
name: IncludeExcludeSchema
|
|
174
|
+
description: >-
|
|
175
|
+
This is a schema that may be used by any service that wishes to
|
|
176
|
+
incorporate "include/exclude" functionality into itself.
|
|
177
|
+
definition:
|
|
178
|
+
include:
|
|
179
|
+
type: array
|
|
180
|
+
description: >-
|
|
181
|
+
A list of special expressions that define which methods are
|
|
182
|
+
included in the operation. These expressions take the format
|
|
183
|
+
"pattern" (where pattern in a regular expression that should
|
|
184
|
+
match the method's name), or "pattern(arity)", where arity is
|
|
185
|
+
either a positive integer (indicating that only methods
|
|
186
|
+
with that arity match), or a positive integer preceded by a
|
|
187
|
+
comparison operator (<, =, or >).
|
|
188
|
+
exclude:
|
|
189
|
+
type: array
|
|
190
|
+
description: >-
|
|
191
|
+
A list of special expressions that define which methods are
|
|
192
|
+
excluded from the operation. The format for these expressions
|
|
193
|
+
is described under the 'include' element.
|
|
194
|
+
|
|
195
|
+
Startup:
|
|
196
|
+
model: singleton
|
|
197
|
+
description: >-
|
|
198
|
+
This is a service that will be automatically instantiated when the
|
|
199
|
+
registry is initialized. Once invoked, it inspects the Startup
|
|
200
|
+
configuration point to determine which other services to load. These
|
|
201
|
+
clients will be ordered based on their 'before' and 'after'
|
|
202
|
+
preferences, and then all enabled services will be started.
|
|
203
|
+
implementor:
|
|
204
|
+
class: copland/impl/startup/Copland::Implementation::Startup
|
|
205
|
+
properties:
|
|
206
|
+
clients: !!configuration Startup
|
|
207
|
+
registry: !!service Registry
|
|
208
|
+
|
|
209
|
+
contributions:
|
|
210
|
+
|
|
211
|
+
SymbolSources:
|
|
212
|
+
- name: FactoryDefaults
|
|
213
|
+
source: !!service FactoryDefaults
|
|
214
|
+
after:
|
|
215
|
+
- ApplicationDefaults
|
|
216
|
+
- name: ApplicationDefaults
|
|
217
|
+
source: !!service ApplicationDefaults
|