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}