wee 0.1.0 → 0.3.1
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.
- data/INSTALL +7 -0
- data/README +268 -0
- data/Rakefile +26 -0
- data/TODO +116 -0
- data/benchmark/Centrino1300/result.2000.counter.action +45 -0
- data/benchmark/Centrino1300/result.2000.counter.render +43 -0
- data/benchmark/Centrino1300/result.2000.filehandler +43 -0
- data/benchmark/Centrino600/result.2000.counter.action +47 -0
- data/benchmark/Centrino600/result.2000.counter.render +45 -0
- data/benchmark/Centrino600/result.2000.filehandler +43 -0
- data/benchmark/Makefile +48 -0
- data/benchmark/bench.sh +24 -0
- data/benchmark/counter.rb +96 -0
- data/benchmark/filehandler.rb +6 -0
- data/doc/rdoc/classes/Array.html +172 -0
- data/doc/rdoc/classes/Cache.html +126 -0
- data/doc/rdoc/classes/Cache/StorageCache.html +320 -0
- data/doc/rdoc/classes/Cache/Strategy.html +128 -0
- data/doc/rdoc/classes/Cache/Strategy/CapacityBounded.html +269 -0
- data/doc/rdoc/classes/Cache/Strategy/LFU.html +238 -0
- data/doc/rdoc/classes/Cache/Strategy/LFU/Item.html +111 -0
- data/doc/rdoc/classes/Cache/Strategy/LRU.html +238 -0
- data/doc/rdoc/classes/Cache/Strategy/LRU/Item.html +111 -0
- data/doc/rdoc/classes/Cache/Strategy/Unbounded.html +225 -0
- data/doc/rdoc/classes/Cache/Strategy/Unbounded/Item.html +111 -0
- data/doc/rdoc/classes/Enumerable.html +146 -0
- data/doc/rdoc/classes/LiteralMethod.html +196 -0
- data/doc/rdoc/classes/Object.html +178 -0
- data/doc/rdoc/classes/String.html +172 -0
- data/doc/rdoc/classes/Struct.html +174 -0
- data/doc/rdoc/classes/Wee.html +160 -0
- data/doc/rdoc/classes/Wee/AnswerDecoration.html +182 -0
- data/doc/rdoc/classes/Wee/Application.html +337 -0
- data/doc/rdoc/classes/Wee/Brush.html +245 -0
- data/doc/rdoc/classes/Wee/Brush/ActionCallbackMixin.html +149 -0
- data/doc/rdoc/classes/Wee/Brush/ActionMixin.html +146 -0
- data/doc/rdoc/classes/Wee/Brush/ActionURLCallbackMixin.html +157 -0
- data/doc/rdoc/classes/Wee/Brush/AnchorTag.html +210 -0
- data/doc/rdoc/classes/Wee/Brush/AssignMixin.html +141 -0
- data/doc/rdoc/classes/Wee/Brush/CallbackMixin.html +141 -0
- data/doc/rdoc/classes/Wee/Brush/FormTag.html +225 -0
- data/doc/rdoc/classes/Wee/Brush/GenericEncodedTextBrush.html +176 -0
- data/doc/rdoc/classes/Wee/Brush/GenericTagBrush.html +283 -0
- data/doc/rdoc/classes/Wee/Brush/GenericTextBrush.html +176 -0
- data/doc/rdoc/classes/Wee/Brush/ImageButtonTag.html +195 -0
- data/doc/rdoc/classes/Wee/Brush/InputCallbackMixin.html +149 -0
- data/doc/rdoc/classes/Wee/Brush/InputTag.html +172 -0
- data/doc/rdoc/classes/Wee/Brush/Page.html +193 -0
- data/doc/rdoc/classes/Wee/Brush/SelectListTag.html +267 -0
- data/doc/rdoc/classes/Wee/Brush/SelectOptionTag.html +177 -0
- data/doc/rdoc/classes/Wee/Brush/SubmitButtonTag.html +154 -0
- data/doc/rdoc/classes/Wee/Brush/TableDataTag.html +173 -0
- data/doc/rdoc/classes/Wee/Brush/TableHeaderTag.html +146 -0
- data/doc/rdoc/classes/Wee/Brush/TableRowTag.html +277 -0
- data/doc/rdoc/classes/Wee/Brush/TableTag.html +146 -0
- data/doc/rdoc/classes/Wee/Brush/TextAreaTag.html +229 -0
- data/doc/rdoc/classes/Wee/Brush/TextInputTag.html +154 -0
- data/doc/rdoc/classes/Wee/Callback.html +231 -0
- data/doc/rdoc/classes/Wee/CallbackRegistry.html +308 -0
- data/doc/rdoc/classes/Wee/CallbackStream.html +227 -0
- data/doc/rdoc/classes/Wee/Canvas.html +235 -0
- data/doc/rdoc/classes/Wee/Component.html +933 -0
- data/doc/rdoc/classes/Wee/Context.html +111 -0
- data/doc/rdoc/classes/Wee/Decoration.html +338 -0
- data/doc/rdoc/classes/Wee/Delegate.html +247 -0
- data/doc/rdoc/classes/Wee/ErrorPage.html +175 -0
- data/doc/rdoc/classes/Wee/ErrorResponse.html +180 -0
- data/doc/rdoc/classes/Wee/GenericResponse.html +162 -0
- data/doc/rdoc/classes/Wee/HtmlCanvas.html +751 -0
- data/doc/rdoc/classes/Wee/HtmlWriter.html +351 -0
- data/doc/rdoc/classes/Wee/LiteralMethodCallback.html +180 -0
- data/doc/rdoc/classes/Wee/MethodCallback.html +193 -0
- data/doc/rdoc/classes/Wee/Page.html +111 -0
- data/doc/rdoc/classes/Wee/Presenter.html +521 -0
- data/doc/rdoc/classes/Wee/RedirectResponse.html +150 -0
- data/doc/rdoc/classes/Wee/RefreshResponse.html +157 -0
- data/doc/rdoc/classes/Wee/RenderingContext.html +111 -0
- data/doc/rdoc/classes/Wee/Request.html +268 -0
- data/doc/rdoc/classes/Wee/RequestHandler.html +336 -0
- data/doc/rdoc/classes/Wee/Response.html +260 -0
- data/doc/rdoc/classes/Wee/Session.html +469 -0
- data/doc/rdoc/classes/Wee/SimpleIdGenerator.html +198 -0
- data/doc/rdoc/classes/Wee/Snapshot.html +211 -0
- data/doc/rdoc/classes/Wee/StateHolder.html +149 -0
- data/doc/rdoc/classes/Wee/StateRegistry.html +434 -0
- data/doc/rdoc/classes/Wee/StateRegistry/Snapshot.html +320 -0
- data/doc/rdoc/classes/Wee/StateRegistry/WithObject.html +153 -0
- data/doc/rdoc/classes/Wee/Utils.html +111 -0
- data/doc/rdoc/classes/Wee/Utils/LRUCache.html +148 -0
- data/doc/rdoc/classes/Wee/ValueHolder.html +220 -0
- data/doc/rdoc/classes/Wee/WEBrickAdaptor.html +330 -0
- data/doc/rdoc/created.rid +1 -0
- data/doc/rdoc/files/INSTALL.html +118 -0
- data/doc/rdoc/files/README.html +466 -0
- data/doc/rdoc/files/lib/cache/cache_rb.html +101 -0
- data/doc/rdoc/files/lib/wee/adaptors/webrick_rb.html +108 -0
- data/doc/rdoc/files/lib/wee/application_rb.html +112 -0
- data/doc/rdoc/files/lib/wee/callback_rb.html +107 -0
- data/doc/rdoc/files/lib/wee/component_ext_rb.html +101 -0
- data/doc/rdoc/files/lib/wee/component_rb.html +109 -0
- data/doc/rdoc/files/lib/wee/context_rb.html +101 -0
- data/doc/rdoc/files/lib/wee/core/callback_rb.html +115 -0
- data/doc/rdoc/files/lib/wee/core/component_rb.html +108 -0
- data/doc/rdoc/files/lib/wee/core/decoration_rb.html +133 -0
- data/doc/rdoc/files/lib/wee/core/presenter_rb.html +112 -0
- data/doc/rdoc/files/lib/wee/core/snapshot_rb.html +113 -0
- data/doc/rdoc/files/lib/wee/core/valueholder_rb.html +110 -0
- data/doc/rdoc/files/lib/wee/core_rb.html +131 -0
- data/doc/rdoc/files/lib/wee/decoration_rb.html +101 -0
- data/doc/rdoc/files/lib/wee/holder_rb.html +101 -0
- data/doc/rdoc/files/lib/wee/html_canvas_rb.html +108 -0
- data/doc/rdoc/files/lib/wee/html_writer_rb.html +108 -0
- data/doc/rdoc/files/lib/wee/idgen_rb.html +101 -0
- data/doc/rdoc/files/lib/wee/page_rb.html +101 -0
- data/doc/rdoc/files/lib/wee/presenter_rb.html +112 -0
- data/doc/rdoc/files/lib/wee/renderer/html/brushes_rb.html +101 -0
- data/doc/rdoc/files/lib/wee/renderer/html/canvas_rb.html +101 -0
- data/doc/rdoc/files/lib/wee/renderer/html/writer_rb.html +108 -0
- data/doc/rdoc/files/lib/wee/rendering/html/brushes_rb.html +101 -0
- data/doc/rdoc/files/lib/wee/rendering/html/canvas_rb.html +101 -0
- data/doc/rdoc/files/lib/wee/rendering/html/writer_rb.html +108 -0
- data/doc/rdoc/files/lib/wee/request_rb.html +113 -0
- data/doc/rdoc/files/lib/wee/requesthandler_rb.html +101 -0
- data/doc/rdoc/files/lib/wee/response_rb.html +108 -0
- data/doc/rdoc/files/lib/wee/session_rb.html +109 -0
- data/doc/rdoc/files/lib/wee/snapshot_ext_rb.html +101 -0
- data/doc/rdoc/files/lib/wee/snapshot_rb.html +107 -0
- data/doc/rdoc/files/lib/wee/state_registry_rb.html +110 -0
- data/doc/rdoc/files/lib/wee/stuff_rb.html +144 -0
- data/doc/rdoc/files/lib/wee/utils/cache_rb.html +108 -0
- data/doc/rdoc/files/lib/wee/webrick_rb.html +108 -0
- data/doc/rdoc/files/lib/wee_rb.html +132 -0
- data/doc/rdoc/fr_class_index.html +93 -0
- data/doc/rdoc/fr_file_index.html +51 -0
- data/doc/rdoc/fr_method_index.html +242 -0
- data/doc/rdoc/index.html +24 -0
- data/doc/rdoc/rdoc-style.css +208 -0
- data/examples/ObjectSpaceBrowser.rb +199 -0
- data/examples/calendar.rb +366 -0
- data/examples/cc.rb +94 -0
- data/examples/draw.rb +91 -0
- data/examples/example.rb +223 -0
- data/examples/test.rb +66 -0
- data/examples/window.rb +53 -0
- data/lib/cache/cache.rb +9 -0
- data/lib/wee.rb +18 -8
- data/lib/wee/adaptors/webrick.rb +73 -0
- data/lib/wee/application.rb +69 -71
- data/lib/wee/context.rb +2 -12
- data/lib/wee/core.rb +15 -0
- data/lib/wee/core/callback.rb +108 -0
- data/lib/wee/core/component.rb +314 -0
- data/lib/wee/core/decoration.rb +129 -0
- data/lib/wee/core/presenter.rb +132 -0
- data/lib/wee/core/snapshot.rb +21 -0
- data/lib/wee/core/valueholder.rb +19 -0
- data/lib/wee/idgen.rb +13 -0
- data/lib/wee/page.rb +1 -1
- data/lib/wee/renderer/html/brushes.rb +435 -0
- data/lib/wee/renderer/html/canvas.rb +148 -0
- data/lib/wee/{html_writer.rb → renderer/html/writer.rb} +31 -16
- data/lib/wee/request.rb +57 -0
- data/lib/wee/requesthandler.rb +77 -0
- data/lib/wee/response.rb +77 -0
- data/lib/wee/session.rb +70 -64
- data/lib/wee/{snapshot.rb → snapshot_ext.rb} +4 -4
- data/test/components/calltest.rb +16 -0
- data/test/components/counter.rb +17 -0
- data/test/components/messagebox.rb +15 -0
- data/test/components/page.rb +14 -0
- data/test/components/page_decoration.rb +7 -0
- data/test/stress.rb +64 -0
- data/test/test_component.rb +106 -0
- data/test/test_html_canvas.rb +25 -0
- data/test/test_html_writer.rb +27 -0
- data/test/test_request.rb +13 -0
- data/test/utils/cross.rb +65 -0
- data/test/utils/generic_plotter.rb +28 -0
- data/test/utils/gnuplot.rb +31 -0
- data/test/utils/measure_memory.rb +9 -0
- data/test/utils/memory_plotter.rb +10 -0
- data/test/utils/object_plotter.rb +10 -0
- data/test/utils/webrick_background.rb +31 -0
- data/wee.gemspec +22 -0
- metadata +222 -18
- data/lib/wee/component.rb +0 -126
- data/lib/wee/delegate_decoration.rb +0 -22
- data/lib/wee/handler_registry.rb +0 -89
- data/lib/wee/holder.rb +0 -14
- data/lib/wee/html_canvas.rb +0 -379
- data/lib/wee/state_registry.rb +0 -173
- data/lib/wee/stuff.rb +0 -29
- data/lib/wee/webrick.rb +0 -15
data/examples/window.rb
ADDED
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
class Wee::Window < Wee::Component
|
|
2
|
+
|
|
3
|
+
def initialize(title, pos, child)
|
|
4
|
+
super()
|
|
5
|
+
@title = title
|
|
6
|
+
@child = child
|
|
7
|
+
@status = :normal
|
|
8
|
+
self.children << @child
|
|
9
|
+
@pos = pos
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
def process_callbacks(callback_stream)
|
|
13
|
+
return if @status == :closed
|
|
14
|
+
super
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
def minimize
|
|
18
|
+
@status = :minimized
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
def maximize
|
|
22
|
+
@status = :normal
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
def close
|
|
26
|
+
@status = :closed
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
def render
|
|
30
|
+
return if @status == :closed
|
|
31
|
+
|
|
32
|
+
r.table.cellspacing(0).style("border:solid 1px grey; position: relative; top: #{@pos}; left: #{200+@pos.to_i}").with do
|
|
33
|
+
r.table_row.style("background-color: lightblue; width: 100%").with do
|
|
34
|
+
r.table_data.style("text-align: left; width: 66%").with(@title)
|
|
35
|
+
r.table_data.style("text-align: right").with do
|
|
36
|
+
if @status == :minimized
|
|
37
|
+
r.anchor.callback{maximize}.with("#")
|
|
38
|
+
else
|
|
39
|
+
r.anchor.callback{minimize}.with("_")
|
|
40
|
+
end
|
|
41
|
+
r.space
|
|
42
|
+
r.anchor.callback{close}.with("X")
|
|
43
|
+
end
|
|
44
|
+
end
|
|
45
|
+
r.table_row do
|
|
46
|
+
r.table_data.colspan(2).with do
|
|
47
|
+
r.render(@child) if @status == :normal
|
|
48
|
+
end
|
|
49
|
+
end
|
|
50
|
+
end
|
|
51
|
+
end
|
|
52
|
+
|
|
53
|
+
end
|
data/lib/cache/cache.rb
CHANGED
|
@@ -1,3 +1,12 @@
|
|
|
1
|
+
unless Enumerable.instance_methods.include?("min_by")
|
|
2
|
+
# for Ruby 1.8
|
|
3
|
+
module Enumerable
|
|
4
|
+
def min_by(&block)
|
|
5
|
+
min {|i,j| block.call(i) <=> block.call(j) }
|
|
6
|
+
end
|
|
7
|
+
end
|
|
8
|
+
end
|
|
9
|
+
|
|
1
10
|
# Abstract super class of all cache implementations.
|
|
2
11
|
class Cache; end
|
|
3
12
|
|
data/lib/wee.rb
CHANGED
|
@@ -1,11 +1,21 @@
|
|
|
1
|
-
module Wee
|
|
1
|
+
module Wee
|
|
2
|
+
Version = "0.3.1"
|
|
3
|
+
end
|
|
4
|
+
|
|
5
|
+
require 'wee/core'
|
|
2
6
|
|
|
3
|
-
require 'wee/application'
|
|
4
|
-
require 'wee/component'
|
|
5
|
-
require 'wee/delegate_decoration'
|
|
6
7
|
require 'wee/context'
|
|
8
|
+
require 'wee/application'
|
|
9
|
+
require 'wee/requesthandler'
|
|
10
|
+
require 'wee/request'
|
|
11
|
+
require 'wee/response'
|
|
7
12
|
require 'wee/session'
|
|
8
|
-
|
|
9
|
-
require 'wee/
|
|
10
|
-
|
|
11
|
-
require 'wee/
|
|
13
|
+
|
|
14
|
+
require 'wee/snapshot_ext'
|
|
15
|
+
|
|
16
|
+
require 'wee/renderer/html/writer'
|
|
17
|
+
require 'wee/renderer/html/brushes'
|
|
18
|
+
require 'wee/renderer/html/canvas'
|
|
19
|
+
Wee::DefaultRenderer = Wee::HtmlCanvas
|
|
20
|
+
|
|
21
|
+
require 'wee/idgen'
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
require 'webrick'
|
|
2
|
+
|
|
3
|
+
# Example of usage:
|
|
4
|
+
#
|
|
5
|
+
# require 'wee/adaptors/webrick'
|
|
6
|
+
# s = WEBrick::HTTPServer.new(:Port => 2000)
|
|
7
|
+
# s.mount '/app', Wee::WEBrickAdaptor, application
|
|
8
|
+
#
|
|
9
|
+
# trap("INT") { s.shutdown; exit }
|
|
10
|
+
# s.start
|
|
11
|
+
#
|
|
12
|
+
# Or when using the convenience methods:
|
|
13
|
+
#
|
|
14
|
+
# require 'wee/adaptors/webrick'
|
|
15
|
+
# Wee::WEBrickAdaptor.
|
|
16
|
+
# register('/app' => application).
|
|
17
|
+
# register('/cnt' => application2).
|
|
18
|
+
# start(:Port => 2000)
|
|
19
|
+
#
|
|
20
|
+
|
|
21
|
+
class Wee::WEBrickAdaptor < WEBrick::HTTPServlet::AbstractServlet
|
|
22
|
+
|
|
23
|
+
# Convenience method
|
|
24
|
+
def self.start(options={})
|
|
25
|
+
server = WEBrick::HTTPServer.new({:Port => 2000}.update(options))
|
|
26
|
+
trap("INT") { server.shutdown }
|
|
27
|
+
|
|
28
|
+
(@apps||[]).each do |path, app|
|
|
29
|
+
server.mount(path, self, path, app)
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
(@mounts||[]).each do |args, block|
|
|
33
|
+
server.mount(*args, &block)
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
yield server if block_given?
|
|
37
|
+
|
|
38
|
+
server.start
|
|
39
|
+
server
|
|
40
|
+
end
|
|
41
|
+
|
|
42
|
+
# Convenience method
|
|
43
|
+
def self.register(hash)
|
|
44
|
+
@apps ||= []
|
|
45
|
+
hash.each do |path, application|
|
|
46
|
+
@apps << [path, application]
|
|
47
|
+
end
|
|
48
|
+
self
|
|
49
|
+
end
|
|
50
|
+
|
|
51
|
+
def mount(*args, &block)
|
|
52
|
+
@mounts ||= []
|
|
53
|
+
@mounts << [args, block]
|
|
54
|
+
self
|
|
55
|
+
end
|
|
56
|
+
|
|
57
|
+
def initialize(server, mount_path, application)
|
|
58
|
+
super(server)
|
|
59
|
+
@mount_path = mount_path
|
|
60
|
+
@application = application
|
|
61
|
+
end
|
|
62
|
+
|
|
63
|
+
def handle_request(req, res)
|
|
64
|
+
context = Wee::Context.new(Wee::Request.new(@mount_path, req.path, req.header, req.query))
|
|
65
|
+
@application.handle_request(context)
|
|
66
|
+
res.status = context.response.status
|
|
67
|
+
res.body = context.response.content
|
|
68
|
+
context.response.header.each { |k,v| res.header[k] = v }
|
|
69
|
+
end
|
|
70
|
+
|
|
71
|
+
alias do_GET handle_request
|
|
72
|
+
alias do_POST handle_request
|
|
73
|
+
end
|
data/lib/wee/application.rb
CHANGED
|
@@ -1,91 +1,89 @@
|
|
|
1
|
+
# A Wee::Application manages all Wee::RequestHandler's of a single application,
|
|
2
|
+
# where most of the time the request handlers are Wee::Session objects. It
|
|
3
|
+
# dispatches the request to the correct handler by examining the request.
|
|
4
|
+
|
|
1
5
|
class Wee::Application
|
|
2
|
-
attr_accessor :name, :path
|
|
3
|
-
attr_accessor :session_store, :session_class
|
|
4
|
-
attr_accessor :dumpfile
|
|
5
6
|
|
|
6
|
-
|
|
7
|
-
setup_session_id_generator
|
|
7
|
+
# The generator used for creating unique request handler id's.
|
|
8
8
|
|
|
9
|
-
|
|
9
|
+
attr_accessor :id_generator
|
|
10
10
|
|
|
11
|
-
|
|
12
|
-
raise ArgumentError, "missing name, path, session_class, session_store or dumpfile"
|
|
13
|
-
end
|
|
14
|
-
end
|
|
11
|
+
# The maximum number of request handlers
|
|
15
12
|
|
|
16
|
-
|
|
17
|
-
@session_cnt = rand(1000_000)
|
|
18
|
-
end
|
|
13
|
+
attr_accessor :max_request_handlers
|
|
19
14
|
|
|
20
|
-
|
|
21
|
-
|
|
15
|
+
# Get or set the default request handler. The default request handler is used
|
|
16
|
+
# if no request handler id is given in a request.
|
|
22
17
|
|
|
23
|
-
|
|
24
|
-
if
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
session = @session_class.new
|
|
30
|
-
session_id = gen_unique_session_id
|
|
31
|
-
@session_store[session_id] = session
|
|
32
|
-
end
|
|
33
|
-
|
|
34
|
-
session = @session_store[session_id]
|
|
35
|
-
if session.nil?
|
|
36
|
-
# TODO: redirect to session-less page, or do whatever
|
|
37
|
-
error_invalid_session(req, res); return
|
|
18
|
+
def default_request_handler(&block)
|
|
19
|
+
if block.nil?
|
|
20
|
+
@default_request_handler
|
|
21
|
+
else
|
|
22
|
+
@default_request_handler = block
|
|
38
23
|
end
|
|
39
|
-
|
|
40
|
-
context = Wee::Context.new(req, res, session, session_id)
|
|
41
|
-
context.application = self
|
|
42
|
-
context.session = session
|
|
43
|
-
context.page_id = hash['p']
|
|
44
|
-
context.handler_id = hash['h']
|
|
45
|
-
context.resource_id = hash['r']
|
|
46
|
-
session.handle_request(context)
|
|
47
|
-
end
|
|
48
|
-
|
|
49
|
-
# TODO: UrlModel, which knows how to create and parse URLs
|
|
50
|
-
def gen_handler_url(session_id, page_id, handler_id)
|
|
51
|
-
[
|
|
52
|
-
self.path,
|
|
53
|
-
['s', session_id].join(':'),
|
|
54
|
-
['p', page_id].join(':'),
|
|
55
|
-
['h', handler_id].join(':')
|
|
56
|
-
].join('/')
|
|
57
24
|
end
|
|
58
25
|
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
end
|
|
26
|
+
# Creates a new application. The block is used to initialize the attributes:
|
|
27
|
+
#
|
|
28
|
+
# Wee::Application.new {|app|
|
|
29
|
+
# app.default_request_handler { MySession.new }
|
|
30
|
+
# app.id_generator = Wee::SimpleIdGenerator.new
|
|
31
|
+
# app.max_request_handlers = 1000
|
|
32
|
+
# }
|
|
67
33
|
|
|
68
|
-
def
|
|
69
|
-
|
|
34
|
+
def initialize(&block)
|
|
35
|
+
@request_handlers = Hash.new
|
|
36
|
+
block.call(self)
|
|
37
|
+
@id_generator ||= Wee::SimpleIdGenerator.new(rand(1_000_000))
|
|
38
|
+
if @default_request_handler.nil?
|
|
39
|
+
raise ArgumentError, "No default request handler specified"
|
|
40
|
+
end
|
|
41
|
+
@mutex = Mutex.new
|
|
70
42
|
end
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
43
|
+
|
|
44
|
+
# TODO: we have to use mutexes here
|
|
45
|
+
# NOTE that id_generator must be thread-safe!
|
|
46
|
+
# TODO: test for max_request_handlers
|
|
47
|
+
|
|
48
|
+
def handle_request(context)
|
|
49
|
+
@mutex.synchronize do
|
|
50
|
+
request_handler_id = context.request.request_handler_id
|
|
51
|
+
request_handler = @request_handlers[request_handler_id]
|
|
52
|
+
|
|
53
|
+
if request_handler_id.nil?
|
|
54
|
+
# No id was given -> create new id and handler
|
|
55
|
+
request_handler_id = unique_request_handler_id()
|
|
56
|
+
request_handler = @default_request_handler.call
|
|
57
|
+
request_handler.id = request_handler_id
|
|
58
|
+
request_handler.application = self
|
|
59
|
+
@request_handlers[request_handler_id] = request_handler
|
|
60
|
+
|
|
61
|
+
context.response = Wee::RedirectResponse.new(context.request.build_url(request_handler_id))
|
|
62
|
+
return
|
|
63
|
+
|
|
64
|
+
elsif request_handler.nil?
|
|
65
|
+
# A false request handler id was given. This might indicate that a
|
|
66
|
+
# request handler has expired.
|
|
67
|
+
request_handler_expired(context)
|
|
68
|
+
return
|
|
69
|
+
end
|
|
70
|
+
|
|
71
|
+
request_handler.handle_request(context)
|
|
72
|
+
end
|
|
73
|
+
rescue => exn
|
|
74
|
+
context.response = Wee::ErrorResponse.new(exn)
|
|
74
75
|
end
|
|
75
76
|
|
|
76
|
-
|
|
77
|
-
Marshal.load(File.read(filename))
|
|
78
|
-
end
|
|
77
|
+
private
|
|
79
78
|
|
|
80
|
-
def
|
|
81
|
-
|
|
79
|
+
def unique_request_handler_id
|
|
80
|
+
id = @id_generator.next.to_s
|
|
81
|
+
raise "failed to create unique request handler id" if @request_handlers.include?(id)
|
|
82
|
+
return id
|
|
82
83
|
end
|
|
83
84
|
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
# TODO: that's insecure. it's just for development!
|
|
87
|
-
def gen_unique_session_id
|
|
88
|
-
(@session_cnt += 1).to_s
|
|
85
|
+
def request_handler_expired(context)
|
|
86
|
+
context.response = Wee::RefreshResponse.new("Invalid or expired request handler!", context.request.application_path)
|
|
89
87
|
end
|
|
90
88
|
|
|
91
89
|
end
|
data/lib/wee/context.rb
CHANGED
|
@@ -1,12 +1,2 @@
|
|
|
1
|
-
class Wee::Context
|
|
2
|
-
|
|
3
|
-
attr_accessor :request, :response, :session, :session_id
|
|
4
|
-
attr_accessor :page_id, :handler_id, :resource_id
|
|
5
|
-
attr_accessor :handler_registry
|
|
6
|
-
|
|
7
|
-
def initialize(request, response, session, session_id)
|
|
8
|
-
@request, @response, @session, @session_id, @root = request, response, session, session_id
|
|
9
|
-
end
|
|
10
|
-
end
|
|
11
|
-
|
|
12
|
-
class Wee::RenderingContext < Struct.new(:context, :document); end
|
|
1
|
+
class Wee::Context < Struct.new(:request, :response); end
|
|
2
|
+
class Wee::RenderingContext < Struct.new(:request, :response, :callbacks, :document); end
|
data/lib/wee/core.rb
ADDED
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
# The only dependencies of the core classes are:
|
|
2
|
+
#
|
|
3
|
+
# * Wee::Session.current in class Wee::Presenter#session
|
|
4
|
+
# * Wee::DefaultRenderer in Wee::Presenter#renderer_class
|
|
5
|
+
#
|
|
6
|
+
|
|
7
|
+
# independent files
|
|
8
|
+
require 'wee/core/valueholder'
|
|
9
|
+
require 'wee/core/snapshot'
|
|
10
|
+
require 'wee/core/callback'
|
|
11
|
+
|
|
12
|
+
# dependent files
|
|
13
|
+
require 'wee/core/presenter'
|
|
14
|
+
require 'wee/core/decoration'
|
|
15
|
+
require 'wee/core/component'
|
|
@@ -0,0 +1,108 @@
|
|
|
1
|
+
# The callback registry is the central datastructure where all components of a
|
|
2
|
+
# session register their callbacks.
|
|
3
|
+
#
|
|
4
|
+
# The format of the internal datastructure is:
|
|
5
|
+
#
|
|
6
|
+
# @callbacks[type][callback_id] => callback
|
|
7
|
+
# @obj_to_id_map[type][object] => [id*]
|
|
8
|
+
|
|
9
|
+
class Wee::CallbackRegistry
|
|
10
|
+
|
|
11
|
+
def initialize(id_generator)
|
|
12
|
+
@idgen = id_generator
|
|
13
|
+
@callbacks = Hash.new
|
|
14
|
+
@obj_to_id_map = Hash.new
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
# Register +callback+ for +object+ under +type+ and return a unique callback id.
|
|
18
|
+
|
|
19
|
+
def register_for(object, type=nil, &callback)
|
|
20
|
+
c = (@callbacks[type] ||= Hash.new)
|
|
21
|
+
o = (@obj_to_id_map[type] ||= Hash.new)
|
|
22
|
+
cid = @idgen.next.to_s
|
|
23
|
+
raise "duplicate callback id" if c.has_key?(cid)
|
|
24
|
+
c[cid] = callback
|
|
25
|
+
(o[object] ||= []) << cid
|
|
26
|
+
return cid
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
|
30
|
+
# :section: Friend methods for Wee::CallbackStream
|
|
31
|
+
# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
|
32
|
+
|
|
33
|
+
def get_ids_for(object, type=nil)
|
|
34
|
+
if o = @obj_to_id_map[type]
|
|
35
|
+
o[object] || []
|
|
36
|
+
else
|
|
37
|
+
[]
|
|
38
|
+
end
|
|
39
|
+
end
|
|
40
|
+
|
|
41
|
+
def get_callback_for(id, type=nil)
|
|
42
|
+
if c = @callbacks[type]
|
|
43
|
+
c[id]
|
|
44
|
+
else
|
|
45
|
+
raise
|
|
46
|
+
end
|
|
47
|
+
end
|
|
48
|
+
|
|
49
|
+
def all_of_type(type=nil)
|
|
50
|
+
if c = @callbacks[type]
|
|
51
|
+
c
|
|
52
|
+
else
|
|
53
|
+
raise
|
|
54
|
+
end
|
|
55
|
+
end
|
|
56
|
+
|
|
57
|
+
end
|
|
58
|
+
|
|
59
|
+
|
|
60
|
+
# The intersection of registered callbacks and those that occured.
|
|
61
|
+
|
|
62
|
+
class Wee::CallbackStream
|
|
63
|
+
|
|
64
|
+
#
|
|
65
|
+
# [<tt>callbacks</tt>]
|
|
66
|
+
# A Wee::CallbackRegistry
|
|
67
|
+
#
|
|
68
|
+
# [<tt>ids_and_values</tt>]
|
|
69
|
+
# A hash that contains all callback ids together with their values that
|
|
70
|
+
# occurend in a request, e.g. { id => value }.
|
|
71
|
+
|
|
72
|
+
def initialize(callbacks, ids_and_values)
|
|
73
|
+
@callbacks = callbacks
|
|
74
|
+
@ids_and_values = ids_and_values
|
|
75
|
+
@ids = @ids_and_values.keys
|
|
76
|
+
end
|
|
77
|
+
|
|
78
|
+
def with_callbacks_for(object, type)
|
|
79
|
+
matching_ids = @callbacks.get_ids_for(object, type) & @ids
|
|
80
|
+
matching_ids.each do |id|
|
|
81
|
+
yield @callbacks.get_callback_for(id, type), @ids_and_values[id]
|
|
82
|
+
end
|
|
83
|
+
@ids -= matching_ids
|
|
84
|
+
end
|
|
85
|
+
|
|
86
|
+
# Returns a [callback, value] array of all callbacks of +type+ for which an
|
|
87
|
+
# id was given.
|
|
88
|
+
|
|
89
|
+
def all_of_type(type)
|
|
90
|
+
a = []
|
|
91
|
+
@callbacks.all_of_type(type).each {|id, callback|
|
|
92
|
+
a << [callback, @ids_and_values[id]] if @ids_and_values.include?(id)
|
|
93
|
+
}
|
|
94
|
+
return a
|
|
95
|
+
end
|
|
96
|
+
|
|
97
|
+
end
|
|
98
|
+
|
|
99
|
+
# A serializable callback.
|
|
100
|
+
class Wee::LiteralMethodCallback
|
|
101
|
+
def initialize(obj, method_id=:call)
|
|
102
|
+
@obj, @method_id = obj, method_id
|
|
103
|
+
end
|
|
104
|
+
|
|
105
|
+
def call(*args)
|
|
106
|
+
@obj.send(@method_id, *args)
|
|
107
|
+
end
|
|
108
|
+
end
|