Skip to content

Commit 126d363

Browse files
OndrejVaneppicha
authored andcommitted
#9 Split SQL scripts
- all queries in the files are split into separate queries - each AP has a list of all the queries it needs to evaluate - all queries from the file are loaded at application startup - mineor changes in PositiveNUmber formating - minor fix
1 parent 8d41034 commit 126d363

File tree

40 files changed

+214
-266
lines changed

40 files changed

+214
-266
lines changed

README.md

Lines changed: 52 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,6 @@
1-
# AntiPatternDetectionApp
2-
This application was created as part of the thesis. It is used for analysis and detection of anti-patterns in project data.
1+
# ReliSA - SPADe-Web-GUI
2+
This application was is used for analysis and detection of anti-patterns in project data.
33

4-
## Thesis abstract
5-
The goal of this thesis is to analyze and automatically detect anti-patterns in the data of project management tools using SPADe tools. The SPADe tool is used to collect data from ALM tools and search for bad practices (anti-patterns) in project data. In order to develop this thesis, an analysis of the available anti-patterns was performed and then a subset was selected for further investigation. In the next part, the detection of the analyzed anti-patterns was implemented using SQL queries and Java programming language was used to process the results of these queries. As an extra feature of this thesis, going beyond the scope of the original assignment, a support web application for running the detection process of implemented anti-patters and results presentation was also developed. Furthermore, an experiment was performed on a selected sets of anti-patterns and project data. The success of the detection was verified by comparing the results to those from a manual anti-pattern detection in project data from the source ALM tools. Detection success was successful at 93.65 % compared to manual control.
6-
7-
## Analyzed Anti-Patterns
84
In version 1.0.0 of this application, the detection of the following Anti-Patterns is implemented:
95
* Business As Usual
106
* Long Or Non-Existant Feedback Loops
@@ -14,19 +10,54 @@ In version 1.0.0 of this application, the detection of the following Anti-Patter
1410
* Too Long Sprint
1511
* Varying Sprint Length
1612

17-
## Run
18-
### Tools to run
19-
It will need the following tools to run the application:
20-
* Docker
21-
* Docker Compose
22-
### Run application
23-
The following list describes the steps to run (you will need):
24-
1. Open terminal.
25-
2. Move to the root folder of this project (AntiPatternDetectionApp).
26-
3. Build docker images with command `docker-compose build`.
27-
4. Create and run all containers with command `docker-compose run`.
28-
5. Open phpMyAdmin on docker address on port 8082.
29-
6. Create database with name spade using command `CREATE DATABASE spade;`.
30-
7. Restore database from file `db_dump.sql` located in project root folder.
31-
8. Run all commands from file `config.sql` located in project root folder.
13+
# Basic architecture of app
14+
15+
# Installation guide
16+
17+
# Add new Anti-Pattern
18+
19+
# User guide
20+
## Analyze projects
21+
1) On home page select project to analyze (you can use check box for select/deselect all projects)
22+
TODO obrázek
23+
2) Select Anti-Patterns to analyze (you can use check box for select/deselect all Anti-Patterns)
24+
TODO obrázek
25+
3) Click to button Analyze
26+
TODO obrázek
27+
4) Table with detections result
28+
TODO obrázek
29+
5) Show details of detection
30+
6) Show detail of Anti-Pattern
31+
32+
## Configuration of Anti-Patterns
33+
1) Go to Configuration page
34+
TODO obrázek
35+
2) Change corresponding threshold values
36+
TODO obrázek
37+
3) Click button Save or press Enter
38+
TODO obrázek
39+
4) If the values ​​are set correctly, a message is displayed stating that the values ​​were saved successfully
40+
TODO obrázek
41+
5) If the values ​​are set incorrectly, a error message is displayed and the corresponding values ​​are highlighted in red with error message
42+
TODO obrázek
43+
44+
## Show Anti-Pattern detail
45+
1) Go to Anti-Pattern detail page
46+
1) On Home page click on anchor Show next to corresponding Anti-Pattern
47+
2) On result page slick on Anti-Pattern name and anchor Detail
48+
2) Anti-Pattern detail page is shown (name, description, anchor to catalogue, configuration values)
49+
3) Configuration values can be updated also in this page
50+
1) Change corresponding threshold values
51+
2) Click button Save or press Enter
52+
4) If the values ​​are set correctly, a message is displayed stating that the values ​​were saved successfully
53+
TODO obrázek
54+
5) If the values ​​are set incorrectly, a error message is displayed and the corresponding values ​​are highlighted in red with error message
55+
TODO obrázek
56+
57+
## Show project detail
58+
1) On home page click on anchor Show, next to corresponding project
59+
TODO obrázek
60+
2) Project details is shown (project id, name, description)
61+
TODO obrázek
62+
3263

src/main/java/cz/zcu/fav/kiv/antipatterndetectionapp/detecting/detectors/AntiPatternDetector.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ public interface AntiPatternDetector {
1212

1313
AntiPattern getAntiPatternModel();
1414

15-
String getAntiPatternSqlFileName();
15+
List<String> getSqlFileNames();
1616

1717
void setSqlQueries(List<String> queries);
1818

src/main/java/cz/zcu/fav/kiv/antipatterndetectionapp/detecting/detectors/BusinessAsUsualDetectorImpl.java

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,11 @@ public class BusinessAsUsualDetectorImpl implements AntiPatternDetector {
3535
}},
3636
"Business_As_Usual.md");
3737

38-
private final String sqlFileName = "business_as_usual.sql";
38+
private final List<String> SQL_FILE_NAMES = Arrays.asList(
39+
"set_project_id.sql",
40+
"select_number_of_iterations.sql",
41+
"select_iterations_with_substrings.sql",
42+
"select_all_wikipages_that_is_updated_in_iteration.sql");
3943

4044
// sql queries loaded from sql file
4145
private List<String> sqlQueries;
@@ -54,8 +58,8 @@ public AntiPattern getAntiPatternModel() {
5458
}
5559

5660
@Override
57-
public String getAntiPatternSqlFileName() {
58-
return this.sqlFileName;
61+
public List<String> getSqlFileNames() {
62+
return this.SQL_FILE_NAMES;
5963
}
6064

6165
@Override

src/main/java/cz/zcu/fav/kiv/antipatterndetectionapp/detecting/detectors/LongOrNonExistentFeedbackLoopsDetectorImpl.java

Lines changed: 14 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,16 @@ public class LongOrNonExistentFeedbackLoopsDetectorImpl implements AntiPatternDe
5151
}}
5252
);
5353

54-
private final String SQL_FILE_NAME = "long_or_non_existent_feedback_loops.sql";
54+
private final List<String> SQL_FILE_NAMES = Arrays.asList(
55+
"set_project_id.sql",
56+
"select_number_of_iterations.sql",
57+
"select_average_iterations_length.sql",
58+
"select_number_of_iterations_with_substrings_in_activity.sql",
59+
"select_all_activities_with_substrings_and_last_modified_date_as_end_date.sql",
60+
"select_project_start_date.sql",
61+
"select_project_end_date.sql",
62+
"select_all_iterations_that_contains_wikipages_with_substrings.sql");
63+
5564
// sql queries loaded from sql file
5665
private List<String> sqlQueries;
5766

@@ -60,7 +69,7 @@ private float getDivisionOfIterationsWithFeedbackLoop() {
6069
}
6170

6271
private float getMaxGapBetweenFeedbackLoopRate() {
63-
return (float) antiPattern.getConfigurations().get("maxGapBetweenFeedbackLoopRate").getValue();
72+
return ((PositiveFloat) antiPattern.getConfigurations().get("maxGapBetweenFeedbackLoopRate").getValue()).floatValue();
6473
}
6574

6675
private List<String> getSearchSubstringsWithFeedbackLoop() {
@@ -72,9 +81,8 @@ public AntiPattern getAntiPatternModel() {
7281
return this.antiPattern;
7382
}
7483

75-
@Override
76-
public String getAntiPatternSqlFileName() {
77-
return this.SQL_FILE_NAME;
84+
public List<String> getSqlFileNames() {
85+
return this.SQL_FILE_NAMES;
7886
}
7987

8088
@Override
@@ -124,7 +132,7 @@ public QueryResultItem analyze(Project project, DatabaseConnection databaseConne
124132
break;
125133
case 2:
126134
if (rs.size() != 0) {
127-
numberOfIterationsWhichContainsAtLeastOneActivityForFeedback = ((Long) rs.get(0).get("totalCountOfIterationsWithFeedbackActivity")).intValue();
135+
numberOfIterationsWhichContainsAtLeastOneActivityForFeedback = ((Long) rs.get(0).get("totalCountOfIterationsWithSubstringsInActivity")).intValue();
128136
}
129137
break;
130138
case 3:

src/main/java/cz/zcu/fav/kiv/antipatterndetectionapp/detecting/detectors/NinetyNinetyRuleDetectorImpl.java

Lines changed: 13 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -34,16 +34,19 @@ public class NinetyNinetyRuleDetectorImpl implements AntiPatternDetector {
3434
new PositiveInteger(2)));
3535
}});
3636

37-
private final String sqlFileName = "ninety_ninety_rule.sql";
37+
private final List<String> SQL_FILE_NAMES = Arrays.asList(
38+
"set_project_id.sql",
39+
"select_all_iterations_with_sum_estimated_and_spent_time.sql");
40+
3841
// sql queries loaded from sql file
3942
private List<String> sqlQueries;
4043

4144
private double getMaxDivisionRange() {
42-
return (Double) antiPattern.getConfigurations().get("maxDivisionRange").getValue();
45+
return ((PositiveFloat) antiPattern.getConfigurations().get("maxDivisionRange").getValue()).doubleValue();
4346
}
4447

4548
private int getMaxBadDivisionLimit() {
46-
return (int) antiPattern.getConfigurations().get("maxBadDivisionLimit").getValue();
49+
return ((PositiveInteger) antiPattern.getConfigurations().get("maxBadDivisionLimit").getValue()).intValue();
4750
}
4851

4952
@Override
@@ -52,8 +55,8 @@ public AntiPattern getAntiPatternModel() {
5255
}
5356

5457
@Override
55-
public String getAntiPatternSqlFileName() {
56-
return this.sqlFileName;
58+
public List<String> getSqlFileNames() {
59+
return this.SQL_FILE_NAMES;
5760
}
5861

5962
@Override
@@ -63,11 +66,11 @@ public void setSqlQueries(List<String> queries) {
6366

6467
/**
6568
* Postup detekce:
66-
* 1) pro každou iteraci udělat součet stráveného a odhadovaného času přes všechny aktivity
67-
* 2) udělat podíl strávený čas / odhadovaný čas
68-
* 3) pokud všechny výsledky podílů budou menší než 1.2 => vše ok
69-
* 4) pokud předchozí bod nezabere, tak iterovat přes všechny podíly
70-
* 5) pokud budou nalezeny tři iterace po sobě, kde se stále zhoršují odhady => detekováno
69+
* 1) pro každou iteraci udělat součet stráveného a odhadovaného času přes všechny aktivity
70+
* 2) udělat podíl strávený čas / odhadovaný čas
71+
* 3) pokud všechny výsledky podílů budou menší než 1.2 => vše ok
72+
* 4) pokud předchozí bod nezabere, tak iterovat přes všechny podíly
73+
* 5) pokud budou nalezeny tři iterace po sobě, kde se stále zhoršují odhady => detekováno
7174
*
7275
* @param project analyzovaný project
7376
* @param databaseConnection databázové připojení

src/main/java/cz/zcu/fav/kiv/antipatterndetectionapp/detecting/detectors/RoadToNowhereDetectorImpl.java

Lines changed: 14 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -44,16 +44,23 @@ public class RoadToNowhereDetectorImpl implements AntiPatternDetector {
4444
}},
4545
"Road_To_Nowhere.md");
4646

47-
private final String sqlFileName = "road_to_nowhere.sql";
47+
private final List<String> SQL_FILE_NAMES = Arrays.asList(
48+
"set_project_id.sql",
49+
"set_first_iteration_start_date.sql",
50+
"set_second_iteration_start_date.sql",
51+
"set_number_of_activities_with_substrings.sql",
52+
"set_number_of_wiki_pages_with_substrings.sql",
53+
"select_number_of_activities_and_wiki_pages_with_substrings.sql");
54+
4855
// sql queries loaded from sql file
4956
private List<String> sqlQueries;
5057

5158
private int getMinNumberOfWikiPagesWithProjectPlan() {
52-
return (int) antiPattern.getConfigurations().get("minNumberOfWikiPagesWithProjectPlan").getValue();
59+
return ((PositiveInteger) antiPattern.getConfigurations().get("minNumberOfWikiPagesWithProjectPlan").getValue()).intValue();
5360
}
5461

5562
private int getMinNumberOfActivitiesWithProjectPlan() {
56-
return (int) antiPattern.getConfigurations().get("minNumberOfActivitiesWithProjectPlan").getValue();
63+
return ((PositiveInteger) antiPattern.getConfigurations().get("minNumberOfActivitiesWithProjectPlan").getValue()).intValue();
5764
}
5865

5966
private List<String> getSearchSubstringsWithProjectPlan() {
@@ -66,8 +73,8 @@ public AntiPattern getAntiPatternModel() {
6673
}
6774

6875
@Override
69-
public String getAntiPatternSqlFileName() {
70-
return this.sqlFileName;
76+
public List<String> getSqlFileNames() {
77+
return this.SQL_FILE_NAMES;
7178
}
7279

7380
@Override
@@ -98,8 +105,8 @@ public QueryResultItem analyze(Project project, DatabaseConnection databaseConne
98105
Utils.fillQueryWithSearchSubstrings(this.sqlQueries, getSearchSubstringsWithProjectPlan()));
99106
if (rs != null) {
100107
while (rs.next()) {
101-
numberOfIssuesForProjectPlan = rs.getInt("numberOfIssuesForProjectPlan");
102-
numberOfWikiPagesForProjectPlan = rs.getInt("numberOfWikiPagesForProjectPlan");
108+
numberOfIssuesForProjectPlan = rs.getInt("numberOfActivitiesWithSubstrings");
109+
numberOfWikiPagesForProjectPlan = rs.getInt("numberOfWikiPagesWithSubstrings");
103110
}
104111
}
105112

src/main/java/cz/zcu/fav/kiv/antipatterndetectionapp/detecting/detectors/SpecifyNothingDetectorImpl.java

Lines changed: 14 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -49,20 +49,26 @@ public class SpecifyNothingDetectorImpl implements AntiPatternDetector {
4949
}},
5050
"Specify_Nothing.md");
5151

52-
private final String sqlFileName = "specify_nothing.sql";
52+
private final List<String> SQL_FILE_NAMES = Arrays.asList(
53+
"set_project_id.sql",
54+
"set_number_of_wiki_pages_with_substrings.sql",
55+
"set_number_of_activities_with_substrings.sql",
56+
"set_average_length_of_activities_description.sql",
57+
"select_statistics_for_given_project.sql");
58+
5359
// sql queries loaded from sql file
5460
private List<String> sqlQueries;
5561

5662
private int getMinNumberOfWikiPagesWithSpecification() {
57-
return (int) antiPattern.getConfigurations().get("minNumberOfWikiPagesWithSpecification").getValue();
63+
return ((PositiveInteger) antiPattern.getConfigurations().get("minNumberOfWikiPagesWithSpecification").getValue()).intValue();
5864
}
5965

6066
private int getMinNumberOfActivitiesWithSpecification() {
61-
return (int) antiPattern.getConfigurations().get("minNumberOfActivitiesWithSpecification").getValue();
67+
return ((PositiveInteger) antiPattern.getConfigurations().get("minNumberOfActivitiesWithSpecification").getValue()).intValue();
6268
}
6369

6470
private int getMinAvgLengthOfActivityDescription() {
65-
return (int) antiPattern.getConfigurations().get("minAvgLengthOfActivityDescription").getValue();
71+
return ((PositiveInteger) antiPattern.getConfigurations().get("minAvgLengthOfActivityDescription").getValue()).intValue();
6672
}
6773

6874
private List<String> getSearchSubstringsWithProjectSpecification() {
@@ -75,8 +81,8 @@ public AntiPattern getAntiPatternModel() {
7581
}
7682

7783
@Override
78-
public String getAntiPatternSqlFileName() {
79-
return this.sqlFileName;
84+
public List<String> getSqlFileNames() {
85+
return this.SQL_FILE_NAMES;
8086
}
8187

8288
@Override
@@ -110,8 +116,8 @@ public QueryResultItem analyze(Project project, DatabaseConnection databaseConne
110116
Utils.fillQueryWithSearchSubstrings(this.sqlQueries, getSearchSubstringsWithProjectSpecification()));
111117
if (rs != null) {
112118
while (rs.next()) {
113-
numberOfWikiPages = rs.getInt("numberOfWikiPages");
114-
numberOfActivitiesForSpecification = rs.getInt("numberOfActivitiesForSpecification");
119+
numberOfWikiPages = rs.getInt("numberOfWikiPagesWithSubstrings");
120+
numberOfActivitiesForSpecification = rs.getInt("numberOfActivitiesWithSubstrings");
115121
averageLengthOfIssueDescription = rs.getDouble("averageLengthOfIssueDescription");
116122
}
117123
}

src/main/java/cz/zcu/fav/kiv/antipatterndetectionapp/detecting/detectors/TooLongSprintDetectorImpl.java

Lines changed: 12 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -6,10 +6,7 @@
66
import org.slf4j.Logger;
77
import org.slf4j.LoggerFactory;
88

9-
import java.util.ArrayList;
10-
import java.util.HashMap;
11-
import java.util.List;
12-
import java.util.Map;
9+
import java.util.*;
1310

1411
public class TooLongSprintDetectorImpl implements AntiPatternDetector {
1512

@@ -37,7 +34,12 @@ public class TooLongSprintDetectorImpl implements AntiPatternDetector {
3734
}}
3835
);
3936

40-
private final String SQL_FILE_NAME = "too_long_sprint.sql";
37+
private final List<String> SQL_FILE_NAMES = Arrays.asList(
38+
"set_project_id.sql",
39+
"set_first_iteration_id.sql",
40+
"set_last_iteration_id.sql",
41+
"select_all_iterations_with_lengths_without_first_and_last.sql");
42+
4143
// sql queries loaded from sql file
4244
private List<String> sqlQueries;
4345

@@ -47,21 +49,22 @@ public AntiPattern getAntiPatternModel() {
4749
}
4850

4951
@Override
50-
public String getAntiPatternSqlFileName() {
51-
return this.SQL_FILE_NAME;
52+
public List<String> getSqlFileNames() {
53+
return this.SQL_FILE_NAMES;
5254
}
5355

56+
5457
@Override
5558
public void setSqlQueries(List<String> queries) {
5659
this.sqlQueries = queries;
5760
}
5861

5962
private Integer getMaxIterationLength(){
60-
return (Integer) this.antiPattern.getConfigurations().get("maxIterationLength").getValue();
63+
return ((PositiveInteger) this.antiPattern.getConfigurations().get("maxIterationLength").getValue()).intValue();
6164
}
6265

6366
private Integer getMaxNumberOfTooLongIterations(){
64-
return (Integer) this.antiPattern.getConfigurations().get("maxNumberOfTooLongIterations").getValue();
67+
return ((PositiveInteger) this.antiPattern.getConfigurations().get("maxNumberOfTooLongIterations").getValue()).intValue();
6568
}
6669

6770
/**

0 commit comments

Comments
 (0)