diff --git a/platform/lang-api/src/com/intellij/execution/CantRunException.java b/platform/lang-api/src/com/intellij/execution/CantRunException.java index b40ac4d63b68..f11032460d9b 100644 --- a/platform/lang-api/src/com/intellij/execution/CantRunException.java +++ b/platform/lang-api/src/com/intellij/execution/CantRunException.java @@ -24,6 +24,10 @@ public class CantRunException extends ExecutionException { super(message); } + public CantRunException(String s, Throwable cause) { + super(s, cause); + } + public static CantRunException noModuleConfigured(final String moduleName) { if (moduleName.trim().length() == 0) { return new CantRunException(ExecutionBundle.message("no.module.defined.error.message")); diff --git a/platform/lang-impl/src/com/intellij/execution/util/ScriptFileUtil.java b/platform/lang-impl/src/com/intellij/execution/util/ScriptFileUtil.java new file mode 100644 index 000000000000..cc453433965d --- /dev/null +++ b/platform/lang-impl/src/com/intellij/execution/util/ScriptFileUtil.java @@ -0,0 +1,111 @@ +package com.intellij.execution.util; + +import com.intellij.execution.CantRunException; +import com.intellij.openapi.diagnostic.Logger; +import com.intellij.openapi.editor.Document; +import com.intellij.openapi.fileEditor.FileDocumentManager; +import com.intellij.openapi.fileEditor.impl.LoadTextUtil; +import com.intellij.openapi.util.SystemInfo; +import com.intellij.openapi.util.io.FileUtil; +import com.intellij.openapi.util.text.StringUtil; +import com.intellij.openapi.vfs.CharsetToolkit; +import com.intellij.openapi.vfs.LocalFileSystem; +import com.intellij.openapi.vfs.VirtualFile; +import com.intellij.util.PathUtil; +import com.intellij.util.containers.ContainerUtil; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +import java.io.File; +import java.io.IOException; +import java.nio.ByteBuffer; +import java.nio.CharBuffer; +import java.util.Map; +import java.util.concurrent.atomic.AtomicLong; + +public class ScriptFileUtil { + + private static final Logger LOG = Logger.getInstance(ScriptFileUtil.class); + + private static final String SCHEME = "mem://"; + private static final Map ourFilesMap = ContainerUtil.createConcurrentWeakValueMap(); + private static final AtomicLong ourFileCounter = new AtomicLong(); + + private ScriptFileUtil() {} + + public static boolean isMemoryScriptPath(@Nullable String url) { + return url != null && url.startsWith(SCHEME); + } + + public static String getScriptFilePath(@NotNull VirtualFile file) { + if (file.isInLocalFileSystem()) return file.getPath(); + + long id = ourFileCounter.incrementAndGet(); + String url = SCHEME + id + "/" + file.getName(); + ourFilesMap.put(url, file); + return url; + } + + @Nullable + public static VirtualFile findScriptFileByPath(@Nullable String path) { + if (StringUtil.isEmpty(path)) return null; + if (!path.startsWith(SCHEME)) { + return LocalFileSystem.getInstance().findFileByPath(path); + } + return ourFilesMap.get(path); + } + + @NotNull + public static String getLocalFilePath(@NotNull String scriptPath) throws CantRunException { + if (isMemoryScriptPath(scriptPath)) { + File tmpFile = copyToTempFile(scriptPath); + return tmpFile.getAbsolutePath(); + } + if (SystemInfo.isWindows) { + return PathUtil.driveLetterToLowerCase(scriptPath); + } + return scriptPath; + } + + @NotNull + public static File copyToTempFile(@NotNull String path) throws CantRunException { + VirtualFile virtualFile = findScriptFileByPath(path); + if (virtualFile == null) { + throw new CantRunException("File not found: " + path); + } + File ioFile; + try { + ioFile = FileUtil.createTempFile(virtualFile.getName(), "", true); + } + catch (IOException e) { + throw new CantRunException("Cannot create temporary file " + virtualFile.getName(), e); + } + try { + copyFile(virtualFile, ioFile); + return ioFile; + } + catch (IOException e) { + throw new CantRunException("Cannot write temp file " + virtualFile.getPath() + " to " + ioFile.getAbsolutePath(), e); + } + } + + private static void copyFile(@NotNull VirtualFile srcFile, @NotNull File destFile) throws IOException { + LOG.info("Copying to " + destFile.getPath()); + CharSequence content = getContent(srcFile); + CharBuffer cb = CharBuffer.wrap(content); + ByteBuffer bb = CharsetToolkit.UTF8_CHARSET.encode(cb); + byte[] result = new byte[bb.remaining()]; + bb.get(result); + FileUtil.writeToFile(destFile, result, false); + } + + @NotNull + private static CharSequence getContent(@NotNull VirtualFile file) { + Document document = FileDocumentManager.getInstance().getCachedDocument(file); + if (document != null) { + return document.getText(); + } + return LoadTextUtil.loadText(file); + } + +} diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/runner/DefaultGroovyScriptRunner.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/runner/DefaultGroovyScriptRunner.java index 28ed24c25a35..3810fd81cea0 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/runner/DefaultGroovyScriptRunner.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/runner/DefaultGroovyScriptRunner.java @@ -22,12 +22,14 @@ import com.intellij.execution.Executor; import com.intellij.execution.configurations.JavaParameters; import com.intellij.execution.configurations.RunProfile; import com.intellij.execution.runners.ExecutionUtil; +import com.intellij.execution.util.ScriptFileUtil; import com.intellij.openapi.module.Module; import com.intellij.openapi.project.Project; import com.intellij.openapi.roots.ui.configuration.ClasspathEditor; import com.intellij.openapi.roots.ui.configuration.ModulesConfigurator; import com.intellij.openapi.util.Comparing; import com.intellij.openapi.util.io.FileUtil; +import com.intellij.openapi.util.text.StringUtil; import com.intellij.openapi.vfs.CharsetToolkit; import com.intellij.openapi.vfs.VirtualFile; import com.intellij.openapi.vfs.encoding.EncodingManager; @@ -77,7 +79,8 @@ public class DefaultGroovyScriptRunner extends GroovyScriptRunner { params.getProgramParametersList().add("--debug"); } - params.getProgramParametersList().add(FileUtil.toSystemDependentName(configuration.getScriptPath())); + String path = ScriptFileUtil.getLocalFilePath(StringUtil.notNullize(configuration.getScriptPath())); + params.getProgramParametersList().add(FileUtil.toSystemDependentName(path)); params.getProgramParametersList().addParametersString(configuration.getScriptParameters()); } diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/runner/GroovyScriptRunConfiguration.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/runner/GroovyScriptRunConfiguration.java index 3d9ed638717e..d48b3dab792c 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/runner/GroovyScriptRunConfiguration.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/runner/GroovyScriptRunConfiguration.java @@ -22,6 +22,7 @@ import com.intellij.execution.process.ProcessAdapter; import com.intellij.execution.process.ProcessEvent; import com.intellij.execution.runners.ExecutionEnvironment; import com.intellij.execution.util.ProgramParametersUtil; +import com.intellij.execution.util.ScriptFileUtil; import com.intellij.openapi.application.ApplicationManager; import com.intellij.openapi.components.PathMacroManager; import com.intellij.openapi.diagnostic.Logger; @@ -37,8 +38,6 @@ import com.intellij.openapi.roots.ProjectRootManager; 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.openapi.vfs.VirtualFileManager; import com.intellij.psi.PsiClass; @@ -47,8 +46,10 @@ import com.intellij.psi.PsiFile; import com.intellij.psi.PsiManager; import com.intellij.refactoring.listeners.RefactoringElementAdapter; import com.intellij.refactoring.listeners.RefactoringElementListener; +import com.intellij.util.ObjectUtils; import com.intellij.util.PathUtil; import com.intellij.util.SystemProperties; +import com.intellij.util.containers.ContainerUtil; import com.intellij.util.containers.hash.LinkedHashMap; import org.jdom.Element; import org.jetbrains.annotations.NotNull; @@ -175,7 +176,7 @@ public class GroovyScriptRunConfiguration extends ModuleBasedConfiguration