sevenscale-adhearsion 0.7.1003 → 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/CHANGELOG +8 -2
- data/EVENTS +11 -0
- data/Rakefile +92 -26
- data/adhearsion.gemspec +131 -23
- data/app_generators/ahn/ahn_generator.rb +21 -7
- data/app_generators/ahn/templates/.ahnrc +10 -4
- data/app_generators/ahn/templates/Rakefile +7 -2
- data/app_generators/ahn/templates/components/ami_remote/ami_remote.rb +15 -0
- data/app_generators/ahn/templates/components/disabled/HOW_TO_ENABLE +7 -0
- data/app_generators/ahn/templates/components/disabled/stomp_gateway/README.markdown +47 -0
- data/app_generators/ahn/templates/components/disabled/stomp_gateway/config.yml +12 -0
- data/app_generators/ahn/templates/components/disabled/stomp_gateway/stomp_gateway.rb +34 -0
- data/app_generators/ahn/templates/components/simon_game/{lib/simon_game.rb → simon_game.rb} +14 -19
- data/app_generators/ahn/templates/config/startup.rb +3 -6
- data/app_generators/ahn/templates/dialplan.rb +2 -3
- data/app_generators/ahn/templates/events.rb +32 -6
- data/bin/jahn +10 -0
- data/examples/asterisk_manager_interface/standalone.rb +51 -0
- data/lib/adhearsion/cli.rb +140 -23
- data/lib/adhearsion/component_manager/component_tester.rb +55 -0
- data/lib/adhearsion/component_manager/spec_framework.rb +24 -0
- data/lib/adhearsion/component_manager.rb +169 -238
- data/lib/adhearsion/events_support.rb +59 -237
- data/lib/adhearsion/{core_extensions → foundation}/all.rb +0 -0
- data/lib/adhearsion/{blank_slate.rb → foundation/blank_slate.rb} +0 -0
- data/lib/adhearsion/{core_extensions → foundation}/custom_daemonizer.rb +0 -0
- data/lib/adhearsion/foundation/event_socket.rb +203 -0
- data/lib/adhearsion/foundation/future_resource.rb +36 -0
- data/lib/adhearsion/{core_extensions → foundation}/global.rb +0 -0
- data/lib/adhearsion/{core_extensions → foundation}/metaprogramming.rb +0 -0
- data/lib/adhearsion/foundation/numeric.rb +13 -0
- data/lib/adhearsion/foundation/pseudo_guid.rb +10 -0
- data/lib/adhearsion/{core_extensions → foundation}/relationship_properties.rb +2 -0
- data/lib/adhearsion/foundation/string.rb +26 -0
- data/lib/adhearsion/foundation/synchronized_hash.rb +96 -0
- data/lib/adhearsion/{core_extensions → foundation}/thread_safety.rb +0 -0
- data/lib/adhearsion/host_definitions.rb +5 -1
- data/lib/adhearsion/initializer/asterisk.rb +33 -11
- data/lib/adhearsion/initializer/configuration.rb +58 -6
- data/lib/adhearsion/initializer/database.rb +3 -46
- data/lib/adhearsion/initializer/drb.rb +9 -3
- data/lib/adhearsion/initializer/freeswitch.rb +3 -3
- data/lib/adhearsion/initializer/rails.rb +1 -1
- data/lib/adhearsion/initializer.rb +213 -87
- data/lib/adhearsion/tasks/deprecations.rb +59 -0
- data/lib/adhearsion/tasks.rb +2 -1
- data/lib/adhearsion/version.rb +3 -3
- data/lib/adhearsion/voip/asterisk/agi_server.rb +6 -6
- data/lib/adhearsion/voip/asterisk/commands.rb +100 -2
- data/lib/adhearsion/voip/asterisk/manager_interface/ami_lexer.rb +1754 -0
- data/lib/adhearsion/voip/asterisk/manager_interface/ami_lexer.rl.rb +286 -0
- data/lib/adhearsion/voip/asterisk/manager_interface/ami_messages.rb +78 -0
- data/lib/adhearsion/voip/asterisk/manager_interface/ami_protocol_lexer_machine.rl +87 -0
- data/lib/adhearsion/voip/asterisk/manager_interface.rb +562 -0
- data/lib/adhearsion/voip/asterisk/super_manager.rb +19 -0
- data/lib/adhearsion/voip/asterisk.rb +1 -8
- data/lib/adhearsion/voip/call.rb +5 -1
- data/lib/adhearsion/voip/dial_plan.rb +74 -61
- data/lib/adhearsion/voip/dsl/dialing_dsl.rb +1 -1
- data/lib/adhearsion/voip/dsl/dialplan/parser.rb +2 -6
- data/lib/adhearsion/voip/dsl/numerical_string.rb +2 -2
- data/lib/adhearsion/voip/freeswitch/oes_server.rb +2 -2
- data/lib/adhearsion.rb +16 -11
- data/lib/theatre/README.markdown +64 -0
- data/lib/theatre/callback_definition_loader.rb +84 -0
- data/lib/theatre/guid.rb +23 -0
- data/lib/theatre/invocation.rb +121 -0
- data/lib/theatre/namespace_manager.rb +153 -0
- data/lib/theatre/version.rb +2 -0
- data/lib/theatre.rb +151 -0
- metadata +60 -147
- data/Manifest.txt +0 -151
- data/README.txt +0 -5
- data/ahn_generators/component/USAGE +0 -5
- data/ahn_generators/component/component_generator.rb +0 -57
- data/ahn_generators/component/templates/configuration.rb +0 -0
- data/ahn_generators/component/templates/lib/lib.rb.erb +0 -3
- data/ahn_generators/component/templates/test/test.rb.erb +0 -12
- data/ahn_generators/component/templates/test/test_helper.rb +0 -14
- data/app_generators/ahn/templates/components/simon_game/configuration.rb +0 -0
- data/app_generators/ahn/templates/components/simon_game/test/test_helper.rb +0 -14
- data/app_generators/ahn/templates/components/simon_game/test/test_simon_game.rb +0 -31
- data/lib/adhearsion/core_extensions/array.rb +0 -0
- data/lib/adhearsion/core_extensions/guid.rb +0 -5
- data/lib/adhearsion/core_extensions/hash.rb +0 -0
- data/lib/adhearsion/core_extensions/numeric.rb +0 -4
- data/lib/adhearsion/core_extensions/proc.rb +0 -0
- data/lib/adhearsion/core_extensions/pseudo_uuid.rb +0 -11
- data/lib/adhearsion/core_extensions/publishable.rb +0 -73
- data/lib/adhearsion/core_extensions/string.rb +0 -26
- data/lib/adhearsion/core_extensions/thread.rb +0 -13
- data/lib/adhearsion/core_extensions/time.rb +0 -0
- data/lib/adhearsion/distributed/gateways/dbus_gateway.rb +0 -0
- data/lib/adhearsion/distributed/gateways/osa_gateway.rb +0 -0
- data/lib/adhearsion/distributed/gateways/rest_gateway.rb +0 -9
- data/lib/adhearsion/distributed/gateways/soap_gateway.rb +0 -9
- data/lib/adhearsion/distributed/gateways/xmlrpc_gateway.rb +0 -9
- data/lib/adhearsion/distributed/peer_finder.rb +0 -0
- data/lib/adhearsion/distributed/remote_cli.rb +0 -0
- data/lib/adhearsion/hooks.rb +0 -57
- data/lib/adhearsion/initializer/paths.rb +0 -55
- data/lib/adhearsion/voip/asterisk/ami/actions.rb +0 -238
- data/lib/adhearsion/voip/asterisk/ami/machine.rb +0 -871
- data/lib/adhearsion/voip/asterisk/ami/machine.rl +0 -109
- data/lib/adhearsion/voip/asterisk/ami/parser.rb +0 -262
- data/lib/adhearsion/voip/asterisk/ami.rb +0 -147
- data/spec/fixtures/dialplan.rb +0 -3
- data/spec/initializer/test_configuration.rb +0 -267
- data/spec/initializer/test_loading.rb +0 -162
- data/spec/initializer/test_paths.rb +0 -43
- data/spec/sample.rb +0 -9
- data/spec/silence.rb +0 -10
- data/spec/test_ahn_command.rb +0 -149
- data/spec/test_code_quality.rb +0 -87
- data/spec/test_component_manager.rb +0 -97
- data/spec/test_constants.rb +0 -8
- data/spec/test_drb.rb +0 -104
- data/spec/test_events.rb +0 -136
- data/spec/test_helper.rb +0 -106
- data/spec/test_hooks.rb +0 -15
- data/spec/test_host_definitions.rb +0 -79
- data/spec/test_initialization.rb +0 -124
- data/spec/test_logging.rb +0 -80
- data/spec/test_relationship_properties.rb +0 -54
- data/spec/voip/asterisk/ami_response_definitions.rb +0 -23
- data/spec/voip/asterisk/config_file_generators/test_agents.rb +0 -253
- data/spec/voip/asterisk/config_file_generators/test_queues.rb +0 -325
- data/spec/voip/asterisk/config_file_generators/test_voicemail.rb +0 -306
- data/spec/voip/asterisk/menu_command/test_calculated_match.rb +0 -111
- data/spec/voip/asterisk/menu_command/test_matchers.rb +0 -98
- data/spec/voip/asterisk/mock_ami_server.rb +0 -176
- data/spec/voip/asterisk/test_agi_server.rb +0 -453
- data/spec/voip/asterisk/test_ami.rb +0 -227
- data/spec/voip/asterisk/test_commands.rb +0 -2006
- data/spec/voip/asterisk/test_config_manager.rb +0 -129
- data/spec/voip/dsl/dispatcher_spec_helper.rb +0 -45
- data/spec/voip/dsl/test_dialing_dsl.rb +0 -268
- data/spec/voip/dsl/test_dispatcher.rb +0 -82
- data/spec/voip/dsl/test_parser.rb +0 -87
- data/spec/voip/freeswitch/test_basic_connection_manager.rb +0 -39
- data/spec/voip/freeswitch/test_inbound_connection_manager.rb +0 -39
- data/spec/voip/freeswitch/test_oes_server.rb +0 -9
- data/spec/voip/test_call_routing.rb +0 -127
- data/spec/voip/test_dialplan_manager.rb +0 -442
- data/spec/voip/test_numerical_string.rb +0 -48
- data/spec/voip/test_phone_number.rb +0 -36
- data/test/test_ahn_generator.rb +0 -59
- data/test/test_component_generator.rb +0 -52
- data/test/test_generator_helper.rb +0 -20
@@ -1,277 +1,208 @@
|
|
1
1
|
module Adhearsion
|
2
|
-
|
3
2
|
module Components
|
4
|
-
class Manager
|
5
|
-
attr_reader :active_components, :host_information, :started_components, :components_with_call_context
|
6
|
-
def initialize
|
7
|
-
@active_components = {}
|
8
|
-
@started_components = []
|
9
|
-
@components_with_call_context = {}
|
10
|
-
end
|
11
|
-
|
12
|
-
def [](component_name)
|
13
|
-
active_components[component_name].component_class.instance
|
14
|
-
end
|
15
3
|
|
16
|
-
|
17
|
-
active_components[component_name]
|
18
|
-
end
|
19
|
-
|
20
|
-
def has_component?(component_name)
|
21
|
-
active_components.has_key?(component_name)
|
22
|
-
end
|
23
|
-
|
24
|
-
def component_gems
|
25
|
-
@repository ||= RubygemsRepository.new
|
26
|
-
@repository.adhearsion_gems
|
27
|
-
end
|
4
|
+
mattr_accessor :component_manager
|
28
5
|
|
29
|
-
|
30
|
-
return unless File.exist?(AHN_ROOT.component_path)
|
31
|
-
component_directories = Dir.glob(File.join(AHN_ROOT.component_path, "*"))
|
32
|
-
component_directories.each do |component_directory|
|
33
|
-
component_name = File.basename(component_directory).to_sym
|
34
|
-
@active_components[component_name] = Component.new(self, component_name, component_directory)
|
35
|
-
end
|
36
|
-
end
|
6
|
+
class ConfigurationError < Exception; end
|
37
7
|
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
@active_components[name].stop
|
8
|
+
class ComponentManager
|
9
|
+
|
10
|
+
class << self
|
11
|
+
|
12
|
+
def scopes_valid?(*scopes)
|
13
|
+
unrecognized_scopes = (scopes.flatten - SCOPE_NAMES).map(&:inspect)
|
14
|
+
raise ArgumentError, "Unrecognized scopes #{unrecognized_scopes.to_sentence}" if unrecognized_scopes.any?
|
15
|
+
true
|
47
16
|
end
|
17
|
+
|
48
18
|
end
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
gems
|
19
|
+
|
20
|
+
SCOPE_NAMES = [:dialplan, :events, :generators, :rpc, :global]
|
21
|
+
DEFAULT_CONFIG_NAME = "config.yml"
|
22
|
+
|
23
|
+
attr_reader :scopes, :lazy_config_loader
|
24
|
+
def initialize(path_to_container_directory)
|
25
|
+
@path_to_container_directory = path_to_container_directory
|
26
|
+
@scopes = SCOPE_NAMES.inject({}) do |scopes, name|
|
27
|
+
scopes[name] = Module.new
|
28
|
+
scopes
|
60
29
|
end
|
61
|
-
|
62
|
-
end
|
63
|
-
|
64
|
-
ClassToGetCallContext = Struct.new(:component_class, :instance_variable)
|
65
|
-
class ClassToGetCallContext
|
66
|
-
def instantiate_with_call_context(call_context, *args, &block)
|
67
|
-
component = component_class.allocate
|
68
|
-
component.instance_variable_set(("@"+instance_variable.to_s).to_sym, call_context)
|
69
|
-
component.send(:initialize, *args, &block)
|
70
|
-
component
|
71
|
-
end
|
72
|
-
end
|
73
|
-
|
74
|
-
|
75
|
-
#component behavior is shared across components
|
76
|
-
module Behavior
|
77
|
-
def self.included(component_class)
|
78
|
-
component_class.extend(ClassMethods)
|
30
|
+
@lazy_config_loader = LazyConfigLoader.new(self)
|
79
31
|
end
|
80
32
|
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
Configuration.description || Component.name
|
33
|
+
##
|
34
|
+
# Includes the anonymous Module created for the :global scope in Object, making its methods globally accessible.
|
35
|
+
#
|
36
|
+
def globalize_global_scope!
|
37
|
+
Object.send :include, @scopes[:global]
|
87
38
|
end
|
88
39
|
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
ComponentManager.components_with_call_context[name] = ClassToGetCallContext.new(self, params[:as])
|
40
|
+
def load_components
|
41
|
+
components = Dir.glob(File.join(@path_to_container_directory + "/*")).select do |path|
|
42
|
+
File.directory?(path)
|
93
43
|
end
|
94
|
-
|
95
|
-
|
96
|
-
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
-
|
102
|
-
|
103
|
-
def self.name
|
104
|
-
'#{component_class_name}'
|
105
|
-
end
|
106
|
-
include Adhearsion::Components::Behavior
|
107
|
-
end
|
108
|
-
EVAL
|
44
|
+
components.map! { |path| File.basename path }
|
45
|
+
components.each do |component|
|
46
|
+
next if component == "disabled"
|
47
|
+
component_file = File.join(@path_to_container_directory, component, component + ".rb")
|
48
|
+
if File.exists? component_file
|
49
|
+
load_file component_file
|
50
|
+
else
|
51
|
+
ahn_log.warn "Component directory does not contain a matching .rb file! Was expecting #{component_file.inspect}"
|
52
|
+
end
|
109
53
|
end
|
110
|
-
end
|
111
54
|
|
112
|
-
attr_reader :manager, :name, :path, :component_module, :component_class
|
113
|
-
def initialize(manager, name, path)
|
114
|
-
@manager = manager
|
115
|
-
@name = name
|
116
|
-
@path = path
|
117
|
-
unless File.exist?(main_file_name)
|
118
|
-
gem_path = @manager.component_gems[@name.to_s]
|
119
|
-
raise "The component '#{@name}' does not have the main file: #{main_file_name}" unless gem_path
|
120
|
-
@path = gem_path
|
121
|
-
end
|
122
|
-
@started = false
|
123
55
|
end
|
124
56
|
|
125
|
-
|
126
|
-
|
127
|
-
|
128
|
-
|
129
|
-
|
130
|
-
|
131
|
-
|
57
|
+
##
|
58
|
+
# Loads the configuration file for a given component name.
|
59
|
+
#
|
60
|
+
# @return [Hash] The loaded YAML for the given component name. An empty Hash if no YAML file exists.
|
61
|
+
#
|
62
|
+
def configuration_for_component_named(component_name)
|
63
|
+
component_dir = File.join(@path_to_container_directory, component_name)
|
64
|
+
config_file = File.join component_dir, DEFAULT_CONFIG_NAME
|
65
|
+
if File.exists?(config_file)
|
66
|
+
YAML.load_file config_file
|
67
|
+
else
|
68
|
+
return {}
|
132
69
|
end
|
133
|
-
@component_module.require(File.join("lib", @name.to_s))
|
134
70
|
end
|
135
71
|
|
136
|
-
def
|
137
|
-
|
72
|
+
def extend_object_with(object, *scopes)
|
73
|
+
raise ArgumentError, "Must supply at least one scope!" if scopes.empty?
|
74
|
+
|
75
|
+
self.class.scopes_valid? scopes
|
76
|
+
|
77
|
+
scopes.each do |scope|
|
78
|
+
methods = @scopes[scope]
|
79
|
+
if object.kind_of?(Module)
|
80
|
+
object.send :include, methods
|
81
|
+
else
|
82
|
+
object.extend methods
|
83
|
+
end
|
84
|
+
end
|
85
|
+
object
|
138
86
|
end
|
139
|
-
|
140
|
-
def
|
141
|
-
|
87
|
+
|
88
|
+
def load_code(code)
|
89
|
+
load_container ComponentDefinitionContainer.load_code(code)
|
142
90
|
end
|
143
|
-
|
144
|
-
def
|
145
|
-
|
91
|
+
|
92
|
+
def load_file(filename)
|
93
|
+
load_container ComponentDefinitionContainer.load_file(filename)
|
146
94
|
end
|
147
95
|
|
148
|
-
|
96
|
+
protected
|
149
97
|
|
150
|
-
|
151
|
-
|
98
|
+
def load_container(container)
|
99
|
+
container.constants.each do |constant_name|
|
100
|
+
constant_value = container.const_get(constant_name)
|
101
|
+
Object.const_set(constant_name, constant_value)
|
152
102
|
end
|
153
|
-
|
154
|
-
|
155
|
-
|
103
|
+
metadata = container.metaclass.send(:instance_variable_get, :@metadata)
|
104
|
+
metadata[:initialization_block].call if metadata[:initialization_block]
|
105
|
+
|
106
|
+
self.class.scopes_valid? metadata[:scopes].keys
|
107
|
+
|
108
|
+
metadata[:scopes].each_pair do |scope, method_definition_blocks|
|
109
|
+
method_definition_blocks.each do |method_definition_block|
|
110
|
+
@scopes[scope].module_eval(&method_definition_block)
|
111
|
+
end
|
156
112
|
end
|
157
|
-
|
158
|
-
|
159
|
-
class ComponentModule < Module
|
160
|
-
# The file with which the Script was instantiated.
|
161
|
-
attr_reader :main_file
|
162
|
-
|
163
|
-
# The directory in which main_file is located, and relative to which
|
164
|
-
# #load searches for files before falling back to Kernel#load.
|
165
|
-
attr_reader :dir
|
166
|
-
|
167
|
-
# A hash that maps <tt>filename=>true</tt> for each file that has been
|
168
|
-
# required locally by the script. This has the same semantics as <tt>$"</tt>,
|
169
|
-
# alias <tt>$LOADED_FEATURES</tt>, except that it is local to this script.
|
170
|
-
attr_reader :loaded_features
|
171
|
-
|
172
|
-
class << self
|
173
|
-
alias load new
|
174
|
-
end
|
175
|
-
|
176
|
-
# Creates new Script, and loads _main_file_ in the scope of the Script. If a
|
177
|
-
# block is given, the script is passed to it before loading from the file, and
|
178
|
-
# constants can be defined as inputs to the script.
|
179
|
-
attr_reader :component
|
180
|
-
def initialize(component) # :yields: self
|
181
|
-
extend ComponentModuleMethods
|
182
|
-
@component = component
|
183
|
-
@loaded_features = {}
|
184
|
-
|
185
|
-
const_set :Component, component
|
186
|
-
const_set :Configuration, OpenStruct.new(:description => nil)
|
187
|
-
|
188
|
-
yield self if block_given?
|
189
|
-
end
|
190
|
-
|
191
|
-
def load_configuration_file
|
192
|
-
load_in_module(component.configuration_file)
|
193
|
-
end
|
194
|
-
|
195
|
-
# Loads _file_ into this Script. Searches relative to the local dir, that is,
|
196
|
-
# the dir of the file given in the original call to
|
197
|
-
# <tt>Script.load(file)</tt>, loads the file, if found, into this Script's
|
198
|
-
# scope, and returns true. If the file is not found, falls back to
|
199
|
-
# <tt>Kernel.load</tt>, which searches on <tt>$LOAD_PATH</tt>, loads the file,
|
200
|
-
# if found, into global scope, and returns true. Otherwise, raises
|
201
|
-
# <tt>LoadError</tt>.
|
202
|
-
#
|
203
|
-
# The _wrap_ argument is passed to <tt>Kernel.load</tt> in the fallback case,
|
204
|
-
# when the file is not found locally.
|
205
|
-
#
|
206
|
-
# Typically called from within the main file to load additional sub files, or
|
207
|
-
# from those sub files.
|
208
|
-
|
209
|
-
def load(file, wrap = false)
|
210
|
-
load_in_module(File.join(component.path, file))
|
211
|
-
true
|
212
|
-
rescue MissingFile
|
213
|
-
super
|
113
|
+
container
|
214
114
|
end
|
215
115
|
|
216
|
-
|
217
|
-
|
218
|
-
|
219
|
-
|
220
|
-
|
221
|
-
|
222
|
-
|
223
|
-
|
224
|
-
|
225
|
-
|
226
|
-
|
227
|
-
|
228
|
-
|
229
|
-
|
230
|
-
load_in_module(File.join(component.path, file))
|
116
|
+
class ComponentDefinitionContainer < Module
|
117
|
+
|
118
|
+
class << self
|
119
|
+
def load_code(code)
|
120
|
+
returning(new) do |instance|
|
121
|
+
instance.module_eval code
|
122
|
+
end
|
123
|
+
end
|
124
|
+
|
125
|
+
def load_file(filename)
|
126
|
+
returning(new) do |instance|
|
127
|
+
instance.module_eval File.read(filename), filename
|
128
|
+
end
|
129
|
+
end
|
231
130
|
end
|
232
|
-
|
233
|
-
|
234
|
-
|
235
|
-
|
236
|
-
|
237
|
-
|
238
|
-
|
239
|
-
|
240
|
-
|
241
|
-
|
242
|
-
|
243
|
-
|
244
|
-
|
245
|
-
|
246
|
-
|
247
|
-
|
248
|
-
|
249
|
-
|
250
|
-
|
131
|
+
|
132
|
+
def initialize(&block)
|
133
|
+
# Hide our instance variables in the singleton class
|
134
|
+
metadata = {}
|
135
|
+
metaclass.send(:instance_variable_set, :@metadata, metadata)
|
136
|
+
|
137
|
+
metadata[:scopes] = ComponentManager::SCOPE_NAMES.inject({}) do |scopes, name|
|
138
|
+
scopes[name] = []
|
139
|
+
scopes
|
140
|
+
end
|
141
|
+
|
142
|
+
super
|
143
|
+
|
144
|
+
meta_def(:initialize) { raise "This object has already been instantiated. Are you sure you didn't mean initialization()?" }
|
145
|
+
end
|
146
|
+
|
147
|
+
def methods_for(*scopes, &block)
|
148
|
+
raise ArgumentError if scopes.empty?
|
149
|
+
|
150
|
+
ComponentManager.scopes_valid? scopes
|
151
|
+
|
152
|
+
metadata = metaclass.send(:instance_variable_get, :@metadata)
|
153
|
+
scopes.each { |scope| metadata[:scopes][scope] << block }
|
154
|
+
end
|
155
|
+
|
156
|
+
def initialization(&block)
|
157
|
+
# Raise an exception if the initialization block has already been set
|
158
|
+
metadata = metaclass.send(:instance_variable_get, :@metadata)
|
159
|
+
if metadata[:initialization_block]
|
160
|
+
raise "You should only have one initialization() block!"
|
161
|
+
else
|
162
|
+
metadata[:initialization_block] = block
|
163
|
+
end
|
251
164
|
end
|
165
|
+
alias initialisation initialization
|
166
|
+
|
167
|
+
protected
|
168
|
+
|
169
|
+
class << self
|
170
|
+
def self.method_added(method_name)
|
171
|
+
@methods ||= []
|
172
|
+
@methods << method_name
|
173
|
+
end
|
174
|
+
end
|
175
|
+
|
252
176
|
end
|
253
|
-
|
254
|
-
|
255
|
-
|
177
|
+
|
178
|
+
class ComponentMethodDefinitionContainer < Module
|
179
|
+
class << self
|
180
|
+
def method_added(method_name)
|
181
|
+
@methods ||= []
|
182
|
+
@methods << method_name
|
183
|
+
end
|
184
|
+
end
|
185
|
+
|
186
|
+
attr_reader :scopes
|
187
|
+
def initialize(*scopes, &block)
|
188
|
+
@scopes = []
|
189
|
+
super(&block)
|
190
|
+
end
|
191
|
+
|
256
192
|
end
|
257
|
-
|
258
|
-
|
259
|
-
|
260
|
-
|
261
|
-
# <tt>Module#module_function(name)</tt>.
|
262
|
-
def method_added(name) # :nodoc:
|
263
|
-
module_function(name)
|
193
|
+
|
194
|
+
class LazyConfigLoader
|
195
|
+
def initialize(component_manager)
|
196
|
+
@component_manager = component_manager
|
264
197
|
end
|
265
|
-
|
266
|
-
def
|
267
|
-
|
268
|
-
|
269
|
-
|
198
|
+
|
199
|
+
def method_missing(component_name)
|
200
|
+
config = @component_manager.configuration_for_component_named(component_name.to_s)
|
201
|
+
(class << self; self; end).send(:define_method, component_name) { config }
|
202
|
+
config
|
270
203
|
end
|
271
|
-
|
272
204
|
end
|
205
|
+
|
273
206
|
end
|
274
207
|
end
|
275
|
-
|
276
|
-
ComponentManager = Components::Manager.new unless defined? ComponentManager
|
277
208
|
end
|