waw 0.2.2
Sign up to get free protection for your applications and to get access to all the features.
- data/LICENCE.rdoc +25 -0
- data/README.rdoc +32 -0
- data/bin/waw +32 -0
- data/bin/waw-profile +26 -0
- data/bin/waw-start +26 -0
- data/bin/wspec +33 -0
- data/layouts/empty/Rakefile +14 -0
- data/layouts/empty/config.ru +5 -0
- data/layouts/empty/config/commons.cfg +31 -0
- data/layouts/empty/config/devel.cfg +21 -0
- data/layouts/empty/ignore +7 -0
- data/layouts/empty/logs/dontforgetme +0 -0
- data/layouts/empty/resources/messages.rs +1 -0
- data/layouts/empty/test/wspec/site_respond.wspec +3 -0
- data/layouts/empty/test/wspec/test_all.rb +13 -0
- data/layouts/empty/waw.deploy +1 -0
- data/layouts/empty/waw.routing +6 -0
- data/layouts/static/dependencies +1 -0
- data/layouts/static/public/.wawaccess +18 -0
- data/layouts/static/public/css/style.css +0 -0
- data/layouts/static/public/images/dontforgetme +0 -0
- data/layouts/static/public/js/project.js +0 -0
- data/layouts/static/public/pages/.wawaccess +30 -0
- data/layouts/static/public/pages/404.wtpl +1 -0
- data/layouts/static/public/pages/index.wtpl +5 -0
- data/layouts/static/public/templates/.wawaccess +9 -0
- data/layouts/static/public/templates/layout.wtpl +17 -0
- data/layouts/static/test/wspec/static_pages_are_served.wspec +21 -0
- data/layouts/static/waw.routing +8 -0
- data/lib/waw.rb +99 -0
- data/lib/waw/commands/command.rb +115 -0
- data/lib/waw/commands/profile_command.rb +66 -0
- data/lib/waw/commands/start_command.rb +59 -0
- data/lib/waw/config.rb +110 -0
- data/lib/waw/controller.rb +25 -0
- data/lib/waw/controllers/action/action.rb +91 -0
- data/lib/waw/controllers/action/action_utils.rb +30 -0
- data/lib/waw/controllers/action/js_generation.rb +116 -0
- data/lib/waw/controllers/action_controller.rb +133 -0
- data/lib/waw/controllers/error/backtrace.rb +54 -0
- data/lib/waw/controllers/error_handler.rb +62 -0
- data/lib/waw/controllers/json_controller.rb +31 -0
- data/lib/waw/controllers/no_cache.rb +22 -0
- data/lib/waw/controllers/static/match.rb +80 -0
- data/lib/waw/controllers/static/waw_access.rb +235 -0
- data/lib/waw/controllers/static/waw_access_dsl.rb +48 -0
- data/lib/waw/controllers/static_controller.rb +37 -0
- data/lib/waw/default_config.cfg +14 -0
- data/lib/waw/environment_utils.rb +57 -0
- data/lib/waw/errors.rb +4 -0
- data/lib/waw/ext.rb +3 -0
- data/lib/waw/ext/core.rb +4 -0
- data/lib/waw/ext/core/hash.rb +47 -0
- data/lib/waw/ext/core/logger.rb +10 -0
- data/lib/waw/ext/core/module.rb +20 -0
- data/lib/waw/ext/core/object.rb +29 -0
- data/lib/waw/ext/rack.rb +19 -0
- data/lib/waw/ext/rack/builder.rb +43 -0
- data/lib/waw/ext/rack/delegator.rb +51 -0
- data/lib/waw/ext/rack/urlmap.rb +55 -0
- data/lib/waw/ext/wlang.rb +1 -0
- data/lib/waw/ext/wlang/hosted_language.rb +21 -0
- data/lib/waw/fullstate.rb +8 -0
- data/lib/waw/fullstate/on_class.rb +37 -0
- data/lib/waw/fullstate/on_instance.rb +27 -0
- data/lib/waw/fullstate/variable.rb +36 -0
- data/lib/waw/kern.rb +6 -0
- data/lib/waw/kern/app.rb +48 -0
- data/lib/waw/kern/empty/waw.deploy +0 -0
- data/lib/waw/kern/empty/waw.routing +1 -0
- data/lib/waw/kern/freezed_state.rb +32 -0
- data/lib/waw/kern/hooks.rb +53 -0
- data/lib/waw/kern/lifecycle.rb +248 -0
- data/lib/waw/kern/living_state.rb +87 -0
- data/lib/waw/kern/utils.rb +27 -0
- data/lib/waw/resource_collection.rb +100 -0
- data/lib/waw/restart.rb +32 -0
- data/lib/waw/routing.rb +43 -0
- data/lib/waw/routing/action_routing.rb +78 -0
- data/lib/waw/routing/dsl.rb +45 -0
- data/lib/waw/routing/feedback.rb +23 -0
- data/lib/waw/routing/form_validation_feedback.rb +36 -0
- data/lib/waw/routing/javascript.rb +17 -0
- data/lib/waw/routing/redirect.rb +26 -0
- data/lib/waw/routing/refresh.rb +17 -0
- data/lib/waw/routing/routing_rule.rb +16 -0
- data/lib/waw/scope_utils.rb +69 -0
- data/lib/waw/session.rb +51 -0
- data/lib/waw/testing.rb +1 -0
- data/lib/waw/tools/mail.rb +4 -0
- data/lib/waw/tools/mail/mail.rb +119 -0
- data/lib/waw/tools/mail/mail_agent.rb +123 -0
- data/lib/waw/tools/mail/mailbox.rb +62 -0
- data/lib/waw/tools/mail/template.rb +38 -0
- data/lib/waw/utils/dsl_helper.rb +116 -0
- data/lib/waw/validation.rb +175 -0
- data/lib/waw/validation/and_validator.rb +27 -0
- data/lib/waw/validation/array_validations.rb +38 -0
- data/lib/waw/validation/boolean_validator.rb +32 -0
- data/lib/waw/validation/comparison_validations.rb +45 -0
- data/lib/waw/validation/date_validator.rb +31 -0
- data/lib/waw/validation/default_validator.rb +30 -0
- data/lib/waw/validation/dsl_ruby_extensions.rb +11 -0
- data/lib/waw/validation/errors.rb +17 -0
- data/lib/waw/validation/ext.rb +3 -0
- data/lib/waw/validation/file_validator.rb +30 -0
- data/lib/waw/validation/float_validator.rb +19 -0
- data/lib/waw/validation/helpers.rb +67 -0
- data/lib/waw/validation/integer_validator.rb +16 -0
- data/lib/waw/validation/isin_validator.rb +24 -0
- data/lib/waw/validation/mandatory_validator.rb +17 -0
- data/lib/waw/validation/missing_validator.rb +17 -0
- data/lib/waw/validation/not_validator.rb +20 -0
- data/lib/waw/validation/or_validator.rb +34 -0
- data/lib/waw/validation/regexp_validator.rb +29 -0
- data/lib/waw/validation/same_validator.rb +16 -0
- data/lib/waw/validation/signature.rb +157 -0
- data/lib/waw/validation/size_validations.rb +44 -0
- data/lib/waw/validation/string_validator.rb +15 -0
- data/lib/waw/validation/validator.rb +48 -0
- data/lib/waw/wawgen.rb +2 -0
- data/lib/waw/wawgen/create.rb +166 -0
- data/lib/waw/wawgen/project.rb +25 -0
- data/lib/waw/wspec.rb +5 -0
- data/lib/waw/wspec/browser.rb +240 -0
- data/lib/waw/wspec/dsl.rb +201 -0
- data/lib/waw/wspec/html_analysis.rb +136 -0
- data/lib/waw/wspec/html_analysis/tag.rb +56 -0
- data/lib/waw/wspec/runner.rb +70 -0
- data/lib/waw/wspec/scenario.rb +35 -0
- data/lib/waw/wspec/suite.rb +54 -0
- data/test/bricks/error_handler/config/test.cfg +2 -0
- data/test/bricks/error_handler/logs/webapp.log +1411 -0
- data/test/bricks/error_handler/test/error_handler.wspec +16 -0
- data/test/bricks/error_handler/waw.deploy +1 -0
- data/test/bricks/error_handler/waw.routing +27 -0
- data/test/integration/waw_create_integration_test.rb +24 -0
- data/test/spec/assumptions_spec.rb +30 -0
- data/test/spec/controllers/action_controller_spec.rb +14 -0
- data/test/spec/controllers/static/waw_access_spec.rb +112 -0
- data/test/spec/environment_utils_spec.rb +15 -0
- data/test/spec/ext/core/hash_spec.rb +58 -0
- data/test/spec/fixtures.rb +41 -0
- data/test/spec/fixtures/action/config/default.cfg +2 -0
- data/test/spec/fixtures/action/lib/action_controller_test.rb +12 -0
- data/test/spec/fixtures/action/waw.deploy +1 -0
- data/test/spec/fixtures/action/waw.routing +6 -0
- data/test/spec/fixtures/empty/waw.deploy +0 -0
- data/test/spec/fixtures/empty/waw.routing +0 -0
- data/test/spec/fullstate/on_class_spec.rb +59 -0
- data/test/spec/fullstate/on_instance_spec.rb +59 -0
- data/test/spec/fullstate/session_spec.rb +43 -0
- data/test/spec/fullstate/variable_spec.rb +55 -0
- data/test/spec/resource_collection_spec.rb +50 -0
- data/test/spec/test_all.rb +9 -0
- data/test/spec/tools/mail/mail_agent_spec.rb +116 -0
- data/test/spec/tools/mail/mail_spec.rb +56 -0
- data/test/spec/tools/mail/mailbox_spec.rb +57 -0
- data/test/spec/tools/mail/template_spec.rb +47 -0
- data/test/spec/validation/array_validation_spec.rb +63 -0
- data/test/spec/validation/array_validator_spec.rb +17 -0
- data/test/spec/validation/date_validation_spec.rb +35 -0
- data/test/spec/validation/default_validation_spec.rb +37 -0
- data/test/spec/validation/disjuctive_validation_spec.rb +33 -0
- data/test/spec/validation/errors_spec.rb +37 -0
- data/test/spec/validation/file_validator_spec.rb +34 -0
- data/test/spec/validation/mail_validation_spec.rb +51 -0
- data/test/spec/validation/missing_validation_spec.rb +43 -0
- data/test/spec/validation/same_validation_spec.rb +24 -0
- data/test/spec/validation/signature_intuition_spec.rb +37 -0
- data/test/spec/validation/signature_spec.rb +164 -0
- data/test/spec/validation/validation_spec.rb +28 -0
- data/test/spec/wspec/html_analysis/tag_spec.rb +38 -0
- data/test/spec/wspec/html_analysis_spec.rb +170 -0
- data/test/unit/test_all.rb +8 -0
- data/test/unit/waw/app_test.rb +126 -0
- data/test/unit/waw/app_test/config/commons.cfg +2 -0
- data/test/unit/waw/app_test/config/devel.cfg +1 -0
- data/test/unit/waw/config_test.rb +54 -0
- data/test/unit/waw/controllers/action_controller_test.rb +76 -0
- data/test/unit/waw/controllers/action_test.rb +35 -0
- data/test/unit/waw/controllers/example_action_controller_test.rb +24 -0
- data/test/unit/waw/controllers/multiple_action_controller_test.rb +78 -0
- data/test/unit/waw/controllers/static/example/css/example.css +1 -0
- data/test/unit/waw/controllers/static/example/index.html +1 -0
- data/test/unit/waw/controllers/static/example/js/example.js +1 -0
- data/test/unit/waw/controllers/static/example/pages/hello.wtpl +1 -0
- data/test/unit/waw/controllers/static/waw_access_test.rb +76 -0
- data/test/unit/waw/ext/rack_test.rb +74 -0
- data/test/unit/waw/resource_collection_test.rb +49 -0
- data/test/unit/waw/resources.txt +4 -0
- data/test/unit/waw/routing/routing_test.rb +26 -0
- data/test/unit/waw/utils/dsl_helper_test.rb +79 -0
- data/test/unit/waw/utils/dsl_helper_test_extensions1.rb +4 -0
- data/test/unit/waw/validation/signature_test.rb +193 -0
- data/test/unit/waw/validation_test.rb +319 -0
- data/test/unit/waw/wspec/html_analysis_test.html +81 -0
- data/test/unit/waw/wspec/html_analysis_test.rb +26 -0
- metadata +272 -0
data/lib/waw/kern/app.rb
ADDED
@@ -0,0 +1,48 @@
|
|
1
|
+
module Waw
|
2
|
+
module Kern
|
3
|
+
# Kernel waw application
|
4
|
+
class App
|
5
|
+
include ::Rack::Delegator
|
6
|
+
include ::Waw::Kern::FreezedState
|
7
|
+
include ::Waw::Kern::LivingState
|
8
|
+
include ::Waw::Kern::Hooks
|
9
|
+
include ::Waw::Kern::Utils
|
10
|
+
include ::Waw::Kern::Lifecycle
|
11
|
+
|
12
|
+
# Creates a kernel application instance
|
13
|
+
def initialize(identifier = nil, options = {})
|
14
|
+
@options = options
|
15
|
+
end
|
16
|
+
|
17
|
+
# Installs the environment and delegates to the business
|
18
|
+
# application
|
19
|
+
def call(env)
|
20
|
+
install_living_state(env)
|
21
|
+
if app=self.app
|
22
|
+
app.call(env)
|
23
|
+
else
|
24
|
+
[503, {'Content-Type' => 'text/plain'}, ['This waw application is unloaded']]
|
25
|
+
end
|
26
|
+
rescue ::WLang::Error => ex
|
27
|
+
# On exception, returns a 500 with a message
|
28
|
+
logger.error("Fatal error #{ex.message}")
|
29
|
+
logger.error(ex.wlang_backtrace.join("\n"))
|
30
|
+
logger.error(ex.backtrace.join("\n"))
|
31
|
+
[500, {'Content-Type' => 'text/plain'}, ['500 Internal Server Error']]
|
32
|
+
rescue Exception => ex
|
33
|
+
# On exception, returns a 500 with a message
|
34
|
+
logger.error("Fatal error #{ex.message}")
|
35
|
+
logger.error(ex.backtrace.join("\n"))
|
36
|
+
[500, {'Content-Type' => 'text/plain'}, ['500 Internal Server Error']]
|
37
|
+
ensure
|
38
|
+
clean_living_state
|
39
|
+
end
|
40
|
+
|
41
|
+
# Returns an identifier for this kernel application
|
42
|
+
def identifier
|
43
|
+
@identifier || "No identifier (#{root_folder}/#{routing})"
|
44
|
+
end
|
45
|
+
|
46
|
+
end # class App
|
47
|
+
end # module Kern
|
48
|
+
end # module Waw
|
File without changes
|
@@ -0,0 +1 @@
|
|
1
|
+
nil
|
@@ -0,0 +1,32 @@
|
|
1
|
+
module Waw
|
2
|
+
module Kern
|
3
|
+
#
|
4
|
+
# Contains all attribute accessors for what is considered freezed
|
5
|
+
# after application loading.
|
6
|
+
#
|
7
|
+
module FreezedState
|
8
|
+
|
9
|
+
# Root application folder
|
10
|
+
attr_accessor :root_folder
|
11
|
+
|
12
|
+
# Deploy words found in waw.deploy
|
13
|
+
attr_accessor :deploy_words
|
14
|
+
|
15
|
+
# ::Waw::Config instance
|
16
|
+
attr_accessor :config
|
17
|
+
|
18
|
+
# Logger instance
|
19
|
+
attr_accessor :logger
|
20
|
+
|
21
|
+
# ::Waw::ResourceCollection instance
|
22
|
+
attr_accessor :resources
|
23
|
+
|
24
|
+
# Routing name
|
25
|
+
attr_accessor :routing
|
26
|
+
|
27
|
+
# Rack user's application
|
28
|
+
attr_accessor :app
|
29
|
+
|
30
|
+
end # module FreezedState
|
31
|
+
end # module Kern
|
32
|
+
end # module Waw
|
@@ -0,0 +1,53 @@
|
|
1
|
+
module Waw
|
2
|
+
module Kern
|
3
|
+
#
|
4
|
+
# Provides the hook support to the waw kernel.
|
5
|
+
#
|
6
|
+
# This module installs a @hooks instance variable (array of hooks by
|
7
|
+
# abstract name). It also expects the _root_folder_ and _logger_ instance
|
8
|
+
# variables provided by other modules.
|
9
|
+
#
|
10
|
+
module Hooks
|
11
|
+
|
12
|
+
# Returns installed hooks for a given abstract name _which_ (:load,
|
13
|
+
# :start, :unload,...). This method always returns an array, which
|
14
|
+
# can be empty if no hook is currently installed under _which_.
|
15
|
+
def hooks(which)
|
16
|
+
@hooks = Hash.new{|h,k| h[k] = []} if @hooks.nil?
|
17
|
+
@hooks[which]
|
18
|
+
end
|
19
|
+
|
20
|
+
# Adds a start hook.
|
21
|
+
def add_start_hook(hook = nil, &block)
|
22
|
+
hooks(:start) << (hook || block)
|
23
|
+
end
|
24
|
+
|
25
|
+
# Adds an unload hook.
|
26
|
+
def add_unload_hook(hook = nil, &block)
|
27
|
+
hooks(:unload) << (hook || block)
|
28
|
+
end
|
29
|
+
|
30
|
+
# Executes all hooks installed under _which_. Hooks installed through
|
31
|
+
# the API are executed first. Hooks installed under root_folder/hooks/_which_
|
32
|
+
# are executed then.
|
33
|
+
def execute_hooks(which)
|
34
|
+
# API installed hooks
|
35
|
+
hooks(which).each do |hook|
|
36
|
+
if hook.respond_to?(:run)
|
37
|
+
hook.run(self)
|
38
|
+
elsif hook.respond_to?(:call)
|
39
|
+
hook.call(self)
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
43
|
+
# the file ones now
|
44
|
+
hooks_dir = File.join(root_folder, 'hooks', which.to_s)
|
45
|
+
Dir[File.join(hooks_dir, '*.rb')].sort{|f1, f2| File.basename(f1) <=> File.basename(f2)}.each do |file|
|
46
|
+
logger.info("Running waw #{which} hook #{file}...")
|
47
|
+
::Kernel.load(file)
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
51
|
+
end # module Hooks
|
52
|
+
end # module Kern
|
53
|
+
end # module Waw
|
@@ -0,0 +1,248 @@
|
|
1
|
+
module Waw
|
2
|
+
module Kern
|
3
|
+
#
|
4
|
+
# Implements waw kernel's lifecycle.
|
5
|
+
#
|
6
|
+
module Lifecycle
|
7
|
+
|
8
|
+
#
|
9
|
+
# Autoloads waw from a given location. The waw root_folder is found
|
10
|
+
# using find_web_root and the application loaded using load_application.
|
11
|
+
#
|
12
|
+
# This method expects read/write accessors for the instance variables below.
|
13
|
+
# All these variables are expected to be initially nil and are affected when
|
14
|
+
# the application is loaded (see load_application).
|
15
|
+
#
|
16
|
+
# * root_folder : the expanded file name of the root folder of the application
|
17
|
+
# * deploy_words : an array of deploy words found in waw.deploy
|
18
|
+
# * config : Waw::Config instance, merged with configuration files in turn
|
19
|
+
# * logger : Logger instance
|
20
|
+
# * resources : ResourceCollection instance, filled with resource files
|
21
|
+
# * routing : name of the waw.routing file that has been loaded
|
22
|
+
# * app : Rack application loaded thanks to the routing file.
|
23
|
+
#
|
24
|
+
def autoload(file)
|
25
|
+
load_application(file)
|
26
|
+
rescue ConfigurationError, WawError => ex
|
27
|
+
raise ex
|
28
|
+
rescue Exception => ex
|
29
|
+
if logger
|
30
|
+
logger.fatal(ex.class.name.to_s + " : " + ex.message)
|
31
|
+
logger.fatal(ex.backtrace.join("\n"))
|
32
|
+
end
|
33
|
+
raise ex
|
34
|
+
end
|
35
|
+
|
36
|
+
#
|
37
|
+
# Loads the entire application from a given root folder, each
|
38
|
+
# load stage in turn:
|
39
|
+
#
|
40
|
+
# -1. find_web_root(from)
|
41
|
+
# 0. load_deploy
|
42
|
+
# 1. load_config
|
43
|
+
# 2. load_logger
|
44
|
+
# 3. load_resources
|
45
|
+
# 4. load_routing
|
46
|
+
# 5. load_hooks
|
47
|
+
#
|
48
|
+
# Returns self. Raises a ConfigurationError if something fails.
|
49
|
+
#
|
50
|
+
def load_application(from)
|
51
|
+
# 0) Load stage -1: finding web root
|
52
|
+
self.root_folder = find_web_root(from)
|
53
|
+
|
54
|
+
# 0) Load stage 0: waw.deploy
|
55
|
+
self.deploy_words = load_deploy(root_folder)
|
56
|
+
|
57
|
+
# 1) Load stage 1: config
|
58
|
+
self.config = load_config(root_folder, deploy_words)
|
59
|
+
|
60
|
+
# 2) Load stage 2: logger
|
61
|
+
self.logger = load_logger(root_folder, deploy_words, config)
|
62
|
+
logger.info("#{self.class.name}: load stage 1 sucessfull (#{deploy_words.join(', ')})")
|
63
|
+
logger.info("#{self.class.name}: load stage 2 sucessfull")
|
64
|
+
|
65
|
+
# 3) Load stage 3: resources
|
66
|
+
self.resources = load_resources(root_folder, deploy_words, config, logger)
|
67
|
+
logger.info("#{self.class.name}: load stage 3 sucessfull (resources)")
|
68
|
+
|
69
|
+
# 4) Load stage 4: routing
|
70
|
+
self.routing, self.app = load_routing(root_folder, deploy_words, config, logger, resources)
|
71
|
+
logger.info("#{self.class.name}: load stage 4 sucessfull (using #{routing})")
|
72
|
+
|
73
|
+
# 5) Load stage 5: load hooks
|
74
|
+
execute_hooks(:load)
|
75
|
+
execute_hooks(:start)
|
76
|
+
logger.info("#{self.class.name}: load stage 5 sucessfull (load hooks executed)")
|
77
|
+
|
78
|
+
# Hey hey, everything fine if we reach this!
|
79
|
+
logger.info("#{self.class.name}: application loaded successfully, enjoy!")
|
80
|
+
self
|
81
|
+
end
|
82
|
+
|
83
|
+
#
|
84
|
+
# Implements load stage #0: waw.deploy
|
85
|
+
#
|
86
|
+
# This method loads the waw.deploy file, decodes it and returns an array
|
87
|
+
# of deploy words.
|
88
|
+
#
|
89
|
+
# Raises a ::Waw::ConfigurationError if waw.deploy cannot be found or is
|
90
|
+
# corrupted.
|
91
|
+
#
|
92
|
+
def load_deploy(root_folder)
|
93
|
+
# Locates the waw.deploy file
|
94
|
+
deploy_file = File.join(root_folder, 'waw.deploy')
|
95
|
+
unless File.exists?(deploy_file)
|
96
|
+
puts "wawdeploy is deprecated, use waw.deploy instead!"
|
97
|
+
deploy_file = File.join(root_folder, 'wawdeploy')
|
98
|
+
end
|
99
|
+
raise ConfigurationError, "Missing waw.deploy file" unless File.exists?(deploy_file)
|
100
|
+
|
101
|
+
words = []
|
102
|
+
File.readlines(deploy_file).each_with_index do |line, i|
|
103
|
+
next if /^#/ =~ (line = line.strip)
|
104
|
+
next if line.empty?
|
105
|
+
raise ConfigurationError, "Waw deploy file corrupted on line #{i} (#{line})"\
|
106
|
+
unless /^[a-z_]+(\s+[a-z_]+)*$/ =~ line
|
107
|
+
words += line.split(/\s+/)
|
108
|
+
end
|
109
|
+
words
|
110
|
+
end
|
111
|
+
|
112
|
+
#
|
113
|
+
# Implements load stage #1: waw configuration
|
114
|
+
#
|
115
|
+
# This method merges all root_folder/config/xxx.cfg files (where xxx denotes
|
116
|
+
# a deploy word) inside the default waw configuration, which is then returned.
|
117
|
+
#
|
118
|
+
# Raises a ConfigurationError if a configuration file is missing or if something
|
119
|
+
# fails when loading a configuration file.
|
120
|
+
#
|
121
|
+
def load_config(root_folder, deploy_words)
|
122
|
+
# create a default configuration
|
123
|
+
config = Waw::Config.new(self, true)
|
124
|
+
config.install_configuration_property(:root_folder, root_folder)
|
125
|
+
|
126
|
+
# Read it and analyse merged configurations
|
127
|
+
conf_file = nil
|
128
|
+
deploy_words.each do |conf|
|
129
|
+
conf_file = File.join(root_folder, 'config', "#{conf}.cfg")
|
130
|
+
raise ConfigurationError, "Missing config file config/#{conf}.cfg" unless File.exists?(conf_file)
|
131
|
+
config.merge_file(conf_file)
|
132
|
+
end
|
133
|
+
|
134
|
+
config
|
135
|
+
rescue ConfigurationError => ex
|
136
|
+
raise ex
|
137
|
+
rescue Exception => ex
|
138
|
+
raise ConfigurationError, "Error occured when loading configuration #{File.basename(conf_file)}\n#{ex.message}", ex.backtrace
|
139
|
+
end
|
140
|
+
|
141
|
+
#
|
142
|
+
# Implements load stage #2: logger
|
143
|
+
#
|
144
|
+
# This method creates a logger instance with the config parameters
|
145
|
+
# and returns it.
|
146
|
+
#
|
147
|
+
# Raises a ConfigurationError if something fails.
|
148
|
+
#
|
149
|
+
def load_logger(root_folder, deploy_words, config)
|
150
|
+
# default parameters
|
151
|
+
appname = config.ensure(:application_name, 'webapp')
|
152
|
+
log_frequency = config.ensure(:log_frequency, 'weekly')
|
153
|
+
|
154
|
+
if config.knows?(:log_io)
|
155
|
+
# We use a given IO
|
156
|
+
logger = Logger.new(config.log_io, log_frequency)
|
157
|
+
else
|
158
|
+
# We go to a log file
|
159
|
+
log_dir = config.ensure(:log_dir, 'logs')
|
160
|
+
log_file = config.ensure(:log_file, "#{appname}.log")
|
161
|
+
|
162
|
+
# Check it now
|
163
|
+
FileUtils.mkdir_p(log_dir) unless File.exists?(log_dir)
|
164
|
+
raise ConfigurationError, "Unable to use #{log_dir} for logs, it's a file..." unless File.directory?(log_dir)
|
165
|
+
raise ConfigurationError, "Unable to use #{log_dir} for logs, not writable" unless File.writable?(log_dir)
|
166
|
+
|
167
|
+
# The log file now
|
168
|
+
log_file = File.join(config.log_dir, config.log_file)
|
169
|
+
logger = Logger.new(log_file, log_frequency)
|
170
|
+
end
|
171
|
+
logger.level = config.ensure(:log_level, Logger::DEBUG)
|
172
|
+
logger
|
173
|
+
end
|
174
|
+
|
175
|
+
#
|
176
|
+
# Implements load stage #3: resources
|
177
|
+
#
|
178
|
+
# This method creates an empty ResourceCollection and fill it with
|
179
|
+
# child collections, one for each resource files (.rs) found in
|
180
|
+
# root_folder/resources. Returns the parent collection.
|
181
|
+
#
|
182
|
+
# Riases a ConfigurationError if something fails.
|
183
|
+
#
|
184
|
+
def load_resources(root_folder, deploy_words, config, logger)
|
185
|
+
resources = ResourceCollection.new
|
186
|
+
resource_dir = File.join(root_folder, 'resources')
|
187
|
+
if File.directory?(resource_dir) and File.readable?(resource_dir)
|
188
|
+
Dir[File.join(resource_dir, '*.rs')].each do |file|
|
189
|
+
name = File.basename(file, '.rs')
|
190
|
+
resources.send(:add_resource, name, ResourceCollection.parse_resource_file(file))
|
191
|
+
logger.debug("Resources #{name} loaded successfully")
|
192
|
+
end
|
193
|
+
elsif not(File.readable?(resource_dir))
|
194
|
+
logger.warn("Ignoring the resources folder (not readable)... something will probably fail later!")
|
195
|
+
end
|
196
|
+
resources
|
197
|
+
end
|
198
|
+
|
199
|
+
#
|
200
|
+
# Implements load stage #4: routing
|
201
|
+
#
|
202
|
+
# This method locates the more specific waw.xxx.routing file, using deploy
|
203
|
+
# words in reverse order, and turning back to 'waw.routing' if no one can
|
204
|
+
# be found. The corresponding routing file is then decoded and the Rack
|
205
|
+
# application built that way.
|
206
|
+
#
|
207
|
+
# This method returns a pair [routing_file_name, rack_app].
|
208
|
+
#
|
209
|
+
# Raises a ConfigurationError if something fails (if the waw.routing file
|
210
|
+
# cannot be found, in particular).
|
211
|
+
#
|
212
|
+
def load_routing(root_folder, deploy_words, config, logger, resources)
|
213
|
+
deploy_words.reverse.each do |word|
|
214
|
+
file = File.join(root_folder, "waw.#{word}.routing")
|
215
|
+
return [File.basename(file), ::Kernel.eval(File.read(file))] if File.exists?(file)
|
216
|
+
end
|
217
|
+
file = File.join(root_folder, 'waw.routing')
|
218
|
+
return ['waw.routing', ::Kernel.eval(File.read(file))] if File.exists?(file)
|
219
|
+
raise ConfigurationError, "Unable to find waw.routing file in #{root_folder}"
|
220
|
+
end
|
221
|
+
|
222
|
+
################################################################# About unloading
|
223
|
+
|
224
|
+
# Unloads the entire application
|
225
|
+
def unload()
|
226
|
+
execute_hooks(:unload)
|
227
|
+
self.root_folder = nil
|
228
|
+
self.deploy_words = nil
|
229
|
+
self.config = nil
|
230
|
+
self.resources = nil
|
231
|
+
self.routing = nil
|
232
|
+
self.app = nil
|
233
|
+
logger.info("#{self.class.name}: application unloaded successfully, ciao!")
|
234
|
+
self.logger = nil
|
235
|
+
end
|
236
|
+
|
237
|
+
################################################################# About reloading
|
238
|
+
|
239
|
+
# Unloads and directly reloads the whole application
|
240
|
+
def reload
|
241
|
+
folder = self.root_folder
|
242
|
+
unload
|
243
|
+
autoload(folder)
|
244
|
+
end
|
245
|
+
|
246
|
+
end # module Loading
|
247
|
+
end # module Kern
|
248
|
+
end # module Waw
|
@@ -0,0 +1,87 @@
|
|
1
|
+
module Waw
|
2
|
+
module Kern
|
3
|
+
# Variables that are living during a web request.
|
4
|
+
module LivingState
|
5
|
+
|
6
|
+
# The living state object itself
|
7
|
+
class Saved
|
8
|
+
|
9
|
+
# Rack environment
|
10
|
+
attr_reader :rack_env
|
11
|
+
|
12
|
+
# Creates a saved instance
|
13
|
+
def initialize(rack_env)
|
14
|
+
@rack_env = rack_env
|
15
|
+
end
|
16
|
+
|
17
|
+
# Current request
|
18
|
+
def rack_request
|
19
|
+
@rack_request ||= Rack::Request.new(rack_env)
|
20
|
+
end
|
21
|
+
|
22
|
+
# Current response
|
23
|
+
def rack_response
|
24
|
+
@rack_response ||= Rack::Response.new(rack_env)
|
25
|
+
end
|
26
|
+
|
27
|
+
# Rack session object
|
28
|
+
def rack_session
|
29
|
+
@rack_session ||= (rack_env['rack.session'] ||= {})
|
30
|
+
end
|
31
|
+
|
32
|
+
# Waw session
|
33
|
+
def waw_session
|
34
|
+
@session ||= ::Waw::Session.new(rack_session)
|
35
|
+
end
|
36
|
+
|
37
|
+
end # class Saved
|
38
|
+
|
39
|
+
# Handler called to install everything required for the living
|
40
|
+
# state to work properly, based on a Rack env variable.
|
41
|
+
def install_living_state(env)
|
42
|
+
Thread.current[:waw_state] = Saved.new(env)
|
43
|
+
end
|
44
|
+
|
45
|
+
# Cleans the living state when a request is done.
|
46
|
+
def clean_living_state
|
47
|
+
Thread.current[:waw_state] = nil
|
48
|
+
end
|
49
|
+
|
50
|
+
# Returns the current waw_state object
|
51
|
+
def waw_state
|
52
|
+
Thread.current[:waw_state] ||= Saved.new({})
|
53
|
+
end
|
54
|
+
|
55
|
+
# Returns the current Rack env instance
|
56
|
+
def rack_env
|
57
|
+
waw_state.rack_env
|
58
|
+
end
|
59
|
+
|
60
|
+
# Returns the current Rack request instance
|
61
|
+
def request
|
62
|
+
waw_state.rack_request
|
63
|
+
end
|
64
|
+
|
65
|
+
# Returns the current Rack request instance
|
66
|
+
def response
|
67
|
+
waw_state.rack_response
|
68
|
+
end
|
69
|
+
|
70
|
+
# Request parameters
|
71
|
+
def params
|
72
|
+
request && request.params
|
73
|
+
end
|
74
|
+
|
75
|
+
# Returns the current Rack session
|
76
|
+
def real_session
|
77
|
+
waw_state.rack_session
|
78
|
+
end
|
79
|
+
|
80
|
+
# Returns the waw session decorator
|
81
|
+
def session
|
82
|
+
waw_state.waw_session
|
83
|
+
end
|
84
|
+
|
85
|
+
end # module LivingState
|
86
|
+
end # module Kern
|
87
|
+
end # module Waw
|