Revize 927147ab
Přidáno uživatelem stepanekp před asi 3 roky(ů)
src/main/java/cz/zcu/fav/kiv/antipatterndetectionapp/repository/ConfigurationRepository.java | ||
---|---|---|
1 |
package cz.zcu.fav.kiv.antipatterndetectionapp.repository; |
|
2 |
|
|
3 |
import com.fasterxml.jackson.databind.JsonNode; |
|
4 |
import cz.zcu.fav.kiv.antipatterndetectionapp.utils.JsonParser; |
|
5 |
import org.slf4j.Logger; |
|
6 |
import org.slf4j.LoggerFactory; |
|
7 |
import org.springframework.stereotype.Component; |
|
8 |
import org.springframework.web.context.ServletContextAware; |
|
9 |
|
|
10 |
import javax.servlet.ServletContext; |
|
11 |
import java.io.File; |
|
12 |
import java.net.URL; |
|
13 |
import java.nio.file.Files; |
|
14 |
import java.util.HashMap; |
|
15 |
import java.util.Map; |
|
16 |
|
|
17 |
@Component |
|
18 |
public class ConfigurationRepository implements ServletContextAware { |
|
19 |
|
|
20 |
private ServletContext servletContext; |
|
21 |
private static final String CONFIGURATION_DIR = "/configurations/"; |
|
22 |
private final Logger LOGGER = LoggerFactory.getLogger(ConfigurationRepository.class); |
|
23 |
|
|
24 |
// Map<ConfigurationName, Map<AntiPatternName, Map<ThresholdName, value>>> |
|
25 |
public Map<String, Map<String, Map<String, String>>> allConfigurations; |
|
26 |
|
|
27 |
@Override |
|
28 |
public void setServletContext(ServletContext servletContext) { |
|
29 |
this.servletContext = servletContext; |
|
30 |
|
|
31 |
loadConfigurations(); |
|
32 |
} |
|
33 |
|
|
34 |
private void loadConfigurations(){ |
|
35 |
LOGGER.info("-------START READING CONFIGURATIONS FROM FILES-------"); |
|
36 |
Map<String, Map<String, Map<String, String>>> configurations = new HashMap<>(); |
|
37 |
try { |
|
38 |
URL url = servletContext.getResource(CONFIGURATION_DIR); |
|
39 |
File folder = new File(url.getFile()); |
|
40 |
|
|
41 |
|
|
42 |
|
|
43 |
for (final File fileEntry : folder.listFiles()) { |
|
44 |
LOGGER.info("Reading configuration from file " + fileEntry.getName()); |
|
45 |
String json = ""; // json configuration file |
|
46 |
JsonNode node = null; |
|
47 |
try { |
|
48 |
json = new String(Files.readAllBytes(fileEntry.toPath())); |
|
49 |
node = JsonParser.parse(json); |
|
50 |
} catch (Exception e) { |
|
51 |
e.printStackTrace(); |
|
52 |
} |
|
53 |
|
|
54 |
|
|
55 |
String configurationName = fileEntry.getName().split("\\.")[0]; |
|
56 |
|
|
57 |
JsonNode arrayOfConfigurations = node.get("configuration"); |
|
58 |
|
|
59 |
Map<String, Map<String, String>> newAntiPatternMap = new HashMap<>(); |
|
60 |
|
|
61 |
for (int i = 0; i < arrayOfConfigurations.size(); i++) { |
|
62 |
|
|
63 |
JsonNode antiPatternNode = arrayOfConfigurations.get(i); |
|
64 |
|
|
65 |
String antiPatternName = antiPatternNode.get("antiPattern").asText(); |
|
66 |
|
|
67 |
JsonNode arrayOfThresholds = antiPatternNode.get("thresholds"); |
|
68 |
|
|
69 |
Map<String, String> newThresholds = new HashMap<String, String>(); |
|
70 |
|
|
71 |
for (int j = 0; j < arrayOfThresholds.size(); j++) { |
|
72 |
JsonNode thresholdNode = arrayOfThresholds.get(j); |
|
73 |
|
|
74 |
String thresholdName = thresholdNode.get("thresholdName").asText(); |
|
75 |
String value = thresholdNode.get("value").asText(); |
|
76 |
|
|
77 |
|
|
78 |
newThresholds.put(thresholdName, value); |
|
79 |
} |
|
80 |
|
|
81 |
newAntiPatternMap.put(antiPatternName, newThresholds); |
|
82 |
|
|
83 |
} |
|
84 |
configurations.put(configurationName, newAntiPatternMap); |
|
85 |
} |
|
86 |
|
|
87 |
} catch (Exception e) { |
|
88 |
e.printStackTrace(); |
|
89 |
} |
|
90 |
this.allConfigurations = configurations; |
|
91 |
|
|
92 |
LOGGER.info("-------FINISHED READING CONFIGURATIONS FROM FILES-------"); |
|
93 |
} |
|
94 |
} |
src/main/java/cz/zcu/fav/kiv/antipatterndetectionapp/service/ConfigurationService.java | ||
---|---|---|
8 | 8 |
|
9 | 9 |
List<String> getDefaultConfigurationNames(); |
10 | 10 |
|
11 |
|
|
11 | 12 |
} |
src/main/java/cz/zcu/fav/kiv/antipatterndetectionapp/service/ConfigurationServiceImpl.java | ||
---|---|---|
1 | 1 |
package cz.zcu.fav.kiv.antipatterndetectionapp.service; |
2 | 2 |
|
3 |
import org.springframework.core.io.FileSystemResource; |
|
3 |
import cz.zcu.fav.kiv.antipatterndetectionapp.repository.ConfigurationRepository; |
|
4 |
import org.springframework.beans.factory.annotation.Autowired; |
|
4 | 5 |
import org.springframework.stereotype.Service; |
5 | 6 |
|
6 |
import java.io.File; |
|
7 |
import java.nio.file.Paths; |
|
8 | 7 |
import java.util.ArrayList; |
9 | 8 |
import java.util.List; |
10 | 9 |
|
11 | 10 |
@Service |
12 | 11 |
public class ConfigurationServiceImpl implements ConfigurationService { |
13 | 12 |
|
14 |
private static final String configurationsLocation = "\\src\\main\\webapp\\configurations"; |
|
13 |
@Autowired |
|
14 |
private ConfigurationRepository configurationRepository; |
|
15 | 15 |
|
16 | 16 |
@Override |
17 | 17 |
public List<String> getAllConfigurationNames() { |
18 | 18 |
List<String> configList = new ArrayList<String>(); |
19 |
File folder = new File(String.valueOf(Paths.get(new FileSystemResource("").getFile().getAbsolutePath() + configurationsLocation))); |
|
20 |
for (final File fileEntry : folder.listFiles()) { |
|
21 |
configList.add(fileEntry.getName().split("\\.")[0]); |
|
19 |
|
|
20 |
// get all configurations |
|
21 |
for (String key : configurationRepository.allConfigurations.keySet() ) { |
|
22 |
configList.add(key); |
|
22 | 23 |
} |
24 |
|
|
23 | 25 |
return configList; |
24 | 26 |
} |
25 | 27 |
|
26 | 28 |
@Override |
27 | 29 |
public List<String> getDefaultConfigurationNames() { |
28 | 30 |
List<String> configList = new ArrayList<String>(); |
31 |
|
|
32 |
// insert only default configurations |
|
29 | 33 |
configList.add("Default"); |
34 |
|
|
30 | 35 |
return configList; |
31 | 36 |
} |
32 | 37 |
|
src/main/webapp/WEB-INF/templates/index.html | ||
---|---|---|
44 | 44 |
<tr th:each="project : ${query.projects}"> |
45 | 45 |
<td th:text="${project.id}"></td> |
46 | 46 |
<td th:text="${project.name}"></td> |
47 |
<td><a th:href="@{/projects/} + ${project.id}">Show</a></td>
|
|
47 |
<td><a th:href="@{'/projects/' + ${project.id}}">Show</a></td>
|
|
48 | 48 |
<td style="text-align: center"> |
49 | 49 |
<input checked type="checkbox" class="form-check-input" name="selectedProjects" |
50 | 50 |
th:value="${project.id}" th:id="@{project_} + ${project.id}"> |
... | ... | |
79 | 79 |
<tr th:each="antiPattern : ${query.antiPatterns}"> |
80 | 80 |
<td th:text="${antiPattern.id}"></td> |
81 | 81 |
<td th:text="${antiPattern.printName}"></td> |
82 |
<td><a th:href="@{/anti-patterns/} + ${antiPattern.id}">Show</a></td>
|
|
82 |
<td><a th:href="@{'/anti-patterns/' + ${antiPattern.id}}">Show</a></td>
|
|
83 | 83 |
<td style="text-align: center"> |
84 | 84 |
<input checked type="checkbox" class="form-check-input" name="selectedAntiPatterns" |
85 | 85 |
th:value="${antiPattern.id}" th:id="@{anti-pattern_} + ${antiPattern.id}"> |
src/main/webapp/configurations/Default.json | ||
---|---|---|
1 | 1 |
{ |
2 |
"name" : "Default", |
|
3 |
"default" : "1", |
|
4 |
"TooLongSprint": [ |
|
5 |
{ |
|
6 |
"thresholdName": "maxIterationLength", |
|
7 |
"value": "21" |
|
8 |
}, |
|
9 |
{ |
|
10 |
"thresholdName": "maxNumberOfTooLongIterations", |
|
11 |
"value": "0" |
|
12 |
} |
|
13 |
], |
|
14 |
"VaryingSprintLength": [ |
|
15 |
{ |
|
16 |
"thresholdName": "maxDaysDifference", |
|
17 |
"value": "7" |
|
2 |
"configuration": [ |
|
3 |
{ |
|
4 |
"antiPattern": "TooLongSprint", |
|
5 |
"thresholds": [ |
|
6 |
{ |
|
7 |
"thresholdName": "maxIterationLength", |
|
8 |
"value": "21" |
|
9 |
}, |
|
10 |
{ |
|
11 |
"thresholdName": "maxNumberOfTooLongIterations", |
|
12 |
"value": "0" |
|
13 |
} |
|
14 |
] |
|
18 | 15 |
}, |
19 | 16 |
{ |
20 |
"thresholdName": "maxIterationChanged", |
|
21 |
"value": "1" |
|
22 |
} |
|
23 |
], |
|
24 |
"BusinessAsUsual": [ |
|
25 |
{ |
|
26 |
"thresholdName": "divisionOfIterationsWithRetrospective", |
|
27 |
"value": "66.66f" |
|
17 |
"antiPattern": "VaryingSprintLength", |
|
18 |
"thresholds": [ |
|
19 |
{ |
|
20 |
"thresholdName": "maxDaysDifference", |
|
21 |
"value": "7" |
|
22 |
}, |
|
23 |
{ |
|
24 |
"thresholdName": "maxIterationChanged", |
|
25 |
"value": "1" |
|
26 |
} |
|
27 |
] |
|
28 | 28 |
}, |
29 | 29 |
{ |
30 |
"thresholdName": "searchSubstringsWithRetrospective", |
|
31 |
"value": "%retr%||%revi%||%week%scrum%" |
|
32 |
} |
|
33 |
], |
|
34 |
"SpecifyNothing": [ |
|
35 |
{ |
|
36 |
"thresholdName": "minNumberOfWikiPagesWithSpecification", |
|
37 |
"value": "1" |
|
30 |
"antiPattern": "BusinessAsUsual", |
|
31 |
"thresholds": [ |
|
32 |
{ |
|
33 |
"thresholdName": "divisionOfIterationsWithRetrospective", |
|
34 |
"value": "66.66f" |
|
35 |
}, |
|
36 |
{ |
|
37 |
"thresholdName": "searchSubstringsWithRetrospective", |
|
38 |
"value": "%retr%||%revi%||%week%scrum%" |
|
39 |
} |
|
40 |
] |
|
38 | 41 |
}, |
39 | 42 |
{ |
40 |
"thresholdName": "minNumberOfActivitiesWithSpecification", |
|
41 |
"value": "1" |
|
43 |
"antiPattern": "SpecifyNothing", |
|
44 |
"thresholds": [ |
|
45 |
{ |
|
46 |
"thresholdName": "minNumberOfWikiPagesWithSpecification", |
|
47 |
"value": "1" |
|
48 |
}, |
|
49 |
{ |
|
50 |
"thresholdName": "minNumberOfActivitiesWithSpecification", |
|
51 |
"value": "1" |
|
52 |
}, |
|
53 |
{ |
|
54 |
"thresholdName": "minAvgLengthOfActivityDescription", |
|
55 |
"value": "150" |
|
56 |
}, |
|
57 |
{ |
|
58 |
"thresholdName": "searchSubstringsWithProjectSpecification", |
|
59 |
"value": "%dsp%||%specifikace%||%specification%||%vize%proj%||%vize%produ%" |
|
60 |
} |
|
61 |
] |
|
42 | 62 |
}, |
43 | 63 |
{ |
44 |
"thresholdName": "minAvgLengthOfActivityDescription", |
|
45 |
"value": "150" |
|
64 |
"antiPattern": "RoadToNowhere", |
|
65 |
"thresholds": [ |
|
66 |
{ |
|
67 |
"thresholdName": "minNumberOfWikiPagesWithProjectPlan", |
|
68 |
"value": "1" |
|
69 |
}, |
|
70 |
{ |
|
71 |
"thresholdName": "minNumberOfActivitiesWithProjectPlan", |
|
72 |
"value": "1" |
|
73 |
}, |
|
74 |
{ |
|
75 |
"thresholdName": "searchSubstringsWithProjectPlan", |
|
76 |
"value": "%plán projektu%||%project plan%||%plan project%||%projektový plán%" |
|
77 |
} |
|
78 |
] |
|
46 | 79 |
}, |
47 | 80 |
{ |
48 |
"thresholdName": "searchSubstringsWithProjectSpecification", |
|
49 |
"value": "%dsp%||%specifikace%||%specification%||%vize%proj%||%vize%produ%" |
|
50 |
} |
|
51 |
], |
|
52 |
"RoadToNowhere": [ |
|
53 |
{ |
|
54 |
"thresholdName": "minNumberOfWikiPagesWithProjectPlan", |
|
55 |
"value": "1" |
|
56 |
}, |
|
57 |
{ |
|
58 |
"thresholdName": "minNumberOfActivitiesWithProjectPlan", |
|
59 |
"value": "1" |
|
60 |
}, |
|
61 |
{ |
|
62 |
"thresholdName": "searchSubstringsWithProjectPlan", |
|
63 |
"value": "%plán projektu%||%project plan%||%plan project%||%projektový plán%" |
|
64 |
} |
|
65 |
], |
|
66 |
"LongOrNonExistentFeedbackLoops": [ |
|
67 |
{ |
|
68 |
"thresholdName": "divisionOfIterationsWithFeedbackLoop", |
|
69 |
"value": "50.00f" |
|
70 |
}, |
|
71 |
{ |
|
72 |
"thresholdName": "maxGapBetweenFeedbackLoopRate", |
|
73 |
"value": "2f" |
|
74 |
}, |
|
75 |
{ |
|
76 |
"thresholdName": "searchSubstringsWithFeedbackLoop", |
|
77 |
"value": "%schůz%zákazník%||%předvedení%zákazník%||%zákazn%demo%||%schůz%zadavat%||%inform%schůz%||%zákazn%||%zadavatel%" |
|
78 |
} |
|
79 |
], |
|
80 |
"NinetyNinetyRule": [ |
|
81 |
{ |
|
82 |
"thresholdName": "maxDivisionRange", |
|
83 |
"value": "1.25f" |
|
81 |
"antiPattern": "LongOrNonExistentFeedbackLoops", |
|
82 |
"thresholds": [ |
|
83 |
{ |
|
84 |
"thresholdName": "divisionOfIterationsWithFeedbackLoop", |
|
85 |
"value": "50.00f" |
|
86 |
}, |
|
87 |
{ |
|
88 |
"thresholdName": "maxGapBetweenFeedbackLoopRate", |
|
89 |
"value": "2f" |
|
90 |
}, |
|
91 |
{ |
|
92 |
"thresholdName": "searchSubstringsWithFeedbackLoop", |
|
93 |
"value": "%schůz%zákazník%||%předvedení%zákazník%||%zákazn%demo%||%schůz%zadavat%||%inform%schůz%||%zákazn%||%zadavatel%" |
|
94 |
} |
|
95 |
] |
|
84 | 96 |
}, |
85 | 97 |
{ |
86 |
"thresholdName": "maxBadDivisionLimit", |
|
87 |
"value": "2" |
|
98 |
"antiPattern": "NinetyNinetyRule", |
|
99 |
"thresholds": [ |
|
100 |
{ |
|
101 |
"thresholdName": "maxDivisionRange", |
|
102 |
"value": "1.25f" |
|
103 |
}, |
|
104 |
{ |
|
105 |
"thresholdName": "maxBadDivisionLimit", |
|
106 |
"value": "2" |
|
107 |
} |
|
108 |
] |
|
88 | 109 |
} |
89 | 110 |
] |
90 | 111 |
} |
Také k dispozici: Unified diff
#14 Configuration repository and service functions added