4 |
4 |
import cz.zcu.fav.kiv.antipatterndetectionapp.model.AntiPattern;
|
5 |
5 |
import cz.zcu.fav.kiv.antipatterndetectionapp.model.Project;
|
6 |
6 |
import cz.zcu.fav.kiv.antipatterndetectionapp.model.QueryResultItem;
|
|
7 |
import cz.zcu.fav.kiv.antipatterndetectionapp.model.ResultDetail;
|
|
8 |
import cz.zcu.fav.kiv.antipatterndetectionapp.utils.Utils;
|
7 |
9 |
import org.slf4j.Logger;
|
8 |
10 |
import org.slf4j.LoggerFactory;
|
9 |
11 |
|
|
12 |
import java.sql.ResultSet;
|
|
13 |
import java.sql.SQLException;
|
10 |
14 |
import java.util.List;
|
11 |
15 |
|
12 |
16 |
public class VaryingSprintLengthDetectorImpl extends AntiPatternDetector {
|
... | ... | |
17 |
21 |
"Varying Sprint Length",
|
18 |
22 |
"VaryingSprintLength",
|
19 |
23 |
"The length of the sprint changes very often. " +
|
20 |
|
"It is clear that iterations will be different " +
|
|
24 |
"It is clear that iterations will be different " +
|
21 |
25 |
"lengths at the beginning and end of the project, " +
|
22 |
26 |
"but the length of the sprint should not change " +
|
23 |
27 |
"during the project.");
|
24 |
28 |
|
25 |
29 |
private final String sqlFileName = "varying_sprint_length.sql";
|
26 |
30 |
|
|
31 |
/**
|
|
32 |
*
|
|
33 |
* @return
|
|
34 |
*/
|
|
35 |
private final int MAXIMUM_DAYS_DIFFERENCE = 5;
|
|
36 |
private final float DIVISION_OF_VARYING_SPRINT_LENGTH = (float) 1/3;
|
|
37 |
|
27 |
38 |
@Override
|
28 |
39 |
public AntiPattern getAntiPatternModel() {
|
29 |
40 |
return this.antiPattern;
|
... | ... | |
34 |
45 |
return this.sqlFileName;
|
35 |
46 |
}
|
36 |
47 |
|
|
48 |
/**
|
|
49 |
* Postup detekce:
|
|
50 |
* 1) najít všechny iterace pro danný projekt seřazené dle start date
|
|
51 |
* 2) odebrání první a poslední iterace z důvodu možných výkyvů
|
|
52 |
* 3) zjistit jejich délku (rozdíl mezi start date a end date)
|
|
53 |
* 4) vždy porovnat dvě po sobě jdoucí iterace
|
|
54 |
* 5) pokud se délka porovnávaných iterací liší o více než 5 dní, tak je zvednut counter
|
|
55 |
* 6) pokud counter překročí 1/3 ze všech sledovaných iterací, tak je anti pattern detekován
|
|
56 |
*
|
|
57 |
* Alternativa (sledovat rozptyl délek jednotlivých iterací a pokud překročí nějakou hodnotu, tak detevat)
|
|
58 |
* @param project analyzovaný project
|
|
59 |
* @param databaseConnection databázové připojení
|
|
60 |
* @param queries list sql dotazů
|
|
61 |
* @return výsledek detekce
|
|
62 |
*/
|
37 |
63 |
@Override
|
38 |
|
public QueryResultItem analyze(Project project, DatabaseConnection databaseConnection, List<String> sql) {
|
39 |
|
return new QueryResultItem(this.antiPattern, true, null);
|
|
64 |
public QueryResultItem analyze(Project project, DatabaseConnection databaseConnection, List<String> queries) {
|
|
65 |
|
|
66 |
int counter = 0;
|
|
67 |
int numberOfIterations = 0;
|
|
68 |
|
|
69 |
try {
|
|
70 |
ResultSet rs = databaseConnection.executeQueries(project, queries);
|
|
71 |
if (rs != null) {
|
|
72 |
int firstIterationLength = Integer.MIN_VALUE;
|
|
73 |
int secondIterationLength;
|
|
74 |
while (rs.next()) {
|
|
75 |
int iterationLength = rs.getInt("iterationLength");
|
|
76 |
numberOfIterations++;
|
|
77 |
if (firstIterationLength == Integer.MIN_VALUE) {
|
|
78 |
firstIterationLength = iterationLength;
|
|
79 |
continue;
|
|
80 |
} else {
|
|
81 |
secondIterationLength = iterationLength;
|
|
82 |
}
|
|
83 |
|
|
84 |
if (Math.abs(firstIterationLength - secondIterationLength) >= MAXIMUM_DAYS_DIFFERENCE) {
|
|
85 |
counter = counter + 1;
|
|
86 |
}
|
|
87 |
firstIterationLength = secondIterationLength;
|
|
88 |
}
|
|
89 |
}
|
|
90 |
|
|
91 |
} catch (SQLException e) {
|
|
92 |
e.printStackTrace();
|
|
93 |
}
|
|
94 |
|
|
95 |
int maxIterationLimit = Math.round(numberOfIterations * DIVISION_OF_VARYING_SPRINT_LENGTH);
|
|
96 |
|
|
97 |
List<ResultDetail> resultDetails = Utils.createResultDetailsList(
|
|
98 |
new ResultDetail("Project id", project.getId().toString()),
|
|
99 |
new ResultDetail("Max Iteration limit", String.valueOf(maxIterationLimit)),
|
|
100 |
new ResultDetail("Count of iterations", String.valueOf(numberOfIterations)),
|
|
101 |
new ResultDetail("Number of significant change of iteration length", String.valueOf(counter)),
|
|
102 |
new ResultDetail("Is detected", String.valueOf((counter >= maxIterationLimit))));
|
|
103 |
|
|
104 |
LOGGER.info(this.antiPattern.getPrintName());
|
|
105 |
LOGGER.info(resultDetails.toString());
|
|
106 |
|
|
107 |
return new QueryResultItem(this.antiPattern, (counter >= maxIterationLimit), resultDetails);
|
40 |
108 |
}
|
41 |
109 |
}
|
Varying sprint length implemented