package com.lightd.ideap.maven; import com.intellij.execution.*; import com.intellij.execution.configurations.ConfigurationFactory; import com.intellij.execution.configurations.JavaParameters; import com.intellij.execution.configurations.RunProfileState; import com.intellij.execution.executors.DefaultDebugExecutor; import com.intellij.execution.runners.ExecutionEnvironment; import com.intellij.openapi.project.Project; import com.intellij.openapi.util.IconLoader; import com.intellij.openapi.util.InvalidDataException; import com.intellij.openapi.util.WriteExternalException; import com.intellij.openapi.util.text.StringUtil; import com.intellij.util.containers.ContainerUtil; import org.jdom.Element; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import org.jetbrains.idea.maven.execution.MavenRunConfiguration; import org.jetbrains.idea.maven.project.MavenProject; import org.jetbrains.idea.maven.project.MavenProjectsManager; import javax.swing.*; import java.util.ArrayList; import java.util.Collections; import java.util.List; import java.util.regex.Pattern; public class MvnRunConfiguration extends MavenRunConfiguration { private static final String TEST_PREFIX = MvnBundle.message("mvn.param.test.object", ""); private static final String PACKAGE_PATTERN = "\\.\\*\\*\\.\\*$"; private RunType runType; private String stopGoal; @Override public JavaParameters createJavaParameters(@Nullable Project project) throws ExecutionException { JavaParameters parameters = super.createJavaParameters(project); foldMavenCommand(parameters); return parameters; } @Override public void readExternal(Element element) throws InvalidDataException { super.readExternal(element); String value = element.getAttributeValue("runType"); if (value != null) runType = RunType.to(value); stopGoal = element.getAttributeValue("stopGoal"); } @Override public void writeExternal(Element element) throws WriteExternalException { super.writeExternal(element); if (runType != null) element.setAttribute("runType", runType.getValue()); if (stopGoal != null) element.setAttribute("stopGoal", stopGoal); } @Override public RunProfileState getState(@NotNull Executor executor, final @NotNull ExecutionEnvironment env) throws ExecutionException { if (DefaultDebugExecutor.EXECUTOR_ID.equals(executor.getId())) { List<String> goals = null; if (RunType.Test.equals(runType)) { RunnerAndConfigurationSettings settings = env.getRunnerAndConfigurationSettings(); if (settings != null && settings.getConfiguration() instanceof MvnRunConfiguration) { goals = disableFork(((MvnRunConfiguration) settings.getConfiguration()).getGoals()); } } if ((RunType.Jetty.equals(runType) || RunType.Tomcat.equals(runType)) || goals != null) { return new DebugServerCommandLineState(env, this, goals); } } return super.getState(executor, env); } protected MvnRunConfiguration(Project project, ConfigurationFactory factory, String name) { super(project, factory, name); } public String getStopGoal() { return stopGoal; } public void setStopGoal(String stopGoal) { this.stopGoal = stopGoal; } @Override public boolean isGeneratedName() { return isTest() || super.isGeneratedName(); } @Nullable @Override public String getActionName() { if (isTest()) { if (isAllTest()) return MvnBundle.message("action.all.tests.text", getModuleName()); if (isPackageTest()) return MvnBundle.message("action.test.package.text", getPackageName()); } return super.getActionName(); } public void setRunType(RunType runType) { this.runType = runType; } @Override public Icon getIcon() { if (runType != null) { return IconLoader.getIcon(runType.toString()); } return MvnBundle.MAVEN_RUN_ICON; } private String getModuleName() { MavenProjectsManager projectsManager = MavenProjectsManager.getInstance(getProject()); String workingDirPath = getRunnerParameters().getWorkingDirPath(); for (MavenProject mavenProject : projectsManager.getProjects()) { if (StringUtil.equals(workingDirPath, mavenProject.getDirectory())) { return mavenProject.getDisplayName(); } } return null; } private String getPackageName() { for (String s : getGoals()) { if (s.startsWith(TEST_PREFIX)) { return s.substring(TEST_PREFIX.length(), s.length() - 5); } } return null; } private List<String> getGoals() { List<String> goals = getRunnerParameters().getGoals(); return goals != null ? goals : Collections.<String>emptyList(); } private boolean isTest() { return getGoals().contains(MvnBundle.message("mvn.param.test")); } private boolean isPackageTest() { return isMatch(getGoals(), TEST_PREFIX, PACKAGE_PATTERN); } private boolean isAllTest() { return isMatch(getGoals(), TEST_PREFIX, null, false); } private boolean isMatch(List<String> list, String prefix, String regex) { return isMatch(list, prefix, regex, true); } private boolean isMatch(List<String> list, String prefix, String regex, boolean match) { String param = null; for (String s : list) { if (s.startsWith(prefix)) { param = s; break; } } if (regex != null) { Pattern pattern = Pattern.compile(regex); if (param != null && pattern.matcher(param).find()) { return match; } } else if (param != null) return match; return !match; } private static List<String> disableFork(List<String> goals) { List<String> bakGoals = new ArrayList<String>(goals.size()); List<String> clone = new ArrayList<String>(goals.size()); bakGoals.addAll(goals); clone.addAll(goals); goals.clear(); boolean changed = false; for (String s : clone) { if (s.startsWith("-DreuseForks=") || s.startsWith("-DthreadCount=")) continue; if (s.startsWith("-Dfork")) { changed = true; String[] keyValue = s.split("="); goals.add(keyValue[0] + "=" + (keyValue[0].length()>10 ? "0" : "never")); } else goals.add(s); } return changed ? bakGoals : null; } private void foldMavenCommand(JavaParameters params) { if (params == null) { return; } List<MvnCommandFolding> list = ContainerUtil.findAll(ConsoleFolding.EP_NAME.getExtensions(), MvnCommandFolding.class); if (list.isEmpty()) return; try { String jdkPath = params.getJdkPath(); String goalStr = params.getProgramParametersList().getParametersString(); for (MvnCommandFolding folding : list) { folding.placeMaven(jdkPath, params.getMainClass(), goalStr); } } catch (CantRunException ignore) { } } }