copland 0.8.0 → 1.0.0
Sign up to get free protection for your applications and to get access to all the features.
- data/doc/manual-html/chapter-1.html +227 -36
- data/doc/manual-html/chapter-10.html +155 -82
- data/doc/manual-html/chapter-11.html +90 -267
- data/doc/manual-html/chapter-12.html +289 -71
- data/doc/manual-html/chapter-13.html +430 -0
- data/doc/manual-html/chapter-2.html +45 -21
- data/doc/manual-html/chapter-3.html +45 -21
- data/doc/manual-html/chapter-4.html +45 -21
- data/doc/manual-html/chapter-5.html +45 -21
- data/doc/manual-html/chapter-6.html +49 -21
- data/doc/manual-html/chapter-7.html +45 -21
- data/doc/manual-html/chapter-8.html +66 -26
- data/doc/manual-html/chapter-9.html +48 -24
- data/doc/manual-html/index.html +54 -22
- data/doc/manual-html/manual.css +12 -0
- data/doc/manual-html/tutorial-1.html +45 -21
- data/doc/manual-html/tutorial-2.html +45 -21
- data/doc/manual-html/tutorial-3.html +45 -21
- data/doc/manual-html/tutorial-4.html +45 -21
- data/doc/manual-html/tutorial-5.html +45 -21
- data/doc/manual/manual.css +12 -0
- data/doc/manual/manual.rb +1 -1
- data/doc/manual/manual.yml +426 -20
- data/doc/packages/copland.html +41 -9
- data/doc/packages/copland.lib.html +36 -8
- data/doc/packages/copland.remote.html +46 -10
- data/doc/packages/copland.webrick.html +16 -65
- data/doc/packages/index.html +1 -1
- data/doc/presentation/copland.mgp +1083 -0
- data/doc/presentation/to_html.rb +52 -0
- data/lib/copland/configuration-point/common.rb +32 -1
- data/lib/copland/configuration/yaml/service-point.rb +10 -1
- data/lib/copland/log-factory.rb +28 -12
- data/lib/copland/logger.rb +155 -0
- data/lib/copland/models/singleton.rb +8 -2
- data/lib/copland/package.rb +32 -14
- data/lib/copland/service-point.rb +7 -0
- data/lib/copland/thread.rb +104 -0
- data/lib/copland/utils.rb +10 -3
- data/lib/copland/version.rb +2 -2
- data/test/configuration/yaml/tc_service-point-processor.rb +8 -0
- data/test/custom-logger.yml +2 -1
- data/test/impl/tc_logging-interceptor.rb +12 -12
- data/test/logger.yml +1 -1
- data/test/mock.rb +2 -0
- data/test/tc_logger.rb +19 -6
- data/test/tc_package.rb +25 -0
- data/test/tc_queryable-mutex.rb +75 -0
- data/test/tc_registry.rb +8 -4
- metadata +9 -2
@@ -0,0 +1,52 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
require 'fileutils'
|
4
|
+
require 'redcloth'
|
5
|
+
|
6
|
+
$target_dir = "html"
|
7
|
+
$resolution = "800x600"
|
8
|
+
$presentation = "copland2.mgp"
|
9
|
+
$image_format = "png"
|
10
|
+
|
11
|
+
FileUtils.rm_rf $target_dir
|
12
|
+
FileUtils.mkdir_p $target_dir
|
13
|
+
system "mgp -g #{$resolution} -D #{$target_dir} -E #{$image_format} #{$presentation}"
|
14
|
+
|
15
|
+
puts "======================================================="
|
16
|
+
puts "inserting slide notes into generated HTML..."
|
17
|
+
|
18
|
+
content = File.read( $presentation )
|
19
|
+
pages = content.split( /%page/ ).map { |p| p.strip }
|
20
|
+
head = pages.shift
|
21
|
+
|
22
|
+
pages.each_with_index do |page, index|
|
23
|
+
if page =~ /^%%==*\n(.*)\n%%==*\n/m
|
24
|
+
note = $1.gsub( /^%% ?/, "" ).strip
|
25
|
+
|
26
|
+
if note.length > 0
|
27
|
+
slide_file = File.join( $target_dir, "mgp%05d.html" % (index+1) )
|
28
|
+
slide_html = File.read( slide_file )
|
29
|
+
|
30
|
+
note.gsub!( /(\S)\n([ \t]*\w)/, '\1 \2' )
|
31
|
+
|
32
|
+
if slide_html =~ /<IMG SRC=\"mgp.*png\".*><BR>/
|
33
|
+
before = $` + $&
|
34
|
+
after = $'
|
35
|
+
new_html = before + "\n" +
|
36
|
+
"<style type=\"text/css\">" +
|
37
|
+
"#notes h1 { font-size: large }\n" +
|
38
|
+
"#notes h2 { font-size: normal }\n" +
|
39
|
+
"#notes h3 { font-size: normal }\n" +
|
40
|
+
"</style>" +
|
41
|
+
"<h2>Slide Notes:</h2>" +
|
42
|
+
"<blockquote id=\"notes\">" +
|
43
|
+
RedCloth.new(note).to_html +
|
44
|
+
"</blockquote>" +
|
45
|
+
after
|
46
|
+
puts " writing slide #{index+1}"
|
47
|
+
File.open( slide_file, "w" ) { |file| file.write new_html }
|
48
|
+
end
|
49
|
+
end
|
50
|
+
end
|
51
|
+
end
|
52
|
+
puts "done!"
|
@@ -156,10 +156,11 @@ module Copland
|
|
156
156
|
# for this configuration point; or if no schema exists, run the
|
157
157
|
# values through the Copland::translate_values method.
|
158
158
|
def process_values( values )
|
159
|
+
Thread.current[:disable_symbol_substitution] = true
|
159
160
|
s = schema
|
160
161
|
contributor = contributor_of( values )
|
161
162
|
if s.respond_to?( :process )
|
162
|
-
if
|
163
|
+
if values.is_a?( Array )
|
163
164
|
values = values.map! { |value|
|
164
165
|
s.process( self, contributor, value )
|
165
166
|
}
|
@@ -172,7 +173,37 @@ module Copland
|
|
172
173
|
end
|
173
174
|
|
174
175
|
return values
|
176
|
+
ensure
|
177
|
+
Thread.current[:disable_symbol_substitution] = false
|
178
|
+
end
|
179
|
+
|
180
|
+
# Processes all substitution symbols in the values of this configuration
|
181
|
+
# point, in place. This has a guard to ensure that it is only executed
|
182
|
+
# once.
|
183
|
+
def substitute_symbols!
|
184
|
+
Thread.critical = true
|
185
|
+
return if @substitution_processed
|
186
|
+
@substitution_processed = true
|
187
|
+
substitute_symbols( self )
|
188
|
+
ensure
|
189
|
+
Thread.critical = false
|
190
|
+
end
|
191
|
+
|
192
|
+
# The recursive portion of the symbol substitution step. This looks for
|
193
|
+
# substitution symbols in all of the values of the configuration point,
|
194
|
+
# substituting them as they are found.
|
195
|
+
def substitute_symbols( value )
|
196
|
+
case value
|
197
|
+
when Hash
|
198
|
+
value.each_pair { |k,v| value[k] = substitute_symbols( v ) }
|
199
|
+
when Array
|
200
|
+
value.map! { |v| substitute_symbols( v ) }
|
201
|
+
when String
|
202
|
+
Copland::substitute_symbols( owner.registry, value )
|
203
|
+
end
|
204
|
+
value
|
175
205
|
end
|
206
|
+
private :substitute_symbols
|
176
207
|
|
177
208
|
# Returns false. Once a configuration point is fixated, it will include
|
178
209
|
# the Copland::ConfigurationPoint::ConfigurationPointFunctionality::Fixated
|
@@ -62,7 +62,8 @@ module Copland
|
|
62
62
|
|
63
63
|
# The list of valid keys that may exist on the input.
|
64
64
|
VALID_KEYS = [ "description", "model", "implementor",
|
65
|
-
"interceptors", "listen-to", "schema"
|
65
|
+
"interceptors", "listen-to", "schema",
|
66
|
+
"visibility" ]
|
66
67
|
|
67
68
|
# The list of required keys that must exist on the input.
|
68
69
|
REQUIRED_KEYS = [ "implementor" ]
|
@@ -101,6 +102,14 @@ module Copland
|
|
101
102
|
when "schema"
|
102
103
|
point.schema = @schema.process( point, value )
|
103
104
|
|
105
|
+
when "visibility"
|
106
|
+
point.visibility = case value.downcase
|
107
|
+
when "public" then :public
|
108
|
+
when "private" then :private
|
109
|
+
else raise ParserError,
|
110
|
+
"invalid visibility value #{value.inspect}"
|
111
|
+
end
|
112
|
+
|
104
113
|
else
|
105
114
|
raise CoplandBug, "[BUG] invalid key discovered too late: #{key.inspect}"
|
106
115
|
end
|
data/lib/copland/log-factory.rb
CHANGED
@@ -31,7 +31,7 @@
|
|
31
31
|
# =============================================================================
|
32
32
|
#++
|
33
33
|
|
34
|
-
require 'logger'
|
34
|
+
require 'copland/logger'
|
35
35
|
require 'thread'
|
36
36
|
require 'yaml'
|
37
37
|
|
@@ -51,6 +51,9 @@ module Copland
|
|
51
51
|
# The default name of the log file to write to.
|
52
52
|
DEFAULT_LOG_FILENAME = "./copland.log"
|
53
53
|
|
54
|
+
# The default format of the log messages (see Logger for more info)
|
55
|
+
DEFAULT_MESSAGE_FORMAT = "[%-5p] %d -- %C: %m"
|
56
|
+
|
54
57
|
# Translate names of levels to their actual values.
|
55
58
|
LEVEL_TRANSLATOR = {
|
56
59
|
"DEBUG" => Logger::DEBUG,
|
@@ -61,8 +64,11 @@ module Copland
|
|
61
64
|
"UNKNOWN" => Logger::UNKNOWN
|
62
65
|
}
|
63
66
|
|
64
|
-
# The default
|
65
|
-
attr_reader :
|
67
|
+
# The default date format string to use when logging.
|
68
|
+
attr_reader :default_date_format
|
69
|
+
|
70
|
+
# The default message format string to use when logging.
|
71
|
+
attr_reader :default_message_format
|
66
72
|
|
67
73
|
# The default log level to use for logs that are created.
|
68
74
|
attr_reader :default_level
|
@@ -82,11 +88,14 @@ module Copland
|
|
82
88
|
# rolled.
|
83
89
|
# * <tt>:roll_frequency</tt>: either 'daily', 'weekly', or 'monthly'.
|
84
90
|
# * <tt>:roll_size</tt>: the maximum size of a log file.
|
85
|
-
# * <tt>:
|
91
|
+
# * <tt>:default_date_format</tt>: the default date format string for the
|
92
|
+
# log.
|
93
|
+
# * <tt>:default_message_format</tt>: the default message format string for
|
94
|
+
# the log.
|
86
95
|
# * <tt>:default_level</tt>: the default log level for the log.
|
87
96
|
# * <tt>:levels</tt>: a hash of patterns that map to a hash of 'level'
|
88
|
-
# and '
|
89
|
-
# log whose name matches the key.
|
97
|
+
# 'date_format', and 'message_format' keys, specifying the log level,
|
98
|
+
# date format, and message format for any log whose name matches the key.
|
90
99
|
def initialize( opts={} )
|
91
100
|
opts[ :config_file ] ||= DEFAULT_CONFIG_FILE
|
92
101
|
read_config opts
|
@@ -102,10 +111,13 @@ module Copland
|
|
102
111
|
:shift_size => roll_size )
|
103
112
|
end
|
104
113
|
|
105
|
-
@
|
114
|
+
@default_date_format = opts[ :default_date_format ]
|
115
|
+
@default_message_format = opts[ :default_message_format ] ||
|
116
|
+
DEFAULT_MESSAGE_FORMAT
|
106
117
|
@default_level = opts[ :default_level ]
|
107
118
|
|
108
|
-
@levels = Hash.new "level" => nil, "format" => nil
|
119
|
+
@levels = Hash.new "level" => nil, "date-format" => nil,
|
120
|
+
"message-format" => nil
|
109
121
|
|
110
122
|
( opts[ :levels ] || Hash.new ).each_pair do |key, value|
|
111
123
|
key = Regexp.new( "^" + key.gsub( /\./, "\\." ).gsub( /\*/, ".*" ) )
|
@@ -125,7 +137,8 @@ module Copland
|
|
125
137
|
file = opts[ :config_file ]
|
126
138
|
if File.exist?( file ) && File.readable?( file )
|
127
139
|
config = YAML.load( File.read( file ) )
|
128
|
-
opts[ :
|
140
|
+
opts[ :default_date_format ] ||= config[ "default-date-format" ]
|
141
|
+
opts[ :default_message_format ] ||= config[ "default-message-format" ]
|
129
142
|
opts[ :default_level ] ||=
|
130
143
|
LEVEL_TRANSLATOR[ config[ "default-level" ] ] ||
|
131
144
|
config[ "default-level" ]
|
@@ -169,14 +182,17 @@ module Copland
|
|
169
182
|
definition = find_definition( name )
|
170
183
|
|
171
184
|
level = definition[ "level" ] || @default_level
|
172
|
-
|
185
|
+
date_format = definition[ "date-format" ] || @default_date_format
|
186
|
+
message_format = definition[ "message-format" ] ||
|
187
|
+
@default_message_format
|
173
188
|
|
174
189
|
level = LEVEL_TRANSLATOR[ level ] || level
|
175
190
|
|
176
|
-
logger = Logger.new( @device )
|
191
|
+
logger = Copland::Logger.new( @device )
|
177
192
|
logger.level = level if level
|
178
|
-
logger.datetime_format = format if format
|
179
193
|
logger.progname = name
|
194
|
+
logger.datetime_format = date_format if date_format
|
195
|
+
logger.message_format = message_format if message_format
|
180
196
|
|
181
197
|
@loggers[ name ] = logger
|
182
198
|
return logger
|
@@ -0,0 +1,155 @@
|
|
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 'logger'
|
35
|
+
require 'strscan'
|
36
|
+
require 'copland/errors'
|
37
|
+
|
38
|
+
module Copland
|
39
|
+
|
40
|
+
# A specialization of the standard Logger class that comes with Ruby. This
|
41
|
+
# provides the additional functionality of a fully-customizable message
|
42
|
+
# format, whereas the original only provided a customizable date format.
|
43
|
+
class Logger < ::Logger
|
44
|
+
|
45
|
+
# The brief name of this logger (derived from #progname).
|
46
|
+
attr_reader :name
|
47
|
+
|
48
|
+
# The format string for the message (+nil+ if the default should be used)
|
49
|
+
attr_reader :message_format
|
50
|
+
|
51
|
+
# The map of specifier options supported by this class.
|
52
|
+
SPECIFIER_OPTIONS = {
|
53
|
+
"c" => { :type => "s", :value => "@name" },
|
54
|
+
"C" => { :type => "s", :value => "self.progname" },
|
55
|
+
"d" => { :type => "s", :value => "opts[:timestamp]" },
|
56
|
+
"F" => { :type => "s", :value => "opts[:caller_file]" },
|
57
|
+
"l" => { :type => "s", :value => "opts[:caller_info]" },
|
58
|
+
"L" => { :type => "d", :value => "opts[:caller_line]" },
|
59
|
+
"m" => { :type => "s", :value => "opts[:msg]" },
|
60
|
+
"M" => { :type => "s", :value => "opts[:caller_method]" },
|
61
|
+
"n" => { :type => "s", :value => "$/" },
|
62
|
+
"p" => { :type => "s", :value => "opts[:severity]" },
|
63
|
+
"t" => { :type => "d", :value => "Thread.current.__id__" },
|
64
|
+
"%" => { :type => "s", :value => "'%'" },
|
65
|
+
"P" => { :type => "s", :value => "opts[:progname]" },
|
66
|
+
"$" => { :type => "d", :value => "$$" }
|
67
|
+
}
|
68
|
+
|
69
|
+
# The regular expression for matching specifier patterns in the
|
70
|
+
# format strings.
|
71
|
+
SPECIFIER_PATTERN = /(.*?)%(-?\d*(?:\.\d+)?)?([cCdFlLmMnpt%$P])/
|
72
|
+
|
73
|
+
# Extracts the unqualified name from the progname, after setting the
|
74
|
+
# progname.
|
75
|
+
def progname=( progname )
|
76
|
+
super
|
77
|
+
@name = progname.split( /\./ ).last
|
78
|
+
end
|
79
|
+
|
80
|
+
# Set the message format string to the given string. This also pre-parses
|
81
|
+
# the format for faster processing.
|
82
|
+
#
|
83
|
+
# The format string is a printf-formatted string, which supports the following
|
84
|
+
# format specifiers:
|
85
|
+
#
|
86
|
+
# c:: the unqualified name of the logger
|
87
|
+
# C:: the fully-qualified name of the logger
|
88
|
+
# d:: the date/time string (as formatted by the #datetime_format string)
|
89
|
+
# F:: the filename of the calling routine
|
90
|
+
# l:: the location of the calling routine
|
91
|
+
# L:: the line number of the calling routine
|
92
|
+
# m:: the message to log
|
93
|
+
# M:: the name of the calling method
|
94
|
+
# n:: the newline character
|
95
|
+
# p:: the name of the priority (or severity) used to log this method
|
96
|
+
# t:: the id of the current thread
|
97
|
+
# %:: a percentage character
|
98
|
+
# P:: the progname that was passed to the logger method
|
99
|
+
# $:: the current process id
|
100
|
+
def message_format=( format )
|
101
|
+
@message_format = format
|
102
|
+
return unless format
|
103
|
+
|
104
|
+
@needs_caller_info = false
|
105
|
+
|
106
|
+
format_string = ""
|
107
|
+
format_parameters = []
|
108
|
+
|
109
|
+
@message_format_tokens = []
|
110
|
+
format.scan( SPECIFIER_PATTERN ) do |v|
|
111
|
+
format_string << v[0] if v[0].length > 0
|
112
|
+
opts = SPECIFIER_OPTIONS[ v[2] ]
|
113
|
+
format_string << "%#{v[1]}#{opts[:type]}"
|
114
|
+
format_parameters << opts[:value]
|
115
|
+
@needs_caller_info = true if v[2] =~ /[FlLM]/
|
116
|
+
end
|
117
|
+
format_string << $' if $'.length > 0
|
118
|
+
format_string << "\n"
|
119
|
+
|
120
|
+
definition = "proc { |opts| #{format_string.inspect} % [ #{format_parameters.join(',')} ] }"
|
121
|
+
@message_formatter = eval( definition )
|
122
|
+
end
|
123
|
+
|
124
|
+
# Format the message using the given parameters. If a message format has
|
125
|
+
# not been given, just call the superclass's implementation. Otherwise,
|
126
|
+
# process the tokens from the parsed message format.
|
127
|
+
def format_message( severity, timestamp, msg, progname )
|
128
|
+
if @message_format.nil?
|
129
|
+
super
|
130
|
+
else
|
131
|
+
opts = {
|
132
|
+
:severity => severity,
|
133
|
+
:timestamp => timestamp,
|
134
|
+
:msg => msg,
|
135
|
+
:progname => progname
|
136
|
+
}
|
137
|
+
|
138
|
+
if @needs_caller_info
|
139
|
+
stack = caller
|
140
|
+
stack.shift while stack.first =~ /\blogger\.rb/
|
141
|
+
opts[:caller_info] = caller_info = stack.first
|
142
|
+
match = caller_info.match( /(.*):(\d+)(?::in `(.*)')?/ )
|
143
|
+
opts[:caller_file] = match[1]
|
144
|
+
opts[:caller_line] = match[2]
|
145
|
+
opts[:caller_method] = match[3]
|
146
|
+
end
|
147
|
+
|
148
|
+
@message_formatter.call( opts )
|
149
|
+
end
|
150
|
+
end
|
151
|
+
private :format_message
|
152
|
+
|
153
|
+
end
|
154
|
+
|
155
|
+
end
|
@@ -31,8 +31,9 @@
|
|
31
31
|
# =============================================================================
|
32
32
|
#++
|
33
33
|
|
34
|
+
require 'copland/errors'
|
34
35
|
require 'copland/models/abstract'
|
35
|
-
require 'thread'
|
36
|
+
require 'copland/thread'
|
36
37
|
|
37
38
|
module Copland
|
38
39
|
|
@@ -47,7 +48,7 @@ module Copland
|
|
47
48
|
# Create a new SingletonServiceModel on the given service point.
|
48
49
|
def initialize( service_point )
|
49
50
|
super
|
50
|
-
@mutex =
|
51
|
+
@mutex = QueryableMutex.new
|
51
52
|
end
|
52
53
|
|
53
54
|
# Return the singleton instance of the service point. This is
|
@@ -55,6 +56,11 @@ module Copland
|
|
55
56
|
def instance( &init )
|
56
57
|
return @instance if @instance
|
57
58
|
|
59
|
+
if @mutex.self_locked?
|
60
|
+
raise CoplandException,
|
61
|
+
"circular dependency on #{service_point.full_name} detected"
|
62
|
+
end
|
63
|
+
|
58
64
|
@mutex.synchronize do
|
59
65
|
return @instance if @instance
|
60
66
|
new_instance( &init )
|
data/lib/copland/package.rb
CHANGED
@@ -78,14 +78,24 @@ module Copland
|
|
78
78
|
end
|
79
79
|
|
80
80
|
# Returns the service point with the given name. If no such service point
|
81
|
-
# exists, this returns +nil+.
|
82
|
-
|
83
|
-
|
81
|
+
# exists, this returns +nil+. If +include_private+ is false, then this will
|
82
|
+
# also return +nil+ if the point exists, but is marked private.
|
83
|
+
def service_point( name, include_private=false )
|
84
|
+
point = @service_points[ name ]
|
85
|
+
return nil if point.nil? || point.visibility == :private &&
|
86
|
+
!include_private
|
87
|
+
point
|
84
88
|
end
|
85
89
|
|
86
|
-
# This returns the names of all service points in the package.
|
87
|
-
|
88
|
-
|
90
|
+
# This returns the names of all service points in the package. If
|
91
|
+
# +include_private+ is true (the default), then only the public service
|
92
|
+
# points will be returned.
|
93
|
+
def service_points( include_private=false )
|
94
|
+
names = @service_points.keys.dup
|
95
|
+
if !include_private
|
96
|
+
names.reject! { |p| @service_points[p].visibility != :public }
|
97
|
+
end
|
98
|
+
names
|
89
99
|
end
|
90
100
|
|
91
101
|
# This instantiates the service point with the given name and returns the
|
@@ -95,15 +105,19 @@ module Copland
|
|
95
105
|
# If a block is given, it will be used to initialize the service (but only
|
96
106
|
# when the service is created--if the service is a singleton service and
|
97
107
|
# it was created previously, the init block will be ignored).
|
98
|
-
|
99
|
-
|
108
|
+
#
|
109
|
+
# If +include_private+ is true, then only public service points may be
|
110
|
+
# instantiated.
|
111
|
+
def service( name, include_private=false, &init )
|
112
|
+
point = service_point( name, include_private ) or
|
113
|
+
raise ServicePointNotFound, name
|
100
114
|
point.instance( &init )
|
101
115
|
end
|
102
116
|
|
103
117
|
# Returns +true+ if the named service exists in this package, and +false+
|
104
118
|
# otherwise.
|
105
|
-
def service_exist?( name )
|
106
|
-
return !service_point( name ).nil?
|
119
|
+
def service_exist?( name, include_private=false )
|
120
|
+
return !service_point( name, include_private ).nil?
|
107
121
|
end
|
108
122
|
|
109
123
|
# This is a convenience method for returning a service with the given name,
|
@@ -155,8 +169,10 @@ module Copland
|
|
155
169
|
end
|
156
170
|
|
157
171
|
# Iterates over each service point in the package.
|
158
|
-
def each_service_point( &block )
|
159
|
-
@service_points.each_value
|
172
|
+
def each_service_point( include_private=false, &block )
|
173
|
+
@service_points.each_value do |pt|
|
174
|
+
yield pt if pt.visibility == :public || include_private
|
175
|
+
end
|
160
176
|
self
|
161
177
|
end
|
162
178
|
|
@@ -171,8 +187,10 @@ module Copland
|
|
171
187
|
end
|
172
188
|
|
173
189
|
# Returns the number of service points in the package.
|
174
|
-
def service_point_count
|
175
|
-
@service_points.
|
190
|
+
def service_point_count( include_private=false )
|
191
|
+
@service_points.
|
192
|
+
reject { |k,v| v.visibility == :private && !include_private }.
|
193
|
+
size
|
176
194
|
end
|
177
195
|
|
178
196
|
# Returns the number of configuration points in the package.
|