Revize cd3f21e5
Přidáno uživatelem stepanekp před asi 3 roky(ů)
src/main/java/cz/zcu/fav/kiv/antipatterndetectionapp/controller/AppController.java | ||
---|---|---|
219 | 219 |
* Method of storing new configurations for individual AP. |
220 | 220 |
* |
221 | 221 |
* @param model object for passing data to the UI |
222 |
* @param configValues changed configuration values
|
|
223 |
* @param configNames changed configuration names
|
|
222 |
* @param thresholdValues changed configuration values
|
|
223 |
* @param thresholdNames changed configuration names
|
|
224 | 224 |
* @return html file name for thymeleaf template |
225 | 225 |
*/ |
226 | 226 |
@PostMapping("/configuration") |
227 | 227 |
public String configurationPost(Model model, |
228 |
@RequestParam(value = "configValues", required = false) String[] configValues,
|
|
229 |
@RequestParam(value = "configNames", required = false) String[] configNames) {
|
|
228 |
@RequestParam(value = "thresholdValues", required = false) String[] thresholdValues,
|
|
229 |
@RequestParam(value = "thresholdNames", required = false) String[] thresholdNames) {
|
|
230 | 230 |
|
231 | 231 |
List<AntiPattern> antiPatterns = antiPatternService.antiPatternsToModel(antiPatternService.getAllAntiPatterns()); |
232 |
List<String> wrongParameters = antiPatternService.saveNewConfiguration(configNames, configValues);
|
|
232 |
List<String> wrongParameters = antiPatternService.saveNewConfiguration(thresholdNames, thresholdValues);
|
|
233 | 233 |
|
234 | 234 |
if (wrongParameters.isEmpty()) { |
235 | 235 |
model.addAttribute("successMessage", "All configuration values has been successfully saved."); |
... | ... | |
247 | 247 |
* |
248 | 248 |
* @param model object for passing data to the UI |
249 | 249 |
* @param id id of AP |
250 |
* @param configValues new config values
|
|
251 |
* @param configNames configuration names
|
|
250 |
* @param thresholdValues new config values
|
|
251 |
* @param thresholdNames configuration names
|
|
252 | 252 |
* @param redirectAttrs attributes for redirection |
253 | 253 |
* @return redirected html file name for thymeleaf template |
254 | 254 |
*/ |
255 | 255 |
@PostMapping("/anti-patterns/{id}") |
256 | 256 |
public String antiPatternsPost(Model model, |
257 | 257 |
@PathVariable Long id, |
258 |
@RequestParam(value = "configValues", required = false) String[] configValues,
|
|
259 |
@RequestParam(value = "configNames", required = false) String[] configNames,
|
|
258 |
@RequestParam(value = "thresholdValues", required = false) String[] thresholdValues,
|
|
259 |
@RequestParam(value = "thresholdNames", required = false) String[] thresholdNames,
|
|
260 | 260 |
RedirectAttributes redirectAttrs) { |
261 | 261 |
|
262 | 262 |
AntiPattern antiPattern = antiPatternService.antiPatternToModel(antiPatternService.getAntiPatternById(id)); |
263 |
List<String> wrongParameters = antiPatternService.saveNewConfiguration(configNames, configValues);
|
|
263 |
List<String> wrongParameters = antiPatternService.saveNewConfiguration(thresholdNames, thresholdValues);
|
|
264 | 264 |
|
265 | 265 |
if (wrongParameters.isEmpty()) { |
266 | 266 |
redirectAttrs.addFlashAttribute("successMessage", "All threshold values has been successfully saved."); |
src/main/java/cz/zcu/fav/kiv/antipatterndetectionapp/model/AntiPattern.java | ||
---|---|---|
18 | 18 |
private String printName; |
19 | 19 |
private String name; |
20 | 20 |
private String description; |
21 |
private Map<String, Configuration> configurations;
|
|
21 |
private Map<String, Threshold> thresholds;
|
|
22 | 22 |
private String catalogueFileName; |
23 | 23 |
|
24 | 24 |
public AntiPattern(Long id, String printName, String name, String description) { |
... | ... | |
28 | 28 |
this.description = description; |
29 | 29 |
} |
30 | 30 |
|
31 |
public AntiPattern(Long id, String printName, String name, String description, Map<String, Configuration> configurations) {
|
|
31 |
public AntiPattern(Long id, String printName, String name, String description, Map<String, Threshold> thresholds) {
|
|
32 | 32 |
this.id = id; |
33 | 33 |
this.printName = printName; |
34 | 34 |
this.name = name; |
35 | 35 |
this.description = description; |
36 |
this.configurations = configurations;
|
|
36 |
this.thresholds = thresholds;
|
|
37 | 37 |
} |
38 | 38 |
|
39 |
public AntiPattern(Long id, String printName, String name, String description, Map<String, Configuration> configurations, String catalogueFileName) {
|
|
39 |
public AntiPattern(Long id, String printName, String name, String description, Map<String, Threshold> thresholds, String catalogueFileName) {
|
|
40 | 40 |
this.id = id; |
41 | 41 |
this.printName = printName; |
42 | 42 |
this.name = name; |
43 | 43 |
this.description = description; |
44 |
this.configurations = configurations;
|
|
44 |
this.thresholds = thresholds;
|
|
45 | 45 |
this.catalogueFileName = catalogueFileName; |
46 | 46 |
} |
47 | 47 |
|
... | ... | |
77 | 77 |
this.description = description; |
78 | 78 |
} |
79 | 79 |
|
80 |
public Map<String, Configuration> getConfigurations() {
|
|
81 |
return configurations;
|
|
80 |
public Map<String, Threshold> getThresholds() {
|
|
81 |
return thresholds;
|
|
82 | 82 |
} |
83 | 83 |
|
84 |
public void setConfigurations(Map<String, Configuration> configurations) {
|
|
85 |
this.configurations = configurations;
|
|
84 |
public void setThresholds(Map<String, Threshold> thresholds) {
|
|
85 |
this.thresholds = thresholds;
|
|
86 | 86 |
} |
87 | 87 |
|
88 | 88 |
public String getUrl() { |
... | ... | |
156 | 156 |
", printName='" + printName + '\'' + |
157 | 157 |
", name='" + name + '\'' + |
158 | 158 |
", description='" + description + '\'' + |
159 |
", configurations=" + configurations +
|
|
159 |
", thresholds=" + thresholds +
|
|
160 | 160 |
", catalogueFileName='" + catalogueFileName + '\'' + |
161 | 161 |
'}'; |
162 | 162 |
} |
src/main/java/cz/zcu/fav/kiv/antipatterndetectionapp/model/Configuration.java | ||
---|---|---|
1 |
package cz.zcu.fav.kiv.antipatterndetectionapp.model; |
|
2 |
|
|
3 |
/** |
|
4 |
* Model class for configuration. |
|
5 |
* @param <T> configuration can have different data types |
|
6 |
*/ |
|
7 |
public class Configuration<T> { |
|
8 |
private String name; |
|
9 |
private String printName; |
|
10 |
private String description; |
|
11 |
private String errorMessage; |
|
12 |
private boolean isErrorMessageShown; |
|
13 |
private T value; |
|
14 |
|
|
15 |
public Configuration(String name, String printName, String description, T value) { |
|
16 |
this.name = name; |
|
17 |
this.printName = printName; |
|
18 |
this.description = description; |
|
19 |
this.value = value; |
|
20 |
this.isErrorMessageShown = false; |
|
21 |
} |
|
22 |
|
|
23 |
public Configuration(String name, String printName, String description, String errorMessage, T value) { |
|
24 |
this.name = name; |
|
25 |
this.printName = printName; |
|
26 |
this.description = description; |
|
27 |
this.errorMessage = errorMessage; |
|
28 |
this.value = value; |
|
29 |
this.isErrorMessageShown = false; |
|
30 |
} |
|
31 |
|
|
32 |
public String getName() { |
|
33 |
return name; |
|
34 |
} |
|
35 |
|
|
36 |
public void setName(String name) { |
|
37 |
this.name = name; |
|
38 |
} |
|
39 |
|
|
40 |
public String getPrintName() { |
|
41 |
return printName; |
|
42 |
} |
|
43 |
|
|
44 |
public void setPrintName(String printName) { |
|
45 |
this.printName = printName; |
|
46 |
} |
|
47 |
|
|
48 |
public String getDescription() { |
|
49 |
return description; |
|
50 |
} |
|
51 |
|
|
52 |
public void setDescription(String description) { |
|
53 |
this.description = description; |
|
54 |
} |
|
55 |
|
|
56 |
public T getValue() { |
|
57 |
return value; |
|
58 |
} |
|
59 |
|
|
60 |
public void setValue(T value) { |
|
61 |
this.value = value; |
|
62 |
} |
|
63 |
|
|
64 |
public String getErrorMessage() { |
|
65 |
return errorMessage; |
|
66 |
} |
|
67 |
|
|
68 |
public void setErrorMessage(String errorMessage) { |
|
69 |
this.errorMessage = errorMessage; |
|
70 |
} |
|
71 |
|
|
72 |
public boolean isErrorMessageShown() { |
|
73 |
return isErrorMessageShown; |
|
74 |
} |
|
75 |
|
|
76 |
public void setErrorMessageShown(boolean errorMessageShown) { |
|
77 |
isErrorMessageShown = errorMessageShown; |
|
78 |
} |
|
79 |
} |
src/main/java/cz/zcu/fav/kiv/antipatterndetectionapp/model/Threshold.java | ||
---|---|---|
1 |
package cz.zcu.fav.kiv.antipatterndetectionapp.model; |
|
2 |
|
|
3 |
/** |
|
4 |
* Model class for threshold. |
|
5 |
* @param <T> threshold can have different data types |
|
6 |
*/ |
|
7 |
public class Threshold<T> { |
|
8 |
private String name; |
|
9 |
private String printName; |
|
10 |
private String description; |
|
11 |
private String errorMessage; |
|
12 |
private boolean isErrorMessageShown; |
|
13 |
private T value; |
|
14 |
|
|
15 |
public Threshold(String name, String printName, String description, T value) { |
|
16 |
this.name = name; |
|
17 |
this.printName = printName; |
|
18 |
this.description = description; |
|
19 |
this.value = value; |
|
20 |
this.isErrorMessageShown = false; |
|
21 |
} |
|
22 |
|
|
23 |
public Threshold(String name, String printName, String description, String errorMessage, T value) { |
|
24 |
this.name = name; |
|
25 |
this.printName = printName; |
|
26 |
this.description = description; |
|
27 |
this.errorMessage = errorMessage; |
|
28 |
this.value = value; |
|
29 |
this.isErrorMessageShown = false; |
|
30 |
} |
|
31 |
|
|
32 |
public String getName() { |
|
33 |
return name; |
|
34 |
} |
|
35 |
|
|
36 |
public void setName(String name) { |
|
37 |
this.name = name; |
|
38 |
} |
|
39 |
|
|
40 |
public String getPrintName() { |
|
41 |
return printName; |
|
42 |
} |
|
43 |
|
|
44 |
public void setPrintName(String printName) { |
|
45 |
this.printName = printName; |
|
46 |
} |
|
47 |
|
|
48 |
public String getDescription() { |
|
49 |
return description; |
|
50 |
} |
|
51 |
|
|
52 |
public void setDescription(String description) { |
|
53 |
this.description = description; |
|
54 |
} |
|
55 |
|
|
56 |
public T getValue() { |
|
57 |
return value; |
|
58 |
} |
|
59 |
|
|
60 |
public void setValue(T value) { |
|
61 |
this.value = value; |
|
62 |
} |
|
63 |
|
|
64 |
public String getErrorMessage() { |
|
65 |
return errorMessage; |
|
66 |
} |
|
67 |
|
|
68 |
public void setErrorMessage(String errorMessage) { |
|
69 |
this.errorMessage = errorMessage; |
|
70 |
} |
|
71 |
|
|
72 |
public boolean isErrorMessageShown() { |
|
73 |
return isErrorMessageShown; |
|
74 |
} |
|
75 |
|
|
76 |
public void setErrorMessageShown(boolean errorMessageShown) { |
|
77 |
isErrorMessageShown = errorMessageShown; |
|
78 |
} |
|
79 |
} |
src/main/java/cz/zcu/fav/kiv/antipatterndetectionapp/service/AntiPatternServiceImpl.java | ||
---|---|---|
4 | 4 |
import cz.zcu.fav.kiv.antipatterndetectionapp.detecting.detectors.AntiPatternDetector; |
5 | 5 |
import cz.zcu.fav.kiv.antipatterndetectionapp.model.AntiPattern; |
6 | 6 |
import cz.zcu.fav.kiv.antipatterndetectionapp.model.CacheablesValues; |
7 |
import cz.zcu.fav.kiv.antipatterndetectionapp.model.Configuration;
|
|
7 |
import cz.zcu.fav.kiv.antipatterndetectionapp.model.Threshold;
|
|
8 | 8 |
import cz.zcu.fav.kiv.antipatterndetectionapp.model.QueryResult; |
9 | 9 |
import cz.zcu.fav.kiv.antipatterndetectionapp.model.types.Percentage; |
10 | 10 |
import cz.zcu.fav.kiv.antipatterndetectionapp.model.types.PositiveFloat; |
... | ... | |
48 | 48 |
AntiPattern antiPattern = antiPatternDetector.getAntiPatternModel(); |
49 | 49 |
|
50 | 50 |
// set to default value |
51 |
for (Map.Entry<String, Configuration> config : antiPattern.getConfigurations().entrySet()) {
|
|
52 |
config.getValue().setErrorMessageShown(false);
|
|
51 |
for (Map.Entry<String, Threshold> threshold : antiPattern.getThresholds().entrySet()) {
|
|
52 |
threshold.getValue().setErrorMessageShown(false);
|
|
53 | 53 |
} |
54 | 54 |
antiPatterns.add(antiPattern); |
55 | 55 |
} |
... | ... | |
60 | 60 |
public AntiPattern antiPatternToModel(AntiPatternDetector antiPatternDetector) { |
61 | 61 |
AntiPattern antiPattern = antiPatternDetector.getAntiPatternModel(); |
62 | 62 |
// set to default value |
63 |
for (Map.Entry<String, Configuration> config : antiPattern.getConfigurations().entrySet()) {
|
|
64 |
config.getValue().setErrorMessageShown(false);
|
|
63 |
for (Map.Entry<String, Threshold> threshold : antiPattern.getThresholds().entrySet()) {
|
|
64 |
threshold.getValue().setErrorMessageShown(false);
|
|
65 | 65 |
} |
66 | 66 |
return antiPattern; |
67 | 67 |
} |
... | ... | |
76 | 76 |
return antiPatternDetectors; |
77 | 77 |
} |
78 | 78 |
|
79 |
public List<String> saveNewConfiguration(String[] configNames, String[] configValues) {
|
|
79 |
public List<String> saveNewConfiguration(String[] thresholdNames, String[] thresholdValues) {
|
|
80 | 80 |
List<AntiPatternDetector> antiPatternDetectors = antiPatternRepository.getAllAntiPatterns(); |
81 | 81 |
List<String> incorrectParameters = new ArrayList<>(); |
82 | 82 |
|
83 | 83 |
for (AntiPatternDetector antiPatternDetector : antiPatternDetectors) { |
84 |
// not every anti-pattern should have configuration
|
|
85 |
if (antiPatternDetector.getAntiPatternModel().getConfigurations() == null) {
|
|
84 |
// not every anti-pattern should have thresholds
|
|
85 |
if (antiPatternDetector.getAntiPatternModel().getThresholds() == null) {
|
|
86 | 86 |
continue; |
87 | 87 |
} |
88 |
for (int i = 0; i < configNames.length; i++) {
|
|
89 |
if (antiPatternDetector.getAntiPatternModel().getConfigurations().containsKey(configNames[i])) {
|
|
88 |
for (int i = 0; i < thresholdNames.length; i++) {
|
|
89 |
if (antiPatternDetector.getAntiPatternModel().getThresholds().containsKey(thresholdNames[i])) {
|
|
90 | 90 |
|
91 |
if (antiPatternDetector.getAntiPatternModel().getConfigurations().get(configNames[i]).getValue().getClass() == Integer.class) {
|
|
91 |
if (antiPatternDetector.getAntiPatternModel().getThresholds().get(thresholdNames[i]).getValue().getClass() == Integer.class) {
|
|
92 | 92 |
try { |
93 |
antiPatternDetector.getAntiPatternModel().getConfigurations().get(configNames[i]).setValue((Integer.parseInt(configValues[i])));
|
|
93 |
antiPatternDetector.getAntiPatternModel().getThresholds().get(thresholdNames[i]).setValue((Integer.parseInt(thresholdValues[i])));
|
|
94 | 94 |
setConfigurationChanged(true); |
95 | 95 |
} catch (NumberFormatException e) { |
96 |
incorrectParameters.add(configNames[i]);
|
|
96 |
incorrectParameters.add(thresholdNames[i]);
|
|
97 | 97 |
} |
98 | 98 |
|
99 |
} else if (antiPatternDetector.getAntiPatternModel().getConfigurations().get(configNames[i]).getValue().getClass() == Percentage.class) {
|
|
99 |
} else if (antiPatternDetector.getAntiPatternModel().getThresholds().get(thresholdNames[i]).getValue().getClass() == Percentage.class) {
|
|
100 | 100 |
try { |
101 |
antiPatternDetector.getAntiPatternModel().getConfigurations().get(configNames[i]).setValue((Percentage.parsePercentage(configValues[i])));
|
|
101 |
antiPatternDetector.getAntiPatternModel().getThresholds().get(thresholdNames[i]).setValue((Percentage.parsePercentage(thresholdValues[i])));
|
|
102 | 102 |
setConfigurationChanged(true); |
103 | 103 |
} catch (NumberFormatException e) { |
104 |
incorrectParameters.add(configNames[i]);
|
|
104 |
incorrectParameters.add(thresholdNames[i]);
|
|
105 | 105 |
} |
106 |
} else if (antiPatternDetector.getAntiPatternModel().getConfigurations().get(configNames[i]).getValue().getClass() == PositiveInteger.class) {
|
|
106 |
} else if (antiPatternDetector.getAntiPatternModel().getThresholds().get(thresholdNames[i]).getValue().getClass() == PositiveInteger.class) {
|
|
107 | 107 |
try { |
108 |
antiPatternDetector.getAntiPatternModel().getConfigurations().get(configNames[i]).setValue((PositiveInteger.parsePositiveInteger(configValues[i])));
|
|
108 |
antiPatternDetector.getAntiPatternModel().getThresholds().get(thresholdNames[i]).setValue((PositiveInteger.parsePositiveInteger(thresholdValues[i])));
|
|
109 | 109 |
setConfigurationChanged(true); |
110 | 110 |
} catch (NumberFormatException e) { |
111 |
incorrectParameters.add(configNames[i]);
|
|
111 |
incorrectParameters.add(thresholdNames[i]);
|
|
112 | 112 |
} |
113 |
} else if (antiPatternDetector.getAntiPatternModel().getConfigurations().get(configNames[i]).getValue().getClass() == PositiveFloat.class) {
|
|
113 |
} else if (antiPatternDetector.getAntiPatternModel().getThresholds().get(thresholdNames[i]).getValue().getClass() == PositiveFloat.class) {
|
|
114 | 114 |
try { |
115 |
antiPatternDetector.getAntiPatternModel().getConfigurations().get(configNames[i]).setValue((PositiveFloat.parsePositiveFloat(configValues[i])));
|
|
115 |
antiPatternDetector.getAntiPatternModel().getThresholds().get(thresholdNames[i]).setValue((PositiveFloat.parsePositiveFloat(thresholdValues[i])));
|
|
116 | 116 |
setConfigurationChanged(true); |
117 | 117 |
} catch (NumberFormatException e) { |
118 |
incorrectParameters.add(configNames[i]);
|
|
118 |
incorrectParameters.add(thresholdNames[i]);
|
|
119 | 119 |
} |
120 |
} else if (antiPatternDetector.getAntiPatternModel().getConfigurations().get(configNames[i]).getValue().getClass() == Float.class) {
|
|
120 |
} else if (antiPatternDetector.getAntiPatternModel().getThresholds().get(thresholdNames[i]).getValue().getClass() == Float.class) {
|
|
121 | 121 |
try { |
122 |
antiPatternDetector.getAntiPatternModel().getConfigurations().get(configNames[i]).setValue((Float.parseFloat(configValues[i])));
|
|
122 |
antiPatternDetector.getAntiPatternModel().getThresholds().get(thresholdNames[i]).setValue((Float.parseFloat(thresholdValues[i])));
|
|
123 | 123 |
setConfigurationChanged(true); |
124 | 124 |
} catch (NumberFormatException e) { |
125 |
incorrectParameters.add(configNames[i]);
|
|
125 |
incorrectParameters.add(thresholdNames[i]);
|
|
126 | 126 |
} |
127 |
} else if (antiPatternDetector.getAntiPatternModel().getConfigurations().get(configNames[i]).getValue().getClass() == Double.class) {
|
|
127 |
} else if (antiPatternDetector.getAntiPatternModel().getThresholds().get(thresholdNames[i]).getValue().getClass() == Double.class) {
|
|
128 | 128 |
try { |
129 |
antiPatternDetector.getAntiPatternModel().getConfigurations().get(configNames[i]).setValue((Double.parseDouble(configValues[i])));
|
|
129 |
antiPatternDetector.getAntiPatternModel().getThresholds().get(thresholdNames[i]).setValue((Double.parseDouble(thresholdValues[i])));
|
|
130 | 130 |
setConfigurationChanged(true); |
131 | 131 |
} catch (NumberFormatException e) { |
132 |
incorrectParameters.add(configNames[i]);
|
|
132 |
incorrectParameters.add(thresholdNames[i]);
|
|
133 | 133 |
} |
134 |
} else if (antiPatternDetector.getAntiPatternModel().getConfigurations().get(configNames[i]).getValue().getClass() == String.class) {
|
|
135 |
if (Utils.checkStringSubstrings(configValues[i])) {
|
|
136 |
antiPatternDetector.getAntiPatternModel().getConfigurations().get(configNames[i]).setValue((configValues[i]));
|
|
134 |
} else if (antiPatternDetector.getAntiPatternModel().getThresholds().get(thresholdNames[i]).getValue().getClass() == String.class) {
|
|
135 |
if (Utils.checkStringSubstrings(thresholdValues[i])) {
|
|
136 |
antiPatternDetector.getAntiPatternModel().getThresholds().get(thresholdNames[i]).setValue((thresholdValues[i]));
|
|
137 | 137 |
setConfigurationChanged(true); |
138 | 138 |
|
139 | 139 |
} else { |
140 |
incorrectParameters.add(configNames[i]);
|
|
140 |
incorrectParameters.add(thresholdNames[i]);
|
|
141 | 141 |
} |
142 | 142 |
} |
143 | 143 |
} |
... | ... | |
185 | 185 |
@Override |
186 | 186 |
public List<AntiPattern> setErrorMessages(List<AntiPattern> antiPatterns, List<String> wrongParameters) { |
187 | 187 |
for (AntiPattern antiPattern : antiPatterns) { |
188 |
for (Map.Entry<String, Configuration> config : antiPattern.getConfigurations().entrySet()) {
|
|
189 |
if (wrongParameters.contains(config.getKey())) {
|
|
190 |
config.getValue().setErrorMessageShown(true);
|
|
188 |
for (Map.Entry<String, Threshold> threshold : antiPattern.getThresholds().entrySet()) {
|
|
189 |
if (wrongParameters.contains(threshold.getKey())) {
|
|
190 |
threshold.getValue().setErrorMessageShown(true);
|
|
191 | 191 |
} else { |
192 |
config.getValue().setErrorMessageShown(false);
|
|
192 |
threshold.getValue().setErrorMessageShown(false);
|
|
193 | 193 |
} |
194 | 194 |
} |
195 | 195 |
} |
... | ... | |
220 | 220 |
String APDescription = node.get("description").asText(); |
221 | 221 |
String APCatalogueFileName = node.get("catalogueFileName") != null ? node.get("catalogueFileName").asText() : null; |
222 | 222 |
|
223 |
Map<String, Configuration> APMap = new HashMap<>();
|
|
223 |
Map<String, Threshold> APMap = new HashMap<>();
|
|
224 | 224 |
|
225 |
JsonNode array = node.get("configurations");
|
|
226 |
Configuration<?> tmpConfig = null;
|
|
225 |
JsonNode array = node.get("thresholds");
|
|
226 |
Threshold<?> tmpThreshold = null;
|
|
227 | 227 |
|
228 | 228 |
for(int i = 0; i < array.size(); i++){ |
229 | 229 |
JsonNode tmpNode = array.get(i); |
230 | 230 |
|
231 |
String configName = tmpNode.get("configName").asText();
|
|
232 |
String configType = tmpNode.get("configType").asText();
|
|
231 |
String thresholdName = tmpNode.get("thresholdName").asText();
|
|
232 |
String thresholdType = tmpNode.get("thresholdType").asText();
|
|
233 | 233 |
|
234 |
JsonNode configNode = tmpNode.get("configuration");
|
|
234 |
JsonNode thresholdNode = tmpNode.get("threshold");
|
|
235 | 235 |
|
236 |
String CConfigName = configNode.get("configName").asText();
|
|
237 |
String CConfigPrintName = configNode.get("configPrintName").asText();
|
|
238 |
String CConfigDescription = configNode.get("configDescription").asText();
|
|
239 |
String CConfigErrorMess = configNode.get("configErrorMess").asText();
|
|
240 |
String CConfigValue = configNode.get("configValue").asText();
|
|
236 |
String tThresholdName = thresholdNode.get("thresholdName").asText();
|
|
237 |
String tThresholdPrintName = thresholdNode.get("thresholdPrintName").asText();
|
|
238 |
String tThresholdDescription = thresholdNode.get("thresholdDescription").asText();
|
|
239 |
String tThresholdErrorMess = thresholdNode.get("thresholdErrorMess").asText();
|
|
240 |
String tThresholdValue = thresholdNode.get("thresholdValue").asText();
|
|
241 | 241 |
|
242 |
tmpConfig = getConfiguration(configType, CConfigName, CConfigPrintName, CConfigDescription, CConfigErrorMess, CConfigValue);
|
|
242 |
tmpThreshold = getThreshold(thresholdType, tThresholdName, tThresholdPrintName, tThresholdDescription, tThresholdErrorMess, tThresholdValue);
|
|
243 | 243 |
|
244 |
APMap.put(configName, tmpConfig);
|
|
244 |
APMap.put(thresholdName, tmpThreshold);
|
|
245 | 245 |
} |
246 | 246 |
|
247 | 247 |
AntiPattern newAP = new AntiPattern(APid, APPrintName, APName, APDescription, APMap, APCatalogueFileName); |
... | ... | |
249 | 249 |
return newAP; |
250 | 250 |
} |
251 | 251 |
|
252 |
private Configuration<?> getConfiguration(String configType, String name, String printName, String description, String errorMessage, String value){
|
|
252 |
private Threshold<?> getThreshold(String thresholdType, String name, String printName, String description, String errorMessage, String value){
|
|
253 | 253 |
|
254 |
if(configType.equals("Percentage")){
|
|
255 |
return new Configuration<>(name, printName, description, errorMessage, new Percentage(Float.parseFloat(value)));
|
|
254 |
if(thresholdType.equals("Percentage")){
|
|
255 |
return new Threshold<>(name, printName, description, errorMessage, new Percentage(Float.parseFloat(value)));
|
|
256 | 256 |
} |
257 |
else if(configType.equals("PositiveFloat")){
|
|
258 |
return new Configuration<>(name, printName, description, errorMessage, new PositiveFloat(Float.parseFloat(value)));
|
|
257 |
else if(thresholdType.equals("PositiveFloat")){
|
|
258 |
return new Threshold<>(name, printName, description, errorMessage, new PositiveFloat(Float.parseFloat(value)));
|
|
259 | 259 |
} |
260 |
else if(configType.equals("PositiveInteger")){
|
|
261 |
return new Configuration<>(name, printName, description, errorMessage, new PositiveInteger(Integer.parseInt(value)));
|
|
260 |
else if(thresholdType.equals("PositiveInteger")){
|
|
261 |
return new Threshold<>(name, printName, description, errorMessage, new PositiveInteger(Integer.parseInt(value)));
|
|
262 | 262 |
} |
263 |
else if(configType.equals("String")){
|
|
264 |
return new Configuration<>(name, printName, description, errorMessage, value);
|
|
263 |
else if(thresholdType.equals("String")){
|
|
264 |
return new Threshold<>(name, printName, description, errorMessage, value);
|
|
265 | 265 |
} |
266 | 266 |
|
267 | 267 |
return null; |
src/main/webapp/WEB-INF/templates/anti-pattern.html | ||
---|---|---|
147 | 147 |
|
148 | 148 |
<!-- Form for configuration values --> |
149 | 149 |
<form action="#" th:action="@{/anti-patterns/} + ${antiPattern.id}" th:object="${antiPattern}" method="post"> |
150 |
<div th:each="config : ${antiPattern.configurations}" class="form-group">
|
|
151 |
<label th:text="${config.value.printName} + ':'"
|
|
152 |
th:for="${config.value.name}"></label>
|
|
153 |
<small th:text="${config.value.description}" th:value="${config.value.name}"
|
|
150 |
<div th:each="threshold : ${antiPattern.thresholds}" class="form-group">
|
|
151 |
<label th:text="${threshold.value.printName} + ':'"
|
|
152 |
th:for="${threshold.value.name}"></label>
|
|
153 |
<small th:text="${threshold.value.description}" th:value="${threshold.value.name}"
|
|
154 | 154 |
class="form-text text-muted"></small> |
155 |
<input th:if="${config.value.isErrorMessageShown}" th:value="${config.value.value}" class="form-control is-invalid" th:id="${config.value.name}"
|
|
156 |
name="configValues">
|
|
157 |
<input th:unless="${config.value.isErrorMessageShown}" th:value="${config.value.value}" class="form-control" th:id="${config.value.name}"
|
|
158 |
name="configValues">
|
|
159 |
<input th:value="${config.value.name}" style="display: none" class="form-control"
|
|
160 |
name="configNames">
|
|
161 |
<small th:if="${config.value.isErrorMessageShown}" th:text="${config.value.errorMessage}" th:value="${config.value.errorMessage}"
|
|
155 |
<input th:if="${threshold.value.isErrorMessageShown}" th:value="${threshold.value.value}" class="form-control is-invalid" th:id="${threshold.value.name}"
|
|
156 |
name="thresholdValues">
|
|
157 |
<input th:unless="${threshold.value.isErrorMessageShown}" th:value="${threshold.value.value}" class="form-control" th:id="${threshold.value.name}"
|
|
158 |
name="thresholdValues">
|
|
159 |
<input th:value="${threshold.value.name}" style="display: none" class="form-control"
|
|
160 |
name="thresholdNames">
|
|
161 |
<small th:if="${threshold.value.isErrorMessageShown}" th:text="${threshold.value.errorMessage}" th:value="${threshold.value.errorMessage}"
|
|
162 | 162 |
class="form-text text-danger"></small> |
163 | 163 |
|
164 | 164 |
</div> |
src/main/webapp/WEB-INF/templates/configuration.html | ||
---|---|---|
37 | 37 |
<form action="#" th:action="@{/configuration}" th:object="${antiPatterns}" method="post"> |
38 | 38 |
<div th:each="antiPattern : ${antiPatterns}"> |
39 | 39 |
<h3 th:text="${antiPattern.printName}"></h3> |
40 |
<div th:each="config : ${antiPattern.configurations}">
|
|
40 |
<div th:each="threshold : ${antiPattern.thresholds}">
|
|
41 | 41 |
<div class="form-group row"> |
42 |
<label th:text="${config.value.printName} + ':'" th:for="${config.value.name}"
|
|
42 |
<label th:text="${threshold.value.printName} + ':'" th:for="${threshold.value.name}"
|
|
43 | 43 |
class="col-sm-5 col-form-label"></label> |
44 | 44 |
<div class="col-sm-5"> |
45 |
<small th:text="${config.value.description}" th:value="${config.value.name}"
|
|
45 |
<small th:text="${threshold.value.description}" th:value="${threshold.value.name}"
|
|
46 | 46 |
class="form-text text-muted"></small> |
47 | 47 |
<div id="wrapper"> |
48 | 48 |
<div id="first"> |
49 |
<input th:if="${config.value.isErrorMessageShown}" th:value="${config.value.value}"
|
|
50 |
class="form-control is-invalid" th:id="${config.value.name}"
|
|
51 |
name="configValues">
|
|
52 |
<input th:unless="${config.value.isErrorMessageShown}"
|
|
53 |
th:value="${config.value.value}"
|
|
54 |
class="form-control" th:id="${config.value.name}"
|
|
55 |
name="configValues">
|
|
56 |
<input th:value="${config.value.name}" style="display: none" class="form-control"
|
|
57 |
name="configNames">
|
|
49 |
<input th:if="${threshold.value.isErrorMessageShown}" th:value="${threshold.value.value}"
|
|
50 |
class="form-control is-invalid" th:id="${threshold.value.name}"
|
|
51 |
name="thresholdValues">
|
|
52 |
<input th:unless="${threshold.value.isErrorMessageShown}"
|
|
53 |
th:value="${threshold.value.value}"
|
|
54 |
class="form-control" th:id="${threshold.value.name}"
|
|
55 |
name="thresholdValues">
|
|
56 |
<input th:value="${threshold.value.name}" style="display: none" class="form-control"
|
|
57 |
name="thresholdNames">
|
|
58 | 58 |
</div> |
59 |
<div th:if="${#strings.contains(config.value.name,'Substrings')}" id="second"
|
|
59 |
<div th:if="${#strings.contains(threshold.value.name,'Substrings')}" id="second"
|
|
60 | 60 |
style="margin: 10px; padding-left: 10px"> |
61 | 61 |
<svg style="display: inline-block" |
62 | 62 |
xmlns="http://www.w3.org/2000/svg" |
... | ... | |
74 | 74 |
</div> |
75 | 75 |
</div> |
76 | 76 |
|
77 |
<small th:if="${config.value.isErrorMessageShown}" th:text="${config.value.errorMessage}"
|
|
78 |
th:value="${config.value.errorMessage}"
|
|
77 |
<small th:if="${threshold.value.isErrorMessageShown}" th:text="${threshold.value.errorMessage}"
|
|
78 |
th:value="${threshold.value.errorMessage}"
|
|
79 | 79 |
class="form-text text-danger"></small> |
80 | 80 |
|
81 | 81 |
</div> |
src/main/webapp/antipatterns/BusinessAsUsual.json | ||
---|---|---|
3 | 3 |
"printName": "Business As Usual", |
4 | 4 |
"name": "BusinessAsUsual", |
5 | 5 |
"description": "Absence of a retrospective after individual iterations or after the completion project.", |
6 |
"configurations": [
|
|
6 |
"thresholds": [
|
|
7 | 7 |
{ |
8 |
"configName": "divisionOfIterationsWithRetrospective",
|
|
9 |
"configType": "Percentage",
|
|
10 |
"configuration": {
|
|
11 |
"configName": "divisionOfIterationsWithRetrospective",
|
|
12 |
"configPrintName": "Division of iterations with retrospective",
|
|
13 |
"configDescription": "Minimum percentage of the total number of iterations with a retrospective (0,100)",
|
|
14 |
"configErrorMess": "Percentage must be float number between 0 and 100",
|
|
15 |
"configValue": "66.66f"
|
|
8 |
"thresholdName": "divisionOfIterationsWithRetrospective",
|
|
9 |
"thresholdType": "Percentage",
|
|
10 |
"threshold": {
|
|
11 |
"thresholdName": "divisionOfIterationsWithRetrospective",
|
|
12 |
"thresholdPrintName": "Division of iterations with retrospective",
|
|
13 |
"thresholdDescription": "Minimum percentage of the total number of iterations with a retrospective (0,100)",
|
|
14 |
"thresholdErrorMess": "Percentage must be float number between 0 and 100",
|
|
15 |
"thresholdValue": "66.66f"
|
|
16 | 16 |
} |
17 | 17 |
}, |
18 | 18 |
{ |
19 |
"configName": "searchSubstringsWithRetrospective",
|
|
20 |
"configType": "String",
|
|
21 |
"configuration": {
|
|
22 |
"configName": "searchSubstringsWithRetrospective",
|
|
23 |
"configPrintName": "Search substrings with retrospective",
|
|
24 |
"configDescription": "Substring that will be search in wikipages and activities",
|
|
25 |
"configErrorMess": "Maximum number of substrings is ten and must not starts and ends with characters || ",
|
|
26 |
"configValue": "%retr%||%revi%||%week%scrum%"
|
|
19 |
"thresholdName": "searchSubstringsWithRetrospective",
|
|
20 |
"thresholdType": "String",
|
|
21 |
"threshold": {
|
|
22 |
"thresholdName": "searchSubstringsWithRetrospective",
|
|
23 |
"thresholdPrintName": "Search substrings with retrospective",
|
|
24 |
"thresholdDescription": "Substring that will be search in wikipages and activities",
|
|
25 |
"thresholdErrorMess": "Maximum number of substrings is ten and must not starts and ends with characters || ",
|
|
26 |
"thresholdValue": "%retr%||%revi%||%week%scrum%"
|
|
27 | 27 |
} |
28 | 28 |
} |
29 | 29 |
], |
src/main/webapp/antipatterns/LongOrNonExistentFeedbackLoops.json | ||
---|---|---|
3 | 3 |
"printName": "Long Or Non Existent Feedback Loops", |
4 | 4 |
"name": "LongOrNonExistentFeedbackLoops", |
5 | 5 |
"description": "Long spacings between customer feedback or no feedback. The customer enters the project and sees the final result. In the end, the customer may not get what he really wanted. With long intervals of feedback, some misunderstood functionality can be created and we have to spend a lot of effort and time to redo it. ", |
6 |
"configurations": [
|
|
6 |
"thresholds": [
|
|
7 | 7 |
{ |
8 |
"configName": "divisionOfIterationsWithFeedbackLoop",
|
|
9 |
"configType": "Percentage",
|
|
10 |
"configuration": {
|
|
11 |
"configName": "divisionOfIterationsWithFeedbackLoop",
|
|
12 |
"configPrintName": "Division of iterations with feedback loop",
|
|
13 |
"configDescription": "Minimum percentage of the total number of iterations with feedback loop (0,100)",
|
|
14 |
"configErrorMess": "Percentage must be float number between 0 and 100",
|
|
15 |
"configValue": "50.00f"
|
|
8 |
"thresholdName": "divisionOfIterationsWithFeedbackLoop",
|
|
9 |
"thresholdType": "Percentage",
|
|
10 |
"threshold": {
|
|
11 |
"thresholdName": "divisionOfIterationsWithFeedbackLoop",
|
|
12 |
"thresholdPrintName": "Division of iterations with feedback loop",
|
|
13 |
"thresholdDescription": "Minimum percentage of the total number of iterations with feedback loop (0,100)",
|
|
14 |
"thresholdErrorMess": "Percentage must be float number between 0 and 100",
|
|
15 |
"thresholdValue": "50.00f"
|
|
16 | 16 |
} |
17 | 17 |
}, |
18 | 18 |
{ |
19 |
"configName": "maxGapBetweenFeedbackLoopRate",
|
|
20 |
"configType": "PositiveFloat",
|
|
21 |
"configuration": {
|
|
22 |
"configName": "maxGapBetweenFeedbackLoopRate",
|
|
23 |
"configPrintName": "Maximum gap between feedback loop rate",
|
|
24 |
"configDescription": "Value that multiplies average iteration length for given project. Result is maximum threshold value for gap between feedback loops in days.",
|
|
25 |
"configErrorMess": "Maximum gap between feedback loop rate must be positive float number",
|
|
26 |
"configValue": "2f"
|
|
19 |
"thresholdName": "maxGapBetweenFeedbackLoopRate",
|
|
20 |
"thresholdType": "PositiveFloat",
|
|
21 |
"threshold": {
|
|
22 |
"thresholdName": "maxGapBetweenFeedbackLoopRate",
|
|
23 |
"thresholdPrintName": "Maximum gap between feedback loop rate",
|
|
24 |
"thresholdDescription": "Value that multiplies average iteration length for given project. Result is maximum threshold value for gap between feedback loops in days.",
|
|
25 |
"thresholdErrorMess": "Maximum gap between feedback loop rate must be positive float number",
|
|
26 |
"thresholdValue": "2f"
|
|
27 | 27 |
} |
28 | 28 |
}, |
29 | 29 |
{ |
30 |
"configName": "searchSubstringsWithFeedbackLoop",
|
|
31 |
"configType": "String",
|
|
32 |
"configuration": {
|
|
33 |
"configName": "searchSubstringsWithFeedbackLoop",
|
|
34 |
"configPrintName": "Search substrings with feedback loop",
|
|
35 |
"configDescription": "Substring that will be search in wikipages and activities",
|
|
36 |
"configErrorMess": "Maximum number of substrings is ten and must not starts and ends with characters ||",
|
|
37 |
"configValue": "%schůz%zákazník%||%předvedení%zákazník%||%zákazn%demo%||%schůz%zadavat%||%inform%schůz%||%zákazn%||%zadavatel%"
|
|
30 |
"thresholdName": "searchSubstringsWithFeedbackLoop",
|
|
31 |
"thresholdType": "String",
|
|
32 |
"threshold": {
|
|
33 |
"thresholdName": "searchSubstringsWithFeedbackLoop",
|
|
34 |
"thresholdPrintName": "Search substrings with feedback loop",
|
|
35 |
"thresholdDescription": "Substring that will be search in wikipages and activities",
|
|
36 |
"thresholdErrorMess": "Maximum number of substrings is ten and must not starts and ends with characters ||",
|
|
37 |
"thresholdValue": "%schůz%zákazník%||%předvedení%zákazník%||%zákazn%demo%||%schůz%zadavat%||%inform%schůz%||%zákazn%||%zadavatel%"
|
|
38 | 38 |
} |
39 | 39 |
} |
40 | 40 |
] |
src/main/webapp/antipatterns/NinetyNinetyRule.json | ||
---|---|---|
3 | 3 |
"printName": "Ninety Ninety Rule", |
4 | 4 |
"name": "NinetyNinetyRule", |
5 | 5 |
"description": "The first 90 percent of the code represents the first 90 percent of development time. The remaining 10 percent of the code represents another 90 percent of development time. Then decide on a long delay of the project compared to the original estimate. The functionality is almost done, some number is already closed and is only waiting for one activity to close, but it has been open for a long time.", |
6 |
"configurations": [
|
|
6 |
"thresholds": [
|
|
7 | 7 |
{ |
8 |
"configName": "maxDivisionRange",
|
|
9 |
"configType": "PositiveFloat",
|
|
10 |
"configuration": {
|
|
11 |
"configName": "maxDivisionRange",
|
|
12 |
"configPrintName": "Maximum ration value",
|
|
13 |
"configDescription": "Maximum ratio value of spent and estimated time",
|
|
14 |
"configErrorMess": "Ration values must be positive float number",
|
|
15 |
"configValue": "1.25f"
|
|
8 |
"thresholdName": "maxDivisionRange",
|
|
9 |
"thresholdType": "PositiveFloat",
|
|
10 |
"threshold": {
|
|
11 |
"thresholdName": "maxDivisionRange",
|
|
12 |
"thresholdPrintName": "Maximum ration value",
|
|
13 |
"thresholdDescription": "Maximum ratio value of spent and estimated time",
|
|
14 |
"thresholdErrorMess": "Ration values must be positive float number",
|
|
15 |
"thresholdValue": "1.25f"
|
|
16 | 16 |
} |
17 | 17 |
}, |
18 | 18 |
{ |
19 |
"configName": "maxBadDivisionLimit",
|
|
20 |
"configType": "PositiveInteger",
|
|
21 |
"configuration": {
|
|
22 |
"configName": "maxBadDivisionLimit",
|
|
23 |
"configPrintName": "Maximum iterations thresholds",
|
|
24 |
"configDescription": "Maximum number of consecutive iterations where the thresholds were exceeded",
|
|
25 |
"configErrorMess": "Maximum number of consecutive iterations must be positive integer number",
|
|
26 |
"configValue": "2"
|
|
19 |
"thresholdName": "maxBadDivisionLimit",
|
|
20 |
"thresholdType": "PositiveInteger",
|
|
21 |
"threshold": {
|
|
22 |
"thresholdName": "maxBadDivisionLimit",
|
|
23 |
"thresholdPrintName": "Maximum iterations thresholds",
|
|
24 |
"thresholdDescription": "Maximum number of consecutive iterations where the thresholds were exceeded",
|
|
25 |
"thresholdErrorMess": "Maximum number of consecutive iterations must be positive integer number",
|
|
26 |
"thresholdValue": "2"
|
|
27 | 27 |
} |
28 | 28 |
} |
29 | 29 |
] |
src/main/webapp/antipatterns/RoadToNowhere.json | ||
---|---|---|
3 | 3 |
"printName": "Road To Nowhere", |
4 | 4 |
"name": "RoadToNowhere", |
5 | 5 |
"description": "The project is not sufficiently planned and therefore takes place on an ad hoc basis with an uncertain outcome and deadline. There is no project plan in the project.", |
6 |
"configurations": [
|
|
6 |
"thresholds": [
|
|
7 | 7 |
{ |
8 |
"configName": "minNumberOfWikiPagesWithProjectPlan",
|
|
9 |
"configType": "PositiveInteger",
|
|
10 |
"configuration": {
|
|
11 |
"configName": "minNumberOfWikiPagesWithProjectPlan",
|
|
12 |
"configPrintName": "Minimum number of wiki pages with project plan",
|
|
13 |
"configDescription": "Number of wiki pages",
|
|
14 |
"configErrorMess": "Minimum number of wikipages must be positive integer number",
|
|
15 |
"configValue": "1"
|
|
8 |
"thresholdName": "minNumberOfWikiPagesWithProjectPlan",
|
|
9 |
"thresholdType": "PositiveInteger",
|
|
10 |
"threshold": {
|
|
11 |
"thresholdName": "minNumberOfWikiPagesWithProjectPlan",
|
|
12 |
"thresholdPrintName": "Minimum number of wiki pages with project plan",
|
|
13 |
"thresholdDescription": "Number of wiki pages",
|
|
14 |
"thresholdErrorMess": "Minimum number of wikipages must be positive integer number",
|
|
15 |
"thresholdValue": "1"
|
|
16 | 16 |
} |
17 | 17 |
}, |
18 | 18 |
{ |
19 |
"configName": "minNumberOfActivitiesWithProjectPlan",
|
|
20 |
"configType": "PositiveInteger",
|
|
21 |
"configuration": {
|
|
22 |
"configName": "minNumberOfActivitiesWithProjectPlan",
|
|
23 |
"configPrintName": "Minimum number of activities with project plan",
|
|
24 |
"configDescription": "Number of activities",
|
|
25 |
"configErrorMess": "Minimum number of activities must be positive integer number",
|
|
26 |
"configValue": "1"
|
|
19 |
"thresholdName": "minNumberOfActivitiesWithProjectPlan",
|
|
20 |
"thresholdType": "PositiveInteger",
|
|
21 |
"threshold": {
|
|
22 |
"thresholdName": "minNumberOfActivitiesWithProjectPlan",
|
|
23 |
"thresholdPrintName": "Minimum number of activities with project plan",
|
|
24 |
"thresholdDescription": "Number of activities",
|
|
25 |
"thresholdErrorMess": "Minimum number of activities must be positive integer number",
|
|
26 |
"thresholdValue": "1"
|
|
27 | 27 |
} |
28 | 28 |
}, |
29 | 29 |
{ |
30 |
"configName": "searchSubstringsWithProjectPlan",
|
|
31 |
"configType": "String",
|
|
32 |
"configuration": {
|
|
33 |
"configName": "searchSubstringsWithProjectPlan",
|
|
34 |
"configPrintName": "Search substrings with project plan",
|
|
35 |
"configDescription": "Substring that will be search in wikipages and activities",
|
|
36 |
"configErrorMess": "Maximum number of substrings is ten and must not starts and ends with characters ||",
|
|
37 |
"configValue": "%plán projektu%||%project plan%||%plan project%||%projektový plán%"
|
|
30 |
"thresholdName": "searchSubstringsWithProjectPlan",
|
|
31 |
"thresholdType": "String",
|
|
32 |
"threshold": {
|
|
33 |
"thresholdName": "searchSubstringsWithProjectPlan",
|
|
34 |
"thresholdPrintName": "Search substrings with project plan",
|
|
35 |
"thresholdDescription": "Substring that will be search in wikipages and activities",
|
|
36 |
"thresholdErrorMess": "Maximum number of substrings is ten and must not starts and ends with characters ||",
|
|
37 |
"thresholdValue": "%plán projektu%||%project plan%||%plan project%||%projektový plán%"
|
|
38 | 38 |
} |
39 | 39 |
} |
40 | 40 |
], |
src/main/webapp/antipatterns/SpecifyNothing.json | ||
---|---|---|
3 | 3 |
"printName": "Specify Nothing", |
4 | 4 |
"name": "SpecifyNothing", |
5 | 5 |
"description": "The specification is not done intentionally. Programmers are expected to work better without written specifications.", |
6 |
"configurations": [
|
|
6 |
"thresholds": [
|
|
7 | 7 |
{ |
8 |
"configName": "minNumberOfWikiPagesWithSpecification",
|
|
9 |
"configType": "PositiveInteger",
|
|
10 |
"configuration": {
|
|
11 |
"configName": "minNumberOfWikiPagesWithSpecification",
|
|
12 |
"configPrintName": "Minimum number of wiki pages with project specification",
|
|
13 |
"configDescription": "Number of wiki pages",
|
|
14 |
"configErrorMess": "Minimum number of wikipages must be positive integer number",
|
|
15 |
"configValue": "1"
|
|
8 |
"thresholdName": "minNumberOfWikiPagesWithSpecification",
|
|
9 |
"thresholdType": "PositiveInteger",
|
|
10 |
"threshold": {
|
|
11 |
"thresholdName": "minNumberOfWikiPagesWithSpecification",
|
|
12 |
"thresholdPrintName": "Minimum number of wiki pages with project specification",
|
|
13 |
"thresholdDescription": "Number of wiki pages",
|
|
14 |
"thresholdErrorMess": "Minimum number of wikipages must be positive integer number",
|
|
15 |
"thresholdValue": "1"
|
|
16 | 16 |
} |
17 | 17 |
}, |
18 | 18 |
{ |
19 |
"configName": "minNumberOfActivitiesWithSpecification",
|
|
20 |
"configType": "PositiveInteger",
|
|
21 |
"configuration": {
|
|
22 |
"configName": "minNumberOfActivitiesWithSpecification",
|
|
23 |
"configPrintName": "Minimum number of activities with project specification",
|
|
24 |
"configDescription": "Number of activities",
|
|
25 |
"configErrorMess": "Minimum number of activities with project specification must be positive integer number",
|
|
26 |
"configValue": "1"
|
|
19 |
"thresholdName": "minNumberOfActivitiesWithSpecification",
|
|
20 |
"thresholdType": "PositiveInteger",
|
|
21 |
"threshold": {
|
|
22 |
"thresholdName": "minNumberOfActivitiesWithSpecification",
|
|
23 |
"thresholdPrintName": "Minimum number of activities with project specification",
|
|
24 |
"thresholdDescription": "Number of activities",
|
|
25 |
"thresholdErrorMess": "Minimum number of activities with project specification must be positive integer number",
|
|
26 |
"thresholdValue": "1"
|
|
27 | 27 |
} |
28 | 28 |
}, |
29 | 29 |
{ |
30 |
"configName": "minAvgLengthOfActivityDescription",
|
|
31 |
"configType": "PositiveInteger",
|
|
32 |
"configuration": {
|
|
33 |
"configName": "minAvgLengthOfActivityDescription",
|
|
34 |
"configPrintName": "Minimum average length of activity description",
|
|
35 |
"configDescription": "Minimum average number of character of activity description",
|
|
36 |
"configErrorMess": "Minimum average length of activity description must be positive integer number",
|
|
37 |
"configValue": "150"
|
|
30 |
"thresholdName": "minAvgLengthOfActivityDescription",
|
|
31 |
"thresholdType": "PositiveInteger",
|
|
32 |
"threshold": {
|
|
33 |
"thresholdName": "minAvgLengthOfActivityDescription",
|
|
34 |
"thresholdPrintName": "Minimum average length of activity description",
|
|
35 |
"thresholdDescription": "Minimum average number of character of activity description",
|
|
36 |
"thresholdErrorMess": "Minimum average length of activity description must be positive integer number",
|
|
37 |
"thresholdValue": "150"
|
|
38 | 38 |
} |
39 | 39 |
}, |
40 | 40 |
{ |
41 |
"configName": "searchSubstringsWithProjectSpecification",
|
|
42 |
"configType": "String",
|
|
43 |
"configuration": {
|
|
44 |
"configName": "searchSubstringsWithProjectSpecification",
|
|
45 |
"configPrintName": "Search substrings with project specification",
|
|
46 |
"configDescription": "Substring that will be search in wikipages and activities",
|
|
47 |
"configErrorMess": "Maximum number of substrings is ten and must not starts and ends with characters ||",
|
|
48 |
"configValue": "%dsp%||%specifikace%||%specification%||%vize%proj%||%vize%produ%"
|
|
41 |
"thresholdName": "searchSubstringsWithProjectSpecification",
|
|
42 |
"thresholdType": "String",
|
|
43 |
"threshold": {
|
|
44 |
"thresholdName": "searchSubstringsWithProjectSpecification",
|
|
45 |
"thresholdPrintName": "Search substrings with project specification",
|
|
46 |
"thresholdDescription": "Substring that will be search in wikipages and activities",
|
|
47 |
"thresholdErrorMess": "Maximum number of substrings is ten and must not starts and ends with characters ||",
|
|
48 |
"thresholdValue": "%dsp%||%specifikace%||%specification%||%vize%proj%||%vize%produ%"
|
|
49 | 49 |
} |
50 | 50 |
} |
51 | 51 |
], |
src/main/webapp/antipatterns/TooLongSprint.json | ||
---|---|---|
3 | 3 |
"printName": "Too Long Sprint", |
4 | 4 |
"name": "TooLongSprint", |
5 | 5 |
"description": "Iterations too long. (ideal iteration length is about 1-2 weeks, maximum 3 weeks). It could also be detected here if the length of the iteration does not change often (It can change at the beginning and at the end of the project, but it should not change in the already started project).", |
6 |
"configurations": [
|
|
6 |
"thresholds": [
|
|
7 | 7 |
{ |
8 |
"configName": "maxIterationLength",
|
|
9 |
"configType": "PositiveInteger",
|
|
10 |
"configuration": {
|
|
11 |
"configName": "maxIterationLength",
|
|
12 |
"configPrintName": "Max Iteration Length",
|
|
13 |
"configDescription": "Maximum iteration length in days",
|
|
14 |
"configErrorMess": "Max iteration length must be positive integer",
|
|
15 |
"configValue": "21"
|
|
8 |
"thresholdName": "maxIterationLength",
|
|
9 |
"thresholdType": "PositiveInteger",
|
|
10 |
"threshold": {
|
|
11 |
"thresholdName": "maxIterationLength",
|
|
12 |
"thresholdPrintName": "Max Iteration Length",
|
|
13 |
"thresholdDescription": "Maximum iteration length in days",
|
|
14 |
"thresholdErrorMess": "Max iteration length must be positive integer",
|
|
15 |
"thresholdValue": "21"
|
|
16 | 16 |
} |
17 | 17 |
}, |
18 | 18 |
{ |
19 |
"configName": "maxNumberOfTooLongIterations",
|
|
20 |
"configType": "PositiveInteger",
|
|
21 |
"configuration": {
|
|
22 |
"configName": "maxNumberOfTooLongIterations",
|
|
23 |
"configPrintName": "Max number of foo long iterations",
|
|
24 |
"configDescription": "Maximum number of too long iterations in project",
|
|
25 |
"configErrorMess": "Max number of too long iterations must be positive integer",
|
|
26 |
"configValue": "0"
|
|
19 |
"thresholdName": "maxNumberOfTooLongIterations",
|
|
20 |
"thresholdType": "PositiveInteger",
|
|
21 |
"threshold": {
|
|
22 |
"thresholdName": "maxNumberOfTooLongIterations",
|
|
23 |
"thresholdPrintName": "Max number of foo long iterations",
|
|
24 |
"thresholdDescription": "Maximum number of too long iterations in project",
|
|
25 |
"thresholdErrorMess": "Max number of too long iterations must be positive integer",
|
|
26 |
"thresholdValue": "0"
|
|
27 | 27 |
} |
28 | 28 |
} |
29 | 29 |
] |
src/main/webapp/antipatterns/VaryingSprintLength.json | ||
---|---|---|
3 | 3 |
"printName": "Varying Sprint Length", |
4 | 4 |
"name": "VaryingSprintLength", |
5 | 5 |
"description": "The length of the sprint changes very often. It is clear that iterations will be different lengths at the beginning and end of the project, but the length of the sprint should not change during the project.", |
6 |
"configurations": [
|
|
6 |
"thresholds": [
|
|
7 | 7 |
{ |
8 |
"configName": "maxDaysDifference",
|
|
9 |
"configType": "PositiveInteger",
|
|
10 |
"configuration": {
|
|
11 |
"configName": "maxDaysDifference",
|
|
12 |
"configPrintName": "Max days difference",
|
|
13 |
"configDescription": "Maximum distance of two consecutive iterations in days",
|
|
14 |
"configErrorMess": "Maximum distance must be positive integer number",
|
|
15 |
"configValue": "7"
|
|
8 |
"thresholdName": "maxDaysDifference",
|
|
9 |
"thresholdType": "PositiveInteger",
|
|
10 |
"threshold": {
|
|
11 |
"thresholdName": "maxDaysDifference",
|
|
12 |
"thresholdPrintName": "Max days difference",
|
|
13 |
"thresholdDescription": "Maximum distance of two consecutive iterations in days",
|
|
14 |
"thresholdErrorMess": "Maximum distance must be positive integer number",
|
|
15 |
"thresholdValue": "7"
|
|
16 | 16 |
} |
17 | 17 |
}, |
18 | 18 |
{ |
19 |
"configName": "maxIterationChanged",
|
|
20 |
"configType": "PositiveInteger",
|
|
21 |
"configuration": {
|
|
22 |
"configName": "maxIterationChanged",
|
|
23 |
"configPrintName": "Max number of iteration changed",
|
|
24 |
"configDescription": "Maximum allowed number of significant changes in iteration lengths",
|
|
25 |
"configErrorMess": "Maximum number of iterations changed must be positive integer number",
|
|
26 |
"configValue": "1"
|
|
19 |
"thresholdName": "maxIterationChanged",
|
|
20 |
"thresholdType": "PositiveInteger",
|
|
21 |
"threshold": {
|
|
22 |
"thresholdName": "maxIterationChanged",
|
|
23 |
"thresholdPrintName": "Max number of iteration changed",
|
|
24 |
"thresholdDescription": "Maximum allowed number of significant changes in iteration lengths",
|
|
25 |
"thresholdErrorMess": "Maximum number of iterations changed must be positive integer number",
|
|
26 |
"thresholdValue": "1"
|
|
27 | 27 |
} |
28 | 28 |
} |
29 | 29 |
] |
Také k dispozici: Unified diff
Configuration renamed to Threshold