From 6470f10bf37fd27872ba5c696c4d8b5bba50ba77 Mon Sep 17 00:00:00 2001 From: anna Date: Wed, 23 Jun 2010 14:08:29 +0400 Subject: [PATCH] run configurations optimization --- .../actions/ConfigurationContext.java | 41 ++++++++++++++++--- .../actions/BaseRunConfigurationAction.java | 14 +++---- .../actions/ChooseRunConfigurationAction.java | 2 +- .../execution/actions/CreateAction.java | 2 +- .../src/com/intellij/ide/DataManager.java | 4 ++ .../intellij/ide/impl/DataManagerImpl.java | 26 ++++++++++++ .../execution/testframework/TestsUIUtil.java | 1 - 7 files changed, 75 insertions(+), 15 deletions(-) diff --git a/platform/lang-api/src/com/intellij/execution/actions/ConfigurationContext.java b/platform/lang-api/src/com/intellij/execution/actions/ConfigurationContext.java index 95ea96eaf73a..535155678892 100644 --- a/platform/lang-api/src/com/intellij/execution/actions/ConfigurationContext.java +++ b/platform/lang-api/src/com/intellij/execution/actions/ConfigurationContext.java @@ -25,6 +25,7 @@ import com.intellij.execution.configurations.RuntimeConfiguration; import com.intellij.execution.junit.RuntimeConfigurationProducer; import com.intellij.ide.DataManager; import com.intellij.openapi.actionSystem.DataContext; +import com.intellij.openapi.actionSystem.DataKey; import com.intellij.openapi.actionSystem.LangDataKeys; import com.intellij.openapi.actionSystem.PlatformDataKeys; import com.intellij.openapi.diagnostic.Logger; @@ -32,6 +33,7 @@ import com.intellij.openapi.editor.Editor; import com.intellij.openapi.module.Module; import com.intellij.openapi.project.Project; import com.intellij.openapi.util.Comparing; +import com.intellij.openapi.util.Ref; import com.intellij.openapi.vfs.VirtualFile; import com.intellij.psi.PsiDocumentManager; import com.intellij.psi.PsiElement; @@ -46,11 +48,26 @@ public class ConfigurationContext { private static final Logger LOG = Logger.getInstance("#com.intellij.execution.actions.ConfigurationContext"); private final Location myLocation; private RunnerAndConfigurationSettings myConfiguration; + private Ref myExistingConfiguration; private final Module myModule; private final RuntimeConfiguration myRuntimeConfiguration; private final Component myContextComponent; - public ConfigurationContext(final DataContext dataContext) { + public static DataKey SHARED_CONTEXT = DataKey.create("SHARED_CONTEXT"); + private List myPreferredProducers; + + public static ConfigurationContext getFromContext(DataContext dataContext) { + final ConfigurationContext context = new ConfigurationContext(dataContext); + final DataManager dataManager = DataManager.getInstance(); + ConfigurationContext sharedContext = dataManager.loadFromDataContext(dataContext, SHARED_CONTEXT); + if (sharedContext == null || !Comparing.equal(sharedContext.getLocation().getPsiElement(), context.getLocation().getPsiElement())) { + sharedContext = context; + dataManager.saveInDataContext(dataContext, SHARED_CONTEXT, sharedContext); + } + return sharedContext; + } + + private ConfigurationContext(final DataContext dataContext) { myRuntimeConfiguration = RuntimeConfiguration.DATA_KEY.getData(dataContext); myContextComponent = PlatformDataKeys.CONTEXT_COMPONENT.getData(dataContext); myModule = LangDataKeys.MODULE.getData(dataContext); @@ -98,23 +115,29 @@ public class ConfigurationContext { @Nullable public RunnerAndConfigurationSettings findExisting() { + if (myExistingConfiguration != null) return myExistingConfiguration.get(); + myExistingConfiguration = new Ref(); if (myLocation == null) { return null; } - final List producers = PreferedProducerFind.findPreferredProducers(myLocation, this, true); + final List producers = findPreferredProducers(); if (producers == null) return null; if (myRuntimeConfiguration != null) { for (RuntimeConfigurationProducer producer : producers) { final RunnerAndConfigurationSettings configuration = producer.findExistingConfiguration(myLocation, this); - if (configuration != null && configuration.getConfiguration() == myRuntimeConfiguration) return configuration; + if (configuration != null && configuration.getConfiguration() == myRuntimeConfiguration) { + myExistingConfiguration.set(configuration); + } } } for (RuntimeConfigurationProducer producer : producers) { final RunnerAndConfigurationSettings configuration = producer.findExistingConfiguration(myLocation, this); - if (configuration != null) return configuration; + if (configuration != null) { + myExistingConfiguration.set(configuration); + } } - return null; + return myExistingConfiguration.get(); } @Nullable @@ -157,4 +180,12 @@ public class ConfigurationContext { public RuntimeConfiguration getOriginalConfiguration(final ConfigurationType type) { return myRuntimeConfiguration != null && Comparing.strEqual(type.getId(), myRuntimeConfiguration.getType().getId()) ? myRuntimeConfiguration : null; } + + @Nullable + public List findPreferredProducers() { + if (myPreferredProducers == null) { + myPreferredProducers = PreferedProducerFind.findPreferredProducers(myLocation, this, true); + } + return myPreferredProducers; + } } diff --git a/platform/lang-impl/src/com/intellij/execution/actions/BaseRunConfigurationAction.java b/platform/lang-impl/src/com/intellij/execution/actions/BaseRunConfigurationAction.java index 9a1cdd30f994..95ddd65e0696 100644 --- a/platform/lang-impl/src/com/intellij/execution/actions/BaseRunConfigurationAction.java +++ b/platform/lang-impl/src/com/intellij/execution/actions/BaseRunConfigurationAction.java @@ -59,7 +59,7 @@ public abstract class BaseRunConfigurationAction extends ActionGroup { } private AnAction[] getChildren(DataContext dataContext) { - final ConfigurationContext context = new ConfigurationContext(dataContext); + final ConfigurationContext context = ConfigurationContext.getFromContext(dataContext); final RunnerAndConfigurationSettings existing = context.findExisting(); if (existing == null) { final List producers = getEnabledProducers(context); @@ -87,7 +87,7 @@ public abstract class BaseRunConfigurationAction extends ActionGroup { @NotNull private List getEnabledProducers(ConfigurationContext context) { - final List preferred = PreferedProducerFind.findPreferredProducers(context.getLocation(), context, true); + final List preferred = context.findPreferredProducers(); if (preferred == null) { return Collections.emptyList(); } @@ -107,7 +107,7 @@ public abstract class BaseRunConfigurationAction extends ActionGroup { @Override public boolean canBePerformed(DataContext dataContext) { - final ConfigurationContext context = new ConfigurationContext(dataContext); + final ConfigurationContext context = ConfigurationContext.getFromContext(dataContext); final RunnerAndConfigurationSettings existing = context.findExisting(); if (existing == null) { final List producers = getEnabledProducers(context); @@ -118,11 +118,11 @@ public abstract class BaseRunConfigurationAction extends ActionGroup { public void actionPerformed(final AnActionEvent e) { final DataContext dataContext = e.getDataContext(); - final ConfigurationContext context = new ConfigurationContext(dataContext); + final ConfigurationContext context = ConfigurationContext.getFromContext(dataContext); final RunnerAndConfigurationSettings existing = context.findExisting(); if (existing == null) { - final List producers = PreferedProducerFind.findPreferredProducers(context.getLocation(), context, true); - if (producers == null) return; + final List producers = getEnabledProducers(context); + if (producers.isEmpty()) return; if (producers.size() > 1) { final Editor editor = PlatformDataKeys.EDITOR.getData(dataContext); Collections.sort(producers, new Comparator() { @@ -173,7 +173,7 @@ public abstract class BaseRunConfigurationAction extends ActionGroup { protected abstract void perform(ConfigurationContext context); public void update(final AnActionEvent event){ - final ConfigurationContext context = new ConfigurationContext(event.getDataContext()); + final ConfigurationContext context = ConfigurationContext.getFromContext(event.getDataContext()); final Presentation presentation = event.getPresentation(); RunnerAndConfigurationSettings configuration; try { diff --git a/platform/lang-impl/src/com/intellij/execution/actions/ChooseRunConfigurationAction.java b/platform/lang-impl/src/com/intellij/execution/actions/ChooseRunConfigurationAction.java index 7f4c439b930d..0bd51de4f52d 100644 --- a/platform/lang-impl/src/com/intellij/execution/actions/ChooseRunConfigurationAction.java +++ b/platform/lang-impl/src/com/intellij/execution/actions/ChooseRunConfigurationAction.java @@ -525,7 +525,7 @@ public class ChooseRunConfigurationAction extends AnAction { final ArrayList contextConfigurations = new ArrayList(); final DataContext dataContext = DataManager.getInstance().getDataContext(); - final ConfigurationContext context = new ConfigurationContext(dataContext); + final ConfigurationContext context = ConfigurationContext.getFromContext(dataContext); final List producers = PreferedProducerFind.findPreferredProducers(context.getLocation(), context, false); if (producers == null) return Collections.emptyList(); diff --git a/platform/lang-impl/src/com/intellij/execution/actions/CreateAction.java b/platform/lang-impl/src/com/intellij/execution/actions/CreateAction.java index 0828d6636fb4..5843bbf7c885 100644 --- a/platform/lang-impl/src/com/intellij/execution/actions/CreateAction.java +++ b/platform/lang-impl/src/com/intellij/execution/actions/CreateAction.java @@ -70,7 +70,7 @@ public class CreateAction extends BaseRunConfigurationAction { } protected void updateIcon(final Presentation presentation, final ConfigurationContext context) { - final List producers = PreferedProducerFind.findPreferredProducers(context.getLocation(), context, true); + final List producers = context.findPreferredProducers(); if (producers != null && producers.size() == 1) { //hide fuzzy icon when multiple run configurations are possible presentation.setIcon(context.getConfiguration().getFactory().getIcon()); } diff --git a/platform/platform-api/src/com/intellij/ide/DataManager.java b/platform/platform-api/src/com/intellij/ide/DataManager.java index 41c71dffaed0..238e1a8f5ce4 100644 --- a/platform/platform-api/src/com/intellij/ide/DataManager.java +++ b/platform/platform-api/src/com/intellij/ide/DataManager.java @@ -16,6 +16,7 @@ package com.intellij.ide; import com.intellij.openapi.actionSystem.DataContext; +import com.intellij.openapi.actionSystem.DataKey; import com.intellij.openapi.application.ApplicationManager; import com.intellij.openapi.util.AsyncResult; import org.jetbrains.annotations.NonNls; @@ -52,4 +53,7 @@ public abstract class DataManager { * component's bounds */ public abstract DataContext getDataContext(@NotNull Component component, int x, int y); + + public abstract void saveInDataContext(DataContext dataContext, DataKey dataKey, T data); + public abstract T loadFromDataContext(DataContext dataContext, DataKey dataKey); } diff --git a/platform/platform-impl/src/com/intellij/ide/impl/DataManagerImpl.java b/platform/platform-impl/src/com/intellij/ide/impl/DataManagerImpl.java index 7d55ebd986c0..6e2671be422b 100644 --- a/platform/platform-impl/src/com/intellij/ide/impl/DataManagerImpl.java +++ b/platform/platform-impl/src/com/intellij/ide/impl/DataManagerImpl.java @@ -32,6 +32,7 @@ import com.intellij.openapi.wm.IdeFocusManager; import com.intellij.openapi.wm.ex.WindowManagerEx; import com.intellij.util.KeyedLazyInstanceEP; import com.intellij.util.StringSetSpinAllocator; +import com.intellij.util.containers.WeakHashMap; import gnu.trove.THashMap; import org.jetbrains.annotations.NonNls; import org.jetbrains.annotations.NotNull; @@ -279,12 +280,21 @@ public class DataManagerImpl extends DataManager implements ApplicationComponent return "DataManager"; } + public void saveInDataContext(DataContext dataContext, DataKey dataKey, T data) { + ((MyDataContext)dataContext).save(dataKey, data); + } + + public T loadFromDataContext(DataContext dataContext, DataKey dataKey) { + return ((MyDataContext)dataContext).load(dataKey); + } + public class MyDataContext implements DataContext { private int myEventCount; // To prevent memory leak we have to wrap passed component into // the weak reference. For example, Swing often remembers menu items // that have DataContext as a field. private final WeakReference myRef; + private WeakHashMap mySavedData; public MyDataContext(final Component component) { myEventCount = -1; @@ -347,6 +357,22 @@ public class DataManagerImpl extends DataManager implements ApplicationComponent public String toString() { return "component=" + String.valueOf(myRef.get()); } + + public void save(DataKey dataKey, T data) { + getOrCreateMap().put(dataKey, data); + } + + + private WeakHashMap getOrCreateMap() { + if (mySavedData == null) { + mySavedData = new WeakHashMap(); + } + return mySavedData; + } + + public T load(DataKey dataKey) { + return (T)getOrCreateMap().get(dataKey); + } } } diff --git a/platform/testRunner/src/com/intellij/execution/testframework/TestsUIUtil.java b/platform/testRunner/src/com/intellij/execution/testframework/TestsUIUtil.java index 3b477ebe2806..414145e803da 100644 --- a/platform/testRunner/src/com/intellij/execution/testframework/TestsUIUtil.java +++ b/platform/testRunner/src/com/intellij/execution/testframework/TestsUIUtil.java @@ -40,7 +40,6 @@ import org.jetbrains.annotations.Nullable; import javax.swing.*; import java.awt.*; import java.awt.image.BufferedImage; -import java.util.*; import java.util.List; public class TestsUIUtil {