TreeDatabase.java

1
package com.jsql.view.swing.tree;
2
3
import com.jsql.model.bean.database.AbstractElementDatabase;
4
import com.jsql.model.bean.database.Column;
5
import com.jsql.model.bean.database.Database;
6
import com.jsql.model.bean.database.Table;
7
import com.jsql.util.LogLevelUtil;
8
import com.jsql.view.swing.tree.model.AbstractNodeModel;
9
import com.jsql.view.swing.tree.model.NodeModelColumn;
10
import com.jsql.view.swing.tree.model.NodeModelDatabase;
11
import com.jsql.view.swing.tree.model.NodeModelTable;
12
import com.jsql.view.swing.util.MediatorHelper;
13
import org.apache.logging.log4j.LogManager;
14
import org.apache.logging.log4j.Logger;
15
16
import javax.swing.*;
17
import javax.swing.tree.DefaultMutableTreeNode;
18
import javax.swing.tree.DefaultTreeModel;
19
import javax.swing.tree.TreePath;
20
import java.util.HashMap;
21
import java.util.List;
22
import java.util.Map;
23
24
public class TreeDatabase extends JTree {
25
    
26
    /**
27
     * Log4j logger sent to view.
28
     */
29
    private static final Logger LOGGER = LogManager.getRootLogger();
30
31
    /**
32
     * Map a database element with the corresponding tree node.<br>
33
     * The injection model sends a database element to the view, then
34
     * the view accesses its graphic component for update.
35
     */
36
    private final transient Map<AbstractElementDatabase, DefaultMutableTreeNode> mapNodes = new HashMap<>();
37
38
    public TreeDatabase(DefaultMutableTreeNode root) {
39
        super(root);
40
    }
41
    
42
    public void reloadNodes() {
43 1 1. reloadNodes : negated conditional → NO_COVERAGE
        if (this.isRootVisible()) {  // I18n of tree empty node
44
            DefaultTreeModel model = (DefaultTreeModel) this.getModel();
45
            DefaultMutableTreeNode root = (DefaultMutableTreeNode) model.getRoot();
46 1 1. reloadNodes : removed call to javax/swing/tree/DefaultTreeModel::reload → NO_COVERAGE
            model.reload(root);
47 1 1. reloadNodes : removed call to com/jsql/view/swing/tree/TreeDatabase::revalidate → NO_COVERAGE
            this.revalidate();
48
        }
49
    }
50
51
    public void reset() {
52 1 1. reset : removed call to java/util/Map::clear → NO_COVERAGE
        this.getTreeNodeModels().clear();
53
54
        DefaultTreeModel treeModel = (DefaultTreeModel) this.getModel();  // Tree model for refreshing the tree
55
        DefaultMutableTreeNode root = (DefaultMutableTreeNode) treeModel.getRoot();  // The tree root
56
57 1 1. reset : removed call to javax/swing/tree/DefaultMutableTreeNode::removeAllChildren → NO_COVERAGE
        root.removeAllChildren();  // Remove tree nodes
58 1 1. reset : removed call to javax/swing/tree/DefaultTreeModel::nodeChanged → NO_COVERAGE
        treeModel.nodeChanged(root);  // Refresh the root
59 1 1. reset : removed call to javax/swing/tree/DefaultTreeModel::reload → NO_COVERAGE
        treeModel.reload();  // Refresh the tree
60
        
61 1 1. reset : removed call to com/jsql/view/swing/tree/TreeDatabase::setRootVisible → NO_COVERAGE
        this.setRootVisible(true);
62
    }
63
    
64
    public void addColumns(List<Column> columns) {
65
        DefaultTreeModel treeModel = (DefaultTreeModel) this.getModel();
66
        DefaultMutableTreeNode tableNode = null;  // The table to update
67
68
        // Loop into the list of columns
69
        for (Column column: columns) {
70
            AbstractNodeModel newTreeNodeModel = new NodeModelColumn(column);  // Create a node model with the column element
71
            var newNode = new DefaultMutableTreeNode(newTreeNodeModel);  // Create the node
72
            tableNode = this.getTreeNodeModels().get(column.getParent());  // Get the parent table
73
            
74
            // Fix #1805 : NullPointerException on tableNode.getChildCount()
75 1 1. addColumns : negated conditional → NO_COVERAGE
            if (tableNode != null) {
76 1 1. addColumns : removed call to javax/swing/tree/DefaultTreeModel::insertNodeInto → NO_COVERAGE
                treeModel.insertNodeInto(newNode, tableNode, tableNode.getChildCount());  // Add the column to the table
77
            }
78
        }
79
80 1 1. addColumns : negated conditional → NO_COVERAGE
        if (tableNode != null) {
81 1 1. addColumns : removed call to com/jsql/view/swing/tree/TreeDatabase::expandPath → NO_COVERAGE
            this.expandPath(new TreePath(tableNode.getPath()));  // Open the table node
82 1 1. addColumns : removed call to com/jsql/view/swing/tree/model/AbstractNodeModel::setLoaded → NO_COVERAGE
            ((AbstractNodeModel) tableNode.getUserObject()).setLoaded(true);  // The table has just been search (avoid double check)
83
        }
84
    }
85
    
86
    public void addDatabases(List<Database> databases) {
87
        DefaultTreeModel treeModel = (DefaultTreeModel) this.getModel();
88
        DefaultMutableTreeNode root = (DefaultMutableTreeNode) treeModel.getRoot();  // First node in tree
89
90
        // Loop into the list of databases
91
        for (Database database: databases) {
92
            AbstractNodeModel newTreeNodeModel = new NodeModelDatabase(database);  // Create a node model with the database element
93
            var newNode = new DefaultMutableTreeNode(newTreeNodeModel);  // Create the node
94
            this.getTreeNodeModels().put(database, newNode);  // Save the node
95 1 1. addDatabases : removed call to javax/swing/tree/DefaultMutableTreeNode::add → NO_COVERAGE
            root.add(newNode);  // Add the node to the tree
96
        }
97
98
        // Refresh the tree
99 1 1. addDatabases : removed call to javax/swing/tree/DefaultTreeModel::reload → NO_COVERAGE
        treeModel.reload(root);
100
        
101
        // Open the root node
102 1 1. addDatabases : removed call to com/jsql/view/swing/tree/TreeDatabase::expandPath → NO_COVERAGE
        this.expandPath(new TreePath(root.getPath()));
103 1 1. addDatabases : removed call to com/jsql/view/swing/tree/TreeDatabase::setRootVisible → NO_COVERAGE
        this.setRootVisible(false);
104
    }
105
    
106
    public void addTables(List<Table> tables) {
107
        DefaultMutableTreeNode databaseNode = null;  // The database to update
108
109
        for (Table table: tables) {
110
            AbstractNodeModel newTreeNodeModel = new NodeModelTable(table);  // Create a node model with the table element
111
            var newNode = new DefaultMutableTreeNode(newTreeNodeModel);  // Create the node
112
            this.getTreeNodeModels().put(table, newNode);  // Save the node
113
            databaseNode = this.getTreeNodeModels().get(table.getParent());
114
115
            // Report NullPointerException #1670
116 1 1. addTables : negated conditional → NO_COVERAGE
            if (databaseNode != null) {
117
                DefaultTreeModel treeModel = (DefaultTreeModel) this.getModel();
118 1 1. addTables : removed call to javax/swing/tree/DefaultTreeModel::insertNodeInto → NO_COVERAGE
                treeModel.insertNodeInto(newNode, databaseNode, databaseNode.getChildCount());  // Add the table to the database
119
            } else {
120
                LOGGER.log(LogLevelUtil.CONSOLE_ERROR, "Missing database for table {}.", () -> table);
121
            }
122
        }
123
124 1 1. addTables : negated conditional → NO_COVERAGE
        if (databaseNode != null) {
125 1 1. addTables : removed call to com/jsql/view/swing/tree/TreeDatabase::expandPath → NO_COVERAGE
            this.expandPath(new TreePath(databaseNode.getPath()));  // Open the database node
126 1 1. addTables : removed call to com/jsql/view/swing/tree/model/AbstractNodeModel::setLoaded → NO_COVERAGE
            ((AbstractNodeModel) databaseNode.getUserObject()).setLoaded(true);  // The database has just been search (avoid double check)
127
        }
128
    }
129
    
130
    public void createValuesTab(String[][] data, String[] columnNames, AbstractElementDatabase table) {
131
        // Report NullPointerException #1683
132
        DefaultMutableTreeNode node = this.getTreeNodeModels().get(table);
133 1 1. createValuesTab : negated conditional → NO_COVERAGE
        if (node != null) {
134
            AbstractNodeModel progressingTreeNodeModel = (AbstractNodeModel) node.getUserObject();
135 1 1. createValuesTab : removed call to com/jsql/view/swing/tree/model/AbstractNodeModel::setIndexProgress → NO_COVERAGE
            progressingTreeNodeModel.setIndexProgress(table.getChildCount());  // Update the progress value of the model, end the progress
136 1 1. createValuesTab : removed call to com/jsql/view/swing/tree/model/AbstractNodeModel::setRunning → NO_COVERAGE
            progressingTreeNodeModel.setRunning(false);  // Mark the node model as 'no stop/pause/resume button'
137 1 1. createValuesTab : removed call to com/jsql/view/swing/tab/TabResults::addTabValues → NO_COVERAGE
            MediatorHelper.tabResults().addTabValues(data, columnNames, table);
138
        }
139
    }
140
    
141
    public void endIndeterminateProgress(AbstractElementDatabase dataElementDatabase) {
142
        DefaultMutableTreeNode node = this.getTreeNodeModels().get(dataElementDatabase);
143
        // Fix #1806 : NullPointerException on ...odels().get(dataElementDatabase).getUserObject()
144 1 1. endIndeterminateProgress : negated conditional → NO_COVERAGE
        if (node != null) {
145
            AbstractNodeModel progressingTreeNodeModel = (AbstractNodeModel) node.getUserObject();
146 1 1. endIndeterminateProgress : removed call to com/jsql/view/swing/tree/model/AbstractNodeModel::setProgressing → NO_COVERAGE
            progressingTreeNodeModel.setProgressing(false);  // Mark the node model as 'no loading bar'
147 1 1. endIndeterminateProgress : removed call to com/jsql/view/swing/tree/model/AbstractNodeModel::setRunning → NO_COVERAGE
            progressingTreeNodeModel.setRunning(false);  // Mark the node model as 'no stop/pause/resume button'
148
            DefaultTreeModel treeModel = (DefaultTreeModel) this.getModel();
149 1 1. endIndeterminateProgress : removed call to javax/swing/tree/DefaultTreeModel::nodeChanged → NO_COVERAGE
            treeModel.nodeChanged(node);  // Update the node
150
        }
151
    }
152
    
153
    public void endProgress(AbstractElementDatabase dataElementDatabase) {
154
        // Report NullPointerException #1671
155
        DefaultMutableTreeNode node = this.getTreeNodeModels().get(dataElementDatabase);
156 1 1. endProgress : negated conditional → NO_COVERAGE
        if (node != null) {
157
            AbstractNodeModel progressingTreeNodeModel = (AbstractNodeModel) node.getUserObject();
158 1 1. endProgress : removed call to com/jsql/view/swing/tree/model/AbstractNodeModel::setLoading → NO_COVERAGE
            progressingTreeNodeModel.setLoading(false);  // Mark the node model as 'no progress bar'
159 1 1. endProgress : removed call to com/jsql/view/swing/tree/model/AbstractNodeModel::setRunning → NO_COVERAGE
            progressingTreeNodeModel.setRunning(false);  // Mark the node model as 'no stop/pause/resume button'
160 1 1. endProgress : removed call to com/jsql/view/swing/tree/model/AbstractNodeModel::setIndexProgress → NO_COVERAGE
            progressingTreeNodeModel.setIndexProgress(0);  // Reset the progress value of the model
161
            DefaultTreeModel treeModel = (DefaultTreeModel) this.getModel();
162 1 1. endProgress : removed call to javax/swing/tree/DefaultTreeModel::nodeChanged → NO_COVERAGE
            treeModel.nodeChanged(node);  // Update the node and progress bar
163
        }
164
    }
165
    
166
    public void startIndeterminateProgress(AbstractElementDatabase dataElementDatabase) {
167
        DefaultMutableTreeNode node = this.getTreeNodeModels().get(dataElementDatabase);
168
        // Fix #45540: NullPointerException on node.getUserObject()
169 1 1. startIndeterminateProgress : negated conditional → NO_COVERAGE
        if (node != null) {
170
            AbstractNodeModel progressingTreeNodeModel = (AbstractNodeModel) node.getUserObject();
171 1 1. startIndeterminateProgress : removed call to com/jsql/view/swing/tree/model/AbstractNodeModel::setProgressing → NO_COVERAGE
            progressingTreeNodeModel.setProgressing(true);  // Mark the node model as 'loading'
172
            DefaultTreeModel treeModel = (DefaultTreeModel) this.getModel();
173 1 1. startIndeterminateProgress : removed call to javax/swing/tree/DefaultTreeModel::nodeChanged → NO_COVERAGE
            treeModel.nodeChanged(node);  // Update the node
174
        }
175
    }
176
    
177
    public void startProgress(AbstractElementDatabase dataElementDatabase) {
178
        DefaultMutableTreeNode node = this.getTreeNodeModels().get(dataElementDatabase);
179
        // Fix rare #73981
180 1 1. startProgress : negated conditional → NO_COVERAGE
        if (node != null) {
181
            AbstractNodeModel progressingTreeNodeModel = (AbstractNodeModel) node.getUserObject();
182
            // Fix rare Unhandled NullPointerException #66340
183 1 1. startProgress : negated conditional → NO_COVERAGE
            if (progressingTreeNodeModel != null) {
184 1 1. startProgress : removed call to com/jsql/view/swing/tree/model/AbstractNodeModel::setLoading → NO_COVERAGE
                progressingTreeNodeModel.setLoading(true);  // Mark the node model as 'display progress bar'
185
            }
186
            DefaultTreeModel treeModel = (DefaultTreeModel) this.getModel();
187 1 1. startProgress : removed call to javax/swing/tree/DefaultTreeModel::nodeChanged → NO_COVERAGE
            treeModel.nodeChanged(node);  // Update the node
188
        }
189
    }
190
    
191
    public void updateProgress(AbstractElementDatabase dataElementDatabase, int dataCount) {
192
        DefaultMutableTreeNode node = this.getTreeNodeModels().get(dataElementDatabase);
193
        // Fix Report #1368: ignore if no element database, usually for mock (eg. metadata, file, shell, list databases)
194 1 1. updateProgress : negated conditional → NO_COVERAGE
        if (node != null) {
195
            AbstractNodeModel progressingTreeNodeModel = (AbstractNodeModel) node.getUserObject();
196 1 1. updateProgress : removed call to com/jsql/view/swing/tree/model/AbstractNodeModel::setIndexProgress → NO_COVERAGE
            progressingTreeNodeModel.setIndexProgress(dataCount);  // Update the progress value of the model
197
            DefaultTreeModel treeModel = (DefaultTreeModel) this.getModel();
198 1 1. updateProgress : removed call to javax/swing/tree/DefaultTreeModel::nodeChanged → NO_COVERAGE
            treeModel.nodeChanged(node);  // Update the node
199
        }
200
    }
201
    
202
    public final Map<AbstractElementDatabase, DefaultMutableTreeNode> getTreeNodeModels() {
203 1 1. getTreeNodeModels : replaced return value with Collections.emptyMap for com/jsql/view/swing/tree/TreeDatabase::getTreeNodeModels → NO_COVERAGE
        return this.mapNodes;
204
    }
205
}

Mutations

43

1.1
Location : reloadNodes
Killed by : none
negated conditional → NO_COVERAGE

46

1.1
Location : reloadNodes
Killed by : none
removed call to javax/swing/tree/DefaultTreeModel::reload → NO_COVERAGE

47

1.1
Location : reloadNodes
Killed by : none
removed call to com/jsql/view/swing/tree/TreeDatabase::revalidate → NO_COVERAGE

52

1.1
Location : reset
Killed by : none
removed call to java/util/Map::clear → NO_COVERAGE

57

1.1
Location : reset
Killed by : none
removed call to javax/swing/tree/DefaultMutableTreeNode::removeAllChildren → NO_COVERAGE

58

1.1
Location : reset
Killed by : none
removed call to javax/swing/tree/DefaultTreeModel::nodeChanged → NO_COVERAGE

59

1.1
Location : reset
Killed by : none
removed call to javax/swing/tree/DefaultTreeModel::reload → NO_COVERAGE

61

1.1
Location : reset
Killed by : none
removed call to com/jsql/view/swing/tree/TreeDatabase::setRootVisible → NO_COVERAGE

75

1.1
Location : addColumns
Killed by : none
negated conditional → NO_COVERAGE

76

1.1
Location : addColumns
Killed by : none
removed call to javax/swing/tree/DefaultTreeModel::insertNodeInto → NO_COVERAGE

80

1.1
Location : addColumns
Killed by : none
negated conditional → NO_COVERAGE

81

1.1
Location : addColumns
Killed by : none
removed call to com/jsql/view/swing/tree/TreeDatabase::expandPath → NO_COVERAGE

82

1.1
Location : addColumns
Killed by : none
removed call to com/jsql/view/swing/tree/model/AbstractNodeModel::setLoaded → NO_COVERAGE

95

1.1
Location : addDatabases
Killed by : none
removed call to javax/swing/tree/DefaultMutableTreeNode::add → NO_COVERAGE

99

1.1
Location : addDatabases
Killed by : none
removed call to javax/swing/tree/DefaultTreeModel::reload → NO_COVERAGE

102

1.1
Location : addDatabases
Killed by : none
removed call to com/jsql/view/swing/tree/TreeDatabase::expandPath → NO_COVERAGE

103

1.1
Location : addDatabases
Killed by : none
removed call to com/jsql/view/swing/tree/TreeDatabase::setRootVisible → NO_COVERAGE

116

1.1
Location : addTables
Killed by : none
negated conditional → NO_COVERAGE

118

1.1
Location : addTables
Killed by : none
removed call to javax/swing/tree/DefaultTreeModel::insertNodeInto → NO_COVERAGE

124

1.1
Location : addTables
Killed by : none
negated conditional → NO_COVERAGE

125

1.1
Location : addTables
Killed by : none
removed call to com/jsql/view/swing/tree/TreeDatabase::expandPath → NO_COVERAGE

126

1.1
Location : addTables
Killed by : none
removed call to com/jsql/view/swing/tree/model/AbstractNodeModel::setLoaded → NO_COVERAGE

133

1.1
Location : createValuesTab
Killed by : none
negated conditional → NO_COVERAGE

135

1.1
Location : createValuesTab
Killed by : none
removed call to com/jsql/view/swing/tree/model/AbstractNodeModel::setIndexProgress → NO_COVERAGE

136

1.1
Location : createValuesTab
Killed by : none
removed call to com/jsql/view/swing/tree/model/AbstractNodeModel::setRunning → NO_COVERAGE

137

1.1
Location : createValuesTab
Killed by : none
removed call to com/jsql/view/swing/tab/TabResults::addTabValues → NO_COVERAGE

144

1.1
Location : endIndeterminateProgress
Killed by : none
negated conditional → NO_COVERAGE

146

1.1
Location : endIndeterminateProgress
Killed by : none
removed call to com/jsql/view/swing/tree/model/AbstractNodeModel::setProgressing → NO_COVERAGE

147

1.1
Location : endIndeterminateProgress
Killed by : none
removed call to com/jsql/view/swing/tree/model/AbstractNodeModel::setRunning → NO_COVERAGE

149

1.1
Location : endIndeterminateProgress
Killed by : none
removed call to javax/swing/tree/DefaultTreeModel::nodeChanged → NO_COVERAGE

156

1.1
Location : endProgress
Killed by : none
negated conditional → NO_COVERAGE

158

1.1
Location : endProgress
Killed by : none
removed call to com/jsql/view/swing/tree/model/AbstractNodeModel::setLoading → NO_COVERAGE

159

1.1
Location : endProgress
Killed by : none
removed call to com/jsql/view/swing/tree/model/AbstractNodeModel::setRunning → NO_COVERAGE

160

1.1
Location : endProgress
Killed by : none
removed call to com/jsql/view/swing/tree/model/AbstractNodeModel::setIndexProgress → NO_COVERAGE

162

1.1
Location : endProgress
Killed by : none
removed call to javax/swing/tree/DefaultTreeModel::nodeChanged → NO_COVERAGE

169

1.1
Location : startIndeterminateProgress
Killed by : none
negated conditional → NO_COVERAGE

171

1.1
Location : startIndeterminateProgress
Killed by : none
removed call to com/jsql/view/swing/tree/model/AbstractNodeModel::setProgressing → NO_COVERAGE

173

1.1
Location : startIndeterminateProgress
Killed by : none
removed call to javax/swing/tree/DefaultTreeModel::nodeChanged → NO_COVERAGE

180

1.1
Location : startProgress
Killed by : none
negated conditional → NO_COVERAGE

183

1.1
Location : startProgress
Killed by : none
negated conditional → NO_COVERAGE

184

1.1
Location : startProgress
Killed by : none
removed call to com/jsql/view/swing/tree/model/AbstractNodeModel::setLoading → NO_COVERAGE

187

1.1
Location : startProgress
Killed by : none
removed call to javax/swing/tree/DefaultTreeModel::nodeChanged → NO_COVERAGE

194

1.1
Location : updateProgress
Killed by : none
negated conditional → NO_COVERAGE

196

1.1
Location : updateProgress
Killed by : none
removed call to com/jsql/view/swing/tree/model/AbstractNodeModel::setIndexProgress → NO_COVERAGE

198

1.1
Location : updateProgress
Killed by : none
removed call to javax/swing/tree/DefaultTreeModel::nodeChanged → NO_COVERAGE

203

1.1
Location : getTreeNodeModels
Killed by : none
replaced return value with Collections.emptyMap for com/jsql/view/swing/tree/TreeDatabase::getTreeNodeModels → NO_COVERAGE

Active mutators

Tests examined


Report generated by PIT 1.19.1