trinidad 1.4.4 → 1.4.5.B1

Sign up to get free protection for your applications and to get access to all the features.
@@ -3,77 +3,119 @@ require 'trinidad/web_app'
3
3
 
4
4
  module Trinidad
5
5
  class Server
6
- attr_reader :config, :tomcat, :web_apps
6
+ attr_reader :config
7
7
 
8
8
  def initialize(config = Trinidad.configuration)
9
- load_config(config)
10
- configure_logging(@config[:log])
11
- load_tomcat_server
12
- @web_apps = create_web_apps
13
- load_host_monitor(@web_apps)
9
+ configure(config)
14
10
  end
15
11
 
16
- def load_config(config)
17
- add_default_web_app! config
12
+ def configure(config = Trinidad.configuration)
13
+ configure_logging config[:log]
18
14
  @config = config.freeze
19
15
  end
16
+ # @deprecated replaced with {#configure}
17
+ def load_config(config); configure(config); end
20
18
 
21
- def load_tomcat_server
22
- load_default_system_properties
23
-
24
- @tomcat = Trinidad::Tomcat::Tomcat.new
25
- @tomcat.base_dir = Dir.pwd
26
- @tomcat.hostname = @config[:address] || 'localhost'
27
- @tomcat.server.address = @config[:address]
28
- @tomcat.port = @config[:port].to_i
29
- create_hosts
30
- @tomcat.enable_naming
31
-
32
- add_http_connector if http_configured?
33
- add_ssl_connector if ssl_enabled?
34
- add_ajp_connector if ajp_enabled?
35
-
36
- @tomcat = Trinidad::Extensions.configure_server_extensions(@config[:extensions], @tomcat)
19
+ def hosts
20
+ @hosts ||= @config[:hosts]
37
21
  end
22
+ attr_writer :hosts
23
+
24
+ def app_base
25
+ @app_base ||= @config[:app_base] || @config[:apps_base]
26
+ end
27
+ attr_writer :app_base
38
28
 
39
- def load_host_monitor(apps)
40
- @tomcat.engine.find_children.each do |host|
41
- host.add_lifecycle_listener(Trinidad::Lifecycle::Host.new(self, *apps))
42
- end
29
+ def web_apps
30
+ @web_apps ||= @config[:web_apps] || @config[:webapps]
31
+ end
32
+ attr_writer :web_apps
33
+
34
+ def trap?
35
+ @trap ||= @config[:trap] if ! defined?(@trap) || @trap.nil?
36
+ @trap
43
37
  end
38
+ attr_writer :trap
44
39
 
45
40
  def ssl_enabled?
46
- !! @config[:ssl] && ! @config[:ssl].empty?
41
+ if ! defined?(@ssl_enabled) || @ssl_enabled.nil?
42
+ @ssl_enabled ||= ( !! @config[:ssl] && ! @config[:ssl].empty? )
43
+ end
44
+ @ssl_enabled
47
45
  end
46
+ attr_writer :ssl_enabled
48
47
 
49
48
  def ajp_enabled?
50
- !! @config[:ajp] && ! @config[:ajp].empty?
49
+ if ! defined?(@ajp_enabled) || @ajp_enabled.nil?
50
+ @ajp_enabled ||= ( !! @config[:ajp] && ! @config[:ajp].empty? )
51
+ end
52
+ @ajp_enabled
51
53
  end
54
+ attr_writer :ajp_enabled
52
55
 
53
56
  def http_configured?
54
- (!! @config[:http] && ! @config[:http].empty?) || @config[:address] != 'localhost'
57
+ if ! defined?(@http_configured) || @http_configured.nil?
58
+ @http_configured ||=
59
+ ( ( !! @config[:http] && ! @config[:http].empty? ) || @config[:address] != 'localhost' )
60
+ end
61
+ @http_configured
55
62
  end
63
+ attr_writer :http_configured
56
64
 
57
- def add_ajp_connector
58
- add_service_connector(@config[:ajp], 'AJP/1.3')
65
+ def tomcat; @tomcat ||= initialize_tomcat; end
66
+
67
+ def initialize_tomcat
68
+ set_system_properties
69
+
70
+ tomcat = Trinidad::Tomcat::Tomcat.new
71
+ tomcat.base_dir = config[:base_dir] || Dir.pwd
72
+ tomcat.hostname = config[:address] || 'localhost'
73
+ tomcat.server.address = config[:address]
74
+ tomcat.port = config[:port].to_i
75
+ default_host(tomcat)
76
+ create_hosts(tomcat)
77
+ tomcat.enable_naming
78
+
79
+ add_http_connector(tomcat) if http_configured?
80
+ add_ssl_connector(tomcat) if ssl_enabled?
81
+ add_ajp_connector(tomcat) if ajp_enabled?
82
+
83
+ Trinidad::Extensions.configure_server_extensions(config[:extensions], tomcat)
84
+ end
85
+ protected :initialize_tomcat
86
+ # #deprecated renamed to {#initialize_tomcat}
87
+ def load_tomcat_server; initialize_tomcat; end
88
+
89
+ def add_host_monitor(app_holders)
90
+ for host in tomcat.engine.find_children
91
+ host_apps = select_host_apps(app_holders, host)
92
+ host.add_lifecycle_listener(Trinidad::Lifecycle::Host.new(self, *host_apps))
93
+ end
59
94
  end
95
+ protected :add_host_monitor
96
+ # @deprecated replaced with {#setup_host_monitor}
97
+ def load_host_monitor(web_apps); add_host_monitor(web_apps); end
60
98
 
61
- def add_http_connector
62
- options = @config[:http] || {}
99
+ def add_ajp_connector(tomcat = @tomcat)
100
+ add_service_connector(@config[:ajp], 'AJP/1.3', tomcat)
101
+ end
102
+
103
+ def add_http_connector(tomcat = @tomcat)
104
+ options = config[:http] || {}
63
105
  options[:address] ||= @config[:address] if @config[:address] != 'localhost'
64
106
  options[:port] = @config[:port]
65
107
  options[:protocol_handler] = 'org.apache.coyote.http11.Http11NioProtocol' if options[:nio]
66
108
 
67
109
  if options[:apr]
68
- @tomcat.server.add_lifecycle_listener(Trinidad::Tomcat::AprLifecycleListener.new)
110
+ tomcat.server.add_lifecycle_listener(Trinidad::Tomcat::AprLifecycleListener.new)
69
111
  end
70
112
 
71
- connector = add_service_connector(options, options[:protocol_handler] || 'HTTP/1.1')
72
- @tomcat.connector = connector
113
+ connector = add_service_connector(options, options[:protocol_handler] || 'HTTP/1.1', tomcat)
114
+ tomcat.connector = connector
73
115
  end
74
116
 
75
- def add_ssl_connector
76
- options = @config[:ssl].merge({
117
+ def add_ssl_connector(tomcat = @tomcat)
118
+ options = config[:ssl].merge({
77
119
  :scheme => 'https',
78
120
  :secure => true,
79
121
  :SSLEnabled => 'true'
@@ -81,164 +123,362 @@ module Trinidad
81
123
 
82
124
  options[:keystoreFile] ||= options.delete(:keystore)
83
125
 
84
- if !options[:keystoreFile] && !options[:SSLCertificateFile]
126
+ if ! options[:keystoreFile] && ! options[:SSLCertificateFile]
85
127
  options[:keystoreFile] = 'ssl/keystore'
86
128
  options[:keystorePass] = 'waduswadus42'
87
129
  generate_default_keystore(options)
88
130
  end
89
131
 
90
- add_service_connector(options)
132
+ add_service_connector(options, nil, tomcat)
91
133
  end
92
134
 
93
- def add_service_connector(options, protocol = nil)
94
- connector = Trinidad::Tomcat::Connector.new(protocol)
135
+ def add_service_connector(options, protocol = nil, tomcat = @tomcat)
95
136
  opts = options.dup
96
137
 
138
+ connector = Trinidad::Tomcat::Connector.new(protocol)
97
139
  connector.scheme = opts.delete(:scheme) if opts[:scheme]
98
140
  connector.secure = opts.delete(:secure) || false
99
141
  connector.port = opts.delete(:port).to_i
100
142
 
101
143
  connector.protocol_handler_class_name = opts.delete(:protocol_handler) if opts[:protocol_handler]
102
144
 
103
- opts.each do |key, value|
104
- connector.setProperty(key.to_s, value.to_s)
105
- end
145
+ opts.each { |key, value| connector.setProperty(key.to_s, value.to_s) }
106
146
 
107
- @tomcat.service.add_connector(connector)
147
+ tomcat.service.add_connector(connector)
108
148
  connector
109
149
  end
150
+ private :add_service_connector
110
151
 
111
- def add_web_app(web_app, host = nil)
112
- host ||= web_app.config[:host] || @tomcat.host
113
- context = @tomcat.addWebapp(host, web_app.context_path, web_app.root_dir)
114
- Trinidad::Extensions.configure_webapp_extensions(web_app.extensions, @tomcat, context)
115
- context.add_lifecycle_listener(web_app.define_lifecycle)
152
+ def add_web_app(web_app, host = nil, start = nil)
153
+ host ||= begin
154
+ name = web_app.host_name
155
+ name ? find_host(name, tomcat) : tomcat.host
156
+ end
157
+ prev_start = host.start_children
158
+ context = begin
159
+ host.start_children = start unless start.nil?
160
+ # public Context addWebapp(Host host, String url, String name, String docBase)
161
+ tomcat.addWebapp(host, web_app.context_path, web_app.context_name, web_app.root_dir)
162
+ rescue java.lang.IllegalArgumentException => e
163
+ if e.message =~ /addChild\:/
164
+ context_name = web_app.context_name
165
+ logger.error "could not add application #{context_name.inspect} from #{web_app.root_dir}\n" <<
166
+ " (same context name is used for #{host.find_child(context_name).doc_base})"
167
+ raise "there's already an application named #{context_name.inspect} for host #{host.name.inspect}"
168
+ end
169
+ raise e
170
+ ensure
171
+ host.start_children = prev_start unless start.nil?
172
+ end
173
+ Trinidad::Extensions.configure_webapp_extensions(web_app.extensions, tomcat, context)
174
+ if lifecycle = web_app.define_lifecycle
175
+ context.add_lifecycle_listener(lifecycle)
176
+ end
116
177
  context
117
178
  end
118
179
 
180
+ def deploy_web_apps(tomcat = self.tomcat)
181
+ add_host_monitor web_apps = create_web_apps
182
+ web_apps
183
+ end
184
+
119
185
  def start
186
+ deploy_web_apps(tomcat)
187
+
120
188
  trap_signals if trap?
121
189
 
122
- @tomcat.start
123
- @tomcat.server.await
190
+ tomcat.start
191
+ tomcat.server.await
192
+ end
193
+
194
+ def start!
195
+ if defined?(@tomcat) && @tomcat
196
+ @tomcat.destroy; @tomcat = nil
197
+ end
198
+ start
124
199
  end
125
200
 
126
201
  def stop
127
- @tomcat.stop
202
+ if defined?(@tomcat) && @tomcat
203
+ @tomcat.stop; true
204
+ end
128
205
  end
129
206
 
130
207
  def stop!
131
- stop
132
- @tomcat.destroy
208
+ (@tomcat.destroy; true) if stop
133
209
  end
134
210
 
135
211
  protected
136
-
137
- def trap?
138
- !!@config[:trap]
139
- end
140
-
212
+
141
213
  def create_web_apps
142
- apps = [ create_from_web_apps ]
143
- apps << create_from_apps_base
144
- apps.flatten!; apps.compact!
145
- apps
146
- end
147
-
148
- def create_from_web_apps
149
- @config[:web_apps].map do |name, app_config|
150
- app_config[:context_name] ||= name
151
- create_web_app(app_config)
152
- end if @config[:web_apps]
153
- end
214
+ # add default web app if needed :
215
+ if ! web_apps && ! app_base && ! hosts
216
+ default_app = { :context_path => config[:context_path] }
217
+ root_dir = web_app_root_dir(config) || Dir.pwd
218
+ default_app[:root_dir] = root_dir if root_dir != false
219
+ default_app[:rackup] = config[:rackup] if config[:rackup]
154
220
 
155
- def create_from_apps_base
156
- if @config[:apps_base] || @config[:hosts]
157
- @tomcat.engine.find_children.map do |host|
158
- apps_base = host.app_base
221
+ self.web_apps = { :default => default_app }
222
+ end
159
223
 
160
- apps_path = Dir.glob(File.join(apps_base, '*')).
161
- select { |path| !(path =~ /tomcat\.\d+$/) }
224
+ apps = []
162
225
 
163
- apps_path.reject! { |path| apps_path.include?(path + '.war') }
226
+ # configured :web_apps
227
+ web_apps.each do |name, app_config|
228
+ app_config[:context_name] ||= name
229
+ apps << ( app_holder = create_web_app(app_config) ); app = app_holder.web_app
230
+ logger.info "Deploying from #{app.root_dir} as #{app.context_path}"
231
+ end if web_apps
232
+
233
+ # configured :app_base or :hosts - scan for applications in host's app_base directory :
234
+ tomcat.engine.find_children.each do |host|
235
+ apps_path = java.io.File.new(host.app_base).list.to_a
236
+ if host.deploy_ignore # respect deploy ignore pattern (even if not deploying on startup)
237
+ deploy_ignore_pattern = Regexp.new(host.deploy_ignore)
238
+ apps_path.reject! { |path| path =~ deploy_ignore_pattern }
239
+ end
240
+ # we do a bit of "default" filtering for hosts of our own :
241
+ work_dir = host.work_dir
242
+ apps_path.reject! do |path|
243
+ if path[0, 1] == '.' then true # ignore "hidden" files
244
+ elsif work_dir && work_dir == path then true
245
+ elsif ! work_dir && path =~ /tomcat\.\d+$/ then true # [host_base]/tomcat.8080
246
+ elsif path[-4..-1] == '.war' && apps_path.include?(path[0...-4]) # only keep expanded .war
247
+ logger.info "Expanded .war at #{path} - only deploying directory (.war ignored)"
248
+ true
249
+ end
250
+ end
164
251
 
165
- apps_path.map do |path|
166
- if File.directory?(path) || path =~ /\.war$/
167
- create_web_app({
168
- :context_name => File.basename(path),
169
- :root_dir => File.expand_path(path),
170
- :host => host
171
- })
252
+ apps_path.each do |path| # host web apps (from dir or .war files)
253
+ app_root = File.expand_path(path, host.app_base)
254
+ if File.directory?(app_root) || ( app_root[-4..-1] == '.war' )
255
+ app_base_name = File.basename(app_root)
256
+ deployed = apps.find do |app_holder|; web_app = app_holder.web_app
257
+ web_app.root_dir == app_root ||
258
+ web_app.context_path == Trinidad::Tomcat::ContextName.new(app_base_name).path
259
+ end
260
+ if deployed
261
+ logger.debug "Skipping auto-deploy from #{app_root} (already deployed)"
262
+ else
263
+ apps << ( app_holder = create_web_app({
264
+ :context_name => path, :root_dir => app_root, :host_name => host.name
265
+ }) ); app = app_holder.web_app
266
+ logger.info "Auto-Deploying from #{app.root_dir} as #{app.context_path}"
172
267
  end
173
268
  end
174
- end.flatten
175
- end
269
+ end
270
+ end if app_base || hosts
271
+
272
+ apps
176
273
  end
177
274
 
178
275
  def create_web_app(app_config)
276
+ host_name = app_config[:host_name] || 'localhost'
277
+ host = tomcat.engine.find_child(host_name)
278
+ app_config[:root_dir] = web_app_root_dir(app_config, host)
279
+
179
280
  web_app = WebApp.create(app_config, config)
180
281
  WebApp::Holder.new(web_app, add_web_app(web_app))
181
282
  end
182
-
183
- def create_hosts
184
- if @config[:hosts]
185
- @config[:hosts].each do |apps_base, names|
186
- create_host(apps_base, names)
283
+
284
+ def create_hosts(tomcat = @tomcat)
285
+ hosts.each do |app_base, host_config|
286
+ next if app_base == :default # @see #default_host
287
+ if host = find_host(app_base, host_config, tomcat)
288
+ setup_host(app_base, host_config, host)
289
+ else
290
+ create_host(app_base, host_config, tomcat)
187
291
  end
188
- elsif @config[:web_apps]
189
- # create the hosts when they are specified for each app into web_apps.
190
- # We must create them before creating the applications.
191
- @config[:web_apps].each do |_, app_config|
192
- if host_names = app_config.delete(:hosts)
193
- dir = web_app_root_dir(app_config)
194
- apps_base = File.dirname(dir) == '.' ? dir : File.dirname(dir)
195
- app_config[:host] = create_host(apps_base, host_names)
292
+ end if hosts
293
+
294
+ default_host = tomcat.host
295
+ default_app_base = ( default_host.app_base == DEFAULT_HOST_APP_BASE )
296
+ if self.app_base ||
297
+ ( default_app_base && ! File.exists?(DEFAULT_HOST_APP_BASE) )
298
+ tomcat.host.app_base = self.app_base || Dir.pwd
299
+ end
300
+
301
+ web_app_hosts = []
302
+ # create hosts as they are specified for each app in :web_apps :
303
+ # e.g. :app1 => { :root_dir => 'app1', :host => 'virtual.host' }
304
+ web_apps.each do |_, app_config|
305
+ if host_names = app_config[:hosts] || app_config[:host]
306
+ if host = find_host(host_names, tomcat)
307
+ app_root = web_app_root_dir(app_config, host)
308
+ set_host_app_base(app_root, host, default_host, web_app_hosts)
309
+ else
310
+ app_root = web_app_root_dir(app_config)
311
+ raise "no root for app #{app_config.inspect}" unless app_root
312
+ app_root = File.expand_path(app_root)
313
+ # for created hosts -> web-app per host by default
314
+ # thus new host's app_base will point to root_dir :
315
+ host = create_host(app_root, host_names, tomcat)
316
+ web_app_hosts << host
196
317
  end
318
+ app_config[:host_name] = host.name
197
319
  end
198
- else
199
- @tomcat.host.app_base = @config[:apps_base] || Dir.pwd
200
- end
320
+ end if web_apps
201
321
  end
202
-
203
- def create_host(apps_base, names)
204
- host_names = Array(names)
205
- host_name = host_names.shift
206
- unless host = @tomcat.engine.find_child(host_name)
207
- host = Trinidad::Tomcat::StandardHost.new
208
- host.name = host_name
209
- host.app_base = apps_base || Dir.pwd
210
- host_names.each { |name| host.add_alias(name) }
211
-
212
- @tomcat.engine.add_child host
213
- end
322
+
323
+ def create_host(app_base, host_config, tomcat = @tomcat)
324
+ host = Trinidad::Tomcat::StandardHost.new
325
+ host.app_base = nil # reset default app_base
326
+ host.deployXML = false # disabled by default
327
+ setup_host(app_base, host_config, host)
328
+ tomcat.engine.add_child host if tomcat
214
329
  host
215
330
  end
216
331
 
217
- def load_default_system_properties
218
- java.lang.System.set_property("org.apache.catalina.startup.EXIT_ON_INIT_FAILURE", 'true')
332
+ def setup_host(app_base, host_config, host)
333
+ if host_config.is_a?(Array)
334
+ name = host_config.shift
335
+ host_config = { :name => name, :aliases => host_config }
336
+ elsif host_config.is_a?(String) || host_config.is_a?(Symbol)
337
+ host_config = { :name => host_config }
338
+ else
339
+ host_config[:name] ||= app_base
340
+ end
341
+ host_config[:app_base] ||= app_base if app_base.is_a?(String)
342
+
343
+ host_config.each do |name, value|
344
+ case (name = name.to_sym)
345
+ when :app_base
346
+ host.app_base = value if default_host_base?(host)
347
+ when :aliases
348
+ aliases = host.find_aliases || []
349
+ value.each do |name|
350
+ next if (name = name.to_s) == host.name
351
+ host.add_alias(name) unless aliases.include?(name)
352
+ end if host_config[:aliases]
353
+ else
354
+ value = value.to_s if value.is_a?(Symbol)
355
+ host.send("#{name}=", value) # e.g. host.name = value
356
+ end
357
+ end
358
+ end
359
+
360
+ def set_system_properties(system = Java::JavaLang::System)
361
+ system.set_property("org.apache.catalina.startup.EXIT_ON_INIT_FAILURE", 'true')
219
362
  end
363
+ # @deprecated renamed to {#set_system_properties}
364
+ def load_default_system_properties; set_system_properties; end
220
365
 
221
366
  def configure_logging(log_level)
222
367
  Trinidad::Logging.configure(log_level)
223
368
  end
224
-
369
+
370
+ def logger; @logger ||= self.class.logger; end
371
+
372
+ def self.logger
373
+ Logging::LogFactory.getLog('org.apache.catalina.startup.Tomcat')
374
+ end
375
+
225
376
  private
226
-
227
- def add_default_web_app!(config)
228
- if ! config[:web_apps] && ! config[:apps_base] && ! config[:hosts]
229
- default_app = {
230
- :context_path => config[:context_path],
231
- :root_dir => web_app_root_dir(config),
232
- :log => config[:log]
233
- }
234
- default_app[:rackup] = config[:rackup] if config[:rackup]
235
377
 
236
- config[:web_apps] = { :default => default_app }
378
+ def default_host(tomcat = @tomcat)
379
+ host = tomcat.host # make sure we initialize default host
380
+ host.deployXML = false
381
+ host_config = @config[:host] || ( @config[:hosts] && @config[:hosts][:default] )
382
+ host_config.each { |name, value| host.send("#{name}=", value) } if host_config
383
+ host
384
+ end
385
+
386
+ DEFAULT_HOST_APP_BASE = 'webapps' # :nodoc:
387
+
388
+ def default_host_base?(host)
389
+ host.app_base.nil? || ( host.app_base == DEFAULT_HOST_APP_BASE && host.name == 'localhost' )
390
+ end
391
+
392
+ def set_host_app_base(app_root, host, default_host, web_app_hosts)
393
+ if host.app_base # we'll try setting a common parent :
394
+ require 'pathname'; app_path = Pathname.new(app_root)
395
+ base_path = Pathname.new(host.app_base)
396
+ unless app_path.exist?
397
+ app_path = app_path.relative_path_from(base_path) rescue app_path
398
+ end
399
+ app_real_path = begin; app_path.realpath.to_s; rescue
400
+ logger.warn "Application root #{app_root} does not exist !"
401
+ return
402
+ end
403
+ base_parent = false
404
+ 2.times do
405
+ begin
406
+ break if base_parent = ( app_real_path.index(base_path.realpath.to_s) == 0 )
407
+ rescue => e
408
+ logger.warn "Host #{host.name.inspect} app_base does not exist," <<
409
+ " try configuring an absolute path or create it\n (#{e.message})"
410
+ return
411
+ end
412
+ base_path = base_path.parent
413
+ end
414
+ if base_parent
415
+ return if base_path.to_s == host.app_base
416
+ host.app_base = base_path.realpath.to_s
417
+ unless web_app_hosts.include?(host)
418
+ logger.info "Changing (configured) app_base for host #{host.name.inspect}" <<
419
+ " (#{host.app_base}) to include application root: #{app_path}"
420
+ end
421
+ else
422
+ logger.warn "Host #{host.name.inspect} app_base #{host.app_base.inspect}" <<
423
+ " is not a parent directory for application root: #{app_path}"
424
+ end
425
+ else
426
+ host.app_base = app_path.parent.realpath.to_s
237
427
  end
238
428
  end
239
-
240
- def web_app_root_dir(config, default = Dir.pwd)
241
- config[:root_dir] || config[:web_app_dir] || default
429
+
430
+ def select_host_apps(app_holders, host)
431
+ app_holders.select do |app_holder|
432
+ host_name = app_holder.web_app.host_name
433
+ ( host_name || 'localhost' ) == host.name
434
+ end
435
+ end
436
+
437
+ def find_host(name, host_config, tomcat = nil)
438
+ if tomcat.nil? # assume 2 args (host_config, tomcat)
439
+ tomcat = host_config; host_config = name
440
+ end
441
+
442
+ if host_config.is_a?(Array)
443
+ names = host_config
444
+ elsif host_config.is_a?(String) || host_config.is_a?(Symbol)
445
+ names = [ host_config ]
446
+ elsif host_config # :localhost => { :aliases => 'local,127.0.0.1' ... }
447
+ names = [ host_config[:name] ||= name ]
448
+ aliases = host_config[:aliases]
449
+ if aliases && ! aliases.is_a?(Array)
450
+ aliases = aliases.split(',').each(&:strip!)
451
+ host_config[:aliases] = aliases
452
+ end
453
+ else # only name passed :
454
+ return tomcat.engine.find_child(name.to_s)
455
+ end
456
+
457
+ hosts = tomcat.engine.find_children
458
+ for name in names # host_names
459
+ host = hosts.find do |host|
460
+ host.name == name || (host.aliases || []).include?(name)
461
+ end
462
+ return host if host
463
+ end
464
+ nil
465
+ end
466
+
467
+ def web_app_root_dir(config, host = nil)
468
+ path = config[:root_dir] || config[:web_app_dir] || begin
469
+ path = config[:context_path]
470
+ ( path && path[0, 1] == '/' ) ? path[1..-1] : path
471
+ end || ( config[:context_name] ? config[:context_name].to_s : nil )
472
+
473
+ return nil if path.nil?
474
+ return File.expand_path(path) if File.exist?(path)
475
+
476
+ if host
477
+ base = host.app_base
478
+ ( path && base ) ? File.join(base, path) : path
479
+ else
480
+ path
481
+ end
242
482
  end
243
483
 
244
484
  def generate_default_keystore(config)