nitweb: use model_json `full_json`
[nit.git] / src / web / api_metrics.nit
1 # This file is part of NIT ( http://www.nitlanguage.org ).
2 #
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
6 #
7 # http://www.apache.org/licenses/LICENSE-2.0
8 #
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.
14
15 module api_metrics
16
17 import web_base
18 import metrics
19
20 redef class APIRouter
21 redef init do
22 super
23 use("/metrics/structural/:id", new APIStructuralMetrics(config))
24 end
25 end
26
27 class APIStructuralMetrics
28 super APIHandler
29
30 private fun mclasses_metrics: MetricSet do
31 var mainmodule = config.mainmodule
32 var metrics = new MetricSet
33 metrics.register(new CNOA(mainmodule, view))
34 metrics.register(new CNOP(mainmodule, view))
35 metrics.register(new CNOC(mainmodule, view))
36 metrics.register(new CNOD(mainmodule, view))
37 metrics.register(new CNOAC(mainmodule, view))
38 metrics.register(new CNOAA(mainmodule, view))
39 metrics.register(new CNOAI(mainmodule, view))
40 metrics.register(new CDIT(mainmodule, view))
41 metrics.register(new CNBP(mainmodule, view))
42 metrics.register(new CNBA(mainmodule, view))
43 metrics.register(new CNBM(mainmodule, view))
44 metrics.register(new CNBI(mainmodule, view))
45 metrics.register(new CNBV(mainmodule, view))
46 metrics.register(new CNBIP(mainmodule, view))
47 metrics.register(new CNBRP(mainmodule, view))
48 metrics.register(new CNBHP(mainmodule, view))
49 metrics.register(new CNBLP(mainmodule, view))
50 return metrics
51 end
52
53 private fun mmodules_metrics: MetricSet do
54 var mainmodule = config.mainmodule
55 var metrics = new MetricSet
56 metrics.register(new MNOA(mainmodule, view))
57 metrics.register(new MNOP(mainmodule, view))
58 metrics.register(new MNOC(mainmodule, view))
59 metrics.register(new MNOD(mainmodule, view))
60 metrics.register(new MDIT(mainmodule, view))
61 metrics.register(new MNBD(mainmodule, view))
62 metrics.register(new MNBI(mainmodule, view))
63 metrics.register(new MNBR(mainmodule, view))
64 metrics.register(new MNBCC(mainmodule, view))
65 metrics.register(new MNBAC(mainmodule, view))
66 metrics.register(new MNBIC(mainmodule, view))
67 return metrics
68 end
69
70 redef fun get(req, res) do
71 var mentity = mentity_from_uri(req, res)
72 if mentity == null then return
73 var metrics = mentity.collect_metrics(self)
74 if metrics == null then
75 res.api_error(404, "No metric for mentity `{mentity.full_name}`")
76 return
77 end
78 res.json metrics
79 end
80 end
81
82 redef class MEntity
83 private fun collect_metrics(h: APIStructuralMetrics): nullable JsonObject do return null
84 end
85
86 redef class MPackage
87 redef fun collect_metrics(h) do
88 var mclasses = new HashSet[MClass]
89 for mgroup in self.mgroups do
90 for mmodule in mgroup.mmodules do mclasses.add_all mmodule.intro_mclasses
91 end
92
93 var mclasses_metrics = h.mclasses_metrics
94 mclasses_metrics.collect(new HashSet[MClass].from(mclasses))
95
96 var mmodules = new HashSet[MModule]
97 for mgroup in self.mgroups do
98 mmodules.add_all mgroup.mmodules
99 end
100
101 var mmodules_metrics = h.mmodules_metrics
102 mmodules_metrics.collect(new HashSet[MModule].from(mmodules))
103
104 var metrics = new JsonObject
105 metrics["mclasses"] = mclasses_metrics
106 metrics["mmodules"] = mmodules_metrics
107 return metrics
108 end
109 end
110
111 redef class MGroup
112 redef fun collect_metrics(h) do
113 var mclasses = new HashSet[MClass]
114 for mmodule in self.mmodules do mclasses.add_all mmodule.intro_mclasses
115
116 var mclasses_metrics = h.mclasses_metrics
117 mclasses_metrics.collect(new HashSet[MClass].from(mclasses))
118
119 var mmodules_metrics = h.mmodules_metrics
120 mmodules_metrics.collect(new HashSet[MModule].from(mmodules))
121
122 var metrics = new JsonObject
123 metrics["mclasses"] = mclasses_metrics
124 metrics["mmodules"] = mmodules_metrics
125 return metrics
126 end
127 end
128
129 redef class MModule
130 redef fun collect_metrics(h) do
131 var mclasses_metrics = h.mclasses_metrics
132 mclasses_metrics.collect(new HashSet[MClass].from(intro_mclasses))
133
134 var mmodule_metrics = h.mmodules_metrics
135 mmodule_metrics.collect(new HashSet[MModule].from([self]))
136
137 var metrics = new JsonObject
138 metrics["mclasses"] = mclasses_metrics
139 metrics["mmodule"] = mmodule_metrics
140 return metrics
141 end
142 end
143
144 redef class MClass
145 redef fun collect_metrics(h) do
146 var mclass_metrics = h.mclasses_metrics
147 mclass_metrics.collect(new HashSet[MClass].from([self]))
148
149 var metrics = new JsonObject
150 metrics["mclass"] = mclass_metrics
151 return metrics
152 end
153 end
154
155 redef class MetricSet
156 super Jsonable
157
158 fun json: JsonObject do
159 var obj = new JsonObject
160 for metric in metrics do
161 obj[metric.name] = metric
162 end
163 return obj
164 end
165
166 redef fun to_json do return json.to_json
167 end
168
169 redef class Metric
170 super Jsonable
171
172 fun json: JsonObject do
173 var obj = new JsonObject
174 obj["name"] = name
175 obj["desc"] = desc
176 obj["empty"] = values.is_empty
177 if values.not_empty then obj["avg"] = avg
178 if values.not_empty then obj["std_dev"] = std_dev
179 if values.not_empty then obj["threshold"] = threshold
180 return obj
181 end
182
183 redef fun to_json do return json.to_json
184 end
185
186 redef class IntMetric
187 redef fun json do
188 var obj = super
189 if values.not_empty then obj["sum"] = sum
190 return obj
191 end
192 end
193
194 redef class FloatMetric
195 redef fun json do
196 var obj = super
197 if values.not_empty then obj["sum"] = sum
198 return obj
199 end
200 end
201
202 redef class MModuleMetric
203 redef fun json do
204 var obj = super
205 if values.not_empty then obj["min"] = min
206 if values.not_empty then obj["max"] = max
207 var values = new JsonObject
208 for value in sort do
209 var v = self[value]
210 var vobj = new JsonObject
211 vobj["mentity"] = value
212 vobj["value"] = if v isa Jsonable then v else v.to_s
213 values[value.full_name] = vobj
214 end
215 obj["values"] = values
216 return obj
217 end
218 end
219
220 redef class MClassMetric
221 redef fun json do
222 var obj = super
223 if values.not_empty then obj["min"] = min
224 if values.not_empty then obj["max"] = max
225 var values = new JsonObject
226 for value in sort do
227 var v = self[value]
228 var vobj = new JsonObject
229 vobj["mentity"] = value
230 vobj["value"] = if v isa Jsonable then v else v.to_s
231 values[value.full_name] = vobj
232 end
233 obj["values"] = values
234 return obj
235 end
236 end