trinidad 1.3.5 → 1.4.0.RC

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,3 +1,3 @@
1
1
  module Trinidad
2
- VERSION = '1.3.5'
2
+ VERSION = '1.4.0.RC'
3
3
  end
@@ -1,162 +1,311 @@
1
1
  module Trinidad
2
2
  class WebApp
3
- attr_reader :config, :app_config, :class_loader, :servlet
4
-
5
- def self.create(config, app_config)
6
- autodetect_configuration(config, app_config)
3
+
4
+ attr_reader :config, :default_config
7
5
 
8
- war?(app_config) ? WarWebApp.new(config, app_config) :
9
- rackup?(app_config) ? RackupWebApp.new(config, app_config) : RailsWebApp.new(config, app_config)
6
+ def self.create(config, default_config = Trinidad.configuration)
7
+ war?(config, default_config) ? WarWebApp.new(config, default_config) :
8
+ rackup?(config, default_config) ? RackupWebApp.new(config, default_config) :
9
+ RailsWebApp.new(config, default_config)
10
10
  end
11
11
 
12
- def self.rackup?(app_config)
13
- app_config.has_key?(:rackup) || !Dir['WEB-INF/**/config.ru'].empty?
12
+ def initialize(config, default_config)
13
+ @config, @default_config = config, default_config || {}
14
+ complete_config!
15
+ # NOTE: we should maybe @config.freeze here ?!
14
16
  end
15
17
 
16
- def self.war?(app_config)
17
- app_config[:context_path] =~ /\.war$/
18
+ def [](key)
19
+ key = key.to_sym
20
+ config.has_key?(key) ? config[key] : default_config[key]
18
21
  end
19
-
20
- def initialize(config, app_config, servlet_class = 'org.jruby.rack.RackServlet', servlet_name = 'RackServlet')
21
- @config = config
22
- @app_config = app_config
23
-
24
- generate_class_loader
25
-
26
- configure_rack_servlet(servlet_class, servlet_name) unless rack_servlet_configured?
22
+
23
+ %w{ context_path web_app_dir libs_dir classes_dir async_supported
24
+ jruby_min_runtimes jruby_max_runtimes jruby_compat_version rackup log
25
+ reload_strategy }.each do |method|
26
+ class_eval "def #{method}; self[:'#{method}']; end"
27
+ end
28
+
29
+ def web_xml; self[:web_xml] || self[:default_web_xml]; end
30
+ def default_web_xml; self[:default_web_xml]; end
31
+
32
+ def public_root; self[:public] || 'public'; end
33
+ def environment; self[:environment] || 'development'; end
34
+ def work_dir; self[:work_dir] || web_app_dir; end
35
+ def log_dir; self[:log_dir] || File.join(work_dir, 'log'); end
36
+
37
+ def extensions
38
+ @extensions ||= begin
39
+ extensions = default_config[:extensions] || {}
40
+ extensions.merge(config[:extensions] || {})
41
+ end
42
+ end
43
+
44
+ def monitor
45
+ File.expand_path(self[:monitor] || 'tmp/restart.txt', work_dir)
27
46
  end
28
47
 
29
- def rack_listener
30
- context_listener unless rack_listener_configured?
48
+ def context_params
49
+ @context_params ||= {}
50
+ add_context_param 'jruby.min.runtimes', jruby_min_runtimes
51
+ add_context_param 'jruby.max.runtimes', jruby_max_runtimes
52
+ add_context_param 'jruby.initial.runtimes', jruby_min_runtimes
53
+ add_context_param 'jruby.compat.version', jruby_compat_version || RUBY_VERSION
54
+ add_context_param 'public.root', File.join('/', public_root)
55
+ @context_params
31
56
  end
57
+ # @deprecated replaced with {#context_params}
58
+ def init_params; context_params; end
32
59
 
33
- def init_params
34
- @params ||= {}
35
- add_parameter_unless_exist 'jruby.min.runtimes', jruby_min_runtimes.to_s
36
- add_parameter_unless_exist 'jruby.max.runtimes', jruby_max_runtimes.to_s
37
- add_parameter_unless_exist 'jruby.initial.runtimes', jruby_min_runtimes.to_s
38
- add_parameter_unless_exist 'public.root', File.join('/', public_root)
39
- add_parameter_unless_exist 'jruby.compat.version', RUBY_VERSION
40
- @params
60
+ def add_context_param(param_name, param_value)
61
+ @context_params ||= {}
62
+ if ! param_value.nil? && ! web_xml_context_param(param_name)
63
+ @context_params[param_name] = param_value.to_s
64
+ end
41
65
  end
42
66
 
67
+ def deployment_descriptor
68
+ @deployment_descriptor ||= if web_xml
69
+ file = File.expand_path(File.join(work_dir, web_xml))
70
+ File.exist?(file) ? file : nil
71
+ end
72
+ end
73
+
74
+ # @deprecated use {#deployment_descriptor}
43
75
  def default_deployment_descriptor
44
- @deployment_descriptor ||= if default_web_xml
76
+ @default_deployment_descriptor ||= if default_web_xml
45
77
  file = File.expand_path(File.join(work_dir, default_web_xml))
46
78
  File.exist?(file) ? file : nil
47
79
  end
48
80
  end
49
-
50
- def rack_servlet_configured?
51
- !!( web_xml && (
52
- web_xml.root.elements["/web-app/servlet[contains(servlet-class, 'org.jruby.rack.RackServlet')]"] ||
53
- web_xml.root.elements["/web-app/filter[contains(filter-class, 'org.jruby.rack.RackFilter')]"]
54
- )
55
- )
81
+
82
+ def class_loader
83
+ @class_loader ||= org.jruby.util.JRubyClassLoader.new(JRuby.runtime.jruby_class_loader)
56
84
  end
57
-
58
- def rack_listener_configured?
59
- !!( web_xml &&
60
- web_xml.root.elements["/web-app/listener[contains(listener-class, '#{context_listener}')]"]
61
- )
85
+
86
+ def class_loader!
87
+ ( @class_loader = nil ) || class_loader
88
+ end
89
+ # @deprecated replaced with {#class_loader!}
90
+ def generate_class_loader; class_loader!; end
91
+
92
+ def define_lifecycle
93
+ Trinidad::Lifecycle::WebApp::Default.new(self)
62
94
  end
63
95
 
64
- %w{ context_path web_app_dir libs_dir classes_dir default_web_xml
65
- jruby_min_runtimes jruby_max_runtimes rackup log }.each do |method_name|
66
- define_method method_name do
67
- sym = method_name.to_sym
68
- @app_config[sym] || @config[sym]
69
- end
96
+ # Reset the hold web application state so it gets re-initialized.
97
+ # Please note that the received configuration object are not cleared.
98
+ def reset!
99
+ vars = instance_variables.map(&:to_sym)
100
+ vars = vars - [ :'@config', :'@default_config' ]
101
+ vars.each { |var| instance_variable_set(var, nil) }
70
102
  end
103
+
104
+ def rack_servlet
105
+ return nil if @rack_servlet == false
106
+ @rack_servlet ||= begin
107
+ servlet_config = self[:servlet] || {}
108
+ servlet_class = servlet_config[:class] || 'org.jruby.rack.RackServlet'
109
+ servlet_name = servlet_config[:name] || 'RackServlet'
71
110
 
72
- def public_root; @app_config[:public] || @config[:public] || 'public'; end
73
- def environment; @app_config[:environment] || @config[:environment] || 'development'; end
74
- def work_dir; @app_config[:work_dir] || @config[:work_dir] || web_app_dir; end
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
+ }
118
+ else
119
+ false # no need to setup a rack servlet
120
+ end
121
+ end || nil
122
+ end
123
+ # @deprecated use {#rack_servlet} instead
124
+ def servlet; rack_servlet; end
75
125
 
76
- def extensions
77
- @extensions ||= begin
78
- extensions = @config[:extensions] || {}
79
- extensions.merge!(@app_config[:extensions]) if @app_config[:extensions]
80
- extensions
81
- end
126
+ def rack_listener
127
+ context_listener unless web_xml_listener?(context_listener)
82
128
  end
83
-
84
- def war?; WebApp.war?(app_config); end
129
+
130
+ def war?; self.class.war?(config); end
85
131
 
86
132
  def solo?
87
- !self.is_a?(WarWebApp) && @app_config[:solo]
133
+ ! is_a?(WarWebApp) && config[:solo]
88
134
  end
89
135
 
90
136
  def threadsafe?
91
137
  jruby_min_runtimes.to_i == 1 && jruby_max_runtimes.to_i == 1
92
138
  end
93
-
94
- def monitor
95
- m_file = @app_config[:monitor] || @config[:monitor] || 'tmp/restart.txt'
96
- File.expand_path(m_file, work_dir)
139
+
140
+ protected
141
+
142
+ def context_listener
143
+ raise NotImplementedError.new "context_listener expected to be redefined"
97
144
  end
98
-
99
- def define_lifecycle
100
- Trinidad::Lifecycle::Default.new(self)
145
+
146
+ def complete_config!
147
+ config[:web_app_dir] ||= default_config[:web_app_dir] || Dir.pwd
101
148
  end
102
-
103
- def generate_class_loader
104
- @class_loader = org.jruby.util.JRubyClassLoader.new(JRuby.runtime.jruby_class_loader)
149
+
150
+ def web_xml_servlet?(servlet_class, servlet_name = nil)
151
+ !!( web_xml_doc && (
152
+ web_xml_doc.root.elements["/web-app/servlet[contains(servlet-class, '#{servlet_class}')]"]
153
+ )
154
+ )
105
155
  end
106
156
 
107
- protected
108
- def add_parameter_unless_exist(param_name, param_value)
109
- @params[param_name] = param_value unless web_context_param(param_name)
157
+ def web_xml_filter?(filter_class)
158
+ !!( web_xml_doc && (
159
+ web_xml_doc.root.elements["/web-app/filter[contains(filter-class, '#{filter_class}')]"]
160
+ )
161
+ )
110
162
  end
111
-
163
+
164
+ def web_xml_listener?(listener_class)
165
+ !!( web_xml_doc &&
166
+ web_xml_doc.root.elements["/web-app/listener[contains(listener-class, '#{listener_class}')]"]
167
+ )
168
+ end
169
+
170
+ def web_xml_context_param(name)
171
+ if web_xml_doc &&
172
+ param = web_xml_doc.root.elements["/web-app/context-param[contains(param-name, '#{name}')]"]
173
+ param.elements['param-value'].text
174
+ end
175
+ end
176
+
112
177
  private
113
- def web_xml
114
- return nil if @web_xml == false
115
- @web_xml ||=
178
+
179
+ def web_xml_doc
180
+ return @web_xml_doc || nil if ! @web_xml_doc.nil?
181
+ if deployment_descriptor
116
182
  begin
117
183
  require 'rexml/document'
118
- REXML::Document.new(File.read(default_deployment_descriptor))
184
+ @web_xml_doc = REXML::Document.new(File.read(deployment_descriptor))
119
185
  rescue REXML::ParseException => e
120
- puts "WARNING: invalid deployment descriptor:[#{default_deployment_descriptor}]"
121
- puts e.message
122
- false
123
- end unless default_deployment_descriptor.nil?
186
+ log = Trinidad::Logging::LogFactory.getLog('')
187
+ log.warn "invalid deployment descriptor:[#{deployment_descriptor}]\n #{e.message}"
188
+ @web_xml_doc = false
189
+ end
190
+ @web_xml_doc || nil
191
+ end
124
192
  end
125
-
126
- def web_context_param(param)
127
- if web_xml && param = web_xml.root.elements["/web-app/context-param[contains(param-name, '#{param}')]"]
128
- param.elements['param-value'].text
193
+
194
+ protected
195
+
196
+ def self.rackup?(config, default_config = nil)
197
+ return true if config.has_key?(:rackup)
198
+ web_app_dir = config[:web_app_dir] ||
199
+ (default_config && default_config[:web_app_dir]) || Dir.pwd
200
+ config_ru = (default_config && default_config[:rackup]) || 'config.ru'
201
+ # Check for rackup (but still use config/environment.rb for Rails 3)
202
+ if File.exists?(File.join(web_app_dir, config_ru)) &&
203
+ ! File.exists?(File.join(web_app_dir, 'config/environment.rb'))
204
+ config[:rackup] = config_ru
129
205
  end
206
+ config[:rackup] || ! Dir[File.join(web_app_dir, 'WEB-INF/**/config.ru')].empty?
130
207
  end
131
208
 
132
- def configure_rack_servlet(servlet_class, servlet_name)
133
- servlet_config = @config[:servlet] || @app_config[:servlet] || {}
134
- @servlet = {
135
- :class => servlet_config[:class] || servlet_class,
136
- :name => servlet_config[:name] || servlet_name,
137
- :instance => servlet_config[:instance]
138
- }
209
+ def self.war?(config, default_config = nil)
210
+ config[:context_path] && config[:context_path][-4..-1] == '.war'
139
211
  end
212
+
213
+ class Holder
214
+
215
+ def initialize(web_app, context)
216
+ @web_app, @context = web_app, context
217
+ end
218
+
219
+ attr_reader :web_app
220
+ attr_accessor :context
221
+
222
+ def monitor; web_app.monitor; end
223
+
224
+ attr_accessor :monitor_mtime
225
+
226
+ def try_lock
227
+ locked? ? false : lock
228
+ end
229
+
230
+ def locked?; !!@lock; end
231
+ def lock; @lock = true; end
232
+ def unlock; @lock = false; end
233
+
234
+ # @deprecated behaves Hash like for (<= 1.3.5) compatibility
235
+ def [](key)
236
+ case key.to_sym
237
+ when :app then
238
+ web_app
239
+ when :context then
240
+ context
241
+ when :lock then
242
+ @lock
243
+ when :monitor then
244
+ monitor
245
+ when :mtime then
246
+ monitor_mtime
247
+ else raise NoMethodError, key.to_s
248
+ end
249
+ end
140
250
 
141
- def self.autodetect_configuration(config, app_config)
142
- # Check for Rails threadsafe mode
143
- environment = app_config[:environment] || config[:environment]
144
- if threadsafe_instance?(app_config[:web_app_dir], environment)
145
- app_config[:jruby_min_runtimes] = 1
146
- app_config[:jruby_max_runtimes] = 1
251
+ # @deprecated behaves Hash like for (<= 1.3.5) compatibility
252
+ def []=(key, val)
253
+ case key.to_sym
254
+ when :context then
255
+ self.context=(val)
256
+ when :lock then
257
+ @lock = val
258
+ when :mtime then
259
+ self.monitor_mtime=(val)
260
+ else raise NoMethodError, "#{key}="
261
+ end
147
262
  end
148
263
 
149
- rackup = config[:rackup] || 'config.ru'
150
- app_config[:web_app_dir] ||= config[:web_app_dir] || Dir.pwd
151
- # Check for rackup (but still use config/environment.rb for Rails 3)
152
- if !app_config[:rackup] &&
153
- File.exists?(File.join(app_config[:web_app_dir], rackup)) &&
154
- !File.exists?(File.join(app_config[:web_app_dir], 'config/environment.rb'))
155
- app_config[:rackup] = rackup
264
+ end
265
+
266
+ end
267
+
268
+ # Rack web application (looks for a rackup config.ru file).
269
+ class RackupWebApp < WebApp
270
+
271
+ def context_params
272
+ add_context_param 'rack.env', environment
273
+ if rackup = self.rackup
274
+ rackup = File.join(rackup, 'config.ru') if File.directory?(rackup)
275
+ add_context_param 'rackup.path', rackup
156
276
  end
277
+ super
278
+ end
279
+
280
+ def context_listener; 'org.jruby.rack.RackServletContextListener'; end
281
+
282
+ end
283
+
284
+ # Rails web app specifics. Supports the same versions as jruby-rack !
285
+ class RailsWebApp < WebApp
286
+
287
+ def context_params
288
+ add_context_param 'rails.env', environment
289
+ add_context_param 'rails.root', '/'
290
+ super
157
291
  end
158
292
 
159
- def self.threadsafe_instance?(app_base, environment)
293
+ def context_listener; 'org.jruby.rack.rails.RailsServletContextListener'; end
294
+
295
+ protected
296
+
297
+ def complete_config!
298
+ super
299
+ # detect threadsafe! in config/environments/environment.rb :
300
+ if self.class.threadsafe?(web_app_dir, environment)
301
+ config[:jruby_min_runtimes] = 1
302
+ config[:jruby_max_runtimes] = 1
303
+ end
304
+ end
305
+
306
+ private
307
+
308
+ def self.threadsafe?(app_base, environment)
160
309
  threadsafe_match?("#{app_base}/config/environments/#{environment}.rb") ||
161
310
  threadsafe_match?("#{app_base}/config/environment.rb")
162
311
  end
@@ -164,5 +313,28 @@ module Trinidad
164
313
  def self.threadsafe_match?(file)
165
314
  File.exist?(file) && File.readlines(file).any? { |l| l =~ /^[^#]*threadsafe!/ }
166
315
  end
316
+
317
+ end
318
+
319
+ # A web application for deploying (java) .war files.
320
+ class WarWebApp < WebApp
321
+
322
+ def context_path
323
+ super.gsub(/\.war$/, '')
324
+ end
325
+
326
+ def work_dir
327
+ File.join(web_app_dir.gsub(/\.war$/, ''), 'WEB-INF')
328
+ end
329
+
330
+ def monitor
331
+ File.expand_path(web_app_dir)
332
+ end
333
+
334
+ def define_lifecycle
335
+ Trinidad::Lifecycle::WebApp::War.new(self)
336
+ end
337
+
167
338
  end
339
+
168
340
  end
@@ -3,20 +3,21 @@ require 'tmpdir'
3
3
 
4
4
  namespace :tomcat do
5
5
 
6
- TOMCAT_CORE_PATH = File.expand_path('../../trinidad-libs/tomcat-core.jar', __FILE__)
6
+ TOMCAT_CORE_JAR = File.expand_path('../../trinidad-libs/tomcat-core.jar', __FILE__)
7
7
  TOMCAT_MAVEN_REPO = 'http://repo2.maven.org/maven2/org/apache/tomcat'
8
8
 
9
9
  tomcat = "#{TOMCAT_MAVEN_REPO}/embed/tomcat-embed-core/%s/tomcat-embed-core-%s.jar"
10
10
  tomcat_jasper = "#{TOMCAT_MAVEN_REPO}/embed/tomcat-embed-jasper/%s/tomcat-embed-jasper-%s.jar"
11
11
  tomcat_logging = "#{TOMCAT_MAVEN_REPO}/embed/tomcat-embed-logging-log4j/%s/tomcat-embed-logging-log4j-%s.jar"
12
12
 
13
- dependencies = [tomcat, tomcat_jasper, tomcat_logging]
13
+ dependencies = [ tomcat, tomcat_jasper, tomcat_logging ]
14
14
 
15
- desc "Updates Tomcat to a given version"
16
- task :update, :version do |task, args|
15
+ task :fetch, :version do |_, args|
17
16
  tomcat_version = [args[:version]] * 2
18
17
 
19
- Dir.chdir(Dir.tmpdir) do
18
+ temp_dir = File.join(Dir.tmpdir, (Time.now.to_f * 1000).to_i.to_s)
19
+ FileUtils.mkdir temp_dir
20
+ Dir.chdir(temp_dir) do
20
21
  dependencies.each do |dependency|
21
22
  dependency_path = dependency % tomcat_version
22
23
  dependency_name = dependency_path.split('/').last
@@ -28,17 +29,47 @@ namespace :tomcat do
28
29
  end
29
30
 
30
31
  # build the jar again
31
- puts "building the tomcat's core jar"
32
- %x{jar -cvf #{TOMCAT_CORE_PATH} META-INF javax org}
32
+ entries = Dir.entries(temp_dir) - [ '.', '..']
33
+ puts "building #{TOMCAT_CORE_JAR}"
34
+ %x{jar -cvf #{TOMCAT_CORE_JAR} #{entries.join(' ')}}
33
35
  end
36
+ FileUtils.rm_r temp_dir
37
+ end
38
+
39
+ TARGET_DIR = File.expand_path('../../target', __FILE__)
40
+
41
+ desc "Updates Tomcat to a given version e.g. `rake tomcat:update[7.0.26]`"
42
+ task :update, :version do |_, args|
43
+ Rake::Task['tomcat:fetch'].invoke(version = args[:version])
44
+ Rake::Task['tomcat:patch'].invoke
34
45
 
35
- puts "updating tomcat's version number to #{tomcat_version.first}"
46
+ puts "updating tomcat's version number to '#{version}'"
36
47
  path = File.expand_path('../../lib/trinidad/jars.rb', __FILE__)
37
48
  file = File.read(path)
38
- file.gsub!(/TOMCAT_VERSION = '(.+)'/, "TOMCAT_VERSION = '#{tomcat_version.first}'")
49
+ file.gsub!(/TOMCAT_VERSION = '(.+)'/, "TOMCAT_VERSION = '#{version}'")
39
50
  File.open(path, 'w') { |io| io.write(file) }
40
-
51
+
41
52
  puts "DONE - Tomcat's version has been updated succesfully, please build Trinidad again."
42
53
  end
54
+
55
+ task :compile do
56
+ FileUtils.mkdir TARGET_DIR unless File.exists?(TARGET_DIR)
57
+ sh 'javac -Xlint:deprecation -Xlint:unchecked -g -source 1.6 -target 1.6 ' +
58
+ "-classpath #{TOMCAT_CORE_JAR} -d #{TARGET_DIR} " +
59
+ Dir["src/java/**/*.java"].join(" ")
60
+ end
61
+
62
+ task :patch => :compile do
63
+ Dir.chdir(TARGET_DIR) do
64
+ entries = Dir.entries(TARGET_DIR) - [ '.', '..']
65
+ puts "updating #{TOMCAT_CORE_JAR}"
66
+ %x{jar -uvf #{TOMCAT_CORE_JAR} #{entries.join(' ')}}
67
+ end
68
+ end
69
+
70
+ task :clean do
71
+ rm_r TARGET_DIR if File.exist?(TARGET_DIR)
72
+ rm TOMCAT_CORE_JAR if File.exist?(TOMCAT_CORE_JAR)
73
+ end
43
74
 
44
75
  end