/**
* Copyright (C) 2010-2017 Gordon Fraser, Andrea Arcuri and EvoSuite
* contributors
*
* This file is part of EvoSuite.
*
* EvoSuite is free software: you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as published
* by the Free Software Foundation, either version 3.0 of the License, or
* (at your option) any later version.
*
* EvoSuite is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with EvoSuite. If not, see <http://www.gnu.org/licenses/>.
*/
package org.evosuite.intellij;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.projectRoots.ProjectJdkTable;
import com.intellij.openapi.projectRoots.Sdk;
import com.intellij.openapi.ui.Messages;
import org.evosuite.intellij.util.EvoVersion;
import org.evosuite.intellij.util.Utils;
import javax.swing.*;
import javax.swing.filechooser.FileFilter;
import java.awt.*;
import java.awt.event.*;
import java.io.File;
import java.text.NumberFormat;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
public class EvoStartDialog extends JDialog {
private JPanel contentPane;
private JButton buttonOK;
private JButton buttonCancel;
private JFormattedTextField memoryField;
private JFormattedTextField coreField;
private JFormattedTextField timeField;
private JTextField folderField;
private JTextField mavenField;
private JTextField javaHomeField;
private JButton selectMavenButton;
private JButton selectJavaHomeButton;
private JTextField evosuiteLocationTesxField;
private JButton evosuiteSelectionButton;
private JRadioButton mavenRadioButton;
private JRadioButton evosuiteRadioButton;
private volatile boolean wasOK = false;
private volatile EvoParameters params;
private volatile Project project;
public void initFields(Project project, EvoParameters params) {
this.project = project;
this.params = params;
coreField.setValue(params.getCores());
memoryField.setValue(params.getMemory());
timeField.setValue(params.getTime());
folderField.setText(params.getFolder());
mavenField.setText(params.getMvnLocation());
evosuiteLocationTesxField.setText(params.getEvosuiteJarLocation());
javaHomeField.setText(params.getJavaHome());
if (!Utils.isMavenProject(project)) {
//disable Maven options
selectMavenButton.setEnabled(false);
mavenRadioButton.setEnabled(false);
params.setExecutionMode(EvoParameters.EXECUTION_MODE_JAR);
}
if (params.usesMaven()) {
mavenRadioButton.setSelected(true);
} else {
evosuiteRadioButton.setSelected(true);
}
checkExecution();
}
public EvoStartDialog() {
setContentPane(contentPane);
setModal(true);
getRootPane().setDefaultButton(buttonOK);
buttonOK.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
onOK();
}
});
buttonCancel.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
onCancel();
}
});
// call onCancel() when cross is clicked
setDefaultCloseOperation(DO_NOTHING_ON_CLOSE);
addWindowListener(new WindowAdapter() {
public void windowClosing(WindowEvent e) {
onCancel();
}
});
// call onCancel() on ESCAPE
contentPane.registerKeyboardAction(new ActionListener() {
public void actionPerformed(ActionEvent e) {
onCancel();
}
}, KeyStroke.getKeyStroke(KeyEvent.VK_ESCAPE, 0), JComponent.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT);
selectMavenButton.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent actionEvent) {
onSelectMvn();
}
});
selectJavaHomeButton.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent actionEvent) {
onSelectJavaHome();
}
});
selectJavaHomeButton.setToolTipText("Choose a valid JDK home for Java " + EvoVersion.JAVA_VERSION);
mavenRadioButton.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent actionEvent) {
checkExecution();
}
});
evosuiteRadioButton.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent actionEvent) {
checkExecution();
}
});
evosuiteSelectionButton.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent actionEvent) {
onSelectEvosuite();
}
});
setPreferredSize(new Dimension(EvoParameters.getInstance().getGuiWidth(), EvoParameters.getInstance().getGuiHeight()));
}
private void onSelectEvosuite() {
JFileChooser fc = new JFileChooser();
fc.setAcceptAllFileFilterUsed(false);
fc.setFileFilter(new FileFilter() {
@Override
public boolean accept(File file) {
if (file.isDirectory()) {
return true; // need to be able to navigate through folders
}
return checkIfValidEvoSuiteJar(file);
}
@Override
public String getDescription() {
return "EvoSuite executable jar";
}
});
int returnVal = fc.showOpenDialog(null);
if (returnVal == JFileChooser.APPROVE_OPTION) {
String path = fc.getSelectedFile().getAbsolutePath();
params.setEvosuiteJarLocation(path);
evosuiteLocationTesxField.setText(path);
}
}
private void checkExecution() {
if (mavenRadioButton.isSelected()) {
params.setExecutionMode(EvoParameters.EXECUTION_MODE_MVN);
} else if (evosuiteRadioButton.isSelected()) {
params.setExecutionMode(EvoParameters.EXECUTION_MODE_JAR);
}
evosuiteLocationTesxField.setEnabled(evosuiteRadioButton.isSelected());
evosuiteSelectionButton.setEnabled(evosuiteRadioButton.isSelected());
mavenField.setEnabled(mavenRadioButton.isSelected());
selectMavenButton.setEnabled(mavenRadioButton.isSelected());
}
private void onSelectMvn() {
JFileChooser fc = new JFileChooser();
fc.setAcceptAllFileFilterUsed(false);
fc.setFileFilter(new FileFilter() {
@Override
public boolean accept(File file) {
if (file.isDirectory()) {
return true; // need to be able to navigate through folders
}
return checkIfValidMaven(file);
}
@Override
public String getDescription() {
return "Maven executable";
}
});
int returnVal = fc.showOpenDialog(null);
if (returnVal == JFileChooser.APPROVE_OPTION) {
String path = fc.getSelectedFile().getAbsolutePath();
params.setMvnLocation(path);
mavenField.setText(path);
}
}
private void onSelectJavaHome() {
String jdkStartLocation = getJDKStartLocation();
JFileChooser fc = new JFileChooser(jdkStartLocation);
fc.setAcceptAllFileFilterUsed(false);
fc.setFileFilter(new FileFilter() {
@Override
public boolean accept(File file) {
//return checkIfValidJavaHome(file);
return true; //otherwise all folders will be greyed out
}
@Override
public String getDescription() {
return "Java Home (containing bin/javac)";
}
});
fc.setFileSelectionMode(JFileChooser.DIRECTORIES_ONLY);
int returnVal = fc.showOpenDialog(null);
if (returnVal == JFileChooser.APPROVE_OPTION) {
String path = fc.getSelectedFile().getAbsolutePath();
if (!checkIfValidJavaHome(new File(path))) {
Messages.showMessageDialog(project, "Invalid JDK home: choose a correct one that contains bin/javac",
"EvoSuite Plugin", Messages.getErrorIcon());
return;
}
params.setJavaHome(path);
javaHomeField.setText(path);
}
}
private String getJDKStartLocation() {
String start = params.getJavaHome(); //TODO check for null
if (start == null || start.isEmpty() && ProjectJdkTable.getInstance().getAllJdks().length > 0) {
//try to check the JDK used by the project
for (Sdk sdk : ProjectJdkTable.getInstance().getAllJdks()) {
if (sdk.getVersionString().contains("" + EvoVersion.JAVA_VERSION)) {
start = sdk.getHomePath();
break;
}
}
if (start == null) {
//just take something as starting point
start = ProjectJdkTable.getInstance().getAllJdks()[0].getHomePath();
}
}
if (start == null || start.isEmpty()) {
return ""; //if still empty, return default ""
}
File file = new File(start);
while (file != null) {
if (file.getName().toLowerCase().contains("jdk")) {
file = file.getParentFile(); //go to the parent, which might have several JDKs
break;
}
file = file.getParentFile();
}
if (file != null) {
return file.getAbsolutePath();
} else {
return "";
}
}
private boolean checkIfValidJavaHome(File file) {
if (file == null || !file.exists() || !file.isDirectory()) {
return false;
}
String javac = Utils.isWindows() ? "javac.exe" : "javac";
File jf = new File(new File(file, "bin"), javac);
return jf.exists();
}
private boolean checkIfValidEvoSuiteJar(File file) {
if (file == null || !file.exists() || file.isDirectory()) {
return false;
}
String name = file.getName().toLowerCase();
if(Arrays.asList("runtime","standalone","client","plugin","test","generated").stream()
.anyMatch(k -> name.contains(k))){
return false;
}
return name.startsWith("evosuite") && name.endsWith(".jar");
}
private boolean checkIfValidMaven(File file) {
if (file == null || !file.exists() || file.isDirectory()) {
return false;
}
List<String> names = Utils.getMvnExecutableNames();
for (String name : names) {
if (file.getName().toLowerCase().equals(name)) {
return true;
}
}
return false;
}
private void onOK() {
// add your code here
dispose();
wasOK = saveParameters(true);
}
private void onCancel() {
// add your code here if necessary
dispose();
saveParameters(false);
}
private boolean saveParameters(boolean validate) {
int cores = ((Number) coreField.getValue()).intValue();
int memory = ((Number) memoryField.getValue()).intValue();
int time = ((Number) timeField.getValue()).intValue();
String dir = folderField.getText();
String mvn = mavenField.getText();
String javaHome = javaHomeField.getText();
String evosuiteJar = evosuiteLocationTesxField.getText();
List<String> errors = new ArrayList<>();
if (cores < 1) {
errors.add("Number of cores needs to be positive value");
} else {
params.setCores(cores);
}
if (memory < 1) {
errors.add("Memory needs to be a positive value");
} else {
params.setMemory(memory);
}
if (time < 1) {
errors.add("Duration needs to be a positive value");
} else {
params.setTime(time);
}
if (params.usesMaven() && !checkIfValidMaven(new File(mvn))) {
errors.add("Invalid Maven executable: choose a correct one");
} else {
params.setMvnLocation(mvn);
}
if (!params.usesMaven() && !checkIfValidEvoSuiteJar(new File(evosuiteJar))) {
errors.add("Invalid EvoSuite executable jar: choose a correct evosuite*.jar one");
} else {
params.setEvosuiteJarLocation(evosuiteJar);
}
if (!checkIfValidJavaHome(new File(javaHome))) {
errors.add("Invalid JDK home: choose a correct one that contains bin/javac");
} else {
params.setJavaHome(javaHome);
}
params.setFolder(dir);
params.setGuiWidth(this.getWidth());
params.setGuiHeight(this.getHeight());
if (validate && !errors.isEmpty()) {
String title = "ERROR: EvoSuite Plugin";
String msg = String.join("\n",errors);
Messages.showMessageDialog(project, msg, title, Messages.getErrorIcon());
return false;
}
return true;
}
public static void main(String[] args) {
EvoStartDialog dialog = new EvoStartDialog();
dialog.pack();
dialog.setVisible(true);
System.exit(0);
}
private void createUIComponents() {
// TODO: place custom component creation code here
NumberFormat nf = NumberFormat.getNumberInstance();
nf.setParseIntegerOnly(true);
coreField = new JFormattedTextField(nf);
memoryField = new JFormattedTextField(nf);
timeField = new JFormattedTextField(nf);
}
public boolean isWasOK() {
return wasOK;
}
}