copland 0.8.0
Sign up to get free protection for your applications and to get access to all the features.
- 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
|