maglev-webtools 0.2.1 → 1.0
Sign up to get free protection for your applications and to get access to all the features.
- data/README.rdoc +38 -29
- data/bin/webtools +22 -1
- data/lib/web_tools/code_browser.rb +156 -0
- data/lib/web_tools/debugger.rb +96 -199
- data/lib/web_tools/info.rb +1 -3
- data/lib/web_tools/method_list.rb +67 -0
- data/lib/web_tools/middleware/debugger.rb +10 -16
- data/lib/web_tools/object_log.rb +24 -0
- data/lib/web_tools/session_list.rb +119 -0
- data/lib/web_tools/shared_page_cache.rb +30 -0
- data/lib/web_tools/stat_process.rb +24 -0
- data/lib/web_tools/statistics.rb +14 -0
- data/lib/web_tools/support/app_model.rb +66 -101
- data/lib/web_tools/support/code_browser.rb +88 -86
- data/lib/web_tools/support/debugger.rb +303 -0
- data/lib/web_tools/support/error_log.rb +33 -0
- data/lib/web_tools/support/ruby.rb +60 -121
- data/lib/web_tools/support/service_helper.rb +38 -10
- data/lib/web_tools/support/smalltalk_extensions.rb +12 -0
- data/lib/web_tools/tool.rb +48 -0
- data/lib/web_tools/ui.rb +14 -53
- data/lib/web_tools/version_report.rb +29 -0
- data/lib/web_tools/workspace.rb +77 -0
- data/lib/web_tools.rb +14 -4
- data/public/CodeBrowser.html +51 -0
- data/public/CodeMirror/LICENSE +19 -0
- data/public/CodeMirror/css/codemirror.css +67 -0
- data/public/CodeMirror/css/default.css +18 -0
- data/public/CodeMirror/js/codemirror.js +2131 -0
- data/public/CodeMirror/js/ruby.js +195 -0
- data/public/CodeMirror/js/smalltalk.js +139 -0
- data/public/Debugger.html +28 -0
- data/public/MethodList.html +20 -0
- data/public/ObjectLog.html +20 -0
- data/public/SessionList.html +31 -0
- data/public/SharedPageCache.html +78 -0
- data/public/Statistics.html +64 -0
- data/public/VersionReport.html +50 -0
- data/public/Workspace.html +39 -0
- data/public/css/CodeBrowser.css +24 -0
- data/public/css/Debugger.css +32 -0
- data/public/css/MethodList.css +8 -0
- data/public/css/ObjectLog.css +5 -0
- data/public/css/SessionList.css +9 -0
- data/public/css/Statistics.css +24 -0
- data/public/{stylesheets → css}/base/images/ui-anim_basic_16x16.gif +0 -0
- data/public/{stylesheets → css}/base/images/ui-bg_flat_0_aaaaaa_40x100.png +0 -0
- data/public/{stylesheets → css}/base/images/ui-bg_flat_75_ffffff_40x100.png +0 -0
- data/public/{stylesheets → css}/base/images/ui-bg_glass_55_fbf9ee_1x400.png +0 -0
- data/public/{stylesheets → css}/base/images/ui-bg_glass_65_ffffff_1x400.png +0 -0
- data/public/{stylesheets → css}/base/images/ui-bg_glass_75_dadada_1x400.png +0 -0
- data/public/{stylesheets → css}/base/images/ui-bg_glass_75_e6e6e6_1x400.png +0 -0
- data/public/{stylesheets → css}/base/images/ui-bg_glass_95_fef1ec_1x400.png +0 -0
- data/public/{stylesheets → css}/base/images/ui-bg_highlight-soft_75_cccccc_1x100.png +0 -0
- data/public/{stylesheets → css}/base/images/ui-icons_222222_256x240.png +0 -0
- data/public/{stylesheets → css}/base/images/ui-icons_2e83ff_256x240.png +0 -0
- data/public/{stylesheets → css}/base/images/ui-icons_454545_256x240.png +0 -0
- data/public/{stylesheets → css}/base/images/ui-icons_888888_256x240.png +0 -0
- data/public/{stylesheets → css}/base/images/ui-icons_cd0a0a_256x240.png +0 -0
- data/public/{stylesheets → css}/base/jquery.ui.accordion.css +0 -0
- data/public/{stylesheets → css}/base/jquery.ui.all.css +0 -0
- data/public/{stylesheets → css}/base/jquery.ui.autocomplete.css +0 -0
- data/public/{stylesheets → css}/base/jquery.ui.base.css +0 -0
- data/public/{stylesheets → css}/base/jquery.ui.button.css +0 -0
- data/public/{stylesheets → css}/base/jquery.ui.core.css +0 -0
- data/public/{stylesheets → css}/base/jquery.ui.datepicker.css +0 -0
- data/public/{stylesheets → css}/base/jquery.ui.dialog.css +0 -0
- data/public/{stylesheets → css}/base/jquery.ui.progressbar.css +0 -0
- data/public/{stylesheets → css}/base/jquery.ui.resizable.css +0 -0
- data/public/{stylesheets → css}/base/jquery.ui.selectable.css +0 -0
- data/public/{stylesheets → css}/base/jquery.ui.slider.css +0 -0
- data/public/{stylesheets → css}/base/jquery.ui.tabs.css +0 -0
- data/public/{stylesheets → css}/base/jquery.ui.theme.css +0 -0
- data/public/css/editor.css +25 -0
- data/public/css/jjmenu.css +33 -0
- data/public/css/menuitem.gif +0 -0
- data/public/css/more.gif +0 -0
- data/public/{stylesheets → css}/reset.css +1 -1
- data/public/css/smoothness/images/ui-anim_basic_16x16.gif +0 -0
- data/public/css/smoothness/images/ui-bg_flat_0_aaaaaa_40x100.png +0 -0
- data/public/css/smoothness/images/ui-bg_flat_75_ffffff_40x100.png +0 -0
- data/public/css/smoothness/images/ui-bg_glass_55_fbf9ee_1x400.png +0 -0
- data/public/css/smoothness/images/ui-bg_glass_65_ffffff_1x400.png +0 -0
- data/public/css/smoothness/images/ui-bg_glass_75_dadada_1x400.png +0 -0
- data/public/css/smoothness/images/ui-bg_glass_75_e6e6e6_1x400.png +0 -0
- data/public/css/smoothness/images/ui-bg_glass_95_fef1ec_1x400.png +0 -0
- data/public/css/smoothness/images/ui-bg_highlight-soft_75_cccccc_1x100.png +0 -0
- data/public/css/smoothness/images/ui-icons_222222_256x240.png +0 -0
- data/public/css/smoothness/images/ui-icons_2e83ff_256x240.png +0 -0
- data/public/css/smoothness/images/ui-icons_454545_256x240.png +0 -0
- data/public/css/smoothness/images/ui-icons_888888_256x240.png +0 -0
- data/public/css/smoothness/images/ui-icons_cd0a0a_256x240.png +0 -0
- data/public/css/smoothness/jquery-ui.css +489 -0
- data/public/css/ui-lightness/images/ui-anim_basic_16x16.gif +0 -0
- data/public/css/ui-lightness/images/ui-bg_diagonals-thick_18_b81900_40x40.png +0 -0
- data/public/css/ui-lightness/images/ui-bg_diagonals-thick_20_666666_40x40.png +0 -0
- data/public/css/ui-lightness/images/ui-bg_flat_10_000000_40x100.png +0 -0
- data/public/css/ui-lightness/images/ui-bg_glass_100_f6f6f6_1x400.png +0 -0
- data/public/css/ui-lightness/images/ui-bg_glass_100_fdf5ce_1x400.png +0 -0
- data/public/css/ui-lightness/images/ui-bg_glass_65_ffffff_1x400.png +0 -0
- data/public/css/ui-lightness/images/ui-bg_gloss-wave_35_f6a828_500x100.png +0 -0
- data/public/css/ui-lightness/images/ui-bg_highlight-soft_100_eeeeee_1x100.png +0 -0
- data/public/css/ui-lightness/images/ui-bg_highlight-soft_75_ffe45c_1x100.png +0 -0
- data/public/css/ui-lightness/images/ui-icons_222222_256x240.png +0 -0
- data/public/css/ui-lightness/images/ui-icons_228ef1_256x240.png +0 -0
- data/public/css/ui-lightness/images/ui-icons_ef8c08_256x240.png +0 -0
- data/public/css/ui-lightness/images/ui-icons_ffd27a_256x240.png +0 -0
- data/public/css/ui-lightness/images/ui-icons_ffffff_256x240.png +0 -0
- data/public/css/ui-lightness/jquery-ui.css +489 -0
- data/public/css/webtools.css +65 -0
- data/public/favicon.ico +0 -0
- data/public/flot/API.txt +1201 -0
- data/public/flot/FAQ.txt +76 -0
- data/public/flot/LICENSE.txt +22 -0
- data/public/flot/Makefile +9 -0
- data/public/flot/NEWS.txt +508 -0
- data/public/flot/PLUGINS.txt +137 -0
- data/public/flot/README.txt +90 -0
- data/public/flot/examples/ajax.html +143 -0
- data/public/flot/examples/annotating.html +75 -0
- data/public/flot/examples/arrow-down.gif +0 -0
- data/public/flot/examples/arrow-left.gif +0 -0
- data/public/flot/examples/arrow-right.gif +0 -0
- data/public/flot/examples/arrow-up.gif +0 -0
- data/public/flot/examples/basic.html +38 -0
- data/public/flot/examples/data-eu-gdp-growth-1.json +4 -0
- data/public/flot/examples/data-eu-gdp-growth-2.json +4 -0
- data/public/flot/examples/data-eu-gdp-growth-3.json +4 -0
- data/public/flot/examples/data-eu-gdp-growth-4.json +4 -0
- data/public/flot/examples/data-eu-gdp-growth-5.json +4 -0
- data/public/flot/examples/data-eu-gdp-growth.json +4 -0
- data/public/flot/examples/data-japan-gdp-growth.json +4 -0
- data/public/flot/examples/data-usa-gdp-growth.json +4 -0
- data/public/flot/examples/graph-types.html +75 -0
- data/public/flot/examples/hs-2004-27-a-large_web.jpg +0 -0
- data/public/flot/examples/image.html +45 -0
- data/public/flot/examples/index.html +44 -0
- data/public/flot/examples/interacting-axes.html +97 -0
- data/public/flot/examples/interacting.html +93 -0
- data/public/flot/examples/layout.css +6 -0
- data/public/flot/examples/multiple-axes.html +60 -0
- data/public/flot/examples/navigate.html +118 -0
- data/public/flot/examples/percentiles.html +57 -0
- data/public/flot/examples/pie.html +756 -0
- data/public/flot/examples/realtime.html +83 -0
- data/public/flot/examples/resize.html +61 -0
- data/public/flot/examples/selection.html +114 -0
- data/public/flot/examples/setting-options.html +61 -0
- data/public/flot/examples/stacking.html +77 -0
- data/public/flot/examples/symbols.html +49 -0
- data/public/flot/examples/thresholding.html +54 -0
- data/public/flot/examples/time.html +71 -0
- data/public/flot/examples/tracking.html +95 -0
- data/public/flot/examples/turning-series.html +98 -0
- data/public/flot/examples/visitors.html +90 -0
- data/public/flot/examples/zooming.html +98 -0
- data/public/flot/excanvas.js +1427 -0
- data/public/flot/excanvas.min.js +1 -0
- data/public/flot/jquery.colorhelpers.js +179 -0
- data/public/flot/jquery.colorhelpers.min.js +1 -0
- data/public/flot/jquery.flot.crosshair.js +167 -0
- data/public/flot/jquery.flot.crosshair.min.js +1 -0
- data/public/flot/jquery.flot.fillbetween.js +183 -0
- data/public/flot/jquery.flot.fillbetween.min.js +1 -0
- data/public/flot/jquery.flot.image.js +238 -0
- data/public/flot/jquery.flot.image.min.js +1 -0
- data/public/flot/jquery.flot.js +2599 -0
- data/public/flot/jquery.flot.min.js +6 -0
- data/public/flot/jquery.flot.navigate.js +336 -0
- data/public/flot/jquery.flot.navigate.min.js +1 -0
- data/public/flot/jquery.flot.pie.js +750 -0
- data/public/flot/jquery.flot.pie.min.js +1 -0
- data/public/flot/jquery.flot.resize.js +60 -0
- data/public/flot/jquery.flot.resize.min.js +1 -0
- data/public/flot/jquery.flot.selection.js +344 -0
- data/public/flot/jquery.flot.selection.min.js +1 -0
- data/public/flot/jquery.flot.stack.js +184 -0
- data/public/flot/jquery.flot.stack.min.js +1 -0
- data/public/flot/jquery.flot.symbol.js +70 -0
- data/public/flot/jquery.flot.symbol.min.js +1 -0
- data/public/flot/jquery.flot.threshold.js +103 -0
- data/public/flot/jquery.flot.threshold.min.js +1 -0
- data/public/flot/jquery.js +8316 -0
- data/public/flot/jquery.min.js +23 -0
- data/public/genPacking.pl +30 -0
- data/public/index.html +28 -0
- data/public/install.tpz +66 -0
- data/public/installAndRun.tpz +5 -0
- data/public/jsTree/jquery.jstree.js +3510 -0
- data/public/jsTree/themes/default/d.gif +0 -0
- data/public/jsTree/themes/default/d.png +0 -0
- data/public/jsTree/themes/default/style.css +73 -0
- data/public/jsTree/themes/default/throbber.gif +0 -0
- data/public/readMe.txt +9 -0
- data/public/scripts/CodeBrowser.js +645 -0
- data/public/scripts/Debugger.js +134 -0
- data/public/scripts/MethodList.js +72 -0
- data/public/scripts/ObjectLog.js +59 -0
- data/public/scripts/SessionList.js +164 -0
- data/public/scripts/Statistics.js +266 -0
- data/public/scripts/editor.js +430 -0
- data/public/scripts/jjmenu.js +375 -0
- data/public/scripts/jquery-ui.js +1012 -0
- data/public/scripts/jquery.js +154 -0
- data/public/scripts/webtools.js +374 -0
- data/public/src/CodeBrowser.gs +416 -0
- data/public/src/Debugger.gs +132 -0
- data/public/src/MethodList.gs +130 -0
- data/public/src/ObjectLog.gs +73 -0
- data/public/src/Server.gs +544 -0
- data/public/src/SessionList.gs +172 -0
- data/public/src/SharedPageCache.gs +66 -0
- data/public/src/StatProcess.gs +280 -0
- data/public/src/StatProcessType.gs +242 -0
- data/public/src/StatStatistic.gs +381 -0
- data/public/src/Statistics.gs +222 -0
- data/public/src/Statmonitor.gs +490 -0
- data/public/src/Tool.gs +86 -0
- data/public/src/VersionReport.gs +52 -0
- data/public/src/Workspace.gs +163 -0
- data/views/debugger.rhtml +6 -9
- metadata +344 -243
- data/lib/web_tools/#debugger.rb# +0 -212
- data/lib/web_tools/browser.rb +0 -45
- data/public/images/favicon.ico +0 -0
- data/public/javascript/CodeMirror/LICENSE +0 -23
- data/public/javascript/CodeMirror/css/Smalltalk.css +0 -34
- data/public/javascript/CodeMirror/js/codemirror.js +0 -582
- data/public/javascript/CodeMirror/js/editor.js +0 -1671
- data/public/javascript/CodeMirror/js/highlight.js +0 -68
- data/public/javascript/CodeMirror/js/parseSmalltalk.js +0 -126
- data/public/javascript/CodeMirror/js/parsedummy.js +0 -32
- data/public/javascript/CodeMirror/js/select.js +0 -699
- data/public/javascript/CodeMirror/js/stringstream.js +0 -159
- data/public/javascript/CodeMirror/js/tokenize.js +0 -57
- data/public/javascript/CodeMirror/js/undo.js +0 -413
- data/public/javascript/CodeMirror/js/util.js +0 -133
- data/public/javascript/CodeMirror/testSmalltalkParser.html +0 -116
- data/public/javascript/ace/ace-uncompressed.js +0 -17299
- data/public/javascript/ace/ace.js +0 -1
- data/public/javascript/ace/keybinding-emacs.js +0 -1
- data/public/javascript/ace/keybinding-vim.js +0 -1
- data/public/javascript/ace/mode-c_cpp.js +0 -1
- data/public/javascript/ace/mode-clojure.js +0 -1
- data/public/javascript/ace/mode-coffee.js +0 -1
- data/public/javascript/ace/mode-csharp.js +0 -1
- data/public/javascript/ace/mode-css.js +0 -1
- data/public/javascript/ace/mode-groovy.js +0 -1
- data/public/javascript/ace/mode-html.js +0 -1
- data/public/javascript/ace/mode-java.js +0 -1
- data/public/javascript/ace/mode-javascript.js +0 -1
- data/public/javascript/ace/mode-json.js +0 -1
- data/public/javascript/ace/mode-lua.js +0 -1
- data/public/javascript/ace/mode-markdown.js +0 -1
- data/public/javascript/ace/mode-ocaml.js +0 -1
- data/public/javascript/ace/mode-perl.js +0 -1
- data/public/javascript/ace/mode-php.js +0 -1
- data/public/javascript/ace/mode-python.js +0 -1
- data/public/javascript/ace/mode-ruby.js +0 -1
- data/public/javascript/ace/mode-scad.js +0 -1
- data/public/javascript/ace/mode-scala.js +0 -1
- data/public/javascript/ace/mode-scss.js +0 -1
- data/public/javascript/ace/mode-svg.js +0 -1
- data/public/javascript/ace/mode-textile.js +0 -1
- data/public/javascript/ace/mode-xml.js +0 -1
- data/public/javascript/ace/theme-clouds.js +0 -1
- data/public/javascript/ace/theme-clouds_midnight.js +0 -1
- data/public/javascript/ace/theme-cobalt.js +0 -1
- data/public/javascript/ace/theme-crimson_editor.js +0 -1
- data/public/javascript/ace/theme-dawn.js +0 -1
- data/public/javascript/ace/theme-eclipse.js +0 -1
- data/public/javascript/ace/theme-idle_fingers.js +0 -1
- data/public/javascript/ace/theme-kr_theme.js +0 -1
- data/public/javascript/ace/theme-merbivore.js +0 -1
- data/public/javascript/ace/theme-merbivore_soft.js +0 -1
- data/public/javascript/ace/theme-mono_industrial.js +0 -1
- data/public/javascript/ace/theme-monokai.js +0 -1
- data/public/javascript/ace/theme-pastel_on_dark.js +0 -1
- data/public/javascript/ace/theme-solarized_dark.js +0 -1
- data/public/javascript/ace/theme-solarized_light.js +0 -1
- data/public/javascript/ace/theme-textmate.js +0 -1
- data/public/javascript/ace/theme-twilight.js +0 -1
- data/public/javascript/ace/theme-vibrant_ink.js +0 -1
- data/public/javascript/ace/worker-coffee.js +0 -1
- data/public/javascript/ace/worker-css.js +0 -1
- data/public/javascript/ace/worker-javascript.js +0 -1
- data/public/javascript/webtools/browser.js +0 -260
- data/public/javascript/webtools/debugger.coffee +0 -286
- data/public/javascript/webtools/debugger.js +0 -366
- data/public/javascript/webtools/sessions.coffee +0 -17
- data/public/javascript/webtools/sessions.js +0 -27
- data/public/javascript/webtools/version.coffee +0 -14
- data/public/javascript/webtools/version.js +0 -20
- data/public/stylesheets/jquery.contextMenu.css +0 -62
- data/public/stylesheets/webtools.css +0 -53
- data/public/test.html +0 -47
@@ -0,0 +1,130 @@
|
|
1
|
+
doit
|
2
|
+
Tool subclass: 'MethodList'
|
3
|
+
instVarNames: #()
|
4
|
+
classVars: #()
|
5
|
+
classInstVars: #()
|
6
|
+
poolDictionaries: #()
|
7
|
+
inDictionary: WebTools
|
8
|
+
options: #()
|
9
|
+
|
10
|
+
%
|
11
|
+
|
12
|
+
! Remove existing behavior from MethodList
|
13
|
+
doit
|
14
|
+
MethodList removeAllMethods.
|
15
|
+
MethodList class removeAllMethods.
|
16
|
+
%
|
17
|
+
! ------------------- Class methods for MethodList
|
18
|
+
! ------------------- Instance methods for MethodList
|
19
|
+
category: 'Public'
|
20
|
+
set compile_env: 0
|
21
|
+
method: MethodList
|
22
|
+
json
|
23
|
+
|
24
|
+
| type |
|
25
|
+
type := arguments at: 'type'.
|
26
|
+
type = 'method' ifTrue: [^self _method].
|
27
|
+
type = 'implementors' ifTrue: [^self _implementors].
|
28
|
+
type = 'senders' ifTrue: [^self _senders].
|
29
|
+
type = 'referencesToGlobal' ifTrue: [^self _referencesToGlobal].
|
30
|
+
^Dictionary new
|
31
|
+
at: 'a' put: 'AAA';
|
32
|
+
yourself.
|
33
|
+
%
|
34
|
+
category: 'Public'
|
35
|
+
set compile_env: 0
|
36
|
+
method: MethodList
|
37
|
+
_implementors
|
38
|
+
|
39
|
+
| name list |
|
40
|
+
name := arguments at: 'find' ifAbsent: [^Dictionary new].
|
41
|
+
list := ClassOrganizer new implementorsOf: name asSymbol.
|
42
|
+
^self _methods: list.
|
43
|
+
%
|
44
|
+
category: 'Public'
|
45
|
+
set compile_env: 0
|
46
|
+
method: MethodList
|
47
|
+
_method
|
48
|
+
|
49
|
+
| symbolList name dictionary isMeta class method |
|
50
|
+
symbolList := System myUserProfile symbolList.
|
51
|
+
name := (arguments at: 'dict') asSymbol.
|
52
|
+
dictionary := symbolList
|
53
|
+
detect: [:each | each name = name]
|
54
|
+
ifNone: [^Dictionary new].
|
55
|
+
name := arguments at: 'klass'.
|
56
|
+
(isMeta := name includesString: ' class') ifTrue: [
|
57
|
+
name := name copyFrom: 1 to: name size - 6.
|
58
|
+
].
|
59
|
+
name := name asSymbol.
|
60
|
+
class := dictionary
|
61
|
+
at: name
|
62
|
+
ifAbsent: [^Dictionary new].
|
63
|
+
isMeta ifTrue: [class := class class].
|
64
|
+
method := class compiledMethodAt: (arguments at: 'selector') asSymbol.
|
65
|
+
^Dictionary new
|
66
|
+
at: 'dictionaryName' put: dictionary name;
|
67
|
+
at: 'className' put: class thisClass name;
|
68
|
+
at: 'isMeta' put: class isMeta;
|
69
|
+
at: 'source' put: method sourceString;
|
70
|
+
at: 'stepPoints' put: method _sourceOffsets;
|
71
|
+
at: 'sends' put: method _sourceOffsetsOfSends;
|
72
|
+
yourself.
|
73
|
+
%
|
74
|
+
category: 'Public'
|
75
|
+
set compile_env: 0
|
76
|
+
method: MethodList
|
77
|
+
_methods: aList
|
78
|
+
|
79
|
+
| symbolList list |
|
80
|
+
symbolList := System myUserProfile symbolList.
|
81
|
+
list := aList collect: [:each |
|
82
|
+
| array dict klass |
|
83
|
+
klass := each inClass.
|
84
|
+
array := symbolList dictionaryAndSymbolOf: klass thisClass.
|
85
|
+
dict := array isNil
|
86
|
+
ifTrue: [nil]
|
87
|
+
ifFalse: [array first name].
|
88
|
+
Dictionary new
|
89
|
+
at: 'dict' put: dict;
|
90
|
+
at: 'klassCat' put: klass category;
|
91
|
+
at: 'klass' put: klass name;
|
92
|
+
at: 'category' put: (klass categoryOfSelector: each selector);
|
93
|
+
at: 'selector' put: each selector;
|
94
|
+
yourself.
|
95
|
+
].
|
96
|
+
^Dictionary new
|
97
|
+
at: 'list' put: list;
|
98
|
+
yourself.
|
99
|
+
%
|
100
|
+
category: 'Public'
|
101
|
+
set compile_env: 0
|
102
|
+
method: MethodList
|
103
|
+
_referencesToGlobal
|
104
|
+
|
105
|
+
| symbolList name dictionary global list |
|
106
|
+
symbolList := System myUserProfile symbolList.
|
107
|
+
name := (arguments at: 'dict') asSymbol.
|
108
|
+
dictionary := symbolList
|
109
|
+
detect: [:each | each name = name]
|
110
|
+
ifNone: [^Dictionary new].
|
111
|
+
name := (arguments at: 'find') asSymbol.
|
112
|
+
global := dictionary
|
113
|
+
at: name
|
114
|
+
ifAbsent: [^Dictionary new].
|
115
|
+
list := ClassOrganizer new referencesToObject: global.
|
116
|
+
^self _methods: list.
|
117
|
+
%
|
118
|
+
category: 'Public'
|
119
|
+
set compile_env: 0
|
120
|
+
method: MethodList
|
121
|
+
_senders
|
122
|
+
|
123
|
+
| name list |
|
124
|
+
name := arguments at: 'find' ifAbsent: [^Dictionary new].
|
125
|
+
list := ClassOrganizer new sendersOf: name asSymbol.
|
126
|
+
^self _methods: list first.
|
127
|
+
%
|
128
|
+
doit
|
129
|
+
MethodList category: 'WebTools'
|
130
|
+
%
|
@@ -0,0 +1,73 @@
|
|
1
|
+
doit
|
2
|
+
Tool subclass: 'ObjectLog'
|
3
|
+
instVarNames: #()
|
4
|
+
classVars: #()
|
5
|
+
classInstVars: #()
|
6
|
+
poolDictionaries: #()
|
7
|
+
inDictionary: WebTools
|
8
|
+
options: #()
|
9
|
+
|
10
|
+
%
|
11
|
+
|
12
|
+
! Remove existing behavior from ObjectLog
|
13
|
+
doit
|
14
|
+
ObjectLog removeAllMethods.
|
15
|
+
ObjectLog class removeAllMethods.
|
16
|
+
%
|
17
|
+
! ------------------- Class methods for ObjectLog
|
18
|
+
category: 'other'
|
19
|
+
set compile_env: 0
|
20
|
+
classmethod: ObjectLog
|
21
|
+
description
|
22
|
+
|
23
|
+
^'Object Log'.
|
24
|
+
%
|
25
|
+
category: 'other'
|
26
|
+
set compile_env: 0
|
27
|
+
classmethod: ObjectLog
|
28
|
+
displayName
|
29
|
+
|
30
|
+
^'Object Log'.
|
31
|
+
%
|
32
|
+
category: 'other'
|
33
|
+
set compile_env: 0
|
34
|
+
classmethod: ObjectLog
|
35
|
+
sortOrder
|
36
|
+
|
37
|
+
^6.
|
38
|
+
%
|
39
|
+
! ------------------- Instance methods for ObjectLog
|
40
|
+
category: 'Public'
|
41
|
+
set compile_env: 0
|
42
|
+
method: ObjectLog
|
43
|
+
json
|
44
|
+
|
45
|
+
| objectLogEntryClass list |
|
46
|
+
objectLogEntryClass := System myUserProfile symbolList objectNamed: #'ObjectLogEntry'.
|
47
|
+
objectLogEntryClass isNil ifTrue: [^Dictionary new].
|
48
|
+
list := objectLogEntryClass objectLog reverse collect: [:each |
|
49
|
+
| label objectString |
|
50
|
+
label := each label.
|
51
|
+
label isNil ifTrue: [label := ''].
|
52
|
+
(label isKindOf: String) ifFalse: [label := label printString].
|
53
|
+
(label first = $' and: [label last = $']) ifTrue: [label := label copyFrom: 2 to: label size - 1].
|
54
|
+
objectString := each objectString.
|
55
|
+
label = objectString ifTrue: [label := label subStrings first].
|
56
|
+
Dictionary new
|
57
|
+
at: 'oop' put: each asOop;
|
58
|
+
at: 'stamp' put: each stampString;
|
59
|
+
at: 'pid' put: each pidString;
|
60
|
+
at: 'label' put: label;
|
61
|
+
at: 'type' put: (#('Fatal' 'Error' 'Warn' 'Info' 'Debug' 'Trace' 'Transcript') at: each priority);
|
62
|
+
at: 'tag' put: (each hasTag ifTrue: [each tag] ifFalse: ['']);
|
63
|
+
at: 'object' put: objectString;
|
64
|
+
at: 'hasContinuation' put: each hasContinuation;
|
65
|
+
yourself.
|
66
|
+
].
|
67
|
+
^Dictionary new
|
68
|
+
at: 'list' put: list;
|
69
|
+
yourself.
|
70
|
+
%
|
71
|
+
doit
|
72
|
+
ObjectLog category: 'WebTools'
|
73
|
+
%
|
@@ -0,0 +1,544 @@
|
|
1
|
+
doit
|
2
|
+
Object subclass: 'Server'
|
3
|
+
instVarNames: #( server socket resultCode
|
4
|
+
httpHeaders stream startTime)
|
5
|
+
classVars: #()
|
6
|
+
classInstVars: #()
|
7
|
+
poolDictionaries: #()
|
8
|
+
inDictionary: WebTools
|
9
|
+
options: #()
|
10
|
+
|
11
|
+
%
|
12
|
+
|
13
|
+
! Remove existing behavior from Server
|
14
|
+
doit
|
15
|
+
Server removeAllMethods.
|
16
|
+
Server class removeAllMethods.
|
17
|
+
%
|
18
|
+
! ------------------- Class methods for Server
|
19
|
+
category: 'other'
|
20
|
+
set compile_env: 0
|
21
|
+
classmethod: Server
|
22
|
+
run
|
23
|
+
"
|
24
|
+
Server run.
|
25
|
+
"
|
26
|
+
self startServerAtPort: 8080.
|
27
|
+
%
|
28
|
+
category: 'other'
|
29
|
+
set compile_env: 0
|
30
|
+
classmethod: Server
|
31
|
+
runInForeground
|
32
|
+
"
|
33
|
+
Server runInForeground.
|
34
|
+
"
|
35
|
+
self new startForegroundServerAtPort: 8080.
|
36
|
+
%
|
37
|
+
category: 'other'
|
38
|
+
set compile_env: 0
|
39
|
+
classmethod: Server
|
40
|
+
startServerAtPort: anInteger
|
41
|
+
"
|
42
|
+
If anInteger is nil then assign a random port.
|
43
|
+
Server startServerAtPort: 8080.
|
44
|
+
"
|
45
|
+
| delay |
|
46
|
+
delay := Delay forSeconds: 5.
|
47
|
+
GsFile stdout nextPutAll: (self new startServerAtPort: anInteger); cr; flush.
|
48
|
+
[System commitTransaction] whileTrue: [delay wait].
|
49
|
+
%
|
50
|
+
! ------------------- Instance methods for Server
|
51
|
+
category: 'Request Handler'
|
52
|
+
set compile_env: 0
|
53
|
+
method: Server
|
54
|
+
beNoCache
|
55
|
+
|
56
|
+
httpHeaders
|
57
|
+
at: 'Cache-Control'
|
58
|
+
put: 'no-cache'.
|
59
|
+
|
60
|
+
%
|
61
|
+
category: 'Request Handler'
|
62
|
+
set compile_env: 0
|
63
|
+
method: Server
|
64
|
+
contentType: aString
|
65
|
+
|
66
|
+
httpHeaders
|
67
|
+
at: 'Content-Type'
|
68
|
+
put: aString.
|
69
|
+
|
70
|
+
%
|
71
|
+
category: 'Request Handler'
|
72
|
+
set compile_env: 0
|
73
|
+
method: Server
|
74
|
+
contentTypes
|
75
|
+
|
76
|
+
^KeyValueDictionary new
|
77
|
+
at: 'css' put: 'text/css';
|
78
|
+
at: 'gif' put: 'image/gif';
|
79
|
+
at: 'html' put: 'text/html; charset=UTF-8';
|
80
|
+
at: 'ico' put: 'image/x-icon';
|
81
|
+
at: 'js' put: 'text/javascript';
|
82
|
+
at: 'png' put: 'image/png';
|
83
|
+
at: 'json' put: 'text/json';
|
84
|
+
yourself.
|
85
|
+
%
|
86
|
+
category: 'Request Handler'
|
87
|
+
set compile_env: 0
|
88
|
+
method: Server
|
89
|
+
doAnswer
|
90
|
+
|
91
|
+
| string |
|
92
|
+
string := stream contents.
|
93
|
+
stream := (WriteStream on: String new)
|
94
|
+
nextPutAll: 'HTTP/1.1 ';
|
95
|
+
nextPutAll: resultCode printString; space;
|
96
|
+
nextPutAll: self reasonPhrase; lf;
|
97
|
+
yourself.
|
98
|
+
httpHeaders
|
99
|
+
at: 'Content-Length'
|
100
|
+
put: string size printString.
|
101
|
+
httpHeaders keys asSortedCollection do: [:each |
|
102
|
+
stream
|
103
|
+
nextPutAll: each;
|
104
|
+
nextPutAll: ': ';
|
105
|
+
nextPutAll: (httpHeaders at: each);
|
106
|
+
lf.
|
107
|
+
].
|
108
|
+
stream
|
109
|
+
lf;
|
110
|
+
nextPutAll: string; lf;
|
111
|
+
yourself.
|
112
|
+
socket writeWillNotBlock ifFalse: [self error: 'socket write will block'].
|
113
|
+
string := stream contents.
|
114
|
+
1 to: string size by: 10000 do: [:i |
|
115
|
+
| chunk numWritten |
|
116
|
+
chunk := string copyFrom: i to: (i + 9999 min: string size).
|
117
|
+
numWritten := socket write: chunk.
|
118
|
+
numWritten == chunk size ifFalse: [
|
119
|
+
socket close.
|
120
|
+
string := 'Tried to write ' , string size printString , ', but wrote ' , numWritten printString.
|
121
|
+
GsFile stdout nextPutAll: string.
|
122
|
+
self error: string.
|
123
|
+
^self.
|
124
|
+
].
|
125
|
+
].
|
126
|
+
socket close.
|
127
|
+
%
|
128
|
+
category: 'Request Handler'
|
129
|
+
set compile_env: 0
|
130
|
+
method: Server
|
131
|
+
encode: aString
|
132
|
+
|
133
|
+
| readStream writeStream |
|
134
|
+
readStream := ReadStream on: aString.
|
135
|
+
writeStream := WriteStream on: String new.
|
136
|
+
[
|
137
|
+
readStream atEnd not.
|
138
|
+
] whileTrue: [
|
139
|
+
| next index |
|
140
|
+
next := readStream next.
|
141
|
+
index := #($" $& $' $< $>) indexOf: next.
|
142
|
+
0 < index ifTrue: [
|
143
|
+
writeStream nextPutAll: (#('"' '&' ''' '<' '>') at: index).
|
144
|
+
] ifFalse: [
|
145
|
+
writeStream nextPut: next.
|
146
|
+
].
|
147
|
+
].
|
148
|
+
^writeStream contents.
|
149
|
+
|
150
|
+
%
|
151
|
+
category: 'Request Handler'
|
152
|
+
set compile_env: 0
|
153
|
+
method: Server
|
154
|
+
errorExpectedGetOrPost
|
155
|
+
|
156
|
+
resultCode := 404.
|
157
|
+
self htmlWithBody: 'Expected a GET or POST request!'.
|
158
|
+
|
159
|
+
|
160
|
+
%
|
161
|
+
category: 'Request Handler'
|
162
|
+
set compile_env: 0
|
163
|
+
method: Server
|
164
|
+
errorExpectedHTTP11
|
165
|
+
|
166
|
+
resultCode := 426.
|
167
|
+
self htmlWithBody: 'Expected HTTP/1.1 support!'.
|
168
|
+
|
169
|
+
%
|
170
|
+
category: 'Request Handler'
|
171
|
+
set compile_env: 0
|
172
|
+
method: Server
|
173
|
+
errorNotFound: aString
|
174
|
+
|
175
|
+
resultCode := 404.
|
176
|
+
self htmlWithBody: aString printString , ' not Found!'.
|
177
|
+
|
178
|
+
%
|
179
|
+
category: 'Request Handler'
|
180
|
+
set compile_env: 0
|
181
|
+
method: Server
|
182
|
+
handleRequest
|
183
|
+
"Called on a copy of the instance accepting connections"
|
184
|
+
| readStream type string line headers contentLength path args selector class pieces gsFile |
|
185
|
+
readStream := ReadStream on: (socket readString: 1000).
|
186
|
+
type := readStream upTo: Character space.
|
187
|
+
(type = 'GET' or: [type = 'POST']) ifFalse: [^self errorExpectedGetOrPost].
|
188
|
+
path := readStream upTo: Character space.
|
189
|
+
string := readStream upTo: Character cr.
|
190
|
+
readStream peekFor: Character lf.
|
191
|
+
string = 'HTTP/1.1' ifFalse: [^self errorExpectedHTTP11].
|
192
|
+
headers := Dictionary new.
|
193
|
+
[
|
194
|
+
line := readStream upTo: Character cr.
|
195
|
+
readStream peekFor: Character lf.
|
196
|
+
line notEmpty.
|
197
|
+
] whileTrue: [
|
198
|
+
| index |
|
199
|
+
index := line indexOf: $:.
|
200
|
+
headers
|
201
|
+
at: (line copyFrom: 1 to: index - 1)
|
202
|
+
put: (line copyFrom: index + 1 to: line size) trimBlanks.
|
203
|
+
].
|
204
|
+
(contentLength := headers at: 'Content-Length' ifAbsent: [nil]) notNil ifTrue: [
|
205
|
+
contentLength := contentLength asNumber.
|
206
|
+
string := readStream upToEnd.
|
207
|
+
100 timesRepeat: [
|
208
|
+
string size < contentLength ifTrue: [
|
209
|
+
string addAll: (socket readString: 10000).
|
210
|
+
string size < contentLength ifTrue: [
|
211
|
+
(Delay forMilliseconds: 10) wait.
|
212
|
+
].
|
213
|
+
].
|
214
|
+
].
|
215
|
+
].
|
216
|
+
type = 'GET' ifTrue: [
|
217
|
+
pieces := path subStrings: $?.
|
218
|
+
path := pieces at: 1.
|
219
|
+
string := 1 < pieces size
|
220
|
+
ifTrue: [pieces at: 2]
|
221
|
+
ifFalse: [''].
|
222
|
+
].
|
223
|
+
args := Dictionary new.
|
224
|
+
(string subStrings: $&) do: [:each |
|
225
|
+
| index |
|
226
|
+
index := each indexOf: $=.
|
227
|
+
args
|
228
|
+
at: (each copyFrom: 1 to: index - 1)
|
229
|
+
put: (self translate: (each copyFrom: index + 1 to: each size)).
|
230
|
+
].
|
231
|
+
path = '/' ifTrue: [path := '/index.html'].
|
232
|
+
pieces := path subStrings: $/.
|
233
|
+
selector := (pieces at: 2) asSymbol.
|
234
|
+
(self class canUnderstand: selector) ifTrue: [
|
235
|
+
^self returnJSON: [self perform: selector].
|
236
|
+
].
|
237
|
+
class := WebTools at: selector ifAbsent: [nil].
|
238
|
+
class notNil ifTrue: [
|
239
|
+
^self returnJSON: [
|
240
|
+
selector := 3 = pieces size
|
241
|
+
ifTrue: [(pieces at: 3) asSymbol]
|
242
|
+
ifFalse: [#'json'].
|
243
|
+
(class arguments: args) perform: selector.
|
244
|
+
].
|
245
|
+
].
|
246
|
+
|
247
|
+
(gsFile := GsFile openReadOnServer: '$GEMSTONE/examples/www' , path) notNil ifTrue: [
|
248
|
+
| type |
|
249
|
+
type := (path subStrings: $.) last.
|
250
|
+
stream nextPutAll: gsFile contents.
|
251
|
+
gsFile close.
|
252
|
+
resultCode := 200.
|
253
|
+
self contentType: (self contentTypes at: type ifAbsent: ['text/html; UTF-8']).
|
254
|
+
self doAnswer.
|
255
|
+
^self.
|
256
|
+
].
|
257
|
+
self errorNotFound: path.
|
258
|
+
%
|
259
|
+
category: 'Request Handler'
|
260
|
+
set compile_env: 0
|
261
|
+
method: Server
|
262
|
+
handleRequestOn: aSocket
|
263
|
+
"Called on a *copy* of the instance accepting connections
|
264
|
+
so we can keep local stuff in instance variables and handle
|
265
|
+
requests in parallel."
|
266
|
+
|
267
|
+
startTime := Time millisecondClockValue.
|
268
|
+
System commitTransaction.
|
269
|
+
server := nil.
|
270
|
+
socket := aSocket.
|
271
|
+
resultCode := nil.
|
272
|
+
stream := WriteStream on: String new.
|
273
|
+
self
|
274
|
+
initializeHeaders;
|
275
|
+
handleRequest;
|
276
|
+
yourself.
|
277
|
+
System commitTransaction.
|
278
|
+
%
|
279
|
+
category: 'Request Handler'
|
280
|
+
set compile_env: 0
|
281
|
+
method: Server
|
282
|
+
htmlForError: ex
|
283
|
+
|
284
|
+
| description |
|
285
|
+
((description := ex description) isKindOf: String) ifFalse: [description := description printString].
|
286
|
+
stream := WriteStream on: String new.
|
287
|
+
stream nextPutAll: '<h3>' , description , '</h3>'.
|
288
|
+
((GsProcess stackReportToLevel: 100) subStrings: Character lf) do: [:each |
|
289
|
+
stream nextPutAll: each , '<br />'.
|
290
|
+
].
|
291
|
+
^stream contents.
|
292
|
+
|
293
|
+
%
|
294
|
+
category: 'Request Handler'
|
295
|
+
set compile_env: 0
|
296
|
+
method: Server
|
297
|
+
htmlWithBody: aString
|
298
|
+
|
299
|
+
stream nextPutAll:
|
300
|
+
'<!DOCTYPE html PUBLIC ''-//W3C//DTD XHTML 1.0 Strict//EN'' ''http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd''>
|
301
|
+
<html xmlns=''http://www.w3.org/1999/xhtml'' xml:lang=''en'' lang=''en''>
|
302
|
+
<head><title>GemStone/S Web Tools</title></head>
|
303
|
+
<body>' , aString , '</body></html>'.
|
304
|
+
self doAnswer.
|
305
|
+
|
306
|
+
%
|
307
|
+
category: 'Request Handler'
|
308
|
+
set compile_env: 0
|
309
|
+
method: Server
|
310
|
+
initializeHeaders
|
311
|
+
|
312
|
+
| dateTime dateString |
|
313
|
+
dateTime := DateTime now.
|
314
|
+
dateString := (WriteStream on: String new)
|
315
|
+
nextPutAll: (#('Sun' 'Mon' 'Tue' 'Wed' 'Thu' 'Fri' 'Sat') at: dateTime dayOfWeekGmt); space;
|
316
|
+
nextPutAll: (dateTime asStringGmtUsingFormat: #(1 2 3 $ 2 1 $: true true false false));
|
317
|
+
nextPutAll: ' GMT';
|
318
|
+
contents.
|
319
|
+
httpHeaders := Dictionary new
|
320
|
+
at: 'Accept-Ranges' put: 'bytes';
|
321
|
+
at: 'Allow' put: 'GET';
|
322
|
+
at: 'Cache-Control' put: 'max-age=0'; "86400';"
|
323
|
+
at: 'Content-Encoding' put: 'none';
|
324
|
+
at: 'Content-Language' put: 'en';
|
325
|
+
at: 'Content-Type' put: 'text/html; charset=utf-8';
|
326
|
+
at: 'Date' put: dateString;
|
327
|
+
at: 'Server' put: 'GemStone/S 64 Bit Server';
|
328
|
+
yourself.
|
329
|
+
%
|
330
|
+
category: 'Request Handler'
|
331
|
+
set compile_env: 0
|
332
|
+
method: Server
|
333
|
+
parseFileAndArgumentsFrom: aString lines: anArray
|
334
|
+
|
335
|
+
| list file args |
|
336
|
+
args := Dictionary new.
|
337
|
+
list := aString subStrings: $?.
|
338
|
+
file := list at: 1.
|
339
|
+
2 <= list size ifTrue: [
|
340
|
+
list := (list at: 2) subStrings: $&.
|
341
|
+
list := list collect: [:each | each subStrings: $=].
|
342
|
+
list do: [:each |
|
343
|
+
args
|
344
|
+
at: each first
|
345
|
+
put: (self translate: each last).
|
346
|
+
].
|
347
|
+
].
|
348
|
+
^file -> args.
|
349
|
+
%
|
350
|
+
category: 'Request Handler'
|
351
|
+
set compile_env: 0
|
352
|
+
method: Server
|
353
|
+
parseHeadersFrom: anArray
|
354
|
+
|
355
|
+
| dict |
|
356
|
+
dict := Dictionary new.
|
357
|
+
anArray do: [:each |
|
358
|
+
| index |
|
359
|
+
index := each indexOf: $:.
|
360
|
+
dict
|
361
|
+
at: (each copyFrom: 1 to: index - 1)
|
362
|
+
put: (each copyFrom: index + 2 to: each size).
|
363
|
+
].
|
364
|
+
^dict.
|
365
|
+
%
|
366
|
+
category: 'Request Handler'
|
367
|
+
set compile_env: 0
|
368
|
+
method: Server
|
369
|
+
reasonPhrase
|
370
|
+
|
371
|
+
^(Dictionary new
|
372
|
+
at: 200 put: 'OK';
|
373
|
+
at: 404 put: 'Not Found';
|
374
|
+
at: 405 put: 'Method Not Allowed';
|
375
|
+
at: 426 put: 'Upgrade Required';
|
376
|
+
yourself)
|
377
|
+
at: resultCode
|
378
|
+
ifAbsent: ['Unknown Error'].
|
379
|
+
|
380
|
+
%
|
381
|
+
category: 'Request Handler'
|
382
|
+
set compile_env: 0
|
383
|
+
method: Server
|
384
|
+
returnJSON: aBlock
|
385
|
+
|
386
|
+
[
|
387
|
+
| data |
|
388
|
+
resultCode := 200.
|
389
|
+
self contentType: 'text/json; charset=UTF-8'.
|
390
|
+
self beNoCache.
|
391
|
+
data := [
|
392
|
+
aBlock value.
|
393
|
+
] on: Error , Admonition do: [:ex |
|
394
|
+
ex return: (Dictionary new
|
395
|
+
at: '_error' put: ex description;
|
396
|
+
at: '_stack' put: (GsProcess stackReportToLevel: 50);
|
397
|
+
yourself).
|
398
|
+
].
|
399
|
+
data at: '_time' put: (Time millisecondClockValue - startTime).
|
400
|
+
data printJsonOn: stream.
|
401
|
+
self doAnswer.
|
402
|
+
] on: Error , Admonition do: [:ex |
|
403
|
+
resultCode := 500.
|
404
|
+
self htmlForError: ex.
|
405
|
+
self doAnswer.
|
406
|
+
ex return.
|
407
|
+
].
|
408
|
+
%
|
409
|
+
category: 'Web Server'
|
410
|
+
set compile_env: 0
|
411
|
+
method: Server
|
412
|
+
serverURL
|
413
|
+
|
414
|
+
^'http://' , ((System descriptionOfSession: System session) at: 3) , ':' , socket port printString , '/'.
|
415
|
+
|
416
|
+
%
|
417
|
+
category: 'Web Server'
|
418
|
+
set compile_env: 0
|
419
|
+
method: Server
|
420
|
+
setupServerSocketAtPort: anInteger
|
421
|
+
|
422
|
+
socket := GsSocket new.
|
423
|
+
(socket makeServerAtPort: anInteger) isNil ifTrue: [
|
424
|
+
| string |
|
425
|
+
string := socket lastErrorString.
|
426
|
+
socket close.
|
427
|
+
self error: string.
|
428
|
+
].
|
429
|
+
%
|
430
|
+
category: 'Web Server'
|
431
|
+
set compile_env: 0
|
432
|
+
method: Server
|
433
|
+
startForegroundServerAtPort: anInteger
|
434
|
+
|
435
|
+
self setupServerSocketAtPort: anInteger.
|
436
|
+
GsFile stdout nextPutAll: self serverURL; cr.
|
437
|
+
[
|
438
|
+
[true] whileTrue: [(Delay forSeconds: 5) wait].
|
439
|
+
] forkAt: Processor userBackgroundPriority.
|
440
|
+
[
|
441
|
+
[
|
442
|
+
true.
|
443
|
+
] whileTrue: [
|
444
|
+
(socket readWillNotBlockWithin: 1000) ifTrue: [
|
445
|
+
self copy handleRequestOn: socket accept.
|
446
|
+
].
|
447
|
+
].
|
448
|
+
] ensure: [
|
449
|
+
socket close.
|
450
|
+
].
|
451
|
+
%
|
452
|
+
category: 'Web Server'
|
453
|
+
set compile_env: 0
|
454
|
+
method: Server
|
455
|
+
startServerAtPort: anInteger
|
456
|
+
|
457
|
+
self setupServerSocketAtPort: anInteger.
|
458
|
+
server := [
|
459
|
+
[
|
460
|
+
[
|
461
|
+
Processor yield.
|
462
|
+
true.
|
463
|
+
] whileTrue: [
|
464
|
+
(socket readWillNotBlockWithin: 1000) ifTrue: [
|
465
|
+
[:aServer :aSocket |
|
466
|
+
aServer handleRequestOn: aSocket.
|
467
|
+
] forkAt: Processor userBackgroundPriority
|
468
|
+
with: (Array
|
469
|
+
with: self copy
|
470
|
+
with: socket accept).
|
471
|
+
].
|
472
|
+
].
|
473
|
+
] ensure: [
|
474
|
+
socket close.
|
475
|
+
].
|
476
|
+
] forkAt: Processor userBackgroundPriority.
|
477
|
+
^self serverURL.
|
478
|
+
%
|
479
|
+
category: 'Web Server'
|
480
|
+
set compile_env: 0
|
481
|
+
method: Server
|
482
|
+
stopServer
|
483
|
+
|
484
|
+
server notNil ifTrue: [
|
485
|
+
server terminate.
|
486
|
+
server := nil.
|
487
|
+
].
|
488
|
+
|
489
|
+
%
|
490
|
+
category: 'Json'
|
491
|
+
set compile_env: 0
|
492
|
+
method: Server
|
493
|
+
tools
|
494
|
+
|
495
|
+
| list |
|
496
|
+
list := WebTools select: [:each | each isClass and: [each ~~ Tool and: [each isSubclassOf: Tool]]].
|
497
|
+
list := list reject: [:each | each sortOrder isNil].
|
498
|
+
list := list asSortedCollection: [:a :b | a sortOrder <= b sortOrder].
|
499
|
+
list := list asArray collect: [:each |
|
500
|
+
Dictionary new
|
501
|
+
at: 'file' put: each fileName;
|
502
|
+
at: 'name' put: each displayName;
|
503
|
+
at: 'description' put: each description;
|
504
|
+
yourself.
|
505
|
+
].
|
506
|
+
^Dictionary new
|
507
|
+
at: #'tools' put: list;
|
508
|
+
yourself.
|
509
|
+
%
|
510
|
+
category: 'Request Handler'
|
511
|
+
set compile_env: 0
|
512
|
+
method: Server
|
513
|
+
translate: aString
|
514
|
+
|
515
|
+
| readStream writeStream string |
|
516
|
+
readStream := ReadStream on: aString.
|
517
|
+
writeStream := WriteStream on: String new.
|
518
|
+
[
|
519
|
+
readStream atEnd not.
|
520
|
+
] whileTrue: [
|
521
|
+
| char |
|
522
|
+
char := readStream next.
|
523
|
+
char = $+ ifTrue: [
|
524
|
+
writeStream space.
|
525
|
+
] ifFalse: [
|
526
|
+
char = $% ifTrue: [
|
527
|
+
| array value |
|
528
|
+
array := #($0 $1 $2 $3 $4 $5 $6 $7 $8 $9 $A $B $C $D $E $F).
|
529
|
+
value := (array indexOf: readStream next) - 1 * 16 + (array indexOf: readStream next) - 1.
|
530
|
+
writeStream nextPut: (Character codePoint: value).
|
531
|
+
] ifFalse: [
|
532
|
+
writeStream nextPut: char.
|
533
|
+
].
|
534
|
+
]
|
535
|
+
].
|
536
|
+
string := writeStream contents.
|
537
|
+
string = 'null' ifTrue: [^nil].
|
538
|
+
string = 'true' ifTrue: [^true].
|
539
|
+
string = 'false' ifTrue: [^false].
|
540
|
+
^string
|
541
|
+
%
|
542
|
+
doit
|
543
|
+
Server category: 'WebTools'
|
544
|
+
%
|