/* * Copyright 2013 Guidewire Software, Inc. */ package gw.plugin.ij.runner; import com.google.common.collect.Lists; import com.intellij.execution.CantRunException; import com.intellij.execution.CommonJavaRunConfigurationParameters; import com.intellij.execution.ExecutionException; import com.intellij.execution.Executor; import com.intellij.execution.configurations.ConfigurationFactory; import com.intellij.execution.configurations.JavaCommandLineState; import com.intellij.execution.configurations.JavaParameters; import com.intellij.execution.configurations.ModuleBasedConfiguration; import com.intellij.execution.configurations.RunConfiguration; import com.intellij.execution.configurations.RunConfigurationModule; import com.intellij.execution.configurations.RunProfileState; import com.intellij.execution.filters.TextConsoleBuilderFactory; import com.intellij.execution.runners.ExecutionEnvironment; import com.intellij.openapi.components.PathMacroManager; import com.intellij.openapi.module.Module; import com.intellij.openapi.module.ModuleManager; import com.intellij.openapi.options.SettingsEditor; import com.intellij.openapi.project.Project; import com.intellij.openapi.projectRoots.Sdk; import com.intellij.openapi.projectRoots.SdkType; import com.intellij.openapi.projectRoots.SdkTypeId; import com.intellij.openapi.roots.ModuleRootManager; import com.intellij.openapi.roots.ProjectRootManager; import com.intellij.openapi.roots.ex.ProjectRootManagerEx; import com.intellij.openapi.util.InvalidDataException; import com.intellij.openapi.util.JDOMExternalizer; import com.intellij.openapi.util.WriteExternalException; import com.intellij.openapi.util.io.FileUtil; import com.intellij.openapi.vfs.LocalFileSystem; import com.intellij.openapi.vfs.VirtualFile; import com.intellij.psi.PsiFile; import com.intellij.psi.PsiManager; import com.intellij.util.PathUtil; import com.intellij.util.containers.hash.LinkedHashMap; import gw.plugin.ij.filetypes.GosuProgramFileProvider; import gw.plugin.ij.lang.psi.impl.GosuScratchpadFileImpl; import gw.plugin.ij.sdk.GosuSdkAdditionalData; import gw.plugin.ij.sdk.GosuSdkType; import org.jdom.Element; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import java.io.File; import java.util.ArrayList; import java.util.Arrays; import java.util.Collection; import java.util.Map; public class GosuProgramRunConfiguration extends ModuleBasedConfiguration<RunConfigurationModule> implements CommonJavaRunConfigurationParameters { public String _vmParams; @Nullable public String _strWorkDir; public String _strProgramParams; public String _strProgramPath; public String _fqn; private Map<String, String> _envs = new LinkedHashMap<>(); private boolean _passParentEnv; public GosuProgramRunConfiguration(String name, @NotNull Project project, ConfigurationFactory factory) { super(name, new RunConfigurationModule(project), factory); _strWorkDir = PathUtil.getLocalPath(project.getBaseDir()); _passParentEnv = true; } @Override public boolean excludeCompileBeforeLaunchOption() { return false; //isTester(); } private boolean isTester() { return getFqn() != null && getFqn().endsWith('.' + GosuScratchpadFileImpl.GOSU_SCRATCHPAD_NAME); } @NotNull @Override protected ModuleBasedConfiguration createInstance() { return new GosuProgramRunConfiguration(getName(), getProject(), getFactory()); } public void setWorkDir(String dir) { _strWorkDir = dir; } @Nullable public String getWorkDir() { return _strWorkDir; } public String getFqn() { return _fqn; } public void setFqn(String fqn) { _fqn = fqn; } @Nullable public Module getModule() { return getConfigurationModule().getModule(); } @Nullable private String getAbsoluteWorkDir() { if (!new File(_strWorkDir).isAbsolute()) { return new File(getProject().getLocation(), _strWorkDir).getAbsolutePath(); } return _strWorkDir; } public Collection<Module> getValidModules() { final Module[] modules = ModuleManager.getInstance(getProject()).getModules(); final GosuProgramRunner runner = findConfiguration(); if (runner != null) { final ArrayList<Module> result = Lists.newArrayList(); for (Module module : modules) { if (runner.isValidModule(module)) { result.add(module); } } return result; } else { return Arrays.asList(modules); } } @Nullable private GosuProgramRunner findConfiguration() { final VirtualFile scriptFile = getProgramFile(); if (scriptFile == null) { return null; } final PsiFile psiFile = PsiManager.getInstance(getProject()).findFile(scriptFile); if (psiFile != null && !GosuProgramFileProvider.isProgram(psiFile.getVirtualFile())) { return null; } return new DefaultGosuRunner(); } public void readExternal(Element element) throws InvalidDataException { PathMacroManager.getInstance(getProject()).expandPaths(element); super.readExternal( element ); readModule( element ); _strProgramPath = JDOMExternalizer.readString(element, "path"); _vmParams = JDOMExternalizer.readString(element, "vmparams"); _strProgramParams = JDOMExternalizer.readString(element, "params"); String wrk = JDOMExternalizer.readString(element, "workDir"); if (!".".equals(wrk)) { _strWorkDir = wrk; } _envs.clear(); JDOMExternalizer.readMap(element, _envs, null, "env"); } public void writeExternal(Element element) throws WriteExternalException { super.writeExternal(element); writeModule(element); JDOMExternalizer.write(element, "path", _strProgramPath); JDOMExternalizer.write(element, "vmparams", _vmParams); JDOMExternalizer.write(element, "params", _strProgramParams); JDOMExternalizer.write(element, "workDir", _strWorkDir); JDOMExternalizer.writeMap(element, _envs, null, "env"); PathMacroManager.getInstance( getProject() ).collapsePathsRecursively(element); } public RunProfileState getState(@NotNull Executor executor, @NotNull ExecutionEnvironment environment) throws ExecutionException { final VirtualFile programFile = getProgramFile(); if (programFile == null) { throw new CantRunException("Cannot find script " + _strProgramPath); } final GosuProgramRunner programRunner = findConfiguration(); if (programRunner == null) { throw new CantRunException("Unknown program type " + _strProgramPath); } final Module module = getModule(); if (!programRunner.ensureRunnerConfigured(module, getName(), getProject())) { return null; } final boolean tests = ProjectRootManager.getInstance(getProject()).getFileIndex().isInTestSourceContent(programFile); JavaCommandLineState state = new JavaCommandLineState(environment) { @NotNull protected JavaParameters createJavaParameters() throws ExecutionException { JavaParameters params = new JavaParameters(); params.setCharset(null); Sdk gosuSdk; if (module != null) { gosuSdk = ModuleRootManager.getInstance(module).getSdk(); } else { ProjectRootManager rootMgr = ProjectRootManagerEx.getInstance(getProject()); gosuSdk = rootMgr.getProjectSdk(); } Sdk sdk; assert gosuSdk != null; SdkTypeId sdkType = gosuSdk.getSdkType(); if (sdkType.equals(GosuSdkType.getInstance())) { GosuSdkAdditionalData data = (GosuSdkAdditionalData) gosuSdk.getSdkAdditionalData(); assert data != null; sdk = data.getJavaSdk(); } else { sdk = gosuSdk; } params.setJdk(sdk); params.setWorkingDirectory(getAbsoluteWorkDir()); programRunner.configureCommandLine(gosuSdk, params, module, tests, programFile, GosuProgramRunConfiguration.this); return params; } }; state.setConsoleBuilder(TextConsoleBuilderFactory.getInstance().createBuilder(getProject())); return state; } @Nullable private VirtualFile getProgramFile() { if (_strProgramPath == null) { return null; } return LocalFileSystem.getInstance().findFileByPath(FileUtil.toSystemIndependentName(_strProgramPath)); } @NotNull public SettingsEditor<? extends RunConfiguration> getConfigurationEditor() { return new GosuRunConfigurationEditor(); } @Override public void setVMParameters( String value ) { _vmParams = value; } @Override public String getVMParameters() { return _vmParams; } @Override public boolean isAlternativeJrePathEnabled() { throw new UnsupportedOperationException(); } @Override public void setAlternativeJrePathEnabled(boolean enabled) { throw new UnsupportedOperationException(); } @Override public String getAlternativeJrePath() { throw new UnsupportedOperationException(); } @Override public void setAlternativeJrePath(String path) { throw new UnsupportedOperationException(); } @Override public String getRunClass() { return null; } @Override public String getPackage() { return null; } @Override public void setProgramParameters( @Nullable String value ) { _strProgramParams = value; } @Override public String getProgramParameters() { return _strProgramParams; } @Override public void setWorkingDirectory( @Nullable String value ) { _strWorkDir = value; } @Override public String getWorkingDirectory() { return _strWorkDir; } @Override public void setEnvs( @NotNull Map<String, String> envs ) { _envs.clear(); _envs.putAll(envs); } @NotNull @Override public Map<String, String> getEnvs() { return _envs; } @Override public void setPassParentEnvs( boolean passParentEnvs ) { _passParentEnv = passParentEnvs; } @Override public boolean isPassParentEnvs() { return _passParentEnv; } }