@@ -73,73 +73,125 @@ public List<RankedCycle> runCycleAnalysis() {
73
73
StaticJavaParser .getParserConfiguration ().setLanguageLevel (ParserConfiguration .LanguageLevel .BLEEDING_EDGE );
74
74
List <RankedCycle > rankedCycles = new ArrayList <>();
75
75
try {
76
- Map <String , String > classNamesAndPaths = getClassNamesAndPaths ();
77
- classReferencesGraph = javaProjectParser .getClassReferences (repositoryPath );
78
- CircularReferenceChecker circularReferenceChecker = new CircularReferenceChecker ();
79
- Map <String , AsSubgraph <String , DefaultWeightedEdge >> cyclesForEveryVertexMap =
80
- circularReferenceChecker .detectCycles (classReferencesGraph );
81
- cyclesForEveryVertexMap .forEach ((vertex , subGraph ) -> {
82
- int vertexCount = subGraph .vertexSet ().size ();
83
- int edgeCount = subGraph .edgeSet ().size ();
84
- double minCut = 0 ;
85
- Set <DefaultWeightedEdge > minCutEdges ;
86
- if (vertexCount > 1 && edgeCount > 1 && !isDuplicateSubGraph (subGraph , vertex )) {
87
- renderedSubGraphs .put (vertex , subGraph );
88
- log .info ("Vertex: " + vertex + " vertex count: " + vertexCount + " edge count: " + edgeCount );
89
- GusfieldGomoryHuCutTree <String , DefaultWeightedEdge > gusfieldGomoryHuCutTree =
90
- new GusfieldGomoryHuCutTree <>(new AsUndirectedGraph <>(subGraph ));
91
- minCut = gusfieldGomoryHuCutTree .calculateMinCut ();
92
- minCutEdges = gusfieldGomoryHuCutTree .getCutEdges ();
93
-
94
- List <CycleNode > cycleNodes = subGraph .vertexSet ().stream ()
95
- .map (classInCycle -> new CycleNode (classInCycle , classNamesAndPaths .get (classInCycle )))
96
- .collect (Collectors .toList ());
97
- List <ScmLogInfo > changeRanks = getRankedChangeProneness (cycleNodes );
98
-
99
- Map <String , CycleNode > cycleNodeMap = new HashMap <>();
100
-
101
- for (CycleNode cycleNode : cycleNodes ) {
102
- cycleNodeMap .put (cycleNode .getFileName (), cycleNode );
103
- }
76
+ boolean calculateCycleChurn = false ;
77
+ idenfifyRankedCycles (rankedCycles , calculateCycleChurn );
78
+ sortRankedCycles (rankedCycles , calculateCycleChurn );
79
+ setPriorities (rankedCycles );
80
+ } catch (IOException e ) {
81
+ throw new RuntimeException (e );
82
+ }
104
83
105
- for (ScmLogInfo changeRank : changeRanks ) {
106
- CycleNode cycleNode = cycleNodeMap .get (changeRank .getPath ());
107
- cycleNode .setScmLogInfo (changeRank );
108
- }
84
+ return rankedCycles ;
85
+ }
109
86
110
- // sum change proneness ranks
111
- int changePronenessRankSum = changeRanks .stream ()
112
- .mapToInt (ScmLogInfo ::getChangePronenessRank )
113
- .sum ();
114
- rankedCycles .add (new RankedCycle (
115
- vertex ,
116
- changePronenessRankSum ,
117
- subGraph .vertexSet (),
118
- subGraph .edgeSet (),
119
- minCut ,
120
- minCutEdges ,
121
- cycleNodes ));
122
- }
123
- });
87
+ public List <RankedCycle > runCycleAnalysisAndCalculateCycleChurn () {
88
+ StaticJavaParser .getParserConfiguration ().setLanguageLevel (ParserConfiguration .LanguageLevel .BLEEDING_EDGE );
89
+ List <RankedCycle > rankedCycles = new ArrayList <>();
90
+ try {
91
+ boolean calculateCycleChurn = true ;
92
+ idenfifyRankedCycles (rankedCycles , calculateCycleChurn );
93
+ sortRankedCycles (rankedCycles , calculateCycleChurn );
94
+ setPriorities (rankedCycles );
95
+ } catch (IOException e ) {
96
+ throw new RuntimeException (e );
97
+ }
124
98
99
+ return rankedCycles ;
100
+ }
101
+
102
+ private void idenfifyRankedCycles (List <RankedCycle > rankedCycles , boolean calculateChurnForCycles )
103
+ throws IOException {
104
+ Map <String , AsSubgraph <String , DefaultWeightedEdge >> cycles = getCycles ();
105
+ Map <String , String > classNamesAndPaths = getClassNamesAndPaths ();
106
+ cycles .forEach ((vertex , subGraph ) -> {
107
+ int vertexCount = subGraph .vertexSet ().size ();
108
+ int edgeCount = subGraph .edgeSet ().size ();
109
+
110
+ if (vertexCount > 1 && edgeCount > 1 && !isDuplicateSubGraph (subGraph , vertex )) {
111
+ renderedSubGraphs .put (vertex , subGraph );
112
+ log .info ("Vertex: " + vertex + " vertex count: " + vertexCount + " edge count: " + edgeCount );
113
+ GusfieldGomoryHuCutTree <String , DefaultWeightedEdge > gusfieldGomoryHuCutTree =
114
+ new GusfieldGomoryHuCutTree <>(new AsUndirectedGraph <>(subGraph ));
115
+ double minCut = gusfieldGomoryHuCutTree .calculateMinCut ();
116
+ Set <DefaultWeightedEdge > minCutEdges = gusfieldGomoryHuCutTree .getCutEdges ();
117
+
118
+ List <CycleNode > cycleNodes = subGraph .vertexSet ().stream ()
119
+ .map (classInCycle -> new CycleNode (classInCycle , classNamesAndPaths .get (classInCycle )))
120
+ .collect (Collectors .toList ());
121
+
122
+ rankedCycles .add (
123
+ createRankedCycle (calculateChurnForCycles , vertex , subGraph , cycleNodes , minCut , minCutEdges ));
124
+ }
125
+ });
126
+ }
127
+
128
+ private static void setPriorities (List <RankedCycle > rankedCycles ) {
129
+ int priority = 1 ;
130
+ for (RankedCycle rankedCycle : rankedCycles ) {
131
+ rankedCycle .setPriority (priority ++);
132
+ }
133
+ }
134
+
135
+ private Map <String , AsSubgraph <String , DefaultWeightedEdge >> getCycles () throws IOException {
136
+ classReferencesGraph = javaProjectParser .getClassReferences (repositoryPath );
137
+ CircularReferenceChecker circularReferenceChecker = new CircularReferenceChecker ();
138
+ Map <String , AsSubgraph <String , DefaultWeightedEdge >> cycles =
139
+ circularReferenceChecker .detectCycles (classReferencesGraph );
140
+ return cycles ;
141
+ }
142
+
143
+ private static void sortRankedCycles (List <RankedCycle > rankedCycles , boolean calculateChurnForCycles ) {
144
+ if (calculateChurnForCycles ) {
125
145
rankedCycles .sort (Comparator .comparing (RankedCycle ::getAverageChangeProneness ));
146
+
126
147
int cpr = 1 ;
127
148
for (RankedCycle rankedCycle : rankedCycles ) {
128
149
rankedCycle .setChangePronenessRank (cpr ++);
129
150
}
130
-
151
+ } else {
131
152
rankedCycles .sort (Comparator .comparing (RankedCycle ::getRawPriority ).reversed ());
153
+ }
154
+ }
132
155
133
- int priority = 1 ;
134
- for (RankedCycle rankedCycle : rankedCycles ) {
135
- rankedCycle .setPriority (priority ++);
156
+ private RankedCycle createRankedCycle (
157
+ boolean calculateChurnForCycles ,
158
+ String vertex ,
159
+ AsSubgraph <String , DefaultWeightedEdge > subGraph ,
160
+ List <CycleNode > cycleNodes ,
161
+ double minCut ,
162
+ Set <DefaultWeightedEdge > minCutEdges ) {
163
+ RankedCycle rankedCycle ;
164
+ if (calculateChurnForCycles ) {
165
+ List <ScmLogInfo > changeRanks = getRankedChangeProneness (cycleNodes );
166
+
167
+ Map <String , CycleNode > cycleNodeMap = new HashMap <>();
168
+
169
+ for (CycleNode cycleNode : cycleNodes ) {
170
+ cycleNodeMap .put (cycleNode .getFileName (), cycleNode );
136
171
}
137
172
138
- } catch (IOException e ) {
139
- throw new RuntimeException (e );
140
- }
173
+ for (ScmLogInfo changeRank : changeRanks ) {
174
+ CycleNode cycleNode = cycleNodeMap .get (changeRank .getPath ());
175
+ cycleNode .setScmLogInfo (changeRank );
176
+ }
141
177
142
- return rankedCycles ;
178
+ // sum change proneness ranks
179
+ int changePronenessRankSum = changeRanks .stream ()
180
+ .mapToInt (ScmLogInfo ::getChangePronenessRank )
181
+ .sum ();
182
+ rankedCycle = new RankedCycle (
183
+ vertex ,
184
+ changePronenessRankSum ,
185
+ subGraph .vertexSet (),
186
+ subGraph .edgeSet (),
187
+ minCut ,
188
+ minCutEdges ,
189
+ cycleNodes );
190
+ } else {
191
+ rankedCycle =
192
+ new RankedCycle (vertex , subGraph .vertexSet (), subGraph .edgeSet (), minCut , minCutEdges , cycleNodes );
193
+ }
194
+ return rankedCycle ;
143
195
}
144
196
145
197
private boolean isDuplicateSubGraph (AsSubgraph <String , DefaultWeightedEdge > subGraph , String vertex ) {
0 commit comments