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 # Limit mentities depending on the `n` parameter.
73 fun limit_mentities
(req
: HttpRequest, mentities
: Array[MEntity]): Array[MEntity] do
74 var n
= req
.int_arg
("n")
76 return mentities
.sub
(0, n
)
81 redef fun get
(req
, res
) do
82 var mentities
= list_mentities
(req
)
83 mentities
= limit_mentities
(req
, mentities
)
84 res
.json
new JsonArray.from
(mentities
)
88 # Search mentities from a query string.
90 # Example: `GET /search?q=Arr`
94 redef fun get
(req
, res
) do
95 var q
= req
.string_arg
("q")
97 res
.json
new JsonArray
100 var n
= req
.int_arg
("n")
101 res
.json
new JsonArray.from
(config
.view
.find
(q
, n
))
105 # Return a random list of MEntities.
107 # Example: `GET /random?n=10&k=module`
111 # Randomize mentities order.
112 fun randomize_mentities
(req
: HttpRequest, mentities
: Array[MEntity]): Array[MEntity] do
113 var res
= mentities
.to_a
118 redef fun get
(req
, res
) do
119 var mentities
= list_mentities
(req
)
120 mentities
= limit_mentities
(req
, mentities
)
121 mentities
= randomize_mentities
(req
, mentities
)
122 res
.json
new JsonArray.from
(mentities
)
126 # Return the JSON representation of a MEntity.
128 # Example: `GET /entity/core::Array`
132 redef fun get
(req
, res
) do
133 var mentity
= mentity_from_uri
(req
, res
)
134 if mentity
== null then return
135 res
.json mentity
.api_json
(self)
139 # List ancestors, parents, child and descendants of MEntity
141 # Example: `GET /entity/core::Array/inheritance`
142 class APIEntityInheritance
145 redef fun get
(req
, res
) do
146 var mentity
= mentity_from_uri
(req
, res
)
147 if mentity
== null then return
148 res
.json mentity
.hierarchy_poset
(config
.view
)[mentity
]
152 # Linearize super definitions of a MClassDef or a MPropDef if any.
154 # Example: `GET /entity/core::Array/linearization`
155 class APIEntityLinearization
158 redef fun get
(req
, res
) do
159 var mentity
= mentity_from_uri
(req
, res
)
160 if mentity
== null then return
161 var lin
= mentity
.collect_linearization
(config
.mainmodule
)
163 res
.api_error
(404, "No linearization for mentity `{mentity.full_name}`")
166 var mentities
= new JsonArray
167 for e
in lin
do mentities
.add e
.full_json
172 # List definitions of a MEntity.
174 # Example: `GET /defs/core::Array`
178 redef fun get
(req
, res
) do
179 var mentity
= mentity_from_uri
(req
, res
)
180 if mentity
== null then return
181 var arr
= new JsonArray
182 if mentity
isa MModule then
183 for mclassdef
in mentity
.mclassdefs
do arr
.add mclassdef
184 else if mentity
isa MClass then
185 for mclassdef
in mentity
.mclassdefs
do arr
.add mclassdef
186 else if mentity
isa MClassDef then
187 for mpropdef
in mentity
.mpropdefs
do arr
.add mpropdef
188 else if mentity
isa MProperty then
189 for mpropdef
in mentity
.mpropdefs
do arr
.add mpropdef
191 res
.api_error
(404, "No definition list for mentity `{mentity.full_name}`")
198 abstract class SVGHandler
201 # Render a `dot` string as a svg image.
202 fun render_dot
(dot
: Text): String do
203 var proc
= new ProcessDuplex("dot", "-Tsvg")
204 var svg
= proc
.write_and_read
(dot
)
211 # Return a UML representation of MEntity.
213 # Example: `GET /entity/core::Array/uml`
217 redef fun get
(req
, res
) do
218 var mentity
= mentity_from_uri
(req
, res
)
219 if mentity
== null then return
221 if mentity
isa MClassDef then mentity
= mentity
.mclass
222 if mentity
isa MClass then
223 var uml
= new UMLModel(config
.view
, config
.mainmodule
)
224 dot
= uml
.generate_class_uml
.write_to_string
225 else if mentity
isa MModule then
226 var uml
= new UMLModel(config
.view
, mentity
)
227 dot
= uml
.generate_package_uml
.write_to_string
229 res
.api_error
(404, "No UML for mentity `{mentity.full_name}`")
232 res
.send render_dot
(dot
)
236 # Return the source code of MEntity.
238 # Example: `GET /entity/core::Array/code`
242 redef fun get
(req
, res
) do
243 var mentity
= mentity_from_uri
(req
, res
)
244 if mentity
== null then return
245 var source
= render_source
(mentity
)
246 if source
== null then
247 res
.api_error
(404, "No code for mentity `{mentity.full_name}`")
253 # Highlight `mentity` source code.
254 private fun render_source
(mentity
: MEntity): nullable HTMLTag do
255 var node
= config
.modelbuilder
.mentity2node
(mentity
)
256 if node
== null then return null
257 var hl
= new HighlightVisitor