Projekt

Obecné

Profil

« Předchozí | Další » 

Revize 6cfce16e

Přidáno uživatelem Ondřej Váně před téměř 3 roky(ů)

#5 Implement user input checks

- added new data types for checking input parameters
- chenged UI for showing error messages
- refactor validation of input parameters

Zobrazit rozdíly:

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