import model::model_json
import doc_down
import popcorn
+import popcorn::pop_config
-# Specific nitcorn Action that uses a Model
-class ModelAction
- super Handler
+# Nitweb config file.
+class NitwebConfig
+ super AppConfig
# Model to use.
var model: Model
# MModule used to flatten model.
var mainmodule: MModule
+ # Modelbuilder used to access sources.
+ var modelbuilder: ModelBuilder
+end
+
+# Specific nitcorn Action that uses a Model
+class ModelHandler
+ super Handler
+
+ # App config.
+ var config: NitwebConfig
+
# Find the MEntity ` with `full_name`.
fun find_mentity(model: ModelView, full_name: nullable String): nullable MEntity do
if full_name == null then return null
# Init the model view from the `req` uri parameters.
fun init_model_view(req: HttpRequest): ModelView do
- var view = new ModelView(model)
+ var view = new ModelView(config.model)
var show_private = req.bool_arg("private") or else false
if not show_private then view.min_visibility = protected_visibility
end
end
-# A NitView is rendered by an action.
-interface NitView
- # Renders this view and returns something that can be written to a HTTP response.
- fun render: Writable is abstract
-end
+# Specific handler for nitweb API.
+abstract class APIHandler
+ super ModelHandler
-redef class HttpResponse
- # Render a NitView as response.
- fun send_view(view: NitView, status: nullable Int) do send(view.render, status)
-end
+ # The JSON API does not filter anything by default.
+ #
+ # So we can cache the model view.
+ var view: ModelView is lazy do
+ var view = new ModelView(config.model)
+ view.min_visibility = private_visibility
+ view.include_fictive = true
+ view.include_empty_doc = true
+ view.include_attribute = true
+ view.include_test_suite = true
+ return view
+ end
-redef class HttpRequest
- # Does the client asked for a json formatted response?
+ # Try to load the mentity from uri with `/:id`.
#
- # Checks the URL get parameter `?json=true`.
- fun is_json_asked: Bool do return bool_arg("json") or else false
+ # Send 400 if `:id` is null.
+ # Send 404 if no entity is found.
+ # Return null in both cases.
+ fun mentity_from_uri(req: HttpRequest, res: HttpResponse): nullable MEntity do
+ var id = req.param("id")
+ if id == null then
+ res.error 400
+ return null
+ end
+ var mentity = find_mentity(view, id)
+ if mentity == null then
+ res.error 404
+ end
+ return mentity
+ end
+end
+
+# A Rooter dedicated to APIHandlers.
+class APIRouter
+ super Router
+
+ # App config.
+ var config: NitwebConfig
end
redef class MEntity
# URL to `self` within the web interface.
- fun web_url: String is abstract
+ fun web_url: String do return "/doc/" / full_name
# URL to `self` within the JSON api.
fun api_url: String do return "/api/entity/" / full_name
modifiers.add modifier
end
obj["modifiers"] = modifiers
+ var mentity = self.mentity
+ if mentity isa MMethod then
+ obj["msignature"] = mentity.intro.msignature
+ else if mentity isa MMethodDef then
+ obj["msignature"] = mentity.msignature
+ else if mentity isa MVirtualTypeProp then
+ obj["bound"] = to_mentity_ref(mentity.intro.bound)
+ else if mentity isa MVirtualTypeDef then
+ obj["bound"] = to_mentity_ref(mentity.bound)
+ end
return obj
end
end
end
end
-redef class MPackage
- redef var web_url = "/package/{full_name}" is lazy
-end
-
-redef class MGroup
- redef var web_url = "/group/{full_name}" is lazy
-end
-
redef class MModule
- redef var web_url = "/module/{full_name}" is lazy
-
redef fun api_json(handler) do
var obj = super
obj["intro_mclassdefs"] = to_mentity_refs(collect_intro_mclassdefs(private_view))
end
redef class MClass
- redef var web_url = "/class/{full_name}" is lazy
-
redef fun api_json(handler) do
var obj = super
obj["all_mproperties"] = to_mentity_refs(collect_accessible_mproperties(private_view))
obj["intro_mproperties"] = to_mentity_refs(collect_intro_mproperties(private_view))
obj["redef_mproperties"] = to_mentity_refs(collect_redef_mproperties(private_view))
- var poset = hierarchy_poset(handler.mainmodule, private_view)
- obj["parents"] = to_mentity_refs(poset[self].direct_greaters)
+ obj["parents"] = to_mentity_refs(collect_parents(private_view))
return obj
end
end
redef class MClassDef
- redef var web_url = "/classdef/{full_name}" is lazy
-
redef fun json do
var obj = super
obj["intro"] = to_mentity_ref(mclass.intro)
end
redef class MProperty
- redef var web_url = "/property/{full_name}" is lazy
-
redef fun json do
var obj = super
obj["intro_mclass"] = to_mentity_ref(intro_mclassdef.mclass)
end
redef class MPropDef
- redef var web_url = "/propdef/{full_name}" is lazy
-
redef fun json do
var obj = super
obj["intro"] = to_mentity_ref(mproperty.intro)
redef class MVirtualType
redef var web_url = mproperty.web_url is lazy
end
+
+redef class POSetElement[E]
+ super Jsonable
+
+ # Return JSON representation of `self`.
+ fun json: JsonObject do
+ assert self isa POSetElement[MEntity]
+ var obj = new JsonObject
+ obj["greaters"] = to_mentity_refs(greaters)
+ obj["direct_greaters"] = to_mentity_refs(direct_greaters)
+ obj["direct_smallers"] = to_mentity_refs(direct_smallers)
+ obj["smallers"] = to_mentity_refs(smallers)
+ return obj
+ end
+
+ redef fun to_json do return json.to_json
+end