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