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