1 # This file is part of NIT ( http://www.nitlanguage.org ).
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
7 # http://www.apache.org/licenses/LICENSE-2.0
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.
20 import model
::model_index
25 use
("/list", new APIList(config
))
26 use
("/search", new APISearch(config
))
27 use
("/random", new APIRandom(config
))
28 use
("/entity/:id", new APIEntity(config
))
29 use
("/code/:id", new APIEntityCode(config
))
30 use
("/uml/:id", new APIEntityUML(config
))
31 use
("/linearization/:id", new APIEntityLinearization(config
))
32 use
("/defs/:id", new APIEntityDefs(config
))
33 use
("/inheritance/:id", new APIEntityInheritance(config
))
39 # MEntities can be filtered on their kind using the `k` parameter.
40 # Allowed kinds are `package`, `group`, `module`, `class`, `classdef`, `property`, `propdef`.
42 # List size can be limited with the `n` parameter.
44 # Example: `GET /list?k=module?n=10`
48 # List mentities depending on the `k` kind parameter.
49 fun list_mentities
(req
: HttpRequest): Array[MEntity] do
50 var k
= req
.string_arg
("k")
51 var mentities
= new Array[MEntity]
52 if k
== "package" then
53 for mentity
in config
.view
.mpackages
do mentities
.add mentity
54 else if k
== "group" then
55 for mentity
in config
.view
.mgroups
do mentities
.add mentity
56 else if k
== "module" then
57 for mentity
in config
.view
.mmodules
do mentities
.add mentity
58 else if k
== "class" then
59 for mentity
in config
.view
.mclasses
do mentities
.add mentity
60 else if k
== "classdef" then
61 for mentity
in config
.view
.mclassdefs
do mentities
.add mentity
62 else if k
== "property" then
63 for mentity
in config
.view
.mproperties
do mentities
.add mentity
64 else if k
== "propdef" then
65 for mentity
in config
.view
.mpropdefs
do mentities
.add mentity
67 for mentity
in config
.view
.mentities
do mentities
.add mentity
72 # Sort mentities by lexicographic order
74 # TODO choose order from request
75 fun sort_mentities
(req
: HttpRequest, mentities
: Array[MEntity]) : Array[MEntity] do
76 var sorted
= mentities
.to_a
77 var sorter
= new MEntityNameSorter
82 # Limit mentities depending on the `n` parameter.
83 fun limit_mentities
(req
: HttpRequest, mentities
: Array[MEntity]): Array[MEntity] do
84 var n
= req
.int_arg
("n")
86 return mentities
.sub
(0, n
)
91 redef fun get
(req
, res
) do
92 var mentities
= list_mentities
(req
)
93 mentities
= sort_mentities
(req
, mentities
)
94 mentities
= limit_mentities
(req
, mentities
)
95 res
.json
new JsonArray.from
(mentities
)
99 # Search mentities from a query string.
101 # Example: `GET /search?q=Arr`
105 redef fun get
(req
, res
) do
106 var q
= req
.string_arg
("q")
108 res
.json
new JsonArray
111 var n
= req
.int_arg
("n")
112 res
.json
new JsonArray.from
(config
.view
.find
(q
, n
))
116 # Return a random list of MEntities.
118 # Example: `GET /random?n=10&k=module`
122 # Randomize mentities order.
123 fun randomize_mentities
(req
: HttpRequest, mentities
: Array[MEntity]): Array[MEntity] do
124 var res
= mentities
.to_a
129 redef fun get
(req
, res
) do
130 var mentities
= list_mentities
(req
)
131 mentities
= randomize_mentities
(req
, mentities
)
132 mentities
= limit_mentities
(req
, mentities
)
133 res
.json
new JsonArray.from
(mentities
)
137 # Return the JSON representation of a MEntity.
139 # Example: `GET /entity/core::Array`
143 redef fun get
(req
, res
) do
144 var mentity
= mentity_from_uri
(req
, res
)
145 if mentity
== null then return
146 res
.raw_json mentity
.to_full_json
150 # List ancestors, parents, child and descendants of MEntity
152 # Example: `GET /entity/core::Array/inheritance`
153 class APIEntityInheritance
156 redef fun get
(req
, res
) do
157 var mentity
= mentity_from_uri
(req
, res
)
158 if mentity
== null then return
159 res
.json mentity
.hierarchy_poset
(config
.view
)[mentity
]
163 # Linearize super definitions of a MClassDef or a MPropDef if any.
165 # Example: `GET /entity/core::Array/linearization`
166 class APIEntityLinearization
169 redef fun get
(req
, res
) do
170 var mentity
= mentity_from_uri
(req
, res
)
171 if mentity
== null then return
172 var lin
= mentity
.collect_linearization
(config
.mainmodule
)
174 res
.api_error
(404, "No linearization for mentity `{mentity.full_name}`")
177 var mentities
= new JsonArray
178 for e
in lin
do mentities
.add e
183 # List definitions of a MEntity.
185 # Example: `GET /defs/core::Array`
189 redef fun get
(req
, res
) do
190 var mentity
= mentity_from_uri
(req
, res
)
191 if mentity
== null then return
192 var mentities
: Array[MEntity]
193 if mentity
isa MModule then
194 mentities
= mentity
.mclassdefs
195 else if mentity
isa MClass then
196 mentities
= mentity
.mclassdefs
197 else if mentity
isa MClassDef then
198 mentities
= mentity
.mpropdefs
199 else if mentity
isa MProperty then
200 mentities
= mentity
.mpropdefs
202 res
.api_error
(404, "No definition list for mentity `{mentity.full_name}`")
205 mentities
= sort_mentities
(req
, mentities
)
206 mentities
= limit_mentities
(req
, mentities
)
207 res
.json
new JsonArray.from
(mentities
)
211 abstract class SVGHandler
214 # Render a `dot` string as a svg image.
215 fun render_dot
(dot
: Text): String do
216 var proc
= new ProcessDuplex("dot", "-Tsvg")
217 var svg
= proc
.write_and_read
(dot
)
224 # Return a UML representation of MEntity.
226 # Example: `GET /entity/core::Array/uml`
230 redef fun get
(req
, res
) do
231 var mentity
= mentity_from_uri
(req
, res
)
232 if mentity
== null then return
234 if mentity
isa MClassDef then mentity
= mentity
.mclass
235 if mentity
isa MClass then
236 var uml
= new UMLModel(config
.view
, config
.mainmodule
)
237 dot
= uml
.generate_class_uml
.write_to_string
238 else if mentity
isa MModule then
239 var uml
= new UMLModel(config
.view
, mentity
)
240 dot
= uml
.generate_package_uml
.write_to_string
242 res
.api_error
(404, "No UML for mentity `{mentity.full_name}`")
245 res
.send render_dot
(dot
)
249 # Return the source code of MEntity.
251 # Example: `GET /entity/core::Array/code`
255 redef fun get
(req
, res
) do
256 var mentity
= mentity_from_uri
(req
, res
)
257 if mentity
== null then return
258 var source
= render_source
(mentity
)
259 if source
== null then
260 res
.api_error
(404, "No code for mentity `{mentity.full_name}`")
266 # Highlight `mentity` source code.
267 private fun render_source
(mentity
: MEntity): nullable HTMLTag do
268 var node
= config
.modelbuilder
.mentity2node
(mentity
)
269 if node
== null then return null
270 var hl
= new HighlightVisitor