Revize 6cfce16e
Přidáno uživatelem Ondřej Váně před téměř 3 roky(ů)
src/main/java/cz/zcu/fav/kiv/antipatterndetectionapp/controller/AppController.java | ||
---|---|---|
137 | 137 |
@RequestParam(value = "configValues", required = false) String[] configValues, |
138 | 138 |
@RequestParam(value = "configNames", required = false) String[] configNames) { |
139 | 139 |
|
140 |
if (antiPatternService.saveNewConfiguration(configNames, configValues)) { |
|
140 |
List<AntiPattern> antiPatterns = antiPatternService.antiPatternsToModel(antiPatternService.getAllAntiPatterns()); |
|
141 |
List<String> wrongParameters = antiPatternService.saveNewConfiguration(configNames, configValues); |
|
142 |
|
|
143 |
if (wrongParameters.isEmpty()) { |
|
141 | 144 |
model.addAttribute("successMessage", "All configuration values has been successfully saved."); |
142 | 145 |
} else { |
143 |
model.addAttribute("errorMessage", "One or more configuration values are not in correct format"); |
|
146 |
model.addAttribute("errorMessage", "One or more configuration values are not in correct format, see messages below."); |
|
147 |
antiPatternService.setErrorMessages(antiPatterns, wrongParameters); |
|
144 | 148 |
} |
145 | 149 |
|
146 |
model.addAttribute("antiPatterns", antiPatternService.antiPatternsToModel(antiPatternService.getAllAntiPatterns())); |
|
147 |
|
|
150 |
model.addAttribute("antiPatterns", antiPatterns); |
|
148 | 151 |
return "configuration"; |
149 | 152 |
} |
150 | 153 |
|
... | ... | |
155 | 158 |
@RequestParam(value = "configNames", required = false) String[] configNames, |
156 | 159 |
RedirectAttributes redirectAttrs) { |
157 | 160 |
|
158 |
if (antiPatternService.saveNewConfiguration(configNames, configValues)) { |
|
161 |
AntiPattern antiPattern = antiPatternService.antiPatternToModel(antiPatternService.getAntiPatternById(id)); |
|
162 |
List<String> wrongParameters = antiPatternService.saveNewConfiguration(configNames, configValues); |
|
163 |
|
|
164 |
if (wrongParameters.isEmpty()) { |
|
159 | 165 |
redirectAttrs.addFlashAttribute("successMessage", "All threshold values has been successfully saved."); |
160 | 166 |
} else { |
161 |
redirectAttrs.addFlashAttribute("errorMessage", "One or more configuration values are not in correct format"); |
|
167 |
redirectAttrs.addFlashAttribute("errorMessage", "One or more configuration values are not in correct format, see messages below."); |
|
168 |
antiPatternService.setErrorMessages(antiPattern, wrongParameters); |
|
162 | 169 |
} |
163 | 170 |
|
164 |
model.addAttribute("antiPatterns", antiPatternService.antiPatternToModel(antiPatternService.getAntiPatternById(id)));
|
|
171 |
model.addAttribute("antiPatterns", antiPattern); |
|
165 | 172 |
|
166 | 173 |
return "redirect:/anti-patterns/{id}"; |
167 | 174 |
} |
src/main/java/cz/zcu/fav/kiv/antipatterndetectionapp/detecting/detectors/BusinessAsUsualDetectorImpl.java | ||
---|---|---|
3 | 3 |
import cz.zcu.fav.kiv.antipatterndetectionapp.Constants; |
4 | 4 |
import cz.zcu.fav.kiv.antipatterndetectionapp.detecting.DatabaseConnection; |
5 | 5 |
import cz.zcu.fav.kiv.antipatterndetectionapp.model.*; |
6 |
import cz.zcu.fav.kiv.antipatterndetectionapp.model.types.Percentage; |
|
6 | 7 |
import cz.zcu.fav.kiv.antipatterndetectionapp.utils.Utils; |
7 | 8 |
import org.slf4j.Logger; |
8 | 9 |
import org.slf4j.LoggerFactory; |
... | ... | |
19 | 20 |
"Absence of a retrospective after individual " + |
20 | 21 |
"iterations or after the completion project.", |
21 | 22 |
new HashMap<>() {{ |
22 |
put("divisionOfIterationsWithRetrospective", new Configuration<Float>("divisionOfIterationsWithRetrospective",
|
|
23 |
put("divisionOfIterationsWithRetrospective", new Configuration<Percentage>("divisionOfIterationsWithRetrospective",
|
|
23 | 24 |
"Division of iterations with retrospective", |
24 |
"Minimum percentage of the total number of iterations with a retrospective (0,1)", 0.66666f)); |
|
25 |
"Minimum percentage of the total number of iterations with a retrospective (0,100)", |
|
26 |
"Percentage must be between 0 and 100", |
|
27 |
new Percentage(66))); |
|
25 | 28 |
put("searchSubstringsWithRetrospective", new Configuration<String>("searchSubstringsWithRetrospective", |
26 | 29 |
"Search substrings with retrospective", |
27 | 30 |
"Substring that will be search in wikipages and activities", |
31 |
"Maximum number of substrings is ten and must not starts and ends with characters || ", |
|
28 | 32 |
"%retr%" + Constants.SUBSTRING_DELIMITER + |
29 | 33 |
"%revi%" + Constants.SUBSTRING_DELIMITER + |
30 | 34 |
"%week%scrum%")); |
... | ... | |
37 | 41 |
private List<String> sqlQueries; |
38 | 42 |
|
39 | 43 |
private float getDivisionOfIterationsWithRetrospective() { |
40 |
return (float) antiPattern.getConfigurations().get("divisionOfIterationsWithRetrospective").getValue();
|
|
44 |
return ((Percentage) antiPattern.getConfigurations().get("divisionOfIterationsWithRetrospective").getValue()).getValue();
|
|
41 | 45 |
} |
42 | 46 |
|
43 | 47 |
private List<String> getSearchSubstringsWithRetrospective() { |
src/main/java/cz/zcu/fav/kiv/antipatterndetectionapp/detecting/detectors/LongOrNonExistentFeedbackLoopsDetectorImpl.java | ||
---|---|---|
3 | 3 |
import cz.zcu.fav.kiv.antipatterndetectionapp.Constants; |
4 | 4 |
import cz.zcu.fav.kiv.antipatterndetectionapp.detecting.DatabaseConnection; |
5 | 5 |
import cz.zcu.fav.kiv.antipatterndetectionapp.model.*; |
6 |
import cz.zcu.fav.kiv.antipatterndetectionapp.model.types.Percentage; |
|
7 |
import cz.zcu.fav.kiv.antipatterndetectionapp.model.types.PositiveFloat; |
|
6 | 8 |
import cz.zcu.fav.kiv.antipatterndetectionapp.utils.Utils; |
7 | 9 |
import org.slf4j.Logger; |
8 | 10 |
import org.slf4j.LoggerFactory; |
... | ... | |
24 | 26 |
"some misunderstood functionality can be created and we have to spend " + |
25 | 27 |
"a lot of effort and time to redo it. ", |
26 | 28 |
new HashMap<>() {{ |
27 |
put("divisionOfIterationsWithFeedbackLoop", new Configuration<Float>("divisionOfIterationsWithFeedbackLoop",
|
|
29 |
put("divisionOfIterationsWithFeedbackLoop", new Configuration<Percentage>("divisionOfIterationsWithFeedbackLoop",
|
|
28 | 30 |
"Division of iterations with feedback loop", |
29 |
"Minimum percentage of the total number of iterations with feedback loop (0,1)", 0.5f)); |
|
30 |
put("maxGapBetweenFeedbackLoopRate", new Configuration<Float>("maxGapBetweenFeedbackLoopRate", |
|
31 |
"Minimum percentage of the total number of iterations with feedback loop (0,1)", |
|
32 |
"Percentage must be between 0 and 100", |
|
33 |
new Percentage(50))); |
|
34 |
put("maxGapBetweenFeedbackLoopRate", new Configuration<PositiveFloat>("maxGapBetweenFeedbackLoopRate", |
|
31 | 35 |
"Maximum gap between feedback loop rate", |
32 | 36 |
"Value that multiplies average iteration length for given project. Result" + |
33 |
" is maximum threshold value for gap between feedback loops in days.", 2f)); |
|
37 |
" is maximum threshold value for gap between feedback loops in days.", |
|
38 |
"Maximum gap between feedback loop rate must be positive float number", |
|
39 |
new PositiveFloat(2f))); |
|
34 | 40 |
put("searchSubstringsWithFeedbackLoop", new Configuration<String>("searchSubstringsWithFeedbackLoop", |
35 | 41 |
"Search substrings with feedback loop", |
36 | 42 |
"Substring that will be search in wikipages and activities", |
43 |
"Maximum number of substrings is ten and must not starts and ends with characters ||", |
|
37 | 44 |
"%schůz%zákazník%" + Constants.SUBSTRING_DELIMITER + |
38 | 45 |
"%předvedení%zákazník%" + Constants.SUBSTRING_DELIMITER + |
39 | 46 |
"%zákazn%demo%" + Constants.SUBSTRING_DELIMITER + |
... | ... | |
49 | 56 |
private List<String> sqlQueries; |
50 | 57 |
|
51 | 58 |
private float getDivisionOfIterationsWithFeedbackLoop() { |
52 |
return (float) antiPattern.getConfigurations().get("divisionOfIterationsWithFeedbackLoop").getValue();
|
|
59 |
return ((Percentage) antiPattern.getConfigurations().get("divisionOfIterationsWithFeedbackLoop").getValue()).getValue();
|
|
53 | 60 |
} |
54 | 61 |
|
55 | 62 |
private float getMaxGapBetweenFeedbackLoopRate() { |
src/main/java/cz/zcu/fav/kiv/antipatterndetectionapp/detecting/detectors/NinetyNinetyRuleDetectorImpl.java | ||
---|---|---|
2 | 2 |
|
3 | 3 |
import cz.zcu.fav.kiv.antipatterndetectionapp.detecting.DatabaseConnection; |
4 | 4 |
import cz.zcu.fav.kiv.antipatterndetectionapp.model.*; |
5 |
import cz.zcu.fav.kiv.antipatterndetectionapp.model.types.PositiveFloat; |
|
6 |
import cz.zcu.fav.kiv.antipatterndetectionapp.model.types.PositiveInteger; |
|
5 | 7 |
import org.slf4j.Logger; |
6 | 8 |
import org.slf4j.LoggerFactory; |
7 | 9 |
|
... | ... | |
20 | 22 |
"The functionality is almost done, some number is already closed and is only waiting " + |
21 | 23 |
"for one activity to close, but it has been open for a long time.", |
22 | 24 |
new HashMap<>() {{ |
23 |
put("maxDivisionRange", new Configuration<Double>("maxDivisionRange",
|
|
25 |
put("maxDivisionRange", new Configuration<PositiveFloat>("maxDivisionRange",
|
|
24 | 26 |
"Maximum ration value", |
25 |
"Maximum ratio value of spent and estimated time", 1.25)); |
|
26 |
put("maxBadDivisionLimit", new Configuration<Integer>("maxBadDivisionLimit", |
|
27 |
"Maximum ratio value of spent and estimated time", |
|
28 |
"Ration values must be positive float number", |
|
29 |
new PositiveFloat(1.25f))); |
|
30 |
put("maxBadDivisionLimit", new Configuration<PositiveInteger>("maxBadDivisionLimit", |
|
27 | 31 |
"Maximum iterations thresholds", |
28 |
"Maximum number of consecutive iterations where the thresholds were exceeded", 2)); |
|
32 |
"Maximum number of consecutive iterations where the thresholds were exceeded", |
|
33 |
"Maximum number of consecutive iterations must be positive integer number", |
|
34 |
new PositiveInteger(2))); |
|
29 | 35 |
}}); |
30 | 36 |
|
31 | 37 |
private final String sqlFileName = "ninety_ninety_rule.sql"; |
src/main/java/cz/zcu/fav/kiv/antipatterndetectionapp/detecting/detectors/RoadToNowhereDetectorImpl.java | ||
---|---|---|
3 | 3 |
import cz.zcu.fav.kiv.antipatterndetectionapp.Constants; |
4 | 4 |
import cz.zcu.fav.kiv.antipatterndetectionapp.detecting.DatabaseConnection; |
5 | 5 |
import cz.zcu.fav.kiv.antipatterndetectionapp.model.*; |
6 |
import cz.zcu.fav.kiv.antipatterndetectionapp.model.types.PositiveInteger; |
|
6 | 7 |
import cz.zcu.fav.kiv.antipatterndetectionapp.utils.Utils; |
7 | 8 |
import org.slf4j.Logger; |
8 | 9 |
import org.slf4j.LoggerFactory; |
... | ... | |
22 | 23 |
"takes place on an ad hoc basis with an uncertain " + |
23 | 24 |
"outcome and deadline. There is no project plan in the project.", |
24 | 25 |
new HashMap<>() {{ |
25 |
put("minNumberOfWikiPagesWithProjectPlan", new Configuration<Integer>("minNumberOfWikiPagesWithProjectPlan", |
|
26 |
put("minNumberOfWikiPagesWithProjectPlan", new Configuration<PositiveInteger>("minNumberOfWikiPagesWithProjectPlan",
|
|
26 | 27 |
"Minimum number of wiki pages with project plan", |
27 |
"Number of wiki pages", 1)); |
|
28 |
put("minNumberOfActivitiesWithProjectPlan", new Configuration<Integer>("minNumberOfActivitiesWithProjectPlan", |
|
28 |
"Number of wiki pages", |
|
29 |
"Minimum number of wikipages must be positive integer number", |
|
30 |
new PositiveInteger(1))); |
|
31 |
put("minNumberOfActivitiesWithProjectPlan", new Configuration<PositiveInteger>("minNumberOfActivitiesWithProjectPlan", |
|
29 | 32 |
"Minimum number of activities with project plan", |
30 |
"Number of activities", 1)); |
|
33 |
"Number of activities", |
|
34 |
"Minimum number of activities must be positive integer number", |
|
35 |
new PositiveInteger(1))); |
|
31 | 36 |
put("searchSubstringsWithProjectPlan", new Configuration<String>("searchSubstringsWithProjectPlan", |
32 | 37 |
"Search substrings with project plan", |
33 | 38 |
"Substring that will be search in wikipages and activities", |
39 |
"Maximum number of substrings is ten and must not starts and ends with characters ||", |
|
34 | 40 |
"%plán projektu%" + Constants.SUBSTRING_DELIMITER + |
35 | 41 |
"%project plan%" + Constants.SUBSTRING_DELIMITER + |
36 | 42 |
"%plan project%" + Constants.SUBSTRING_DELIMITER + |
src/main/java/cz/zcu/fav/kiv/antipatterndetectionapp/detecting/detectors/SpecifyNothingDetectorImpl.java | ||
---|---|---|
3 | 3 |
import cz.zcu.fav.kiv.antipatterndetectionapp.Constants; |
4 | 4 |
import cz.zcu.fav.kiv.antipatterndetectionapp.detecting.DatabaseConnection; |
5 | 5 |
import cz.zcu.fav.kiv.antipatterndetectionapp.model.*; |
6 |
import cz.zcu.fav.kiv.antipatterndetectionapp.model.types.PositiveInteger; |
|
6 | 7 |
import cz.zcu.fav.kiv.antipatterndetectionapp.utils.Utils; |
7 | 8 |
import org.slf4j.Logger; |
8 | 9 |
import org.slf4j.LoggerFactory; |
... | ... | |
21 | 22 |
"The specification is not done intentionally. Programmers are " + |
22 | 23 |
"expected to work better without written specifications.", |
23 | 24 |
new HashMap<>() {{ |
24 |
put("minNumberOfWikiPagesWithSpecification", new Configuration<Integer>("minNumberOfWikiPagesWithSpecification", |
|
25 |
put("minNumberOfWikiPagesWithSpecification", new Configuration<PositiveInteger>("minNumberOfWikiPagesWithSpecification",
|
|
25 | 26 |
"Minimum number of wiki pages with project specification", |
26 |
"Number of wiki pages", 1)); |
|
27 |
put("minNumberOfActivitiesWithSpecification", new Configuration<Integer>("minNumberOfActivitiesWithSpecification", |
|
27 |
"Number of wiki pages", |
|
28 |
"Minimum number of wikipages must be positive integer number", |
|
29 |
new PositiveInteger(1))); |
|
30 |
put("minNumberOfActivitiesWithSpecification", new Configuration<PositiveInteger>("minNumberOfActivitiesWithSpecification", |
|
28 | 31 |
"Minimum number of activities with project specification", |
29 |
"Number of activities", 1)); |
|
30 |
put("minAvgLengthOfActivityDescription", new Configuration<Integer>("minAvgLengthOfActivityDescription", |
|
32 |
"Number of activities", |
|
33 |
"Minimum number of activities with project specification must be positive integer number", |
|
34 |
new PositiveInteger(1))); |
|
35 |
put("minAvgLengthOfActivityDescription", new Configuration<PositiveInteger>("minAvgLengthOfActivityDescription", |
|
31 | 36 |
"Minimum average length of activity description", |
32 |
"Minimum average number of character of activity description", 150)); |
|
37 |
"Minimum average number of character of activity description", |
|
38 |
"Minimum average length of activity description must be positive integer number", |
|
39 |
new PositiveInteger(150))); |
|
33 | 40 |
put("searchSubstringsWithProjectSpecification", new Configuration<String>("searchSubstringsWithProjectSpecification", |
34 | 41 |
"Search substrings with project specification", |
35 | 42 |
"Substring that will be search in wikipages and activities", |
43 |
"Maximum number of substrings is ten and must not starts and ends with characters ||", |
|
36 | 44 |
"%dsp%" + Constants.SUBSTRING_DELIMITER + |
37 | 45 |
"%specifikace%" + Constants.SUBSTRING_DELIMITER + |
38 | 46 |
"%specification%" + Constants.SUBSTRING_DELIMITER + |
src/main/java/cz/zcu/fav/kiv/antipatterndetectionapp/detecting/detectors/TooLongSprintDetectorImpl.java | ||
---|---|---|
2 | 2 |
|
3 | 3 |
import cz.zcu.fav.kiv.antipatterndetectionapp.detecting.DatabaseConnection; |
4 | 4 |
import cz.zcu.fav.kiv.antipatterndetectionapp.model.*; |
5 |
import cz.zcu.fav.kiv.antipatterndetectionapp.model.types.PositiveInteger; |
|
5 | 6 |
import org.slf4j.Logger; |
6 | 7 |
import org.slf4j.LoggerFactory; |
7 | 8 |
|
... | ... | |
23 | 24 |
"beginning and at the end of the project, but it should not " + |
24 | 25 |
"change in the already started project).", |
25 | 26 |
new HashMap<>() {{ |
26 |
put("maxIterationLength", new Configuration<Integer>("maxIterationLength", |
|
27 |
put("maxIterationLength", new Configuration<PositiveInteger>("maxIterationLength",
|
|
27 | 28 |
"Max Iteration Length", |
28 |
"Maximum iteration length in days", 21)); |
|
29 |
put("maxNumberOfTooLongIterations", new Configuration<Integer>("maxNumberOfTooLongIterations", |
|
29 |
"Maximum iteration length in days", |
|
30 |
"Max iteration length must be positive integer", |
|
31 |
new PositiveInteger(21))); |
|
32 |
put("maxNumberOfTooLongIterations", new Configuration<PositiveInteger>("maxNumberOfTooLongIterations", |
|
30 | 33 |
"Max number of foo long iterations", |
31 |
"Maximum number of too long iterations in project", 0)); |
|
34 |
"Maximum number of too long iterations in project", |
|
35 |
"Max number of too long iterations must be positive integer", |
|
36 |
new PositiveInteger(0))); |
|
32 | 37 |
}} |
33 | 38 |
); |
34 | 39 |
|
src/main/java/cz/zcu/fav/kiv/antipatterndetectionapp/detecting/detectors/VaryingSprintLengthDetectorImpl.java | ||
---|---|---|
2 | 2 |
|
3 | 3 |
import cz.zcu.fav.kiv.antipatterndetectionapp.detecting.DatabaseConnection; |
4 | 4 |
import cz.zcu.fav.kiv.antipatterndetectionapp.model.*; |
5 |
import cz.zcu.fav.kiv.antipatterndetectionapp.model.types.PositiveInteger; |
|
5 | 6 |
import org.slf4j.Logger; |
6 | 7 |
import org.slf4j.LoggerFactory; |
7 | 8 |
|
... | ... | |
24 | 25 |
"but the length of the sprint should not change " + |
25 | 26 |
"during the project.", |
26 | 27 |
new HashMap<>() {{ |
27 |
put("maxDaysDifference", new Configuration<Integer>("maxDaysDifference", |
|
28 |
put("maxDaysDifference", new Configuration<PositiveInteger>("maxDaysDifference",
|
|
28 | 29 |
"Max days difference", |
29 |
"Maximum distance of two consecutive iterations in days", 7)); |
|
30 |
put("maxIterationChanged", new Configuration<Integer>("maxIterationChanged", |
|
30 |
"Maximum distance of two consecutive iterations in days", |
|
31 |
"Maximum distance must be positive integer number", |
|
32 |
new PositiveInteger(7))); |
|
33 |
put("maxIterationChanged", new Configuration<PositiveInteger>("maxIterationChanged", |
|
31 | 34 |
"Max number of iteration changed", |
32 |
"Maximum allowed number of significant changes in iteration lengths", 1)); |
|
35 |
"Maximum allowed number of significant changes in iteration lengths", |
|
36 |
"Maximum number of iterations changed must be positive integer number", |
|
37 |
new PositiveInteger(1))); |
|
33 | 38 |
}}); |
34 | 39 |
|
35 | 40 |
private final String sqlFileName = "varying_sprint_length.sql"; |
src/main/java/cz/zcu/fav/kiv/antipatterndetectionapp/model/Configuration.java | ||
---|---|---|
4 | 4 |
private String name; |
5 | 5 |
private String printName; |
6 | 6 |
private String description; |
7 |
private String errorMessage; |
|
8 |
private boolean isErrorMessageShown; |
|
7 | 9 |
private T value; |
8 | 10 |
|
9 | 11 |
public Configuration(String name, String printName, String description, T value) { |
... | ... | |
11 | 13 |
this.printName = printName; |
12 | 14 |
this.description = description; |
13 | 15 |
this.value = value; |
16 |
this.isErrorMessageShown = false; |
|
17 |
} |
|
18 |
|
|
19 |
public Configuration(String name, String printName, String description, String errorMessage, T value) { |
|
20 |
this.name = name; |
|
21 |
this.printName = printName; |
|
22 |
this.description = description; |
|
23 |
this.errorMessage = errorMessage; |
|
24 |
this.value = value; |
|
25 |
this.isErrorMessageShown = false; |
|
14 | 26 |
} |
15 | 27 |
|
16 | 28 |
public String getName() { |
... | ... | |
44 | 56 |
public void setValue(T value) { |
45 | 57 |
this.value = value; |
46 | 58 |
} |
59 |
|
|
60 |
public String getErrorMessage() { |
|
61 |
return errorMessage; |
|
62 |
} |
|
63 |
|
|
64 |
public void setErrorMessage(String errorMessage) { |
|
65 |
this.errorMessage = errorMessage; |
|
66 |
} |
|
67 |
|
|
68 |
public boolean isErrorMessageShown() { |
|
69 |
return isErrorMessageShown; |
|
70 |
} |
|
71 |
|
|
72 |
public void setErrorMessageShown(boolean errorMessageShown) { |
|
73 |
isErrorMessageShown = errorMessageShown; |
|
74 |
} |
|
47 | 75 |
} |
src/main/java/cz/zcu/fav/kiv/antipatterndetectionapp/model/types/Percentage.java | ||
---|---|---|
1 |
package cz.zcu.fav.kiv.antipatterndetectionapp.model.types; |
|
2 |
|
|
3 |
public class Percentage extends Number { |
|
4 |
|
|
5 |
public static final float MAX_VALUE = 100; |
|
6 |
public static final float MIN_VALUE = 0; |
|
7 |
|
|
8 |
private final int value; |
|
9 |
|
|
10 |
public Percentage(int value) throws NumberFormatException { |
|
11 |
if (value > MAX_VALUE || value < MIN_VALUE) { |
|
12 |
throw new NumberFormatException("Percentage should be between 0 and 100"); |
|
13 |
} |
|
14 |
this.value = value; |
|
15 |
} |
|
16 |
|
|
17 |
public static Percentage parsePercentage(String value) { |
|
18 |
return new Percentage(Integer.parseInt(value)); |
|
19 |
} |
|
20 |
|
|
21 |
@Override |
|
22 |
public int intValue() { |
|
23 |
return this.value; |
|
24 |
} |
|
25 |
|
|
26 |
@Override |
|
27 |
public long longValue() { |
|
28 |
return (long) this.value; |
|
29 |
} |
|
30 |
|
|
31 |
@Override |
|
32 |
public float floatValue() { |
|
33 |
return (float) this.value; |
|
34 |
} |
|
35 |
|
|
36 |
@Override |
|
37 |
public double doubleValue() { |
|
38 |
return (double) this.value; |
|
39 |
} |
|
40 |
|
|
41 |
@Override |
|
42 |
public String toString() { |
|
43 |
return String.valueOf(value); |
|
44 |
} |
|
45 |
|
|
46 |
public float getValue() { |
|
47 |
return (float) value/100; |
|
48 |
} |
|
49 |
} |
src/main/java/cz/zcu/fav/kiv/antipatterndetectionapp/model/types/PositiveFloat.java | ||
---|---|---|
1 |
package cz.zcu.fav.kiv.antipatterndetectionapp.model.types; |
|
2 |
|
|
3 |
public class PositiveFloat extends Number { |
|
4 |
public static final float MAX_VALUE = Float.MAX_VALUE; |
|
5 |
public static final int MIN_VALUE = 0; |
|
6 |
|
|
7 |
private final float value; |
|
8 |
|
|
9 |
public PositiveFloat(float value) throws NumberFormatException { |
|
10 |
if (value > MAX_VALUE || value < MIN_VALUE) { |
|
11 |
throw new NumberFormatException("Positive integer should be between 0 and infinity"); |
|
12 |
} |
|
13 |
this.value = value; |
|
14 |
} |
|
15 |
|
|
16 |
|
|
17 |
@Override |
|
18 |
public int intValue() { |
|
19 |
return 0; |
|
20 |
} |
|
21 |
|
|
22 |
@Override |
|
23 |
public long longValue() { |
|
24 |
return 0; |
|
25 |
} |
|
26 |
|
|
27 |
@Override |
|
28 |
public float floatValue() { |
|
29 |
return 0; |
|
30 |
} |
|
31 |
|
|
32 |
@Override |
|
33 |
public double doubleValue() { |
|
34 |
return 0; |
|
35 |
} |
|
36 |
|
|
37 |
public static PositiveFloat parsePositiveFloat(String value) { |
|
38 |
return new PositiveFloat(Float.parseFloat(value)); |
|
39 |
} |
|
40 |
|
|
41 |
@Override |
|
42 |
public String toString() { |
|
43 |
return String.valueOf(value); |
|
44 |
} |
|
45 |
} |
src/main/java/cz/zcu/fav/kiv/antipatterndetectionapp/model/types/PositiveInteger.java | ||
---|---|---|
1 |
package cz.zcu.fav.kiv.antipatterndetectionapp.model.types; |
|
2 |
|
|
3 |
public class PositiveInteger extends Number { |
|
4 |
|
|
5 |
public static final int MAX_VALUE = Integer.MAX_VALUE; |
|
6 |
public static final int MIN_VALUE = 0; |
|
7 |
|
|
8 |
private final int value; |
|
9 |
|
|
10 |
public PositiveInteger(int value) throws NumberFormatException { |
|
11 |
if (value > MAX_VALUE || value < MIN_VALUE) { |
|
12 |
throw new NumberFormatException("Positive integer should be between 0 and infinity"); |
|
13 |
} |
|
14 |
this.value = value; |
|
15 |
} |
|
16 |
|
|
17 |
|
|
18 |
@Override |
|
19 |
public int intValue() { |
|
20 |
return 0; |
|
21 |
} |
|
22 |
|
|
23 |
@Override |
|
24 |
public long longValue() { |
|
25 |
return 0; |
|
26 |
} |
|
27 |
|
|
28 |
@Override |
|
29 |
public float floatValue() { |
|
30 |
return 0; |
|
31 |
} |
|
32 |
|
|
33 |
@Override |
|
34 |
public double doubleValue() { |
|
35 |
return 0; |
|
36 |
} |
|
37 |
|
|
38 |
public static PositiveInteger parsePositiveInteger(String value) { |
|
39 |
return new PositiveInteger(Integer.parseInt(value)); |
|
40 |
} |
|
41 |
|
|
42 |
@Override |
|
43 |
public String toString() { |
|
44 |
return String.valueOf(value); |
|
45 |
} |
|
46 |
} |
src/main/java/cz/zcu/fav/kiv/antipatterndetectionapp/service/AntiPatternService.java | ||
---|---|---|
18 | 18 |
|
19 | 19 |
List<AntiPatternDetector> getAllAntiPatternsForGivenIds(Long[] ids); |
20 | 20 |
|
21 |
boolean saveNewConfiguration(String[] configNames, String[] configValues);
|
|
21 |
List<String> saveNewConfiguration(String[] configNames, String[] configValues);
|
|
22 | 22 |
|
23 | 23 |
void saveAnalyzedProjects(String[] selectedProjects, String[] selectedAntiPatterns); |
24 | 24 |
|
... | ... | |
34 | 34 |
|
35 | 35 |
List<QueryResult> getResults(); |
36 | 36 |
|
37 |
List<AntiPattern> setErrorMessages(List<AntiPattern> antiPatterns, List<String> wrongParameters); |
|
38 |
|
|
39 |
AntiPattern setErrorMessages(AntiPattern antiPattern, List<String> wrongParameters); |
|
37 | 40 |
} |
src/main/java/cz/zcu/fav/kiv/antipatterndetectionapp/service/AntiPatternServiceImpl.java | ||
---|---|---|
3 | 3 |
import cz.zcu.fav.kiv.antipatterndetectionapp.detecting.detectors.AntiPatternDetector; |
4 | 4 |
import cz.zcu.fav.kiv.antipatterndetectionapp.model.AntiPattern; |
5 | 5 |
import cz.zcu.fav.kiv.antipatterndetectionapp.model.CacheablesValues; |
6 |
import cz.zcu.fav.kiv.antipatterndetectionapp.model.Configuration; |
|
6 | 7 |
import cz.zcu.fav.kiv.antipatterndetectionapp.model.QueryResult; |
8 |
import cz.zcu.fav.kiv.antipatterndetectionapp.model.types.Percentage; |
|
9 |
import cz.zcu.fav.kiv.antipatterndetectionapp.model.types.PositiveFloat; |
|
10 |
import cz.zcu.fav.kiv.antipatterndetectionapp.model.types.PositiveInteger; |
|
7 | 11 |
import cz.zcu.fav.kiv.antipatterndetectionapp.repository.AntiPatternRepository; |
12 |
import cz.zcu.fav.kiv.antipatterndetectionapp.utils.Utils; |
|
8 | 13 |
import org.springframework.beans.factory.annotation.Autowired; |
9 | 14 |
import org.springframework.stereotype.Service; |
10 | 15 |
|
11 | 16 |
import java.util.ArrayList; |
12 | 17 |
import java.util.LinkedList; |
13 | 18 |
import java.util.List; |
19 |
import java.util.Map; |
|
14 | 20 |
|
15 | 21 |
|
16 | 22 |
@Service |
... | ... | |
36 | 42 |
public List<AntiPattern> antiPatternsToModel(List<AntiPatternDetector> antiPatternDetectors) { |
37 | 43 |
List<AntiPattern> antiPatterns = new LinkedList<>(); |
38 | 44 |
for (AntiPatternDetector antiPatternDetector : antiPatternDetectors) { |
39 |
antiPatterns.add(antiPatternDetector.getAntiPatternModel()); |
|
45 |
AntiPattern antiPattern = antiPatternDetector.getAntiPatternModel(); |
|
46 |
|
|
47 |
// set to default value |
|
48 |
for (Map.Entry<String, Configuration> config : antiPattern.getConfigurations().entrySet()) { |
|
49 |
config.getValue().setErrorMessageShown(false); |
|
50 |
} |
|
51 |
antiPatterns.add(antiPattern); |
|
40 | 52 |
} |
41 | 53 |
return antiPatterns; |
42 | 54 |
} |
43 | 55 |
|
44 | 56 |
@Override |
45 | 57 |
public AntiPattern antiPatternToModel(AntiPatternDetector antiPatternDetector) { |
46 |
return antiPatternDetector.getAntiPatternModel(); |
|
58 |
AntiPattern antiPattern = antiPatternDetector.getAntiPatternModel(); |
|
59 |
// set to default value |
|
60 |
for (Map.Entry<String, Configuration> config : antiPattern.getConfigurations().entrySet()) { |
|
61 |
config.getValue().setErrorMessageShown(false); |
|
62 |
} |
|
63 |
return antiPattern; |
|
47 | 64 |
} |
48 | 65 |
|
49 | 66 |
@Override |
... | ... | |
56 | 73 |
return antiPatternDetectors; |
57 | 74 |
} |
58 | 75 |
|
59 |
@Override |
|
60 |
public boolean saveNewConfiguration(String[] configNames, String[] configValues) { |
|
76 |
public List<String> saveNewConfiguration(String[] configNames, String[] configValues) { |
|
61 | 77 |
List<AntiPatternDetector> antiPatternDetectors = antiPatternRepository.getAllAntiPatterns(); |
78 |
List<String> incorrectParameters = new ArrayList<>(); |
|
62 | 79 |
|
63 | 80 |
for (AntiPatternDetector antiPatternDetector : antiPatternDetectors) { |
64 | 81 |
// not every anti-pattern should have configuration |
... | ... | |
73 | 90 |
antiPatternDetector.getAntiPatternModel().getConfigurations().get(configNames[i]).setValue((Integer.parseInt(configValues[i]))); |
74 | 91 |
setConfigurationChanged(true); |
75 | 92 |
} catch (NumberFormatException e) { |
76 |
return false;
|
|
93 |
incorrectParameters.add(configNames[i]);
|
|
77 | 94 |
} |
78 | 95 |
|
96 |
} else if (antiPatternDetector.getAntiPatternModel().getConfigurations().get(configNames[i]).getValue().getClass() == Percentage.class) { |
|
97 |
try { |
|
98 |
antiPatternDetector.getAntiPatternModel().getConfigurations().get(configNames[i]).setValue((Percentage.parsePercentage(configValues[i]))); |
|
99 |
setConfigurationChanged(true); |
|
100 |
} catch (NumberFormatException e) { |
|
101 |
incorrectParameters.add(configNames[i]); |
|
102 |
} |
|
103 |
} else if (antiPatternDetector.getAntiPatternModel().getConfigurations().get(configNames[i]).getValue().getClass() == PositiveInteger.class) { |
|
104 |
try { |
|
105 |
antiPatternDetector.getAntiPatternModel().getConfigurations().get(configNames[i]).setValue((PositiveInteger.parsePositiveInteger(configValues[i]))); |
|
106 |
setConfigurationChanged(true); |
|
107 |
} catch (NumberFormatException e) { |
|
108 |
incorrectParameters.add(configNames[i]); |
|
109 |
} |
|
110 |
} else if (antiPatternDetector.getAntiPatternModel().getConfigurations().get(configNames[i]).getValue().getClass() == PositiveFloat.class) { |
|
111 |
try { |
|
112 |
antiPatternDetector.getAntiPatternModel().getConfigurations().get(configNames[i]).setValue((PositiveFloat.parsePositiveFloat(configValues[i]))); |
|
113 |
setConfigurationChanged(true); |
|
114 |
} catch (NumberFormatException e) { |
|
115 |
incorrectParameters.add(configNames[i]); |
|
116 |
} |
|
79 | 117 |
} else if (antiPatternDetector.getAntiPatternModel().getConfigurations().get(configNames[i]).getValue().getClass() == Float.class) { |
80 | 118 |
try { |
81 | 119 |
antiPatternDetector.getAntiPatternModel().getConfigurations().get(configNames[i]).setValue((Float.parseFloat(configValues[i]))); |
82 | 120 |
setConfigurationChanged(true); |
83 | 121 |
} catch (NumberFormatException e) { |
84 |
return false;
|
|
122 |
incorrectParameters.add(configNames[i]);
|
|
85 | 123 |
} |
86 | 124 |
} else if (antiPatternDetector.getAntiPatternModel().getConfigurations().get(configNames[i]).getValue().getClass() == Double.class) { |
87 | 125 |
try { |
88 | 126 |
antiPatternDetector.getAntiPatternModel().getConfigurations().get(configNames[i]).setValue((Double.parseDouble(configValues[i]))); |
89 | 127 |
setConfigurationChanged(true); |
90 | 128 |
} catch (NumberFormatException e) { |
91 |
return false;
|
|
129 |
incorrectParameters.add(configNames[i]);
|
|
92 | 130 |
} |
93 | 131 |
} else if (antiPatternDetector.getAntiPatternModel().getConfigurations().get(configNames[i]).getValue().getClass() == String.class) { |
132 |
if (Utils.checkStringSubstrings(configValues[i])) { |
|
94 | 133 |
antiPatternDetector.getAntiPatternModel().getConfigurations().get(configNames[i]).setValue((configValues[i])); |
95 | 134 |
setConfigurationChanged(true); |
135 |
|
|
136 |
} else { |
|
137 |
incorrectParameters.add(configNames[i]); |
|
138 |
} |
|
96 | 139 |
} |
97 | 140 |
} |
98 | 141 |
} |
99 | 142 |
} |
100 |
return true;
|
|
143 |
return incorrectParameters;
|
|
101 | 144 |
} |
102 | 145 |
|
103 | 146 |
@Override |
... | ... | |
117 | 160 |
} |
118 | 161 |
|
119 | 162 |
@Override |
120 |
public void setConfigurationChanged(boolean configurationChanged) {
|
|
121 |
this.cacheablesValues.setConfigurationChanged(configurationChanged);
|
|
163 |
public boolean isConfigurationChanged() {
|
|
164 |
return this.cacheablesValues.isConfigurationChanged();
|
|
122 | 165 |
} |
123 | 166 |
|
124 | 167 |
@Override |
125 |
public boolean isConfigurationChanged() {
|
|
126 |
return this.cacheablesValues.isConfigurationChanged();
|
|
168 |
public void setConfigurationChanged(boolean configurationChanged) {
|
|
169 |
this.cacheablesValues.setConfigurationChanged(configurationChanged);
|
|
127 | 170 |
} |
128 | 171 |
|
129 | 172 |
@Override |
... | ... | |
135 | 178 |
public List<QueryResult> getResults() { |
136 | 179 |
return this.cacheablesValues.getResults(); |
137 | 180 |
} |
181 |
|
|
182 |
@Override |
|
183 |
public List<AntiPattern> setErrorMessages(List<AntiPattern> antiPatterns, List<String> wrongParameters) { |
|
184 |
for (AntiPattern antiPattern : antiPatterns) { |
|
185 |
for (Map.Entry<String, Configuration> config : antiPattern.getConfigurations().entrySet()) { |
|
186 |
if (wrongParameters.contains(config.getKey())) { |
|
187 |
config.getValue().setErrorMessageShown(true); |
|
188 |
} else { |
|
189 |
config.getValue().setErrorMessageShown(false); |
|
190 |
} |
|
191 |
} |
|
192 |
} |
|
193 |
return antiPatterns; |
|
194 |
} |
|
195 |
|
|
196 |
@Override |
|
197 |
public AntiPattern setErrorMessages(AntiPattern antiPattern, List<String> wrongParameters) { |
|
198 |
List<AntiPattern> antiPatterns = new ArrayList<>(); |
|
199 |
antiPatterns.add(antiPattern); |
|
200 |
return setErrorMessages(antiPatterns, wrongParameters).get(0); |
|
201 |
} |
|
138 | 202 |
} |
src/main/java/cz/zcu/fav/kiv/antipatterndetectionapp/utils/Utils.java | ||
---|---|---|
1 | 1 |
package cz.zcu.fav.kiv.antipatterndetectionapp.utils; |
2 | 2 |
|
3 |
import cz.zcu.fav.kiv.antipatterndetectionapp.Constants; |
|
3 | 4 |
import cz.zcu.fav.kiv.antipatterndetectionapp.model.ResultDetail; |
4 | 5 |
import org.slf4j.Logger; |
5 | 6 |
import org.slf4j.LoggerFactory; |
... | ... | |
73 | 74 |
|
74 | 75 |
return preparedQueries; |
75 | 76 |
} |
77 |
|
|
78 |
public static boolean checkStringSubstrings(String substrings) { |
|
79 |
if (substrings.startsWith(Constants.SUBSTRING_DELIMITER)) { |
|
80 |
return false; |
|
81 |
} |
|
82 |
|
|
83 |
if (substrings.endsWith(Constants.SUBSTRING_DELIMITER)) { |
|
84 |
return false; |
|
85 |
} |
|
86 |
|
|
87 |
if (substrings.split("\\|\\|").length > 10) { |
|
88 |
return false; |
|
89 |
} |
|
90 |
|
|
91 |
return true; |
|
92 |
} |
|
76 | 93 |
} |
src/main/webapp/WEB-INF/templates/anti-pattern.html | ||
---|---|---|
91 | 91 |
<div th:each="config : ${antiPattern.configurations}" class="form-group"> |
92 | 92 |
<label th:text="${config.value.printName} + ':'" |
93 | 93 |
th:for="${config.value.name}"></label> |
94 |
<input th:value="${config.value.value}" class="form-control" th:id="${config.value.name}" |
|
94 |
<small th:text="${config.value.description}" th:value="${config.value.name}" |
|
95 |
class="form-text text-muted"></small> |
|
96 |
<input th:if="${config.value.isErrorMessageShown}" th:value="${config.value.value}" class="form-control is-invalid" th:id="${config.value.name}" |
|
97 |
name="configValues"> |
|
98 |
<input th:unless="${config.value.isErrorMessageShown}" th:value="${config.value.value}" class="form-control" th:id="${config.value.name}" |
|
95 | 99 |
name="configValues"> |
96 | 100 |
<input th:value="${config.value.name}" style="display: none" class="form-control" |
97 | 101 |
name="configNames"> |
98 |
<small th:text="${config.value.description}" th:value="${config.value.name}" |
|
99 |
class="form-text text-muted"></small> |
|
102 |
<small th:if="${config.value.isErrorMessageShown}" th:text="${config.value.errorMessage}" th:value="${config.value.errorMessage}" |
|
103 |
class="form-text text-danger"></small> |
|
104 |
|
|
100 | 105 |
</div> |
101 | 106 |
<div class="analyze-button-container"> |
102 | 107 |
<button type="submit" class="btn btn-primary btn-lg btn-block">Save configuration</button> |
src/main/webapp/WEB-INF/templates/configuration.html | ||
---|---|---|
52 | 52 |
<label th:text="${config.value.printName} + ':'" th:for="${config.value.name}" |
53 | 53 |
class="col-sm-5 col-form-label"></label> |
54 | 54 |
<div class="col-sm-5"> |
55 |
<input th:value="${config.value.value}" class="form-control" th:id="${config.value.name}" |
|
55 |
<small th:text="${config.value.description}" th:value="${config.value.name}" |
|
56 |
class="form-text text-muted"></small> |
|
57 |
<input th:if="${config.value.isErrorMessageShown}" th:value="${config.value.value}" class="form-control is-invalid" th:id="${config.value.name}" |
|
58 |
name="configValues"> |
|
59 |
<input th:unless="${config.value.isErrorMessageShown}" th:value="${config.value.value}" class="form-control" th:id="${config.value.name}" |
|
56 | 60 |
name="configValues"> |
57 | 61 |
<input th:value="${config.value.name}" style="display: none" class="form-control" |
58 | 62 |
name="configNames"> |
59 |
<small th:text="${config.value.description}" th:value="${config.value.name}" |
|
60 |
class="form-text text-muted"></small> |
|
63 |
<small th:if="${config.value.isErrorMessageShown}" th:text="${config.value.errorMessage}" th:value="${config.value.errorMessage}" |
|
64 |
class="form-text text-danger"></small> |
|
65 |
|
|
61 | 66 |
</div> |
62 | 67 |
</div> |
63 | 68 |
|
Také k dispozici: Unified diff
#5 Implement user input checks
- added new data types for checking input parameters
- chenged UI for showing error messages
- refactor validation of input parameters