14bfcca693fce7231f50deb0a3b4a36070ecabdf
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.
15 # Base classes used by `nitweb`.
18 import model
::model_views
19 import model
::model_json
22 import popcorn
::pop_config
23 import popcorn
::pop_repos
29 redef var default_db_name
= "nitweb"
34 # MModule used to flatten model.
35 var mainmodule
: MModule
37 # Modelbuilder used to access sources.
38 var modelbuilder
: ModelBuilder
40 # The JSON API does not filter anything by default.
42 # So we can cache the model view.
43 var view
: ModelView is lazy
do
44 var view
= new ModelView(model
)
45 view
.min_visibility
= private_visibility
46 view
.include_fictive
= true
47 view
.include_empty_doc
= true
48 view
.include_attribute
= true
49 view
.include_test_suite
= true
54 # Specific handler for the nitweb API.
55 abstract class APIHandler
59 var config
: NitwebConfig
61 # Find the MEntity ` with `full_name`.
62 fun find_mentity
(model
: ModelView, full_name
: nullable String): nullable MEntity do
63 if full_name
== null then return null
64 return model
.mentity_by_full_name
(full_name
.from_percent_encoding
)
67 # Try to load the mentity from uri with `/:id`.
69 # Send 400 if `:id` is null.
70 # Send 404 if no entity is found.
71 # Return null in both cases.
72 fun mentity_from_uri
(req
: HttpRequest, res
: HttpResponse): nullable MEntity do
73 var id
= req
.param
("id")
75 res
.api_error
(400, "Expected mentity full name")
78 var mentity
= find_mentity
(config
.view
, id
)
79 if mentity
== null then
80 res
.api_error
(404, "MEntity `{id}` not found")
86 # A Rooter dedicated to APIHandlers.
91 var config
: NitwebConfig
94 redef class HttpResponse
96 # Return an HTTP error response with `status`
98 # Like the rest of the API, errors are formated as JSON:
100 # { "status": 404, "message": "Not found" }
102 fun api_error
(status
: Int, message
: String) do
103 json
(new APIError(status
, message
), status
)
107 # An error returned by the API.
109 # Can be serialized to json.
116 # Response error message
119 # Json Object for this error
120 var json
: JsonObject is lazy
do
121 var obj
= new JsonObject
122 obj
["status"] = status
123 obj
["message"] = message
127 redef fun to_json
do return json
.to_json
130 # Fullname representation that can be used to build decorated links
132 # * MPackage: `mpackage_name`
133 # * MGroup: `(mpackage_name::)mgroup_name`
135 super Array[nullable NSEntity]
138 redef fun to_s
do return self.join
("")
139 redef fun to_json
do return (new JsonArray.from
(self)).to_json
142 # Something that goes in a Namespace
145 # * a `NSToken` for tokens like `::`, `>` and `$`
146 # * a `MSRef` for references to mentities
151 # A reference to a MEntity that can be rendered as a link.
153 # We do not reuse `MEntityRef` ref since NSRef can be found in a ref and create
158 # The mentity to link to/
162 var obj
= new JsonObject
163 obj
["web_url"] = mentity
.web_url
164 obj
["api_url"] = mentity
.api_url
165 obj
["name"] = mentity
.name
170 # A namespace token representation
172 # Used for namespace tokens like `::`, `>` and `$`
179 # URL to `self` within the web interface.
180 fun web_url
: String do return "/doc/" / full_name
182 # URL to `self` within the JSON api.
183 fun api_url
: String do return "/api/entity/" / full_name
187 obj
["namespace"] = namespace
188 obj
["web_url"] = web_url
189 obj
["api_url"] = api_url
193 # Get the full json repesentation of `self` with MEntityRefs resolved.
194 fun api_json
(handler
: APIHandler): JsonObject do return full_json
196 # Return `self.full_name` as an object that can be serialized to json.
197 fun namespace
: nullable Namespace do return null
199 # Return a new NSRef to `self`.
200 fun to_ns_ref
: NSRef do return new NSRef(self)
203 redef class MEntityRef
206 obj
["namespace"] = mentity
.namespace
207 obj
["web_url"] = mentity
.web_url
208 obj
["api_url"] = mentity
.api_url
209 obj
["name"] = mentity
.name
210 obj
["mdoc"] = mentity
.mdoc_or_fallback
211 obj
["visibility"] = mentity
.visibility
212 var modifiers
= new JsonArray
213 for modifier
in mentity
.collect_modifiers
do
214 modifiers
.add modifier
216 obj
["modifiers"] = modifiers
217 var mentity
= self.mentity
218 if mentity
isa MMethod then
219 obj
["msignature"] = mentity
.intro
.msignature
220 else if mentity
isa MMethodDef then
221 obj
["msignature"] = mentity
.msignature
222 else if mentity
isa MVirtualTypeProp then
223 obj
["bound"] = to_mentity_ref
(mentity
.intro
.bound
)
224 else if mentity
isa MVirtualTypeDef then
225 obj
["bound"] = to_mentity_ref
(mentity
.bound
)
230 redef fun full_json
do
232 obj
["location"] = mentity
.location
239 # Add doc down processing
241 var obj
= new JsonObject
242 obj
["html_synopsis"] = html_synopsis
.write_to_string
243 obj
["html_documentation"] = html_documentation
.write_to_string
249 redef fun namespace
do return new Namespace.from
([to_ns_ref
])
253 redef fun namespace
do
256 return new Namespace.from
([to_ns_ref
, ">": nullable NSEntity])
258 return new Namespace.from
([p
.namespace
, to_ns_ref
, ">": nullable NSEntity])
263 redef fun namespace
do
264 var mgroup
= self.mgroup
265 if mgroup
== null then
266 return new Namespace.from
([to_ns_ref
])
268 return new Namespace.from
([mgroup
.mpackage
.to_ns_ref
, "::", to_ns_ref
: nullable NSEntity])
271 private fun ns_for
(visibility
: MVisibility): nullable Namespace do
272 if visibility
<= private_visibility
then return namespace
273 var mgroup
= self.mgroup
274 if mgroup
== null then return namespace
275 return mgroup
.mpackage
.namespace
280 redef fun namespace
do
281 return new Namespace.from
([intro_mmodule
.ns_for
(visibility
), "::", to_ns_ref
: nullable NSEntity])
285 redef class MClassDef
286 redef fun namespace
do
288 return new Namespace.from
([mmodule
.ns_for
(mclass
.visibility
), "$", to_ns_ref
: nullable NSEntity])
289 else if mclass
.intro_mmodule
.mpackage
!= mmodule
.mpackage
then
290 return new Namespace.from
([mmodule
.namespace
, "$", mclass
.namespace
: nullable NSEntity])
291 else if mclass
.visibility
> private_visibility
then
292 return new Namespace.from
([mmodule
.namespace
, "$", mclass
.to_ns_ref
: nullable NSEntity])
294 return new Namespace.from
([mmodule
.full_name
, "$::", mclass
.intro_mmodule
.to_ns_ref
: nullable NSEntity])
298 redef class MProperty
299 redef fun namespace
do
300 if intro_mclassdef
.is_intro
then
301 return new Namespace.from
([intro_mclassdef
.mmodule
.ns_for
(visibility
), "::", intro_mclassdef
.mclass
.to_ns_ref
, "::", to_ns_ref
: nullable NSEntity])
303 return new Namespace.from
([intro_mclassdef
.mmodule
.namespace
, "::", intro_mclassdef
.mclass
.to_ns_ref
, "::", to_ns_ref
: nullable NSEntity])
309 redef fun namespace
do
310 var res
= new Namespace
311 res
.add mclassdef
.namespace
314 if mclassdef
.mclass
== mproperty
.intro_mclassdef
.mclass
then
317 if mclassdef
.mmodule
.mpackage
!= mproperty
.intro_mclassdef
.mmodule
.mpackage
then
318 res
.add mproperty
.intro_mclassdef
.mmodule
.ns_for
(mproperty
.visibility
)
320 else if mproperty
.visibility
<= private_visibility
then
321 if mclassdef
.mmodule
.namespace_for
(mclassdef
.mclass
.visibility
) != mproperty
.intro_mclassdef
.mmodule
.mpackage
then
323 res
.add mproperty
.intro_mclassdef
.mmodule
.to_ns_ref
327 if mclassdef
.mclass
!= mproperty
.intro_mclassdef
.mclass
then
328 res
.add mproperty
.intro_mclassdef
.to_ns_ref
337 redef class MClassType
338 redef var web_url
= mclass
.web_url
is lazy
341 redef class MNullableType
342 redef var web_url
= mtype
.web_url
is lazy
345 redef class MParameterType
346 redef var web_url
= mclass
.web_url
is lazy
349 redef class MVirtualType
350 redef var web_url
= mproperty
.web_url
is lazy
353 redef class POSetElement[E
]
356 # Return JSON representation of `self`.
357 fun json
: JsonObject do
358 assert self isa POSetElement[MEntity]
359 var obj
= new JsonObject
360 obj
["greaters"] = to_mentity_refs
(greaters
)
361 obj
["direct_greaters"] = to_mentity_refs
(direct_greaters
)
362 obj
["direct_smallers"] = to_mentity_refs
(direct_smallers
)
363 obj
["smallers"] = to_mentity_refs
(smallers
)
367 redef fun to_json
do return json
.to_json