JFrameView.java

1
/*******************************************************************************
2
 * Copyhacked (H) 2012-2020.
3
 * This program and the accompanying materials
4
 * are made available under no term at all, use it like
5
 * you want, but share and discuss about it
6
 * every time possible with every body.
7
 * 
8
 * Contributors:
9
 *      ron190 at ymail dot com - initial implementation
10
 ******************************************************************************/
11
package com.jsql.view.swing;
12
13
import com.jsql.model.InjectionModel;
14
import com.jsql.util.I18nUtil;
15
import com.jsql.view.interaction.SubscriberInteraction;
16
import com.jsql.view.swing.action.HotkeyUtil;
17
import com.jsql.view.swing.menubar.Menubar;
18
import com.jsql.view.swing.panel.PanelAddressBar;
19
import com.jsql.view.swing.panel.split.SplitHorizontalTopBottom;
20
import com.jsql.view.swing.shadow.ShadowPopupFactory;
21
import com.jsql.view.swing.shell.AbstractShell;
22
import com.jsql.view.swing.tab.TabManagers;
23
import com.jsql.view.swing.util.MediatorHelper;
24
import com.jsql.view.swing.util.UiUtil;
25
26
import javax.swing.*;
27
import java.awt.*;
28
import java.awt.event.WindowAdapter;
29
import java.awt.event.WindowEvent;
30
import java.math.BigDecimal;
31
import java.math.RoundingMode;
32
import java.util.HashMap;
33
import java.util.Locale;
34
import java.util.Map;
35
import java.util.UUID;
36
import java.util.prefs.Preferences;
37
import java.util.stream.Stream;
38
39
/**
40
 * View in the MVC pattern, defines all the components
41
 * and process actions sent by the model.<br>
42
 * Main groups of components:<br>
43
 * - at the top: textfield inputs,<br>
44
 * - at the center: tree on the left, table on the right,<br>
45
 * - at the bottom: information labels.
46
 */
47
public class JFrameView extends JFrame {
48
49
    // Main center panel
50
    private SplitHorizontalTopBottom splitHorizontalTopBottom;
51
52
    // List of terminal by unique identifier
53
    private final Map<UUID, AbstractShell> mapShells = new HashMap<>();
54
    
55
    private final transient SubscriberInteraction subscriber = new SubscriberInteraction("com.jsql.view.swing.interaction");
56
    
57
    // Build the GUI: add app icon, tree icons, the 3 main panels
58
    public JFrameView() {
59
        
60
        super("jSQL Injection");
61
        
62 1 1. <init> : removed call to com/jsql/view/swing/util/MediatorHelper::register → NO_COVERAGE
        MediatorHelper.register(this);
63
64
        // Load UI before any component
65 1 1. <init> : removed call to com/jsql/view/swing/util/UiUtil::prepareGUI → NO_COVERAGE
        UiUtil.prepareGUI();
66 1 1. <init> : removed call to com/jsql/view/swing/shadow/ShadowPopupFactory::install → NO_COVERAGE
        ShadowPopupFactory.install();
67
        
68 1 1. <init> : removed call to com/jsql/view/swing/JFrameView::initializePaneComponents → NO_COVERAGE
        this.initializePaneComponents();
69 1 1. <init> : removed call to com/jsql/view/swing/JFrameView::initializeWindow → NO_COVERAGE
        this.initializeWindow();
70 1 1. <init> : removed call to com/jsql/view/swing/JFrameView::initializeShortcuts → NO_COVERAGE
        this.initializeShortcuts();
71
    }
72
73
    private void initializeWindow() {
74
        
75
        // Define a small and large app icon
76 1 1. initializeWindow : removed call to com/jsql/view/swing/JFrameView::setIconImages → NO_COVERAGE
        this.setIconImages(UiUtil.getIcons());
77
78 1 1. initializeWindow : removed call to com/jsql/view/swing/JFrameView::addWindowListener → NO_COVERAGE
        this.addWindowListener(new WindowAdapter() {
79
            
80
            @Override
81
            public void windowOpened(WindowEvent event) {
82
                
83 1 1. windowOpened : removed call to java/awt/event/WindowAdapter::windowOpened → NO_COVERAGE
                super.windowOpened(event);
84
                
85
                var preferences = Preferences.userRoot().node(InjectionModel.class.getName());
86
                var horizontalTopBottomSplitter = preferences.getDouble(SplitHorizontalTopBottom.getNameHSplitpane(), 0.75);
87
                
88 4 1. windowOpened : changed conditional boundary → NO_COVERAGE
2. windowOpened : changed conditional boundary → NO_COVERAGE
3. windowOpened : negated conditional → NO_COVERAGE
4. windowOpened : negated conditional → NO_COVERAGE
                if (!(0.0 <= horizontalTopBottomSplitter && horizontalTopBottomSplitter <= 1.0)) {
89
                    
90
                    horizontalTopBottomSplitter = 0.75;
91
                }
92
93 1 1. windowOpened : removed call to com/jsql/view/swing/panel/split/SplitHorizontalTopBottom::setDividerLocation → NO_COVERAGE
                JFrameView.this.splitHorizontalTopBottom.setDividerLocation(horizontalTopBottomSplitter);
94
            }
95
            
96
            @Override
97
            public void windowClosing(WindowEvent e) {
98
                
99
                var preferences = Preferences.userRoot().node(InjectionModel.class.getName());
100 1 1. windowClosing : removed call to java/util/prefs/Preferences::putInt → NO_COVERAGE
                preferences.putInt(
101
                    SplitHorizontalTopBottom.getNameVSplitpane(),
102
                    JFrameView.this.splitHorizontalTopBottom.getSplitVerticalLeftRight().getDividerLocation()
103
                );
104
                
105
                var roundDecimal = BigDecimal.valueOf(
106 1 1. windowClosing : Replaced double multiplication with division → NO_COVERAGE
                    JFrameView.this.splitHorizontalTopBottom.getDividerLocation() * 100.0
107 2 1. windowClosing : Replaced double division with multiplication → NO_COVERAGE
2. windowClosing : Replaced double division with multiplication → NO_COVERAGE
                    / JFrameView.this.splitHorizontalTopBottom.getHeight()
108
                    / 100
109
                );
110
                roundDecimal = roundDecimal.setScale(2, RoundingMode.HALF_UP);
111
                
112
                // Divider location change when window is maximized, we can't save getDividerLocation()
113 1 1. windowClosing : removed call to java/util/prefs/Preferences::putDouble → NO_COVERAGE
                preferences.putDouble(
114
                    SplitHorizontalTopBottom.getNameHSplitpane(),
115
                    // Fix scale
116 1 1. windowClosing : Replaced double subtraction with addition → NO_COVERAGE
                    roundDecimal.doubleValue() - 0.01
117
                );
118
                
119 1 1. windowClosing : removed call to java/util/prefs/Preferences::putBoolean → NO_COVERAGE
                preferences.putBoolean(UiUtil.BINARY_VISIBLE, false);
120 1 1. windowClosing : removed call to java/util/prefs/Preferences::putBoolean → NO_COVERAGE
                preferences.putBoolean(UiUtil.CHUNK_VISIBLE, false);
121 1 1. windowClosing : removed call to java/util/prefs/Preferences::putBoolean → NO_COVERAGE
                preferences.putBoolean(UiUtil.NETWORK_VISIBLE, false);
122 1 1. windowClosing : removed call to java/util/prefs/Preferences::putBoolean → NO_COVERAGE
                preferences.putBoolean(UiUtil.JAVA_VISIBLE, false);
123
                
124 2 1. windowClosing : changed conditional boundary → NO_COVERAGE
2. windowClosing : negated conditional → NO_COVERAGE
                for (var i = 0 ; i < MediatorHelper.tabConsoles().getTabCount() ; i++) {
125
                    
126 1 1. windowClosing : negated conditional → NO_COVERAGE
                    if ("CONSOLE_BINARY_LABEL".equals(MediatorHelper.tabConsoles().getTabComponentAt(i).getName())) {
127
                        
128 1 1. windowClosing : removed call to java/util/prefs/Preferences::putBoolean → NO_COVERAGE
                        preferences.putBoolean(UiUtil.BINARY_VISIBLE, true);
129
                        
130 1 1. windowClosing : negated conditional → NO_COVERAGE
                    } else if ("CONSOLE_CHUNK_LABEL".equals(MediatorHelper.tabConsoles().getTabComponentAt(i).getName())) {
131
                        
132 1 1. windowClosing : removed call to java/util/prefs/Preferences::putBoolean → NO_COVERAGE
                        preferences.putBoolean(UiUtil.CHUNK_VISIBLE, true);
133
                        
134 1 1. windowClosing : negated conditional → NO_COVERAGE
                    } else if ("CONSOLE_NETWORK_LABEL".equals(MediatorHelper.tabConsoles().getTabComponentAt(i).getName())) {
135
                        
136 1 1. windowClosing : removed call to java/util/prefs/Preferences::putBoolean → NO_COVERAGE
                        preferences.putBoolean(UiUtil.NETWORK_VISIBLE, true);
137
                        
138 1 1. windowClosing : negated conditional → NO_COVERAGE
                    } else if ("CONSOLE_JAVA_LABEL".equals(MediatorHelper.tabConsoles().getTabComponentAt(i).getName())) {
139
                        
140 1 1. windowClosing : removed call to java/util/prefs/Preferences::putBoolean → NO_COVERAGE
                        preferences.putBoolean(UiUtil.JAVA_VISIBLE, true);
141
                    }
142
                }
143
            }
144
        });
145
        
146
        // Size of window
147 1 1. initializeWindow : removed call to com/jsql/view/swing/JFrameView::setSize → NO_COVERAGE
        this.setSize(1024, 768);
148 1 1. initializeWindow : removed call to com/jsql/view/swing/JFrameView::setVisible → NO_COVERAGE
        this.setVisible(true);
149
150
        // Center the window
151 1 1. initializeWindow : removed call to com/jsql/view/swing/JFrameView::setLocationRelativeTo → NO_COVERAGE
        this.setLocationRelativeTo(null);
152
        
153 1 1. initializeWindow : removed call to com/jsql/view/swing/JFrameView::setVisible → NO_COVERAGE
        this.setVisible(true);
154 1 1. initializeWindow : removed call to com/jsql/view/swing/JFrameView::setDefaultCloseOperation → NO_COVERAGE
        this.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
155
        
156
        MediatorHelper.panelAddressBar().getTextFieldAddress().requestFocusInWindow();
157
    }
158
159
    private void initializeShortcuts() {
160
        
161
        // Define the keyword shortcuts for tabs #Need to work even if the focus is not on tabs
162 1 1. initializeShortcuts : removed call to com/jsql/view/swing/action/HotkeyUtil::addShortcut → NO_COVERAGE
        HotkeyUtil.addShortcut(this.getRootPane(), MediatorHelper.tabResults());
163 1 1. initializeShortcuts : removed call to com/jsql/view/swing/action/HotkeyUtil::addTextFieldShortcutSelectAll → NO_COVERAGE
        HotkeyUtil.addTextFieldShortcutSelectAll();
164
    }
165
166
    private void initializePaneComponents() {
167
        
168
        // Save controller
169
        var menubar = new Menubar();
170 1 1. initializePaneComponents : removed call to com/jsql/view/swing/JFrameView::setJMenuBar → NO_COVERAGE
        this.setJMenuBar(menubar);
171 1 1. initializePaneComponents : removed call to com/jsql/view/swing/util/MediatorHelper::register → NO_COVERAGE
        MediatorHelper.register(menubar);
172
        
173
        // Define the default panel: each component on a vertical line
174 1 1. initializePaneComponents : removed call to java/awt/Container::setLayout → NO_COVERAGE
        this.getContentPane().setLayout(new BoxLayout(this.getContentPane(), BoxLayout.PAGE_AXIS));
175
176
        // Main panel for tree and tables in the middle
177
        // Set proxy tabs dependency
178
        var mainPanel = new JPanel(new GridLayout(1, 0));
179
        this.splitHorizontalTopBottom = new SplitHorizontalTopBottom();
180
        mainPanel.add(this.splitHorizontalTopBottom);
181
182
        var panelAddressBar = new PanelAddressBar();  // Textfields at the top
183
        JTabbedPane tabManagers = new TabManagers();  // Tab manager use proxy tabs dependency
184
185
        this.add(tabManagers);
186
        this.add(panelAddressBar);
187 1 1. initializePaneComponents : removed call to com/jsql/view/swing/util/MediatorHelper::register → NO_COVERAGE
        MediatorHelper.register(panelAddressBar);
188
189
        this.add(mainPanel);
190
        
191 1 1. initializePaneComponents : removed call to com/jsql/view/swing/menubar/Menubar::switchLocale → NO_COVERAGE
        menubar.switchLocale(Locale.ENGLISH, I18nUtil.getLocaleDefault(), true);
192
    }
193
194
    // Empty the interface
195
    public void resetInterface() {
196
        
197 1 1. resetInterface : removed call to com/jsql/view/swing/panel/address/AddressMenuBar::reset → NO_COVERAGE
        MediatorHelper.panelAddressBar().getAddressMenuBar().reset();
198
        
199 1 1. resetInterface : removed call to java/util/Map::clear → NO_COVERAGE
        MediatorHelper.treeDatabase().getTreeNodeModels().clear();
200 1 1. resetInterface : removed call to java/util/Map::clear → NO_COVERAGE
        this.mapShells.clear();
201
        
202 1 1. resetInterface : removed call to com/jsql/view/swing/panel/PanelConsoles::reset → NO_COVERAGE
        MediatorHelper.panelConsoles().reset();
203 1 1. resetInterface : removed call to com/jsql/view/swing/tree/TreeDatabase::reset → NO_COVERAGE
        MediatorHelper.treeDatabase().reset();
204
        
205 2 1. resetInterface : changed conditional boundary → NO_COVERAGE
2. resetInterface : negated conditional → NO_COVERAGE
        for (var i = 0 ; i < MediatorHelper.tabConsoles().getTabCount() ; i++) {
206
            
207
            var tabComponent = MediatorHelper.tabConsoles().getTabComponentAt(i);
208 1 1. resetInterface : negated conditional → NO_COVERAGE
            if (tabComponent != null) {
209
                
210 1 1. resetInterface : removed call to java/awt/Component::setFont → NO_COVERAGE
                tabComponent.setFont(tabComponent.getFont().deriveFont(Font.PLAIN));
211
            }
212
        }
213
        
214
        Stream.of(
215
            MediatorHelper.managerUpload(),
216
            MediatorHelper.managerFile(),
217
            MediatorHelper.managerWebshell(),
218
            MediatorHelper.managerSqlshell()
219
        )
220 1 1. resetInterface : removed call to java/util/stream/Stream::forEach → NO_COVERAGE
        .forEach(managerList -> {
221
            
222 1 1. lambda$resetInterface$0 : removed call to com/jsql/view/swing/manager/AbstractManagerList::setButtonEnable → NO_COVERAGE
            managerList.setButtonEnable(false);
223 1 1. lambda$resetInterface$0 : removed call to com/jsql/view/swing/manager/AbstractManagerList::changePrivilegeIcon → NO_COVERAGE
            managerList.changePrivilegeIcon(UiUtil.ICON_SQUARE_GREY);
224
        });
225
    }
226
    
227
    
228
    // Getters and setters
229
230
    /**
231
     * Get list of terminal by unique identifier.
232
     * @return Map of key/value UUID => Terminal
233
     */
234
    public final Map<UUID, AbstractShell> getConsoles() {
235 1 1. getConsoles : replaced return value with Collections.emptyMap for com/jsql/view/swing/JFrameView::getConsoles → NO_COVERAGE
        return this.mapShells;
236
    }
237
238
    public SubscriberInteraction getSubscriber() {
239 1 1. getSubscriber : replaced return value with null for com/jsql/view/swing/JFrameView::getSubscriber → NO_COVERAGE
        return this.subscriber;
240
    }
241
242
    public SplitHorizontalTopBottom getSplitHorizontalTopBottom() {
243 1 1. getSplitHorizontalTopBottom : replaced return value with null for com/jsql/view/swing/JFrameView::getSplitHorizontalTopBottom → NO_COVERAGE
        return this.splitHorizontalTopBottom;
244
    }
245
}

Mutations

62

1.1
Location : <init>
Killed by : none
removed call to com/jsql/view/swing/util/MediatorHelper::register → NO_COVERAGE

65

1.1
Location : <init>
Killed by : none
removed call to com/jsql/view/swing/util/UiUtil::prepareGUI → NO_COVERAGE

66

1.1
Location : <init>
Killed by : none
removed call to com/jsql/view/swing/shadow/ShadowPopupFactory::install → NO_COVERAGE

68

1.1
Location : <init>
Killed by : none
removed call to com/jsql/view/swing/JFrameView::initializePaneComponents → NO_COVERAGE

69

1.1
Location : <init>
Killed by : none
removed call to com/jsql/view/swing/JFrameView::initializeWindow → NO_COVERAGE

70

1.1
Location : <init>
Killed by : none
removed call to com/jsql/view/swing/JFrameView::initializeShortcuts → NO_COVERAGE

76

1.1
Location : initializeWindow
Killed by : none
removed call to com/jsql/view/swing/JFrameView::setIconImages → NO_COVERAGE

78

1.1
Location : initializeWindow
Killed by : none
removed call to com/jsql/view/swing/JFrameView::addWindowListener → NO_COVERAGE

83

1.1
Location : windowOpened
Killed by : none
removed call to java/awt/event/WindowAdapter::windowOpened → NO_COVERAGE

88

1.1
Location : windowOpened
Killed by : none
changed conditional boundary → NO_COVERAGE

2.2
Location : windowOpened
Killed by : none
changed conditional boundary → NO_COVERAGE

3.3
Location : windowOpened
Killed by : none
negated conditional → NO_COVERAGE

4.4
Location : windowOpened
Killed by : none
negated conditional → NO_COVERAGE

93

1.1
Location : windowOpened
Killed by : none
removed call to com/jsql/view/swing/panel/split/SplitHorizontalTopBottom::setDividerLocation → NO_COVERAGE

100

1.1
Location : windowClosing
Killed by : none
removed call to java/util/prefs/Preferences::putInt → NO_COVERAGE

106

1.1
Location : windowClosing
Killed by : none
Replaced double multiplication with division → NO_COVERAGE

107

1.1
Location : windowClosing
Killed by : none
Replaced double division with multiplication → NO_COVERAGE

2.2
Location : windowClosing
Killed by : none
Replaced double division with multiplication → NO_COVERAGE

113

1.1
Location : windowClosing
Killed by : none
removed call to java/util/prefs/Preferences::putDouble → NO_COVERAGE

116

1.1
Location : windowClosing
Killed by : none
Replaced double subtraction with addition → NO_COVERAGE

119

1.1
Location : windowClosing
Killed by : none
removed call to java/util/prefs/Preferences::putBoolean → NO_COVERAGE

120

1.1
Location : windowClosing
Killed by : none
removed call to java/util/prefs/Preferences::putBoolean → NO_COVERAGE

121

1.1
Location : windowClosing
Killed by : none
removed call to java/util/prefs/Preferences::putBoolean → NO_COVERAGE

122

1.1
Location : windowClosing
Killed by : none
removed call to java/util/prefs/Preferences::putBoolean → NO_COVERAGE

124

1.1
Location : windowClosing
Killed by : none
changed conditional boundary → NO_COVERAGE

2.2
Location : windowClosing
Killed by : none
negated conditional → NO_COVERAGE

126

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

128

1.1
Location : windowClosing
Killed by : none
removed call to java/util/prefs/Preferences::putBoolean → NO_COVERAGE

130

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

132

1.1
Location : windowClosing
Killed by : none
removed call to java/util/prefs/Preferences::putBoolean → NO_COVERAGE

134

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

136

1.1
Location : windowClosing
Killed by : none
removed call to java/util/prefs/Preferences::putBoolean → NO_COVERAGE

138

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

140

1.1
Location : windowClosing
Killed by : none
removed call to java/util/prefs/Preferences::putBoolean → NO_COVERAGE

147

1.1
Location : initializeWindow
Killed by : none
removed call to com/jsql/view/swing/JFrameView::setSize → NO_COVERAGE

148

1.1
Location : initializeWindow
Killed by : none
removed call to com/jsql/view/swing/JFrameView::setVisible → NO_COVERAGE

151

1.1
Location : initializeWindow
Killed by : none
removed call to com/jsql/view/swing/JFrameView::setLocationRelativeTo → NO_COVERAGE

153

1.1
Location : initializeWindow
Killed by : none
removed call to com/jsql/view/swing/JFrameView::setVisible → NO_COVERAGE

154

1.1
Location : initializeWindow
Killed by : none
removed call to com/jsql/view/swing/JFrameView::setDefaultCloseOperation → NO_COVERAGE

162

1.1
Location : initializeShortcuts
Killed by : none
removed call to com/jsql/view/swing/action/HotkeyUtil::addShortcut → NO_COVERAGE

163

1.1
Location : initializeShortcuts
Killed by : none
removed call to com/jsql/view/swing/action/HotkeyUtil::addTextFieldShortcutSelectAll → NO_COVERAGE

170

1.1
Location : initializePaneComponents
Killed by : none
removed call to com/jsql/view/swing/JFrameView::setJMenuBar → NO_COVERAGE

171

1.1
Location : initializePaneComponents
Killed by : none
removed call to com/jsql/view/swing/util/MediatorHelper::register → NO_COVERAGE

174

1.1
Location : initializePaneComponents
Killed by : none
removed call to java/awt/Container::setLayout → NO_COVERAGE

187

1.1
Location : initializePaneComponents
Killed by : none
removed call to com/jsql/view/swing/util/MediatorHelper::register → NO_COVERAGE

191

1.1
Location : initializePaneComponents
Killed by : none
removed call to com/jsql/view/swing/menubar/Menubar::switchLocale → NO_COVERAGE

197

1.1
Location : resetInterface
Killed by : none
removed call to com/jsql/view/swing/panel/address/AddressMenuBar::reset → NO_COVERAGE

199

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

200

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

202

1.1
Location : resetInterface
Killed by : none
removed call to com/jsql/view/swing/panel/PanelConsoles::reset → NO_COVERAGE

203

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

205

1.1
Location : resetInterface
Killed by : none
changed conditional boundary → NO_COVERAGE

2.2
Location : resetInterface
Killed by : none
negated conditional → NO_COVERAGE

208

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

210

1.1
Location : resetInterface
Killed by : none
removed call to java/awt/Component::setFont → NO_COVERAGE

220

1.1
Location : resetInterface
Killed by : none
removed call to java/util/stream/Stream::forEach → NO_COVERAGE

222

1.1
Location : lambda$resetInterface$0
Killed by : none
removed call to com/jsql/view/swing/manager/AbstractManagerList::setButtonEnable → NO_COVERAGE

223

1.1
Location : lambda$resetInterface$0
Killed by : none
removed call to com/jsql/view/swing/manager/AbstractManagerList::changePrivilegeIcon → NO_COVERAGE

235

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

239

1.1
Location : getSubscriber
Killed by : none
replaced return value with null for com/jsql/view/swing/JFrameView::getSubscriber → NO_COVERAGE

243

1.1
Location : getSplitHorizontalTopBottom
Killed by : none
replaced return value with null for com/jsql/view/swing/JFrameView::getSplitHorizontalTopBottom → NO_COVERAGE

Active mutators

Tests examined


Report generated by PIT 1.16.1