AbstractListTransfertHandler.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.list;
12
13
import com.jsql.util.LogLevelUtil;
14
import org.apache.logging.log4j.LogManager;
15
import org.apache.logging.log4j.Logger;
16
17
import javax.swing.*;
18
import java.awt.*;
19
import java.awt.datatransfer.DataFlavor;
20
import java.awt.datatransfer.StringSelection;
21
import java.awt.datatransfer.Transferable;
22
import java.awt.datatransfer.UnsupportedFlavorException;
23
import java.io.File;
24
import java.io.IOException;
25
import java.util.List;
26
27
/**
28
 * Handler for processing cut/copy/paste/drag/drop action on a JList items.
29
 */
30
public abstract class AbstractListTransfertHandler extends TransferHandler {
31
    
32
    /**
33
     * Log4j logger sent to view.
34
     */
35
    private static final Logger LOGGER = LogManager.getRootLogger();
36
37
    /**
38
     * List of cut/copy/paste/drag/drop items.
39
     */
40
    protected transient List<ItemList> dragPaths = null;
41
    
42
    protected abstract String initializeTransferable();
43
    
44
    protected abstract void parseStringDrop(TransferSupport support, DnDList list, DefaultListModel<ItemList> listModel);
45
    
46
    protected abstract List<Integer> initializeStringPaste(String clipboardText, int selectedIndex, DefaultListModel<ItemList> listModel);
47
    
48
    @Override
49
    public int getSourceActions(JComponent c) {
50 1 1. getSourceActions : replaced int return with 0 for com/jsql/view/swing/list/AbstractListTransfertHandler::getSourceActions → NO_COVERAGE
        return TransferHandler.COPY_OR_MOVE;
51
    }
52
    
53
    @Override
54
    protected Transferable createTransferable(JComponent c) {
55
        
56
        DnDList list = (DnDList) c;
57
        
58
        this.dragPaths = list.getSelectedValuesList();
59
        
60
        var stringTransferable = this.initializeTransferable();
61
62 1 1. createTransferable : replaced return value with null for com/jsql/view/swing/list/AbstractListTransfertHandler::createTransferable → NO_COVERAGE
        return new StringSelection(stringTransferable.trim());
63
    }
64
65
    @SuppressWarnings("unchecked")
66
    @Override
67
    protected void exportDone(JComponent c, Transferable data, int action) {
68 1 1. exportDone : negated conditional → NO_COVERAGE
        if (action == TransferHandler.MOVE) {
69
            
70
            JList<ItemList> list = (JList<ItemList>) c;
71
            DefaultListModel<ItemList> model = (DefaultListModel<ItemList>) list.getModel();
72
            
73
            for (ItemList itemPath: this.dragPaths) {
74
                // Unhandled ArrayIndexOutOfBoundsException #56115 on remove()
75
                try {
76
                    model.remove(model.indexOf(itemPath));
77
                } catch (ArrayIndexOutOfBoundsException e) {
78
                    LOGGER.log(LogLevelUtil.CONSOLE_JAVA, e.getMessage(), e);
79
                }
80
            }
81
            
82
            this.dragPaths = null;
83
        }
84
    }
85
86
    @Override
87
    public boolean canImport(TransferSupport support) {
88 1 1. canImport : replaced boolean return with true for com/jsql/view/swing/list/AbstractListTransfertHandler::canImport → NO_COVERAGE
        return
89 1 1. canImport : negated conditional → NO_COVERAGE
            support.isDataFlavorSupported(DataFlavor.stringFlavor)
90 1 1. canImport : negated conditional → NO_COVERAGE
            || support.isDataFlavorSupported(DataFlavor.javaFileListFlavor);
91
    }
92
93
    @Override
94
    public boolean importData(TransferSupport support) {
95
        
96 1 1. importData : negated conditional → NO_COVERAGE
        if (!this.canImport(support)) {
97 1 1. importData : replaced boolean return with true for com/jsql/view/swing/list/AbstractListTransfertHandler::importData → NO_COVERAGE
            return false;
98
        }
99
100
        DnDList list = (DnDList) support.getComponent();
101
        DefaultListModel<ItemList> listModel = (DefaultListModel<ItemList>) list.getModel();
102
        
103
        //This is a drop
104 1 1. importData : negated conditional → NO_COVERAGE
        if (support.isDrop()) {
105 1 1. importData : negated conditional → NO_COVERAGE
            if (support.isDataFlavorSupported(DataFlavor.stringFlavor)) {
106 1 1. importData : removed call to com/jsql/view/swing/list/AbstractListTransfertHandler::parseStringDrop → NO_COVERAGE
                this.parseStringDrop(support, list, listModel);
107 1 1. importData : negated conditional → NO_COVERAGE
            } else if (support.isDataFlavorSupported(DataFlavor.javaFileListFlavor)) {
108 1 1. importData : removed call to com/jsql/view/swing/list/AbstractListTransfertHandler::parseFileDrop → NO_COVERAGE
                this.parseFileDrop(support, list);
109
            }
110
        } else {
111
            
112
            //This is a paste
113
            var transferableFromClipboard = Toolkit.getDefaultToolkit().getSystemClipboard().getContents(null);
114
            
115 1 1. importData : negated conditional → NO_COVERAGE
            if (transferableFromClipboard != null) {
116 1 1. importData : negated conditional → NO_COVERAGE
                if (transferableFromClipboard.isDataFlavorSupported(DataFlavor.stringFlavor)) {
117 1 1. importData : removed call to com/jsql/view/swing/list/AbstractListTransfertHandler::parseStringPaste → NO_COVERAGE
                    this.parseStringPaste(list, listModel, transferableFromClipboard);
118 1 1. importData : negated conditional → NO_COVERAGE
                } else if (transferableFromClipboard.isDataFlavorSupported(DataFlavor.javaFileListFlavor)) {
119 1 1. importData : removed call to com/jsql/view/swing/list/AbstractListTransfertHandler::parseFilePaste → NO_COVERAGE
                    this.parseFilePaste(list, transferableFromClipboard);
120
                }
121
            }
122
        }
123
124 1 1. importData : replaced boolean return with false for com/jsql/view/swing/list/AbstractListTransfertHandler::importData → NO_COVERAGE
        return true;
125
    }
126
127
    @SuppressWarnings("unchecked")
128
    private void parseFileDrop(TransferSupport support, DnDList list) {
129
        
130
        JList.DropLocation dropLocation = (JList.DropLocation) support.getDropLocation();
131
        int childIndex = dropLocation.getIndex();
132
133
        try {
134 1 1. parseFileDrop : removed call to com/jsql/view/swing/list/DnDList::dropPasteFile → NO_COVERAGE
            list.dropPasteFile(
135
                (List<File>) support.getTransferable().getTransferData(DataFlavor.javaFileListFlavor),
136
                childIndex
137
            );
138
        } catch (UnsupportedFlavorException | IOException e) {
139
            LOGGER.log(LogLevelUtil.CONSOLE_JAVA, e, e);
140
        }
141
    }
142
143
    private void parseStringPaste(DnDList list, DefaultListModel<ItemList> listModel, Transferable transferableFromClipboard) {
144
        try {
145
            String clipboardText = (String) transferableFromClipboard.getTransferData(DataFlavor.stringFlavor);
146
            var selectedIndexPaste = Math.max(list.getSelectedIndex(), 0);
147 1 1. parseStringPaste : removed call to com/jsql/view/swing/list/DnDList::clearSelection → NO_COVERAGE
            list.clearSelection();
148
            List<Integer> selectedIndexes = this.initializeStringPaste(clipboardText, selectedIndexPaste, listModel);
149
            var selectedIndexesPasted = new int[selectedIndexes.size()];
150
            var i = 0;
151
            
152
            for (Integer selectedIndex: selectedIndexes) {
153
                
154
                selectedIndexesPasted[i] = selectedIndex;
155 1 1. parseStringPaste : Changed increment from 1 to -1 → NO_COVERAGE
                i++;
156
            }
157
            
158 1 1. parseStringPaste : removed call to com/jsql/view/swing/list/DnDList::setSelectedIndices → NO_COVERAGE
            list.setSelectedIndices(selectedIndexesPasted);
159 1 1. parseStringPaste : removed call to com/jsql/view/swing/list/DnDList::scrollRectToVisible → NO_COVERAGE
            list.scrollRectToVisible(
160
                list.getCellBounds(
161
                    list.getMinSelectionIndex(),
162
                    list.getMaxSelectionIndex()
163
                )
164
            );
165
        } catch (NullPointerException | UnsupportedFlavorException | IOException e) {
166
            // Fix #8831: Multiple Exception on scrollRectToVisible()
167
            LOGGER.log(LogLevelUtil.CONSOLE_JAVA, e, e);
168
        }
169
    }
170
171
    @SuppressWarnings("unchecked")
172
    private void parseFilePaste(DnDList list, Transferable transferableFromClipboard) {
173
        try {
174
            var selectedIndex = Math.max(list.getSelectedIndex(), 0);
175 1 1. parseFilePaste : removed call to com/jsql/view/swing/list/DnDList::clearSelection → NO_COVERAGE
            list.clearSelection();
176 1 1. parseFilePaste : removed call to com/jsql/view/swing/list/DnDList::dropPasteFile → NO_COVERAGE
            list.dropPasteFile(
177
                (List<File>) transferableFromClipboard.getTransferData(DataFlavor.javaFileListFlavor),
178
                selectedIndex
179
            );
180
        } catch (UnsupportedFlavorException | IOException e) {
181
            LOGGER.log(LogLevelUtil.CONSOLE_JAVA, e, e);
182
        }
183
    }
184
}

Mutations

50

1.1
Location : getSourceActions
Killed by : none
replaced int return with 0 for com/jsql/view/swing/list/AbstractListTransfertHandler::getSourceActions → NO_COVERAGE

62

1.1
Location : createTransferable
Killed by : none
replaced return value with null for com/jsql/view/swing/list/AbstractListTransfertHandler::createTransferable → NO_COVERAGE

68

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

88

1.1
Location : canImport
Killed by : none
replaced boolean return with true for com/jsql/view/swing/list/AbstractListTransfertHandler::canImport → NO_COVERAGE

89

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

90

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

96

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

97

1.1
Location : importData
Killed by : none
replaced boolean return with true for com/jsql/view/swing/list/AbstractListTransfertHandler::importData → NO_COVERAGE

104

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

105

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

106

1.1
Location : importData
Killed by : none
removed call to com/jsql/view/swing/list/AbstractListTransfertHandler::parseStringDrop → NO_COVERAGE

107

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

108

1.1
Location : importData
Killed by : none
removed call to com/jsql/view/swing/list/AbstractListTransfertHandler::parseFileDrop → NO_COVERAGE

115

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

116

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

117

1.1
Location : importData
Killed by : none
removed call to com/jsql/view/swing/list/AbstractListTransfertHandler::parseStringPaste → NO_COVERAGE

118

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

119

1.1
Location : importData
Killed by : none
removed call to com/jsql/view/swing/list/AbstractListTransfertHandler::parseFilePaste → NO_COVERAGE

124

1.1
Location : importData
Killed by : none
replaced boolean return with false for com/jsql/view/swing/list/AbstractListTransfertHandler::importData → NO_COVERAGE

134

1.1
Location : parseFileDrop
Killed by : none
removed call to com/jsql/view/swing/list/DnDList::dropPasteFile → NO_COVERAGE

147

1.1
Location : parseStringPaste
Killed by : none
removed call to com/jsql/view/swing/list/DnDList::clearSelection → NO_COVERAGE

155

1.1
Location : parseStringPaste
Killed by : none
Changed increment from 1 to -1 → NO_COVERAGE

158

1.1
Location : parseStringPaste
Killed by : none
removed call to com/jsql/view/swing/list/DnDList::setSelectedIndices → NO_COVERAGE

159

1.1
Location : parseStringPaste
Killed by : none
removed call to com/jsql/view/swing/list/DnDList::scrollRectToVisible → NO_COVERAGE

175

1.1
Location : parseFilePaste
Killed by : none
removed call to com/jsql/view/swing/list/DnDList::clearSelection → NO_COVERAGE

176

1.1
Location : parseFilePaste
Killed by : none
removed call to com/jsql/view/swing/list/DnDList::dropPasteFile → NO_COVERAGE

Active mutators

Tests examined


Report generated by PIT 1.16.1