X-Git-Url: http://nitlanguage.org diff --git a/src/web/model_api.nit b/src/web/model_api.nit index 78d6063..0d4c205 100644 --- a/src/web/model_api.nit +++ b/src/web/model_api.nit @@ -16,83 +16,7 @@ module model_api import web_base import highlight - -# Specific handler for nitweb API. -abstract class APIHandler - super ModelHandler - - # 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(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 - - # Try to load the mentity from uri with `/:id`. - # - # 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 - -# Group all api handlers in one router. -class APIRouter - super Router - - # Model to pass to handlers. - var model: Model - - # ModelBuilder to pass to handlers. - var modelbuilder: ModelBuilder - - # Mainmodule to pass to handlers. - var mainmodule: MModule - - init do - use("/list", new APIList(model, mainmodule)) - use("/search", new APISearch(model, mainmodule)) - use("/random", new APIRandom(model, mainmodule)) - use("/code/:id", new APIEntityCode(model, mainmodule, modelbuilder)) - end -end - -# Search mentities from a query string. -# -# Example: `GET /search?q=Arr` -class APISearch - super APIHandler - - redef fun get(req, res) do - var q = req.string_arg("q") - if q == null then - res.error 400 - return - end - var arr = new JsonArray - for mentity in view.mentities do - if mentity.name.has_prefix(q) then arr.add mentity - end - res.json arr - end -end +import uml # List all mentities. # @@ -141,9 +65,24 @@ class APIList redef fun get(req, res) do var mentities = list_mentities(req) mentities = limit_mentities(req, mentities) - var arr = new JsonArray - for mentity in mentities do arr.add mentity - res.json arr + res.json new JsonArray.from(mentities) + end +end + +# Search mentities from a query string. +# +# Example: `GET /search?q=Arr` +class APISearch + super APIList + + redef fun list_mentities(req) do + var q = req.string_arg("q") + var mentities = new Array[MEntity] + if q == null then return mentities + for mentity in view.mentities do + if mentity.name.has_prefix(q) then mentities.add mentity + end + return mentities end end @@ -164,12 +103,102 @@ class APIRandom var mentities = list_mentities(req) mentities = limit_mentities(req, mentities) mentities = randomize_mentities(req, mentities) + res.json new JsonArray.from(mentities) + end +end + +# Return the JSON representation of a MEntity. +# +# Example: `GET /entity/core::Array` +class APIEntity + super APIHandler + + redef fun get(req, res) do + var mentity = mentity_from_uri(req, res) + if mentity == null then return + res.json mentity.api_json(self) + end +end + +# Linearize super definitions of a MClassDef or a MPropDef if any. +# +# Example: `GET /entity/core::Array/linearization` +class APIEntityLinearization + super APIHandler + + redef fun get(req, res) do + var mentity = mentity_from_uri(req, res) + if mentity == null then + res.error 404 + return + end + var lin = mentity.collect_linearization(mainmodule) + if lin == null then + res.error 404 + return + end + res.json new JsonArray.from(lin) + end +end + +# List definitions of a MEntity. +# +# Example: `GET /defs/core::Array` +class APIEntityDefs + super APIHandler + + redef fun get(req, res) do + var mentity = mentity_from_uri(req, res) var arr = new JsonArray - for mentity in mentities do arr.add mentity + if mentity isa MModule then + for mclassdef in mentity.mclassdefs do arr.add mclassdef + else if mentity isa MClass then + for mclassdef in mentity.mclassdefs do arr.add mclassdef + else if mentity isa MClassDef then + for mpropdef in mentity.mpropdefs do arr.add mpropdef + else if mentity isa MProperty then + for mpropdef in mentity.mpropdefs do arr.add mpropdef + else + res.error 404 + return + end res.json arr end end +# Return a UML representation of MEntity. +# +# Example: `GET /entity/core::Array/uml` +class APIEntityUML + super APIHandler + + redef fun get(req, res) do + var mentity = mentity_from_uri(req, res) + var dot + if mentity isa MClassDef then mentity = mentity.mclass + if mentity isa MClass then + var uml = new UMLModel(view, mainmodule) + dot = uml.generate_class_uml.write_to_string + else if mentity isa MModule then + var uml = new UMLModel(view, mentity) + dot = uml.generate_package_uml.write_to_string + else + res.error 404 + return + end + res.send render_svg(dot) + end + + # Render a `dot` string as a svg image. + fun render_svg(dot: String): String do + var proc = new ProcessDuplex("dot", "-Tsvg") + var svg = proc.write_and_read(dot) + proc.close + proc.wait + return svg + end +end + # Return the source code of MEntity. # # Example: `GET /entity/core::Array/code`