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
        // Report NullPointerException #1683
129
        DefaultMutableTreeNode node = this.getTreeNodeModels().get(table);
130 1 1. createValuesTab : negated conditional → NO_COVERAGE
        if (node != null) {
131
            AbstractNodeModel progressingTreeNodeModel = (AbstractNodeModel) node.getUserObject();
132 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
133 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'
134 1 1. createValuesTab : removed call to com/jsql/view/swing/tab/TabResults::addTabValues → NO_COVERAGE
            MediatorHelper.tabResults().addTabValues(data, columnNames, table);
135
        }
136
    }
137
    
138
    public void endIndeterminateProgress(AbstractElementDatabase dataElementDatabase) {
139
        DefaultMutableTreeNode node = this.getTreeNodeModels().get(dataElementDatabase);
140
        // Fix #1806 : NullPointerException on ...odels().get(dataElementDatabase).getUserObject()
141 1 1. endIndeterminateProgress : negated conditional → NO_COVERAGE
        if (node != null) {
142
            AbstractNodeModel progressingTreeNodeModel = (AbstractNodeModel) node.getUserObject();
143 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'
144 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'
145
            DefaultTreeModel treeModel = (DefaultTreeModel) this.getModel();
146 1 1. endIndeterminateProgress : removed call to javax/swing/tree/DefaultTreeModel::nodeChanged → NO_COVERAGE
            treeModel.nodeChanged(node);  // Update the node
147
        }
148
    }
149
    
150
    public void endProgress(AbstractElementDatabase dataElementDatabase) {
151
        // Report NullPointerException #1671
152
        DefaultMutableTreeNode node = this.getTreeNodeModels().get(dataElementDatabase);
153 1 1. endProgress : negated conditional → NO_COVERAGE
        if (node != null) {
154
            AbstractNodeModel progressingTreeNodeModel = (AbstractNodeModel) node.getUserObject();
155 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'
156 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'
157 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
158
            DefaultTreeModel treeModel = (DefaultTreeModel) this.getModel();
159 1 1. endProgress : removed call to javax/swing/tree/DefaultTreeModel::nodeChanged → NO_COVERAGE
            treeModel.nodeChanged(node);  // Update the node and progress bar
160
        }
161
    }
162
    
163
    public void startIndeterminateProgress(AbstractElementDatabase dataElementDatabase) {
164
        DefaultMutableTreeNode node = this.getTreeNodeModels().get(dataElementDatabase);
165
        // Fix #45540: NullPointerException on node.getUserObject()
166 1 1. startIndeterminateProgress : negated conditional → NO_COVERAGE
        if (node != null) {
167
            AbstractNodeModel progressingTreeNodeModel = (AbstractNodeModel) node.getUserObject();
168 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'
169
            DefaultTreeModel treeModel = (DefaultTreeModel) this.getModel();
170 1 1. startIndeterminateProgress : removed call to javax/swing/tree/DefaultTreeModel::nodeChanged → NO_COVERAGE
            treeModel.nodeChanged(node);  // Update the node
171
        }
172
    }
173
    
174
    public void startProgress(AbstractElementDatabase dataElementDatabase) {
175
        DefaultMutableTreeNode node = this.getTreeNodeModels().get(dataElementDatabase);
176
        // Fix rare #73981
177 1 1. startProgress : negated conditional → NO_COVERAGE
        if (node != null) {
178
            AbstractNodeModel progressingTreeNodeModel = (AbstractNodeModel) node.getUserObject();
179
            // Fix rare Unhandled NullPointerException #66340
180 1 1. startProgress : negated conditional → NO_COVERAGE
            if (progressingTreeNodeModel != null) {
181 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'
182
            }
183
            DefaultTreeModel treeModel = (DefaultTreeModel) this.getModel();
184 1 1. startProgress : removed call to javax/swing/tree/DefaultTreeModel::nodeChanged → NO_COVERAGE
            treeModel.nodeChanged(node);  // Update the node
185
        }
186
    }
187
    
188
    public void updateProgress(AbstractElementDatabase dataElementDatabase, int dataCount) {
189
        DefaultMutableTreeNode node = this.getTreeNodeModels().get(dataElementDatabase);
190
        // Fix Report #1368: ignore if no element database, usually for mock (eg. metadata, file, shell, list databases)
191 1 1. updateProgress : negated conditional → NO_COVERAGE
        if (node != null) {
192
            AbstractNodeModel progressingTreeNodeModel = (AbstractNodeModel) node.getUserObject();
193 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
194
            DefaultTreeModel treeModel = (DefaultTreeModel) this.getModel();
195 1 1. updateProgress : removed call to javax/swing/tree/DefaultTreeModel::nodeChanged → NO_COVERAGE
            treeModel.nodeChanged(node);  // Update the node
196
        }
197
    }
198
    
199
    public final Map<AbstractElementDatabase, DefaultMutableTreeNode> getTreeNodeModels() {
200 1 1. getTreeNodeModels : replaced return value with Collections.emptyMap for com/jsql/view/swing/tree/TreeDatabase::getTreeNodeModels → NO_COVERAGE
        return this.mapNodes;
201
    }
202
}

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

130

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

132

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

133

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

134

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

141

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

143

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

144

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

146

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

153

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

155

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

156

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

157

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

159

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

166

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

168

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

170

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

177

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

180

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

181

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

184

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

191

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

193

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

195

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

200

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