rsence-pre 2.1.0.1.pre
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/.yardopts +10 -0
- data/INSTALL.rdoc +330 -0
- data/LICENSE.txt +622 -0
- data/README.rdoc +98 -0
- data/VERSION +1 -0
- data/bin/rsence +25 -0
- data/bin/rsence-pre +25 -0
- data/conf/default_conf.yaml +346 -0
- data/conf/default_strings.yaml +76 -0
- data/conf/rsence_command_strings.yaml +444 -0
- data/docs/ExampleGuiPlugin.rdoc +193 -0
- data/docs/JavascriptBundles.rdoc +0 -0
- data/docs/PluginBundleInfo.rdoc +173 -0
- data/docs/PluginBundles.rdoc +96 -0
- data/docs/Values.rdoc +163 -0
- data/js/comm/autosync/autosync.js +17 -0
- data/js/comm/autosync/js.inc +0 -0
- data/js/comm/comm.js +203 -0
- data/js/comm/js.inc +0 -0
- data/js/comm/jsloader/js.inc +0 -0
- data/js/comm/jsloader/jsloader.js +112 -0
- data/js/comm/queue/js.inc +0 -0
- data/js/comm/queue/queue.js +184 -0
- data/js/comm/session/js.inc +0 -0
- data/js/comm/session/session.js +52 -0
- data/js/comm/sessionwatcher/js.inc +0 -0
- data/js/comm/sessionwatcher/sessionwatcher.js +44 -0
- data/js/comm/transporter/js.inc +0 -0
- data/js/comm/transporter/transporter.js +261 -0
- data/js/comm/urlresponder/js.inc +0 -0
- data/js/comm/urlresponder/urlresponder.js +149 -0
- data/js/comm/values/js.inc +0 -0
- data/js/comm/values/values.js +433 -0
- data/js/controls/button/button.js +72 -0
- data/js/controls/button/js.inc +0 -0
- data/js/controls/button/themes/bright/button.css +89 -0
- data/js/controls/button/themes/bright/button.html +7 -0
- data/js/controls/button/themes/bright/button_parts1-ie6.gif +0 -0
- data/js/controls/button/themes/bright/button_parts1.png +0 -0
- data/js/controls/button/themes/default/button.css +89 -0
- data/js/controls/button/themes/default/button.html +7 -0
- data/js/controls/button/themes/default/button_parts1-ie6.gif +0 -0
- data/js/controls/button/themes/default/button_parts1.png +0 -0
- data/js/controls/checkbox/checkbox.js +49 -0
- data/js/controls/checkbox/js.inc +0 -0
- data/js/controls/checkbox/themes/default/checkbox.css +69 -0
- data/js/controls/checkbox/themes/default/checkbox.html +5 -0
- data/js/controls/checkbox/themes/default/checkbox_parts1-ie6.gif +0 -0
- data/js/controls/checkbox/themes/default/checkbox_parts1.png +0 -0
- data/js/controls/dialogs/alert_sheet/alert_sheet.js +63 -0
- data/js/controls/dialogs/alert_sheet/js.inc +0 -0
- data/js/controls/dialogs/confirm_sheet/confirm_sheet.js +37 -0
- data/js/controls/dialogs/confirm_sheet/js.inc +0 -0
- data/js/controls/dialogs/sheet/js.inc +0 -0
- data/js/controls/dialogs/sheet/sheet.js +84 -0
- data/js/controls/dialogs/sheet/themes/default/sheet.css +64 -0
- data/js/controls/dialogs/sheet/themes/default/sheet.html +14 -0
- data/js/controls/dialogs/sheet/themes/default/sheet_bg-ie6.gif +0 -0
- data/js/controls/dialogs/sheet/themes/default/sheet_bg.png +0 -0
- data/js/controls/dialogs/sheet/themes/default/sheet_dim-ie6.gif +0 -0
- data/js/controls/dialogs/sheet/themes/default/sheet_dim.png +0 -0
- data/js/controls/dialogs/sheet/themes/default/sheet_parts1-ie6.gif +0 -0
- data/js/controls/dialogs/sheet/themes/default/sheet_parts1.png +0 -0
- data/js/controls/dialogs/sheet/themes/default/sheet_parts2-ie6.gif +0 -0
- data/js/controls/dialogs/sheet/themes/default/sheet_parts2.png +0 -0
- data/js/controls/dialogs/sheet/themes/default/sheet_warning-ie6.gif +0 -0
- data/js/controls/dialogs/sheet/themes/default/sheet_warning.png +0 -0
- data/js/controls/imageview/imageview.js +109 -0
- data/js/controls/imageview/js.inc +0 -0
- data/js/controls/imageview/themes/default/blank.gif +0 -0
- data/js/controls/passwordcontrol/js.inc +0 -0
- data/js/controls/passwordcontrol/passwordcontrol.js +23 -0
- data/js/controls/passwordcontrol/themes/default/passwordcontrol.css +0 -0
- data/js/controls/passwordcontrol/themes/default/passwordcontrol.html +18 -0
- data/js/controls/progress/progressbar/js.inc +0 -0
- data/js/controls/progress/progressbar/progressbar.js +40 -0
- data/js/controls/progress/progressbar/themes/default/progressbar.css +16 -0
- data/js/controls/progress/progressbar/themes/default/progressbar.html +2 -0
- data/js/controls/progress/progressindicator/js.inc +0 -0
- data/js/controls/progress/progressindicator/progressindicator.js +44 -0
- data/js/controls/radiobutton/js.inc +0 -0
- data/js/controls/radiobutton/radiobutton.js +43 -0
- data/js/controls/radiobutton/themes/default/radiobutton.css +69 -0
- data/js/controls/radiobutton/themes/default/radiobutton.html +5 -0
- data/js/controls/radiobutton/themes/default/radiobutton_parts1-ie6.gif +0 -0
- data/js/controls/radiobutton/themes/default/radiobutton_parts1.png +0 -0
- data/js/controls/sliders/slider/js.inc +0 -0
- data/js/controls/sliders/slider/slider.js +357 -0
- data/js/controls/sliders/slider/themes/default/hslider_tracks-ie6.gif +0 -0
- data/js/controls/sliders/slider/themes/default/hslider_tracks.png +0 -0
- data/js/controls/sliders/slider/themes/default/slider.css +108 -0
- data/js/controls/sliders/slider/themes/default/slider.html +5 -0
- data/js/controls/sliders/slider/themes/default/slider_thumbs-ie6.gif +0 -0
- data/js/controls/sliders/slider/themes/default/slider_thumbs.png +0 -0
- data/js/controls/sliders/vslider/js.inc +0 -0
- data/js/controls/sliders/vslider/themes/default/vslider.css +52 -0
- data/js/controls/sliders/vslider/themes/default/vslider.html +5 -0
- data/js/controls/sliders/vslider/themes/default/vslider_tracks-ie6.gif +0 -0
- data/js/controls/sliders/vslider/themes/default/vslider_tracks.png +0 -0
- data/js/controls/sliders/vslider/vslider.js +41 -0
- data/js/controls/stepper/js.inc +0 -0
- data/js/controls/stepper/stepper.js +213 -0
- data/js/controls/stepper/themes/default/stepper-ie6.gif +0 -0
- data/js/controls/stepper/themes/default/stepper.css +14 -0
- data/js/controls/stepper/themes/default/stepper.html +2 -0
- data/js/controls/stepper/themes/default/stepper.png +0 -0
- data/js/controls/stringview/js.inc +0 -0
- data/js/controls/stringview/stringview.js +49 -0
- data/js/controls/stringview/themes/default/stringview.css +8 -0
- data/js/controls/stringview/themes/default/stringview.html +1 -0
- data/js/controls/tab/js.inc +0 -0
- data/js/controls/tab/tab.js +280 -0
- data/js/controls/tab/themes/bright/tab.css +76 -0
- data/js/controls/tab/themes/bright/tab.html +6 -0
- data/js/controls/tab/themes/bright/tab_bg_color-ie6.gif +0 -0
- data/js/controls/tab/themes/bright/tab_bg_color.png +0 -0
- data/js/controls/tab/themes/bright/tab_border_pattern-ie6.gif +0 -0
- data/js/controls/tab/themes/bright/tab_border_pattern.png +0 -0
- data/js/controls/tab/themes/bright/tab_parts1-ie6.gif +0 -0
- data/js/controls/tab/themes/bright/tab_parts1.png +0 -0
- data/js/controls/tab/themes/default/tab.css +77 -0
- data/js/controls/tab/themes/default/tab.html +6 -0
- data/js/controls/tab/themes/default/tab_bg_color-ie6.gif +0 -0
- data/js/controls/tab/themes/default/tab_bg_color.png +0 -0
- data/js/controls/tab/themes/default/tab_border_pattern-ie6.gif +0 -0
- data/js/controls/tab/themes/default/tab_border_pattern.png +0 -0
- data/js/controls/tab/themes/default/tab_parts1-ie6.gif +0 -0
- data/js/controls/tab/themes/default/tab_parts1.png +0 -0
- data/js/controls/textarea/js.inc +0 -0
- data/js/controls/textarea/textarea.js +24 -0
- data/js/controls/textarea/themes/default/textarea.css +21 -0
- data/js/controls/textarea/themes/default/textarea.html +18 -0
- data/js/controls/textcontrol/js.inc +0 -0
- data/js/controls/textcontrol/textcontrol.js +374 -0
- data/js/controls/textcontrol/themes/default/textcontrol.css +107 -0
- data/js/controls/textcontrol/themes/default/textcontrol.html +18 -0
- data/js/controls/textcontrol/themes/default/textcontrol_parts1-ie6.gif +0 -0
- data/js/controls/textcontrol/themes/default/textcontrol_parts1.png +0 -0
- data/js/controls/textcontrol/themes/default/textcontrol_parts2-ie6.gif +0 -0
- data/js/controls/textcontrol/themes/default/textcontrol_parts2.png +0 -0
- data/js/controls/textcontrol/themes/default/textcontrol_parts3-ie6.gif +0 -0
- data/js/controls/textcontrol/themes/default/textcontrol_parts3.png +0 -0
- data/js/controls/uploader/js.inc +0 -0
- data/js/controls/uploader/themes/default/upload_progress.gif +0 -0
- data/js/controls/uploader/themes/default/uploader.css +108 -0
- data/js/controls/uploader/themes/default/uploader.html +27 -0
- data/js/controls/uploader/uploader.js +154 -0
- data/js/controls/validatorview/js.inc +0 -0
- data/js/controls/validatorview/themes/default/validator-ie6.gif +0 -0
- data/js/controls/validatorview/themes/default/validator.png +0 -0
- data/js/controls/validatorview/themes/default/validatorview.css +0 -0
- data/js/controls/validatorview/themes/default/validatorview.html +0 -0
- data/js/controls/validatorview/validatorview.js +62 -0
- data/js/controls/window/js.inc +0 -0
- data/js/controls/window/themes/default/window.css +219 -0
- data/js/controls/window/themes/default/window.html +17 -0
- data/js/controls/window/themes/default/window_bg_active-ie6.gif +0 -0
- data/js/controls/window/themes/default/window_bg_active.png +0 -0
- data/js/controls/window/themes/default/window_bg_inactive-ie6.gif +0 -0
- data/js/controls/window/themes/default/window_bg_inactive.png +0 -0
- data/js/controls/window/themes/default/window_buttons-ie6.gif +0 -0
- data/js/controls/window/themes/default/window_buttons.png +0 -0
- data/js/controls/window/themes/default/window_parts1-ie6.gif +0 -0
- data/js/controls/window/themes/default/window_parts1.png +0 -0
- data/js/controls/window/themes/default/window_parts2-ie6.gif +0 -0
- data/js/controls/window/themes/default/window_parts2.png +0 -0
- data/js/controls/window/window.js +286 -0
- data/js/core/class/class.js +318 -0
- data/js/core/class/js.inc +0 -0
- data/js/core/elem/elem.js +1383 -0
- data/js/core/elem/js.inc +0 -0
- data/js/core/event/event.js +153 -0
- data/js/core/event/js.inc +0 -0
- data/js/core/iefix/ie_css_element.htc +5 -0
- data/js/core/iefix/ie_css_style.htc +5 -0
- data/js/core/iefix/iefix.js +359 -0
- data/js/core/iefix/js.inc +0 -0
- data/js/core/rsence_ns/js.inc +0 -0
- data/js/core/rsence_ns/rsence_ns.js +21 -0
- data/js/datetime/calendar/calendar.js +198 -0
- data/js/datetime/calendar/js.inc +0 -0
- data/js/datetime/calendar/themes/default/calendar.css +108 -0
- data/js/datetime/calendar/themes/default/calendar.html +9 -0
- data/js/datetime/calendar/themes/default/calendar_arrows-ie6.gif +0 -0
- data/js/datetime/calendar/themes/default/calendar_arrows.png +0 -0
- data/js/datetime/datetimevalue/datetimevalue.js +247 -0
- data/js/datetime/datetimevalue/js.inc +0 -0
- data/js/datetime/timesheet/js.inc +0 -0
- data/js/datetime/timesheet/themes/default/timesheet.css +30 -0
- data/js/datetime/timesheet/themes/default/timesheet.html +2 -0
- data/js/datetime/timesheet/timesheet.js +183 -0
- data/js/datetime/timesheet_item/js.inc +0 -0
- data/js/datetime/timesheet_item/themes/default/timesheet_item.css +42 -0
- data/js/datetime/timesheet_item/themes/default/timesheet_item.html +8 -0
- data/js/datetime/timesheet_item/timesheet_item.js +248 -0
- data/js/datetime/timesheet_item_edit/js.inc +0 -0
- data/js/datetime/timesheet_item_edit/timesheet_item_edit.js +274 -0
- data/js/foundation/application/application.js +208 -0
- data/js/foundation/application/js.inc +0 -0
- data/js/foundation/control/control.js +339 -0
- data/js/foundation/control/controldefaults/controldefaults.js +56 -0
- data/js/foundation/control/controldefaults/js.inc +0 -0
- data/js/foundation/control/dummyvalue/dummyvalue.js +51 -0
- data/js/foundation/control/dummyvalue/js.inc +0 -0
- data/js/foundation/control/dyncontrol/dyncontrol.js +500 -0
- data/js/foundation/control/dyncontrol/js.inc +0 -0
- data/js/foundation/control/dyncontrol/themes/default/dyncontrol.css +0 -0
- data/js/foundation/control/dyncontrol/themes/default/dyncontrol.html +0 -0
- data/js/foundation/control/eventresponder/eventresponder.js +750 -0
- data/js/foundation/control/eventresponder/js.inc +0 -0
- data/js/foundation/control/js.inc +0 -0
- data/js/foundation/control/valuematrix/js.inc +0 -0
- data/js/foundation/control/valuematrix/valuematrix.js +135 -0
- data/js/foundation/control/valueresponder/js.inc +0 -0
- data/js/foundation/control/valueresponder/valueresponder.js +79 -0
- data/js/foundation/eventmanager/eventmanager.js +991 -0
- data/js/foundation/eventmanager/js.inc +0 -0
- data/js/foundation/geom/point/js.inc +0 -0
- data/js/foundation/geom/point/point.js +202 -0
- data/js/foundation/geom/rect/js.inc +0 -0
- data/js/foundation/geom/rect/rect.js +651 -0
- data/js/foundation/json_renderer/js.inc +0 -0
- data/js/foundation/json_renderer/json_renderer.js +246 -0
- data/js/foundation/system/js.inc +0 -0
- data/js/foundation/system/system.js +381 -0
- data/js/foundation/thememanager/js.inc +0 -0
- data/js/foundation/thememanager/thememanager.js +393 -0
- data/js/foundation/value/js.inc +0 -0
- data/js/foundation/value/value.js +183 -0
- data/js/foundation/view/js.inc +0 -0
- data/js/foundation/view/markupview/js.inc +0 -0
- data/js/foundation/view/markupview/markupview.js +114 -0
- data/js/foundation/view/morphanimation/js.inc +0 -0
- data/js/foundation/view/morphanimation/morphanimation.js +237 -0
- data/js/foundation/view/view.js +1812 -0
- data/js/foundation/view/viewdefaults/js.inc +0 -0
- data/js/foundation/view/viewdefaults/viewdefaults.js +26 -0
- data/js/lists/checkboxlist/checkboxlist.js +171 -0
- data/js/lists/checkboxlist/js.inc +0 -0
- data/js/lists/listitems/js.inc +0 -0
- data/js/lists/listitems/listitems.js +88 -0
- data/js/lists/propertylist/js.inc +0 -0
- data/js/lists/propertylist/propertylist.js +326 -0
- data/js/lists/radiobuttonlist/js.inc +0 -0
- data/js/lists/radiobuttonlist/radiobuttonlist.js +116 -0
- data/js/util/reloadapp/js.inc +0 -0
- data/js/util/reloadapp/reloadapp.js +152 -0
- data/js/util/reloadapp/themes/default/reloadapp_warning-ie6.gif +0 -0
- data/js/util/reloadapp/themes/default/reloadapp_warning.png +0 -0
- data/js/util/sha/js.inc +0 -0
- data/js/util/sha/sha.js +426 -0
- data/js/views/centerview/centerview.js +75 -0
- data/js/views/centerview/js.inc +0 -0
- data/js/views/inlineview/inlineview.js +15 -0
- data/js/views/inlineview/js.inc +0 -0
- data/js/views/scrollview/js.inc +0 -0
- data/js/views/scrollview/scrollview.js +40 -0
- data/lib/conf/argv.rb +850 -0
- data/lib/conf/default.rb +219 -0
- data/lib/daemon/daemon.rb +387 -0
- data/lib/daemon/sigcomm.rb +64 -0
- data/lib/http/broker.rb +150 -0
- data/lib/http/rackup.rb +91 -0
- data/lib/http/request.rb +66 -0
- data/lib/http/response.rb +65 -0
- data/lib/plugins/dependencies.rb +285 -0
- data/lib/plugins/gui_plugin.rb +160 -0
- data/lib/plugins/guiparser.rb +123 -0
- data/lib/plugins/plugin.rb +438 -0
- data/lib/plugins/plugin_base.rb +162 -0
- data/lib/plugins/plugin_plugins.rb +81 -0
- data/lib/plugins/plugin_sqlite_db.rb +98 -0
- data/lib/plugins/pluginmanager.rb +635 -0
- data/lib/plugins/plugins.rb +169 -0
- data/lib/plugins/servlet.rb +108 -0
- data/lib/rsence.rb +32 -0
- data/lib/session/msg.rb +327 -0
- data/lib/session/sessionmanager.rb +522 -0
- data/lib/session/sessionstorage.rb +340 -0
- data/lib/transporter/transporter.rb +263 -0
- data/lib/util/gzstring.rb +9 -0
- data/lib/util/ruby19_fixes.rb +18 -0
- data/lib/values/hvalue.rb +378 -0
- data/lib/values/valuemanager.rb +172 -0
- data/plugins/client_pkg/client_pkg.rb +157 -0
- data/plugins/client_pkg/info.yaml +25 -0
- data/plugins/client_pkg/lib/client_pkg_build.rb +561 -0
- data/plugins/client_pkg/lib/client_pkg_cache.rb +50 -0
- data/plugins/client_pkg/lib/client_pkg_serve.rb +218 -0
- data/plugins/index_html/img/loading.gif +0 -0
- data/plugins/index_html/img/riassence.gif +0 -0
- data/plugins/index_html/index_html.rb +120 -0
- data/plugins/index_html/info.yaml +18 -0
- data/plugins/index_html/tmpl/index.html +15 -0
- data/plugins/main/info.yaml +18 -0
- data/plugins/main/js/main.js +84 -0
- data/plugins/main/main.rb +255 -0
- data/plugins/main/values.yaml +8 -0
- data/plugins/ticket/info.yaml +21 -0
- data/plugins/ticket/lib/common.rb +392 -0
- data/plugins/ticket/lib/favicon.rb +39 -0
- data/plugins/ticket/lib/file.rb +58 -0
- data/plugins/ticket/lib/img.rb +50 -0
- data/plugins/ticket/lib/objblob.rb +66 -0
- data/plugins/ticket/lib/rsrc.rb +34 -0
- data/plugins/ticket/lib/upload.rb +236 -0
- data/plugins/ticket/ticket.rb +333 -0
- data/setup/welcome/gui/welcome.yaml +92 -0
- data/setup/welcome/info.yaml +13 -0
- data/setup/welcome/text/welcome.html +9 -0
- data/setup/welcome/values.yaml +9 -0
- data/setup/welcome/welcome.rb +54 -0
- metadata +407 -0
data/lib/http/broker.rb
ADDED
@@ -0,0 +1,150 @@
|
|
1
|
+
## RSence
|
2
|
+
# Copyright 2008 Riassence Inc.
|
3
|
+
# http://riassence.com/
|
4
|
+
#
|
5
|
+
# You should have received a copy of the GNU General Public License along
|
6
|
+
# with this software package. If not, contact licensing@riassence.com
|
7
|
+
##
|
8
|
+
|
9
|
+
require 'rubygems'
|
10
|
+
require 'rack'
|
11
|
+
|
12
|
+
## Minimally WEBrick -compatible response object
|
13
|
+
require 'http/response'
|
14
|
+
|
15
|
+
## Minimally WEBrick -compatible request object
|
16
|
+
require 'http/request'
|
17
|
+
|
18
|
+
|
19
|
+
module RSence
|
20
|
+
|
21
|
+
|
22
|
+
# Broker sets up Rack and routes requests to the proper request processing instance.
|
23
|
+
class Broker
|
24
|
+
|
25
|
+
# This method is called from Rack.
|
26
|
+
# @param [Hash] env is the Rack environment.
|
27
|
+
# @return [Array(Number, Hash, String)] Rack-style response status, header, body
|
28
|
+
def call( env )
|
29
|
+
sleep @@ping_sim if @@ping_sim
|
30
|
+
unless @@transporter.online?
|
31
|
+
puts "#{Time.now.strftime('%Y-%m-%d %H:%M:%S')} -- Server busy."
|
32
|
+
headers = {
|
33
|
+
'Retry-After' => '2',
|
34
|
+
'Content-Type' => 'text/plain',
|
35
|
+
'Refresh' => "2; #{env['REQUEST_URI']}",
|
36
|
+
'Content-Length' => '4'
|
37
|
+
}
|
38
|
+
return [ 503, headers, 'BUSY' ]
|
39
|
+
end
|
40
|
+
request = Request.new(env)
|
41
|
+
response = Response.new
|
42
|
+
request_method = request.request_method.downcase
|
43
|
+
dispatcher = dispatcher_class.new( request, response )
|
44
|
+
dispatcher.send( request_method )
|
45
|
+
content_type = dispatcher.content_type
|
46
|
+
response.header['Content-Length'] = response.body.length.to_s unless response.header.has_key?('Content-Length')
|
47
|
+
return [response.status, response.header, response.body]
|
48
|
+
end
|
49
|
+
|
50
|
+
# Returns a dynamically created "REST Dispatcher" kind of class that has
|
51
|
+
# request and response as instance variables and the rest of the Broker
|
52
|
+
# class as the superclass. It calls the method according to the http method. Called from {#call}
|
53
|
+
# Broker currently implements only the {#get} and {#post} methods.
|
54
|
+
# @return [Broker] An instance of Broker with a {Request} instance as +@request+ and a {Response} instance as +@response+
|
55
|
+
def dispatcher_class
|
56
|
+
@dispatcher ||= Class.new(self.class) do
|
57
|
+
attr_accessor :content_type
|
58
|
+
def initialize(request,response)
|
59
|
+
@request = request
|
60
|
+
@response = response
|
61
|
+
end
|
62
|
+
end
|
63
|
+
end
|
64
|
+
|
65
|
+
# Creates the Rack instance and set up itself accordingly.
|
66
|
+
#
|
67
|
+
# @param [Transporter] transporter The single {Transporter} instance initialized by {HTTPDaemon}
|
68
|
+
# @param [Hash{Symbol => String}] conf Rack initialization settings
|
69
|
+
# @option conf [String] :bind_address ('127.0.0.1') The TCP/IP address or mask to bind to.
|
70
|
+
# @option conf [#to_i] :port ('8001') The TCP port to bind to.
|
71
|
+
# @option conf [String] :rack_require ('mongrel') The Rack handler to use.
|
72
|
+
def self.start( transporter, conf = {:bind_address => '127.0.0.1', :port => '8001', :rack_require => 'mongrel'} )
|
73
|
+
|
74
|
+
host = conf[:bind_address]
|
75
|
+
port = conf[:port]
|
76
|
+
|
77
|
+
@@transporter = transporter
|
78
|
+
latency = ::RSence.config[:http_server][:latency]
|
79
|
+
if latency == 0
|
80
|
+
@@ping_sim = false
|
81
|
+
else
|
82
|
+
@@ping_sim = latency/1000.0
|
83
|
+
end
|
84
|
+
Thread.new do
|
85
|
+
Thread.pass
|
86
|
+
puts "Testing if #{host}:#{port} responds.." if ::RSence.args[:debug]
|
87
|
+
until RSence.argv.test_port( port, host )
|
88
|
+
puts "..#{host}:#{port} doesn't respond yet.." if ::RSence.args[:debug]
|
89
|
+
sleep 0.2
|
90
|
+
end
|
91
|
+
puts "..#{host}:#{port} responds!" if ::RSence.args[:debug]
|
92
|
+
puts "RSence is online on the address http://#{host}:#{port}#{::RSence.config[:base_url]}"
|
93
|
+
@@transporter.online = true
|
94
|
+
end
|
95
|
+
|
96
|
+
require 'rack'
|
97
|
+
|
98
|
+
# Loads the selected web-server (default is 'mongrel')
|
99
|
+
rack_require = conf[:rack_require]
|
100
|
+
puts conf.inspect if RSence.args[:debug]
|
101
|
+
|
102
|
+
require rack_require
|
103
|
+
|
104
|
+
# Selects the handler for Rack
|
105
|
+
handler = {
|
106
|
+
'webrick' => lambda { Rack::Handler::WEBrick },
|
107
|
+
'ebb' => lambda { Rack::Handler::Ebb },
|
108
|
+
'thin' => lambda { Rack::Handler::Thin },
|
109
|
+
'mongrel' => lambda { Rack::Handler::Mongrel },
|
110
|
+
'unicorn' => lambda { Rack::Handler::Unicorn },
|
111
|
+
'rainbows' => lambda { Rack::Handler::Rainbows }
|
112
|
+
}[rack_require].call
|
113
|
+
|
114
|
+
handler.run( Rack::Lint.new(self.new), :Host => host, :Port => port )
|
115
|
+
|
116
|
+
end
|
117
|
+
|
118
|
+
# Generic 404 error handler. Just sets up response status, headers, body as a small "Page Not Found" html page
|
119
|
+
def not_found
|
120
|
+
puts "/404: #{@request.fullpath.inspect}" if RSence.args[:verbose]
|
121
|
+
@response.status = 404
|
122
|
+
err404 = '<html><head><title>404 - Page Not Found</title></head><body>404 - Page Not Found</body></html>'
|
123
|
+
@response['Content-Type'] = 'text/html; charset=UTF-8'
|
124
|
+
@response['Content-Length'] = err404.length.to_s
|
125
|
+
@response.body = err404
|
126
|
+
end
|
127
|
+
|
128
|
+
# Routes POST requests to {Transporter#servlet}
|
129
|
+
def post
|
130
|
+
|
131
|
+
puts "post: #{@request.fullpath}" if RSence.args[:verbose]
|
132
|
+
|
133
|
+
not_found unless @@transporter.servlet( :post, @request, @response )
|
134
|
+
|
135
|
+
end
|
136
|
+
|
137
|
+
# Routes GET requests to {Transporter#servlet}
|
138
|
+
def get
|
139
|
+
|
140
|
+
puts "get: #{@request.fullpath}" if RSence.args[:verbose]
|
141
|
+
|
142
|
+
not_found unless @@transporter.servlet( :get, @request, @response )
|
143
|
+
|
144
|
+
end
|
145
|
+
|
146
|
+
### -- Add more http methods here when we have some apps to test with CalDAV implementation maybe? ++
|
147
|
+
|
148
|
+
end
|
149
|
+
|
150
|
+
end
|
data/lib/http/rackup.rb
ADDED
@@ -0,0 +1,91 @@
|
|
1
|
+
## RSence
|
2
|
+
# Copyright 2008 Riassence Inc.
|
3
|
+
# http://riassence.com/
|
4
|
+
#
|
5
|
+
# You should have received a copy of the GNU General Public License along
|
6
|
+
# with this software package. If not, contact licensing@riassence.com
|
7
|
+
##
|
8
|
+
|
9
|
+
|
10
|
+
warn "Current RSence rackup Broker implementation does not work."
|
11
|
+
warn "Please try again in a future revision."
|
12
|
+
exit
|
13
|
+
|
14
|
+
if ARGV.include?('--root-path')
|
15
|
+
SERVER_PATH = ARGV[ARGV.index('--root-path')+1]
|
16
|
+
else
|
17
|
+
path = ::File.dirname(__FILE__)
|
18
|
+
exp_path = ::File.expand_path( path )
|
19
|
+
lib_path = ::File.split( exp_path )[0]
|
20
|
+
SERVER_PATH = ::File.split( lib_path )[0]
|
21
|
+
end
|
22
|
+
|
23
|
+
$LOAD_PATH << SERVER_PATH
|
24
|
+
$LOAD_PATH << ::File.join( SERVER_PATH, 'lib' )
|
25
|
+
|
26
|
+
# Use the default configuration:
|
27
|
+
require 'conf/default'
|
28
|
+
|
29
|
+
# Debug mode switch. The debug mode is intended for developers, not production.
|
30
|
+
$DEBUG_MODE = RSence.config[:debug_mode]
|
31
|
+
|
32
|
+
ENV['RACK_ENV'] = 'production' unless $DEBUG_MODE
|
33
|
+
|
34
|
+
## Minimally WEBrick -compatible response object
|
35
|
+
require 'http/response'
|
36
|
+
|
37
|
+
## Minimally WEBrick -compatible request object
|
38
|
+
require 'http/request'
|
39
|
+
|
40
|
+
# Transporter is the top-level handler for calls coming from the javascript COMM.Transporter.
|
41
|
+
require 'transporter/transporter'
|
42
|
+
|
43
|
+
module RSence
|
44
|
+
module Broker
|
45
|
+
|
46
|
+
@@transporter = Transporter.new
|
47
|
+
|
48
|
+
def self.start
|
49
|
+
conf = RSence.config[:http_server][:latency]
|
50
|
+
if conf == 0
|
51
|
+
@@ping_sim = false
|
52
|
+
else
|
53
|
+
@@ping_sim = conf/1000.0
|
54
|
+
end
|
55
|
+
end
|
56
|
+
|
57
|
+
def self.stop
|
58
|
+
@@transporter.plugins.shutdown
|
59
|
+
@@transporter.sessions.shutdown
|
60
|
+
end
|
61
|
+
|
62
|
+
def self.call(env)
|
63
|
+
request = Request.new(env)
|
64
|
+
response = Response.new
|
65
|
+
request_method = request.request_method.downcase
|
66
|
+
if request_method == 'get'
|
67
|
+
puts "get: #{request.fullpath}" if $DEBUG_MODE
|
68
|
+
sleep @@ping_sim if @@ping_sim
|
69
|
+
not_found( request, response ) unless @@transporter.servlet( :get, request, response )
|
70
|
+
elsif request_method == 'post'
|
71
|
+
puts "post: #{request.fullpath}" if $DEBUG_MODE
|
72
|
+
sleep @@ping_sim if @@ping_sim
|
73
|
+
not_found( request, response ) unless @@transporter.servlet( :post, request, response )
|
74
|
+
else
|
75
|
+
puts "unsupported method: #{request_method.inspect}"
|
76
|
+
end
|
77
|
+
response.header['Content-Length'] = response.body.length.to_s unless response.header.has_key?('Content-Length')
|
78
|
+
return [response.status, response.header, response.body]
|
79
|
+
end
|
80
|
+
|
81
|
+
def not_found( request, response )
|
82
|
+
puts "/404: #{request.fullpath.inspect}" if $DEBUG_MODE
|
83
|
+
response.status = 404
|
84
|
+
err404 = '<html><head><title>404 - Page Not Found</title></head><body>404 - Page Not Found</body></html>'
|
85
|
+
response['content-type'] = 'text/html; charset=UTF-8'
|
86
|
+
response['content-length'] = err404.length.to_s
|
87
|
+
response.body = err404
|
88
|
+
end
|
89
|
+
|
90
|
+
end
|
91
|
+
end
|
data/lib/http/request.rb
ADDED
@@ -0,0 +1,66 @@
|
|
1
|
+
## RSence
|
2
|
+
# Copyright 2008 Riassence Inc.
|
3
|
+
# http://riassence.com/
|
4
|
+
#
|
5
|
+
# You should have received a copy of the GNU General Public License along
|
6
|
+
# with this software package. If not, contact licensing@riassence.com
|
7
|
+
##
|
8
|
+
|
9
|
+
|
10
|
+
|
11
|
+
require 'rubygems'
|
12
|
+
require 'rack'
|
13
|
+
|
14
|
+
module RSence
|
15
|
+
|
16
|
+
# Simple Request class, slightly more involved
|
17
|
+
# than the Rack::Request it's extending.
|
18
|
+
class Request < Rack::Request
|
19
|
+
attr_reader :header, :path, :query
|
20
|
+
def initialize(env)
|
21
|
+
@header = {}
|
22
|
+
super
|
23
|
+
env2header()
|
24
|
+
@path = path_info()
|
25
|
+
@query = params()
|
26
|
+
end
|
27
|
+
def unparsed_uri
|
28
|
+
return @header['request-uri']
|
29
|
+
end
|
30
|
+
def env2header
|
31
|
+
[ ['SERVER_NAME', 'server-name'],
|
32
|
+
['HTTP_USER_AGENT', 'user-agent'],
|
33
|
+
['HTTP_ACCEPT_ENCODING', 'accept-encoding'],
|
34
|
+
['PATH_INFO', 'path-info'],
|
35
|
+
['HTTP_HOST', 'host'],
|
36
|
+
['HTTP_ACCEPT_LANGUAGE', 'accept-language'],
|
37
|
+
['SERVER_PROTOCOL', 'server-protocol'],
|
38
|
+
['REQUEST_PATH', 'request-path'],
|
39
|
+
['HTTP_KEEP_ALIVE', 'keep-alive'],
|
40
|
+
['SERVER_SOFTWARE', 'server-software'],
|
41
|
+
['REMOTE_ADDR', 'remote-addr'],
|
42
|
+
['HTTP_REFERER', 'referer'],
|
43
|
+
['HTTP_VERSION', 'version'],
|
44
|
+
['HTTP_ACCEPT_CHARSET', 'accept-charset'],
|
45
|
+
['REQUEST_URI', 'request-uri'],
|
46
|
+
['SERVER_PORT', 'server-port'],
|
47
|
+
['QUERY_STRING', 'query-string'],
|
48
|
+
['HTTP_ACCEPT', 'accept'],
|
49
|
+
['REQUEST_METHOD', 'request-method'],
|
50
|
+
['HTTP_CONNECTION', 'connection'],
|
51
|
+
['HTTP_SOAPACTION', 'soapaction'],
|
52
|
+
['HTTP_FORWARDED_HOST', 'forwarded-host']
|
53
|
+
].each do |env_key,header_key|
|
54
|
+
if @env.has_key?(env_key)
|
55
|
+
@header[header_key] = @env[env_key]
|
56
|
+
end
|
57
|
+
if env_key.start_with?( 'HTTP_' )
|
58
|
+
x_env_key = "HTTP_X#{env_key[4..-1]}"
|
59
|
+
if @env.has_key?( x_env_key )
|
60
|
+
@header["x-#{header_key}"] = @env[ x_env_key ]
|
61
|
+
end
|
62
|
+
end
|
63
|
+
end
|
64
|
+
end
|
65
|
+
end
|
66
|
+
end
|
@@ -0,0 +1,65 @@
|
|
1
|
+
## RSence
|
2
|
+
# Copyright 2008 Riassence Inc.
|
3
|
+
# http://riassence.com/
|
4
|
+
#
|
5
|
+
# You should have received a copy of the GNU General Public License along
|
6
|
+
# with this software package. If not, contact licensing@riassence.com
|
7
|
+
##
|
8
|
+
|
9
|
+
|
10
|
+
|
11
|
+
module RSence
|
12
|
+
|
13
|
+
# Classic WEBrick -compatible Response object for Rack.
|
14
|
+
# Implements only the methods used by the framework.
|
15
|
+
class Response
|
16
|
+
|
17
|
+
# Adds the + method "operator" to an extended Array.
|
18
|
+
# Used for pushing http body data.
|
19
|
+
class ResponseBody < Array
|
20
|
+
def +(body_data)
|
21
|
+
self.push(body_data)
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
def initialize
|
26
|
+
@body = ResponseBody.new(1)
|
27
|
+
@body[0] = ''
|
28
|
+
@status = 200
|
29
|
+
@header = {
|
30
|
+
'Content-Type' => 'text/plain',
|
31
|
+
'Server' => 'RSence'
|
32
|
+
}
|
33
|
+
end
|
34
|
+
def body=(body_data)
|
35
|
+
@body = ResponseBody.new(1)
|
36
|
+
@body[0] = body_data
|
37
|
+
end
|
38
|
+
def body
|
39
|
+
@body.join
|
40
|
+
end
|
41
|
+
def content_type=(new_content_type)
|
42
|
+
@header['Content-Type'] = new_content_type
|
43
|
+
end
|
44
|
+
def content_type
|
45
|
+
@header['Content-Type']
|
46
|
+
end
|
47
|
+
def camelize( header_key )
|
48
|
+
header_key.capitalize.gsub(/\-([a-z])/) { '-'+$1.upcase }
|
49
|
+
end
|
50
|
+
def []=(header_key,header_val)
|
51
|
+
@header[camelize( header_key )] = header_val.to_s
|
52
|
+
end
|
53
|
+
def status=(new_val)
|
54
|
+
@status = new_val.to_i
|
55
|
+
end
|
56
|
+
def status
|
57
|
+
@status
|
58
|
+
end
|
59
|
+
def header
|
60
|
+
@header
|
61
|
+
end
|
62
|
+
end
|
63
|
+
|
64
|
+
end
|
65
|
+
|
@@ -0,0 +1,285 @@
|
|
1
|
+
## RSence
|
2
|
+
# Copyright 2010 Riassence Inc.
|
3
|
+
# http://riassence.com/
|
4
|
+
#
|
5
|
+
# You should have received a copy of the GNU General Public License along
|
6
|
+
# with this software package. If not, contact licensing@riassence.com
|
7
|
+
##
|
8
|
+
|
9
|
+
|
10
|
+
module RSence
|
11
|
+
|
12
|
+
# = Description:
|
13
|
+
# Generic dependency calculator. Used by PluginManager.
|
14
|
+
# = Usage:
|
15
|
+
# This is an almost real world example:
|
16
|
+
# ## Initialize with pre-satisfied dependencies
|
17
|
+
# deps = RSence::Dependencies.new( [:foo1,:foo2] )
|
18
|
+
#
|
19
|
+
# ## :client_pkg doesn't depend on anything
|
20
|
+
# deps.set_deps( :client_pkg, nil )
|
21
|
+
#
|
22
|
+
# ## :system is the category of :client_pkg
|
23
|
+
# deps.set_deps( :system, :client_pkg )
|
24
|
+
#
|
25
|
+
# ## :index_html depends on :client_pkg
|
26
|
+
# deps.set_deps( :index_html, :client_pkg )
|
27
|
+
#
|
28
|
+
# ## :system is the category of :index_html
|
29
|
+
# deps.set_deps( :system, :index_html )
|
30
|
+
#
|
31
|
+
# ## :main depends on :index_html
|
32
|
+
# deps.set_deps( :main, :index_html )
|
33
|
+
#
|
34
|
+
# ## :system is the category of :main
|
35
|
+
# deps.set_deps( :system, :main )
|
36
|
+
#
|
37
|
+
# ## :impossible has several dependencies, of which :foo3 can't be satisfied
|
38
|
+
# deps.set_deps( :impossible, [:foo1, :foo2, :foo3] )
|
39
|
+
#
|
40
|
+
# ## :ticket has no dependencies
|
41
|
+
# deps.set_deps( :ticket, nil )
|
42
|
+
#
|
43
|
+
# ## :system is the category of :ticket
|
44
|
+
# deps.set_deps( :system, :ticket )
|
45
|
+
#
|
46
|
+
# ## :welcome depends on the :system category
|
47
|
+
# deps.set_deps( :welcome, :system )
|
48
|
+
#
|
49
|
+
# ## :first doesn't depend on anything
|
50
|
+
# deps.set_deps( :first, nil )
|
51
|
+
#
|
52
|
+
# ## Prepending is handled like this:
|
53
|
+
# deps.set_deps( :client_pkg, :first )
|
54
|
+
# deps.set_deps( :ticket, :first )
|
55
|
+
#
|
56
|
+
# ## Calculates the list of dependencies and returns them in an Array
|
57
|
+
# p deps.list
|
58
|
+
#
|
59
|
+
# ## Output of the example above:
|
60
|
+
# # impossible dependencies:
|
61
|
+
# # :impossible => [:foo3]
|
62
|
+
# # [:foo1, :foo2, :first, :ticket, :client_pkg, :index_html, :main, :system, :welcome]
|
63
|
+
class Dependencies
|
64
|
+
|
65
|
+
# Don't use Dependencies for external projects yet. It's subject to change
|
66
|
+
# without deprecation warnings.
|
67
|
+
# +resolved+ and +categories+ are optional.
|
68
|
+
def initialize( resolved = [], categories = {}, quiet=true )
|
69
|
+
@quiet = quiet
|
70
|
+
@pre_resolved = resolved.clone
|
71
|
+
@depends_on = {
|
72
|
+
# :name => [ :dep1, :dep2, :dep3, ... ]
|
73
|
+
}
|
74
|
+
@dependencies_of = {
|
75
|
+
#:dep1 => [ :name1, :name2, ... ]
|
76
|
+
}
|
77
|
+
@categories = []
|
78
|
+
categories.each_key do |cat_name, cat_items|
|
79
|
+
add_category( cat_name )
|
80
|
+
set_deps( cat_name, nil )
|
81
|
+
end
|
82
|
+
@unresolved = []
|
83
|
+
recalculate!
|
84
|
+
end
|
85
|
+
|
86
|
+
# Returns true, if +name+ is a pre-resolved dependency.
|
87
|
+
def pre_resolved?( name )
|
88
|
+
@pre_resolved.include?( name )
|
89
|
+
end
|
90
|
+
|
91
|
+
# Returns true, if +name+ is not a pre-resolved dependency and not a category.
|
92
|
+
def loadable?( name )
|
93
|
+
return (not pre_resolved?(name) and not category?(name))
|
94
|
+
end
|
95
|
+
|
96
|
+
# Returns list of items that are dependencies of +name+ in
|
97
|
+
# no particular order.
|
98
|
+
def deps_of( name )
|
99
|
+
outp = []
|
100
|
+
if @dependencies_of.has_key?(name)
|
101
|
+
@dependencies_of[name].each do |dep|
|
102
|
+
outp.push( dep )
|
103
|
+
outp += deps_of( dep )
|
104
|
+
end
|
105
|
+
end
|
106
|
+
outp.uniq!
|
107
|
+
outp.delete( name )
|
108
|
+
return outp
|
109
|
+
end
|
110
|
+
alias dependencies_of deps_of
|
111
|
+
|
112
|
+
# Returns list of items that +name+ depends on in no particular order.
|
113
|
+
def deps_on( name )
|
114
|
+
outp = []
|
115
|
+
if @depends_on.has_key?(name)
|
116
|
+
@depends_on[name].each do |dep|
|
117
|
+
outp.push( dep )
|
118
|
+
outp += deps_on( dep )
|
119
|
+
end
|
120
|
+
end
|
121
|
+
outp.uniq!
|
122
|
+
outp.delete( name )
|
123
|
+
return outp
|
124
|
+
end
|
125
|
+
alias depends_on deps_on
|
126
|
+
|
127
|
+
# List of categories
|
128
|
+
attr_reader :categories
|
129
|
+
|
130
|
+
# Adds the category +name+.
|
131
|
+
def add_category( name )
|
132
|
+
@categories.push( name ) unless @categories.include?( name )
|
133
|
+
end
|
134
|
+
|
135
|
+
# Deletes the category +name+, but doesn't dissolve its dependencies.
|
136
|
+
# Essentially turns +name+ into a regular item.
|
137
|
+
def del_category( name )
|
138
|
+
@categories.delete( name ) if @categories.include?( name )
|
139
|
+
end
|
140
|
+
|
141
|
+
# Returns true, if +name+ is a category.
|
142
|
+
def category?( name )
|
143
|
+
@categories.include?( name )
|
144
|
+
end
|
145
|
+
|
146
|
+
# Set list of dependency names as +deps+ that +name+ depends on
|
147
|
+
def set_deps( name, deps )
|
148
|
+
if deps.class == Symbol
|
149
|
+
deps = [deps]
|
150
|
+
elsif deps.class == String
|
151
|
+
deps = [deps.to_sym]
|
152
|
+
elsif deps.class == NilClass
|
153
|
+
deps = []
|
154
|
+
elsif deps.class != Array
|
155
|
+
raise "Dependencies.set_deps error: the deps is an unsupported type: #{deps.class}"
|
156
|
+
end
|
157
|
+
if not @depends_on.has_key?(name)
|
158
|
+
@depends_on[name] = deps
|
159
|
+
else
|
160
|
+
deps.each do |dep|
|
161
|
+
@depends_on[name].push( dep ) unless @depends_on[name].include?( dep )
|
162
|
+
end
|
163
|
+
end
|
164
|
+
deps.each do |dep|
|
165
|
+
if not @dependencies_of.has_key?( dep )
|
166
|
+
@dependencies_of[dep] = [name]
|
167
|
+
elsif not @dependencies_of[dep].include?( name )
|
168
|
+
@dependencies_of[dep].push( name )
|
169
|
+
end
|
170
|
+
end
|
171
|
+
recalculate!
|
172
|
+
end
|
173
|
+
alias set_dependencies set_deps
|
174
|
+
alias set_dependency set_deps
|
175
|
+
|
176
|
+
# Returns copy of the @depends_on Array
|
177
|
+
def clone_depends_on
|
178
|
+
Marshal.load( Marshal.dump( @depends_on ) )
|
179
|
+
end
|
180
|
+
|
181
|
+
# Returns clone of the @dependencies_of Array
|
182
|
+
def clone_dependencies_of
|
183
|
+
Marshal.load( Marshal.dump( @dependencies_of ) )
|
184
|
+
end
|
185
|
+
|
186
|
+
# Remove +name+ from dependency system, throws error if it's depended on another item.
|
187
|
+
def del_item( name )
|
188
|
+
d_of = deps_of( name )
|
189
|
+
if not d_of.empty?
|
190
|
+
d_of.each do |dep|
|
191
|
+
if category?( dep )
|
192
|
+
@depends_on[ dep ].delete( name )
|
193
|
+
else
|
194
|
+
throw "Dependencies.del_item error: the following items depend on #{name.inspect} -> #{deps_of(name).inspect}"
|
195
|
+
end
|
196
|
+
end
|
197
|
+
end
|
198
|
+
unless category?( name )
|
199
|
+
deps_on( name ).each do |dep|
|
200
|
+
@dependencies_of[dep].delete(name) if @dependencies_of.has_key?(dep)
|
201
|
+
end
|
202
|
+
@depends_on.delete( name )
|
203
|
+
@dependencies_of.delete( name )
|
204
|
+
end
|
205
|
+
recalculate!
|
206
|
+
end
|
207
|
+
|
208
|
+
# Returns the order of deletion possible without breaking the dependency chain
|
209
|
+
def del_order( name )
|
210
|
+
d_order = []
|
211
|
+
d_of = deps_of( name )
|
212
|
+
list.reverse.each do |dep|
|
213
|
+
if d_of.include?( dep )
|
214
|
+
d_order.push( dep )
|
215
|
+
end
|
216
|
+
end
|
217
|
+
d_order.push( name )
|
218
|
+
return d_order
|
219
|
+
end
|
220
|
+
|
221
|
+
# Deletes +name+ and all dependencies of +name+
|
222
|
+
def del_deps( name )
|
223
|
+
del_order( name ).each do |del_name|
|
224
|
+
del_item( del_name )
|
225
|
+
end
|
226
|
+
end
|
227
|
+
|
228
|
+
# Returns true, if +name+ is unresolved. The list of unresolved items is
|
229
|
+
# updated every time self#recalculate is called.
|
230
|
+
def unresolved?( name )
|
231
|
+
@unresolved.include?( name )
|
232
|
+
end
|
233
|
+
|
234
|
+
# Returns true, if +name+ is resolved (a valid dependency). Inverse of self#unresolved?
|
235
|
+
def resolved?( name )
|
236
|
+
(not unresolved?( name ))
|
237
|
+
end
|
238
|
+
|
239
|
+
# Recalculates the list and unresolved items.
|
240
|
+
def recalculate!
|
241
|
+
unresolved = []
|
242
|
+
resolved = @pre_resolved.clone
|
243
|
+
same_len = false
|
244
|
+
depends_on = clone_depends_on
|
245
|
+
target_len = depends_on.keys.length + resolved.length
|
246
|
+
until resolved.length == target_len
|
247
|
+
len = resolved.length
|
248
|
+
depends_on.each do | name, deps |
|
249
|
+
if deps.empty? and not resolved.include?(name)
|
250
|
+
resolved.push( name )
|
251
|
+
elsif deps.empty?
|
252
|
+
next
|
253
|
+
else
|
254
|
+
deps.each do |dep|
|
255
|
+
deps.delete(dep) if resolved.include?(dep)
|
256
|
+
end
|
257
|
+
end
|
258
|
+
end
|
259
|
+
if len == resolved.length
|
260
|
+
if same_len
|
261
|
+
warn "impossible dependencies:" unless @quiet
|
262
|
+
(depends_on.keys - resolved).each do |unsatisfied|
|
263
|
+
warn " #{unsatisfied.inspect} => #{depends_on[unsatisfied].inspect}" unless @quiet
|
264
|
+
unresolved.push( unsatisfied )
|
265
|
+
end
|
266
|
+
break
|
267
|
+
else
|
268
|
+
same_len = true
|
269
|
+
end
|
270
|
+
else
|
271
|
+
same_len = false
|
272
|
+
end
|
273
|
+
end
|
274
|
+
@unresolved = unresolved
|
275
|
+
@resolved = resolved
|
276
|
+
end
|
277
|
+
|
278
|
+
# Returns dependencies sorted in load order
|
279
|
+
def list
|
280
|
+
@resolved.clone
|
281
|
+
end
|
282
|
+
alias load_order list
|
283
|
+
end
|
284
|
+
end
|
285
|
+
|