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.
24 use
("/list", new APIList(config
))
25 use
("/search", new APISearch(config
))
26 use
("/random", new APIRandom(config
))
27 use
("/entity/:id", new APIEntity(config
))
28 use
("/code/:id", new APIEntityCode(config
))
29 use
("/uml/:id", new APIEntityUML(config
))
30 use
("/linearization/:id", new APIEntityLinearization(config
))
31 use
("/defs/:id", new APIEntityDefs(config
))
32 use
("/inheritance/:id", new APIEntityInheritance(config
))
38 # MEntities can be filtered on their kind using the `k` parameter.
39 # Allowed kinds are `package`, `group`, `module`, `class`, `classdef`, `property`, `propdef`.
41 # List size can be limited with the `n` parameter.
43 # Example: `GET /list?k=module?n=10`
47 # List mentities depending on the `k` kind parameter.
48 fun list_mentities
(req
: HttpRequest): Array[MEntity] do
49 var k
= req
.string_arg
("k")
50 var mentities
= new Array[MEntity]
51 if k
== "package" then
52 for mentity
in view
.mpackages
do mentities
.add mentity
53 else if k
== "group" then
54 for mentity
in view
.mgroups
do mentities
.add mentity
55 else if k
== "module" then
56 for mentity
in view
.mmodules
do mentities
.add mentity
57 else if k
== "class" then
58 for mentity
in view
.mclasses
do mentities
.add mentity
59 else if k
== "classdef" then
60 for mentity
in view
.mclassdefs
do mentities
.add mentity
61 else if k
== "property" then
62 for mentity
in view
.mproperties
do mentities
.add mentity
63 else if k
== "propdef" then
64 for mentity
in view
.mpropdefs
do mentities
.add mentity
66 for mentity
in view
.mentities
do mentities
.add mentity
71 # Limit mentities depending on the `n` parameter.
72 fun limit_mentities
(req
: HttpRequest, mentities
: Array[MEntity]): Array[MEntity] do
73 var n
= req
.int_arg
("n")
75 return mentities
.sub
(0, n
)
80 redef fun get
(req
, res
) do
81 var mentities
= list_mentities
(req
)
82 mentities
= limit_mentities
(req
, mentities
)
83 res
.json
new JsonArray.from
(mentities
)
87 # Search mentities from a query string.
89 # Example: `GET /search?q=Arr`
93 redef fun list_mentities
(req
) do
94 var q
= req
.string_arg
("q")
95 var mentities
= new Array[MEntity]
96 if q
== null then return mentities
97 for mentity
in view
.mentities
do
98 if mentity
.name
.has_prefix
(q
) then mentities
.add mentity
104 # Return a random list of MEntities.
106 # Example: `GET /random?n=10&k=module`
110 # Randomize mentities order.
111 fun randomize_mentities
(req
: HttpRequest, mentities
: Array[MEntity]): Array[MEntity] do
112 var res
= mentities
.to_a
117 redef fun get
(req
, res
) do
118 var mentities
= list_mentities
(req
)
119 mentities
= limit_mentities
(req
, mentities
)
120 mentities
= randomize_mentities
(req
, mentities
)
121 res
.json
new JsonArray.from
(mentities
)
125 # Return the JSON representation of a MEntity.
127 # Example: `GET /entity/core::Array`
131 redef fun get
(req
, res
) do
132 var mentity
= mentity_from_uri
(req
, res
)
133 if mentity
== null then return
134 res
.json mentity
.api_json
(self)
138 # List ancestors, parents, child and descendants of MEntity
140 # Example: `GET /entity/core::Array/inheritance`
141 class APIEntityInheritance
144 redef fun get
(req
, res
) do
145 var mentity
= mentity_from_uri
(req
, res
)
146 if mentity
== null then return
147 res
.json mentity
.hierarchy_poset
(view
)[mentity
]
151 # Linearize super definitions of a MClassDef or a MPropDef if any.
153 # Example: `GET /entity/core::Array/linearization`
154 class APIEntityLinearization
157 redef fun get
(req
, res
) do
158 var mentity
= mentity_from_uri
(req
, res
)
159 if mentity
== null then return
160 var lin
= mentity
.collect_linearization
(config
.mainmodule
)
162 res
.api_error
(404, "No linearization for mentity `{mentity.full_name}`")
165 var mentities
= new JsonArray
166 for e
in lin
do mentities
.add e
.full_json
171 # List definitions of a MEntity.
173 # Example: `GET /defs/core::Array`
177 redef fun get
(req
, res
) do
178 var mentity
= mentity_from_uri
(req
, res
)
179 if mentity
== null then return
180 var arr
= new JsonArray
181 if mentity
isa MModule then
182 for mclassdef
in mentity
.mclassdefs
do arr
.add mclassdef
183 else if mentity
isa MClass then
184 for mclassdef
in mentity
.mclassdefs
do arr
.add mclassdef
185 else if mentity
isa MClassDef then
186 for mpropdef
in mentity
.mpropdefs
do arr
.add mpropdef
187 else if mentity
isa MProperty then
188 for mpropdef
in mentity
.mpropdefs
do arr
.add mpropdef
190 res
.api_error
(404, "No definition list for mentity `{mentity.full_name}`")
197 abstract class SVGHandler
200 # Render a `dot` string as a svg image.
201 fun render_dot
(dot
: Text): String do
202 var proc
= new ProcessDuplex("dot", "-Tsvg")
203 var svg
= proc
.write_and_read
(dot
)
210 # Return a UML representation of MEntity.
212 # Example: `GET /entity/core::Array/uml`
216 redef fun get
(req
, res
) do
217 var mentity
= mentity_from_uri
(req
, res
)
218 if mentity
== null then return
220 if mentity
isa MClassDef then mentity
= mentity
.mclass
221 if mentity
isa MClass then
222 var uml
= new UMLModel(view
, config
.mainmodule
)
223 dot
= uml
.generate_class_uml
.write_to_string
224 else if mentity
isa MModule then
225 var uml
= new UMLModel(view
, mentity
)
226 dot
= uml
.generate_package_uml
.write_to_string
228 res
.api_error
(404, "No UML for mentity `{mentity.full_name}`")
231 res
.send render_dot
(dot
)
235 # Return the source code of MEntity.
237 # Example: `GET /entity/core::Array/code`
241 redef fun get
(req
, res
) do
242 var mentity
= mentity_from_uri
(req
, res
)
243 if mentity
== null then return
244 var source
= render_source
(mentity
)
245 if source
== null then
246 res
.api_error
(404, "No code for mentity `{mentity.full_name}`")
252 # Highlight `mentity` source code.
253 private fun render_source
(mentity
: MEntity): nullable HTMLTag do
254 var node
= config
.modelbuilder
.mentity2node
(mentity
)
255 if node
== null then return null
256 var hl
= new HighlightVisitor