gonzui 1.2-x86-mswin32-60

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 (120) hide show
  1. data/AUTHORS.txt +9 -0
  2. data/History.txt +5539 -0
  3. data/Manifest.txt +115 -0
  4. data/PostInstall.txt +17 -0
  5. data/README.rdoc +149 -0
  6. data/Rakefile +28 -0
  7. data/bin/gonzui-db +167 -0
  8. data/bin/gonzui-import +177 -0
  9. data/bin/gonzui-remove +58 -0
  10. data/bin/gonzui-search +68 -0
  11. data/bin/gonzui-server +176 -0
  12. data/bin/gonzui-update +53 -0
  13. data/data/gonzui/catalog/catalog.ja +80 -0
  14. data/data/gonzui/doc/favicon.ico +0 -0
  15. data/data/gonzui/doc/folder.png +0 -0
  16. data/data/gonzui/doc/gonzui.css +279 -0
  17. data/data/gonzui/doc/gonzui.js +111 -0
  18. data/data/gonzui/doc/text.png +0 -0
  19. data/data/gonzuirc.sample +29 -0
  20. data/ext/autopack/autopack.c +88 -0
  21. data/ext/autopack/extconf.rb +3 -0
  22. data/ext/delta/delta.c +147 -0
  23. data/ext/delta/extconf.rb +5 -0
  24. data/ext/texttokenizer/extconf.rb +5 -0
  25. data/ext/texttokenizer/texttokenizer.c +93 -0
  26. data/ext/xmlformatter/extconf.rb +5 -0
  27. data/ext/xmlformatter/xmlformatter.c +207 -0
  28. data/lib/gonzui.rb +59 -0
  29. data/lib/gonzui/apt.rb +193 -0
  30. data/lib/gonzui/autopack.so +0 -0
  31. data/lib/gonzui/bdbdbm.rb +118 -0
  32. data/lib/gonzui/cmdapp.rb +14 -0
  33. data/lib/gonzui/cmdapp/app.rb +175 -0
  34. data/lib/gonzui/cmdapp/search.rb +134 -0
  35. data/lib/gonzui/config.rb +117 -0
  36. data/lib/gonzui/content.rb +19 -0
  37. data/lib/gonzui/dbm.rb +673 -0
  38. data/lib/gonzui/deindexer.rb +162 -0
  39. data/lib/gonzui/delta.rb +49 -0
  40. data/lib/gonzui/delta.so +0 -0
  41. data/lib/gonzui/extractor.rb +347 -0
  42. data/lib/gonzui/fetcher.rb +309 -0
  43. data/lib/gonzui/gettext.rb +144 -0
  44. data/lib/gonzui/importer.rb +84 -0
  45. data/lib/gonzui/indexer.rb +316 -0
  46. data/lib/gonzui/info.rb +80 -0
  47. data/lib/gonzui/license.rb +100 -0
  48. data/lib/gonzui/logger.rb +48 -0
  49. data/lib/gonzui/monitor.rb +177 -0
  50. data/lib/gonzui/progressbar.rb +235 -0
  51. data/lib/gonzui/remover.rb +38 -0
  52. data/lib/gonzui/searcher.rb +330 -0
  53. data/lib/gonzui/searchquery.rb +235 -0
  54. data/lib/gonzui/searchresult.rb +111 -0
  55. data/lib/gonzui/texttokenizer.so +0 -0
  56. data/lib/gonzui/updater.rb +254 -0
  57. data/lib/gonzui/util.rb +415 -0
  58. data/lib/gonzui/vcs.rb +128 -0
  59. data/lib/gonzui/webapp.rb +25 -0
  60. data/lib/gonzui/webapp/advsearch.rb +123 -0
  61. data/lib/gonzui/webapp/filehandler.rb +24 -0
  62. data/lib/gonzui/webapp/jsfeed.rb +61 -0
  63. data/lib/gonzui/webapp/markup.rb +445 -0
  64. data/lib/gonzui/webapp/search.rb +269 -0
  65. data/lib/gonzui/webapp/servlet.rb +319 -0
  66. data/lib/gonzui/webapp/snippet.rb +155 -0
  67. data/lib/gonzui/webapp/source.rb +37 -0
  68. data/lib/gonzui/webapp/stat.rb +137 -0
  69. data/lib/gonzui/webapp/top.rb +63 -0
  70. data/lib/gonzui/webapp/uri.rb +140 -0
  71. data/lib/gonzui/webapp/webrick.rb +48 -0
  72. data/lib/gonzui/webapp/xmlformatter.so +0 -0
  73. data/script/console +10 -0
  74. data/script/destroy +14 -0
  75. data/script/generate +14 -0
  76. data/script/makemanifest.rb +21 -0
  77. data/tasks/extconf.rake +13 -0
  78. data/tasks/extconf/autopack.rake +43 -0
  79. data/tasks/extconf/delta.rake +43 -0
  80. data/tasks/extconf/texttokenizer.rake +43 -0
  81. data/tasks/extconf/xmlformatter.rake +43 -0
  82. data/test/_external_tools.rb +13 -0
  83. data/test/_test-util.rb +142 -0
  84. data/test/foo/Makefile.foo +66 -0
  85. data/test/foo/bar.c +5 -0
  86. data/test/foo/bar.h +6 -0
  87. data/test/foo/foo.c +25 -0
  88. data/test/foo/foo.spec +33 -0
  89. data/test/test_apt.rb +42 -0
  90. data/test/test_autopack_extn.rb +7 -0
  91. data/test/test_bdbdbm.rb +79 -0
  92. data/test/test_cmdapp-app.rb +35 -0
  93. data/test/test_cmdapp-search.rb +99 -0
  94. data/test/test_config.rb +28 -0
  95. data/test/test_content.rb +15 -0
  96. data/test/test_dbm.rb +171 -0
  97. data/test/test_deindexer.rb +50 -0
  98. data/test/test_delta.rb +66 -0
  99. data/test/test_extractor.rb +78 -0
  100. data/test/test_fetcher.rb +75 -0
  101. data/test/test_gettext.rb +50 -0
  102. data/test/test_gonzui.rb +11 -0
  103. data/test/test_helper.rb +10 -0
  104. data/test/test_importer.rb +56 -0
  105. data/test/test_indexer.rb +37 -0
  106. data/test/test_info.rb +82 -0
  107. data/test/test_license.rb +49 -0
  108. data/test/test_logger.rb +60 -0
  109. data/test/test_monitor.rb +23 -0
  110. data/test/test_searcher.rb +37 -0
  111. data/test/test_searchquery.rb +27 -0
  112. data/test/test_searchresult.rb +43 -0
  113. data/test/test_texttokenizer.rb +47 -0
  114. data/test/test_updater.rb +95 -0
  115. data/test/test_util.rb +149 -0
  116. data/test/test_vcs.rb +61 -0
  117. data/test/test_webapp-markup.rb +42 -0
  118. data/test/test_webapp-util.rb +19 -0
  119. data/test/test_webapp-xmlformatter.rb +19 -0
  120. metadata +292 -0
@@ -0,0 +1,155 @@
1
+ #
2
+ # snippet.rb - snippet implementation
3
+ #
4
+ # Copyright (C) 2004-2005 Satoru Takabayashi <satoru@namazu.org>
5
+ # All rights reserved.
6
+ # This is free software with ABSOLUTELY NO WARRANTY.
7
+ #
8
+ # You can redistribute it and/or modify it under the terms of
9
+ # the GNU General Public License version 2.
10
+ #
11
+
12
+ module Gonzui
13
+ class SnippetMaker
14
+ include URIMaker
15
+
16
+ def initialize(content, result_item, link_uri = nil)
17
+ @content = content
18
+ @result_item = result_item
19
+ @link_uri = link_uri
20
+
21
+ # FIXME: should be customizable?
22
+ @ncontexts = 1
23
+ end
24
+
25
+ private
26
+ def make_emphasized_line(lineno, line_range, *occ_list)
27
+ line = [:span]
28
+ occ_list.each {|occ|
29
+ occ_range = (occ.byteno ... (occ.byteno + occ.length))
30
+ pre = range = nil
31
+ if line_range.include?(occ.byteno)
32
+ pre = @content.substring(line_range.first...occ.byteno)
33
+ range = (occ.byteno ... [occ_range.last, line_range.last].min)
34
+ elsif occ_range.include?(line_range.first)
35
+ range = (line_range.first ... [occ_range.last, line_range.last].min)
36
+ end
37
+ line.push(pre) if pre
38
+ if range
39
+ text = @content[range]
40
+ line.push([:strong, text])
41
+ line_range = (range.last ... line_range.last)
42
+ end
43
+ }
44
+ remaining = @content.substring(line_range)
45
+ line.push(remaining)
46
+ return line
47
+ end
48
+
49
+ def make_occurrences_by_lineno
50
+ occurrences_by_lineno = {}
51
+ @result_item.list.sort_by {|occ| occ.byteno}.each {|occ|
52
+ occurrences_by_lineno[occ.lineno] ||= []
53
+ occurrences_by_lineno[occ.lineno].push(occ)
54
+ }
55
+ return occurrences_by_lineno
56
+ end
57
+
58
+ def add_contexts(lines_with_lineno, occ)
59
+ @content.each_line_range(occ.byteno, @ncontexts) {|lineno_offset, range|
60
+ lineno = occ.lineno + lineno_offset
61
+ line = @content.substring(range)
62
+ lines_with_lineno.push([line, lineno]) unless lineno == occ.lineno
63
+ }
64
+ return lines_with_lineno.sort_by {|line, lineno| lineno }
65
+ end
66
+
67
+ def make_kwic_single
68
+ lines_with_lineno = []
69
+ occ = @result_item.list.first
70
+ text = @content[occ.byteno, occ.length]
71
+ @content.each_line_range(occ.byteno, @ncontexts) {|lineno_offset, range|
72
+ lineno = occ.lineno + lineno_offset
73
+ line = make_emphasized_line(lineno, range, occ)
74
+ lines_with_lineno.push([line, lineno])
75
+ }
76
+ return lines_with_lineno
77
+ end
78
+
79
+ def make_kwic_multi
80
+ seen = {}
81
+ lines_with_lineno = []
82
+ occurrences_by_lineno = make_occurrences_by_lineno
83
+ occurrences_by_lineno.keys.sort.each {|lineno|
84
+ occ_list = occurrences_by_lineno[lineno]
85
+ range = @content.line_range(occ_list.first.byteno)
86
+ line = make_emphasized_line(lineno, range, *occ_list)
87
+ lines_with_lineno.push([line, lineno])
88
+ }
89
+ if occurrences_by_lineno.length == 1
90
+ occ = @result_item.list.first
91
+ lines_with_lineno = add_contexts(lines_with_lineno, occ)
92
+ end
93
+ return lines_with_lineno
94
+ end
95
+
96
+ def make_kwic
97
+ if @result_item.list.length == 1
98
+ return make_kwic_single
99
+ else
100
+ return make_kwic_multi
101
+ end
102
+ end
103
+
104
+ def collect_context_lines
105
+ context_lines = {}
106
+
107
+ occurrences_by_lineno = make_occurrences_by_lineno
108
+ occurrences_by_lineno.keys.sort.each {|lineno|
109
+ occ_list = occurrences_by_lineno[lineno]
110
+ range = @content.line_range(occ_list.first.byteno)
111
+ occ = occ_list.first
112
+ @content.each_line_range(occ.byteno, @ncontexts) {|lineno_offset,range|
113
+ lineno = occ.lineno + lineno_offset
114
+ next if context_lines.has_key?(lineno) and lineno_offset != 0
115
+ line = make_emphasized_line(lineno, range, *occ_list)
116
+ context_lines[lineno] = line
117
+ }
118
+ }
119
+ return context_lines
120
+ end
121
+
122
+ def make_separator
123
+ [:div, {:class => "separator"}, ""]
124
+ end
125
+
126
+ public
127
+ def make_line_oriented_kwic
128
+ lines_with_lineno = make_kwic
129
+ pre = [:pre, {:class => "lines"}]
130
+ lines_with_lineno.sort_by {|line, lineno|
131
+ lineno
132
+ }.each {|line, lineno|
133
+ lineno_uri = make_lineno_uri(@link_uri, lineno)
134
+ lineno_mark = [:a, {:href => lineno_uri}, lineno.to_s + ": "]
135
+ pre.push(lineno_mark, line)
136
+ pre.push("\n")
137
+ }
138
+ return pre
139
+ end
140
+
141
+ def make_context_grep
142
+ context_lines = collect_context_lines
143
+ pre = [:pre, {:class => "lines"}]
144
+ prev_lineno = nil
145
+ context_lines.keys.sort.each {|lineno|
146
+ lineno_uri = make_lineno_uri(@link_uri, lineno)
147
+ lineno_mark = [:a, {:href => lineno_uri }, lineno.to_s + ": "]
148
+ pre.push(make_separator)if prev_lineno and lineno > prev_lineno + 1
149
+ pre.push(lineno_mark, context_lines[lineno], "\n")
150
+ prev_lineno = lineno
151
+ }
152
+ return pre
153
+ end
154
+ end
155
+ end
@@ -0,0 +1,37 @@
1
+ #
2
+ # source.rb - source servlet
3
+ #
4
+ # Copyright (C) 2004-2005 Satoru Takabayashi <satoru@namazu.org>
5
+ # All rights reserved.
6
+ # This is free software with ABSOLUTELY NO WARRANTY.
7
+ #
8
+ # You can redistribute it and/or modify it under the terms of
9
+ # the GNU General Public License version 2.
10
+ #
11
+
12
+ module Gonzui
13
+ class SourceServlet < GonzuiAbstractServlet
14
+ def self.mount_point
15
+ "source"
16
+ end
17
+
18
+ def do_GET(request, response)
19
+ init_servlet(request, response)
20
+ path = make_path
21
+ log(path)
22
+
23
+ path_id = @dbm.get_path_id(path)
24
+ if path_id
25
+ content = @dbm.get_content(path_id)
26
+ response.body = content
27
+ mime_type = get_mime_type(path)
28
+ response["Content-Type"] = mime_type
29
+ else
30
+ response.body = sprintf("%s: not found", path)
31
+ response.status = 404
32
+ end
33
+ end
34
+
35
+ GonzuiServlet.register(self)
36
+ end
37
+ end
@@ -0,0 +1,137 @@
1
+ #
2
+ # stat.rb - statistics servlet
3
+ #
4
+ # Copyright (C) 2004-2005 Satoru Takabayashi <satoru@namazu.org>
5
+ # All rights reserved.
6
+ # This is free software with ABSOLUTELY NO WARRANTY.
7
+ #
8
+ # You can redistribute it and/or modify it under the terms of
9
+ # the GNU General Public License version 2.
10
+ #
11
+
12
+ module Gonzui
13
+ class StatisticsServlet < GonzuiAbstractServlet
14
+ def self.mount_point
15
+ "stat"
16
+ end
17
+
18
+ RankingMax = 100
19
+
20
+ def choose_tr_class(i)
21
+ if (i + 1) % 2 == 0 then "even" else "odd" end
22
+ end
23
+
24
+ def make_heading(*items)
25
+ tr = [:tr, {:class => "heading"}]
26
+ items.each {|string, klass, colspan|
27
+ td = [:td, {:class => klass}, string]
28
+ td[1][:colspan] = colspan if colspan
29
+ tr.push(td)
30
+ }
31
+ return tr
32
+ end
33
+
34
+ def make_bar(freq, max)
35
+ percentage = freq * 100 / max
36
+ style = "width: #{percentage}px;"
37
+ bar = [:div, {:class => "bar", :style => style}, ""]
38
+ end
39
+
40
+ def do_make_status_line
41
+ []
42
+ end
43
+
44
+ def make_tr(first, second, third = nil)
45
+ tr = [:tr]
46
+ td1 = [:td, {:class => "first", :width => "76%"}, first]
47
+ if third
48
+ td2 = [:td, {:class => "nonfirst-right", :width => "12%"},
49
+ commify(second)]
50
+ td3 = [:td, {:width => "12%"}, third]
51
+ else
52
+ td2 = [:td, {:class => "nonfirst-center", :width => "24%"},
53
+ commify(second)]
54
+ end
55
+ tr.push(td1)
56
+ tr.push(td2)
57
+ tr.push(td3) if td3
58
+ return tr
59
+ end
60
+
61
+ def make_format_table
62
+ table = [:table, {:class => "fullwidth"}]
63
+ heading = make_heading([_("Contents by Format"), "first", 3])
64
+ table.push(heading)
65
+ formats = []
66
+ max = -1
67
+ @dbm.each_format {|format_id, format_abbrev, format_name|
68
+ ncontents = @dbm.get_ncontents_by_format_id(format_id)
69
+ formats.push([format_id, format_abbrev, format_name, ncontents])
70
+ max = [max, ncontents].max
71
+ }
72
+ return if formats.empty?
73
+ formats = formats.sort_by {|id, abbr, name, ncontents| - ncontents}
74
+ formats.each_with_index {|item, i|
75
+ id, abbr, name, ncontents = item
76
+ text = name
77
+ tr = make_tr(text, ncontents, make_bar(ncontents, max))
78
+ k = choose_tr_class(i)
79
+ tr.insert(1, {:class => k})
80
+ table.push(tr)
81
+ }
82
+ return table
83
+ end
84
+
85
+ def make_overview_table
86
+ table = [:table, {:class => "fullwidth"}]
87
+ heading = make_heading([_("Overview"), "first", 2])
88
+ table.push(heading)
89
+ trs = []
90
+ trs << make_tr(_("Packages"), @dbm.get_npackages)
91
+ trs << make_tr(_("Contents"), @dbm.get_ncontents)
92
+ trs << make_tr(_("Indexed Contents"), @dbm.get_ncontents_indexed)
93
+ trs << make_tr(_("Binary Contents"), @dbm.get_ncontents - @dbm.get_ncontents_indexed)
94
+ trs << make_tr(_("Lines of Indexed Contents"), @dbm.get_nlines_indexed)
95
+ trs << make_tr(_("Indexed Keys"), @dbm.get_nwords)
96
+ trs << make_tr(_("Formats"), @dbm.get_nformats)
97
+ trs.each_with_index {|tr, i|
98
+ k = choose_tr_class(i)
99
+ tr.insert(1, {:class => k})
100
+ table.push(tr)
101
+ }
102
+ return table
103
+ end
104
+
105
+ def make_top_page
106
+ title = make_title( _("Statistics"))
107
+ content = [:div]
108
+ content.push(make_overview_table)
109
+ content.push(make_format_table)
110
+ status_line = make_status_line(_("Statistics"))
111
+ return title, status_line, content
112
+ end
113
+
114
+ def do_GET(request, response)
115
+ init_servlet(request, response)
116
+ log()
117
+
118
+ @path = make_path
119
+ title, status_line, content = make_top_page
120
+
121
+ html = make_html
122
+ head = [:head, title, make_script, *make_meta_and_css]
123
+ body = [:body]
124
+ body.push(make_h1)
125
+ body.push(make_search_form)
126
+ body.push(status_line)
127
+ body.push(content)
128
+ body.push(make_footer)
129
+ html.push(head)
130
+ html.push(body)
131
+ set_content_type_text_html
132
+ response.body = format_html(html)
133
+ end
134
+
135
+ GonzuiServlet.register(self)
136
+ end
137
+ end
@@ -0,0 +1,63 @@
1
+ #
2
+ # top.rb - top page servlet
3
+ #
4
+ # Copyright (C) 2004-2005 Satoru Takabayashi <satoru@namazu.org>
5
+ # All rights reserved.
6
+ # This is free software with ABSOLUTELY NO WARRANTY.
7
+ #
8
+ # You can redistribute it and/or modify it under the terms of
9
+ # the GNU General Public License version 2.
10
+ #
11
+
12
+ module Gonzui
13
+ class TopPageServlet < GonzuiAbstractServlet
14
+ def self.mount_point
15
+ ""
16
+ end
17
+
18
+ def validate_request
19
+ return if @request.path_info == "/" or @request.path_info.empty?
20
+ if @request.path_info == "/favicon.ico"
21
+ uri = make_doc_uri("favicon.ico")
22
+ @response.set_redirect(HTTPStatus::MovedPermanently, uri)
23
+ else
24
+ raise HTTPStatus::NotFound.new("not found")
25
+ end
26
+ assert_not_reached
27
+ end
28
+
29
+ def do_GET(request, response)
30
+ init_servlet(request, response)
31
+ validate_request
32
+ log()
33
+
34
+ title = make_title
35
+ html = make_html
36
+ head = [:head, title, make_script, *make_meta_and_css]
37
+ body = [:body]
38
+
39
+ content = [:div, {:class => "center"},
40
+ make_h1,
41
+ make_search_form(:central => true),
42
+ ]
43
+ footer = make_footer
44
+ summary = [
45
+ [:br],
46
+ sprintf(_("Searching %s packages of %s contents"),
47
+ commify(@dbm.get_npackages),
48
+ commify(@dbm.get_ncontents))
49
+ ]
50
+ footer.push(*summary)
51
+
52
+ content.push(footer)
53
+ body.push(content)
54
+ html.push(head)
55
+ html.push(body)
56
+ set_content_type_text_html
57
+ response.body = format_html(html)
58
+ end
59
+
60
+ GonzuiServlet.register(self)
61
+ end
62
+ end
63
+
@@ -0,0 +1,140 @@
1
+ #
2
+ # uri.rb - uri functions
3
+ #
4
+ # Copyright (C) 2004-2005 Satoru Takabayashi <satoru@namazu.org>
5
+ # All rights reserved.
6
+ # This is free software with ABSOLUTELY NO WARRANTY.
7
+ #
8
+ # You can redistribute it and/or modify it under the terms of
9
+ # the GNU General Public License version 2.
10
+ #
11
+
12
+ module Gonzui
13
+ QueryValue = Struct.new(:short_name, :default_value, :conversion_method)
14
+
15
+ module URIMaker
16
+ ParamTable = {
17
+ :display_language => QueryValue.new("dl", nil, :to_s),
18
+ :from => QueryValue.new("f", 0, :to_i),
19
+ :format => QueryValue.new("fm", "all", :to_s),
20
+ :grep_pattern => QueryValue.new("g", nil, :to_s),
21
+ :license => QueryValue.new("l", "all", :to_s),
22
+ :nresults_per_page => QueryValue.new("n", 10, :to_i),
23
+ :phrase_query => QueryValue.new("pq", nil, :to_s),
24
+ :basic_query => QueryValue.new("q", "", :to_s),
25
+ :target_type => QueryValue.new("tt", nil, :to_s),
26
+ }
27
+
28
+ def decompose_search_query(search_query)
29
+ options = {}
30
+ options[:basic_query] = search_query.string
31
+ options[:format] = search_query.format
32
+ options[:license] = search_query.license
33
+ return options
34
+ end
35
+
36
+ def get_default_query_value(long_name)
37
+ ParamTable[long_name]
38
+ end
39
+
40
+ def get_query_value(query, long_name)
41
+ qv = get_default_query_value(long_name)
42
+ assert(qv)
43
+ value = query[qv.short_name]
44
+ if value and not value.empty?
45
+ return value.send(qv.conversion_method)
46
+ else
47
+ return qv.default_value
48
+ end
49
+ end
50
+
51
+ def get_short_name(long_name)
52
+ qv = ParamTable[long_name]
53
+ raise "unknown variable name" if qv.nil?
54
+ return qv.short_name
55
+ end
56
+
57
+ def make_advanced_search_uri(search_query)
58
+ make_uri_general(AdvancedSearchServlet)
59
+ end
60
+
61
+ def make_doc_uri(path = nil)
62
+ make_uri_general(FileHandler, path)
63
+ end
64
+
65
+ def make_google_uri(search_query)
66
+ sprintf("http://www.google.com/search?q=%s",
67
+ HTTPUtils.escape_form(search_query.string_without_properties))
68
+ end
69
+
70
+ def make_lineno_uri(markup_uri, lineno)
71
+ sprintf("%s#l%d", markup_uri, lineno)
72
+ end
73
+
74
+ def make_markup_uri(path = "", search_query = nil, options = {})
75
+ if search_query
76
+ decompose_search_query(search_query).each {|k, v|
77
+ options[k] = v
78
+ }
79
+ end
80
+ return make_uri_with_options(MarkupServlet, path, options)
81
+ end
82
+
83
+ def make_search_uri(search_query, options = {})
84
+ options.merge!(decompose_search_query(search_query))
85
+ make_uri_with_options(SearchServlet, "", options)
86
+ end
87
+
88
+ def make_search_uri_partial(query_string)
89
+ sprintf("%s?%s=",
90
+ make_uri_general(SearchServlet),
91
+ get_short_name(:basic_query))
92
+ end
93
+
94
+ def make_source_uri(path = nil)
95
+ make_uri_general(SourceServlet, path)
96
+ end
97
+
98
+ def make_stat_uri(path = nil)
99
+ make_uri_general(StatisticsServlet, path)
100
+ end
101
+
102
+ def make_top_uri
103
+ make_uri_general(TopPageServlet)
104
+ end
105
+
106
+ def escape_path(path)
107
+ path.gsub(%r{[^A-Za-z0-9\-._~!$&'()*+,;=:@/]}) {
108
+ '%' + $&.unpack("H2")[0].upcase
109
+ }
110
+ end
111
+
112
+ def make_uri_general(klass, path = nil)
113
+ assert_non_nil(@config)
114
+ if path
115
+ return URI.path_join(@config.base_mount_point,
116
+ klass.mount_point,
117
+ escape_path(path))
118
+ else
119
+ return URI.path_join(@config.base_mount_point, klass.mount_point)
120
+ end
121
+ end
122
+
123
+ def make_uri_with_options(klass, path, options)
124
+ params = []
125
+ options.each {|name, value|
126
+ next if value.nil?
127
+ qv = get_default_query_value(name)
128
+ if qv and value != qv.default_value
129
+ param = sprintf("%s=%s", qv.short_name, HTTPUtils.escape_form(value.to_s))
130
+ params.push(param)
131
+ end
132
+ }
133
+ assert_non_nil(@config)
134
+ uri = URI.path_join(@config.base_mount_point, klass.mount_point)
135
+ uri = URI.path_join(uri, escape_path(path)) unless path.empty?
136
+ uri << "?" + params.join("&") unless params.empty?
137
+ return uri
138
+ end
139
+ end
140
+ end