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

Mutations

40

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

43

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

44

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

49

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

54

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

55

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

56

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

58

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

72

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

73

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

77

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

78

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

79

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

92

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

96

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

99

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

100

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

113

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

115

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

121

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

122

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

123

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

128

1.1
Location : createValuesTab
Killed by : none
removed call to com/jsql/view/swing/panel/split/SplitNS::invokeLaterWithSplitOrientation → NO_COVERAGE

131

1.1
Location : lambda$createValuesTab$1
Killed by : none
negated conditional → NO_COVERAGE

133

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

134

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

135

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

143

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

145

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

146

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

148

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

155

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

157

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

158

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

159

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

161

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

168

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

170

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

172

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

179

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

182

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

183

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

186

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

193

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

195

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

197

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

202

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.22.1