mongrel 0.3.6 → 0.3.7

Sign up to get free protection for your applications and to get access to all the features.
Files changed (76) hide show
  1. data/README +28 -1
  2. data/Rakefile +2 -2
  3. data/bin/mongrel_rails +102 -65
  4. data/bin/mongrel_rails_service +16 -7
  5. data/bin/mongrel_rails_svc +184 -87
  6. data/doc/rdoc/classes/Mongrel.html +1 -0
  7. data/doc/rdoc/classes/Mongrel/Const.html +3 -3
  8. data/doc/rdoc/classes/Mongrel/HeaderOut.html +10 -10
  9. data/doc/rdoc/classes/Mongrel/HeaderOut.src/{M000028.html → M000014.html} +4 -4
  10. data/doc/rdoc/classes/Mongrel/HeaderOut.src/{M000029.html → M000015.html} +7 -7
  11. data/doc/rdoc/classes/Mongrel/HttpParser.html +35 -35
  12. data/doc/rdoc/classes/Mongrel/HttpParser.src/{M000015.html → M000001.html} +0 -0
  13. data/doc/rdoc/classes/Mongrel/HttpParser.src/{M000016.html → M000002.html} +0 -0
  14. data/doc/rdoc/classes/Mongrel/HttpParser.src/{M000017.html → M000003.html} +0 -0
  15. data/doc/rdoc/classes/Mongrel/HttpParser.src/{M000018.html → M000004.html} +0 -0
  16. data/doc/rdoc/classes/Mongrel/HttpParser.src/{M000019.html → M000005.html} +0 -0
  17. data/doc/rdoc/classes/Mongrel/HttpParser.src/{M000020.html → M000006.html} +0 -0
  18. data/doc/rdoc/classes/Mongrel/HttpParser.src/{M000021.html → M000007.html} +0 -0
  19. data/doc/rdoc/classes/Mongrel/HttpRequest.html +5 -5
  20. data/doc/rdoc/classes/Mongrel/HttpRequest.src/{M000041.html → M000029.html} +25 -25
  21. data/doc/rdoc/classes/Mongrel/HttpResponse.html +36 -36
  22. data/doc/rdoc/classes/Mongrel/HttpResponse.src/{M000034.html → M000016.html} +7 -7
  23. data/doc/rdoc/classes/Mongrel/HttpResponse.src/{M000035.html → M000017.html} +6 -6
  24. data/doc/rdoc/classes/Mongrel/HttpResponse.src/{M000036.html → M000018.html} +5 -5
  25. data/doc/rdoc/classes/Mongrel/HttpResponse.src/{M000037.html → M000019.html} +5 -5
  26. data/doc/rdoc/classes/Mongrel/HttpResponse.src/{M000038.html → M000020.html} +6 -6
  27. data/doc/rdoc/classes/Mongrel/HttpResponse.src/{M000039.html → M000021.html} +6 -6
  28. data/doc/rdoc/classes/Mongrel/HttpResponse.src/{M000040.html → M000022.html} +6 -6
  29. data/doc/rdoc/classes/Mongrel/HttpServer.html +34 -35
  30. data/doc/rdoc/classes/Mongrel/HttpServer.src/M000008.html +36 -0
  31. data/doc/rdoc/classes/Mongrel/HttpServer.src/{M000023.html → M000009.html} +43 -43
  32. data/doc/rdoc/classes/Mongrel/HttpServer.src/{M000024.html → M000010.html} +31 -31
  33. data/doc/rdoc/classes/Mongrel/HttpServer.src/{M000025.html → M000011.html} +4 -4
  34. data/doc/rdoc/classes/Mongrel/HttpServer.src/{M000026.html → M000012.html} +4 -4
  35. data/doc/rdoc/classes/Mongrel/HttpServer.src/M000013.html +23 -0
  36. data/doc/rdoc/classes/{FactoryError.html → Mongrel/TimeoutWorker.html} +7 -34
  37. data/doc/rdoc/classes/Mongrel/URIClassifier.html +63 -20
  38. data/doc/rdoc/classes/Mongrel/URIClassifier.src/M000023.html +18 -0
  39. data/doc/rdoc/classes/Mongrel/URIClassifier.src/M000024.html +18 -0
  40. data/doc/rdoc/classes/Mongrel/URIClassifier.src/{M000030.html → M000025.html} +0 -0
  41. data/doc/rdoc/classes/Mongrel/URIClassifier.src/{M000031.html → M000026.html} +0 -0
  42. data/doc/rdoc/classes/Mongrel/URIClassifier.src/{M000032.html → M000027.html} +0 -0
  43. data/doc/rdoc/classes/Mongrel/URIClassifier.src/{M000033.html → M000028.html} +0 -0
  44. data/doc/rdoc/created.rid +1 -1
  45. data/doc/rdoc/files/README.html +35 -2
  46. data/doc/rdoc/files/lib/mongrel_rb.html +4 -1
  47. data/doc/rdoc/fr_class_index.html +1 -2
  48. data/doc/rdoc/fr_file_index.html +0 -1
  49. data/doc/rdoc/fr_method_index.html +29 -41
  50. data/lib/mongrel.rb +37 -9
  51. data/lib/mongrel/command.rb +13 -34
  52. data/lib/mongrel/plugins.rb +156 -0
  53. data/lib/mongrel/rails.rb +70 -0
  54. data/test/plugins/commands/test1.rb +19 -0
  55. data/test/test_plugins.rb +45 -0
  56. data/test/test_uriclassifier.rb +5 -1
  57. metadata +38 -49
  58. data/doc/rdoc/classes/FactoryError.src/M000001.html +0 -23
  59. data/doc/rdoc/classes/Mongrel/HttpServer.src/M000022.html +0 -33
  60. data/doc/rdoc/classes/Mongrel/HttpServer.src/M000027.html +0 -19
  61. data/doc/rdoc/classes/PluginFactory.html +0 -409
  62. data/doc/rdoc/classes/PluginFactory.src/M000002.html +0 -18
  63. data/doc/rdoc/classes/PluginFactory.src/M000003.html +0 -18
  64. data/doc/rdoc/classes/PluginFactory.src/M000004.html +0 -22
  65. data/doc/rdoc/classes/PluginFactory.src/M000005.html +0 -22
  66. data/doc/rdoc/classes/PluginFactory.src/M000006.html +0 -33
  67. data/doc/rdoc/classes/PluginFactory.src/M000007.html +0 -32
  68. data/doc/rdoc/classes/PluginFactory.src/M000008.html +0 -18
  69. data/doc/rdoc/classes/PluginFactory.src/M000009.html +0 -24
  70. data/doc/rdoc/classes/PluginFactory.src/M000010.html +0 -40
  71. data/doc/rdoc/classes/PluginFactory.src/M000011.html +0 -39
  72. data/doc/rdoc/classes/PluginFactory.src/M000012.html +0 -24
  73. data/doc/rdoc/classes/PluginFactory.src/M000013.html +0 -70
  74. data/doc/rdoc/classes/PluginFactory.src/M000014.html +0 -34
  75. data/doc/rdoc/files/lib/pluginfactory_rb.html +0 -132
  76. data/lib/pluginfactory.rb +0 -384
@@ -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