coderay 0.7.2.168 → 0.7.2.176

Sign up to get free protection for your applications and to get access to all the features.
@@ -1,326 +1,326 @@
1
- # = PluginHost
2
- #
3
- # $Id: plugin.rb 154 2006-07-11 05:37:50Z murphy $
4
- #
5
- # A simple subclass plugin system.
6
- #
7
- # Example:
8
- # class Generators < PluginHost
9
- # plugin_path 'app/generators'
10
- # end
11
- #
12
- # class Generator
13
- # extend Plugin
14
- # PLUGIN_HOST = Generators
15
- # end
16
- #
17
- # class FancyGenerator < Generator
18
- # register_for :fancy
19
- # end
20
- #
21
- # Generators[:fancy] #-> FancyGenerator
22
- # # or
23
- # require_plugin 'Generators/fancy'
24
- module PluginHost
25
-
26
- # Raised if Encoders::[] fails because:
27
- # * a file could not be found
28
- # * the requested Encoder is not registered
29
- PluginNotFound = Class.new Exception
30
- HostNotFound = Class.new Exception
31
-
32
- PLUGIN_HOSTS = []
33
- PLUGIN_HOSTS_BY_ID = {} # dummy hash
34
-
35
- # Loads all plugins using all_plugin_names and load.
36
- def load_all
37
- for plugin in all_plugin_names
38
- load plugin
39
- end
40
- end
41
-
42
- # Returns the Plugin for +id+.
43
- #
44
- # Example:
45
- # yaml_plugin = MyPluginHost[:yaml]
46
- def [] id, *args, &blk
47
- plugin = validate_id(id)
48
- begin
49
- plugin = plugin_hash.[] plugin, *args, &blk
50
- end while plugin.is_a? Symbol
51
- plugin
52
- end
53
-
54
- # Alias for +[]+.
55
- alias load []
56
-
57
- def require_helper plugin_id, helper_name
58
- path = path_to File.join(plugin_id, helper_name)
59
- require path
60
- end
61
-
62
- class << self
63
-
64
- # Adds the module/class to the PLUGIN_HOSTS list.
65
- def extended mod
66
- PLUGIN_HOSTS << mod
67
- end
68
-
69
- # Warns you that you should not #include this module.
70
- def included mod
71
- warn "#{name} should not be included. Use extend."
72
- end
73
-
74
- # Find the PluginHost for host_id.
75
- def host_by_id host_id
76
- unless PLUGIN_HOSTS_BY_ID.default_proc
77
- ph = Hash.new do |h, a_host_id|
78
- for host in PLUGIN_HOSTS
79
- h[host.host_id] = host
80
- end
81
- h.fetch a_host_id, nil
82
- end
83
- PLUGIN_HOSTS_BY_ID.replace ph
84
- end
85
- PLUGIN_HOSTS_BY_ID[host_id]
86
- end
87
-
88
- end
89
-
90
- # The path where the plugins can be found.
91
- def plugin_path *args
92
- unless args.empty?
93
- @plugin_path = File.expand_path File.join(*args)
94
- load_map
95
- end
96
- @plugin_path
97
- end
98
-
99
- # The host's ID.
100
- #
101
- # If PLUGIN_HOST_ID is not set, it is simply the class name.
102
- def host_id
103
- if self.const_defined? :PLUGIN_HOST_ID
104
- self::PLUGIN_HOST_ID
105
- else
106
- name
107
- end
108
- end
109
-
110
- # Map a plugin_id to another.
111
- #
112
- # Usage: Put this in a file plugin_path/_map.rb.
113
- #
114
- # class MyColorHost < PluginHost
115
- # map :navy => :dark_blue,
116
- # :maroon => :brown,
117
- # :luna => :moon
118
- # end
119
- def map hash
120
- for from, to in hash
121
- from = validate_id from
122
- to = validate_id to
123
- plugin_hash[from] = to unless plugin_hash.has_key? from
124
- end
125
- end
126
-
127
- # Define the default plugin to use when no plugin is found
128
- # for a given id.
129
- #
130
- # See also map.
131
- #
132
- # class MyColorHost < PluginHost
133
- # map :navy => :dark_blue
134
- # default :gray
135
- # end
136
- def default id
137
- id = validate_id id
138
- plugin_hash[nil] = id
139
- end
140
-
141
- # Every plugin must register itself for one or more
142
- # +ids+ by calling register_for, which calls this method.
143
- #
144
- # See Plugin#register_for.
145
- def register plugin, *ids
146
- for id in ids
147
- unless id.is_a? Symbol
148
- raise ArgumentError,
149
- "id must be a Symbol, but it was a #{id.class}"
150
- end
151
- plugin_hash[validate_id(id)] = plugin
152
- end
153
- end
154
-
155
- # A Hash of plugion_id => Plugin pairs.
156
- def plugin_hash
157
- @plugin_hash ||= create_plugin_hash
158
- end
159
-
160
- # Returns an array of all .rb files in the plugin path.
161
- #
162
- # The extension .rb is not included.
163
- def all_plugin_names
164
- Dir[path_to('*')].select do |file|
165
- File.basename(file)[/^(?!_)\w+\.rb$/]
166
- end.map do |file|
167
- File.basename file, '.rb'
168
- end
169
- end
170
-
171
- # Makes a map of all loaded plugins.
172
- def inspect
173
- map = plugin_hash.dup
174
- map.each do |id, plugin|
175
- map[id] = plugin.to_s[/(?>[\w_]+)$/]
176
- end
177
- "#{name}[#{host_id}]#{map.inspect}"
178
- end
179
-
180
- protected
181
- # Created a new plugin list and stores it to @plugin_hash.
182
- def create_plugin_hash
183
- @plugin_hash =
184
- Hash.new do |h, plugin_id|
185
- id = validate_id(plugin_id)
186
- path = path_to id
187
- begin
188
- require path
189
- rescue LoadError => boom
190
- if h.has_key? nil # default plugin
191
- h[id] = h[nil]
192
- else
193
- raise PluginNotFound, 'Could not load plugin %p: %s' % [id, boom]
194
- end
195
- else
196
- # Plugin should have registered by now
197
- unless h.has_key? id
198
- raise PluginNotFound,
199
- "No #{self.name} plugin for #{id.inspect} found in #{path}."
200
- end
201
- end
202
- h[id]
203
- end
204
- end
205
-
206
- # Loads the map file (see map).
207
- #
208
- # This is done automatically when plugin_path is called.
209
- def load_map
210
- mapfile = path_to '_map'
211
- if File.exist? mapfile
212
- require mapfile
213
- elsif $DEBUG
214
- warn 'no _map.rb found for %s' % name
215
- end
216
- end
217
-
218
- # Returns the Plugin for +id+.
219
- # Use it like Hash#fetch.
220
- #
221
- # Example:
222
- # yaml_plugin = MyPluginHost[:yaml, :default]
223
- def fetch id, *args, &blk
224
- plugin_hash.fetch validate_id(id), *args, &blk
225
- end
226
-
227
- # Returns the expected path to the plugin file for the given id.
228
- def path_to plugin_id
229
- File.join plugin_path, "#{plugin_id}.rb"
230
- end
231
-
232
- # Converts +id+ to a Symbol if it is a String,
233
- # or returns +id+ if it already is a Symbol.
234
- #
235
- # Raises +ArgumentError+ for all other objects, or if the
236
- # given String includes non-alphanumeric characters (\W).
237
- def validate_id id
238
- if id.is_a? Symbol or id.nil?
239
- id
240
- elsif id.is_a? String
241
- if id[/\w+/] == id
242
- id.to_sym
243
- else
244
- raise ArgumentError, "Invalid id: '#{id}' given."
245
- end
246
- else
247
- raise ArgumentError,
248
- "String or Symbol expected, but #{id.class} given."
249
- end
250
- end
251
-
252
- end
253
-
254
-
255
- # = Plugin
256
- #
257
- # Plugins have to include this module.
258
- #
259
- # IMPORTANT: use extend for this module.
260
- #
261
- # Example: see PluginHost.
262
- module Plugin
263
-
264
- def included mod
265
- warn "#{name} should not be included. Use extend."
266
- end
267
-
268
- # Register this class for the given langs.
269
- # Example:
270
- # class MyPlugin < PluginHost::BaseClass
271
- # register_for :my_id
272
- # ...
273
- # end
274
- #
275
- # See PluginHost.register.
276
- def register_for *ids
277
- plugin_host.register self, *ids
278
- end
279
-
280
- # The host for this Plugin class.
281
- def plugin_host host = nil
282
- if host and not host.is_a? PluginHost
283
- raise ArgumentError,
284
- "PluginHost expected, but #{host.class} given."
285
- end
286
- self.const_set :PLUGIN_HOST, host if host
287
- self::PLUGIN_HOST
288
- end
289
-
290
- # Require some helper files.
291
- #
292
- # Example:
293
- #
294
- # class MyPlugin < PluginHost::BaseClass
295
- # register_for :my_id
296
- # helper :my_helper
297
- #
298
- # The above example loads the file myplugin/my_helper.rb relative to the
299
- # file in which MyPlugin was defined.
300
- def helper *helpers
301
- for helper in helpers
302
- self::PLUGIN_HOST.require_helper plugin_id, helper.to_s
303
- end
304
- end
305
-
306
- # Returns the pulgin id used by the engine.
307
- def plugin_id
308
- name[/[\w_]+$/].downcase
309
- end
310
-
311
- end
312
-
313
-
314
- # Convenience method for plugin loading.
315
- # The syntax used is:
316
- #
317
- # require_plugin '<Host ID>/<Plugin ID>'
318
- #
319
- # Returns the loaded plugin.
320
- def require_plugin path
321
- host_id, plugin_id = path.split '/', 2
322
- host = PluginHost.host_by_id(host_id)
323
- raise PluginHost::HostNotFound,
324
- "No host for #{host_id.inspect} found." unless host
325
- host.load plugin_id
326
- end
1
+ # = PluginHost
2
+ #
3
+ # $Id: plugin.rb 174 2006-10-15 09:08:50Z murphy $
4
+ #
5
+ # A simple subclass plugin system.
6
+ #
7
+ # Example:
8
+ # class Generators < PluginHost
9
+ # plugin_path 'app/generators'
10
+ # end
11
+ #
12
+ # class Generator
13
+ # extend Plugin
14
+ # PLUGIN_HOST = Generators
15
+ # end
16
+ #
17
+ # class FancyGenerator < Generator
18
+ # register_for :fancy
19
+ # end
20
+ #
21
+ # Generators[:fancy] #-> FancyGenerator
22
+ # # or
23
+ # require_plugin 'Generators/fancy'
24
+ module PluginHost
25
+
26
+ # Raised if Encoders::[] fails because:
27
+ # * a file could not be found
28
+ # * the requested Encoder is not registered
29
+ PluginNotFound = Class.new Exception
30
+ HostNotFound = Class.new Exception
31
+
32
+ PLUGIN_HOSTS = []
33
+ PLUGIN_HOSTS_BY_ID = {} # dummy hash
34
+
35
+ # Loads all plugins using all_plugin_names and load.
36
+ def load_all
37
+ for plugin in all_plugin_names
38
+ load plugin
39
+ end
40
+ end
41
+
42
+ # Returns the Plugin for +id+.
43
+ #
44
+ # Example:
45
+ # yaml_plugin = MyPluginHost[:yaml]
46
+ def [] id, *args, &blk
47
+ plugin = validate_id(id)
48
+ begin
49
+ plugin = plugin_hash.[] plugin, *args, &blk
50
+ end while plugin.is_a? Symbol
51
+ plugin
52
+ end
53
+
54
+ # Alias for +[]+.
55
+ alias load []
56
+
57
+ def require_helper plugin_id, helper_name
58
+ path = path_to File.join(plugin_id, helper_name)
59
+ require path
60
+ end
61
+
62
+ class << self
63
+
64
+ # Adds the module/class to the PLUGIN_HOSTS list.
65
+ def extended mod
66
+ PLUGIN_HOSTS << mod
67
+ end
68
+
69
+ # Warns you that you should not #include this module.
70
+ def included mod
71
+ warn "#{name} should not be included. Use extend."
72
+ end
73
+
74
+ # Find the PluginHost for host_id.
75
+ def host_by_id host_id
76
+ unless PLUGIN_HOSTS_BY_ID.default_proc
77
+ ph = Hash.new do |h, a_host_id|
78
+ for host in PLUGIN_HOSTS
79
+ h[host.host_id] = host
80
+ end
81
+ h.fetch a_host_id, nil
82
+ end
83
+ PLUGIN_HOSTS_BY_ID.replace ph
84
+ end
85
+ PLUGIN_HOSTS_BY_ID[host_id]
86
+ end
87
+
88
+ end
89
+
90
+ # The path where the plugins can be found.
91
+ def plugin_path *args
92
+ unless args.empty?
93
+ @plugin_path = File.expand_path File.join(*args)
94
+ load_map
95
+ end
96
+ @plugin_path
97
+ end
98
+
99
+ # The host's ID.
100
+ #
101
+ # If PLUGIN_HOST_ID is not set, it is simply the class name.
102
+ def host_id
103
+ if self.const_defined? :PLUGIN_HOST_ID
104
+ self::PLUGIN_HOST_ID
105
+ else
106
+ name
107
+ end
108
+ end
109
+
110
+ # Map a plugin_id to another.
111
+ #
112
+ # Usage: Put this in a file plugin_path/_map.rb.
113
+ #
114
+ # class MyColorHost < PluginHost
115
+ # map :navy => :dark_blue,
116
+ # :maroon => :brown,
117
+ # :luna => :moon
118
+ # end
119
+ def map hash
120
+ for from, to in hash
121
+ from = validate_id from
122
+ to = validate_id to
123
+ plugin_hash[from] = to unless plugin_hash.has_key? from
124
+ end
125
+ end
126
+
127
+ # Define the default plugin to use when no plugin is found
128
+ # for a given id.
129
+ #
130
+ # See also map.
131
+ #
132
+ # class MyColorHost < PluginHost
133
+ # map :navy => :dark_blue
134
+ # default :gray
135
+ # end
136
+ def default id
137
+ id = validate_id id
138
+ plugin_hash[nil] = id
139
+ end
140
+
141
+ # Every plugin must register itself for one or more
142
+ # +ids+ by calling register_for, which calls this method.
143
+ #
144
+ # See Plugin#register_for.
145
+ def register plugin, *ids
146
+ for id in ids
147
+ unless id.is_a? Symbol
148
+ raise ArgumentError,
149
+ "id must be a Symbol, but it was a #{id.class}"
150
+ end
151
+ plugin_hash[validate_id(id)] = plugin
152
+ end
153
+ end
154
+
155
+ # A Hash of plugion_id => Plugin pairs.
156
+ def plugin_hash
157
+ @plugin_hash ||= create_plugin_hash
158
+ end
159
+
160
+ # Returns an array of all .rb files in the plugin path.
161
+ #
162
+ # The extension .rb is not included.
163
+ def all_plugin_names
164
+ Dir[path_to('*')].select do |file|
165
+ File.basename(file)[/^(?!_)\w+\.rb$/]
166
+ end.map do |file|
167
+ File.basename file, '.rb'
168
+ end
169
+ end
170
+
171
+ # Makes a map of all loaded plugins.
172
+ def inspect
173
+ map = plugin_hash.dup
174
+ map.each do |id, plugin|
175
+ map[id] = plugin.to_s[/(?>[\w_]+)$/]
176
+ end
177
+ "#{name}[#{host_id}]#{map.inspect}"
178
+ end
179
+
180
+ protected
181
+ # Created a new plugin list and stores it to @plugin_hash.
182
+ def create_plugin_hash
183
+ @plugin_hash =
184
+ Hash.new do |h, plugin_id|
185
+ id = validate_id(plugin_id)
186
+ path = path_to id
187
+ begin
188
+ require path
189
+ rescue LoadError => boom
190
+ if h.has_key? nil # default plugin
191
+ h[id] = h[nil]
192
+ else
193
+ raise PluginNotFound, 'Could not load plugin %p: %s' % [id, boom]
194
+ end
195
+ else
196
+ # Plugin should have registered by now
197
+ unless h.has_key? id
198
+ raise PluginNotFound,
199
+ "No #{self.name} plugin for #{id.inspect} found in #{path}."
200
+ end
201
+ end
202
+ h[id]
203
+ end
204
+ end
205
+
206
+ # Loads the map file (see map).
207
+ #
208
+ # This is done automatically when plugin_path is called.
209
+ def load_map
210
+ mapfile = path_to '_map'
211
+ if File.exist? mapfile
212
+ require mapfile
213
+ elsif $DEBUG
214
+ warn 'no _map.rb found for %s' % name
215
+ end
216
+ end
217
+
218
+ # Returns the Plugin for +id+.
219
+ # Use it like Hash#fetch.
220
+ #
221
+ # Example:
222
+ # yaml_plugin = MyPluginHost[:yaml, :default]
223
+ def fetch id, *args, &blk
224
+ plugin_hash.fetch validate_id(id), *args, &blk
225
+ end
226
+
227
+ # Returns the expected path to the plugin file for the given id.
228
+ def path_to plugin_id
229
+ File.join plugin_path, "#{plugin_id}.rb"
230
+ end
231
+
232
+ # Converts +id+ to a Symbol if it is a String,
233
+ # or returns +id+ if it already is a Symbol.
234
+ #
235
+ # Raises +ArgumentError+ for all other objects, or if the
236
+ # given String includes non-alphanumeric characters (\W).
237
+ def validate_id id
238
+ if id.is_a? Symbol or id.nil?
239
+ id
240
+ elsif id.is_a? String
241
+ if id[/\w+/] == id
242
+ id.to_sym
243
+ else
244
+ raise ArgumentError, "Invalid id: '#{id}' given."
245
+ end
246
+ else
247
+ raise ArgumentError,
248
+ "String or Symbol expected, but #{id.class} given."
249
+ end
250
+ end
251
+
252
+ end
253
+
254
+
255
+ # = Plugin
256
+ #
257
+ # Plugins have to include this module.
258
+ #
259
+ # IMPORTANT: use extend for this module.
260
+ #
261
+ # Example: see PluginHost.
262
+ module Plugin
263
+
264
+ def included mod
265
+ warn "#{name} should not be included. Use extend."
266
+ end
267
+
268
+ # Register this class for the given langs.
269
+ # Example:
270
+ # class MyPlugin < PluginHost::BaseClass
271
+ # register_for :my_id
272
+ # ...
273
+ # end
274
+ #
275
+ # See PluginHost.register.
276
+ def register_for *ids
277
+ plugin_host.register self, *ids
278
+ end
279
+
280
+ # The host for this Plugin class.
281
+ def plugin_host host = nil
282
+ if host and not host.is_a? PluginHost
283
+ raise ArgumentError,
284
+ "PluginHost expected, but #{host.class} given."
285
+ end
286
+ self.const_set :PLUGIN_HOST, host if host
287
+ self::PLUGIN_HOST
288
+ end
289
+
290
+ # Require some helper files.
291
+ #
292
+ # Example:
293
+ #
294
+ # class MyPlugin < PluginHost::BaseClass
295
+ # register_for :my_id
296
+ # helper :my_helper
297
+ #
298
+ # The above example loads the file myplugin/my_helper.rb relative to the
299
+ # file in which MyPlugin was defined.
300
+ def helper *helpers
301
+ for helper in helpers
302
+ self::PLUGIN_HOST.require_helper plugin_id, helper.to_s
303
+ end
304
+ end
305
+
306
+ # Returns the pulgin id used by the engine.
307
+ def plugin_id
308
+ name[/[\w_]+$/].downcase
309
+ end
310
+
311
+ end
312
+
313
+
314
+ # Convenience method for plugin loading.
315
+ # The syntax used is:
316
+ #
317
+ # require_plugin '<Host ID>/<Plugin ID>'
318
+ #
319
+ # Returns the loaded plugin.
320
+ def require_plugin path
321
+ host_id, plugin_id = path.split '/', 2
322
+ host = PluginHost.host_by_id(host_id)
323
+ raise PluginHost::HostNotFound,
324
+ "No host for #{host_id.inspect} found." unless host
325
+ host.load plugin_id
326
+ end