-
Notifications
You must be signed in to change notification settings - Fork 33
Expand file tree
/
Copy pathJarFileMetrics.java
More file actions
123 lines (101 loc) · 4.13 KB
/
Copy pathJarFileMetrics.java
File metadata and controls
123 lines (101 loc) · 4.13 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
package org.example.model;
import lombok.Data;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
@Data
public class JarFileMetrics {
private Map<String, String> classNameToParentName;
private Map<String, List<String>> classNameToMethodSignatures;
private Map<String, Integer> classNameToMaxDepth;
private Map<String, Integer> classNameToOverriddenMethodsCount;
private Map<String, ClassMetrics> classNameToClassMetrics;
public JarFileMetrics() {
this.classNameToParentName = new HashMap<>();
this.classNameToMethodSignatures = new HashMap<>();
this.classNameToMaxDepth = new HashMap<>();
this.classNameToOverriddenMethodsCount = new HashMap<>();
this.classNameToClassMetrics = new HashMap<>();
}
public void addClassNameToParentName(String className, String classParentName) {
this.classNameToParentName.put(className, classParentName);
}
public void addClassNameToMethodsSignatures(String className, List<String> methodSignatures) {
this.classNameToMethodSignatures.put(className, methodSignatures);
}
public void addClassNameToClassMetrics(ClassMetrics classMetrics) {
this.classNameToClassMetrics.put(classMetrics.getName(), classMetrics);
}
public void calculateMetrics() {
for (var className : classNameToParentName.keySet()) {
calculateMaxDepth(className);
}
for (var className : classNameToMethodSignatures.keySet()) {
var methods = classNameToMethodSignatures.get(className);
countOverriddenMethods(className, methods);
}
}
public int getMaxInheritanceDepth() {
return classNameToMaxDepth.values().stream()
.max(Integer::compareTo)
.orElse(0);
}
public double getAvgInheritanceDepth() {
return classNameToMaxDepth.values().stream()
.mapToInt(Integer::intValue)
.average()
.orElse(0.0);
}
public double getAvgAbcMetric() {
return classNameToClassMetrics.values().stream()
.flatMap(classMetrics -> classMetrics.getMethodMetrics().stream())
.map(MethodMetrics::getAbcMetric)
.mapToDouble(ABCMetric::getMetricValue)
.average()
.orElse(0.0);
}
public double getAvgOverriddenMethods() {
return classNameToOverriddenMethodsCount.values().stream()
.mapToInt(Integer::intValue)
.average()
.orElse(0.0);
}
public double getAvgFieldCount() {
return classNameToClassMetrics.values().stream()
.mapToInt(ClassMetrics::getFieldCount)
.average()
.orElse(0.0);
}
private void calculateMaxDepth(String className) {
var depth = 0;
var currentClassName = className;
while (classNameToParentName.containsKey(currentClassName)) {
depth++;
currentClassName = classNameToParentName.get(currentClassName);
}
classNameToMaxDepth.put(className, depth);
}
private void countOverriddenMethods(String className, List<String> methods) {
if (!classNameToParentName.containsKey(className)) {
classNameToOverriddenMethodsCount.put(className, 0);
return;
}
var parent = classNameToParentName.get(className);
Set<String> inheritedMethods = new HashSet<>();
// Собираем все методы всех родительских классов
while (parent != null) {
var parentMethods = classNameToMethodSignatures.get(parent);
if (parentMethods != null) {
inheritedMethods.addAll(parentMethods);
}
parent = classNameToParentName.get(parent);
}
// Считаем переопределения
var overriddenCount = methods.stream()
.filter(inheritedMethods::contains)
.count();
classNameToOverriddenMethodsCount.put(className, (int) overriddenCount);
}
}