nitweb: add /uml/:namespace route
[nit.git] / src / web / web_actions.nit
1 # This file is part of NIT ( http://www.nitlanguage.org ).
2 #
3 # Licensed under the Apache License, Version 2.0 (the "License");
4 # you may not use this file except in compliance with the License.
5 # You may obtain a copy of the License at
6 #
7 # http://www.apache.org/licenses/LICENSE-2.0
8 #
9 # Unless required by applicable law or agreed to in writing, software
10 # distributed under the License is distributed on an "AS IS" BASIS,
11 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 # See the License for the specific language governing permissions and
13 # limitations under the License.
14
15 # Nitcorn actions used by the nitweb server.
16 module web_actions
17
18 import web_views
19 import uml
20
21 # Display the tree of all loaded mentities.
22 class TreeAction
23 super ModelAction
24
25 redef fun answer(request, url) do
26 var model = init_model_view(request)
27 var view = new HtmlHomePage(model.to_tree)
28 return render_view(view)
29 end
30 end
31
32 # Display the list of mentities matching `namespace`.
33 class SearchAction
34 super ModelAction
35
36 # TODO handle more than full namespaces.
37 redef fun answer(request, url) do
38 var namespace = request.param("namespace")
39 if namespace == null or namespace.is_empty then
40 return render_error(400, "Missing :namespace.")
41 end
42 var model = init_model_view(request)
43 var mentities = model.mentities_by_namespace(namespace)
44 if request.is_json_asked then
45 var json = new JsonArray
46 for mentity in mentities do
47 json.add mentity.to_json
48 end
49 return render_json(json)
50 end
51 var view = new HtmlResultPage(namespace, mentities)
52 return render_view(view)
53 end
54 end
55
56 # Display a MEntity source code.
57 class CodeAction
58 super ModelAction
59
60 # Modelbuilder used to access sources.
61 var modelbuilder: ModelBuilder
62
63 # TODO handle more than full namespaces.
64 redef fun answer(request, url) do
65 var namespace = request.param("namespace")
66 if namespace == null or namespace.is_empty then
67 return render_error(400, "Missing :namespace.")
68 end
69 var model = init_model_view(request)
70 var mentities = model.mentities_by_namespace(namespace)
71 if mentities.is_empty then
72 return render_error(404, "No mentity matching this namespace.")
73 end
74 var view = new HtmlSourcePage(modelbuilder, mentities.first)
75 return render_view(view)
76 end
77 end
78
79 # Display the doc of a MEntity.
80 class DocAction
81 super ModelAction
82
83 # Modelbuilder used to access sources.
84 var modelbuilder: ModelBuilder
85
86 # TODO handle more than full namespaces.
87 redef fun answer(request, url) do
88 var namespace = request.param("namespace")
89 if namespace == null or namespace.is_empty then
90 return render_error(400, "Missing :namespace.")
91 end
92 var model = init_model_view(request)
93 var mentities = model.mentities_by_namespace(namespace)
94 if mentities.is_empty then
95 return render_error(404, "No mentity matching this namespace.")
96 end
97 var view = new HtmlDocPage(modelbuilder, mentities.first)
98 return render_view(view)
99 end
100 end
101
102 # Return an UML diagram for `namespace`.
103 class UMLDiagramAction
104 super ModelAction
105
106 # Mainmodule used for hierarchy flattening.
107 var mainmodule: MModule
108
109 redef fun answer(request, url) do
110 var namespace = request.param("namespace")
111 if namespace == null or namespace.is_empty then
112 return render_error(400, "Missing :namespace.")
113 end
114 var model = init_model_view(request)
115 var mentities = model.mentities_by_namespace(namespace)
116 if mentities.is_empty then
117 return render_error(404, "No mentity matching this namespace.")
118 end
119 var mentity = mentities.first
120 if mentity isa MClassDef then mentity = mentity.mclass
121
122 var dot
123 if mentity isa MClass then
124 var uml = new UMLModel(model, mainmodule)
125 dot = uml.generate_class_uml.write_to_string
126 else if mentity isa MModule then
127 var uml = new UMLModel(model, mentity)
128 dot = uml.generate_package_uml.write_to_string
129 else
130 return render_error(404, "No diagram matching this namespace.")
131 end
132 var view = new HtmlDotPage(dot, mentity.html_name)
133 return render_view(view)
134 end
135 end
136
137 # Return a random list of MEntities.
138 class RandomAction
139 super ModelAction
140
141 # TODO handle more than full namespaces.
142 redef fun answer(request, url) do
143 var n = request.int_arg("n") or else 10
144 var k = request.string_arg("k") or else "modules"
145 var model = init_model_view(request)
146 var mentities: Array[MEntity]
147 if k == "modules" then
148 mentities = model.mmodules.to_a
149 else if k == "classdefs" then
150 mentities = model.mclassdefs.to_a
151 else
152 mentities = model.mpropdefs.to_a
153 end
154 mentities.shuffle
155 mentities = mentities.sub(0, n)
156 if request.is_json_asked then
157 var json = new JsonArray
158 for mentity in mentities do
159 json.add mentity.to_json
160 end
161 return render_json(json)
162 end
163 var view = new HtmlResultPage("random", mentities)
164 return render_view(view)
165 end
166 end
167
168 redef class MEntity
169
170 # Return `self` as a JsonObject.
171 fun to_json: JsonObject do
172 var obj = new JsonObject
173 obj["name"] = html_name
174 obj["namespace"] = html_raw_namespace
175 var mdoc = self.mdoc
176 if mdoc != null then
177 obj["synopsis"] = mdoc.content.first.html_escape
178 obj["mdoc"] = mdoc.content.join("\n").html_escape
179 end
180 return obj
181 end
182 end