trinidad 1.4.1 → 1.4.3
Sign up to get free protection for your applications and to get access to all the features.
- data/Gemfile +17 -4
- data/History.txt +57 -0
- data/LICENSE +5 -4
- data/README.md +96 -24
- data/Rakefile +89 -29
- data/lib/rack/handler/trinidad.rb +3 -5
- data/lib/trinidad.rb +4 -3
- data/lib/trinidad/command_line_parser.rb +81 -55
- data/lib/trinidad/configuration.rb +23 -20
- data/lib/trinidad/lifecycle/host.rb +2 -0
- data/lib/trinidad/lifecycle/web_app/default.rb +59 -25
- data/lib/trinidad/lifecycle/web_app/shared.rb +115 -14
- data/lib/trinidad/lifecycle/web_app/war.rb +6 -3
- data/lib/trinidad/server.rb +14 -14
- data/lib/trinidad/version.rb +1 -1
- data/lib/trinidad/web_app.rb +363 -78
- data/rakelib/tomcat.rake +29 -18
- data/trinidad.gemspec +7 -7
- metadata +7 -9
- data/rakelib/trinidad.rake +0 -26
- data/rakelib/trinidad_jars.rake +0 -26
@@ -1,3 +1,6 @@
|
|
1
|
+
require 'trinidad/lifecycle/base'
|
2
|
+
require 'trinidad/lifecycle/web_app/shared'
|
3
|
+
|
1
4
|
module Trinidad
|
2
5
|
module Lifecycle
|
3
6
|
module WebApp
|
@@ -15,7 +18,7 @@ module Trinidad
|
|
15
18
|
end
|
16
19
|
|
17
20
|
def configure(context)
|
18
|
-
super
|
21
|
+
super # TODO assuming warbler .war !
|
19
22
|
configure_class_loader(context)
|
20
23
|
end
|
21
24
|
|
@@ -32,7 +35,7 @@ module Trinidad
|
|
32
35
|
def expand_war_app(context)
|
33
36
|
unless File.exist?(context.doc_base)
|
34
37
|
host = context.parent
|
35
|
-
war_file = java.io.File.new(web_app.
|
38
|
+
war_file = java.io.File.new(web_app.root_dir)
|
36
39
|
war = java.net.URL.new("jar:" + war_file.toURI.toURL.to_s + "!/")
|
37
40
|
path_name = File.basename(context.doc_base)
|
38
41
|
|
@@ -42,7 +45,7 @@ module Trinidad
|
|
42
45
|
|
43
46
|
def remove_war_app(context)
|
44
47
|
require 'fileutils'
|
45
|
-
FileUtils.rm_rf web_app.
|
48
|
+
FileUtils.rm_rf web_app.root_dir.gsub(/\.war$/, '')
|
46
49
|
end
|
47
50
|
|
48
51
|
end
|
data/lib/trinidad/server.rb
CHANGED
@@ -1,3 +1,6 @@
|
|
1
|
+
require 'trinidad/configuration'
|
2
|
+
require 'trinidad/web_app'
|
3
|
+
|
1
4
|
module Trinidad
|
2
5
|
class Server
|
3
6
|
attr_reader :config, :tomcat, :web_apps
|
@@ -40,15 +43,15 @@ module Trinidad
|
|
40
43
|
end
|
41
44
|
|
42
45
|
def ssl_enabled?
|
43
|
-
@config[:ssl] &&
|
46
|
+
!! @config[:ssl] && ! @config[:ssl].empty?
|
44
47
|
end
|
45
48
|
|
46
49
|
def ajp_enabled?
|
47
|
-
@config[:ajp] &&
|
50
|
+
!! @config[:ajp] && ! @config[:ajp].empty?
|
48
51
|
end
|
49
52
|
|
50
53
|
def http_configured?
|
51
|
-
(@config[:http] &&
|
54
|
+
(!! @config[:http] && ! @config[:http].empty?) || @config[:address] != 'localhost'
|
52
55
|
end
|
53
56
|
|
54
57
|
def add_ajp_connector
|
@@ -107,10 +110,10 @@ module Trinidad
|
|
107
110
|
|
108
111
|
def add_web_app(web_app, host = nil)
|
109
112
|
host ||= web_app.config[:host] || @tomcat.host
|
110
|
-
|
111
|
-
Trinidad::Extensions.configure_webapp_extensions(web_app.extensions, @tomcat,
|
112
|
-
|
113
|
-
|
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)
|
116
|
+
context
|
114
117
|
end
|
115
118
|
|
116
119
|
def start
|
@@ -144,9 +147,7 @@ module Trinidad
|
|
144
147
|
|
145
148
|
def create_from_web_apps
|
146
149
|
@config[:web_apps].map do |name, app_config|
|
147
|
-
app_config[:
|
148
|
-
app_config[:web_app_dir] ||= Dir.pwd
|
149
|
-
|
150
|
+
app_config[:context_name] ||= name
|
150
151
|
create_web_app(app_config)
|
151
152
|
end if @config[:web_apps]
|
152
153
|
end
|
@@ -163,11 +164,10 @@ module Trinidad
|
|
163
164
|
|
164
165
|
apps_path.map do |path|
|
165
166
|
if File.directory?(path) || path =~ /\.war$/
|
166
|
-
name = File.basename(path)
|
167
167
|
create_web_app({
|
168
|
-
:
|
169
|
-
:
|
170
|
-
:host
|
168
|
+
:context_name => File.basename(path),
|
169
|
+
:root_dir => File.expand_path(path),
|
170
|
+
:host => host
|
171
171
|
})
|
172
172
|
end
|
173
173
|
end
|
data/lib/trinidad/version.rb
CHANGED
data/lib/trinidad/web_app.rb
CHANGED
@@ -1,6 +1,10 @@
|
|
1
|
+
require 'trinidad/configuration'
|
2
|
+
|
1
3
|
module Trinidad
|
2
4
|
class WebApp
|
3
5
|
|
6
|
+
@@defaults = Trinidad::Configuration::DEFAULTS
|
7
|
+
|
4
8
|
attr_reader :config, :default_config
|
5
9
|
|
6
10
|
def self.create(config, default_config = Trinidad.configuration)
|
@@ -17,22 +21,98 @@ module Trinidad
|
|
17
21
|
|
18
22
|
def [](key)
|
19
23
|
key = key.to_sym
|
20
|
-
config.
|
24
|
+
config.key?(key) ? config[key] : default_config[key]
|
25
|
+
end
|
26
|
+
|
27
|
+
def key?(key, use_default = true)
|
28
|
+
key = key.to_sym
|
29
|
+
return true if config.has_key?(key)
|
30
|
+
use_default ? default_config.key?(key) : false
|
21
31
|
end
|
22
32
|
|
23
|
-
%w{
|
24
|
-
|
25
|
-
reload_strategy }.each do |method|
|
33
|
+
%w{ root_dir jruby_compat_version
|
34
|
+
rackup log async_supported reload_strategy }.each do |method|
|
26
35
|
class_eval "def #{method}; self[:'#{method}']; end"
|
27
36
|
end
|
37
|
+
alias_method :web_app_dir, :root_dir # is getting deprecated soon
|
38
|
+
|
39
|
+
def context_path
|
40
|
+
path = self[:context_path] || self[:path]
|
41
|
+
path ? path.to_s : path
|
42
|
+
end
|
43
|
+
|
44
|
+
def context_name
|
45
|
+
name = self[:context_name] || self[:name]
|
46
|
+
name ? name.to_s : name
|
47
|
+
end
|
48
|
+
|
49
|
+
# NOTE: should be set to application root (base) directory thus
|
50
|
+
# JRuby-Rack correctly resolves relative paths for the context!
|
51
|
+
def doc_base; self[:doc_base] || root_dir; end
|
28
52
|
|
53
|
+
def jruby_min_runtimes
|
54
|
+
if min = config[:jruby_min_runtimes]
|
55
|
+
return min.to_i # min specified overrides :threadsafe
|
56
|
+
else # but :threadsafe takes precendence over default :
|
57
|
+
self[:threadsafe] ? 1 : default_config[:jruby_min_runtimes]
|
58
|
+
end
|
59
|
+
end
|
60
|
+
|
61
|
+
def jruby_max_runtimes
|
62
|
+
if max = config[:jruby_max_runtimes]
|
63
|
+
return max.to_i # max specified overrides :threadsafe
|
64
|
+
else # but :threadsafe takes precendence over default :
|
65
|
+
self[:threadsafe] ? 1 : default_config[:jruby_max_runtimes]
|
66
|
+
end
|
67
|
+
end
|
68
|
+
|
69
|
+
def jruby_runtime_acquire_timeout
|
70
|
+
self[:jruby_runtime_acquire_timeout] || 5.0 # default 10s seems too high
|
71
|
+
end
|
72
|
+
|
73
|
+
def environment; self[:environment] || @@defaults[:environment]; end # TODO check web.xml
|
74
|
+
|
75
|
+
def public_dir
|
76
|
+
@public_dir ||= expand_path(public_root)
|
77
|
+
end
|
78
|
+
|
79
|
+
# by (a "Rails") convention use '[RAILS_ROOT]/tmp'
|
80
|
+
def work_dir
|
81
|
+
@work_dir ||= self[:work_dir] || File.join(root_dir, 'tmp')
|
82
|
+
end
|
83
|
+
|
84
|
+
# by a "Rails" convention defaults to '[RAILS_ROOT]/log'
|
85
|
+
def log_dir
|
86
|
+
@log_dir ||= self[:log_dir] || File.join(root_dir, 'log')
|
87
|
+
end
|
88
|
+
|
89
|
+
def monitor
|
90
|
+
File.expand_path(self[:monitor] || 'restart.txt', work_dir)
|
91
|
+
end
|
92
|
+
|
93
|
+
def context_xml; self[:context_xml] || self[:default_context_xml]; end
|
29
94
|
def web_xml; self[:web_xml] || self[:default_web_xml]; end
|
30
95
|
def default_web_xml; self[:default_web_xml]; end
|
31
96
|
|
32
|
-
def
|
33
|
-
|
34
|
-
|
35
|
-
|
97
|
+
def java_lib
|
98
|
+
# accepts #deprecated :libs_dir syntax
|
99
|
+
self[:java_lib] || self[:libs_dir] || @@defaults[:java_lib]
|
100
|
+
end
|
101
|
+
|
102
|
+
def java_classes
|
103
|
+
# accepts #deprecated :classes_dir syntax
|
104
|
+
self[:java_classes] || self[:classes_dir] || File.join(java_lib, 'classes')
|
105
|
+
end
|
106
|
+
|
107
|
+
def java_lib_dir
|
108
|
+
@java_lib_dir ||= self[:java_lib_dir] || expand_path(java_lib)
|
109
|
+
end
|
110
|
+
alias_method :libs_dir, :java_lib_dir # #deprecated
|
111
|
+
|
112
|
+
def java_classes_dir
|
113
|
+
@java_classes_dir ||= self[:java_classes_dir] || expand_path(java_classes)
|
114
|
+
end
|
115
|
+
alias_method :classes_dir, :java_classes_dir # #deprecated
|
36
116
|
|
37
117
|
def extensions
|
38
118
|
@extensions ||= begin
|
@@ -40,16 +120,13 @@ module Trinidad
|
|
40
120
|
extensions.merge(config[:extensions] || {})
|
41
121
|
end
|
42
122
|
end
|
43
|
-
|
44
|
-
def monitor
|
45
|
-
File.expand_path(self[:monitor] || 'tmp/restart.txt', work_dir)
|
46
|
-
end
|
47
123
|
|
48
124
|
def context_params
|
49
125
|
@context_params ||= {}
|
50
126
|
add_context_param 'jruby.min.runtimes', jruby_min_runtimes
|
51
127
|
add_context_param 'jruby.max.runtimes', jruby_max_runtimes
|
52
128
|
add_context_param 'jruby.initial.runtimes', jruby_min_runtimes
|
129
|
+
add_context_param 'jruby.runtime.acquire.timeout', jruby_runtime_acquire_timeout
|
53
130
|
add_context_param 'jruby.compat.version', jruby_compat_version || RUBY_VERSION
|
54
131
|
add_context_param 'public.root', File.join('/', public_root)
|
55
132
|
@context_params
|
@@ -65,22 +142,80 @@ module Trinidad
|
|
65
142
|
end
|
66
143
|
|
67
144
|
def deployment_descriptor
|
68
|
-
@deployment_descriptor
|
69
|
-
|
70
|
-
File.exist?(file) ? file : nil
|
71
|
-
end
|
145
|
+
return nil if @deployment_descriptor == false
|
146
|
+
@deployment_descriptor ||= expand_path(web_xml) || false
|
72
147
|
end
|
73
148
|
|
74
149
|
# @deprecated use {#deployment_descriptor}
|
75
150
|
def default_deployment_descriptor
|
76
|
-
@default_deployment_descriptor
|
77
|
-
|
78
|
-
|
151
|
+
return nil if @default_deployment_descriptor == false
|
152
|
+
@default_deployment_descriptor ||= expand_path(default_web_xml) || false
|
153
|
+
end
|
154
|
+
|
155
|
+
def public_root
|
156
|
+
@public_root ||= ( public_config[:root] || @@defaults[:public] )
|
157
|
+
end
|
158
|
+
alias_method :public, :public_root
|
159
|
+
|
160
|
+
# we do support nested :public configuration e.g. :
|
161
|
+
# public:
|
162
|
+
# root: /assets
|
163
|
+
# cache: true
|
164
|
+
# cache_ttl: 60000
|
165
|
+
def public_config
|
166
|
+
@public_config ||=
|
167
|
+
self[:public].is_a?(String) ?
|
168
|
+
{ :root => self[:public] } :
|
169
|
+
( self[:public] || {} )
|
170
|
+
end
|
171
|
+
|
172
|
+
def aliases # :public => { :aliases => ... }
|
173
|
+
return nil unless aliases = ( self[:aliases] || public_config[:aliases] )
|
174
|
+
return aliases if aliases.is_a?(String)
|
175
|
+
# "/aliasPath1=docBase1,/aliasPath2=docBase2"
|
176
|
+
@aliases ||= aliases.map do |path, base|
|
177
|
+
path = path.to_s
|
178
|
+
if (root = '/') != path[0, 1]
|
179
|
+
path = (root << path)
|
180
|
+
end
|
181
|
+
"#{path}=#{File.expand_path(base, root_dir)}"
|
182
|
+
end.join(',')
|
183
|
+
end
|
184
|
+
|
185
|
+
def caching_allowed? # :public => { :cached => ... }
|
186
|
+
# ((BaseDirContext) resources).setCached(isCachingAllowed())
|
187
|
+
return @caching_allowed unless @caching_allowed.nil?
|
188
|
+
@caching_allowed = self[:caching_allowed]
|
189
|
+
if @caching_allowed.nil?
|
190
|
+
@caching_allowed = public_config[:cached]
|
191
|
+
if @caching_allowed.nil?
|
192
|
+
@caching_allowed = environment != 'development'
|
193
|
+
end
|
79
194
|
end
|
195
|
+
@caching_allowed = !! @caching_allowed
|
196
|
+
end
|
197
|
+
|
198
|
+
# The cache max size in kB
|
199
|
+
def cache_max_size # :public => { :cache_max_size => ... }
|
200
|
+
# ((BaseDirContext) resources).setCacheMaxSize
|
201
|
+
self[:cache_max_size] || public_config[:cache_max_size]
|
202
|
+
end
|
203
|
+
|
204
|
+
# The max size for a cached object in kB
|
205
|
+
def cache_object_max_size # :public => { :cache_object_max_size => ... }
|
206
|
+
# ((BaseDirContext) resources).setCacheObjectMaxSize
|
207
|
+
self[:cache_object_max_size] || public_config[:cache_object_max_size]
|
208
|
+
end
|
209
|
+
|
210
|
+
# Cache entry time-to-live in millis
|
211
|
+
def cache_ttl # :public => { :cache_ttl => ... }
|
212
|
+
# ((BaseDirContext) resources).setCacheTTL
|
213
|
+
self[:cache_ttl] || public_config[:cache_ttl]
|
80
214
|
end
|
81
215
|
|
82
216
|
def class_loader
|
83
|
-
@class_loader ||=
|
217
|
+
@class_loader ||=
|
218
|
+
org.jruby.util.JRubyClassLoader.new(JRuby.runtime.jruby_class_loader)
|
84
219
|
end
|
85
220
|
|
86
221
|
def class_loader!
|
@@ -94,29 +229,108 @@ module Trinidad
|
|
94
229
|
end
|
95
230
|
|
96
231
|
# Reset the hold web application state so it gets re-initialized.
|
97
|
-
# Please note that the
|
232
|
+
# Please note that the configuration objects are not cleared.
|
98
233
|
def reset!
|
99
234
|
vars = instance_variables.map(&:to_sym)
|
100
235
|
vars = vars - [ :'@config', :'@default_config' ]
|
101
236
|
vars.each { |var| instance_variable_set(var, nil) }
|
102
237
|
end
|
103
238
|
|
239
|
+
DEFAULT_SERVLET_CLASS = nil # by default we resolve by it's name
|
240
|
+
DEFAULT_SERVLET_NAME = 'default'
|
241
|
+
|
242
|
+
# Returns a servlet config for the DefaultServlet.
|
243
|
+
# This servlet is setup for each and every Tomcat context and is named
|
244
|
+
# 'default' and mapped to '/' we allow fine tunning of this servlet.
|
245
|
+
# Return values should be interpreted as follows :
|
246
|
+
# true - do nothing leave the servlet as set-up (by default)
|
247
|
+
# false - remove the set-up default (e.g. configured in web.xml)
|
248
|
+
def default_servlet
|
249
|
+
return @default_servlet unless @default_servlet.nil?
|
250
|
+
@default_servlet ||= begin
|
251
|
+
if ! web_xml_servlet?(DEFAULT_SERVLET_CLASS, DEFAULT_SERVLET_NAME)
|
252
|
+
default_servlet = self[:default_servlet]
|
253
|
+
if default_servlet.is_a?(javax.servlet.Servlet)
|
254
|
+
{ :instance => default_servlet }
|
255
|
+
elsif default_servlet == false
|
256
|
+
false # forced by user to remove
|
257
|
+
elsif default_servlet == true
|
258
|
+
true # forced by user to leave as is
|
259
|
+
else
|
260
|
+
default_servlet = {} if default_servlet.nil?
|
261
|
+
unless default_servlet.key?(:class)
|
262
|
+
# we use a custom class by default to server /public assets :
|
263
|
+
default_servlet[:class] = 'rb.trinidad.servlets.DefaultServlet'
|
264
|
+
end
|
265
|
+
default_servlet
|
266
|
+
end
|
267
|
+
else
|
268
|
+
false # configured in web.xml thus remove the (default) "default"
|
269
|
+
end
|
270
|
+
end
|
271
|
+
end
|
272
|
+
|
273
|
+
JSP_SERVLET_CLASS = nil # by default we resolve by it's name
|
274
|
+
JSP_SERVLET_NAME = 'jsp'
|
275
|
+
|
276
|
+
# Returns a servlet config for the JspServlet.
|
277
|
+
# This servlet is setup by default for every Tomcat context and is named
|
278
|
+
# 'jsp' with '*.jsp' and '*.jspx' mappings.
|
279
|
+
# Return values should be interpreted as follows :
|
280
|
+
# true - do nothing leave the servlet as set-up (by default)
|
281
|
+
# false - remove the set-up servlet (by default we do not need jsp support)
|
282
|
+
def jsp_servlet
|
283
|
+
return @jsp_servlet unless @jsp_servlet.nil?
|
284
|
+
@jsp_servlet ||= begin
|
285
|
+
if ! web_xml_servlet?(JSP_SERVLET_CLASS, JSP_SERVLET_NAME)
|
286
|
+
jsp_servlet = self[:jsp_servlet]
|
287
|
+
if jsp_servlet.is_a?(javax.servlet.Servlet)
|
288
|
+
{ :instance => jsp_servlet }
|
289
|
+
else
|
290
|
+
jsp_servlet || false # remove jsp support unless specified
|
291
|
+
end
|
292
|
+
else
|
293
|
+
false # configured in web.xml thus remove the default "jsp"
|
294
|
+
end
|
295
|
+
end
|
296
|
+
end
|
297
|
+
|
298
|
+
RACK_SERVLET_CLASS = 'org.jruby.rack.RackServlet'
|
299
|
+
RACK_SERVLET_NAME = 'rack' # in-case of a "custom" rack servlet class
|
300
|
+
RACK_FILTER_CLASS = 'org.jruby.rack.RackFilter'
|
301
|
+
RACK_FILTER_NAME = 'rack'
|
302
|
+
|
303
|
+
# Returns a config for the RackServlet or nil if no need to set-up one.
|
304
|
+
# (to be used for dispatching to this Rack / Rails web application)
|
104
305
|
def rack_servlet
|
105
306
|
return nil if @rack_servlet == false
|
106
307
|
@rack_servlet ||= begin
|
107
|
-
|
108
|
-
|
109
|
-
|
110
|
-
|
111
|
-
if ! web_xml_servlet?(servlet_class, servlet_name) &&
|
112
|
-
! web_xml_filter?('org.jruby.rack.RackFilter')
|
113
|
-
{
|
114
|
-
:class => servlet_class, :name => servlet_name,
|
115
|
-
:async_supported => !! servlet_config[:async_supported],
|
116
|
-
:instance => servlet_config[:instance]
|
117
|
-
}
|
308
|
+
rack_servlet = self[:rack_servlet] || self[:servlet] || {}
|
309
|
+
|
310
|
+
if rack_servlet.is_a?(javax.servlet.Servlet)
|
311
|
+
{ :instance => rack_servlet, :name => RACK_SERVLET_NAME, :mapping => '/*' }
|
118
312
|
else
|
119
|
-
|
313
|
+
servlet_class = rack_servlet[:class] || RACK_SERVLET_CLASS
|
314
|
+
servlet_name = rack_servlet[:name] || RACK_SERVLET_NAME
|
315
|
+
|
316
|
+
if ! web_xml_servlet?(servlet_class, servlet_name) &&
|
317
|
+
! web_xml_filter?(RACK_FILTER_CLASS, RACK_FILTER_NAME)
|
318
|
+
{
|
319
|
+
:instance => rack_servlet[:instance],
|
320
|
+
:class => servlet_class, :name => servlet_name,
|
321
|
+
:init_params => rack_servlet[:init_params],
|
322
|
+
:async_supported => !! ( rack_servlet.has_key?(:async_supported) ?
|
323
|
+
rack_servlet[:async_supported] : async_supported ),
|
324
|
+
:load_on_startup => ( rack_servlet[:load_on_startup] || 2 ).to_i,
|
325
|
+
:mapping => rack_servlet[:mapping] || '/*'
|
326
|
+
}
|
327
|
+
else
|
328
|
+
if ! rack_servlet.empty?
|
329
|
+
logger.info "ignoring :rack_servlet configuration for " +
|
330
|
+
"#{context_path} due #{deployment_descriptor}"
|
331
|
+
end
|
332
|
+
false # no need to setup a rack servlet
|
333
|
+
end
|
120
334
|
end
|
121
335
|
end || nil
|
122
336
|
end
|
@@ -132,9 +346,9 @@ module Trinidad
|
|
132
346
|
def solo?
|
133
347
|
! is_a?(WarWebApp) && config[:solo]
|
134
348
|
end
|
135
|
-
|
349
|
+
|
136
350
|
def threadsafe?
|
137
|
-
jruby_min_runtimes
|
351
|
+
jruby_min_runtimes == 1 && jruby_max_runtimes == 1
|
138
352
|
end
|
139
353
|
|
140
354
|
protected
|
@@ -144,34 +358,56 @@ module Trinidad
|
|
144
358
|
end
|
145
359
|
|
146
360
|
def complete_config!
|
147
|
-
config[:
|
361
|
+
config[:root_dir] ||= self.class.root_dir(config, default_config)
|
362
|
+
config[:context_path] = self.class.context_path(config, default_config)
|
148
363
|
end
|
149
364
|
|
150
365
|
public
|
151
366
|
|
367
|
+
# Returns true if there's a servlet with the given servlet-class name
|
368
|
+
# configured or if the optional name second argument is given it also
|
369
|
+
# checks for a servlet with the given name.
|
152
370
|
def web_xml_servlet?(servlet_class, servlet_name = nil)
|
153
|
-
|
154
|
-
|
155
|
-
|
156
|
-
|
371
|
+
return nil unless web_xml_doc
|
372
|
+
if servlet_class
|
373
|
+
servlet_xpath = "/web-app/servlet[servlet-class = '#{servlet_class}']"
|
374
|
+
return true if web_xml_doc.root.elements[servlet_xpath] # else try name
|
375
|
+
end
|
376
|
+
if servlet_name
|
377
|
+
servlet_xpath = "/web-app/servlet[servlet-name = '#{servlet_name}']"
|
378
|
+
return !! web_xml_doc.root.elements[servlet_xpath]
|
379
|
+
end
|
380
|
+
|
381
|
+
return false if servlet_class || servlet_name
|
382
|
+
raise ArgumentError, "nor servlet_class nor servlet_name given"
|
157
383
|
end
|
158
384
|
|
159
|
-
|
160
|
-
|
161
|
-
|
162
|
-
|
163
|
-
|
385
|
+
# Returns true if a filter definition with a given filter-class is found.
|
386
|
+
def web_xml_filter?(filter_class, filter_name = nil)
|
387
|
+
return nil unless web_xml_doc
|
388
|
+
if filter_class
|
389
|
+
filter_xpath = "/web-app/filter[filter-class = '#{filter_class}']"
|
390
|
+
return true if web_xml_doc.root.elements[filter_xpath] # else try name
|
391
|
+
end
|
392
|
+
if filter_name
|
393
|
+
filter_xpath = "/web-app/filter[filter-name = '#{filter_name}']"
|
394
|
+
return !! web_xml_doc.root.elements[filter_xpath]
|
395
|
+
end
|
396
|
+
|
397
|
+
return false if filter_class || filter_name
|
398
|
+
raise ArgumentError, "nor filter_class nor filter_name given"
|
164
399
|
end
|
165
400
|
|
401
|
+
# Returns true if a listener definition with a given listener-class is found.
|
166
402
|
def web_xml_listener?(listener_class)
|
167
|
-
|
168
|
-
|
169
|
-
)
|
403
|
+
return nil unless web_xml_doc
|
404
|
+
!! web_xml_doc.root.elements["/web-app/listener[listener-class = '#{listener_class}']"]
|
170
405
|
end
|
171
406
|
|
407
|
+
# Returns a param-value for a context-param with a given param-name.
|
172
408
|
def web_xml_context_param(name)
|
173
|
-
|
174
|
-
|
409
|
+
return nil unless web_xml_doc
|
410
|
+
if param = web_xml_doc.root.elements["/web-app/context-param[param-name = '#{name}']"]
|
175
411
|
param.elements['param-value'].text
|
176
412
|
end
|
177
413
|
end
|
@@ -180,54 +416,99 @@ module Trinidad
|
|
180
416
|
|
181
417
|
def web_xml_doc
|
182
418
|
return @web_xml_doc || nil unless @web_xml_doc.nil?
|
183
|
-
|
419
|
+
descriptor = deployment_descriptor
|
420
|
+
if descriptor && File.exist?(descriptor)
|
184
421
|
begin
|
185
422
|
require 'rexml/document'
|
186
|
-
@web_xml_doc = REXML::Document.new(File.read(
|
423
|
+
@web_xml_doc = REXML::Document.new(File.read(descriptor))
|
187
424
|
rescue REXML::ParseException => e
|
188
|
-
|
189
|
-
log.warn "invalid deployment descriptor:[#{deployment_descriptor}]\n #{e.message}"
|
425
|
+
logger.warn "invalid deployment descriptor:[#{descriptor}]\n #{e.message}"
|
190
426
|
@web_xml_doc = false
|
191
427
|
end
|
192
428
|
@web_xml_doc || nil
|
193
429
|
end
|
194
430
|
end
|
195
431
|
|
432
|
+
def expand_path(path)
|
433
|
+
if path
|
434
|
+
path_file = java.io.File.new(path)
|
435
|
+
if path_file.absolute?
|
436
|
+
path_file.absolute_path
|
437
|
+
else
|
438
|
+
File.expand_path(path, root_dir)
|
439
|
+
end
|
440
|
+
end
|
441
|
+
end
|
442
|
+
|
443
|
+
def logger
|
444
|
+
@logger ||= Trinidad::Logging::LogFactory.getLog('')
|
445
|
+
end
|
446
|
+
|
196
447
|
protected
|
197
448
|
|
198
449
|
def self.rackup?(config, default_config = nil)
|
199
450
|
return true if config.has_key?(:rackup)
|
200
|
-
|
201
|
-
(default_config && default_config[:web_app_dir]) || Dir.pwd
|
451
|
+
root_dir = root_dir(config, default_config)
|
202
452
|
config_ru = (default_config && default_config[:rackup]) || 'config.ru'
|
203
453
|
# check for rackup (but still use config/environment.rb for rails 3)
|
204
|
-
if File.exists?(File.join(
|
454
|
+
if File.exists?(File.join(root_dir, config_ru)) &&
|
205
455
|
! rails?(config, default_config) # do not :rackup a rails app
|
206
456
|
config[:rackup] = config_ru
|
207
457
|
end
|
208
|
-
config[:rackup] || ! Dir[File.join(
|
458
|
+
config[:rackup] || ! Dir[File.join(root_dir, 'WEB-INF/**/config.ru')].empty?
|
209
459
|
end
|
210
460
|
|
211
461
|
def self.rails?(config, default_config = nil)
|
212
|
-
|
213
|
-
(default_config && default_config[:web_app_dir]) || Dir.pwd
|
462
|
+
root_dir = root_dir(config, default_config)
|
214
463
|
# standart Rails 3.x `class Application < Rails::Application`
|
215
|
-
if File.exists?(application = File.join(
|
216
|
-
|
217
|
-
return true if application_rb =~ /^[^#]*Rails::Application/
|
464
|
+
if File.exists?(application = File.join(root_dir, 'config/application.rb'))
|
465
|
+
return true if file_line_match?(application, /^[^#]*Rails::Application/)
|
218
466
|
end
|
219
|
-
if File.exists?(environment = File.join(
|
220
|
-
|
221
|
-
|
222
|
-
|
223
|
-
|
224
|
-
|
467
|
+
if File.exists?(environment = File.join(root_dir, 'config/environment.rb'))
|
468
|
+
return true if file_line_match?(environment) do |line|
|
469
|
+
# customized Rails 3.x, expects a `Rails::Application` subclass
|
470
|
+
# or a plain-old Rails 2.3 with `RAILS_GEM_VERSION = '2.3.14'`
|
471
|
+
line =~ /^[^#]*Rails::Application/ || line =~ /^[^#]*RAILS_GEM_VERSION/
|
472
|
+
end
|
225
473
|
end
|
226
474
|
false
|
227
475
|
end
|
228
476
|
|
229
477
|
def self.war?(config, default_config = nil)
|
230
|
-
config[:context_path] && config[:context_path][-4..-1] == '.war'
|
478
|
+
config[:context_path] && config[:context_path].to_s[-4..-1] == '.war'
|
479
|
+
end
|
480
|
+
|
481
|
+
private
|
482
|
+
|
483
|
+
def self.root_dir(config, default_config)
|
484
|
+
# for backwards compatibility accepts the :web_app_dir "alias"
|
485
|
+
config[:root_dir] || config[:web_app_dir] ||
|
486
|
+
( default_config &&
|
487
|
+
( default_config[:root_dir] || default_config[:web_app_dir] ) ) ||
|
488
|
+
Dir.pwd
|
489
|
+
end
|
490
|
+
|
491
|
+
def self.context_path(config, default_config = nil)
|
492
|
+
path = config[:context_path] ||
|
493
|
+
( default_config && default_config[:context_path] )
|
494
|
+
unless path
|
495
|
+
name = config[:context_name] ||
|
496
|
+
( default_config && default_config[:context_name] )
|
497
|
+
path = name.to_s == 'default' ? '/' : "/#{name}"
|
498
|
+
end
|
499
|
+
path = "/#{path}" if path.to_s[0, 1] != '/'
|
500
|
+
path.to_s
|
501
|
+
end
|
502
|
+
|
503
|
+
def self.file_line_match?(path, pattern = nil)
|
504
|
+
File.open(path) do |file|
|
505
|
+
if block_given?
|
506
|
+
file.each_line { |line| return true if yield(line) }
|
507
|
+
else
|
508
|
+
file.each_line { |line| return true if line =~ pattern }
|
509
|
+
end
|
510
|
+
end
|
511
|
+
false
|
231
512
|
end
|
232
513
|
|
233
514
|
class Holder
|
@@ -251,7 +532,7 @@ module Trinidad
|
|
251
532
|
def lock; @lock = true; end
|
252
533
|
def unlock; @lock = false; end
|
253
534
|
|
254
|
-
#
|
535
|
+
# #deprecated behaves Hash like for (<= 1.3.5) compatibility
|
255
536
|
def [](key)
|
256
537
|
case key.to_sym
|
257
538
|
when :app then
|
@@ -268,7 +549,7 @@ module Trinidad
|
|
268
549
|
end
|
269
550
|
end
|
270
551
|
|
271
|
-
#
|
552
|
+
# #deprecated behaves Hash like for (<= 1.3.5) compatibility
|
272
553
|
def []=(key, val)
|
273
554
|
case key.to_sym
|
274
555
|
when :context then
|
@@ -317,9 +598,9 @@ module Trinidad
|
|
317
598
|
def complete_config!
|
318
599
|
super
|
319
600
|
# detect threadsafe! in config/environments/environment.rb :
|
320
|
-
if self.class.threadsafe?(
|
321
|
-
config[:jruby_min_runtimes] = 1
|
322
|
-
config[:jruby_max_runtimes] = 1
|
601
|
+
if ! key?(:threadsafe) && self.class.threadsafe?(root_dir, environment)
|
602
|
+
config[:jruby_min_runtimes] = 1 unless key?(:jruby_min_runtimes, false)
|
603
|
+
config[:jruby_max_runtimes] = 1 unless key?(:jruby_max_runtimes, false)
|
323
604
|
end
|
324
605
|
end
|
325
606
|
|
@@ -331,7 +612,7 @@ module Trinidad
|
|
331
612
|
end
|
332
613
|
|
333
614
|
def self.threadsafe_match?(file)
|
334
|
-
File.exist?(file) &&
|
615
|
+
File.exist?(file) && file_line_match?(file, /^[^#]*threadsafe!/)
|
335
616
|
end
|
336
617
|
|
337
618
|
end
|
@@ -343,12 +624,16 @@ module Trinidad
|
|
343
624
|
super.gsub(/\.war$/, '')
|
344
625
|
end
|
345
626
|
|
627
|
+
def log_dir
|
628
|
+
@log_dir ||= self[:log_dir] || File.join(work_dir, 'log')
|
629
|
+
end
|
630
|
+
|
346
631
|
def work_dir
|
347
|
-
File.join(
|
632
|
+
@work_dir ||= File.join(root_dir.gsub(/\.war$/, ''), 'WEB-INF')
|
348
633
|
end
|
349
634
|
|
350
635
|
def monitor
|
351
|
-
File.expand_path(
|
636
|
+
File.expand_path(root_dir)
|
352
637
|
end
|
353
638
|
|
354
639
|
def define_lifecycle
|