package jetbrains.mps.execution.impl.configurations;
/*Generated by MPS */
import com.intellij.openapi.components.ProjectComponent;
import jetbrains.mps.plugins.PluginReloadingListener;
import org.apache.log4j.Logger;
import org.apache.log4j.LogManager;
import com.intellij.openapi.project.Project;
import jetbrains.mps.plugins.projectplugins.ProjectPluginManager;
import java.util.List;
import jetbrains.mps.plugins.PluginContributor;
import com.intellij.execution.ui.RunContentDescriptor;
import com.intellij.openapi.application.ApplicationManager;
import java.util.Iterator;
import jetbrains.mps.internal.collections.runtime.ListSequence;
import com.intellij.ui.content.Content;
import org.apache.log4j.Level;
import com.intellij.openapi.application.ModalityState;
import com.intellij.execution.ExecutionManager;
import com.intellij.execution.ui.RunContentManagerImpl;
import jetbrains.mps.internal.collections.runtime.Sequence;
import jetbrains.mps.internal.collections.runtime.IWhereFilter;
import com.intellij.execution.configurations.RunConfiguration;
import jetbrains.mps.classloading.ModuleClassLoader;
import jetbrains.mps.internal.collections.runtime.ISelector;
import java.util.ArrayList;
import com.intellij.execution.impl.RunManagerImpl;
import com.intellij.execution.RunManagerEx;
import com.intellij.execution.impl.ProjectRunConfigurationManager;
import org.jetbrains.annotations.NonNls;
import org.jetbrains.annotations.NotNull;
import com.intellij.execution.configurations.ConfigurationType;
import com.intellij.openapi.extensions.Extensions;
import java.util.Set;
import jetbrains.mps.internal.collections.runtime.SetSequence;
import java.util.HashSet;
import org.jdom.Element;
/**
* This component allows to create reloadable (!) run configurations within MPS.
* It listens to the project plugins manager because we use custom project plugins to register custom 'before' tasks (like 'make' etc.)
* It saves all run configurations at the plugin unload and then restores them at the plugin load event
*/
public class RunConfigurationsStateManager implements ProjectComponent, PluginReloadingListener {
private static final Logger LOG = LogManager.getLogger(RunConfigurationsStateManager.class);
private final Project myProject;
private final ProjectPluginManager myProjectPluginManager;
private RunConfigurationsStateManager.RunConfigurationsState myState = null;
public RunConfigurationsStateManager(Project project, ProjectPluginManager pluginManager) {
myProject = project;
myProjectPluginManager = pluginManager;
}
@Override
public void afterPluginsLoaded(List<PluginContributor> contributors) {
initRunConfigurations();
}
@Override
public void beforePluginsUnloaded(List<PluginContributor> contributors) {
disposeRunConfigurations();
}
@Override
public void initComponent() {
myState = new RunConfigurationsStateManager.RunConfigurationsState();
myState.saveState();
myProjectPluginManager.addReloadingListener(this);
}
@Override
public void disposeComponent() {
myProjectPluginManager.removeReloadingListener(this);
}
@Override
public void projectOpened() {
}
@Override
public void projectClosed() {
}
public void initRunConfigurations() {
if (myProject.isDisposed()) {
return;
}
myState.restoreState();
}
public void disposeRunConfigurations() {
assert !(myProject.isDisposed());
myState.saveState();
disposeRunContentDescriptors();
clearAllRunConfigurations();
}
private void disposeRunContentDescriptors() {
final List<RunContentDescriptor> descriptors = collectDescriptorsToDispose();
ApplicationManager.getApplication().invokeLater(new Runnable() {
@Override
public void run() {
{
Iterator<RunContentDescriptor> descriptor_it = ListSequence.fromList(descriptors).iterator();
RunContentDescriptor descriptor_var;
while (descriptor_it.hasNext()) {
descriptor_var = descriptor_it.next();
Content attachedContent = descriptor_var.getAttachedContent();
if (attachedContent == null) {
if (LOG.isEnabledFor(Level.WARN)) {
LOG.warn("Attached content of descriptor " + descriptor_var.getDisplayName() + " is null.");
}
} else
if (attachedContent.getManager() == null) {
if (LOG.isEnabledFor(Level.WARN)) {
LOG.warn("Manager of attached content of descriptor " + descriptor_var.getDisplayName() + " is null.");
}
} else {
attachedContent.getManager().removeAllContents(true);
}
}
}
}
}, ModalityState.NON_MODAL);
}
private void clearAllRunConfigurations() {
getRunManager().clearAll();
}
private List<RunContentDescriptor> collectDescriptorsToDispose() {
ExecutionManager executionManager = ExecutionManager.getInstance(myProject);
final RunContentManagerImpl contentManager = (RunContentManagerImpl) executionManager.getContentManager();
final List<String> reloadableConfigurationNames = Sequence.fromIterable(Sequence.fromArray(getRunManager().getAllConfigurations())).where(new IWhereFilter<RunConfiguration>() {
public boolean accept(RunConfiguration it) {
return it.getClass().getClassLoader() instanceof ModuleClassLoader;
}
}).select(new ISelector<RunConfiguration, String>() {
public String select(RunConfiguration it) {
return it.getName();
}
}).toListSequence();
final List<RunContentDescriptor> descriptors = ListSequence.fromList(new ArrayList<RunContentDescriptor>());
{
Iterator<RunContentDescriptor> descriptor_it = ListSequence.fromList(contentManager.getAllDescriptors()).iterator();
RunContentDescriptor descriptor_var;
while (descriptor_it.hasNext()) {
descriptor_var = descriptor_it.next();
if (ListSequence.fromList(reloadableConfigurationNames).contains(descriptor_var.getDisplayName())) {
ListSequence.fromList(descriptors).addElement(descriptor_var);
}
}
}
return descriptors;
}
private RunManagerImpl getRunManager() {
return (RunManagerImpl) RunManagerEx.getInstanceEx(myProject);
}
private ProjectRunConfigurationManager getSharedConfigurationManager() {
return myProject.getComponent(ProjectRunConfigurationManager.class);
}
@NonNls
@NotNull
@Override
public String getComponentName() {
return "MPS Run Configs Manager";
}
public static ConfigurationType[] getConfigurationTypes() {
ConfigurationType[] configurationTypes = Extensions.getExtensions(ConfigurationType.CONFIGURATION_TYPE_EP);
List<ConfigurationType> result = ListSequence.fromList(new ArrayList<ConfigurationType>());
Set<String> uniqTypes = SetSequence.fromSet(new HashSet<String>());
for (ConfigurationType type : configurationTypes) {
String typeId = type.getClass().getName();
if (!(SetSequence.fromSet(uniqTypes).contains(typeId))) {
ListSequence.fromList(result).addElement(type);
SetSequence.fromSet(uniqTypes).addElement(typeId);
}
}
return ListSequence.fromList(result).toGenericArray(ConfigurationType.class);
}
public static RunConfigurationsStateManager getInstance(Project project) {
return project.getComponent(RunConfigurationsStateManager.class);
}
private class RunConfigurationsState {
private Element myState;
private Element mySharedState;
public RunConfigurationsState() {
}
public void restoreState() {
assert myState != null && mySharedState != null;
getRunManager().initializeConfigurationTypes(RunConfigurationsStateManager.getConfigurationTypes());
try {
getRunManager().loadState(myState);
getSharedConfigurationManager().loadState(mySharedState);
} catch (Exception e) {
if (LOG.isEnabledFor(Level.ERROR)) {
LOG.error("Can't read execution configurations state", e);
}
}
}
public void saveState() {
try {
myState = getRunManager().getState();
mySharedState = getSharedConfigurationManager().getState();
} catch (Exception e) {
if (LOG.isEnabledFor(Level.ERROR)) {
LOG.error("Can't save run configurations state", e);
}
}
}
}
}