mongrel 0.3.6 → 0.3.7
Sign up to get free protection for your applications and to get access to all the features.
- data/README +28 -1
- data/Rakefile +2 -2
- data/bin/mongrel_rails +102 -65
- data/bin/mongrel_rails_service +16 -7
- data/bin/mongrel_rails_svc +184 -87
- data/doc/rdoc/classes/Mongrel.html +1 -0
- data/doc/rdoc/classes/Mongrel/Const.html +3 -3
- data/doc/rdoc/classes/Mongrel/HeaderOut.html +10 -10
- data/doc/rdoc/classes/Mongrel/HeaderOut.src/{M000028.html → M000014.html} +4 -4
- data/doc/rdoc/classes/Mongrel/HeaderOut.src/{M000029.html → M000015.html} +7 -7
- data/doc/rdoc/classes/Mongrel/HttpParser.html +35 -35
- data/doc/rdoc/classes/Mongrel/HttpParser.src/{M000015.html → M000001.html} +0 -0
- data/doc/rdoc/classes/Mongrel/HttpParser.src/{M000016.html → M000002.html} +0 -0
- data/doc/rdoc/classes/Mongrel/HttpParser.src/{M000017.html → M000003.html} +0 -0
- data/doc/rdoc/classes/Mongrel/HttpParser.src/{M000018.html → M000004.html} +0 -0
- data/doc/rdoc/classes/Mongrel/HttpParser.src/{M000019.html → M000005.html} +0 -0
- data/doc/rdoc/classes/Mongrel/HttpParser.src/{M000020.html → M000006.html} +0 -0
- data/doc/rdoc/classes/Mongrel/HttpParser.src/{M000021.html → M000007.html} +0 -0
- data/doc/rdoc/classes/Mongrel/HttpRequest.html +5 -5
- data/doc/rdoc/classes/Mongrel/HttpRequest.src/{M000041.html → M000029.html} +25 -25
- data/doc/rdoc/classes/Mongrel/HttpResponse.html +36 -36
- data/doc/rdoc/classes/Mongrel/HttpResponse.src/{M000034.html → M000016.html} +7 -7
- data/doc/rdoc/classes/Mongrel/HttpResponse.src/{M000035.html → M000017.html} +6 -6
- data/doc/rdoc/classes/Mongrel/HttpResponse.src/{M000036.html → M000018.html} +5 -5
- data/doc/rdoc/classes/Mongrel/HttpResponse.src/{M000037.html → M000019.html} +5 -5
- data/doc/rdoc/classes/Mongrel/HttpResponse.src/{M000038.html → M000020.html} +6 -6
- data/doc/rdoc/classes/Mongrel/HttpResponse.src/{M000039.html → M000021.html} +6 -6
- data/doc/rdoc/classes/Mongrel/HttpResponse.src/{M000040.html → M000022.html} +6 -6
- data/doc/rdoc/classes/Mongrel/HttpServer.html +34 -35
- data/doc/rdoc/classes/Mongrel/HttpServer.src/M000008.html +36 -0
- data/doc/rdoc/classes/Mongrel/HttpServer.src/{M000023.html → M000009.html} +43 -43
- data/doc/rdoc/classes/Mongrel/HttpServer.src/{M000024.html → M000010.html} +31 -31
- data/doc/rdoc/classes/Mongrel/HttpServer.src/{M000025.html → M000011.html} +4 -4
- data/doc/rdoc/classes/Mongrel/HttpServer.src/{M000026.html → M000012.html} +4 -4
- data/doc/rdoc/classes/Mongrel/HttpServer.src/M000013.html +23 -0
- data/doc/rdoc/classes/{FactoryError.html → Mongrel/TimeoutWorker.html} +7 -34
- data/doc/rdoc/classes/Mongrel/URIClassifier.html +63 -20
- data/doc/rdoc/classes/Mongrel/URIClassifier.src/M000023.html +18 -0
- data/doc/rdoc/classes/Mongrel/URIClassifier.src/M000024.html +18 -0
- data/doc/rdoc/classes/Mongrel/URIClassifier.src/{M000030.html → M000025.html} +0 -0
- data/doc/rdoc/classes/Mongrel/URIClassifier.src/{M000031.html → M000026.html} +0 -0
- data/doc/rdoc/classes/Mongrel/URIClassifier.src/{M000032.html → M000027.html} +0 -0
- data/doc/rdoc/classes/Mongrel/URIClassifier.src/{M000033.html → M000028.html} +0 -0
- data/doc/rdoc/created.rid +1 -1
- data/doc/rdoc/files/README.html +35 -2
- data/doc/rdoc/files/lib/mongrel_rb.html +4 -1
- data/doc/rdoc/fr_class_index.html +1 -2
- data/doc/rdoc/fr_file_index.html +0 -1
- data/doc/rdoc/fr_method_index.html +29 -41
- data/lib/mongrel.rb +37 -9
- data/lib/mongrel/command.rb +13 -34
- data/lib/mongrel/plugins.rb +156 -0
- data/lib/mongrel/rails.rb +70 -0
- data/test/plugins/commands/test1.rb +19 -0
- data/test/test_plugins.rb +45 -0
- data/test/test_uriclassifier.rb +5 -1
- metadata +38 -49
- data/doc/rdoc/classes/FactoryError.src/M000001.html +0 -23
- data/doc/rdoc/classes/Mongrel/HttpServer.src/M000022.html +0 -33
- data/doc/rdoc/classes/Mongrel/HttpServer.src/M000027.html +0 -19
- data/doc/rdoc/classes/PluginFactory.html +0 -409
- data/doc/rdoc/classes/PluginFactory.src/M000002.html +0 -18
- data/doc/rdoc/classes/PluginFactory.src/M000003.html +0 -18
- data/doc/rdoc/classes/PluginFactory.src/M000004.html +0 -22
- data/doc/rdoc/classes/PluginFactory.src/M000005.html +0 -22
- data/doc/rdoc/classes/PluginFactory.src/M000006.html +0 -33
- data/doc/rdoc/classes/PluginFactory.src/M000007.html +0 -32
- data/doc/rdoc/classes/PluginFactory.src/M000008.html +0 -18
- data/doc/rdoc/classes/PluginFactory.src/M000009.html +0 -24
- data/doc/rdoc/classes/PluginFactory.src/M000010.html +0 -40
- data/doc/rdoc/classes/PluginFactory.src/M000011.html +0 -39
- data/doc/rdoc/classes/PluginFactory.src/M000012.html +0 -24
- data/doc/rdoc/classes/PluginFactory.src/M000013.html +0 -70
- data/doc/rdoc/classes/PluginFactory.src/M000014.html +0 -34
- data/doc/rdoc/files/lib/pluginfactory_rb.html +0 -132
- data/lib/pluginfactory.rb +0 -384
data/lib/pluginfactory.rb
DELETED
@@ -1,384 +0,0 @@
|
|
1
|
-
#!/usr/bin/env ruby -w
|
2
|
-
#
|
3
|
-
# This module contains the PluginFactory mixin. Including PluginFactory in your
|
4
|
-
# class turns it into a factory for its derivatives, capable of searching for
|
5
|
-
# and loading them by name. This is useful when you have an abstract base class
|
6
|
-
# which defines an interface and basic functionality for a part of a larger
|
7
|
-
# system, and a collection of subclasses which implement the interface for
|
8
|
-
# different underlying functionality.
|
9
|
-
#
|
10
|
-
# An example of where this might be useful is in a program which talks to a
|
11
|
-
# database. To avoid coupling it to a specific database, you use a Driver class
|
12
|
-
# which encapsulates your program's interaction with the database behind a
|
13
|
-
# useful interface. Now you can create a concrete implementation of the Driver
|
14
|
-
# class for each kind of database you wish to talk to. If you make the base
|
15
|
-
# Driver class a PluginFactory, too, you can add new drivers simply by dropping
|
16
|
-
# them in a directory and using the Driver's <tt>create</tt> method to
|
17
|
-
# instantiate them:
|
18
|
-
#
|
19
|
-
# == Creation Argument Variants
|
20
|
-
#
|
21
|
-
# The +create+ class method added to your class by PluginFactory searches for your module using
|
22
|
-
#
|
23
|
-
# == Synopsis
|
24
|
-
#
|
25
|
-
#---##### in driver.rb #####---
|
26
|
-
#
|
27
|
-
# require "PluginFactory"
|
28
|
-
#
|
29
|
-
# class Driver
|
30
|
-
# include PluginFactory
|
31
|
-
# def self::derivativeDirs
|
32
|
-
# ["drivers"]
|
33
|
-
# end
|
34
|
-
# end
|
35
|
-
#
|
36
|
-
#---##########
|
37
|
-
#
|
38
|
-
#---##### in drivers/mysql.rb #####
|
39
|
-
#
|
40
|
-
# require 'driver'
|
41
|
-
#
|
42
|
-
# class MysqlDriver < Driver
|
43
|
-
# ...implementation...
|
44
|
-
# end
|
45
|
-
#
|
46
|
-
#---##########
|
47
|
-
#
|
48
|
-
#---##### in /usr/lib/ruby/1.8/PostgresDriver.rb #####
|
49
|
-
#
|
50
|
-
# require 'driver'
|
51
|
-
#
|
52
|
-
# class PostgresDriver < Driver
|
53
|
-
# ...implementation...
|
54
|
-
# end
|
55
|
-
#
|
56
|
-
#---##########
|
57
|
-
#
|
58
|
-
#---##### elsewhere #####
|
59
|
-
#
|
60
|
-
# require 'driver'
|
61
|
-
#
|
62
|
-
# config[:driver_type] #=> "mysql"
|
63
|
-
# driver = Driver::create( config[:driver_type] )
|
64
|
-
# driver.class #=> MysqlDriver
|
65
|
-
# pgdriver = Driver::create( "PostGresDriver" )
|
66
|
-
#
|
67
|
-
#---##########
|
68
|
-
#
|
69
|
-
# == Rcsid
|
70
|
-
#
|
71
|
-
# $Id: pluginfactory.rb 32 2005-03-05 00:21:05Z ged $
|
72
|
-
#
|
73
|
-
# == Authors
|
74
|
-
#
|
75
|
-
# * Martin Chase <stillflame@FaerieMUD.org>
|
76
|
-
# * Michael Granger <ged@FaerieMUD.org>
|
77
|
-
#
|
78
|
-
# modified temporarily by Zed A. Shaw until license attribution can be given.
|
79
|
-
#---
|
80
|
-
#
|
81
|
-
# Please see the file docs/COPYRIGHT for licensing details.
|
82
|
-
#
|
83
|
-
|
84
|
-
|
85
|
-
### An exception class for PluginFactory specific errors.
|
86
|
-
class FactoryError < RuntimeError
|
87
|
-
def initialize( *args )
|
88
|
-
if ! args.empty?
|
89
|
-
msg = args.collect {|a| a.to_s}.join
|
90
|
-
super( msg )
|
91
|
-
else
|
92
|
-
super( message )
|
93
|
-
end
|
94
|
-
end
|
95
|
-
end # class FactoryError
|
96
|
-
|
97
|
-
|
98
|
-
### A mixin that adds PluginFactory class methods to a base class, so that
|
99
|
-
### subclasses may be instantiated by name.
|
100
|
-
module PluginFactory
|
101
|
-
|
102
|
-
### A callback for logging the various debug and information this module
|
103
|
-
### has to log. Should take two arguments, the log level, possibly as a
|
104
|
-
### symbol, and the log message itself.
|
105
|
-
@logger_callback = nil
|
106
|
-
class << self
|
107
|
-
attr_accessor :logger_callback
|
108
|
-
end
|
109
|
-
|
110
|
-
### If the logger callback is set, use it to pass on a log entry. First argument is
|
111
|
-
def self::log(level, *msg)
|
112
|
-
@logger_callback.call(level, msg.join) if @logger_callback
|
113
|
-
end
|
114
|
-
|
115
|
-
|
116
|
-
### Inclusion callback -- extends the including class.
|
117
|
-
def self::included( klass )
|
118
|
-
klass.extend( self )
|
119
|
-
end
|
120
|
-
|
121
|
-
|
122
|
-
### Raise an exception if the object being extended is anything but a
|
123
|
-
### class.
|
124
|
-
def self::extend_object( obj )
|
125
|
-
unless obj.is_a?( Class )
|
126
|
-
raise TypeError, "Cannot extend a #{obj.class.name}", caller(1)
|
127
|
-
end
|
128
|
-
obj.instance_variable_set( :@derivatives, {} )
|
129
|
-
super
|
130
|
-
end
|
131
|
-
|
132
|
-
|
133
|
-
#############################################################
|
134
|
-
### M I X I N M E T H O D S
|
135
|
-
#############################################################
|
136
|
-
|
137
|
-
### Return the Hash of derivative classes, keyed by various versions of
|
138
|
-
### the class name.
|
139
|
-
def derivatives
|
140
|
-
ancestors.each {|klass|
|
141
|
-
if klass.instance_variables.include?( "@derivatives" )
|
142
|
-
break klass.instance_variable_get( :@derivatives )
|
143
|
-
end
|
144
|
-
}
|
145
|
-
end
|
146
|
-
|
147
|
-
|
148
|
-
### Returns the type name used when searching for a derivative.
|
149
|
-
def factoryType
|
150
|
-
base = nil
|
151
|
-
self.ancestors.each {|klass|
|
152
|
-
if klass.instance_variables.include?( "@derivatives" )
|
153
|
-
base = klass
|
154
|
-
break
|
155
|
-
end
|
156
|
-
}
|
157
|
-
|
158
|
-
raise FactoryError, "Couldn't find factory base for #{self.name}" if
|
159
|
-
base.nil?
|
160
|
-
|
161
|
-
if base.name =~ /^.*::(.*)/
|
162
|
-
return $1
|
163
|
-
else
|
164
|
-
return base.name
|
165
|
-
end
|
166
|
-
end
|
167
|
-
|
168
|
-
|
169
|
-
### Inheritance callback -- Register subclasses in the derivatives hash
|
170
|
-
### so that ::create knows about them.
|
171
|
-
def inherited( subclass )
|
172
|
-
keys = [ subclass.name, subclass.name.downcase, subclass ]
|
173
|
-
|
174
|
-
# Handle class names like 'FooBar' for 'Bar' factories.
|
175
|
-
if subclass.name.match( /(?:.*::)?(\w+)(?:#{self.factoryType})/i )
|
176
|
-
keys << Regexp.last_match[1].downcase
|
177
|
-
else
|
178
|
-
keys << subclass.name.sub( /.*::/, '' ).downcase
|
179
|
-
end
|
180
|
-
|
181
|
-
keys.uniq.each {|key|
|
182
|
-
#PluginFactory::log :info, "Registering %s derivative of %s as %p" %
|
183
|
-
# [ subclass.name, self.name, key ]
|
184
|
-
self.derivatives[ key ] = subclass
|
185
|
-
}
|
186
|
-
super
|
187
|
-
end
|
188
|
-
|
189
|
-
|
190
|
-
### Returns an Array of registered derivatives
|
191
|
-
def derivativeClasses
|
192
|
-
self.derivatives.values.uniq
|
193
|
-
end
|
194
|
-
|
195
|
-
|
196
|
-
### Given the <tt>className</tt> of the class to instantiate, and other
|
197
|
-
### arguments bound for the constructor of the new object, this method
|
198
|
-
### loads the derivative class if it is not loaded already (raising a
|
199
|
-
### LoadError if an appropriately-named file cannot be found), and
|
200
|
-
### instantiates it with the given <tt>args</tt>. The <tt>className</tt>
|
201
|
-
### may be the the fully qualified name of the class, the class object
|
202
|
-
### itself, or the unique part of the class name. The following examples
|
203
|
-
### would all try to load and instantiate a class called "FooListener"
|
204
|
-
### if Listener included Factory
|
205
|
-
### obj = Listener::create( 'FooListener' )
|
206
|
-
### obj = Listener::create( FooListener )
|
207
|
-
### obj = Listener::create( 'Foo' )
|
208
|
-
def create( subType, *args, &block )
|
209
|
-
subclass = getSubclass( subType )
|
210
|
-
|
211
|
-
return subclass.new( *args, &block )
|
212
|
-
rescue => err
|
213
|
-
nicetrace = err.backtrace.reject {|frame| /#{__FILE__}/ =~ frame}
|
214
|
-
msg = "When creating '#{subType}': " + err.message
|
215
|
-
Kernel::raise( err.class, msg, nicetrace )
|
216
|
-
end
|
217
|
-
|
218
|
-
|
219
|
-
### Given a <tt>className</tt> like that of the first argument to
|
220
|
-
### #create, attempt to load the corresponding class if it is not
|
221
|
-
### already loaded and return the class object.
|
222
|
-
def getSubclass( className )
|
223
|
-
return self if ( self.name == className || className == '' )
|
224
|
-
return className if className.is_a?( Class ) && className >= self
|
225
|
-
|
226
|
-
unless self.derivatives.has_key?( className.downcase )
|
227
|
-
self.loadDerivative( className )
|
228
|
-
|
229
|
-
unless self.derivatives.has_key?( className.downcase )
|
230
|
-
raise FactoryError,
|
231
|
-
"loadDerivative(%s) didn't add a '%s' key to the "\
|
232
|
-
"registry for %s" %
|
233
|
-
[ className, className.downcase, self.name ]
|
234
|
-
end
|
235
|
-
|
236
|
-
subclass = self.derivatives[ className.downcase ]
|
237
|
-
unless subclass.is_a?( Class )
|
238
|
-
raise FactoryError,
|
239
|
-
"loadDerivative(%s) added something other than a class "\
|
240
|
-
"to the registry for %s: %p" %
|
241
|
-
[ className, self.name, subclass ]
|
242
|
-
end
|
243
|
-
end
|
244
|
-
|
245
|
-
return self.derivatives[ className.downcase ]
|
246
|
-
end
|
247
|
-
|
248
|
-
|
249
|
-
### Calculates an appropriate filename for the derived class using the
|
250
|
-
### name of the base class and tries to load it via <tt>require</tt>. If
|
251
|
-
### the including class responds to a method named
|
252
|
-
### <tt>derivativeDirs</tt>, its return value (either a String, or an
|
253
|
-
### array of Strings) is added to the list of prefix directories to try
|
254
|
-
### when attempting to require a modules. Eg., if
|
255
|
-
### <tt>class.derivativeDirs</tt> returns <tt>['foo','bar']</tt> the
|
256
|
-
### require line is tried with both <tt>'foo/'</tt> and <tt>'bar/'</tt>
|
257
|
-
### prepended to it.
|
258
|
-
def loadDerivative( className )
|
259
|
-
className = className.to_s
|
260
|
-
|
261
|
-
#PluginFactory::log :debug, "Loading derivative #{className}"
|
262
|
-
|
263
|
-
# Get the unique part of the derived class name and try to
|
264
|
-
# load it from one of the derivative subdirs, if there are
|
265
|
-
# any.
|
266
|
-
modName = self.getModuleName( className )
|
267
|
-
self.requireDerivative( modName )
|
268
|
-
|
269
|
-
# Check to see if the specified listener is now loaded. If it
|
270
|
-
# is not, raise an error to that effect.
|
271
|
-
unless self.derivatives[ className.downcase ]
|
272
|
-
raise FactoryError,
|
273
|
-
"Couldn't find a %s named '%s'. Loaded derivatives are: %p" % [
|
274
|
-
self.factoryType,
|
275
|
-
className.downcase,
|
276
|
-
self.derivatives.keys,
|
277
|
-
], caller(3)
|
278
|
-
end
|
279
|
-
|
280
|
-
return true
|
281
|
-
end
|
282
|
-
|
283
|
-
|
284
|
-
### Build and return the unique part of the given <tt>className</tt>
|
285
|
-
### either by stripping leading namespaces if the name already has the
|
286
|
-
### name of the factory type in it (eg., 'My::FooService' for Service,
|
287
|
-
### or by appending the factory type if it doesn't.
|
288
|
-
def getModuleName( className )
|
289
|
-
if className =~ /\w+#{self.factoryType}/
|
290
|
-
modName = className.sub( /(?:.*::)?(\w+)(?:#{self.factoryType})/, "\\1" )
|
291
|
-
else
|
292
|
-
modName = className
|
293
|
-
end
|
294
|
-
|
295
|
-
return modName
|
296
|
-
end
|
297
|
-
|
298
|
-
|
299
|
-
### If the factory responds to the #derivativeDirs method, call
|
300
|
-
### it and use the returned array as a list of directories to
|
301
|
-
### search for the module with the specified <tt>modName</tt>.
|
302
|
-
def requireDerivative( modName )
|
303
|
-
|
304
|
-
# See if we have a list of special subdirs that derivatives
|
305
|
-
# live in
|
306
|
-
if ( self.respond_to?(:derivativeDirs) )
|
307
|
-
subdirs = self.derivativeDirs
|
308
|
-
subdirs = [ subdirs ] unless subdirs.is_a?( Array )
|
309
|
-
|
310
|
-
# If not, just try requiring it from $LOAD_PATH
|
311
|
-
else
|
312
|
-
subdirs = ['']
|
313
|
-
end
|
314
|
-
|
315
|
-
fatals = []
|
316
|
-
|
317
|
-
# Iterate over the subdirs until we successfully require a
|
318
|
-
# module.
|
319
|
-
catch( :found ) {
|
320
|
-
subdirs.collect {|dir| dir.strip}.each do |subdir|
|
321
|
-
self.makeRequirePath( modName, subdir ).each {|path|
|
322
|
-
#PluginFactory::log :debug, "Trying #{path}..."
|
323
|
-
|
324
|
-
# Try to require the module, saving errors and jumping
|
325
|
-
# out of the catch block on success.
|
326
|
-
begin
|
327
|
-
require( path.untaint )
|
328
|
-
rescue LoadError => err
|
329
|
-
PluginFactory::log :debug,
|
330
|
-
"No module at '%s', trying the next alternative: '%s'" %
|
331
|
-
[ path, err.message ]
|
332
|
-
rescue ScriptError,StandardError => err
|
333
|
-
fatals << err
|
334
|
-
PluginFactory::log :error,
|
335
|
-
"Found '#{path}', but encountered an error: %s\n\t%s" %
|
336
|
-
[ err.message, err.backtrace.join("\n\t") ]
|
337
|
-
else
|
338
|
-
#PluginFactory::log :debug,
|
339
|
-
# "Found '#{path}'. Throwing :found"
|
340
|
-
throw :found
|
341
|
-
end
|
342
|
-
}
|
343
|
-
end
|
344
|
-
|
345
|
-
#PluginFactory::log :debug, "fatals = %p" % [ fatals ]
|
346
|
-
|
347
|
-
# Re-raise is there was a file found, but it didn't load for
|
348
|
-
# some reason.
|
349
|
-
if ! fatals.empty?
|
350
|
-
#PluginFactory::log :debug, "Re-raising first fatal error"
|
351
|
-
Kernel::raise( fatals.first )
|
352
|
-
end
|
353
|
-
|
354
|
-
nil
|
355
|
-
}
|
356
|
-
end
|
357
|
-
|
358
|
-
|
359
|
-
### Make a list of permutations of the given +modname+ for the given
|
360
|
-
### +subdir+. Called on a +DataDriver+ class with the arguments 'Socket' and
|
361
|
-
### 'drivers', returns:
|
362
|
-
### ["drivers/socketdatadriver", "drivers/socketDataDriver",
|
363
|
-
### "drivers/SocketDataDriver", "drivers/socket", "drivers/Socket"]
|
364
|
-
def makeRequirePath( modname, subdir )
|
365
|
-
path = []
|
366
|
-
myname = self.factoryType
|
367
|
-
|
368
|
-
# Make permutations of the two parts
|
369
|
-
path << modname
|
370
|
-
path << modname.downcase
|
371
|
-
path << modname + myname
|
372
|
-
path << modname.downcase + myname
|
373
|
-
path << modname.downcase + myname.downcase
|
374
|
-
|
375
|
-
# If a non-empty subdir was given, prepend it to all the items in the
|
376
|
-
# path
|
377
|
-
unless subdir.nil? or subdir.empty?
|
378
|
-
path.collect! {|m| File::join(subdir, m)}
|
379
|
-
end
|
380
|
-
|
381
|
-
return path.uniq.reverse
|
382
|
-
end
|
383
|
-
|
384
|
-
end # module Factory
|