cc57e405679692f8ef37726c044698df48f526b0
[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 redef fun core_serialize_to(v) do
158 for metric in metrics do
159 v.serialize_attribute(metric.name, metric)
160 end
161 end
162 end
163
164 redef class Metric
165 super Jsonable
166
167 redef fun core_serialize_to(v) do
168 v.serialize_attribute("name", name)
169 v.serialize_attribute("desc", desc)
170 v.serialize_attribute("empty", values.is_empty)
171 if values.not_empty then v.serialize_attribute("avg", avg)
172 if values.not_empty then v.serialize_attribute("std_dev", std_dev)
173 if values.not_empty then v.serialize_attribute("threshold", threshold)
174 end
175 end
176
177 redef class IntMetric
178 redef fun core_serialize_to(v) do
179 super
180 if values.not_empty then v.serialize_attribute("sum", sum)
181 end
182 end
183
184 redef class FloatMetric
185 redef fun core_serialize_to(v) do
186 super
187 if values.not_empty then v.serialize_attribute("sum", sum)
188 end
189 end
190
191 redef class MModuleMetric
192 redef fun core_serialize_to(v) do
193 super
194 if values.not_empty then v.serialize_attribute("min", min)
195 if values.not_empty then v.serialize_attribute("max", max)
196 var values = new JsonObject
197 for value in sort do
198 values[value.full_name] = new MetricEntry(value, self[value])
199 end
200 v.serialize_attribute("values", values)
201 end
202 end
203
204 redef class MClassMetric
205 redef fun core_serialize_to(v) do
206 super
207 if values.not_empty then v.serialize_attribute("min", min)
208 if values.not_empty then v.serialize_attribute("max", max)
209 var values = new JsonObject
210 for value in sort do
211 values[value.full_name] = new MetricEntry(value, self[value])
212 end
213 v.serialize_attribute("values", values)
214 end
215 end
216
217 private class MetricEntry
218 super Jsonable
219
220 var mentity: MEntity
221 var value: Object
222
223 redef fun core_serialize_to(v) do
224 v.serialize_attribute("mentity", mentity)
225 v.serialize_attribute("value", if value isa JsonObject then value else value.to_s)
226 end
227 end