Projekt

Obecné

Profil

« Předchozí | Další » 

Revize f30c9e9e

Přidáno uživatelem Michal Linha před téměř 4 roky(ů)

re #8113 re #7885 all functions implemented, contingency table generation improved; re #8154 value filtering added; no comments

Zobrazit rozdíly:

src/main/java/vldc/aswi/database/DatabaseInterface.java
97 97
    public Map<String, TableColumn> executeQueryAndReturnTableColumns(String sqlQuery) {
98 98
        return jdbcTemplate.query(
99 99
                sqlQuery,
100
                new ResultSetExtractor<Map<String, TableColumn>>() {
101
                    @Override
102
                    public Map<String, TableColumn> extractData(ResultSet resultSet) throws SQLException, DataAccessException {
103
                        List<TableColumn> tableColumnsList = new ArrayList<>();
100
                resultSet -> {
101
                    List<TableColumn> tableColumnsList = new ArrayList<>();
104 102

  
105
                        ResultSetMetaData resultSetMetaData = resultSet.getMetaData();
106
                        int columnCount = resultSetMetaData.getColumnCount();
103
                    ResultSetMetaData resultSetMetaData = resultSet.getMetaData();
104
                    int columnCount = resultSetMetaData.getColumnCount();
107 105

  
108
                        // The column count starts from 1.
109
                        for (int i = 1; i <= columnCount; i++ ) {
110
                            String columnName = resultSetMetaData.getColumnName(i);
111
                            tableColumnsList.add(new TableColumn(columnName));
112
                        }
106
                    // The column count starts from 1.
107
                    for (int i = 1; i <= columnCount; i++ ) {
108
                        String columnName = resultSetMetaData.getColumnName(i);
109
                        tableColumnsList.add(new TableColumn(columnName));
110
                    }
113 111

  
114
                        // Add values from row to every column.
115
                        while(resultSet.next()) {
116
                            for (int i = 1; i <= columnCount; i++) {
117
                                tableColumnsList.get(i - 1).addValue(resultSet.getString(i));
118
                            }
112
                    // Add values from row to every column.
113
                    while(resultSet.next()) {
114
                        for (int i = 1; i <= columnCount; i++) {
115
                            tableColumnsList.get(i - 1).addValue(resultSet.getString(i));
119 116
                        }
117
                    }
120 118

  
121
                        Map<String, TableColumn> tableColumnMap = new HashMap<>();
122

  
123
                        // Create map, where key is tablecolumn name.
124
                        for (TableColumn column : tableColumnsList) {
125
                            tableColumnMap.put(column.getName(), column);
126
                        }
119
                    Map<String, TableColumn> tableColumnMap = new HashMap<>();
127 120

  
128
                        return tableColumnMap;
121
                    // Create map, where key is tablecolumn name.
122
                    for (TableColumn column : tableColumnsList) {
123
                        tableColumnMap.put(column.getName(), column);
129 124
                    }
125

  
126
                    return tableColumnMap;
130 127
                }
131 128
        );
132 129
    }
src/main/java/vldc/aswi/model/table/BooleanWrapper.java
1
package vldc.aswi.model.table;
2

  
3
public class BooleanWrapper {
4

  
5
    private boolean value;
6

  
7
    public BooleanWrapper(boolean value) {
8
        this.value = value;
9
    }
10

  
11
    public boolean isValue() {
12
        return value;
13
    }
14

  
15
    public void setValue(boolean value) {
16
        this.value = value;
17
    }
18
}
src/main/java/vldc/aswi/model/table/DoubleWrapper.java
1
package vldc.aswi.model.table;
2

  
3
public class DoubleWrapper {
4

  
5
    private double value;
6

  
7
    public DoubleWrapper(double value) {
8
        this.value = value;
9
    }
10

  
11
    public double getValue() {
12
        return value;
13
    }
14

  
15
    public void setValue(double value) {
16
        this.value = value;
17
    }
18
}
src/main/java/vldc/aswi/model/table/Node.java
1 1
package vldc.aswi.model.table;
2 2

  
3 3
import java.util.ArrayList;
4
import java.util.Collection;
5 4
import java.util.List;
6 5

  
7 6
/**
......
9 8
 */
10 9
public class Node {
11 10

  
11
    private double totalResult;
12

  
13
    private double totalResultAvg;
14

  
15
    private double totalResultAvgSum;
16

  
17
    private double totalResultSum;
18

  
19
    private double totalMin;
20

  
21
    private double totalMax;
22

  
23
    private boolean isFirstMin;
24

  
25
    private boolean isFirstMax;
26

  
12 27
    /**
13 28
     * Values of the nodes on a path the the node.
14 29
     */
......
18 33
     * Creates a node.
19 34
     */
20 35
    public Node() {
36
        isFirstMin = true;
37
        isFirstMax = true;
21 38
        this.values = new ArrayList<>();
22 39
    }
23 40

  
......
26 43
     * @param node node to be copied
27 44
     */
28 45
    public Node(Node node) {
46
        isFirstMin = true;
47
        isFirstMax = true;
29 48
        this.values = new ArrayList<>(node.values);
30 49
    }
31 50

  
......
44 63
    public void setValues(List<String> values) {
45 64
        this.values = values;
46 65
    }
66

  
67
    public double getTotalResult() {
68
        return totalResult;
69
    }
70

  
71
    public void setTotalResult(double totalResult) {
72
        this.totalResult = totalResult;
73
    }
74

  
75
    public double getTotalResultAvg() {
76
        return totalResultAvg;
77
    }
78

  
79
    public void setTotalResultAvg(double totalResultAvg) {
80
        this.totalResultAvg = totalResultAvg;
81
    }
82

  
83
    public double getTotalResultAvgSum() {
84
        return totalResultAvgSum;
85
    }
86

  
87
    public void setTotalResultAvgSum(double totalResultAvgSum) {
88
        this.totalResultAvgSum = totalResultAvgSum;
89
    }
90

  
91
    public double getTotalResultSum() {
92
        return totalResultSum;
93
    }
94

  
95
    public void setTotalResultSum(double totalResultSum) {
96
        this.totalResultSum = totalResultSum;
97
    }
98

  
99
    public double getTotalMin() {
100
        return totalMin;
101
    }
102

  
103
    public void setTotalMin(double totalMin) {
104
        this.totalMin = totalMin;
105
    }
106

  
107
    public double getTotalMax() {
108
        return totalMax;
109
    }
110

  
111
    public void setTotalMax(double totalMax) {
112
        this.totalMax = totalMax;
113
    }
114

  
115
    public boolean isFirstMin() {
116
        return isFirstMin;
117
    }
118

  
119
    public void setFirstMin(boolean firstMin) {
120
        isFirstMin = firstMin;
121
    }
122

  
123
    public boolean isFirstMax() {
124
        return isFirstMax;
125
    }
126

  
127
    public void setFirstMax(boolean firstMax) {
128
        isFirstMax = firstMax;
129
    }
47 130
}
src/main/java/vldc/aswi/model/table/ValueFunction.java
6 6
 */
7 7
public class ValueFunction {
8 8

  
9
    private double totalResult = 0.0;
10

  
11
    private double totalResultAvg;
12

  
13
    private double totalResultAvgSum;
14

  
15
    private double totalResultSum;
16

  
17
    private double totalMin;
18

  
19
    private double totalMax;
20

  
21
    private boolean isFirstMin = true;
22

  
23
    private boolean isFirstMax = true;
24

  
9 25
    /**
10 26
     * Value
11 27
     */
12
    private String value;
28
    private String nameOfSelect;
29

  
30
    private String name;
31

  
13 32
    /**
14 33
     * Function
15 34
     */
16 35
    private String function;
17 36

  
37
    private String type;
38

  
18 39
    /**
19 40
     * Creates an instance of the class
20
     * @param value value
41
     * @param nameOfSelect value
21 42
     * @param function function
22 43
     */
23
    public ValueFunction(String value, String function) {
24
        this.value = value;
44
    public ValueFunction(String nameOfSelect, String name, String function, String type) {
45
        this.nameOfSelect = nameOfSelect;
46
        this.name = name;
25 47
        this.function = function;
48
        this.type = type;
26 49
    }
27 50

  
28 51
    /**
29 52
     * Gets value.
30 53
     * @return value
31 54
     */
32
    public String getValue() {
33
        return value;
55
    public String getNameOfSelect() {
56
        return nameOfSelect;
34 57
    }
35 58

  
36 59
    /**
37 60
     * Sets value.
38
     * @param value value
61
     * @param nameOfSelect value
39 62
     */
40
    public void setValue(String value) {
41
        this.value = value;
63
    public void setNameOfSelect(String nameOfSelect) {
64
        this.nameOfSelect = nameOfSelect;
65
    }
66

  
67
    public String getName() {
68
        return name;
69
    }
70

  
71
    public void setName(String name) {
72
        this.name = name;
42 73
    }
43 74

  
44 75
    /**
......
56 87
    public void setFunction(String function) {
57 88
        this.function = function;
58 89
    }
90

  
91
    public String getType() {
92
        return type;
93
    }
94

  
95
    public void setType(String type) {
96
        this.type = type;
97
    }
98

  
99
    public double getTotalResult() {
100
        return totalResult;
101
    }
102

  
103
    public void setTotalResult(double totalResult) {
104
        this.totalResult = totalResult;
105
    }
106

  
107
    public double getTotalResultAvg() {
108
        return totalResultAvg;
109
    }
110

  
111
    public void setTotalResultAvg(double totalResultAvg) {
112
        this.totalResultAvg = totalResultAvg;
113
    }
114

  
115
    public double getTotalResultAvgSum() {
116
        return totalResultAvgSum;
117
    }
118

  
119
    public void setTotalResultAvgSum(double totalResultAvgSum) {
120
        this.totalResultAvgSum = totalResultAvgSum;
121
    }
122

  
123
    public double getTotalResultSum() {
124
        return totalResultSum;
125
    }
126

  
127
    public void setTotalResultSum(double totalResultSum) {
128
        this.totalResultSum = totalResultSum;
129
    }
130

  
131
    public double getTotalMin() {
132
        return totalMin;
133
    }
134

  
135
    public void setTotalMin(double totalMin) {
136
        this.totalMin = totalMin;
137
    }
138

  
139
    public double getTotalMax() {
140
        return totalMax;
141
    }
142

  
143
    public void setTotalMax(double totalMax) {
144
        this.totalMax = totalMax;
145
    }
146

  
147
    public boolean isFirstMin() {
148
        return isFirstMin;
149
    }
150

  
151
    public void setFirstMin(boolean firstMin) {
152
        isFirstMin = firstMin;
153
    }
154

  
155
    public boolean isFirstMax() {
156
        return isFirstMax;
157
    }
158

  
159
    public void setFirstMax(boolean firstMax) {
160
        isFirstMax = firstMax;
161
    }
59 162
}
src/main/java/vldc/aswi/model/table/contingencyTable/ContingencyTableRow.java
37 37
        cells.add(cell);
38 38
    }
39 39

  
40
    /**
41
     * Add new cells from the list into current row.
42
     * @param cells - List of new cells.
43
     */
44
    public void addTableRowCells(List<ContingencyTableRowCell> cells) {
45
        this.cells.addAll(cells);
46
    }
47

  
40 48
    /**
41 49
     * Check if current row is header or not.
42 50
     * @return True if current row is header, false if not.
src/main/java/vldc/aswi/service/SqlQueryManagerImpl.java
4 4
import org.springframework.beans.factory.annotation.Autowired;
5 5
import org.springframework.stereotype.Service;
6 6
import vldc.aswi.database.DatabaseInterface;
7
import vldc.aswi.domain.Assembly;
8 7
import vldc.aswi.domain.Configuration;
9 8
import vldc.aswi.domain.Function;
10 9
import vldc.aswi.domain.parameter.ParameterInConfiguration;
......
14 13
import vldc.aswi.model.table.contingencyTable.ContingencyTableRow;
15 14
import vldc.aswi.utils.Converter;
16 15

  
17
import javax.sql.DataSource;
18 16
import java.util.*;
19 17
import java.util.concurrent.TimeUnit;
20 18

  
......
23 21
 */
24 22
@Service
25 23
@Slf4j
26
public class SqlQueryManagerImpl implements SqlQueryManager{
24
public class SqlQueryManagerImpl implements SqlQueryManager {
27 25

  
28
    /** Autowired databaseInterface component. */
26
    /**
27
     * Autowired databaseInterface component.
28
     */
29 29
    @Autowired
30 30
    private DatabaseInterface databaseInterface;
31
    
31

  
32 32
    /**
33 33
     * Get list of  contingencyTableRow.
34
     * @param sqlQuery
35
     * @param parameterInConfigurations
34
     *
35
     * @param configuration - configuration from which table will be created.
36 36
     * @return List of contingencyTableRow.
37 37
     */
38 38
    @Override
39
    public List<ContingencyTableRow> getContingencyTableRow(String sqlQuery, List<ParameterInConfiguration> parameterInConfigurations) {
39
    public List<ContingencyTableRow> getContingencyTableRow(Configuration configuration) {
40 40
        long startTime = System.nanoTime();
41
        Map<String, TableColumn> tableColumns = this.databaseInterface.executeQueryAndReturnTableColumns(sqlQuery);
41

  
42
        Map<String, TableColumn> tableColumns = this.databaseInterface.executeQueryAndReturnTableColumns(
43
                generateFullSQLQuery(configuration.getAssembly().getSQLQuery(), configuration.getParametersInConfiguration())
44
        );
45

  
42 46
        long stopTime = System.nanoTime();
43 47
        System.out.println("Select:" + TimeUnit.MILLISECONDS.convert((stopTime - startTime), TimeUnit.NANOSECONDS));
44 48
        List<NameUserName> rowNames = new ArrayList<>();
......
46 50
        List<ValueFunction> valueFunctions = new ArrayList<>();
47 51

  
48 52
        // Create a copy of list.
49
        List<ParameterInConfiguration> copiedParametersInConfiguration = new ArrayList<>(parameterInConfigurations);
53
        List<ParameterInConfiguration> copiedParametersInConfiguration = new ArrayList<>(configuration.getParametersInConfiguration());
50 54

  
51 55
        // sort parameters in configuration to have them in order set by user
52 56
        Collections.sort(copiedParametersInConfiguration);
53 57

  
54
        // TODO: 28.05.2020 map would be better
55
        for(ParameterInConfiguration parameterInConfiguration : copiedParametersInConfiguration) {
56
            if (parameterInConfiguration.getLocation() != null && parameterInConfiguration.getLocation().getName().equals("Řádek")) {
57
                rowNames.add(new NameUserName(parameterInConfiguration.getParameter().getNameOfSelect().toUpperCase(),
58
                        parameterInConfiguration.getColumnName()));
59
            }
60
            else if (parameterInConfiguration.getLocation() != null && parameterInConfiguration.getLocation().getName().equals("Sloupec")) {
61
                columnNames.add(new NameUserName(parameterInConfiguration.getParameter().getNameOfSelect().toUpperCase(),
62
                        parameterInConfiguration.getColumnName()));
63
            }
64
            else if(parameterInConfiguration.getLocation() != null && parameterInConfiguration.getLocation().getName().equals("Hodnota")) {
65
                for (Function function : parameterInConfiguration.getFunctions()) {
66
                    valueFunctions.add(new ValueFunction(parameterInConfiguration.getParameter().getNameOfSelect().toUpperCase(),
67
                            function.getName().toUpperCase()));
68
                }
69
            }
70
        }
58
        initializeContingencyTableDataLists(rowNames, columnNames, valueFunctions, configuration.getParametersInConfiguration());
71 59

  
72
        Converter converter = new Converter();
73
        return converter.convertTableColumnsToContingencyTableRows(tableColumns, rowNames, columnNames, valueFunctions);
60
        Converter converter = new Converter(tableColumns, rowNames, columnNames, valueFunctions, true);
61
        return converter.convertTableColumnsToContingencyTableRows();
74 62
    }
75 63

  
76 64
    /**
......
91 79
    public List<String> getNameOfColumnsFromQuery(String sqlQuery) {
92 80
        return this.databaseInterface.getNameOfColumnsFromQuery(sqlQuery);
93 81
    }
82

  
83
    private void initializeContingencyTableDataLists(List<NameUserName> rowNames, List<NameUserName> columnNames,
84
                                                     List<ValueFunction> valueFunctions, List<ParameterInConfiguration> parametersInConfiguration) {
85
        for (ParameterInConfiguration parameterInConfiguration : parametersInConfiguration) {
86
            if (parameterInConfiguration.getLocation() != null && parameterInConfiguration.getLocation().getName().equals("Řádek")) {
87
                rowNames.add(new NameUserName(parameterInConfiguration.getParameter().getNameOfSelect().toUpperCase(),
88
                        parameterInConfiguration.getColumnName()));
89
            } else if (parameterInConfiguration.getLocation() != null && parameterInConfiguration.getLocation().getName().equals("Sloupec")) {
90
                columnNames.add(new NameUserName(parameterInConfiguration.getParameter().getNameOfSelect().toUpperCase(),
91
                        parameterInConfiguration.getColumnName()));
92
            } else if (parameterInConfiguration.getLocation() != null && parameterInConfiguration.getLocation().getName().equals("Hodnota")) {
93
                for (Function function : parameterInConfiguration.getFunctions()) {
94
                    valueFunctions.add(new ValueFunction(parameterInConfiguration.getParameter().getNameOfSelect().toUpperCase(),
95
                            parameterInConfiguration.getParameter().getName(), function.getName().toUpperCase(),
96
                            parameterInConfiguration.getParameter().getParameterType().getName()));
97
                }
98
            }
99
        }
100
    }
101

  
102
    private String generateFullSQLQuery(String basicSQLQuery, List<ParameterInConfiguration> parametersInConfiguration) {
103
        StringBuilder finalSQLQuery = new StringBuilder("SELECT * FROM (");
104
        finalSQLQuery.append(basicSQLQuery);
105
        finalSQLQuery.append(")");
106

  
107
        boolean isWhereDefined = false;
108

  
109
        for (ParameterInConfiguration parameterInConfiguration : parametersInConfiguration) {
110
            if (parameterInConfiguration.getOperator() != null && !parameterInConfiguration.getOperator().getName().equals("zadny") &&
111
                    parameterInConfiguration.getOperatorValue() != null && !parameterInConfiguration.getOperatorValue().equals("")) {
112
                String[] values = parameterInConfiguration.getOperatorValue().split(";");
113
                if (!isWhereDefined) {
114
                    finalSQLQuery.append(" WHERE ");
115
                    isWhereDefined = true;
116
                } else {
117
                    finalSQLQuery.append(" AND ");
118
                }
119

  
120
                finalSQLQuery.append(parameterInConfiguration.getParameter().getNameOfSelect());
121
                finalSQLQuery.append(" ");
122
                finalSQLQuery.append(parameterInConfiguration.getOperator().getName());
123
                finalSQLQuery.append(" ");
124
                switch (parameterInConfiguration.getOperator().getName()) {
125
                    case "BETWEEN":
126
                    case "NOT BETWEEN":
127
                        finalSQLQuery.append(betweenNotBetween(values, parameterInConfiguration.getParameter().getParameterType().getName()));
128
                        break;
129
                    case "IN":
130
                    case "NOT IN":
131
                        finalSQLQuery.append(inNotIn(values, parameterInConfiguration.getParameter().getParameterType().getName()));
132
                        break;
133
                    case "LIKE":
134
                    case "NOT LIKE":
135
                        finalSQLQuery.append(likeNotLike(values, parameterInConfiguration.getParameter().getParameterType().getName()));
136
                        break;
137
                    default:
138
                        finalSQLQuery.append(otherOperators(values, parameterInConfiguration.getParameter().getParameterType().getName()));
139
                        break;
140
                }
141

  
142
            }
143
        }
144

  
145
        return finalSQLQuery.toString();
146
    }
147

  
148
    private String likeNotLike(String[] values, String type) {
149
        StringBuilder SQLQueryPart = new StringBuilder();
150
        addQuotes(type, SQLQueryPart);
151
        SQLQueryPart.append(values[0]);
152
        addQuotes(type, SQLQueryPart);
153

  
154
        return SQLQueryPart.toString();
155
    }
156

  
157
    private String inNotIn(String[] values, String type) {
158
        StringBuilder SQLQueryPart = new StringBuilder();
159
        SQLQueryPart.append("(");
160
        for (int i = 0; i < values.length; i++) {
161
            addQuotes(type, SQLQueryPart);
162
            SQLQueryPart.append(values[i]);
163
            addQuotes(type, SQLQueryPart);
164
            if (i < values.length - 1) {
165
                SQLQueryPart.append(",");
166
            }
167
        }
168
        SQLQueryPart.append(")");
169

  
170
        return SQLQueryPart.toString();
171
    }
172

  
173
    private String betweenNotBetween(String[] values, String type) {
174
        StringBuilder SQLQueryPart = new StringBuilder();
175

  
176
        addQuotes(type, SQLQueryPart);
177
        SQLQueryPart.append(values[0]);
178
        addQuotes(type, SQLQueryPart);
179

  
180
        SQLQueryPart.append(" AND ");
181

  
182
        addQuotes(type, SQLQueryPart);
183
        SQLQueryPart.append(values[1]);
184
        addQuotes(type, SQLQueryPart);
185

  
186
        return SQLQueryPart.toString();
187
    }
188

  
189
    private String otherOperators(String[] values, String type) {
190
        StringBuilder SQLQueryPart = new StringBuilder();
191

  
192
        addQuotes(type, SQLQueryPart);
193
        SQLQueryPart.append(values[0]);
194
        addQuotes(type, SQLQueryPart);
195

  
196
        return SQLQueryPart.toString();
197
    }
198

  
199
    private void addQuotes(String type, StringBuilder SQLQueryPart) {
200
        if (type.equals("Text") || type.equals("Datum")) {
201
            SQLQueryPart.append("'");
202
        }
203
    }
94 204
}
src/main/java/vldc/aswi/utils/Converter.java
1 1
package vldc.aswi.utils;
2 2

  
3
import vldc.aswi.model.table.NameUserName;
4
import vldc.aswi.model.table.Node;
5
import vldc.aswi.model.table.TableColumn;
6
import vldc.aswi.model.table.ValueFunction;
3
import vldc.aswi.model.table.*;
7 4
import vldc.aswi.model.table.contingencyTable.ContingencyTableRow;
8 5
import vldc.aswi.model.table.contingencyTable.ContingencyTableRowCell;
9 6

  
10
import javax.persistence.criteria.CriteriaBuilder;
7
import java.text.DecimalFormat;
11 8
import java.util.ArrayList;
12 9
import java.util.List;
13 10
import java.util.Map;
......
18 15
 */
19 16
public class Converter {
20 17

  
21
    private List<Node> rowNodes;
18
    private final Map<String, TableColumn> tableColumns;
19
    private final List<NameUserName> rowNames;
20
    private final List<NameUserName> columnNames;
21
    private final List<ValueFunction> valueFunctions;
22

  
22 23
    private List<Node> columnNodes;
24
    private final DecimalFormat decimalFormat = new DecimalFormat("0.###");
25

  
26
    public Converter(Map<String, TableColumn> tableColumns, List<NameUserName> rowNames, List<NameUserName> columnNames,
27
                     List<ValueFunction> valueFunctions) {
28
        this.tableColumns = tableColumns;
29
        this.rowNames = rowNames;
30
        this.columnNames = columnNames;
31
        this.valueFunctions = valueFunctions;
32
    }
23 33

  
24 34
    /**
25 35
     * Convert Map of TableColumns into list of ContingencyTableRow.
26
     * @param tableColumns - Map of TableColumn.
27 36
     * @return List of ContingencyTableRow.
28 37
     */
29
    public List<ContingencyTableRow> convertTableColumnsToContingencyTableRows(Map<String, TableColumn> tableColumns,
30
                                                                                      List<NameUserName> rowNames,
31
                                                                                      List<NameUserName> columnNames,
32
                                                                               List<ValueFunction> valueFunctions) {
38
    public List<ContingencyTableRow> convertTableColumnsToContingencyTableRows() {
33 39
        long startTime = System.nanoTime();
34 40
        List<ContingencyTableRow> contingencyTableRows = new ArrayList<>();
35 41

  
36 42
        long startTime2 = System.nanoTime();
37
        List<ContingencyTableRow> headerRows = createHeaderOnlyRows(tableColumns, columnNames, valueFunctions);
43
        List<ContingencyTableRow> headerRows = createHeaderOnlyRows();
38 44
        long stopTime2 = System.nanoTime();
39 45
        System.out.println("Headers:" + TimeUnit.MILLISECONDS.convert((stopTime2 - startTime2), TimeUnit.NANOSECONDS));
40 46

  
41 47
        long startTime3 = System.nanoTime();
42
        List<ContingencyTableRow> dataRows = createDataRows(tableColumns, columnNames, rowNames, valueFunctions);
48
        List<ContingencyTableRow> dataRows = createDataRows();
43 49
        long stopTime3 = System.nanoTime();
44 50
        System.out.println("Rows:" + TimeUnit.MILLISECONDS.convert((stopTime3 - startTime3), TimeUnit.NANOSECONDS));
45 51

  
......
54 60

  
55 61
    /**
56 62
     * Generates header rows.
57
     * @param tableColumns Map of TableColumn
58
     * @param columnNames list of column and user column names
59
     * @param valueFunctions list of values and their functions
60 63
     * @return list of contingency table rows
61 64
     */
62
    private List<ContingencyTableRow> createHeaderOnlyRows(Map<String, TableColumn> tableColumns,
63
                                                           List<NameUserName> columnNames, List<ValueFunction> valueFunctions) {
65
    private List<ContingencyTableRow> createHeaderOnlyRows() {
64 66
        List<List<String>> values = new ArrayList<>();
65 67
        columnNodes = new ArrayList<>();
66 68
        List<ContingencyTableRow> headerRows = new ArrayList<>();
67 69

  
68 70
        List<String> valueOptions = new ArrayList<>();
69 71
        for (ValueFunction valueFunction : valueFunctions) {
70
            valueOptions.add(valueFunction.getFunction() + " z " + valueFunction.getValue());
72
            valueOptions.add(valueFunction.getFunction() + " z " + valueFunction.getName());
71 73
        }
72 74
        values.add(valueOptions);
73 75
        headerRows.add(new ContingencyTableRow(true, 0));
......
108 110
            for(ValueFunction valueFunction: valueFunctions) {
109 111
                if (i == 0) {
110 112
                    headerRows.get(i).addTableRowCell(new ContingencyTableRowCell("Celkový " + valueFunction.getFunction() +
111
                            " z " + valueFunction.getValue(), 1));
113
                            " z " + valueFunction.getName(), 1));
112 114
                } else {
113 115
                    headerRows.get(i).addTableRowCell(new ContingencyTableRowCell("", 1));
114 116
                }
......
144 146

  
145 147
    /**
146 148
     * Creates data rows.
147
     * @param tableColumns Map of TableColumn
148
     * @param columnNames list of column and user column names
149
     * @param rowNames list of row and user row names
150
     * @param valueFunctions list of values and their functions
151 149
     * @return list of contingency table rows
152 150
     */
153
    private List<ContingencyTableRow> createDataRows(Map<String, TableColumn> tableColumns, List<NameUserName> columnNames,
154
                                                     List<NameUserName> rowNames, List<ValueFunction> valueFunctions) {
151
    private List<ContingencyTableRow> createDataRows() {
155 152
        List<ContingencyTableRow> dataRows = new ArrayList<>();
156
        rowNodes = new ArrayList<>();
153
        List<Node> rowNodes = new ArrayList<>();
157 154
        List<List<String>> values = new ArrayList<>();
158 155
        for(NameUserName nameUserName : rowNames) {
159 156
            TableColumn column = tableColumns.get(nameUserName.getName());
......
166 163
        long stopTime = System.nanoTime();
167 164
        System.out.println("Rows List:" + TimeUnit.MILLISECONDS.convert((stopTime - startTime), TimeUnit.NANOSECONDS));
168 165

  
166
        boolean[] usableColumns = new boolean[(valueFunctions.size() * columnNodes.size())];
167

  
168
        List<ContingencyTableRow> rowsToBeRemoved = new ArrayList<>();
169 169
        for (int i = 0; i < dataRows.size(); i++) {
170
            fillRowWithData(dataRows.get(i), tableColumns, rowNodes.get(i), rowNames, columnNames, valueFunctions);
170
            if (!fillRowWithData(dataRows.get(i), rowNodes.get(i), usableColumns)) {
171
                rowsToBeRemoved.add(dataRows.get(i));
172
            }
173
        }
174

  
175
        dataRows.removeAll(rowsToBeRemoved);
176

  
177
//        for (ContingencyTableRow row : dataRows) {
178
//            List<ContingencyTableRowCell> cellsToRemove = new ArrayList<>();
179
//            for (int i = 1; i < usableColumns.length; i++) {
180
//                if (!usableColumns[i - 1]) {
181
//                    cellsToRemove.add(row.getCells().get(i));
182
//                }
183
//            }
184
//            row.getCells().removeAll(cellsToRemove);
185
//            cellsToRemove.clear();
186
//        }
187

  
188
        ContingencyTableRow finalRow = new ContingencyTableRow(false, 0);
189
        finalRow.addTableRowCell(new ContingencyTableRowCell("Celkem", 1));
190

  
191
        int columnIndex = 0;
192
        List<ContingencyTableRowCell> valueCells = new ArrayList<>();
193
        for (ValueFunction valueFunction : valueFunctions) {
194
            for (Node columnNode : columnNodes) {
195
                if (true) {
196
                    finalRow.addTableRowCell(generateFilledCell(valueFunction.getFunction(), columnNode.getTotalResult(), columnNode.getTotalResultSum(),
197
                            columnNode.getTotalMin(), columnNode.getTotalMax(), columnNode.getTotalResultAvgSum(),
198
                            columnNode.getTotalResultAvg()));
199
                    columnIndex++;
200
                }
201
            }
202
            valueCells.add(generateFilledCell(valueFunction.getFunction(), valueFunction.getTotalResult(), valueFunction.getTotalResultSum(),
203
                    valueFunction.getTotalMin(), valueFunction.getTotalMax(), valueFunction.getTotalResultAvgSum(),
204
                    valueFunction.getTotalResultAvg()));
171 205
        }
172 206

  
207
        finalRow.addTableRowCells(valueCells);
208

  
209
        dataRows.add(finalRow);
210

  
173 211
        return dataRows;
174 212
    }
175 213

  
......
226 264
    /**
227 265
     * Fills each data row with data.
228 266
     * @param row row to ne filled with data
229
     * @param tableColumns Map of TableColumn
230 267
     * @param node node of the row
231
     * @param rowNames list of row names and user names
232
     * @param columnNames list of column names and user names
233
     * @param valueFunctions list of values and their functions
234 268
     */
235
    private void fillRowWithData(ContingencyTableRow row, Map<String, TableColumn> tableColumns, Node node,
236
                                 List<NameUserName> rowNames, List<NameUserName> columnNames, List<ValueFunction> valueFunctions) {
269
    private boolean fillRowWithData(ContingencyTableRow row, Node node, boolean[] usableColumns) {
270
        if (valueFunctions.size() == 0) {
271
            return true;
272
        }
273

  
274
        boolean isSingleValueRow = false;
275

  
276
        if (node.getValues().size() <= 1) {
277
            isSingleValueRow = true;
278
        }
279

  
280
        boolean isRowUsable = false;
237 281
        if (columnNodes.size() == 0) {
238 282
            columnNodes.add(new Node());
239 283
        }
240 284

  
241
        List<Integer> usableIDs = getUsableIDs(tableColumns, node, rowNames);
285
        List<Integer> usableIDs = getUsableIDs(node);
242 286

  
243
        int[] totals = new int[valueFunctions.size()];
287
        DoubleWrapper[] totals = new DoubleWrapper[valueFunctions.size()];
288
        initializeWrapperField(totals);
289

  
290
        DoubleWrapper[] totalsAvgSum = new DoubleWrapper[valueFunctions.size()];
291
        initializeWrapperField(totalsAvgSum);
292

  
293
        boolean[] isFilledValueCells = new boolean[valueFunctions.size()];
294
        int columnIndex = 0;
244 295
        //hodnota
245 296
        for (int v = 0; v < valueFunctions.size(); v++) {
297
            BooleanWrapper isFirstMinMaxTotal = new BooleanWrapper(true);
246 298
            ValueFunction valueFunction = valueFunctions.get(v);
247 299
            //sloupec v kont. tabulce
248 300
            for (Node columnNode : columnNodes) {
249
                int result = 0;
301
                DoubleWrapper result = new DoubleWrapper(0);
302
                DoubleWrapper resultAvgSum = new DoubleWrapper(0);
303
                BooleanWrapper isFirstMinMax = new BooleanWrapper(true);
304
                boolean isFilledCell = false;
250 305
                // radek v orig. tabulce
251 306
                for (Integer usableID : usableIDs) {
252 307
                    boolean isUsable = true;
253 308
                    int j;
254
                    // zvoleny sloupec ze sloupcu
309
                    // zvoleny sloupec ze sloupcu, ziska hodnoty z pouzitelne radky danych sloupcu originalni tabulky a
310
                    // pokud se vsechny rovnaji hodnotam, ktere jsou ulozeny v hodnotach uzlu na pozici vybraneho
311
                    // sloupce, je kommbinace pouzitelna k vypoctum
255 312
                    for (j = 0; j < columnNode.getValues().size(); j++) {
256 313
                        if (!tableColumns.get(columnNames.get(j).getName()).getValues().get(usableID).equals(columnNode.getValues().get(j))) {
257 314
                            isUsable = false;
......
259 316
                        }
260 317
                    }
261 318
                    // zvoleny sloupec z hodnot
262
                    if (tableColumns.get(valueFunction.getValue()).getValues().get(usableID) == null) {
319
                    if (tableColumns.get(valueFunction.getNameOfSelect()).getValues().get(usableID) == null) {
263 320
                        isUsable = false;
264 321
                    }
265 322

  
266
                    if (isUsable) {
267
                        if (valueFunction.getFunction().equals("COUNT")) {
268
                            result++;
269
                        } else if (valueFunction.getFunction().equals("SUM")) {
270
                            result += Integer.parseInt(tableColumns.get(valueFunction.getValue()).getValues().get(usableID));
271
                        }
272
                        if (j - 1 == 0 || j == 0) {
273
                            if (valueFunction.getFunction().equals("COUNT")) {
274
                                totals[v]++;
275
                            } else if (valueFunction.getFunction().equals("SUM")) {
276
                                totals[v] += Integer.parseInt(tableColumns.get(valueFunction.getValue()).getValues().get(usableID));
277
                            }
323
                    usableColumns[columnIndex] = isUsable;
324

  
325
                    if (isUsable) { // pokud lze hodnotu pouzit, prunik vsech hodnot sedi (ma nejakou hodnotu)
326
                        isRowUsable = true;
327
                        isFilledCell = true;
328
                        computeValues(valueFunction, result, resultAvgSum, columnNode, isFirstMinMax,
329
                                usableID, false, isSingleValueRow);
330
                        if (j <= 1) {
331
                            isFilledValueCells[v] = true;
332
                            computeValues(valueFunction, totals[v], totalsAvgSum[v], null, isFirstMinMaxTotal,
333
                                    usableID, true, isSingleValueRow);
278 334
                        }
279 335
                    }
280 336
                }
281
                row.addTableRowCell(new ContingencyTableRowCell(Integer.toString(result), 0));
337
                if (!isFilledCell) {
338
                    row.addTableRowCell(new ContingencyTableRowCell("", 0));
339
                }
340
                else {
341
                    row.addTableRowCell(generateFilledCell(valueFunction.getFunction(), result.getValue(), result.getValue(), result.getValue(),
342
                            result.getValue(), resultAvgSum.getValue(), result.getValue()));
343
                }
344
                columnIndex++;
282 345
            }
283 346
        }
284
        for (int total : totals) {
285
            row.addTableRowCell(new ContingencyTableRowCell(Integer.toString(total), 0));
347
        for (int i = 0; i < valueFunctions.size(); i++) {
348
            if (!isFilledValueCells[i]) {
349
                row.addTableRowCell(new ContingencyTableRowCell("", 0));
350
            }
351
            else {
352
                row.addTableRowCell(generateFilledCell(valueFunctions.get(i).getFunction(), totals[i].getValue(), totals[i].getValue(),
353
                        totals[i].getValue(), totals[i].getValue(), totalsAvgSum[i].getValue(), totals[i].getValue()));
354
            }
286 355
        }
356

  
357
        return isRowUsable;
287 358
    }
288 359

  
289 360
    /**
290 361
     * Gets a list of IDs of the query rows that fit the contingency table row settings.
291
     * @param tableColumns Map of TableColumn
292 362
     * @param node node of the row
293
     * @param rowNames list of row names and user names
294 363
     * @return list of usable IDs
295 364
     */
296
    private List<Integer> getUsableIDs(Map<String, TableColumn> tableColumns, Node node, List<NameUserName> rowNames) {
365
    private List<Integer> getUsableIDs(Node node) {
297 366
        List<Integer> ids = new ArrayList<>();
298 367

  
299 368
        for (int i = 0; i < tableColumns.get(rowNames.get(0).getName()).getValues().size(); i++) {
369
            boolean isUsable = true;
300 370
            for (int j = 0; j < node.getValues().size(); j++) {
301
                if (tableColumns.get(rowNames.get(j).getName()).getValues().get(i).equals(node.getValues().get(j))) {
302
                    ids.add(i);
371
                if (!tableColumns.get(rowNames.get(j).getName()).getValues().get(i).equals(node.getValues().get(j))) {
372
                    isUsable = false;
373
                    break;
303 374
                }
304 375
            }
376
            if (isUsable) {
377
                ids.add(i);
378
            }
305 379
        }
306 380

  
307 381
        return ids;
308 382
    }
383

  
384
    private void computeValues(ValueFunction valueFunction, DoubleWrapper result, DoubleWrapper resultAvgSum, Node columnNode,
385
                               BooleanWrapper isFirstMinMax, int usableID, boolean isValueTotal, boolean isSingleValueRow) {
386
        switch (valueFunction.getFunction()) {
387
            case "COUNT":
388
                count(valueFunction, result, columnNode, isValueTotal, isSingleValueRow);
389
                break;
390
            case "SUM":
391
                sum(valueFunction, result, columnNode, usableID, isValueTotal, isSingleValueRow);
392
                break;
393
            case "MIN":
394
                min(valueFunction, result, columnNode, isFirstMinMax, usableID, isValueTotal, isSingleValueRow);
395
                break;
396
            case "MAX":
397
                max(valueFunction, result, columnNode, isFirstMinMax, usableID, isValueTotal, isSingleValueRow);
398
                break;
399
            case "AVG":
400
                average(valueFunction, result, resultAvgSum, columnNode, usableID, isValueTotal, isSingleValueRow);
401
                break;
402
        }
403
    }
404

  
405
    private ContingencyTableRowCell generateFilledCell(String function, double totalResult, double totalResultSum,
406
                                                       double totalMin, double totalMax, double totalResultAvgSum,
407
                                                       double totalResultAvg) {
408
        ContingencyTableRowCell cell = null;
409
        switch (function) {
410
            case "COUNT":
411
                cell = new ContingencyTableRowCell(decimalFormat.format(totalResult), 1);
412
                break;
413
            case "SUM":
414
                cell = new ContingencyTableRowCell(decimalFormat.format(totalResultSum), 1);
415
                break;
416
            case "MIN":
417
                cell = new ContingencyTableRowCell(decimalFormat.format(totalMin), 1);
418
                break;
419
            case "MAX":
420
                cell = new ContingencyTableRowCell(decimalFormat.format(totalMax), 1);
421
                break;
422
            case "AVG":
423
                if (totalResultAvg == 0) {
424
                    cell = new ContingencyTableRowCell("!!Dělení nulou!!", 0);
425
                } else {
426
                    cell = new ContingencyTableRowCell(decimalFormat.format(totalResultAvgSum / totalResultAvg), 0);
427
                }
428
                break;
429
        }
430

  
431
        return cell;
432
    }
433

  
434
    private void initializeWrapperField(DoubleWrapper[] field) {
435
        for (int i = 0; i < field.length; i++) {
436
            field[i] = new DoubleWrapper(0);
437
        }
438
    }
439

  
440
    private void count(ValueFunction valueFunction, DoubleWrapper result, Node columnNode, boolean isValueTotal,
441
                       boolean isSingleValueRow) {
442
        result.setValue(result.getValue() + 1);
443
        if (columnNode != null && isSingleValueRow) {
444
            columnNode.setTotalResult(columnNode.getTotalResult() + 1);
445
        }
446
        if (isValueTotal && isSingleValueRow) {
447
            valueFunction.setTotalResult(valueFunction.getTotalResult() + 1);
448
        }
449
    }
450

  
451
    private void sum(ValueFunction valueFunction, DoubleWrapper result, Node columnNode, int usableID, boolean isValueTotal,
452
                     boolean isSingleValueRow) {
453
        if (valueFunction.getType().equals("Číslo")) {
454
            result.setValue(result.getValue() + Double.parseDouble(tableColumns.get(valueFunction.getNameOfSelect()).getValues().get(usableID)));
455
            if (columnNode != null && isSingleValueRow) {
456
                columnNode.setTotalResultSum(columnNode.getTotalResultSum() + Double.parseDouble(tableColumns.get(valueFunction.getNameOfSelect()).getValues().get(usableID)));
457
            }
458
            if (isValueTotal && isSingleValueRow) {
459
                valueFunction.setTotalResultSum(valueFunction.getTotalResultSum() + Double.parseDouble(tableColumns.get(valueFunction.getNameOfSelect()).getValues().get(usableID)));
460
            }
461
        }
462
    }
463

  
464
    private void min(ValueFunction valueFunction, DoubleWrapper result, Node columnNode, BooleanWrapper isFirstMinMax,
465
                     int usableID, boolean isValueTotal, boolean isSingleValueRow) {
466
        if (valueFunction.getType().equals("Číslo")) {
467
            if (isFirstMinMax.isValue()) {
468
                isFirstMinMax.setValue(false);
469
                result.setValue(Double.parseDouble(tableColumns.get(valueFunction.getNameOfSelect()).getValues().get(usableID)));
470
            }
471
            else {
472
                result.setValue(Math.min(result.getValue(), Integer.parseInt(tableColumns.get(valueFunction.getNameOfSelect()).getValues().get(usableID))));
473
            }
474
            if (columnNode != null && isSingleValueRow) {
475
                if (columnNode.isFirstMin()) {
476
                    columnNode.setFirstMin(false);
477
                    columnNode.setTotalMin(Double.parseDouble(tableColumns.get(valueFunction.getNameOfSelect()).getValues().get(usableID)));
478
                } else {
479
                    columnNode.setTotalMin(Math.min(columnNode.getTotalMin(), Integer.parseInt(tableColumns.get(valueFunction.getNameOfSelect()).getValues().get(usableID))));
480
                }
481
            }
482
            if (isValueTotal && isSingleValueRow) {
483
                if (valueFunction.isFirstMin()) {
484
                    valueFunction.setFirstMin(false);
485
                    valueFunction.setTotalMin(Double.parseDouble(tableColumns.get(valueFunction.getNameOfSelect()).getValues().get(usableID)));
486
                } else {
487
                    valueFunction.setTotalMin(Math.min(valueFunction.getTotalMin(), Integer.parseInt(tableColumns.get(valueFunction.getNameOfSelect()).getValues().get(usableID))));
488
                }
489
            }
490
        }
491
    }
492

  
493
    private void max(ValueFunction valueFunction, DoubleWrapper result, Node columnNode, BooleanWrapper isFirstMinMax,
494
                     int usableID, boolean isValueTotal, boolean isSingleValueRow) {
495
        if (valueFunction.getType().equals("Číslo")) {
496
            if (isFirstMinMax.isValue()) {
497
                isFirstMinMax.setValue(false);
498
                result.setValue(Double.parseDouble(tableColumns.get(valueFunction.getNameOfSelect()).getValues().get(usableID)));
499
            }
500
            else {
501
                result.setValue(Math.max(result.getValue(), Integer.parseInt(tableColumns.get(valueFunction.getNameOfSelect()).getValues().get(usableID))));
502
            }
503
            if (columnNode != null && isSingleValueRow) {
504
                if (columnNode.isFirstMax()) {
505
                    columnNode.setFirstMax(false);
506
                    columnNode.setTotalMax(Double.parseDouble(tableColumns.get(valueFunction.getNameOfSelect()).getValues().get(usableID)));
507
                } else {
508
                    columnNode.setTotalMax(Math.max(columnNode.getTotalMax(), Integer.parseInt(tableColumns.get(valueFunction.getNameOfSelect()).getValues().get(usableID))));
509
                }
510
            }
511
            if (isValueTotal && isSingleValueRow) {
512
                if (valueFunction.isFirstMax()) {
513
                    valueFunction.setFirstMax(false);
514
                    valueFunction.setTotalMax(Double.parseDouble(tableColumns.get(valueFunction.getNameOfSelect()).getValues().get(usableID)));
515
                } else {
516
                    valueFunction.setTotalMax(Math.max(valueFunction.getTotalMax(), Integer.parseInt(tableColumns.get(valueFunction.getNameOfSelect()).getValues().get(usableID))));
517
                }
518
            }
519
        }
520
    }
521

  
522
    private void average(ValueFunction valueFunction, DoubleWrapper result, DoubleWrapper resultAvgSum, Node columnNode,
523
                         int usableID, boolean isValueTotal, boolean isSingleValueRow) {
524
        if (valueFunction.getType().equals("Číslo")) {
525
            result.setValue(result.getValue() + 1);
526
            resultAvgSum.setValue(resultAvgSum.getValue() + Double.parseDouble(tableColumns.get(valueFunction.getNameOfSelect()).getValues().get(usableID)));
527
            if (columnNode != null && isSingleValueRow) {
528
                columnNode.setTotalResultAvg(columnNode.getTotalResultAvg() + 1);
529
                columnNode.setTotalResultAvgSum(columnNode.getTotalResultAvgSum() + Double.parseDouble(tableColumns.get(valueFunction.getNameOfSelect()).getValues().get(usableID)));
530
            }
531
            if (isValueTotal && isSingleValueRow) {
532
                valueFunction.setTotalResultAvg(valueFunction.getTotalResultAvg() + 1);
533
                valueFunction.setTotalResultAvgSum(valueFunction.getTotalResultAvgSum() + Double.parseDouble(tableColumns.get(valueFunction.getNameOfSelect()).getValues().get(usableID)));
534
            }
535
        }
536
    }
309 537
}

Také k dispozici: Unified diff