From c7d161a72b594adb40feaf62aeb0ed6a2a5d6d99 Mon Sep 17 00:00:00 2001 From: "Gregory.Shrago" Date: Wed, 27 Apr 2016 20:11:15 +0300 Subject: [PATCH] Startup scripts: cleanup --- .../ExtensionsRootType.java | 9 +- .../ide/script/IdeStartupScripts.java | 167 ++++++++---------- 2 files changed, 74 insertions(+), 102 deletions(-) diff --git a/platform/lang-impl/src/com/intellij/ide/extensionResources/ExtensionsRootType.java b/platform/lang-impl/src/com/intellij/ide/extensionResources/ExtensionsRootType.java index 6b4fa1225cf6..c0c70cc9ae56 100644 --- a/platform/lang-impl/src/com/intellij/ide/extensionResources/ExtensionsRootType.java +++ b/platform/lang-impl/src/com/intellij/ide/extensionResources/ExtensionsRootType.java @@ -152,11 +152,12 @@ public class ExtensionsRootType extends RootType { private File findExtensionsDirectoryImpl(@NotNull PluginId pluginId, @NotNull String path, boolean createIfMissing) throws IOException { String fullPath = getPath(pluginId, path); File dir = new File(FileUtil.toSystemDependentName(fullPath)); - if (createIfMissing && !dir.exists()) { - //noinspection ResultOfMethodCallIgnored - dir.mkdirs(); + if (createIfMissing && !dir.exists() && !dir.mkdirs()) { + throw new IOException("Failed to create directory: " + dir.getPath()); } - return dir.exists() && dir.isDirectory()? dir : null; + if (!dir.exists()) return null; + if (!dir.isDirectory()) throw new IOException("Not a directory: " + dir.getPath()); + return dir; } @Nullable diff --git a/platform/lang-impl/src/com/intellij/ide/script/IdeStartupScripts.java b/platform/lang-impl/src/com/intellij/ide/script/IdeStartupScripts.java index 63fe343d6419..6c56d61f7a50 100644 --- a/platform/lang-impl/src/com/intellij/ide/script/IdeStartupScripts.java +++ b/platform/lang-impl/src/com/intellij/ide/script/IdeStartupScripts.java @@ -21,6 +21,7 @@ import com.intellij.openapi.application.ApplicationManager; import com.intellij.openapi.components.ApplicationComponent; import com.intellij.openapi.diagnostic.Logger; import com.intellij.openapi.extensions.PluginId; +import com.intellij.openapi.progress.ProcessCanceledException; import com.intellij.openapi.project.Project; import com.intellij.openapi.project.ProjectManager; import com.intellij.openapi.project.ProjectManagerAdapter; @@ -30,7 +31,6 @@ import com.intellij.openapi.util.text.StringUtil; import com.intellij.openapi.vfs.VfsUtil; import com.intellij.openapi.vfs.VfsUtilCore; import com.intellij.openapi.vfs.VirtualFile; -import com.intellij.util.Function; import com.intellij.util.ObjectUtils; import com.intellij.util.containers.ContainerUtil; import org.jetbrains.annotations.NotNull; @@ -41,157 +41,128 @@ import org.jetbrains.ide.script.IdeScriptEngineManager; import org.jetbrains.ide.script.IdeScriptException; import java.io.IOException; -import java.util.Comparator; import java.util.List; -import java.util.concurrent.Callable; import java.util.concurrent.ExecutionException; import java.util.concurrent.Future; import java.util.concurrent.atomic.AtomicBoolean; class IdeStartupScripts extends ApplicationComponent.Adapter { - @SuppressWarnings("FieldCanBeLocal") - private static String SCRIPT_DIR_NAME = "startup"; - - private static Logger LOG = Logger.getInstance(IdeStartupScripts.class); + private static final Logger LOG = Logger.getInstance(IdeStartupScripts.class); + private static final String SCRIPT_DIR_NAME = "startup"; @Override public void initComponent() { - if (ApplicationManager.getApplication().isUnitTestMode()) { - return; - } + if (ApplicationManager.getApplication().isUnitTestMode()) return; - List scripts = getScripts(); - if (scripts.isEmpty()) { - LOG.debug("No startup scripts detected"); - } - else { - scheduleStartupScriptsExecution(scripts); - } + scheduleStartupScriptsExecution(); } - private static void scheduleStartupScriptsExecution(@NotNull List scripts) { + private static void scheduleStartupScriptsExecution() { + List scripts = getScripts(); + LOG.info(scripts.size() + " startup script(s) found"); + if (scripts.isEmpty()) return; + final Future>> scriptsAndEnginesFuture = prepareScriptEnginesAsync(scripts); ProjectManager.getInstance().addProjectManagerListener(new ProjectManagerAdapter() { - private final AtomicBoolean myScriptsExecutionStarted = new AtomicBoolean(); + final AtomicBoolean myScriptsExecutionStarted = new AtomicBoolean(); @Override public void projectOpened(final Project project) { - StartupManager.getInstance(project).runWhenProjectIsInitialized(new Runnable() { - @Override - public void run() { - if (myScriptsExecutionStarted.compareAndSet(false, true)) { - executeScriptsAndDispose(project); - } - } + StartupManager.getInstance(project).runWhenProjectIsInitialized(() -> { + if (project.isDisposed()) return; + if (!myScriptsExecutionStarted.compareAndSet(false, true)) return; + ProjectManager.getInstance().removeProjectManagerListener(this); + runAllScriptsImpl(project); }); } - private void executeScriptsAndDispose(@NotNull Project project) { - for (Pair scriptAndEngine : getScriptsAndEngines()) { - executeScript(project.isDisposed() ? null : project, scriptAndEngine.first, scriptAndEngine.second); - } - ProjectManager.getInstance().removeProjectManagerListener(this); - } - - @NotNull - private List> getScriptsAndEngines() { + private void runAllScriptsImpl(@NotNull Project project) { try { - return scriptsAndEnginesFuture.get(); + for (Pair pair : scriptsAndEnginesFuture.get()) { + try { + if (pair.second == null) { + LOG.warn(pair.first.getPath() + " not supported (no script engine)"); + } + else { + runImpl(project, pair.first, pair.second); + } + } + catch (Exception e) { + LOG.warn(e); + } + } + } + catch (ProcessCanceledException e) { + LOG.warn("... cancelled"); } catch (InterruptedException e) { - LOG.info("Script engines initialization cancelled"); + LOG.warn("... interrupted"); } - catch (ExecutionException e) { - LOG.error("Failed to initialize script engines", e); + catch (Exception e) { + LOG.error(e); } - return ContainerUtil.emptyList(); } }); } @NotNull private static Future>> prepareScriptEnginesAsync(@NotNull final List scripts) { - return PooledThreadExecutor.INSTANCE.submit(new Callable>>() { - @Override - public List> call() throws Exception { - return prepareScriptEngines(scripts); - } - }); + return PooledThreadExecutor.INSTANCE.submit(() -> prepareScriptEngines(scripts)); } @NotNull - private static List> prepareScriptEngines(@NotNull final List scripts) { - final IdeScriptEngineManager scriptEngineManager = IdeScriptEngineManager.getInstance(); - return ContainerUtil.map(scripts, new Function>() { - @Override - public Pair fun(VirtualFile script) { - String extension = script.getExtension(); - return Pair.create(script, extension != null ? scriptEngineManager.getEngineForFileExtension(extension, null) : null); - } - }); + private static List> prepareScriptEngines(@NotNull List scripts) { + IdeScriptEngineManager scriptEngineManager = IdeScriptEngineManager.getInstance(); + List> result = ContainerUtil.newArrayList(); + for (VirtualFile script : scripts) { + String extension = script.getExtension(); + IdeScriptEngine engine = extension != null ? scriptEngineManager.getEngineForFileExtension(extension, null) : null; + result.add(Pair.create(script, engine)); + } + return result; } - private static void executeScript(@Nullable Project project, @NotNull VirtualFile script, @Nullable IdeScriptEngine scriptEngine) { - if (scriptEngine == null) { - LOG.warn("No script engine found for script: " + script.getPath()); - return; - } - - String scriptText; - try { - scriptText = VfsUtilCore.loadText(script); - } - catch (IOException e) { - LOG.warn("Cannot load script: " + script.getPath(), e); - return; - } - - IdeScriptBindings.ensureIdeIsBound(project, scriptEngine); + private static void runImpl(@NotNull Project project, + @NotNull VirtualFile script, + @NotNull IdeScriptEngine engine) throws ExecutionException, IOException, IdeScriptException { + String scriptText = VfsUtilCore.loadText(script); + IdeScriptBindings.ensureIdeIsBound(project, engine); + LOG.info(script.getPath()); long start = System.currentTimeMillis(); try { - LOG.info("Running script: " + script.getPath()); - scriptEngine.eval(scriptText); - } - catch (IdeScriptException e) { - LOG.error("Error in script: " + script.getPath(), e); + engine.eval(scriptText); } finally { - long end = System.currentTimeMillis(); - LOG.info(script.getPath() + " completed in " + (end - start) + " ms"); + LOG.info("... completed in " + StringUtil.formatDuration(System.currentTimeMillis() - start)); } } @NotNull private static List getScripts() { - VirtualFile root = getScriptsRootDirectory(); + VirtualFile root = null; + try { + root = getScriptsRootDirectory(); + } + catch (IOException e) { + LOG.warn(e); + } if (root == null) return ContainerUtil.emptyList(); VfsUtil.markDirtyAndRefresh(false, true, true, root); List scripts = VfsUtil.collectChildrenRecursively(root); scripts = ContainerUtil.filter(scripts, ExtensionsRootType.regularFileFilter()); - ContainerUtil.sort(scripts, new FileNameComparator()); + ContainerUtil.sort(scripts, (f1, f2) -> { + String f1Name = f1 != null ? f1.getName() : null; + String f2Name = f2 != null ? f2.getName() : null; + return StringUtil.compare(f1Name, f2Name, false); + }); return scripts; } @Nullable - private static VirtualFile getScriptsRootDirectory() { - try { - PluginId corePlugin = ObjectUtils.assertNotNull(PluginId.findId(PluginManagerCore.CORE_PLUGIN_ID)); - return ExtensionsRootType.getInstance().findResourceDirectory(corePlugin, SCRIPT_DIR_NAME, false); - } - catch (IOException e) { - LOG.warn("Failed to open/create startup scripts directory", e); - } - return null; - } - - private static class FileNameComparator implements Comparator { - @Override - public int compare(VirtualFile f1, VirtualFile f2) { - String f1Name = f1 != null ? f1.getName() : null; - String f2Name = f2 != null ? f2.getName() : null; - return StringUtil.compare(f1Name, f2Name, false); - } + private static VirtualFile getScriptsRootDirectory() throws IOException { + PluginId corePlugin = ObjectUtils.assertNotNull(PluginId.findId(PluginManagerCore.CORE_PLUGIN_ID)); + return ExtensionsRootType.getInstance().findResourceDirectory(corePlugin, SCRIPT_DIR_NAME, false); } }