nitweb: split APIRouter in modules
[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
73 res.error 404
74 return
75 end
76 var metrics = mentity.collect_metrics(self)
77 if metrics == null then
78 res.error 404
79 return
80 end
81 res.json metrics
82 end
83 end
84
85 redef class MEntity
86 private fun collect_metrics(h: APIStructuralMetrics): nullable JsonObject do return null
87 end
88
89 redef class MPackage
90 redef fun collect_metrics(h) do
91 var mclasses = new HashSet[MClass]
92 for mgroup in self.mgroups do
93 for mmodule in mgroup.mmodules do mclasses.add_all mmodule.intro_mclasses
94 end
95
96 var mclasses_metrics = h.mclasses_metrics
97 mclasses_metrics.collect(new HashSet[MClass].from(mclasses))
98
99 var mmodules = new HashSet[MModule]
100 for mgroup in self.mgroups do
101 mmodules.add_all mgroup.mmodules
102 end
103
104 var mmodules_metrics = h.mmodules_metrics
105 mmodules_metrics.collect(new HashSet[MModule].from(mmodules))
106
107 var metrics = new JsonObject
108 metrics["mclasses"] = mclasses_metrics
109 metrics["mmodules"] = mmodules_metrics
110 return metrics
111 end
112 end
113
114 redef class MGroup
115 redef fun collect_metrics(h) do
116 var mclasses = new HashSet[MClass]
117 for mmodule in self.mmodules do mclasses.add_all mmodule.intro_mclasses
118
119 var mclasses_metrics = h.mclasses_metrics
120 mclasses_metrics.collect(new HashSet[MClass].from(mclasses))
121
122 var mmodules_metrics = h.mmodules_metrics
123 mmodules_metrics.collect(new HashSet[MModule].from(mmodules))
124
125 var metrics = new JsonObject
126 metrics["mclasses"] = mclasses_metrics
127 metrics["mmodules"] = mmodules_metrics
128 return metrics
129 end
130 end
131
132 redef class MModule
133 redef fun collect_metrics(h) do
134 var mclasses_metrics = h.mclasses_metrics
135 mclasses_metrics.collect(new HashSet[MClass].from(intro_mclasses))
136
137 var mmodule_metrics = h.mmodules_metrics
138 mmodule_metrics.collect(new HashSet[MModule].from([self]))
139
140 var metrics = new JsonObject
141 metrics["mclasses"] = mclasses_metrics
142 metrics["mmodule"] = mmodule_metrics
143 return metrics
144 end
145 end
146
147 redef class MClass
148 redef fun collect_metrics(h) do
149 var mclass_metrics = h.mclasses_metrics
150 mclass_metrics.collect(new HashSet[MClass].from([self]))
151
152 var metrics = new JsonObject
153 metrics["mclass"] = mclass_metrics
154 return metrics
155 end
156 end
157
158 redef class MetricSet
159 super Jsonable
160
161 fun json: JsonObject do
162 var obj = new JsonObject
163 for metric in metrics do
164 obj[metric.name] = metric
165 end
166 return obj
167 end
168
169 redef fun to_json do return json.to_json
170 end
171
172 redef class Metric
173 super Jsonable
174
175 fun json: JsonObject do
176 var obj = new JsonObject
177 obj["name"] = name
178 obj["desc"] = desc
179 obj["empty"] = values.is_empty
180 if values.not_empty then obj["avg"] = avg
181 if values.not_empty then obj["std_dev"] = std_dev
182 if values.not_empty then obj["threshold"] = threshold
183 return obj
184 end
185
186 redef fun to_json do return json.to_json
187 end
188
189 redef class IntMetric
190 redef fun json do
191 var obj = super
192 if values.not_empty then obj["sum"] = sum
193 return obj
194 end
195 end
196
197 redef class FloatMetric
198 redef fun json do
199 var obj = super
200 if values.not_empty then obj["sum"] = sum
201 return obj
202 end
203 end
204
205 redef class MModuleMetric
206 redef fun json do
207 var obj = super
208 if values.not_empty then obj["min"] = min
209 if values.not_empty then obj["max"] = max
210 var values = new JsonObject
211 for value in sort do
212 var v = self[value]
213 var vobj = new JsonObject
214 vobj["mentity"] = value
215 vobj["value"] = if v isa Jsonable then v else v.to_s
216 values[value.full_name] = vobj
217 end
218 obj["values"] = values
219 return obj
220 end
221 end
222
223 redef class MClassMetric
224 redef fun json do
225 var obj = super
226 if values.not_empty then obj["min"] = min
227 if values.not_empty then obj["max"] = max
228 var values = new JsonObject
229 for value in sort do
230 var v = self[value]
231 var vobj = new JsonObject
232 vobj["mentity"] = value
233 vobj["value"] = if v isa Jsonable then v else v.to_s
234 values[value.full_name] = vobj
235 end
236 obj["values"] = values
237 return obj
238 end
239 end