+++ /dev/null
-# This file is part of NIT ( http://www.nitlanguage.org ).
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-
-module model_api
-
-import web_base
-import highlight
-import uml
-
-# List all mentities.
-#
-# MEntities can be filtered on their kind using the `k` parameter.
-# Allowed kinds are `package`, `group`, `module`, `class`, `classdef`, `property`, `propdef`.
-#
-# List size can be limited with the `n` parameter.
-#
-# Example: `GET /list?k=module?n=10`
-class APIList
- super APIHandler
-
- # List mentities depending on the `k` kind parameter.
- fun list_mentities(req: HttpRequest): Array[MEntity] do
- var k = req.string_arg("k")
- var mentities = new Array[MEntity]
- if k == "package" then
- for mentity in view.mpackages do mentities.add mentity
- else if k == "group" then
- for mentity in view.mgroups do mentities.add mentity
- else if k == "module" then
- for mentity in view.mmodules do mentities.add mentity
- else if k == "class" then
- for mentity in view.mclasses do mentities.add mentity
- else if k == "classdef" then
- for mentity in view.mclassdefs do mentities.add mentity
- else if k == "property" then
- for mentity in view.mproperties do mentities.add mentity
- else if k == "propdef" then
- for mentity in view.mpropdefs do mentities.add mentity
- else
- for mentity in view.mentities do mentities.add mentity
- end
- return mentities
- end
-
- # Limit mentities depending on the `n` parameter.
- fun limit_mentities(req: HttpRequest, mentities: Array[MEntity]): Array[MEntity] do
- var n = req.int_arg("n")
- if n != null then
- return mentities.sub(0, n)
- end
- return mentities
- end
-
- redef fun get(req, res) do
- var mentities = list_mentities(req)
- mentities = limit_mentities(req, mentities)
- 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
-
-# Return a random list of MEntities.
-#
-# Example: `GET /random?n=10&k=module`
-class APIRandom
- super APIList
-
- # Randomize mentities order.
- fun randomize_mentities(req: HttpRequest, mentities: Array[MEntity]): Array[MEntity] do
- var res = mentities.to_a
- res.shuffle
- return res
- end
-
- redef fun get(req, res) do
- 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
-
-# List ancestors, parents, child and descendants of MEntity
-#
-# Example: `GET /entity/core::Array/inheritance`
-class APIEntityInheritance
- super APIHandler
-
- redef fun get(req, res) do
- var mentity = mentity_from_uri(req, res)
- if mentity == null then
- res.error 404
- return
- end
- res.json mentity.hierarchy_poset(view)[mentity]
- 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
- 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
-
-abstract class SVGHandler
- super APIHandler
-
- # Render a `dot` string as a svg image.
- fun render_dot(dot: Text): String do
- var proc = new ProcessDuplex("dot", "-Tsvg")
- var svg = proc.write_and_read(dot)
- proc.close
- proc.wait
- return svg
- end
-end
-
-# Return a UML representation of MEntity.
-#
-# Example: `GET /entity/core::Array/uml`
-class APIEntityUML
- super SVGHandler
-
- 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_dot(dot)
- end
-end
-
-# Return the source code of MEntity.
-#
-# Example: `GET /entity/core::Array/code`
-class APIEntityCode
- super APIHandler
-
- # Modelbuilder used to access sources.
- var modelbuilder: ModelBuilder
-
- redef fun get(req, res) do
- var mentity = mentity_from_uri(req, res)
- if mentity == null then return
- var source = render_source(mentity)
- if source == null then
- res.error 404
- return
- end
- res.send source
- end
-
- # Highlight `mentity` source code.
- private fun render_source(mentity: MEntity): nullable HTMLTag do
- var node = modelbuilder.mentity2node(mentity)
- if node == null then return null
- var hl = new HighlightVisitor
- hl.enter_visit node
- return hl.html
- end
-end