Projekt

Obecné

Profil

« Předchozí | Další » 

Revize f1f46aab

Přidáno uživatelem stepanekp před asi 3 roky(ů)

Change of resource files location

Zobrazit rozdíly:

pom.xml
81 81
				<artifactId>spring-boot-maven-plugin</artifactId>
82 82
			</plugin>
83 83
		</plugins>
84
		<resources>
85
			<resource>
86
				<directory>src/main/java/resources</directory>
87
				<includes>
88
					<include>queries/*.sql</include>
89
				</includes>
90
			</resource>
91
			<resource>
92
				<directory>src/main/java/resources</directory>
93
				<includes>
94
					<include>antipatterns/*.json</include>
95
				</includes>
96
			</resource>
97
			<resource>
98
				<directory>src/main/java/resources</directory>
99
				<includes>
100
					<include>configurations/*.json</include>
101
				</includes>
102
			</resource>
103
		</resources>
104 84
	</build>
105 85

  
106 86
</project>
src/main/java/cz/zcu/fav/kiv/antipatterndetectionapp/repository/AntiPatternRepository.java
11 11
import org.springframework.beans.factory.annotation.Value;
12 12
import org.springframework.core.io.FileSystemResource;
13 13
import org.springframework.stereotype.Component;
14
import org.springframework.web.context.ServletContextAware;
15 14

  
16
import javax.servlet.ServletContext;
17
import java.io.BufferedReader;
18
import java.io.IOException;
19
import java.io.InputStreamReader;
15
import java.io.*;
20 16
import java.lang.reflect.InvocationTargetException;
21 17
import java.net.URL;
22 18
import java.util.*;
......
25 21
 * A class that takes care of working with AP.
26 22
 */
27 23
@Component
28
public class AntiPatternRepository implements ServletContextAware {
24
public class AntiPatternRepository {
29 25

  
30
    private static final String QUERY_DIR = "/queries/";
31
    private static final String AP_DIR = "/antipatterns/";
26
    private final String QUERY_DIR;
27
    private final String AP_DIR;
32 28
    private final String OPERATIONALIZATION_DIR;
33 29
    private final String OPERATIONALIZATION_IMG_DIR;
34 30
    private final Logger LOGGER = LoggerFactory.getLogger(AntiPatternRepository.class);
35
    private ServletContext servletContext;
36 31
    private Map<Long, AntiPatternDetector> antiPatternDetectors;
37 32

  
38 33

  
39 34
    public AntiPatternRepository(@Value("${DATA_PATH}")String dir){
40 35
        this.OPERATIONALIZATION_DIR = dir + "operationalizations/";
41 36
        this.OPERATIONALIZATION_IMG_DIR = dir + "operationalizations/images/";
42
    }
43
    /**
44
     * This method load all queries from files for each AP.
45
     *
46
     * @param servletContext servlet context
47
     */
48
    @Override
49
    public void setServletContext(ServletContext servletContext) {
50
        this.servletContext = servletContext;
37
        this.AP_DIR = "antipatterns/";
38
        this.QUERY_DIR = "queries/";
51 39

  
52
        // initialize all detectors
53 40
        this.antiPatternDetectors = initDetectors();
54

  
55
        // initialize sql queries
56 41
        initSqlQueries();
57 42
    }
58 43

  
59

  
60 44
    /**
61 45
     * The method that loads all available detectors that implement
62 46
     * the AntiPatternDetector interface creates objects that the
......
128 112
            LOGGER.info("Reading sql query from file " + fileName);
129 113

  
130 114
            try {
131
                URL test = servletContext.getResource(QUERY_DIR + fileName);
115
                URL url = getClass().getClassLoader().getResource(QUERY_DIR + fileName);
132 116
                BufferedReader read = new BufferedReader(
133
                        new InputStreamReader(test.openStream()));
117
                        new InputStreamReader(url.openStream()));
134 118
                String line;
135 119
                while ((line = read.readLine()) != null) {
136 120
                    if (line.startsWith("select") || line.startsWith("set") && line.charAt(line.length() - 1) == ';') {
......
159 143
        LOGGER.info("Reading anti-pattern from json file " + jsonFileName);
160 144

  
161 145
        try {
162
            URL url = servletContext.getResource(AP_DIR + jsonFileName);
146
            URL url = getClass().getClassLoader().getResource(AP_DIR + jsonFileName);
163 147

  
164 148
            BufferedReader read = new BufferedReader(
165 149
                    new InputStreamReader(url.openStream()));
src/main/webapp/antipatterns/BusinessAsUsual.json
1
{
2
    "id": "3",
3
    "printName": "Business As Usual",
4
    "name": "BusinessAsUsual",
5
    "description": "Absence of a retrospective after individual iterations or after the completion project.",
6
    "thresholds": [
7
        {
8
            "thresholdName": "divisionOfIterationsWithRetrospective",
9
            "thresholdType": "Percentage",
10
            "thresholdPrintName": "Division of iterations with retrospective",
11
            "thresholdDescription": "Minimum percentage of the total number of iterations with a retrospective (0,100)",
12
            "thresholdErrorMess": "Percentage must be float number between 0 and 100"
13
        },
14
        {
15
            "thresholdName": "searchSubstringsWithRetrospective",
16
            "thresholdType": "String",
17
            "thresholdPrintName": "Search substrings with retrospective",
18
            "thresholdDescription": "Substring that will be search in wikipages and activities",
19
            "thresholdErrorMess": "Maximum number of substrings is ten and must not starts and ends with characters || "
20
        }
21
    ],
22
    "catalogueFileName": "Business_As_Usual.md"
23
}
src/main/webapp/antipatterns/LongOrNonExistentFeedbackLoops.json
1
{
2
    "id": "6",
3
    "printName": "Long Or Non Existent Feedback Loops",
4
    "name": "LongOrNonExistentFeedbackLoops",
5
    "description": "Long spacings between customer feedback or no feedback. The customer enters the project and sees the final result. In the end, the customer may not get what he really wanted. With long intervals of feedback, some misunderstood functionality can be created and we have to spend a lot of effort and time to redo it. ",
6
    "thresholds": [
7
        {
8
            "thresholdName": "divisionOfIterationsWithFeedbackLoop",
9
            "thresholdType": "Percentage",
10
            "thresholdPrintName": "Division of iterations with feedback loop",
11
            "thresholdDescription": "Minimum percentage of the total number of iterations with feedback loop (0,100)",
12
            "thresholdErrorMess": "Percentage must be float number between 0 and 100"
13
        },
14
        {
15
            "thresholdName": "maxGapBetweenFeedbackLoopRate",
16
            "thresholdType": "PositiveFloat",
17
            "thresholdPrintName": "Maximum gap between feedback loop rate",
18
            "thresholdDescription": "Value that multiplies average iteration length for given project. Result is maximum threshold value for gap between feedback loops in days.",
19
            "thresholdErrorMess": "Maximum gap between feedback loop rate must be positive float number"
20
        },
21
        {
22
            "thresholdName": "searchSubstringsWithFeedbackLoop",
23
            "thresholdType": "String",
24
            "thresholdPrintName": "Search substrings with feedback loop",
25
            "thresholdDescription": "Substring that will be search in wikipages and activities",
26
            "thresholdErrorMess": "Maximum number of substrings is ten and must not starts and ends with characters ||"
27
        }
28
    ]
29
}
src/main/webapp/antipatterns/NinetyNinetyRule.json
1
{
2
    "id": "7",
3
    "printName": "Ninety Ninety Rule",
4
    "name": "NinetyNinetyRule",
5
    "description": "The first 90 percent of the code represents the first 90 percent of development time. The remaining 10 percent of the code represents another 90 percent of development time. Then decide on a long delay of the project compared to the original estimate. The functionality is almost done, some number is already closed and is only waiting for one activity to close, but it has been open for a long time.",
6
    "thresholds": [
7
        {
8
            "thresholdName": "maxDivisionRange",
9
            "thresholdType": "PositiveFloat",
10
            "thresholdPrintName": "Maximum ration value",
11
            "thresholdDescription": "Maximum ratio value of spent and estimated time",
12
            "thresholdErrorMess": "Ration values must be positive float number"
13
        },
14
        {
15
            "thresholdName": "maxBadDivisionLimit",
16
            "thresholdType": "PositiveInteger",
17
            "thresholdPrintName": "Maximum iterations thresholds",
18
            "thresholdDescription": "Maximum number of consecutive iterations where the thresholds were exceeded",
19
            "thresholdErrorMess": "Maximum number of consecutive iterations must be positive integer number"
20
        }
21
    ]
22
}
src/main/webapp/antipatterns/RoadToNowhere.json
1
{
2
    "id": "5",
3
    "printName": "Road To Nowhere",
4
    "name": "RoadToNowhere",
5
    "description": "The project is not sufficiently planned and therefore takes place on an ad hoc basis with an uncertain outcome and deadline. There is no project plan in the project.",
6
    "thresholds": [
7
        {
8
            "thresholdName": "minNumberOfWikiPagesWithProjectPlan",
9
            "thresholdType": "PositiveInteger",
10
            "thresholdPrintName": "Minimum number of wiki pages with project plan",
11
            "thresholdDescription": "Number of wiki pages",
12
            "thresholdErrorMess": "Minimum number of wikipages must be positive integer number"
13
        },
14
        {
15
            "thresholdName": "minNumberOfActivitiesWithProjectPlan",
16
            "thresholdType": "PositiveInteger",
17
            "thresholdPrintName": "Minimum number of activities with project plan",
18
            "thresholdDescription": "Number of activities",
19
            "thresholdErrorMess": "Minimum number of activities must be positive integer number"
20
        },
21
        {
22
            "thresholdName": "searchSubstringsWithProjectPlan",
23
            "thresholdType": "String",
24
            "thresholdPrintName": "Search substrings with project plan",
25
            "thresholdDescription": "Substring that will be search in wikipages and activities",
26
            "thresholdErrorMess": "Maximum number of substrings is ten and must not starts and ends with characters ||"
27
        }
28
    ],
29
    "catalogueFileName": "Road_To_Nowhere.md"
30
}
src/main/webapp/antipatterns/SpecifyNothing.json
1
{
2
    "id": "4",
3
    "printName": "Specify Nothing",
4
    "name": "SpecifyNothing",
5
    "description": "The specification is not done intentionally. Programmers are expected to work better without written specifications.",
6
    "thresholds": [
7
        {
8
            "thresholdName": "minNumberOfWikiPagesWithSpecification",
9
            "thresholdType": "PositiveInteger",
10
            "thresholdPrintName": "Minimum number of wiki pages with project specification",
11
            "thresholdDescription": "Number of wiki pages",
12
            "thresholdErrorMess": "Minimum number of wikipages must be positive integer number"
13
        },
14
        {
15
            "thresholdName": "minNumberOfActivitiesWithSpecification",
16
            "thresholdType": "PositiveInteger",
17
            "thresholdPrintName": "Minimum number of activities with project specification",
18
            "thresholdDescription": "Number of activities",
19
            "thresholdErrorMess": "Minimum number of activities with project specification must be positive integer number"
20
        },
21
        {
22
            "thresholdName": "minAvgLengthOfActivityDescription",
23
            "thresholdType": "PositiveInteger",
24
            "thresholdPrintName": "Minimum average length of activity description",
25
            "thresholdDescription": "Minimum average number of character of activity description",
26
            "thresholdErrorMess": "Minimum average length of activity description must be positive integer number"
27
        },
28
        {
29
            "thresholdName": "searchSubstringsWithProjectSpecification",
30
            "thresholdType": "String",
31
            "thresholdPrintName": "Search substrings with project specification",
32
            "thresholdDescription": "Substring that will be search in wikipages and activities",
33
            "thresholdErrorMess": "Maximum number of substrings is ten and must not starts and ends with characters ||"
34
        }
35
    ],
36
    "catalogueFileName": "Specify_Nothing.md"
37
}
src/main/webapp/antipatterns/TooLongSprint.json
1
{
2
    "id": "1",
3
    "printName": "Too Long Sprint",
4
    "name": "TooLongSprint",
5
    "description": "Iterations too long. (ideal iteration length is about 1-2 weeks, maximum 3 weeks). It could also be detected here if the length of the iteration does not change often (It can change at the beginning and at the end of the project, but it should not change in the already started project).",
6
    "thresholds": [
7
        {
8
            "thresholdName": "maxIterationLength",
9
            "thresholdType": "PositiveInteger",
10
            "thresholdPrintName": "Max Iteration Length",
11
            "thresholdDescription": "Maximum iteration length in days",
12
            "thresholdErrorMess": "Max iteration length must be positive integer"
13
        },
14
        {
15
            "thresholdName": "maxNumberOfTooLongIterations",
16
            "thresholdType": "PositiveInteger",
17
            "thresholdPrintName": "Max number of foo long iterations",
18
            "thresholdDescription": "Maximum number of too long iterations in project",
19
            "thresholdErrorMess": "Max number of too long iterations must be positive integer"
20

  
21
        }
22
    ]
23
}
src/main/webapp/antipatterns/VaryingSprintLength.json
1
{
2
    "id": "2",
3
    "printName": "Varying Sprint Length",
4
    "name": "VaryingSprintLength",
5
    "description": "The length of the sprint changes very often. It is clear that iterations will be different lengths at the beginning and end of the project, but the length of the sprint should not change during the project.",
6
    "thresholds": [
7
        {
8
            "thresholdName": "maxDaysDifference",
9
            "thresholdType": "PositiveInteger",
10
            "thresholdPrintName": "Max days difference",
11
            "thresholdDescription": "Maximum distance of two consecutive iterations in days",
12
            "thresholdErrorMess": "Maximum distance must be positive integer number"
13
        },
14
        {
15
            "thresholdName": "maxIterationChanged",
16
            "thresholdType": "PositiveInteger",
17
            "thresholdPrintName": "Max number of iteration changed",
18
            "thresholdDescription": "Maximum allowed number of significant changes in iteration lengths",
19
            "thresholdErrorMess": "Maximum number of iterations changed must be positive integer number"
20
        }
21
    ]
22
}
src/main/webapp/queries/select_all_activities_with_substrings_and_last_modified_date_as_end_date.sql
1
/* Select all activities with substrings and with last modified date as end date */
2
select wuv.id, wuv.iterationName, wuv.name, cast(max(fieldChangeView.created) as date) as 'endDate' from workUnitView as wuv inner join fieldChangeView on wuv.id = fieldChangeView.itemId where wuv.projectId = @projectId and (wuv.name like '§0§' or wuv.name like '§1§' or wuv.name like '§2§' or wuv.name like '§3§' or wuv.name like '§4§' or wuv.name like '§5§' or wuv.name like '§6§' or wuv.name like '§7§' or wuv.name like '§8§' or wuv.name like '§9§') GROUP by id order by fieldChangeView.created;
src/main/webapp/queries/select_all_iterations_that_contains_wikipages_with_substrings.sql
1
/* Select all iterations that contains wiki pages which were created or updated in iteration and have name or description that mentions some key words for customer demo*/
2
select iteration.name as 'iterationWithCustomerFeedback', cast(max(fieldChangeView.created) as date) as 'appointmentDate' from artifactView inner join fieldChangeView on artifactView.id = fieldChangeView.itemId inner join iteration on (fieldChangeView.created between iteration.startDate and iteration.endDate) and iteration.superProjectId = @projectId where artifactView.artifactClass like 'WIKIPAGE' and artifactView.projectId = @projectId and length(fieldChangeView.newValue) > length(fieldChangeView.oldValue) and (artifactView.name like '§0§' or artifactView.name like '§1§' or artifactView.name like '§2§' or artifactView.name like '§3§' or artifactView.name like '§4§' or artifactView.name like '§5§' or artifactView.name like '§6§' or artifactView.name like '§7§' or artifactView.name like '§8§' or artifactView.name like '§9§') group by iteration.name order by iteration.name;
src/main/webapp/queries/select_all_iterations_with_lengths_without_first_and_last.sql
1
/* !Global variables must be set for proper behavior! Select all iterations with their length without first and last iterations */
2
select datediff(endDate, startDate) as `iterationLength` from iteration where iteration.superProjectId = @projectId and iteration.id != @idOfFirstIteration and iteration.id != @idOfLastIteration order by iteration.name;
src/main/webapp/queries/select_all_iterations_with_sum_estimated_and_spent_time.sql
1
/* Select all activities for each iteration and sum estimated time and spent time */
2
select iterationName, sum(estimatedTime) as 'estimatedTime', sum(spentTime) as 'spentTime', sum(spentTime)/sum(estimatedTime) as 'timeDivision',  abs(1-(sum(spentTime)/sum(estimatedTime))) as 'deviation' from workUnitView where projectid = @projectId and iterationName is not null group by iterationName order by iterationName;
src/main/webapp/queries/select_all_wikipages_that_is_updated_in_iteration.sql
1
/* Select all wikipages that were created or updated in iteration and have name with retr or revi*/
2
select iteration.name as 'iterationName', count(distinct(artifactView.name)) as 'numberOfWikiPages' from artifactView inner join fieldChangeView on artifactView.id = fieldChangeView.itemId inner join iteration on (fieldChangeView.created between iteration.startDate and iteration.endDate) and iteration.superProjectId = @projectId where artifactView.projectId = @projectId and artifactView.artifactClass like 'WIKIPAGE' and (lower(artifactView.name) like lower('§0§') or lower(artifactView.name) like lower('§1§') or lower(artifactView.name) like lower('§2§') or lower(artifactView.name) like lower('§3§') or lower(artifactView.name) like lower('§4§') or lower(artifactView.name) like lower('§5§') or lower(artifactView.name) like lower('§6§') or lower(artifactView.name) like lower('§7§') or lower(artifactView.name) like lower('§8§') or lower(artifactView.name) like lower('§9§')) group by iteration.id order by iteration.name;
src/main/webapp/queries/select_average_iterations_length.sql
1
/* Average iteration length */
2
select avg(abs(dateDiff(iteration.endDate, iteration.startDate))) as 'averageIterationLength' from iteration where superProjectId = @projectId;
src/main/webapp/queries/select_iterations_with_substrings.sql
1
/* Select all iteration with detected retrospective activities */
2
select iterationName as 'iterationName', count(name) as 'numberOfIssues' from workUnitView where projectId = @projectId and (lower(name) like lower('§0§') or lower(name) like lower('§1§') or lower(name) like lower('§2§') or lower(name) like lower('§3§') or lower(name) like lower('§4§') or lower(name) like lower('§5§') or lower(name) like lower('§6§') or lower(name) like lower('§7§') or lower(name) like lower('§8§') or lower(name) like lower('§9§')) group by iterationName;
src/main/webapp/queries/select_number_of_activities_and_wiki_pages_with_substrings.sql
1
/* !Global variables must be set for proper behavior.! Select number of activities and wiki pages with given substrings and for given projects. */
2
select @projectId as `projectId`, @numberOfActivitiesWithSubstrings as `numberOfActivitiesWithSubstrings`, @numberOfWikiPagesWithSubstrings as `numberOfWikiPagesWithSubstrings`;
src/main/webapp/queries/select_number_of_iterations.sql
1
/* Number of iterations for given project */
2
select COUNT(id) as 'numberOfIterations' from iteration where superProjectId = @projectId and name like '%itera%';
src/main/webapp/queries/select_number_of_iterations_with_substrings_in_activity.sql
1
/* Select number of iterations which with substring in activity */
2
select count(*) over () as 'totalCountOfIterationsWithSubstringsInActivity' from workUnitView as wuv where wuv.projectId = @projectId and (wuv.name like '§0§' or wuv.name like '§1§' or wuv.name like '§2§' or wuv.name like '§3§' or wuv.name like '§4§' or wuv.name like '§5§' or wuv.name like '§6§' or wuv.name like '§7§' or wuv.name like '§8§' or wuv.name like '§9§') group by wuv.iterationName order by wuv.activityEndDate;
src/main/webapp/queries/select_project_end_date.sql
1
/* Get project end date */
2
select endDate as 'projectEndDate' from iteration where superProjectId = @projectId order by endDate desc limit 1;
src/main/webapp/queries/select_project_start_date.sql
1
/* Get project start date */
2
select startDate as 'projectStartDate' from iteration where superProjectId = @projectId order by startDate limit 1;
src/main/webapp/queries/select_statistics_for_given_project.sql
1
/* !Global variables must be set for proper behavior! Show number of wiki pages, number */
2
select @projectId as `projectId`, @numberOfWikiPagesWithSubstrings as `numberOfWikiPagesWithSubstrings`, @numberOfActivitiesWithSubstrings as `numberOfActivitiesWithSubstrings`, @averageLengthOfIssueDescription as `averageLengthOfIssueDescription`;
src/main/webapp/queries/set_average_length_of_activities_description.sql
1
/* Count average length of issues description */
2
set @averageLengthOfIssueDescription = (select AVG(CHAR_LENGTH(workUnitView.description)) from workUnitView where workUnitView.projectId = @projectId);
src/main/webapp/queries/set_first_iteration_id.sql
1
/* Id of first iteration */
2
set @idOfFirstIteration = (select id from iteration where iteration.superProjectId = @projectId order by name limit 1);
src/main/webapp/queries/set_first_iteration_start_date.sql
1
/* set first iteration start date to the global values named @firstIterationStartDate */
2
set @firstIterationStartDate = (select startDate from iteration where superProjectId = @projectId ORDER BY startDate LIMIT 1 offset 0);
src/main/webapp/queries/set_last_iteration_id.sql
1
/* Id of last iteration */
2
set @idOfLastIteration = (select id from iteration where iteration.superProjectId = @projectId order by name desc limit 1);
src/main/webapp/queries/set_number_of_activities_with_substrings.sql
1
/* Select number of activities with given substrings and set it to the global value named @numberOfActivitiesWithSubstrings */
2
set @numberOfActivitiesWithSubstrings = (SELECT count(*) from workUnitView where projectId = @projectId  and (lower(workUnitView.name) like lower('§0§') or lower(workUnitView.description) like lower('§0§') or lower(workUnitView.name) like lower('§1§') or lower(workUnitView.description) like lower('§1§') or lower(workUnitView.name) like lower('§2§') or lower(workUnitView.description) like lower('§2§') or lower(workUnitView.name) like lower('§3§') or lower(workUnitView.description) like lower('§3§') or lower(workUnitView.name) like lower('§4§') or lower(workUnitView.description) like lower('§4§') or lower(workUnitView.name) like lower('§5§') or lower(workUnitView.description) like lower('§5§') or lower(workUnitView.name) like lower('§6§') or lower(workUnitView.description) like lower('§6§') or lower(workUnitView.name) like lower('§7§') or lower(workUnitView.description) like lower('§7§') or lower(workUnitView.name) like lower('§8§') or lower(workUnitView.description) like lower('§8§') or lower(workUnitView.name) like lower('§9§') or lower(workUnitView.description) like lower('§9§')) AND (iterationStartDate = @firstIterationStartDate OR iterationStartDate = @secondIterationStartDate));
src/main/webapp/queries/set_number_of_wiki_pages_with_substrings.sql
1
/* Select number of wiki pages with given substrings and set it to the global value named @numberOfWikiPagesWithSubstrings */
2
set @numberOfWikiPagesWithSubstrings = (SELECT count(*) from artifactView where projectId = @projectId AND artifactClass like 'WIKIPAGE' AND (lower(artifactView.name) like lower('§0§') or lower(artifactView.description) like lower('§0§') or lower(artifactView.name) like lower('§1§') or lower(artifactView.description) like lower('§1§') or lower(artifactView.name) like lower('§2§') or lower(artifactView.description) like lower('§2§') or lower(artifactView.name) like lower('§3§') or lower(artifactView.description) like lower('§3§') or lower(artifactView.name) like lower('§4§') or lower(artifactView.description) like lower('§4§') or lower(artifactView.name) like lower('§5§') or lower(artifactView.description) like lower('§5§') or lower(artifactView.name) like lower('§6§') or lower(artifactView.description) like lower('§6§') or lower(artifactView.name) like lower('§7§') or lower(artifactView.description) like lower('§7§') or lower(artifactView.name) like lower('§8§') or lower(artifactView.description) like lower('§8§') or lower(artifactView.name) like lower('§9§') or lower(artifactView.description) like lower('§9§')));
src/main/webapp/queries/set_project_id.sql
1
/* Init project id */
2
set @projectId = ?;
src/main/webapp/queries/set_second_iteration_start_date.sql
1
/* set second iteration start date to the global values named @firstIterationStartDate */
2
set @secondIterationStartDate = (select startDate from iteration where superProjectId = @projectId ORDER BY startDate LIMIT 1 offset 1);

Také k dispozici: Unified diff