CreateAdminPageTab.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.interaction;
12
13
import com.jsql.util.I18nUtil;
14
import com.jsql.util.LogLevelUtil;
15
import com.jsql.view.interaction.InteractionCommand;
16
import com.jsql.view.swing.menubar.JMenuItemWithMargin;
17
import com.jsql.view.swing.scrollpane.LightScrollPane;
18
import com.jsql.view.swing.tab.TabHeader;
19
import com.jsql.view.swing.util.I18nViewUtil;
20
import com.jsql.view.swing.util.MediatorHelper;
21
import com.jsql.view.swing.util.UiUtil;
22
import org.apache.commons.lang3.StringUtils;
23
import org.apache.logging.log4j.LogManager;
24
import org.apache.logging.log4j.Logger;
25
import org.jsoup.Jsoup;
26
import org.jsoup.safety.Safelist;
27
28
import javax.swing.*;
29
import javax.swing.text.DefaultEditorKit;
30
import java.awt.*;
31
import java.awt.datatransfer.StringSelection;
32
import java.awt.event.*;
33
import java.io.IOException;
34
import java.util.EmptyStackException;
35
36
/**
37
 * Create a new tab for an administration webpage.
38
 */
39
public class CreateAdminPageTab extends CreateTabHelper implements InteractionCommand {
40
    
41
    /**
42
     * Log4j logger sent to view.
43
     */
44
    private static final Logger LOGGER = LogManager.getRootLogger();
45
46
    /**
47
     * Url for the administration webpage.
48
     */
49
    private final String url;
50
51
    /**
52
     * @param interactionParams Url of the webpage
53
     */
54
    public CreateAdminPageTab(Object[] interactionParams) {
55
        this.url = (String) interactionParams[0];
56
    }
57
58
    @Override
59
    public void execute() {
60
        
61
        String htmlSource = StringUtils.EMPTY;
62
        
63
        // Fix #4081: SocketTimeoutException on get()
64
        // Fix #44642: NoClassDefFoundError on get()
65
        // Fix #44641: ExceptionInInitializerError on get()
66
        try {
67
            // Previous test for 2xx Success and 3xx Redirection was Header only,
68
            // now get the HTML content.
69
            // Proxy is used by jsoup
70
            htmlSource = Jsoup.clean(
71
                Jsoup.connect(this.url)
72
                    // Prevent exception on UnsupportedMimeTypeException: Unhandled content type. Must be text/*, application/xml, or application/*+xml
73
                    .ignoreContentType(true)
74
                    // Prevent exception on HTTP errors
75
                    .ignoreHttpErrors(true)
76
                    .get()
77
                    .html()
78
                    .replaceAll("<img[^>]*>", StringUtils.EMPTY)
79
                    .replaceAll("<input[^>]*type=\"?hidden\"?[^>]*>", StringUtils.EMPTY)
80
                    .replaceAll("<input[^>]*type=\"?(submit|button)\"?[^>]*>", "<div style=\"background-color:#eeeeee;text-align:center;border:1px solid black;width:100px;\">button</div>")
81
                    .replaceAll("<input[^>]*>", "<div style=\"text-align:center;border:1px solid black;width:100px;\">input</div>"),
82
                Safelist.relaxed()
83
                    .addTags("center", "div", "span")
84
                    .addAttributes(":all", "style")
85
            );
86
        } catch (IOException e) {
87
            LOGGER.log(LogLevelUtil.CONSOLE_ERROR, "Failure opening page: {}", e.getMessage());
88
        } catch (ExceptionInInitializerError | NoClassDefFoundError e) {
89
            LOGGER.log(LogLevelUtil.CONSOLE_JAVA, e, e);
90
        }
91
92
        final var browser = new JTextPane();
93 1 1. execute : removed call to javax/swing/JTextPane::setContentType → NO_COVERAGE
        browser.setContentType("text/html");
94 1 1. execute : removed call to javax/swing/JTextPane::setEditable → NO_COVERAGE
        browser.setEditable(false);
95
        
96
        // Fix #43220: EmptyStackException on setText()
97
        // Fix #94242: IndexOutOfBoundsException on setText()
98
        try {
99 1 1. execute : removed call to javax/swing/JTextPane::setText → NO_COVERAGE
            browser.setText(htmlSource);
100
        } catch (IndexOutOfBoundsException | EmptyStackException e) {
101
            LOGGER.log(LogLevelUtil.CONSOLE_JAVA, e, e);
102
        }
103
104
        final var menu = new JPopupMenu();
105
        
106
        JMenuItem itemCopyUrl = new JMenuItemWithMargin(I18nUtil.valueByKey("CONTEXT_MENU_COPY_PAGE_URL"));
107 1 1. execute : removed call to com/jsql/view/swing/util/I18nViewUtil::addComponentForKey → NO_COVERAGE
        I18nViewUtil.addComponentForKey("CONTEXT_MENU_COPY_PAGE_URL", itemCopyUrl);
108
        
109
        JMenuItem itemCopy = new JMenuItemWithMargin();
110 1 1. execute : removed call to javax/swing/JMenuItem::setAction → NO_COVERAGE
        itemCopy.setAction(browser.getActionMap().get(DefaultEditorKit.copyAction));
111 1 1. execute : removed call to javax/swing/JMenuItem::setAccelerator → NO_COVERAGE
        itemCopy.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_C, InputEvent.CTRL_DOWN_MASK));
112 1 1. execute : removed call to javax/swing/JMenuItem::setMnemonic → NO_COVERAGE
        itemCopy.setMnemonic('C');
113 1 1. execute : removed call to javax/swing/JMenuItem::setText → NO_COVERAGE
        itemCopy.setText(I18nUtil.valueByKey("CONTEXT_MENU_COPY"));
114 1 1. execute : removed call to com/jsql/view/swing/util/I18nViewUtil::addComponentForKey → NO_COVERAGE
        I18nViewUtil.addComponentForKey("CONTEXT_MENU_COPY", itemCopy);
115
        
116
        JMenuItem itemSelectAll = new JMenuItemWithMargin();
117 1 1. execute : removed call to javax/swing/JMenuItem::setAction → NO_COVERAGE
        itemSelectAll.setAction(browser.getActionMap().get(DefaultEditorKit.selectAllAction));
118 1 1. execute : removed call to javax/swing/JMenuItem::setAccelerator → NO_COVERAGE
        itemSelectAll.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_A, InputEvent.CTRL_DOWN_MASK));
119 1 1. execute : removed call to javax/swing/JMenuItem::setText → NO_COVERAGE
        itemSelectAll.setText(I18nUtil.valueByKey("CONTEXT_MENU_SELECT_ALL"));
120 1 1. execute : removed call to com/jsql/view/swing/util/I18nViewUtil::addComponentForKey → NO_COVERAGE
        I18nViewUtil.addComponentForKey("CONTEXT_MENU_SELECT_ALL", itemSelectAll);
121 1 1. execute : removed call to javax/swing/JMenuItem::setMnemonic → NO_COVERAGE
        itemSelectAll.setMnemonic('A');
122
        
123
        menu.add(itemCopyUrl);
124
        menu.add(new JSeparator());
125
        menu.add(itemCopy);
126
        menu.add(itemSelectAll);
127
        
128 1 1. execute : removed call to javax/swing/JPopupMenu::applyComponentOrientation → NO_COVERAGE
        menu.applyComponentOrientation(ComponentOrientation.getOrientation(I18nUtil.getLocaleDefault()));
129
130 1 1. execute : removed call to javax/swing/JMenuItem::addActionListener → NO_COVERAGE
        itemCopyUrl.addActionListener(actionEvent -> {
131
            
132
            var stringSelection = new StringSelection(CreateAdminPageTab.this.url);
133
            var clipboard = Toolkit.getDefaultToolkit().getSystemClipboard();
134 1 1. lambda$execute$0 : removed call to java/awt/datatransfer/Clipboard::setContents → NO_COVERAGE
            clipboard.setContents(stringSelection, null);
135
        });
136
137 2 1. lambda$execute$1 : removed call to javax/swing/JTextPane::selectAll → NO_COVERAGE
2. execute : removed call to javax/swing/JMenuItem::addActionListener → NO_COVERAGE
        itemSelectAll.addActionListener(actionEvent -> browser.selectAll());
138
        
139 1 1. execute : removed call to javax/swing/JTextPane::addFocusListener → NO_COVERAGE
        browser.addFocusListener(new FocusAdapter() {
140
            
141
            @Override
142
            public void focusGained(FocusEvent arg0) {
143 1 1. focusGained : removed call to javax/swing/text/Caret::setVisible → NO_COVERAGE
                browser.getCaret().setVisible(true);
144 1 1. focusGained : removed call to javax/swing/text/Caret::setSelectionVisible → NO_COVERAGE
                browser.getCaret().setSelectionVisible(true);
145
            }
146
        });
147
        
148 1 1. execute : removed call to javax/swing/JTextPane::addMouseListener → NO_COVERAGE
        browser.addMouseListener(new MouseAdapter() {
149
            
150
            @Override
151
            public void mousePressed(MouseEvent evt) {
152
                
153
                browser.requestFocusInWindow();
154
                
155 1 1. mousePressed : negated conditional → NO_COVERAGE
                if (evt.isPopupTrigger()) {
156 1 1. mousePressed : removed call to javax/swing/JPopupMenu::show → NO_COVERAGE
                    menu.show(evt.getComponent(), evt.getX(), evt.getY());
157
                }
158
            }
159
160
            @Override
161
            public void mouseReleased(MouseEvent evt) {
162 1 1. mouseReleased : negated conditional → NO_COVERAGE
                if (evt.isPopupTrigger()) {
163
                    
164
                    // Fix #45348: IllegalComponentStateException on show()
165
                    try {
166 1 1. mouseReleased : removed call to javax/swing/JPopupMenu::show → NO_COVERAGE
                        menu.show(evt.getComponent(), evt.getX(), evt.getY());
167
                    } catch (IllegalComponentStateException e) {
168
                        LOGGER.log(LogLevelUtil.CONSOLE_JAVA, e, e);
169
                    }
170
                    
171 1 1. mouseReleased : removed call to javax/swing/JPopupMenu::setLocation → NO_COVERAGE
                    menu.setLocation(
172 1 1. mouseReleased : negated conditional → NO_COVERAGE
                        ComponentOrientation.RIGHT_TO_LEFT.equals(ComponentOrientation.getOrientation(I18nUtil.getLocaleDefault()))
173 1 1. mouseReleased : Replaced integer subtraction with addition → NO_COVERAGE
                        ? evt.getXOnScreen() - menu.getWidth()
174
                        : evt.getXOnScreen(),
175
                        evt.getYOnScreen()
176
                    );
177
                }
178
            }
179
        });
180
181
        final var scroller = new LightScrollPane(1, 0, 0, 0, browser);
182 1 1. execute : removed call to com/jsql/view/swing/tab/TabResults::addTab → NO_COVERAGE
        MediatorHelper.tabResults().addTab(this.url.replaceAll(".*/", StringUtils.EMPTY) + StringUtils.SPACE, scroller);
183
184
        // Focus on the new tab
185 1 1. execute : removed call to com/jsql/view/swing/tab/TabResults::setSelectedComponent → NO_COVERAGE
        MediatorHelper.tabResults().setSelectedComponent(scroller);
186
187
        // Create a custom tab header with close button
188
        var header = new TabHeader(
189
            this.url.replaceAll(
190
                ".*/",
191
                StringUtils.EMPTY
192
            ),
193
            UiUtil.ICON_ADMIN_SERVER
194
        );
195
196 1 1. execute : removed call to com/jsql/view/swing/tab/TabResults::setToolTipTextAt → NO_COVERAGE
        MediatorHelper.tabResults().setToolTipTextAt(
197
            MediatorHelper.tabResults().indexOfComponent(scroller),
198
            String.format("<html>%s</html>", this.url)
199
        );
200
201
        // Apply the custom header to the tab
202 1 1. execute : removed call to com/jsql/view/swing/tab/TabResults::setTabComponentAt → NO_COVERAGE
        MediatorHelper.tabResults().setTabComponentAt(MediatorHelper.tabResults().indexOfComponent(scroller), header);
203
204
        // Give focus to the admin page
205
        browser.requestFocusInWindow();
206
207
        // Get back to the top
208 1 1. execute : removed call to javax/swing/SwingUtilities::invokeLater → NO_COVERAGE
        SwingUtilities.invokeLater(() ->
209 1 1. lambda$execute$2 : removed call to javax/swing/JViewport::setViewPosition → NO_COVERAGE
            scroller.scrollPane.getViewport().setViewPosition(new Point(0, 0))
210
        );
211
    }
212
}

Mutations

93

1.1
Location : execute
Killed by : none
removed call to javax/swing/JTextPane::setContentType → NO_COVERAGE

94

1.1
Location : execute
Killed by : none
removed call to javax/swing/JTextPane::setEditable → NO_COVERAGE

99

1.1
Location : execute
Killed by : none
removed call to javax/swing/JTextPane::setText → NO_COVERAGE

107

1.1
Location : execute
Killed by : none
removed call to com/jsql/view/swing/util/I18nViewUtil::addComponentForKey → NO_COVERAGE

110

1.1
Location : execute
Killed by : none
removed call to javax/swing/JMenuItem::setAction → NO_COVERAGE

111

1.1
Location : execute
Killed by : none
removed call to javax/swing/JMenuItem::setAccelerator → NO_COVERAGE

112

1.1
Location : execute
Killed by : none
removed call to javax/swing/JMenuItem::setMnemonic → NO_COVERAGE

113

1.1
Location : execute
Killed by : none
removed call to javax/swing/JMenuItem::setText → NO_COVERAGE

114

1.1
Location : execute
Killed by : none
removed call to com/jsql/view/swing/util/I18nViewUtil::addComponentForKey → NO_COVERAGE

117

1.1
Location : execute
Killed by : none
removed call to javax/swing/JMenuItem::setAction → NO_COVERAGE

118

1.1
Location : execute
Killed by : none
removed call to javax/swing/JMenuItem::setAccelerator → NO_COVERAGE

119

1.1
Location : execute
Killed by : none
removed call to javax/swing/JMenuItem::setText → NO_COVERAGE

120

1.1
Location : execute
Killed by : none
removed call to com/jsql/view/swing/util/I18nViewUtil::addComponentForKey → NO_COVERAGE

121

1.1
Location : execute
Killed by : none
removed call to javax/swing/JMenuItem::setMnemonic → NO_COVERAGE

128

1.1
Location : execute
Killed by : none
removed call to javax/swing/JPopupMenu::applyComponentOrientation → NO_COVERAGE

130

1.1
Location : execute
Killed by : none
removed call to javax/swing/JMenuItem::addActionListener → NO_COVERAGE

134

1.1
Location : lambda$execute$0
Killed by : none
removed call to java/awt/datatransfer/Clipboard::setContents → NO_COVERAGE

137

1.1
Location : lambda$execute$1
Killed by : none
removed call to javax/swing/JTextPane::selectAll → NO_COVERAGE

2.2
Location : execute
Killed by : none
removed call to javax/swing/JMenuItem::addActionListener → NO_COVERAGE

139

1.1
Location : execute
Killed by : none
removed call to javax/swing/JTextPane::addFocusListener → NO_COVERAGE

143

1.1
Location : focusGained
Killed by : none
removed call to javax/swing/text/Caret::setVisible → NO_COVERAGE

144

1.1
Location : focusGained
Killed by : none
removed call to javax/swing/text/Caret::setSelectionVisible → NO_COVERAGE

148

1.1
Location : execute
Killed by : none
removed call to javax/swing/JTextPane::addMouseListener → NO_COVERAGE

155

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

156

1.1
Location : mousePressed
Killed by : none
removed call to javax/swing/JPopupMenu::show → NO_COVERAGE

162

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

166

1.1
Location : mouseReleased
Killed by : none
removed call to javax/swing/JPopupMenu::show → NO_COVERAGE

171

1.1
Location : mouseReleased
Killed by : none
removed call to javax/swing/JPopupMenu::setLocation → NO_COVERAGE

172

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

173

1.1
Location : mouseReleased
Killed by : none
Replaced integer subtraction with addition → NO_COVERAGE

182

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

185

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

196

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

202

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

208

1.1
Location : execute
Killed by : none
removed call to javax/swing/SwingUtilities::invokeLater → NO_COVERAGE

209

1.1
Location : lambda$execute$2
Killed by : none
removed call to javax/swing/JViewport::setViewPosition → NO_COVERAGE

Active mutators

Tests examined


Report generated by PIT 1.16.1