001/**
002 * Copyright (c) 2004-2011 QOS.ch
003 * All rights reserved.
004 *
005 * Permission is hereby granted, free  of charge, to any person obtaining
006 * a  copy  of this  software  and  associated  documentation files  (the
007 * "Software"), to  deal in  the Software without  restriction, including
008 * without limitation  the rights to  use, copy, modify,  merge, publish,
009 * distribute,  sublicense, and/or sell  copies of  the Software,  and to
010 * permit persons to whom the Software  is furnished to do so, subject to
011 * the following conditions:
012 *
013 * The  above  copyright  notice  and  this permission  notice  shall  be
014 * included in all copies or substantial portions of the Software.
015 *
016 * THE  SOFTWARE IS  PROVIDED  "AS  IS", WITHOUT  WARRANTY  OF ANY  KIND,
017 * EXPRESS OR  IMPLIED, INCLUDING  BUT NOT LIMITED  TO THE  WARRANTIES OF
018 * MERCHANTABILITY,    FITNESS    FOR    A   PARTICULAR    PURPOSE    AND
019 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
020 * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
021 * OF CONTRACT, TORT OR OTHERWISE,  ARISING FROM, OUT OF OR IN CONNECTION
022 * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
023 *
024 */
025package org.slf4j.migrator.internal;
026
027import java.awt.event.ActionEvent;
028import java.awt.event.ActionListener;
029import java.io.File;
030import java.util.ArrayList;
031import java.util.List;
032
033import javax.swing.ButtonGroup;
034import javax.swing.JButton;
035import javax.swing.JCheckBox;
036import javax.swing.JFileChooser;
037import javax.swing.JFrame;
038import javax.swing.JLabel;
039import javax.swing.JOptionPane;
040import javax.swing.JProgressBar;
041import javax.swing.JRadioButton;
042import javax.swing.JTextField;
043import javax.swing.SpringLayout;
044import javax.swing.WindowConstants;
045
046import org.slf4j.migrator.Constant;
047import org.slf4j.migrator.helper.SpringLayoutHelper;
048
049public class MigratorFrame extends JFrame implements ActionListener {
050    private static final long serialVersionUID = 1L;
051
052    private static final int BASIC_PADDING = 10;
053    private static final int FOLDER_COLUMNS = 40;
054    private static final String MIGRATE_COMMAND = "MIGRATE_COMMAND";
055    private static final String BROWSE_COMMAND = "BROWSE_COMMAND";
056    static final String EXIT_COMMAND = "EXIT_COMMAND";
057
058    static final int X_SIZE = 700;
059    static final int Y_SIZE = 400;
060
061    private final SpringLayout layoutManager = new SpringLayout();
062    private final SpringLayoutHelper slh = new SpringLayoutHelper(layoutManager, BASIC_PADDING);
063
064    private JLabel migrationLabel;
065
066    private JRadioButton radioLog4j;
067    private JRadioButton radioJCL;
068    private JRadioButton radioJUL;
069    private ButtonGroup buttonGroup;
070
071    private JTextField folderTextField;
072    private JLabel warningLabel;
073    JButton migrateButton;
074    private JButton browseButton;
075    private JLabel folderLabel;
076
077    private JCheckBox awareCheckBox;
078    private JLabel awareLabel;
079
080    JLabel otherLabel;
081    JProgressBar progressBar;
082    private JFileChooser fileChooser;
083
084    public MigratorFrame() {
085        super();
086        initGUI();
087    }
088
089    private void initGUI() {
090        try {
091            setDefaultCloseOperation(WindowConstants.DISPOSE_ON_CLOSE);
092            getContentPane().setLayout(layoutManager);
093            this.setTitle("SLF4J migrator");
094
095            createComponents();
096            constrainAll();
097            addAllComponentsToContextPane();
098            pack();
099            this.setSize(700, 400);
100        } catch (Exception e) {
101            e.printStackTrace();
102        }
103    }
104
105    private void createComponents() {
106        createMigrationLabel();
107        createRadioJCL();
108        createRadioLog4j();
109        createRadioJUL();
110        createButtonGroup();
111        createFolderLabel();
112        createFolderTextField();
113        createBrowseButton();
114        createMigrateButton();
115        createAwareCheckbox();
116        createAwareLabel();
117        createWarningLabel();
118        createFileChooser();
119
120        otherLabel = new JLabel();
121        otherLabel.setText("");
122        createProgressBar();
123
124    }
125
126    /**
127     * 
128     */
129    private void constrainAll() {
130
131        // constraints migration label
132        layoutManager.putConstraint(SpringLayout.WEST, migrationLabel, BASIC_PADDING, SpringLayout.EAST, this);
133
134        layoutManager.putConstraint(SpringLayout.NORTH, migrationLabel, BASIC_PADDING, SpringLayout.NORTH, this);
135
136        slh.placeToTheRight(migrationLabel, radioJCL, BASIC_PADDING, -BASIC_PADDING / 2);
137        slh.placeBelow(radioJCL, radioLog4j, 0, 0);
138
139        slh.placeBelow(radioLog4j, radioJUL, 0, 0);
140
141        slh.placeBelow(migrationLabel, folderLabel, 0, BASIC_PADDING * 6);
142        slh.placeToTheRight(folderLabel, folderTextField);
143        slh.placeToTheRight(folderTextField, browseButton, BASIC_PADDING, -BASIC_PADDING / 2);
144
145        slh.placeBelow(folderLabel, warningLabel, 0, BASIC_PADDING * 3);
146
147        slh.placeBelow(warningLabel, awareCheckBox, 0, (int) (BASIC_PADDING * 1.5));
148        slh.placeToTheRight(awareCheckBox, awareLabel);
149
150        slh.placeBelow(awareCheckBox, migrateButton, 0, BASIC_PADDING * 3);
151
152        slh.placeBelow(migrateButton, otherLabel, 0, BASIC_PADDING * 2);
153
154        slh.placeBelow(otherLabel, progressBar, 0, BASIC_PADDING);
155    }
156
157    private void addAllComponentsToContextPane() {
158        getContentPane().add(migrationLabel);
159        getContentPane().add(radioJCL);
160        getContentPane().add(radioLog4j);
161        getContentPane().add(radioJUL);
162
163        getContentPane().add(folderLabel);
164        getContentPane().add(folderTextField);
165        getContentPane().add(browseButton);
166        getContentPane().add(migrateButton);
167
168        getContentPane().add(awareCheckBox);
169        getContentPane().add(awareLabel);
170
171        getContentPane().add(warningLabel);
172
173        getContentPane().add(otherLabel);
174        getContentPane().add(progressBar);
175    }
176
177    private void createButtonGroup() {
178        buttonGroup = new ButtonGroup();
179        buttonGroup.add(radioJCL);
180        buttonGroup.add(radioLog4j);
181        buttonGroup.add(radioJUL);
182    }
183
184    private void createMigrationLabel() {
185        migrationLabel = new JLabel();
186        migrationLabel.setText("Migration Type");
187    }
188
189    private void createRadioJCL() {
190        radioJCL = new JRadioButton();
191        radioJCL.setText("from Jakarta Commons Logging to SLF4J");
192        radioJCL.setToolTipText("Select this button if you wish to migrate a Java project using Jakarta Commons Logging to use SLF4J.");
193    }
194
195    private void createRadioLog4j() {
196        radioLog4j = new JRadioButton();
197        radioLog4j.setText("from log4j to SLF4J ");
198        radioLog4j.setToolTipText("Select this button if you wish to migrate a Java project using log4j to use SLF4J.");
199    }
200
201    private void createRadioJUL() {
202        radioJUL = new JRadioButton();
203        radioJUL.setText("from JUL to SLF4J ");
204        radioJUL.setToolTipText("Select this button if you wish to migrate a Java project using java.utl.logging (JUL) to use SLF4J.");
205    }
206
207    private void createFolderLabel() {
208        folderLabel = new JLabel();
209        folderLabel.setText("Project Directory");
210    }
211
212    private void createFolderTextField() {
213        folderTextField = new JTextField();
214        folderTextField.setColumns(FOLDER_COLUMNS);
215    }
216
217    private void createBrowseButton() {
218        browseButton = new JButton();
219        browseButton.setText("Browse");
220        browseButton.addActionListener(this);
221        browseButton.setActionCommand(BROWSE_COMMAND);
222        browseButton.setToolTipText("Click this button to browse the file systems on your computer.");
223    }
224
225    private void createAwareCheckbox() {
226        awareCheckBox = new JCheckBox();
227        awareCheckBox.setToolTipText("<html><p>Check this box of you understand that the migration tool<p>will <b>not</b> backup your Java source files.</html>");
228    }
229
230    private void createAwareLabel() {
231        awareLabel = new JLabel();
232        awareLabel.setText("<html>" + "<p>I am aware that this tool will directly modify all Java source files"
233                        + "<p>in the selected folder without creating backup files." + "</html>");
234    }
235
236    private void createWarningLabel() {
237        warningLabel = new JLabel();
238        warningLabel.setText("<html>" + "<p><span color=\"red\">WARNING:</span> This SLF4J migration tool will directly modify all Java source files"
239                        + "<p>in the selected project folder without creating a backup of the original files." + "</html>");
240    }
241
242    private void createMigrateButton() {
243        migrateButton = new JButton();
244        migrateButton.setText("Migrate Project to SLF4J");
245        migrateButton.setToolTipText("Click this button to initiate migration of your project.");
246        migrateButton.addActionListener(this);
247        migrateButton.setActionCommand(MIGRATE_COMMAND);
248    }
249
250    private void createFileChooser() {
251        fileChooser = new JFileChooser();
252        fileChooser.setDialogTitle("Source folder selector");
253        fileChooser.setFileSelectionMode(JFileChooser.DIRECTORIES_ONLY);
254    }
255
256    private void createProgressBar() {
257        progressBar = new JProgressBar(0, 1);
258        progressBar.setPreferredSize(new java.awt.Dimension((int) (X_SIZE * 0.8), 5));
259        progressBar.setVisible(false);
260    }
261
262    public void disableInput() {
263        radioJCL.setEnabled(false);
264        radioLog4j.setEnabled(false);
265
266        browseButton.setEnabled(false);
267
268        folderTextField.setEnabled(false);
269        awareCheckBox.setEnabled(false);
270        migrateButton.setText("Migration in progress");
271        migrateButton.setEnabled(false);
272
273    }
274
275    public void actionPerformed(ActionEvent e) {
276
277        if (MIGRATE_COMMAND.equals(e.getActionCommand())) {
278
279            List<String> errorList = doSanityAnalysis();
280            if (errorList.size() > 0) {
281                showDialogBox(errorList);
282            } else {
283
284                File projectFolder = new File(folderTextField.getText());
285                int conversionType;
286                if (radioJCL.isSelected()) {
287                    conversionType = Constant.JCL_TO_SLF4J;
288                } else if (radioLog4j.isSelected()) {
289                    conversionType = Constant.LOG4J_TO_SLF4J;
290                } else if (radioJUL.isSelected()) {
291                    conversionType = Constant.JUL_TO_SLF4J;
292                } else {
293                    // we cannot possibly reach here
294                    throw new IllegalStateException("One of JCL or log4j project must have been previously chosen.");
295                }
296                ConversionTask task = new ConversionTask(projectFolder, this, conversionType);
297                task.launch();
298            }
299        } else if (BROWSE_COMMAND.equals(e.getActionCommand())) {
300            showFileChooser();
301        } else if (EXIT_COMMAND.equals(e.getActionCommand())) {
302            this.dispose();
303        }
304    }
305
306    void showFileChooser() {
307        int returnVal = fileChooser.showOpenDialog(this);
308        if (returnVal == JFileChooser.APPROVE_OPTION) {
309            File selectedFile = fileChooser.getSelectedFile();
310            folderTextField.setText(selectedFile.getAbsolutePath());
311        }
312    }
313
314    List<String> doSanityAnalysis() {
315
316        List<String> errorList = new ArrayList<>();
317        if (!radioJCL.isSelected() && !radioLog4j.isSelected() && !radioJUL.isSelected()) {
318            errorList.add("Please select the migration type: JCL, log4j, or JUL to SLF4J.");
319        }
320
321        String folder = folderTextField.getText();
322
323        if (folder == null || folder.length() == 0) {
324            errorList.add("Please select the folder of the project to migrate");
325        } else if (!isDirectory(folder)) {
326            errorList.add("[" + folder + "] does not look like a valid folder");
327        }
328
329        if (!awareCheckBox.isSelected()) {
330            errorList.add("Cannot initiate migration unless you acknowledge<p>that files will be modified without creating backup files");
331        }
332        return errorList;
333    }
334
335    void showDialogBox(List<String> errorList) {
336        StringBuilder buf = new StringBuilder();
337        buf.append("<html>");
338        int i = 1;
339        for (String msg : errorList) {
340            buf.append("<p>");
341            buf.append(i);
342            buf.append(". ");
343            buf.append(msg);
344            buf.append("");
345            i++;
346        }
347        buf.append("</html>");
348
349        JOptionPane.showMessageDialog(this, buf.toString(), "", JOptionPane.ERROR_MESSAGE);
350    }
351
352    boolean isDirectory(String filename) {
353        if (filename == null) {
354            return false;
355        }
356        File file = new File(filename);
357        if (file.exists() && file.isDirectory()) {
358            return true;
359        } else {
360            return false;
361        }
362    }
363}