Class: Trinidad::WebApp

Inherits:
Object
  • Object
show all
Defined in:
lib/trinidad/web_app.rb

Direct Known Subclasses

RackWebApp, RailsWebApp, WarWebApp

Defined Under Namespace

Classes: Holder

Constant Summary collapse

DEFAULT_SERVLET_CLASS =

by default we resolve by it’s name

nil
DEFAULT_SERVLET_NAME =
'default'
JSP_SERVLET_CLASS =

by default we resolve by it’s name

nil
JSP_SERVLET_NAME =
'jsp'
RACK_SERVLET_CLASS =
'org.jruby.rack.RackServlet'
RACK_SERVLET_NAME =

in-case of a “custom” rack servlet class

'rack'
RACK_FILTER_CLASS =
'org.jruby.rack.RackFilter'
RACK_FILTER_NAME =
'rack'
@@defaults =
Configuration::DEFAULTS

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(config, default_config = Trinidad.configuration) ⇒ WebApp

Returns a new instance of WebApp.



16
17
18
19
20
# File 'lib/trinidad/web_app.rb', line 16

def initialize(config, default_config = Trinidad.configuration)
  @config, @default_config = config, default_config || {}
  complete_config!
  # NOTE: we should maybe @config.freeze here ?!
end

Instance Attribute Details

#configObject (readonly)

Returns the value of attribute config.



8
9
10
# File 'lib/trinidad/web_app.rb', line 8

def config
  @config
end

#default_configObject (readonly)

Returns the value of attribute default_config.



8
9
10
# File 'lib/trinidad/web_app.rb', line 8

def default_config
  @default_config
end

Class Method Details

.create(config, default_config = Trinidad.configuration) ⇒ Object



10
11
12
13
14
# File 'lib/trinidad/web_app.rb', line 10

def self.create(config, default_config = Trinidad.configuration)
  war?(config, default_config) ? WarWebApp.new(config, default_config) :
    rackup?(config, default_config) ? RackupWebApp.new(config, default_config) :
      RailsWebApp.new(config, default_config)
end

Instance Method Details

#[](key) ⇒ Object



22
23
24
25
# File 'lib/trinidad/web_app.rb', line 22

def [](key)
  key = key.to_sym
  config.key?(key) ? config[key] : default_config[key]
end

#[]=(key, value) ⇒ Object



27
28
29
# File 'lib/trinidad/web_app.rb', line 27

def []=(key, value)
  config[key.to_sym] = value
end

#add_context_param(param_name, param_value) ⇒ Object



175
176
177
178
179
180
# File 'lib/trinidad/web_app.rb', line 175

def add_context_param(param_name, param_value)
  @context_params ||= {}
  if ! param_value.nil? && ! web_xml_context_param(param_name)
    @context_params[param_name] = param_value.to_s
  end
end

#aliasesObject

:public => { :aliases => … }



229
230
231
232
233
234
235
236
237
238
239
240
# File 'lib/trinidad/web_app.rb', line 229

def aliases # :public => { :aliases => ... }
  return nil unless aliases = ( self[:aliases] || public_config[:aliases] )
  return aliases if aliases.is_a?(String)
  # "/aliasPath1=docBase1,/aliasPath2=docBase2"
  @aliases ||= aliases.map do |path, base|
    path = path.to_s
    if (root = '/') != path[0, 1]
      path = (root << path)
    end
    "#{path}=#{File.expand_path(base, root_dir)}"
  end.join(',')
end

#allow_linkingObject



61
# File 'lib/trinidad/web_app.rb', line 61

def allow_linking; key?(:allow_linking) ? self[:allow_linking] : true; end

#app_rootObject



42
# File 'lib/trinidad/web_app.rb', line 42

def app_root; root_dir; end

#cache_max_sizeObject

The cache max size in kB



254
255
256
257
# File 'lib/trinidad/web_app.rb', line 254

def cache_max_size # :public => { :cache_max_size => ... }
  # ((BaseDirContext) resources).setCacheMaxSize
  self[:cache_max_size] || public_config[:cache_max_size]
end

#cache_object_max_sizeObject

The max size for a cached object in kB



260
261
262
263
# File 'lib/trinidad/web_app.rb', line 260

def cache_object_max_size # :public => { :cache_object_max_size => ... }
  # ((BaseDirContext) resources).setCacheObjectMaxSize
  self[:cache_object_max_size] || public_config[:cache_object_max_size]
end

#cache_ttlObject

Cache entry time-to-live in millis



266
267
268
269
# File 'lib/trinidad/web_app.rb', line 266

def cache_ttl # :public => { :cache_ttl => ... }
  # ((BaseDirContext) resources).setCacheTTL
  self[:cache_ttl] || public_config[:cache_ttl]
end

#caching_allowed?Boolean

:public => { :cached => … }

Returns:

  • (Boolean)


242
243
244
245
246
247
248
249
250
251
# File 'lib/trinidad/web_app.rb', line 242

def caching_allowed? # :public => { :cached => ... }
  # ((BaseDirContext) resources).setCached(isCachingAllowed())
  return @caching_allowed unless @caching_allowed.nil?
  @caching_allowed = self[:caching_allowed]
  if @caching_allowed.nil?
    @caching_allowed = public_config[:cached]
    @caching_allowed = environment != 'development' if @caching_allowed.nil?
  end
  @caching_allowed = !! @caching_allowed
end

#class_loaderObject



271
272
273
274
# File 'lib/trinidad/web_app.rb', line 271

def class_loader
  @class_loader ||=
    org.jruby.util.JRubyClassLoader.new(JRuby.runtime.jruby_class_loader)
end

#class_loader!Object



276
277
278
# File 'lib/trinidad/web_app.rb', line 276

def class_loader!
  ( @class_loader = nil ) || class_loader
end

#context_managerObject

TODO: internal API - should be configurable/adjustable with context.yml !



183
# File 'lib/trinidad/web_app.rb', line 183

def context_manager; Java::RbTrinidadContext::DefaultManager.new end

#context_nameObject



52
53
54
55
# File 'lib/trinidad/web_app.rb', line 52

def context_name
  name = self[:context_name] || self[:name]
  name ? name.to_s : name
end

#context_paramsObject



160
161
162
163
164
165
166
167
168
169
170
171
# File 'lib/trinidad/web_app.rb', line 160

def context_params
  @context_params ||= {}
  add_context_param 'jruby.min.runtimes', jruby_min_runtimes
  add_context_param 'jruby.max.runtimes', jruby_max_runtimes
  add_context_param 'jruby.initial.runtimes', jruby_initial_runtimes
  add_context_param 'jruby.runtime.acquire.timeout', jruby_runtime_acquire_timeout
  add_context_param 'jruby.compat.version', jruby_compat_version
  add_context_param 'public.root', public_root
  add_context_param 'jruby.rack.layout_class', layout_class
  add_context_param 'jruby.rack.error', false # do not start error app on errors
  @context_params
end

#context_pathObject



47
48
49
50
# File 'lib/trinidad/web_app.rb', line 47

def context_path
  path = self[:context_path] || self[:path]
  path ? path.to_s : path
end

#context_xmlObject



129
# File 'lib/trinidad/web_app.rb', line 129

def context_xml; self[:context_xml] || self[:default_context_xml]; end

#default_deployment_descriptorObject

Deprecated.


207
208
209
210
# File 'lib/trinidad/web_app.rb', line 207

def default_deployment_descriptor
  return nil if @default_deployment_descriptor == false
  @default_deployment_descriptor ||= expand_path(default_web_xml) || false
end

#default_servletObject

Returns a servlet config for the DefaultServlet. This servlet is setup for each and every Tomcat context and is named ‘default’ and mapped to ‘/’ we allow fine tunning of this servlet. Return values should be interpreted as follows :

true - do nothing leave the servlet as set-up (by default)
false - remove the set-up default (e.g. configured in web.xml)


303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
# File 'lib/trinidad/web_app.rb', line 303

def default_servlet
  return @default_servlet unless @default_servlet.nil?
  @default_servlet ||= begin
    if ! web_xml_servlet?(DEFAULT_SERVLET_CLASS, DEFAULT_SERVLET_NAME)
      default_servlet = self[:default_servlet]
      if default_servlet.is_a?(javax.servlet.Servlet)
        { :instance => default_servlet }
      elsif default_servlet == false
        false # forced by user to remove
      elsif default_servlet == true
        true # forced by user to leave as is
      else
        default_servlet = {} if default_servlet.nil?
        unless default_servlet.key?(:class)
          # we use a custom class by default to server /public assets :
          default_servlet[:class] = 'rb.trinidad.servlets.DefaultServlet'
        end
        default_servlet
      end
    else
      false # configured in web.xml thus remove the (default) "default"
    end
  end
end

#default_web_xmlObject



131
# File 'lib/trinidad/web_app.rb', line 131

def default_web_xml; self[:default_web_xml]; end

#define_lifecycleObject



282
283
284
# File 'lib/trinidad/web_app.rb', line 282

def define_lifecycle
  Lifecycle::WebApp::Default.new(self)
end

#deployment_descriptorObject



201
202
203
204
# File 'lib/trinidad/web_app.rb', line 201

def deployment_descriptor
  return nil if @deployment_descriptor == false
  @deployment_descriptor ||= expand_path(web_xml) || false
end

#doc_baseObject

NOTE: should be set to application root (base) directory thus JRuby-Rack correctly resolves relative paths for the context!



59
# File 'lib/trinidad/web_app.rb', line 59

def doc_base; self[:doc_base] || root_dir; end

#environmentObject



96
97
98
99
100
101
102
103
104
105
106
107
108
109
# File 'lib/trinidad/web_app.rb', line 96

def environment
  @environment ||= begin
    if env = web_xml_environment
      if self[:environment] && env != self[:environment]
        logger.info "Ignoring set :environment '#{self[:environment]}' for " <<
          "#{context_path} since it's configured in web.xml as '#{env}'"
      end
    else
      env = self[:environment] || @@defaults[:environment]
      env = env.to_s if env.is_a?(Symbol) # make sure it's a String
    end
    env
  end
end

#extensionsObject



153
154
155
156
157
158
# File 'lib/trinidad/web_app.rb', line 153

def extensions
  @extensions ||= begin
    extensions = default_config[:extensions] || {}
    extensions.merge(config[:extensions] || {})
  end
end

#generate_class_loaderObject

Deprecated.

replaced with #class_loader!



280
# File 'lib/trinidad/web_app.rb', line 280

def generate_class_loader; class_loader!; end

#init_paramsObject

Deprecated.

replaced with #context_params



173
# File 'lib/trinidad/web_app.rb', line 173

def init_params; context_params; end

#java_classesObject



138
139
140
141
# File 'lib/trinidad/web_app.rb', line 138

def java_classes
  # accepts #deprecated :classes_dir syntax
  self[:java_classes] || self[:classes_dir] || File.join(java_lib, 'classes')
end

#java_classes_dirObject Also known as: classes_dir



148
149
150
# File 'lib/trinidad/web_app.rb', line 148

def java_classes_dir
  @java_classes_dir ||= self[:java_classes_dir] || expand_path(java_classes)
end

#java_libObject



133
134
135
136
# File 'lib/trinidad/web_app.rb', line 133

def java_lib
  # accepts #deprecated :libs_dir syntax
  self[:java_lib] || self[:libs_dir] || @@defaults[:java_lib]
end

#java_lib_dirObject Also known as: libs_dir



143
144
145
# File 'lib/trinidad/web_app.rb', line 143

def java_lib_dir
  @java_lib_dir ||= self[:java_lib_dir] || expand_path(java_lib)
end

#jruby_compat_versionObject



92
93
94
# File 'lib/trinidad/web_app.rb', line 92

def jruby_compat_version
  fetch_config_value(:jruby_compat_version, RUBY_VERSION)
end

#jruby_initial_runtimesObject



79
80
81
82
83
84
85
86
# File 'lib/trinidad/web_app.rb', line 79

def jruby_initial_runtimes
  if ini = config[:jruby_initial_runtimes]
    return ini.to_i # min specified overrides :threadsafe
  else # but :threadsafe takes precendence over default :
    self[:threadsafe] ? 1 :
      fetch_default_config_value(:jruby_initial_runtimes, jruby_min_runtimes)
  end
end

#jruby_max_runtimesObject



71
72
73
74
75
76
77
# File 'lib/trinidad/web_app.rb', line 71

def jruby_max_runtimes
  if max = config[:jruby_max_runtimes]
    return max.to_i # max specified overrides :threadsafe
  else # but :threadsafe takes precendence over default :
    self[:threadsafe] ? 1 : fetch_default_config_value(:jruby_max_runtimes)
  end
end

#jruby_min_runtimesObject



63
64
65
66
67
68
69
# File 'lib/trinidad/web_app.rb', line 63

def jruby_min_runtimes
  if min = config[:jruby_min_runtimes]
    return min.to_i # min specified overrides :threadsafe
  else # but :threadsafe takes precendence over default :
    self[:threadsafe] ? 1 : fetch_default_config_value(:jruby_min_runtimes)
  end
end

#jruby_runtime_acquire_timeoutObject



88
89
90
# File 'lib/trinidad/web_app.rb', line 88

def jruby_runtime_acquire_timeout
  fetch_config_value(:jruby_runtime_acquire_timeout, 5.0) # default 10s seems too high
end

#jsp_servletObject

Returns a servlet config for the JspServlet. This servlet is setup by default for every Tomcat context and is named ‘jsp’ with ‘*.jsp’ and ‘*.jspx’ mappings. Return values should be interpreted as follows :

true - do nothing leave the servlet as set-up (by default)
false - remove the set-up servlet (by default we do not need jsp support)


337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
# File 'lib/trinidad/web_app.rb', line 337

def jsp_servlet
  return @jsp_servlet unless @jsp_servlet.nil?
  @jsp_servlet ||= begin
    if ! web_xml_servlet?(JSP_SERVLET_CLASS, JSP_SERVLET_NAME)
      jsp_servlet = self[:jsp_servlet]
      if jsp_servlet.is_a?(javax.servlet.Servlet)
        { :instance => jsp_servlet }
      else
        jsp_servlet || false # remove jsp support unless specified
      end
    else
      false # configured in web.xml thus remove the default "jsp"
    end
  end
end

#key?(key, use_default = true) ⇒ Boolean

Returns:

  • (Boolean)


31
32
33
34
35
# File 'lib/trinidad/web_app.rb', line 31

def key?(key, use_default = true)
  key = key.to_sym
  return true if config.has_key?(key)
  use_default ? default_config.key?(key) : false
end

#logObject

Deprecated.

use ‘self` instead



45
# File 'lib/trinidad/web_app.rb', line 45

def log; self[:log]; end

#log_dirObject

by a “Rails” convention defaults to ‘[RAILS_ROOT]/log’



121
122
123
# File 'lib/trinidad/web_app.rb', line 121

def log_dir
  @log_dir ||= self[:log_dir] || File.join(root_dir, 'log')
end

#loggingObject



185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
# File 'lib/trinidad/web_app.rb', line 185

def logging
  @logging ||= begin
    defaults = {
      :level => log, # backwards compatibility
      :use_parent_handlers => ( environment == 'development' ),
      :file => {
        :dir => log_dir,
        :prefix => environment,
        :suffix => '.log',
        :rotate => true
      }
    }
    Configuration.merge_options(defaults, self[:logging])
  end
end

#monitorObject



125
126
127
# File 'lib/trinidad/web_app.rb', line 125

def monitor
  File.expand_path(self[:monitor] || 'restart.txt', work_dir)
end

#public_configObject

we do support nested :public configuration e.g. : public:

root: /assets
cache: true
cache_ttl: 60000


222
223
224
225
226
227
# File 'lib/trinidad/web_app.rb', line 222

def public_config
  @public_config ||=
    self[:public].is_a?(String) ?
      { :root => self[:public] } :
        ( self[:public] || {} )
end

#public_dirObject



111
112
113
# File 'lib/trinidad/web_app.rb', line 111

def public_dir
  @public_dir ||= ( public_root == '/' ? root_dir : expand_path(public_root) )
end

#public_rootObject Also known as: public



212
213
214
# File 'lib/trinidad/web_app.rb', line 212

def public_root
  @public_root ||= ( public_config[:root] || @@defaults[:public] )
end

#rack_listenerObject



395
396
397
# File 'lib/trinidad/web_app.rb', line 395

def rack_listener
  context_listener unless web_xml_listener?(context_listener)
end

#rack_servletObject

Returns a config for the RackServlet or nil if no need to set-up one. (to be used for dispatching to this Rack / Rails web application)



360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
# File 'lib/trinidad/web_app.rb', line 360

def rack_servlet
  return nil if @rack_servlet == false
  @rack_servlet ||= begin
    rack_servlet = self[:rack_servlet] || self[:servlet] || {}

    if rack_servlet.is_a?(javax.servlet.Servlet)
      { :instance => rack_servlet, :name => RACK_SERVLET_NAME, :mapping => '/*' }
    else
      servlet_class = rack_servlet[:class] || RACK_SERVLET_CLASS
      servlet_name = rack_servlet[:name] || RACK_SERVLET_NAME

      if ! web_xml_servlet?(servlet_class, servlet_name) &&
          ! web_xml_filter?(RACK_FILTER_CLASS, RACK_FILTER_NAME)
        {
          :instance => rack_servlet[:instance],
          :class => servlet_class, :name => servlet_name,
          :init_params => rack_servlet[:init_params],
          :async_supported => !! ( rack_servlet.has_key?(:async_supported) ?
              rack_servlet[:async_supported] : async_supported ),
          :load_on_startup => ( rack_servlet[:load_on_startup] || 2 ).to_i,
          :mapping => rack_servlet[:mapping] || '/*'
        }
      else
        if ! rack_servlet.empty?
          logger.info "Ignoring :rack_servlet configuration for " <<
                      "#{context_path} due #{deployment_descriptor}"
        end
        false # no need to setup a rack servlet
      end
    end
  end || nil
end

#reset!Object

Reset the hold web application state so it gets re-initialized. Please note that the configuration objects are not cleared.



288
289
290
291
292
# File 'lib/trinidad/web_app.rb', line 288

def reset!
  vars = instance_variables.map(&:to_sym)
  vars = vars - [ :'@config', :'@default_config' ]
  vars.each { |var| instance_variable_set(var, nil) }
end

#servletObject

Deprecated.

use #rack_servlet instead



393
# File 'lib/trinidad/web_app.rb', line 393

def servlet; rack_servlet; end

#solo?Boolean

Returns:

  • (Boolean)


401
402
403
# File 'lib/trinidad/web_app.rb', line 401

def solo?
  ! is_a?(WarWebApp) && config[:solo]
end

#threadsafe?Boolean

Returns:

  • (Boolean)


405
406
407
# File 'lib/trinidad/web_app.rb', line 405

def threadsafe?
  jruby_min_runtimes == 1 && jruby_max_runtimes == 1 # handles [:threadsafe]
end

#war?Boolean

Returns:

  • (Boolean)


399
# File 'lib/trinidad/web_app.rb', line 399

def war?; self.class.war?(config); end

#web_app_dirObject

is getting deprecated soon



41
# File 'lib/trinidad/web_app.rb', line 41

alias_method :web_app_dir, :root_dir

#web_xmlObject



130
# File 'lib/trinidad/web_app.rb', line 130

def web_xml; self[:web_xml] || self[:default_web_xml]; end

#web_xml_context_param(name) ⇒ Object

Returns a param-value for a context-param with a given param-name.



468
469
470
471
472
473
# File 'lib/trinidad/web_app.rb', line 468

def web_xml_context_param(name)
  return nil unless web_xml_doc
  if param = web_xml_doc.root.elements["/web-app/context-param[param-name = '#{name}']"]
    param.elements['param-value'].text
  end
end

#web_xml_environmentObject



475
# File 'lib/trinidad/web_app.rb', line 475

def web_xml_environment; nil; end

#web_xml_filter?(filter_class, filter_name = nil) ⇒ Boolean

Returns true if a filter definition with a given filter-class is found.

Returns:

  • (Boolean)

Raises:

  • (ArgumentError)


446
447
448
449
450
451
452
453
454
455
456
457
458
459
# File 'lib/trinidad/web_app.rb', line 446

def web_xml_filter?(filter_class, filter_name = nil)
  return nil unless web_xml_doc
  if filter_class
    filter_xpath = "/web-app/filter[filter-class = '#{filter_class}']"
    return true if web_xml_doc.root.elements[filter_xpath] # else try name
  end
  if filter_name
    filter_xpath = "/web-app/filter[filter-name = '#{filter_name}']"
    return !! web_xml_doc.root.elements[filter_xpath]
  end

  return false if filter_class || filter_name
  raise ArgumentError, "nor filter_class nor filter_name given"
end

#web_xml_listener?(listener_class) ⇒ Boolean

Returns true if a listener definition with a given listener-class is found.

Returns:

  • (Boolean)


462
463
464
465
# File 'lib/trinidad/web_app.rb', line 462

def web_xml_listener?(listener_class)
  return nil unless web_xml_doc
  !! web_xml_doc.root.elements["/web-app/listener[listener-class = '#{listener_class}']"]
end

#web_xml_servlet?(servlet_class, servlet_name = nil) ⇒ Boolean

Returns true if there’s a servlet with the given servlet-class name configured or if the optional name second argument is given it also checks for a servlet with the given name.

Returns:

  • (Boolean)

Raises:

  • (ArgumentError)


430
431
432
433
434
435
436
437
438
439
440
441
442
443
# File 'lib/trinidad/web_app.rb', line 430

def web_xml_servlet?(servlet_class, servlet_name = nil)
  return nil unless web_xml_doc
  if servlet_class
    servlet_xpath = "/web-app/servlet[servlet-class = '#{servlet_class}']"
    return true if web_xml_doc.root.elements[servlet_xpath] # else try name
  end
  if servlet_name
    servlet_xpath = "/web-app/servlet[servlet-name = '#{servlet_name}']"
    return !! web_xml_doc.root.elements[servlet_xpath]
  end

  return false if servlet_class || servlet_name
  raise ArgumentError, "nor servlet_class nor servlet_name given"
end

#work_dirObject

by (a “Rails”) convention use ‘[RAILS_ROOT]/tmp’



116
117
118
# File 'lib/trinidad/web_app.rb', line 116

def work_dir
  @work_dir ||= self[:work_dir] || File.join(root_dir, 'tmp')
end