lib/html: escape Bootstrap links titles
[nit.git] / src / doc / api / api_base.nit
index d683dab..4c3db90 100644 (file)
 # Base classes used by `nitweb`.
 module api_base
 
-import model::model_views
-import model::model_json
-import doc_down
 import popcorn
 import popcorn::pop_config
 import popcorn::pop_repos
 import popcorn::pop_json
 
+import commands::commands_http
+import commands::commands_json
+import commands::commands_html
+
 # Nitweb config file.
 class NitwebConfig
        super AppConfig
@@ -38,8 +39,11 @@ class NitwebConfig
        # Modelbuilder used to access sources.
        var modelbuilder: ModelBuilder
 
-       # ModelView used to access model.
-       var view: ModelView
+       # The JSON API does not filter anything by default.
+       var filter: nullable ModelFilter
+
+       # Catalog to pass to handlers.
+       var catalog: Catalog
 end
 
 # Specific handler for the nitweb API.
@@ -50,11 +54,13 @@ abstract class APIHandler
        var config: NitwebConfig
 
        # Find the MEntity ` with `full_name`.
-       fun find_mentity(model: ModelView, full_name: nullable String): nullable MEntity do
+       fun find_mentity(full_name: nullable String): nullable MEntity do
                if full_name == null then return null
-               var mentity = model.mentity_by_full_name(full_name.from_percent_encoding)
+               var mentity = config.model.mentity_by_full_name(full_name.from_percent_encoding, config.filter)
                if mentity == null then return null
-               if config.view.accept_mentity(mentity) then return mentity
+
+               var filter = config.filter
+               if filter == null or filter.accept_mentity(mentity) then return mentity
                return null
        end
 
@@ -69,7 +75,7 @@ abstract class APIHandler
                        res.api_error(400, "Expected mentity full name")
                        return null
                end
-               var mentity = find_mentity(config.view, id)
+               var mentity = find_mentity(id)
                if mentity == null then
                        res.api_error(404, "MEntity `{id}` not found")
                end
@@ -143,27 +149,6 @@ redef class HttpResponse
        fun api_json(req: HttpRequest, serializable: nullable Serializable, status: nullable Int, plain, pretty: nullable Bool) do
                json(serializable, status, plain, req.bool_arg("pretty"))
        end
-
-       # Return the full version of `serializable` as a json string
-       #
-       # Uses `req` to define serializable options.
-       fun api_full_json(req: HttpRequest, serializable: nullable MEntity, status: nullable Int, plain, pretty: nullable Bool) do
-               if serializable == null then
-                       json(null, status)
-               else
-                       raw_json(serializable.serialize_to_full_json(
-                               plain or else true, req.bool_arg("pretty") or else false), status)
-               end
-       end
-       # Write data as JSON and set the right content type header.
-       fun raw_json(json: nullable String, status: nullable Int) do
-               header["Content-Type"] = media_types["json"].as(not null)
-               if json == null then
-                       send(null, status)
-               else
-                       send(json, status)
-               end
-       end
 end
 
 # An error returned by the API.
@@ -179,53 +164,6 @@ class APIError
        var message: String
 end
 
-# Fullname representation that can be used to build decorated links
-#
-# * MPackage: `mpackage_name`
-# * MGroup: `(mpackage_name::)mgroup_name`
-class Namespace
-       super Array[nullable NSEntity]
-       super NSEntity
-       serialize
-
-       redef fun to_s do return self.join("")
-       redef fun serialize_to(v) do to_a.serialize_to(v)
-end
-
-# Something that goes in a Namespace
-#
-# Can be either:
-# * a `NSToken` for tokens like `::`, `>` and `$`
-# * a `MSRef` for references to mentities
-interface NSEntity
-       super Serializable
-end
-
-# A reference to a MEntity that can be rendered as a link.
-#
-# We do not reuse `MEntityRef` ref since NSRef can be found in a ref and create
-# an infinite loop.
-class NSRef
-       super NSEntity
-       serialize
-
-       # The mentity to link to/
-       var mentity: MEntity
-
-       redef fun core_serialize_to(v) do
-               v.serialize_attribute("web_url", mentity.web_url)
-               v.serialize_attribute("api_url", mentity.api_url)
-               v.serialize_attribute("name", mentity.name)
-       end
-end
-
-# A namespace token representation
-#
-# Used for namespace tokens like `::`, `>` and `$`
-redef class String
-       super NSEntity
-end
-
 redef class MEntity
 
        # URL to `self` within the web interface.
@@ -234,168 +172,75 @@ redef class MEntity
        # URL to `self` within the JSON api.
        fun api_url: String do return "/api/entity/" / full_name
 
+       redef fun html_url do return web_url
+
        redef fun core_serialize_to(v) do
                super
-               v.serialize_attribute("namespace", namespace)
                v.serialize_attribute("web_url", web_url)
                v.serialize_attribute("api_url", api_url)
        end
-
-       # Return `self.full_name` as an object that can be serialized to json.
-       fun namespace: nullable Namespace do return null
-
-       # Return a new NSRef to `self`.
-       fun to_ns_ref: NSRef do return new NSRef(self)
 end
 
 redef class MEntityRef
        redef fun core_serialize_to(v) do
                super
-               v.serialize_attribute("namespace", mentity.namespace)
                v.serialize_attribute("web_url", mentity.web_url)
                v.serialize_attribute("api_url", mentity.api_url)
-               v.serialize_attribute("name", mentity.name)
-               v.serialize_attribute("mdoc", mentity.mdoc_or_fallback)
-               v.serialize_attribute("visibility", mentity.visibility.to_s)
-               v.serialize_attribute("modifiers", mentity.collect_modifiers)
-               v.serialize_attribute("class_name", mentity.class_name)
-               var mentity = self.mentity
-               if mentity isa MMethod then
-                       v.serialize_attribute("msignature", mentity.intro.msignature)
-               else if mentity isa MMethodDef then
-                       v.serialize_attribute("msignature", mentity.msignature)
-               else if mentity isa MVirtualTypeProp then
-                       v.serialize_attribute("bound", to_mentity_ref(mentity.intro.bound))
-               else if mentity isa MVirtualTypeDef then
-                       v.serialize_attribute("bound", to_mentity_ref(mentity.bound))
-               end
-               v.serialize_attribute("location", mentity.location)
-       end
-end
-
-redef class MDoc
-
-       # Add doc down processing
-       redef fun core_serialize_to(v) do
-               v.serialize_attribute("html_synopsis", html_synopsis.write_to_string)
-       end
-end
-
-redef class MPackage
-       redef fun namespace do return new Namespace.from([to_ns_ref])
-end
-
-redef class MGroup
-       redef fun namespace do
-               var p = parent
-               if p == null then
-                       return new Namespace.from([to_ns_ref, ">": nullable NSEntity])
-               end
-               return new Namespace.from([p.namespace, to_ns_ref, ">": nullable NSEntity])
-       end
-end
-
-redef class MModule
-       redef fun namespace do
-               var mgroup = self.mgroup
-               if mgroup == null then
-                       return new Namespace.from([to_ns_ref])
-               end
-               return new Namespace.from([mgroup.mpackage.to_ns_ref, "::", to_ns_ref: nullable NSEntity])
-       end
-
-       private fun ns_for(visibility: MVisibility): nullable Namespace do
-               if visibility <= private_visibility then return namespace
-               var mgroup = self.mgroup
-               if mgroup == null then return namespace
-               return mgroup.mpackage.namespace
-       end
-end
-
-redef class MClass
-       redef fun namespace do
-               return new Namespace.from([intro_mmodule.ns_for(visibility), "::", to_ns_ref: nullable NSEntity])
        end
 end
 
 redef class MClassDef
-       redef fun namespace do
-               if is_intro then
-                       return new Namespace.from([mmodule.ns_for(mclass.visibility), "$", to_ns_ref: nullable NSEntity])
-               else if mclass.intro_mmodule.mpackage != mmodule.mpackage then
-                       return new Namespace.from([mmodule.namespace, "$", mclass.namespace: nullable NSEntity])
-               else if mclass.visibility > private_visibility then
-                       return new Namespace.from([mmodule.namespace, "$", mclass.to_ns_ref: nullable NSEntity])
-               end
-               return new Namespace.from([mmodule.full_name, "$::", mclass.intro_mmodule.to_ns_ref: nullable NSEntity])
-       end
-
        redef fun web_url do return "{mclass.web_url}/lin#{full_name}"
 end
 
-redef class MProperty
-       redef fun namespace do
-               if intro_mclassdef.is_intro then
-                       return new Namespace.from([intro_mclassdef.mmodule.ns_for(visibility), "::", intro_mclassdef.mclass.to_ns_ref, "::", to_ns_ref: nullable NSEntity])
-               else
-                       return new Namespace.from([intro_mclassdef.mmodule.namespace, "::", intro_mclassdef.mclass.to_ns_ref, "::", to_ns_ref: nullable NSEntity])
-               end
-       end
+redef class MPropDef
+       redef fun web_url do return "{mproperty.web_url}/lin#{full_name}"
 end
 
-redef class MPropDef
-       redef fun namespace do
-               var res = new Namespace
-               res.add mclassdef.namespace
-               res.add "$"
-
-               if mclassdef.mclass == mproperty.intro_mclassdef.mclass then
-                       res.add to_ns_ref
-               else
-                       if mclassdef.mmodule.mpackage != mproperty.intro_mclassdef.mmodule.mpackage then
-                               res.add mproperty.intro_mclassdef.mmodule.ns_for(mproperty.visibility)
-                               res.add "::"
-                       else if mproperty.visibility <= private_visibility then
-                               if mclassdef.mmodule.namespace_for(mclassdef.mclass.visibility) != mproperty.intro_mclassdef.mmodule.mpackage then
-                                       res.add "::"
-                                       res.add mproperty.intro_mclassdef.mmodule.to_ns_ref
-                                       res.add "::"
-                               end
-                       end
-                       if mclassdef.mclass != mproperty.intro_mclassdef.mclass then
-                               res.add mproperty.intro_mclassdef.to_ns_ref
-                               res.add "::"
-                       end
-                       res.add to_ns_ref
-               end
-               return res
+redef class MType
+       redef fun core_serialize_to(v) do
+               super
+               v.serialize_attribute("web_url", web_url)
+               v.serialize_attribute("api_url", api_url)
        end
-
-       redef fun web_url do return "{mproperty.web_url}/lin#{full_name}"
 end
 
 redef class MClassType
        redef var web_url = mclass.web_url is lazy
+       redef var api_url = mclass.api_url is lazy
 end
 
 redef class MNullableType
        redef var web_url = mtype.web_url is lazy
+       redef var api_url = mtype.api_url is lazy
 end
 
 redef class MParameterType
        redef var web_url = mclass.web_url is lazy
+       redef var api_url = mclass.api_url is lazy
 end
 
 redef class MVirtualType
        redef var web_url = mproperty.web_url is lazy
+       redef var api_url = mproperty.api_url is lazy
 end
 
-redef class POSetElement[E]
-       super Serializable
+redef class HtmlightVisitor
+       redef fun hrefto(mentity) do return mentity.html_url
+end
 
-       redef fun core_serialize_to(v) do
-               assert self isa POSetElement[MEntity]
-               v.serialize_attribute("direct_greaters", to_mentity_refs(direct_greaters))
-               v.serialize_attribute("direct_smallers", to_mentity_refs(direct_smallers))
+redef class CmdLicenseFile
+       redef var file_url is lazy do
+               var mentity = self.mentity
+               if mentity == null then return super
+               return "{mentity.web_url}/license"
+       end
+end
+
+redef class CmdContribFile
+       redef var file_url is lazy do
+               var mentity = self.mentity
+               if mentity == null then return super
+               return "{mentity.web_url}/contrib"
        end
 end