class Trinidad::WebApp
Constants
- DEFAULT_SERVLET_CLASS
- DEFAULT_SERVLET_NAME
- JSP_SERVLET_CLASS
- JSP_SERVLET_NAME
- RACK_FILTER_CLASS
- RACK_FILTER_NAME
- RACK_SERVLET_CLASS
- RACK_SERVLET_NAME
Attributes
Public Class Methods
# 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
# 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
Protected Class Methods
# File lib/trinidad/web_app.rb, line 526 def self.rackup?(config, default_config = nil) return true if config.has_key?(:rackup) root_dir = root_dir(config, default_config) config_ru = (default_config && default_config[:rackup]) || 'config.ru' # check for rackup (but still use config/environment.rb for rails 3) if File.exists?(File.join(root_dir, config_ru)) && ! rails?(config, default_config) # do not :rackup a rails app config[:rackup] = config_ru end config[:rackup] || ! Dir[File.join(root_dir, 'WEB-INF/**/config.ru')].empty? end
# File lib/trinidad/web_app.rb, line 538 def self.rails?(config, default_config = nil) root_dir = root_dir(config, default_config) # standart Rails 3.x `class Application < Rails::Application` if File.exists?(application = File.join(root_dir, 'config/application.rb')) return true if file_line_match?(application, /^[^#]*Rails::Application/) end if File.exists?(environment = File.join(root_dir, 'config/environment.rb')) return true if file_line_match?(environment) do |line| # customized Rails 3.x, expects a `Rails::Application` subclass # or a plain-old Rails 2.3 with `RAILS_GEM_VERSION = '2.3.14'` line =~ /^[^#]*Rails::Application/ || line =~ /^[^#]*RAILS_GEM_VERSION/ end end false end
# File lib/trinidad/web_app.rb, line 554 def self.war?(config, default_config = nil) root_dir = root_dir(config, default_config) return true if root_dir && root_dir.to_s[-4..-1] == '.war' context_path = config[:context_path] # backwards-compatibility : context_path && context_path.to_s[-4..-1] == '.war' end
Private Class Methods
# File lib/trinidad/web_app.rb, line 571 def self.context_path(config, default_config = nil) path = config[:context_path] || ( default_config && default_config[:context_path] ) unless path name = config[:context_name] || ( default_config && default_config[:context_name] ) path = name.to_s == 'default' ? '/' : "/#{name}" end path = "/#{path}" if path.to_s[0, 1] != '/' path.to_s end
# File lib/trinidad/web_app.rb, line 583 def self.file_line_match?(path, pattern = nil) File.open(path) do |file| if block_given? file.each_line { |line| return true if yield(line) } else file.each_line { |line| return true if line =~ pattern } end end false end
# File lib/trinidad/web_app.rb, line 563 def self.root_dir(config, default_config, default_dir = Dir.pwd) # for backwards compatibility accepts the :web_app_dir "alias" config[:root_dir] || config[:web_app_dir] || ( default_config && ( default_config[:root_dir] || default_config[:web_app_dir] ) ) || default_dir end
Public Instance Methods
# File lib/trinidad/web_app.rb, line 22 def [](key) key = key.to_sym config.key?(key) ? config[key] : default_config[key] end
# File lib/trinidad/web_app.rb, line 27 def []=(key, value) config[key.to_sym] = value end
# 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
# 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
# File lib/trinidad/web_app.rb, line 61 def allow_linking; key?(:allow_linking) ? self[:allow_linking] : true; end
# File lib/trinidad/web_app.rb, line 42 def app_root; root_dir; end
The cache max size in kB
# 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
The max size for a cached object in kB
# 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 entry time-to-live in millis
# 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
# 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
# File lib/trinidad/web_app.rb, line 271 def class_loader @class_loader ||= org.jruby.util.JRubyClassLoader.new(JRuby.runtime.jruby_class_loader) end
# File lib/trinidad/web_app.rb, line 276 def class_loader! ( @class_loader = nil ) || class_loader end
TODO: internal API - should be configurable/adjustable with context.yml !
# File lib/trinidad/web_app.rb, line 183 def context_manager; Java::RbTrinidadContext::DefaultManager.new end
# File lib/trinidad/web_app.rb, line 52 def context_name name = self[:context_name] || self[:name] name ? name.to_s : name end
# 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
# File lib/trinidad/web_app.rb, line 47 def context_path path = self[:context_path] || self[:path] path ? path.to_s : path end
# File lib/trinidad/web_app.rb, line 129 def context_xml; self[:context_xml] || self[:default_context_xml]; end
@deprecated use {#deployment_descriptor}
# 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
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)
# 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
# File lib/trinidad/web_app.rb, line 131 def default_web_xml; self[:default_web_xml]; end
# File lib/trinidad/web_app.rb, line 282 def define_lifecycle Lifecycle::WebApp::Default.new(self) end
# 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
NOTE: should be set to application root (base) directory thus JRuby-Rack correctly resolves relative paths for the context!
# File lib/trinidad/web_app.rb, line 59 def doc_base; self[:doc_base] || root_dir; end
# 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
# File lib/trinidad/web_app.rb, line 153 def extensions @extensions ||= begin extensions = default_config[:extensions] || {} extensions.merge(config[:extensions] || {}) end end
@deprecated replaced with {#class_loader!}
# File lib/trinidad/web_app.rb, line 280 def generate_class_loader; class_loader!; end
@deprecated replaced with {#context_params}
# File lib/trinidad/web_app.rb, line 173 def init_params; context_params; end
# 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
# File lib/trinidad/web_app.rb, line 148 def java_classes_dir @java_classes_dir ||= self[:java_classes_dir] || expand_path(java_classes) end
# 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
# File lib/trinidad/web_app.rb, line 143 def java_lib_dir @java_lib_dir ||= self[:java_lib_dir] || expand_path(java_lib) end
# File lib/trinidad/web_app.rb, line 92 def jruby_compat_version fetch_config_value(:jruby_compat_version, RUBY_VERSION) end
# 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
# 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
# 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
# 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
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)
# 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
# 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
@deprecated use `self` instead
# File lib/trinidad/web_app.rb, line 45 def log; self[:log]; end
by a “Rails” convention defaults to '[RAILS_ROOT]/log'
# File lib/trinidad/web_app.rb, line 121 def log_dir @log_dir ||= self[:log_dir] || File.join(root_dir, 'log') end
# 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
# File lib/trinidad/web_app.rb, line 125 def monitor File.expand_path(self[:monitor] || 'restart.txt', work_dir) end
we do support nested :public configuration e.g. : public:
root: /assets cache: true cache_ttl: 60000
# File lib/trinidad/web_app.rb, line 222 def public_config @public_config ||= self[:public].is_a?(String) ? { :root => self[:public] } : ( self[:public] || {} ) end
# File lib/trinidad/web_app.rb, line 111 def public_dir @public_dir ||= ( public_root == '/' ? root_dir : expand_path(public_root) ) end
# File lib/trinidad/web_app.rb, line 212 def public_root @public_root ||= ( public_config[:root] || @@defaults[:public] ) end
# File lib/trinidad/web_app.rb, line 395 def rack_listener context_listener unless web_xml_listener?(context_listener) end
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)
# 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 the hold web application state so it gets re-initialized. Please note that the configuration objects are not cleared.
# 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
@deprecated use {#rack_servlet} instead
# File lib/trinidad/web_app.rb, line 393 def servlet; rack_servlet; end
# File lib/trinidad/web_app.rb, line 401 def solo? ! is_a?(WarWebApp) && config[:solo] end
# File lib/trinidad/web_app.rb, line 405 def threadsafe? jruby_min_runtimes == 1 && jruby_max_runtimes == 1 # handles [:threadsafe] end
# File lib/trinidad/web_app.rb, line 399 def war?; self.class.war?(config); end
# File lib/trinidad/web_app.rb, line 130 def web_xml; self[:web_xml] || self[:default_web_xml]; end
Returns a param-value for a context-param with a given param-name.
# 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
# File lib/trinidad/web_app.rb, line 475 def web_xml_environment; nil; end
Returns true if a filter definition with a given filter-class is found.
# 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
Returns true if a listener definition with a given listener-class is found.
# 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
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.
# 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
by (a “Rails”) convention use '[RAILS_ROOT]/tmp'
# File lib/trinidad/web_app.rb, line 116 def work_dir @work_dir ||= self[:work_dir] || File.join(root_dir, 'tmp') end
Protected Instance Methods
# File lib/trinidad/web_app.rb, line 419 def complete_config! config[:root_dir] ||= self.class.root_dir(config, default_config) config[:root_dir] = File.expand_path(config[:root_dir]) config[:context_path] = self.class.context_path(config, default_config) end
# File lib/trinidad/web_app.rb, line 411 def context_listener raise NotImplementedError.new "context_listener expected to be redefined" end
# File lib/trinidad/web_app.rb, line 415 def layout_class 'JRuby::Rack::FileSystemLayout' # handles Rails as well as Rack end
Private Instance Methods
# File lib/trinidad/web_app.rb, line 494 def expand_path(path) if path path_file = java.io.File.new(path) if path_file.absolute? path_file.absolute_path else File.expand_path(path, root_dir) end end end
# File lib/trinidad/web_app.rb, line 505 def fetch_config_value(name, default = nil) value = config[name] value.nil? ? fetch_default_config_value(name, default) : value end
# File lib/trinidad/web_app.rb, line 510 def fetch_default_config_value(name, default = nil) value = default_config[name] if value.nil? # JRuby-Rack names: jruby_min_runtimes -> jruby.min.runtimes : value = java.lang.System.getProperty(name.to_s.gsub('_', '.')) value ||= default end value end
# File lib/trinidad/web_app.rb, line 520 def logger @logger ||= Logging::LogFactory.getLog('') end
# File lib/trinidad/web_app.rb, line 479 def web_xml_doc return @web_xml_doc || nil unless @web_xml_doc.nil? descriptor = deployment_descriptor if descriptor && File.exist?(descriptor) begin require 'rexml/document' @web_xml_doc = REXML::Document.new(File.read(descriptor)) rescue REXML::ParseException => e logger.warn "Invalid deployment descriptor:[#{descriptor}]\n #{e.message}" @web_xml_doc = false end @web_xml_doc || nil end end