/* * Copyright 2005-2010 Ignis Software Tools Ltd. All rights reserved. */ package jsystem.treeui.utilities; import java.io.File; import java.util.Collection; import javax.swing.ImageIcon; import javax.swing.JFileChooser; import javax.swing.JOptionPane; import org.apache.commons.io.filefilter.IOFileFilter; import jsystem.framework.FrameworkOptions; import jsystem.framework.JSystemProperties; import jsystem.framework.TestRunnerFrame; import jsystem.framework.common.CommonResources; import jsystem.guiMapping.JsystemMapping; import jsystem.treeui.TestRunner; import jsystem.treeui.images.ImageCenter; import jsystem.utils.StringUtils; public class ApplicationUtilities { public static String invalidClassesDirectoryMessage = "The given workspace is missing required sut and scenarion libraries. \n" + "These libraries are needed for runner execution. \n" + "Please select a different workspace or create necessary folders."; /** * chooseClassesDirectory() method can be invoke for two different cases: * 1 - During runner loading - Call this method with the classes path exists in jsystem.properties file * 2 - When the user chooses to switch project - Call this method with the classes path = null. * * At first stage we check if the path parameter is valid. in case this method has been called during Runner loading, and the * jsystem.properties already had a valid path, we return this path and exit the method. * If path=null (the user pressed the changeProject button), or the path in the jsystem.properties is invalid, * We open the file chooser dialog inside a loop until one of the following: * 1 - The user choose a valid classes directory * 2 - The user chooses to exit * * If the user choose an invalid directory, a pop up error message inform the user that the selected directory is invalid. * If the user chooses to exit the system then: * If this method was called during Runner loading, the runner cannot be loaded and therefore we exit with error code = 1 * If this method was called from "Switch Project" - We return null (which ends closing the change directory dialog. * * @param path * path contain the value of the test.dir property from the jsystem.properties file (in case we call this method during Runner loading) * path = null if the user pressed the "Change Project" button * @param mustChooseProject: * If we call this method during Runner loading mustChooseProject = true. * If we call this method from the switch project button, mustChooseProject = false * @return null if path is incorrect or cancel was selected */ public static String chooseClassesDirectory(String path, boolean mustChooseProject) { if (verifyClassesDirectory(path)){ return path; } String newPath = null; String testDirectory = JSystemProperties.getInstance().getPreference(FrameworkOptions.TESTS_CLASS_FOLDER); String currentDir = (StringUtils.isEmpty(testDirectory))? System.getProperty("user.dir") : testDirectory; JFileChooser fc = new JFileChooser(currentDir); File f = new File(currentDir); fc.setFileSelectionMode(JFileChooser.DIRECTORIES_ONLY); fc.setMultiSelectionEnabled(false); fc.setDialogTitle(JsystemMapping.getInstance().getSwitchProjectWin()); String exitString = mustChooseProject? "Exit" : "Continue with current Project"; boolean validDirectory = false; while (! validDirectory) { fc.setCurrentDirectory(f); if (fc.showDialog(TestRunnerFrame.guiMainFrame,JsystemMapping.getInstance().getSwitchProjectSaveButton()) != JFileChooser.APPROVE_OPTION ) { // handle cancel on file chooser if (!mustChooseProject){ // runner is already active return null; } // runner is starting JOptionPane.showMessageDialog( fc, "A project must be selected. Please restart the runner and select a project. \nYou can set tests.dir property manualy In the jsystem.properties file", "Setting tests directory", JOptionPane.WARNING_MESSAGE); throw new RuntimeException("Project was not selected"); } else { // a directory was chosen in the file chooser newPath = fc.getSelectedFile().getPath(); newPath = findClassesFolder(newPath); validDirectory = verifyClassesDirectory(newPath); if (! validDirectory) { ImageIcon icon = ImageCenter.getInstance().getImage(ImageCenter.ICON_WARNING); String title = "Invalid Classes Directory"; String[] options = new String[]{"Choose a different directory","Continue",exitString}; String message = "The given workspace is missing required sut and scenarion libraries. \n" + "These libraries are needed for runner execution. \n" + "Please select a different workspace or create necessary folders."; int res = JOptionPane.showOptionDialog(fc,message, title, JOptionPane.YES_NO_OPTION,JOptionPane.ERROR_MESSAGE, icon, options , "Choose a different directory"); if (res == 1){ validDirectory = true; } else if (res == 2) { if (mustChooseProject){ TestRunner.treeView.getRunner().exit(); }else{ return null; } } } } } // while return newPath; } /** * Find the classes folder in the given folder name or in one of the sub * folder. * * @param classesFolderName * @return classes actual folder or null if not found */ private static String findClassesFolder(String classesFolderName) { if (StringUtils.isEmpty(classesFolderName)) { return null; } File potentialClassesFolder = new File(classesFolderName); if (!potentialClassesFolder.exists() || !potentialClassesFolder.isDirectory()) { return null; } Collection<File> files = org.apache.commons.io.FileUtils.listFilesAndDirs(potentialClassesFolder, new IOFileFilter() { @Override public boolean accept(File dir, String name) { return false; } @Override public boolean accept(File file) { return false; } }, new IOFileFilter() { @Override public boolean accept(File dir, String name) { return false; } @Override public boolean accept(File file) { if (file.getName().equals("classes") || file.getName().equals("target")) { return true; } return false; } }); for (File file : files) { if (file.getName().equals("classes")) { return file.getAbsolutePath(); } } return null; } public static boolean verifyClassesDirectory(String path) { if (path == null){ return false; } boolean sutFolderExists, scenariosFolderExists; File selectedDirectory = new File(path); String[] list = selectedDirectory.list(); sutFolderExists = searchFor(list, "sut"); scenariosFolderExists = searchFor(list, "scenarios"); return sutFolderExists && scenariosFolderExists; } private static boolean searchFor(String[] list, String item) { boolean result = false; if (list == null){ return false; } for (int i = 0; i < list.length; i++) { if ( list[i].equals(item) ) { result = true; break; } } return result; } public static boolean isNumric(String strValue) { boolean isNumeric = true; try { Integer.parseInt(strValue); } catch (Exception e) { isNumeric = false; } return isNumeric; } /** * This method receive a long string that contain a list of email addresses separated by ';' * and verify all mail addresses are valid * @param value - the mail list entered by the user * @return: true - if all mail addresses are valid. false - otherwise */ public static boolean isEmailList(String value) { String[] addresses = value.split(CommonResources.DELIMITER); for (int i = 0; i < addresses.length; i++) { if (! isEmailAddress(addresses[i])) { return false; } } return true; } /** * This method verify that the given string parameter contain a valid email address * @param value - the email address that was entered by the user * @return true if the given string is a valid email address, false - otherwise. */ public static boolean isEmailAddress(String value) { Character lastChar = value.charAt(value.length()-1); Character firstChar = value.charAt(0); // Verify the string contain only letters, "@" and "." (No other characters if (value.length() < 5) { return false; } // check that no other characters then letters numbers and the following special characters: {'@', '.', '_', '-'} for (int index = 0; index < value.length(); index++) { if (validateCharacter(value.charAt(index)) == false) { return false; } } // Check that "." appear in the string if ( ! value.contains(".") ) { return false; } // Check that "@" appear in the string if ( ! value.contains("@") ) { return false; } // Check that "@" appear only once int atIndex = value.indexOf("@"); if (atIndex != value.lastIndexOf("@")) { return false; // more then one appearance of "@" } // check that the "@" comes before the last "." and that there is at list one letter between them if (value.lastIndexOf(".") - atIndex < 2) { return false; } // Check that the first character is a letter if (! Character.isLetter(firstChar)) { return false; } // Check that the last character is a letter if (! Character.isLetter(lastChar)) { return false; } // If we arrive here it means that the string is a legal Email address return true; } /** * This method receive a character and verify it is a valid Email character * @param currentChar * @return true if the received character can be part of an Email address, false - otherwise */ private static boolean validateCharacter(Character currentChar){ Character[] allowCharacters = new Character[]{'@', '.', '_', '-'}; boolean validCharacter = false; if ( Character.isLetter(currentChar) || Character.isDigit(currentChar) ) { validCharacter = true; } else { for (int index = 0; index < allowCharacters.length; index++) { if (currentChar == allowCharacters[index]) { validCharacter = true; } } } return validCharacter; } }