Projekt

Obecné

Profil

« Předchozí | Další » 

Revize ca69c8a7

Přidáno uživatelem Ondřej Váně před asi 4 roky(ů)

Business as usual implemented

Zobrazit rozdíly:

src/main/java/cz/zcu/fav/kiv/antipatterndetectionapp/detecting/DatabaseConnection.java
6 6
import cz.zcu.fav.kiv.antipatterndetectionapp.utils.Utils;
7 7

  
8 8
import java.sql.*;
9
import java.util.Arrays;
10
import java.util.List;
9
import java.util.*;
11 10

  
12 11
public class DatabaseConnection {
13 12

  
......
66 65
        }
67 66
        return resultSet;
68 67
    }
68

  
69
    public List<List<Map<String,Object>>> executeQueriesWithMultipleResults(Project project, List<String> queries) {
70
        Statement stmt;
71
        List<List<Map<String,Object>>> allResults = new ArrayList<>();
72
        ResultSet resultSet = null;
73
        try {
74
            stmt = this.getDatabaseConnection().createStatement();
75

  
76
            for (String query : queries) {
77
                if(queries.indexOf(query) != queries.size()-1){
78
                    if(query.contains("?"))
79
                        query = query.replace("?", project.getId().toString());
80
                    resultSet = stmt.executeQuery(query);
81
                } else {
82
                    resultSet = stmt.executeQuery(query);
83
                }
84

  
85
                if (query.toLowerCase().startsWith("select")) {
86
                    allResults.add(resultSetToArrayList(resultSet));
87
                }
88

  
89
            }
90
        } catch (SQLException e) {
91
            e.printStackTrace();
92
        }
93

  
94
        return allResults;
95
    }
96

  
97
    public List<Map<String,Object>> resultSetToArrayList(ResultSet rs) throws SQLException {
98
        ResultSetMetaData md = rs.getMetaData();
99
        int columns = md.getColumnCount();
100
        List<Map<String, Object>> list = new ArrayList<>();
101
        while (rs.next()) {
102
            Map<String, Object> row = new HashMap<>(columns);
103
            for (int i = 1; i <= columns; ++i) {
104
                row.put(md.getColumnName(i), rs.getObject(i));
105
            }
106
            list.add(row);
107
        }
108

  
109
        return list;
110
    }
69 111
}
src/main/java/cz/zcu/fav/kiv/antipatterndetectionapp/detecting/detectors/BusinessAsUsualDetectorImpl.java
4 4
import cz.zcu.fav.kiv.antipatterndetectionapp.model.AntiPattern;
5 5
import cz.zcu.fav.kiv.antipatterndetectionapp.model.Project;
6 6
import cz.zcu.fav.kiv.antipatterndetectionapp.model.QueryResultItem;
7
import cz.zcu.fav.kiv.antipatterndetectionapp.model.ResultDetail;
8
import cz.zcu.fav.kiv.antipatterndetectionapp.utils.Utils;
7 9
import org.slf4j.Logger;
8 10
import org.slf4j.LoggerFactory;
9 11

  
12
import java.util.HashMap;
10 13
import java.util.List;
14
import java.util.Map;
11 15

  
12 16
public class BusinessAsUsualDetectorImpl extends AntiPatternDetector {
13 17

  
......
19 23
            "Absence of a retrospective after individual " +
20 24
                    "iterations or after the completion project.");
21 25

  
22
    private final String sqlFileName = "too_long_sprint.sql";
26
    private final String sqlFileName = "business_as_usual.sql";
27

  
28
    /**
29
     * Settings
30
     */
31
    private final float DIVISION_BUSINESS_AS_USUAL_ITERATIONS = (float) 1/3;
23 32

  
24 33
    @Override
25 34
    public AntiPattern getAntiPatternModel() {
......
31 40
        return this.sqlFileName;
32 41
    }
33 42

  
43
    /**
44
     * Postup detekce:
45
     * 1) ke každé iteraci najít všechny aktivity které obsahují název "%retr%"=retrospektiva nebo "%revi%"=revize
46
     * (mohlo by se dále detekovat že si na této aktivitě logují všichni členové, tato aktivita by měla být bez commitu,
47
     * měla by být dokončena někdy ke konci iterace => pokud by se ale vzaly v úvahu všechny tyto atributy, tak nenajedem
48
     * žádnou aktivita => příliš přísná kritéria)
49
     * 2) v každé iteraci by měla být alespoň jedna aktivita představující retrospektivu
50
     * 3) dále nalézt všechny wiki stránky, které byly upravené nebo vytvořené v dané iteraci
51
     * 4) zjistit jestli wiki stránka představuje nějaké poznámky z retrospektivy
52
     * 5) výsledky wiki stránek a aktivit dát dohromady a u každé iterace by měl být alespoň jeden záznam
53
     * 6) pokud nebude nalezen žádný záznam u více jak jedné třetiny iterací, tak je anti-pattern detekován
54
     *
55
     * @param project            analyzovaný project
56
     * @param databaseConnection databázové připojení
57
     * @param queries            list sql dotazů
58
     * @return výsledek detekce
59
     */
34 60
    @Override
35
    public QueryResultItem analyze(Project project, DatabaseConnection databaseConnection, List<String> sql) {
61
    public QueryResultItem analyze(Project project, DatabaseConnection databaseConnection, List<String> queries) {
62
        Long totalNumberIterations = 0L;
63
        Map<String, Integer> iterationsResults = new HashMap<>();
64

  
65
        // projít výsledky dotazů a dát do jedné mapy => v této mapě by měly být všechny iterace
66
        List<List<Map<String, Object>>> resultSets = databaseConnection.executeQueriesWithMultipleResults(project, queries);
67
        for (int i = 0; i < resultSets.size(); i++) {
68
            List<Map<String, Object>> rs = resultSets.get(i);
69

  
70
            if (i == 0) {
71
                totalNumberIterations = (Long) rs.get(0).get("numberOfIterations");
72
            }
73

  
74
            if (i == 1) {
75
                String iterationName;
76
                for (Map<String, Object> map : rs) {
77
                    iterationName = (String) map.get("iterationName");
78
                    iterationsResults.put(iterationName, 1);
79
                }
80
            }
81

  
82
            if (i == 2) {
83
                String iterationName;
84
                for (Map<String, Object> map : rs) {
85
                    iterationName = (String) map.get("iterationName");
86
                    iterationsResults.put(iterationName, 2);
87
                }
88
            }
89

  
90
        }
91

  
92

  
93
        int minRetrospectiveLimit =  totalNumberIterations.intValue() - Math.round(totalNumberIterations * DIVISION_BUSINESS_AS_USUAL_ITERATIONS);
94

  
95
        List<ResultDetail> resultDetails = Utils.createResultDetailsList(
96
                new ResultDetail("Project id", project.getId().toString()),
97
                new ResultDetail("Min retrospective loimit", String.valueOf(minRetrospectiveLimit)),
98
                new ResultDetail("Found retrospectives", String.valueOf(iterationsResults.size())));
99
        LOGGER.info(this.antiPattern.getPrintName());
100
        LOGGER.info(resultDetails.toString());
36 101

  
37
        return new QueryResultItem(this.antiPattern, false, null);
102
        return new QueryResultItem(this.antiPattern, minRetrospectiveLimit > iterationsResults.size(), resultDetails);
38 103
    }
39 104
}
src/main/resources/queries/business_as_usual.sql
15 15
           retrospectives (%retr%).
16 16
*/
17 17

  
18
/* Init global variables */
18
/* Init project id */
19 19
set @projectId = ?;
20 20
/* Retrospective substring */
21 21
set @restrospectiveSubstring = '%retr%';
22
/* Number of developers in project */
23
set @numberOfPeople =  (select count(DISTINCT assigneeId) from workunitview where projectId = @projectId and assigneeName != 'unknown');
22
/* Revision substring */
23
set @revisionSubstring = '%revi%';
24 24
/* Number of iterations for given project */
25
set @numberOfIterations = (select COUNT(*) from iteration where superProjectId = @projectId);
26
/* Number of wikipages with substring retr */
27
set @numberOfWikipageWithRetr = (select count(*) from artifactview where projectId = @projectId AND artifactClass like 'WIKIPAGE' AND (name like @restrospectiveSubstring OR description like @restrospectiveSubstring));
28
/* Number of issues with retr root ends same day like iteration and all members of team are logging  time on this issue */
29
set @numberOfRestrospectiveActivities = (select COUNT(distinct activityEndDate) from (select workunitview.id, workunitview.activityEndDate from workunitview INNER JOIN fieldchangeview on workunitview.id = fieldchangeview.itemId where workunitview.projectId = @projectId AND fieldchangeview.changeName LIKE 'LOGTIME' AND (abs(datediff(workunitview.activityEndDate, workunitview.iterationEndDate) = 0)) AND (workunitview.name like @restrospectiveSubstring OR workunitview.description LIKE @restrospectiveSubstring) GROUP by workunitview.id HAVING COUNT(DISTINCT fieldchangeview.authorId) = @numberOfPeople) as test);
30
/* Show all statistics */
31
select @projectId as `projectId`, @numberOfPeople as `numberOfPeople`, @numberOfIterations as `numberOfIterations`, @numberOfWikipageWithRetr as `numberOfWikipageWithRetr`, @numberOfRestrospectiveActivities as `numberOfRestrospectiveActivities`;
25
select COUNT(id) as 'numberOfIterations' from iteration where superProjectId = @projectId;
26
/* Select all iteration with detected retrospective activities */
27
select  iterationName as 'iterationName', count(name) as 'numberOfIssues' from workunitview where projectId = @projectId and (name like @restrospectiveSubstring or name like @revisionSubstring) group by iterationName;
28
/* Select all wikipages that were created or updated in iteration and have name with retr or revi*/
29
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.itemCreated between iteration.startDate and iteration.endDate) and iteration.superProjectId = @projectId where artifactview.projectId = @projectId and artifactview.artifactClass like 'WIKIPAGE' and (artifactview.name like '%retr%' or artifactview.description like '%retr%') group by iteration.id order by iteration.name;

Také k dispozici: Unified diff