maglev-webtools 0.2.1 → 1.0

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.
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
+ %