maglev-webtools 0.2.1 → 1.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (296) hide show
  1. data/README.rdoc +38 -29
  2. data/bin/webtools +22 -1
  3. data/lib/web_tools/code_browser.rb +156 -0
  4. data/lib/web_tools/debugger.rb +96 -199
  5. data/lib/web_tools/info.rb +1 -3
  6. data/lib/web_tools/method_list.rb +67 -0
  7. data/lib/web_tools/middleware/debugger.rb +10 -16
  8. data/lib/web_tools/object_log.rb +24 -0
  9. data/lib/web_tools/session_list.rb +119 -0
  10. data/lib/web_tools/shared_page_cache.rb +30 -0
  11. data/lib/web_tools/stat_process.rb +24 -0
  12. data/lib/web_tools/statistics.rb +14 -0
  13. data/lib/web_tools/support/app_model.rb +66 -101
  14. data/lib/web_tools/support/code_browser.rb +88 -86
  15. data/lib/web_tools/support/debugger.rb +303 -0
  16. data/lib/web_tools/support/error_log.rb +33 -0
  17. data/lib/web_tools/support/ruby.rb +60 -121
  18. data/lib/web_tools/support/service_helper.rb +38 -10
  19. data/lib/web_tools/support/smalltalk_extensions.rb +12 -0
  20. data/lib/web_tools/tool.rb +48 -0
  21. data/lib/web_tools/ui.rb +14 -53
  22. data/lib/web_tools/version_report.rb +29 -0
  23. data/lib/web_tools/workspace.rb +77 -0
  24. data/lib/web_tools.rb +14 -4
  25. data/public/CodeBrowser.html +51 -0
  26. data/public/CodeMirror/LICENSE +19 -0
  27. data/public/CodeMirror/css/codemirror.css +67 -0
  28. data/public/CodeMirror/css/default.css +18 -0
  29. data/public/CodeMirror/js/codemirror.js +2131 -0
  30. data/public/CodeMirror/js/ruby.js +195 -0
  31. data/public/CodeMirror/js/smalltalk.js +139 -0
  32. data/public/Debugger.html +28 -0
  33. data/public/MethodList.html +20 -0
  34. data/public/ObjectLog.html +20 -0
  35. data/public/SessionList.html +31 -0
  36. data/public/SharedPageCache.html +78 -0
  37. data/public/Statistics.html +64 -0
  38. data/public/VersionReport.html +50 -0
  39. data/public/Workspace.html +39 -0
  40. data/public/css/CodeBrowser.css +24 -0
  41. data/public/css/Debugger.css +32 -0
  42. data/public/css/MethodList.css +8 -0
  43. data/public/css/ObjectLog.css +5 -0
  44. data/public/css/SessionList.css +9 -0
  45. data/public/css/Statistics.css +24 -0
  46. data/public/{stylesheets → css}/base/images/ui-anim_basic_16x16.gif +0 -0
  47. data/public/{stylesheets → css}/base/images/ui-bg_flat_0_aaaaaa_40x100.png +0 -0
  48. data/public/{stylesheets → css}/base/images/ui-bg_flat_75_ffffff_40x100.png +0 -0
  49. data/public/{stylesheets → css}/base/images/ui-bg_glass_55_fbf9ee_1x400.png +0 -0
  50. data/public/{stylesheets → css}/base/images/ui-bg_glass_65_ffffff_1x400.png +0 -0
  51. data/public/{stylesheets → css}/base/images/ui-bg_glass_75_dadada_1x400.png +0 -0
  52. data/public/{stylesheets → css}/base/images/ui-bg_glass_75_e6e6e6_1x400.png +0 -0
  53. data/public/{stylesheets → css}/base/images/ui-bg_glass_95_fef1ec_1x400.png +0 -0
  54. data/public/{stylesheets → css}/base/images/ui-bg_highlight-soft_75_cccccc_1x100.png +0 -0
  55. data/public/{stylesheets → css}/base/images/ui-icons_222222_256x240.png +0 -0
  56. data/public/{stylesheets → css}/base/images/ui-icons_2e83ff_256x240.png +0 -0
  57. data/public/{stylesheets → css}/base/images/ui-icons_454545_256x240.png +0 -0
  58. data/public/{stylesheets → css}/base/images/ui-icons_888888_256x240.png +0 -0
  59. data/public/{stylesheets → css}/base/images/ui-icons_cd0a0a_256x240.png +0 -0
  60. data/public/{stylesheets → css}/base/jquery.ui.accordion.css +0 -0
  61. data/public/{stylesheets → css}/base/jquery.ui.all.css +0 -0
  62. data/public/{stylesheets → css}/base/jquery.ui.autocomplete.css +0 -0
  63. data/public/{stylesheets → css}/base/jquery.ui.base.css +0 -0
  64. data/public/{stylesheets → css}/base/jquery.ui.button.css +0 -0
  65. data/public/{stylesheets → css}/base/jquery.ui.core.css +0 -0
  66. data/public/{stylesheets → css}/base/jquery.ui.datepicker.css +0 -0
  67. data/public/{stylesheets → css}/base/jquery.ui.dialog.css +0 -0
  68. data/public/{stylesheets → css}/base/jquery.ui.progressbar.css +0 -0
  69. data/public/{stylesheets → css}/base/jquery.ui.resizable.css +0 -0
  70. data/public/{stylesheets → css}/base/jquery.ui.selectable.css +0 -0
  71. data/public/{stylesheets → css}/base/jquery.ui.slider.css +0 -0
  72. data/public/{stylesheets → css}/base/jquery.ui.tabs.css +0 -0
  73. data/public/{stylesheets → css}/base/jquery.ui.theme.css +0 -0
  74. data/public/css/editor.css +25 -0
  75. data/public/css/jjmenu.css +33 -0
  76. data/public/css/menuitem.gif +0 -0
  77. data/public/css/more.gif +0 -0
  78. data/public/{stylesheets → css}/reset.css +1 -1
  79. data/public/css/smoothness/images/ui-anim_basic_16x16.gif +0 -0
  80. data/public/css/smoothness/images/ui-bg_flat_0_aaaaaa_40x100.png +0 -0
  81. data/public/css/smoothness/images/ui-bg_flat_75_ffffff_40x100.png +0 -0
  82. data/public/css/smoothness/images/ui-bg_glass_55_fbf9ee_1x400.png +0 -0
  83. data/public/css/smoothness/images/ui-bg_glass_65_ffffff_1x400.png +0 -0
  84. data/public/css/smoothness/images/ui-bg_glass_75_dadada_1x400.png +0 -0
  85. data/public/css/smoothness/images/ui-bg_glass_75_e6e6e6_1x400.png +0 -0
  86. data/public/css/smoothness/images/ui-bg_glass_95_fef1ec_1x400.png +0 -0
  87. data/public/css/smoothness/images/ui-bg_highlight-soft_75_cccccc_1x100.png +0 -0
  88. data/public/css/smoothness/images/ui-icons_222222_256x240.png +0 -0
  89. data/public/css/smoothness/images/ui-icons_2e83ff_256x240.png +0 -0
  90. data/public/css/smoothness/images/ui-icons_454545_256x240.png +0 -0
  91. data/public/css/smoothness/images/ui-icons_888888_256x240.png +0 -0
  92. data/public/css/smoothness/images/ui-icons_cd0a0a_256x240.png +0 -0
  93. data/public/css/smoothness/jquery-ui.css +489 -0
  94. data/public/css/ui-lightness/images/ui-anim_basic_16x16.gif +0 -0
  95. data/public/css/ui-lightness/images/ui-bg_diagonals-thick_18_b81900_40x40.png +0 -0
  96. data/public/css/ui-lightness/images/ui-bg_diagonals-thick_20_666666_40x40.png +0 -0
  97. data/public/css/ui-lightness/images/ui-bg_flat_10_000000_40x100.png +0 -0
  98. data/public/css/ui-lightness/images/ui-bg_glass_100_f6f6f6_1x400.png +0 -0
  99. data/public/css/ui-lightness/images/ui-bg_glass_100_fdf5ce_1x400.png +0 -0
  100. data/public/css/ui-lightness/images/ui-bg_glass_65_ffffff_1x400.png +0 -0
  101. data/public/css/ui-lightness/images/ui-bg_gloss-wave_35_f6a828_500x100.png +0 -0
  102. data/public/css/ui-lightness/images/ui-bg_highlight-soft_100_eeeeee_1x100.png +0 -0
  103. data/public/css/ui-lightness/images/ui-bg_highlight-soft_75_ffe45c_1x100.png +0 -0
  104. data/public/css/ui-lightness/images/ui-icons_222222_256x240.png +0 -0
  105. data/public/css/ui-lightness/images/ui-icons_228ef1_256x240.png +0 -0
  106. data/public/css/ui-lightness/images/ui-icons_ef8c08_256x240.png +0 -0
  107. data/public/css/ui-lightness/images/ui-icons_ffd27a_256x240.png +0 -0
  108. data/public/css/ui-lightness/images/ui-icons_ffffff_256x240.png +0 -0
  109. data/public/css/ui-lightness/jquery-ui.css +489 -0
  110. data/public/css/webtools.css +65 -0
  111. data/public/favicon.ico +0 -0
  112. data/public/flot/API.txt +1201 -0
  113. data/public/flot/FAQ.txt +76 -0
  114. data/public/flot/LICENSE.txt +22 -0
  115. data/public/flot/Makefile +9 -0
  116. data/public/flot/NEWS.txt +508 -0
  117. data/public/flot/PLUGINS.txt +137 -0
  118. data/public/flot/README.txt +90 -0
  119. data/public/flot/examples/ajax.html +143 -0
  120. data/public/flot/examples/annotating.html +75 -0
  121. data/public/flot/examples/arrow-down.gif +0 -0
  122. data/public/flot/examples/arrow-left.gif +0 -0
  123. data/public/flot/examples/arrow-right.gif +0 -0
  124. data/public/flot/examples/arrow-up.gif +0 -0
  125. data/public/flot/examples/basic.html +38 -0
  126. data/public/flot/examples/data-eu-gdp-growth-1.json +4 -0
  127. data/public/flot/examples/data-eu-gdp-growth-2.json +4 -0
  128. data/public/flot/examples/data-eu-gdp-growth-3.json +4 -0
  129. data/public/flot/examples/data-eu-gdp-growth-4.json +4 -0
  130. data/public/flot/examples/data-eu-gdp-growth-5.json +4 -0
  131. data/public/flot/examples/data-eu-gdp-growth.json +4 -0
  132. data/public/flot/examples/data-japan-gdp-growth.json +4 -0
  133. data/public/flot/examples/data-usa-gdp-growth.json +4 -0
  134. data/public/flot/examples/graph-types.html +75 -0
  135. data/public/flot/examples/hs-2004-27-a-large_web.jpg +0 -0
  136. data/public/flot/examples/image.html +45 -0
  137. data/public/flot/examples/index.html +44 -0
  138. data/public/flot/examples/interacting-axes.html +97 -0
  139. data/public/flot/examples/interacting.html +93 -0
  140. data/public/flot/examples/layout.css +6 -0
  141. data/public/flot/examples/multiple-axes.html +60 -0
  142. data/public/flot/examples/navigate.html +118 -0
  143. data/public/flot/examples/percentiles.html +57 -0
  144. data/public/flot/examples/pie.html +756 -0
  145. data/public/flot/examples/realtime.html +83 -0
  146. data/public/flot/examples/resize.html +61 -0
  147. data/public/flot/examples/selection.html +114 -0
  148. data/public/flot/examples/setting-options.html +61 -0
  149. data/public/flot/examples/stacking.html +77 -0
  150. data/public/flot/examples/symbols.html +49 -0
  151. data/public/flot/examples/thresholding.html +54 -0
  152. data/public/flot/examples/time.html +71 -0
  153. data/public/flot/examples/tracking.html +95 -0
  154. data/public/flot/examples/turning-series.html +98 -0
  155. data/public/flot/examples/visitors.html +90 -0
  156. data/public/flot/examples/zooming.html +98 -0
  157. data/public/flot/excanvas.js +1427 -0
  158. data/public/flot/excanvas.min.js +1 -0
  159. data/public/flot/jquery.colorhelpers.js +179 -0
  160. data/public/flot/jquery.colorhelpers.min.js +1 -0
  161. data/public/flot/jquery.flot.crosshair.js +167 -0
  162. data/public/flot/jquery.flot.crosshair.min.js +1 -0
  163. data/public/flot/jquery.flot.fillbetween.js +183 -0
  164. data/public/flot/jquery.flot.fillbetween.min.js +1 -0
  165. data/public/flot/jquery.flot.image.js +238 -0
  166. data/public/flot/jquery.flot.image.min.js +1 -0
  167. data/public/flot/jquery.flot.js +2599 -0
  168. data/public/flot/jquery.flot.min.js +6 -0
  169. data/public/flot/jquery.flot.navigate.js +336 -0
  170. data/public/flot/jquery.flot.navigate.min.js +1 -0
  171. data/public/flot/jquery.flot.pie.js +750 -0
  172. data/public/flot/jquery.flot.pie.min.js +1 -0
  173. data/public/flot/jquery.flot.resize.js +60 -0
  174. data/public/flot/jquery.flot.resize.min.js +1 -0
  175. data/public/flot/jquery.flot.selection.js +344 -0
  176. data/public/flot/jquery.flot.selection.min.js +1 -0
  177. data/public/flot/jquery.flot.stack.js +184 -0
  178. data/public/flot/jquery.flot.stack.min.js +1 -0
  179. data/public/flot/jquery.flot.symbol.js +70 -0
  180. data/public/flot/jquery.flot.symbol.min.js +1 -0
  181. data/public/flot/jquery.flot.threshold.js +103 -0
  182. data/public/flot/jquery.flot.threshold.min.js +1 -0
  183. data/public/flot/jquery.js +8316 -0
  184. data/public/flot/jquery.min.js +23 -0
  185. data/public/genPacking.pl +30 -0
  186. data/public/index.html +28 -0
  187. data/public/install.tpz +66 -0
  188. data/public/installAndRun.tpz +5 -0
  189. data/public/jsTree/jquery.jstree.js +3510 -0
  190. data/public/jsTree/themes/default/d.gif +0 -0
  191. data/public/jsTree/themes/default/d.png +0 -0
  192. data/public/jsTree/themes/default/style.css +73 -0
  193. data/public/jsTree/themes/default/throbber.gif +0 -0
  194. data/public/readMe.txt +9 -0
  195. data/public/scripts/CodeBrowser.js +645 -0
  196. data/public/scripts/Debugger.js +134 -0
  197. data/public/scripts/MethodList.js +72 -0
  198. data/public/scripts/ObjectLog.js +59 -0
  199. data/public/scripts/SessionList.js +164 -0
  200. data/public/scripts/Statistics.js +266 -0
  201. data/public/scripts/editor.js +430 -0
  202. data/public/scripts/jjmenu.js +375 -0
  203. data/public/scripts/jquery-ui.js +1012 -0
  204. data/public/scripts/jquery.js +154 -0
  205. data/public/scripts/webtools.js +374 -0
  206. data/public/src/CodeBrowser.gs +416 -0
  207. data/public/src/Debugger.gs +132 -0
  208. data/public/src/MethodList.gs +130 -0
  209. data/public/src/ObjectLog.gs +73 -0
  210. data/public/src/Server.gs +544 -0
  211. data/public/src/SessionList.gs +172 -0
  212. data/public/src/SharedPageCache.gs +66 -0
  213. data/public/src/StatProcess.gs +280 -0
  214. data/public/src/StatProcessType.gs +242 -0
  215. data/public/src/StatStatistic.gs +381 -0
  216. data/public/src/Statistics.gs +222 -0
  217. data/public/src/Statmonitor.gs +490 -0
  218. data/public/src/Tool.gs +86 -0
  219. data/public/src/VersionReport.gs +52 -0
  220. data/public/src/Workspace.gs +163 -0
  221. data/views/debugger.rhtml +6 -9
  222. metadata +344 -243
  223. data/lib/web_tools/#debugger.rb# +0 -212
  224. data/lib/web_tools/browser.rb +0 -45
  225. data/public/images/favicon.ico +0 -0
  226. data/public/javascript/CodeMirror/LICENSE +0 -23
  227. data/public/javascript/CodeMirror/css/Smalltalk.css +0 -34
  228. data/public/javascript/CodeMirror/js/codemirror.js +0 -582
  229. data/public/javascript/CodeMirror/js/editor.js +0 -1671
  230. data/public/javascript/CodeMirror/js/highlight.js +0 -68
  231. data/public/javascript/CodeMirror/js/parseSmalltalk.js +0 -126
  232. data/public/javascript/CodeMirror/js/parsedummy.js +0 -32
  233. data/public/javascript/CodeMirror/js/select.js +0 -699
  234. data/public/javascript/CodeMirror/js/stringstream.js +0 -159
  235. data/public/javascript/CodeMirror/js/tokenize.js +0 -57
  236. data/public/javascript/CodeMirror/js/undo.js +0 -413
  237. data/public/javascript/CodeMirror/js/util.js +0 -133
  238. data/public/javascript/CodeMirror/testSmalltalkParser.html +0 -116
  239. data/public/javascript/ace/ace-uncompressed.js +0 -17299
  240. data/public/javascript/ace/ace.js +0 -1
  241. data/public/javascript/ace/keybinding-emacs.js +0 -1
  242. data/public/javascript/ace/keybinding-vim.js +0 -1
  243. data/public/javascript/ace/mode-c_cpp.js +0 -1
  244. data/public/javascript/ace/mode-clojure.js +0 -1
  245. data/public/javascript/ace/mode-coffee.js +0 -1
  246. data/public/javascript/ace/mode-csharp.js +0 -1
  247. data/public/javascript/ace/mode-css.js +0 -1
  248. data/public/javascript/ace/mode-groovy.js +0 -1
  249. data/public/javascript/ace/mode-html.js +0 -1
  250. data/public/javascript/ace/mode-java.js +0 -1
  251. data/public/javascript/ace/mode-javascript.js +0 -1
  252. data/public/javascript/ace/mode-json.js +0 -1
  253. data/public/javascript/ace/mode-lua.js +0 -1
  254. data/public/javascript/ace/mode-markdown.js +0 -1
  255. data/public/javascript/ace/mode-ocaml.js +0 -1
  256. data/public/javascript/ace/mode-perl.js +0 -1
  257. data/public/javascript/ace/mode-php.js +0 -1
  258. data/public/javascript/ace/mode-python.js +0 -1
  259. data/public/javascript/ace/mode-ruby.js +0 -1
  260. data/public/javascript/ace/mode-scad.js +0 -1
  261. data/public/javascript/ace/mode-scala.js +0 -1
  262. data/public/javascript/ace/mode-scss.js +0 -1
  263. data/public/javascript/ace/mode-svg.js +0 -1
  264. data/public/javascript/ace/mode-textile.js +0 -1
  265. data/public/javascript/ace/mode-xml.js +0 -1
  266. data/public/javascript/ace/theme-clouds.js +0 -1
  267. data/public/javascript/ace/theme-clouds_midnight.js +0 -1
  268. data/public/javascript/ace/theme-cobalt.js +0 -1
  269. data/public/javascript/ace/theme-crimson_editor.js +0 -1
  270. data/public/javascript/ace/theme-dawn.js +0 -1
  271. data/public/javascript/ace/theme-eclipse.js +0 -1
  272. data/public/javascript/ace/theme-idle_fingers.js +0 -1
  273. data/public/javascript/ace/theme-kr_theme.js +0 -1
  274. data/public/javascript/ace/theme-merbivore.js +0 -1
  275. data/public/javascript/ace/theme-merbivore_soft.js +0 -1
  276. data/public/javascript/ace/theme-mono_industrial.js +0 -1
  277. data/public/javascript/ace/theme-monokai.js +0 -1
  278. data/public/javascript/ace/theme-pastel_on_dark.js +0 -1
  279. data/public/javascript/ace/theme-solarized_dark.js +0 -1
  280. data/public/javascript/ace/theme-solarized_light.js +0 -1
  281. data/public/javascript/ace/theme-textmate.js +0 -1
  282. data/public/javascript/ace/theme-twilight.js +0 -1
  283. data/public/javascript/ace/theme-vibrant_ink.js +0 -1
  284. data/public/javascript/ace/worker-coffee.js +0 -1
  285. data/public/javascript/ace/worker-css.js +0 -1
  286. data/public/javascript/ace/worker-javascript.js +0 -1
  287. data/public/javascript/webtools/browser.js +0 -260
  288. data/public/javascript/webtools/debugger.coffee +0 -286
  289. data/public/javascript/webtools/debugger.js +0 -366
  290. data/public/javascript/webtools/sessions.coffee +0 -17
  291. data/public/javascript/webtools/sessions.js +0 -27
  292. data/public/javascript/webtools/version.coffee +0 -14
  293. data/public/javascript/webtools/version.js +0 -20
  294. data/public/stylesheets/jquery.contextMenu.css +0 -62
  295. data/public/stylesheets/webtools.css +0 -53
  296. 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: (#('&quot;' '&amp;' '&apos;' '&lt;' '&gt;') 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
+ %