fixed memory leaks from snapshot attached to IDEA-65035

This commit is contained in:
nik
2011-02-04 10:24:20 +03:00
parent 26099475c1
commit 8d1cb02778
12 changed files with 133 additions and 56 deletions
@@ -64,10 +64,19 @@ public class ProjectJdksConfigurable extends MasterDetailsComponent {
super();
myProject = project;
myProjectJdksModel = ProjectStructureConfigurable.getInstance(project).getProjectJdksModel();
MasterDetailsStateService.getInstance(project).register("ProjectJDKs.UI", this);
initTree();
}
@Override
protected String getComponentStateKey() {
return "ProjectJDKs.UI";
}
@Override
protected MasterDetailsStateService getStateService() {
return MasterDetailsStateService.getInstance(myProject);
}
protected void initTree() {
super.initTree();
new TreeSpeedSearch(myTree, new Convertor<TreePath, String>() {
@@ -34,7 +34,6 @@ import com.intellij.openapi.roots.ui.configuration.libraryEditor.LibraryEditorLi
import com.intellij.openapi.roots.ui.configuration.projectRoot.*;
import com.intellij.openapi.roots.ui.configuration.projectRoot.daemon.ProjectStructureElement;
import com.intellij.openapi.ui.MasterDetailsState;
import com.intellij.openapi.ui.MasterDetailsStateService;
import com.intellij.openapi.ui.NamedConfigurable;
import com.intellij.packaging.artifacts.*;
import com.intellij.packaging.impl.artifacts.ArtifactUtil;
@@ -61,7 +60,11 @@ public class ArtifactsStructureConfigurable extends BaseStructureConfigurable {
public ArtifactsStructureConfigurable(@NotNull Project project) {
super(project, new ArtifactStructureConfigurableState());
MasterDetailsStateService.getInstance(project).register("ArtifactsStructureConfigurable.UI", this);
}
@Override
protected String getComponentStateKey() {
return "ArtifactsStructureConfigurable.UI";
}
public void init(StructureConfigurableContext context, ModuleStructureConfigurable moduleStructureConfigurable,
@@ -160,7 +163,7 @@ public class ArtifactsStructureConfigurable extends BaseStructureConfigurable {
}
@Override
public MasterDetailsState getState() {
protected MasterDetailsState getState() {
((ArtifactStructureConfigurableState)myState).setDefaultArtifactSettings(myDefaultSettings.getState());
return super.getState();
}
@@ -209,6 +212,7 @@ public class ArtifactsStructureConfigurable extends BaseStructureConfigurable {
@Override
public void reset() {
loadComponentState();
myPackagingEditorContext.resetModifiableModel();
super.reset();
}
@@ -32,6 +32,7 @@ import com.intellij.openapi.roots.libraries.LibraryTable;
import com.intellij.openapi.roots.ui.configuration.projectRoot.daemon.*;
import com.intellij.openapi.ui.MasterDetailsComponent;
import com.intellij.openapi.ui.MasterDetailsState;
import com.intellij.openapi.ui.MasterDetailsStateService;
import com.intellij.openapi.ui.NamedConfigurable;
import com.intellij.openapi.util.ActionCallback;
import com.intellij.openapi.util.Condition;
@@ -100,6 +101,10 @@ public abstract class BaseStructureConfigurable extends MasterDetailsComponent i
});
}
@Override
protected MasterDetailsStateService getStateService() {
return MasterDetailsStateService.getInstance(myProject);
}
public ActionCallback navigateTo(@Nullable final Place place, final boolean requestFocus) {
if (place == null) return new ActionCallback.Done();
@@ -37,7 +37,6 @@ import com.intellij.openapi.project.Project;
import com.intellij.openapi.project.ProjectBundle;
import com.intellij.openapi.roots.ui.configuration.ProjectStructureConfigurable;
import com.intellij.openapi.ui.DetailsComponent;
import com.intellij.openapi.ui.MasterDetailsStateService;
import com.intellij.openapi.ui.NamedConfigurable;
import com.intellij.openapi.util.IconLoader;
import org.jetbrains.annotations.NotNull;
@@ -59,10 +58,14 @@ public class FacetStructureConfigurable extends BaseStructureConfigurable {
public FacetStructureConfigurable(final Project project, ModuleManager moduleManager) {
super(project);
MasterDetailsStateService.getInstance(project).register("FacetStructureConfigurable.UI", this);
myModuleManager = moduleManager;
}
@Override
protected String getComponentStateKey() {
return "FacetStructureConfigurable.UI";
}
public static FacetStructureConfigurable getInstance(final @NotNull Project project) {
return ServiceManager.getService(project, FacetStructureConfigurable.class);
}
@@ -19,7 +19,6 @@ import com.intellij.openapi.components.ServiceManager;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.project.ProjectBundle;
import com.intellij.openapi.roots.libraries.LibraryTablesRegistrar;
import com.intellij.openapi.ui.MasterDetailsStateService;
import org.jetbrains.annotations.Nls;
import org.jetbrains.annotations.NonNls;
import org.jetbrains.annotations.NotNull;
@@ -31,10 +30,14 @@ public class GlobalLibrariesConfigurable extends BaseLibrariesConfigurable {
public GlobalLibrariesConfigurable(final Project project) {
super(project);
MasterDetailsStateService.getInstance(project).register("GlobalLibrariesConfigurable.UI", this);
myLevel = LibraryTablesRegistrar.APPLICATION_LEVEL;
}
@Override
protected String getComponentStateKey() {
return "GlobalLibrariesConfigurable.UI";
}
@Nls
public String getDisplayName() {
return "Global Libraries";
@@ -30,7 +30,6 @@ import com.intellij.openapi.roots.ui.configuration.ProjectStructureConfigurable;
import com.intellij.openapi.roots.ui.configuration.projectRoot.daemon.ProjectStructureElement;
import com.intellij.openapi.roots.ui.configuration.projectRoot.daemon.SdkProjectStructureElement;
import com.intellij.openapi.ui.MasterDetailsComponent;
import com.intellij.openapi.ui.MasterDetailsStateService;
import com.intellij.openapi.ui.NamedConfigurable;
import com.intellij.util.Consumer;
import org.jetbrains.annotations.Nls;
@@ -75,10 +74,15 @@ public class JdkListConfigurable extends BaseStructureConfigurable {
public JdkListConfigurable(final Project project, ProjectStructureConfigurable root) {
super(project);
MasterDetailsStateService.getInstance(project).register("JdkListConfigurable.UI", this);
myJdksTreeModel = root.getProjectJdksModel();
myJdksTreeModel.addListener(myListener);
}
@Override
protected String getComponentStateKey() {
return "JdkListConfigurable.UI";
}
protected void processRemovedItems() {
}
@@ -50,7 +50,6 @@ import com.intellij.openapi.roots.ui.configuration.projectRoot.daemon.ModuleProj
import com.intellij.openapi.roots.ui.configuration.projectRoot.daemon.ProjectStructureDaemonAnalyzer;
import com.intellij.openapi.roots.ui.configuration.projectRoot.daemon.ProjectStructureElement;
import com.intellij.openapi.ui.DialogWrapper;
import com.intellij.openapi.ui.MasterDetailsStateService;
import com.intellij.openapi.ui.Messages;
import com.intellij.openapi.ui.NamedConfigurable;
import com.intellij.openapi.util.Comparing;
@@ -96,10 +95,13 @@ public class ModuleStructureConfigurable extends BaseStructureConfigurable imple
public ModuleStructureConfigurable(Project project, ModuleManager manager) {
super(project);
MasterDetailsStateService.getInstance(project).register("ModuleStructureConfigurable.UI", this);
myModuleManager = manager;
}
@Override
protected String getComponentStateKey() {
return "ModuleStructureConfigurable.UI";
}
protected void initTree() {
super.initTree();
@@ -19,7 +19,6 @@ import com.intellij.openapi.components.ServiceManager;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.project.ProjectBundle;
import com.intellij.openapi.roots.libraries.LibraryTablesRegistrar;
import com.intellij.openapi.ui.MasterDetailsStateService;
import org.jetbrains.annotations.Nls;
import org.jetbrains.annotations.NonNls;
import org.jetbrains.annotations.NotNull;
@@ -30,10 +29,14 @@ import javax.swing.*;
public class ProjectLibrariesConfigurable extends BaseLibrariesConfigurable {
public ProjectLibrariesConfigurable(final Project project) {
super(project);
MasterDetailsStateService.getInstance(project).register("ProjectLibrariesConfigurable.UI", this);
myLevel = LibraryTablesRegistrar.PROJECT_LEVEL;
}
@Override
protected String getComponentStateKey() {
return "ProjectLibrariesConfigurable.UI";
}
@Nls
public String getDisplayName() {
return "Libraries";
@@ -61,6 +61,7 @@ import java.util.*;
public class ScopeChooserConfigurable extends MasterDetailsComponent implements NonDefaultProjectConfigurable, SearchableConfigurable {
private static final Icon SCOPES = IconLoader.getIcon("/ide/scopeConfigurable.png");
private static final Icon SAVE_ICON = IconLoader.getIcon("/runConfigurations/saveTempConfig.png");
@NonNls public static final String SCOPE_CHOOSER_CONFIGURABLE_UI_KEY = "ScopeChooserConfigurable.UI";
private final NamedScopesHolder myLocalScopesManager;
private final NamedScopesHolder mySharedScopesManager;
@@ -81,10 +82,19 @@ public class ScopeChooserConfigurable extends MasterDetailsComponent implements
mySharedScopesManager = DependencyValidationManager.getInstance(project);
myProject = project;
MasterDetailsStateService.getInstance(project).register("ScopeChooserConfigurable.UI", this);
initTree();
}
@Override
protected String getComponentStateKey() {
return SCOPE_CHOOSER_CONFIGURABLE_UI_KEY;
}
@Override
protected MasterDetailsStateService getStateService() {
return MasterDetailsStateService.getInstance(myProject);
}
protected ArrayList<AnAction> createActions(final boolean fromPopup) {
final ArrayList<AnAction> result = new ArrayList<AnAction>();
result.add(new MyAddAction(fromPopup));
@@ -323,6 +323,7 @@ public abstract class MasterDetailsComponent implements Configurable, DetailsCom
protected abstract boolean wasObjectStored(Object editableObject);
public void reset() {
loadComponentState();
myHasDeletedItems = false;
((DefaultTreeModel)myTree.getModel()).reload();
//myTree.requestFocus();
@@ -345,6 +346,17 @@ public abstract class MasterDetailsComponent implements Configurable, DetailsCom
updateSelectionFromTree();
}
protected void loadComponentState() {
final String key = getComponentStateKey();
final MasterDetailsStateService stateService = getStateService();
if (key != null && stateService != null) {
final MasterDetailsState state = stateService.getComponentState(key, myState.getClass());
if (state != null) {
loadState(state);
}
}
}
private static String getNodePathString(final MyNode node) {
StringBuilder path = new StringBuilder();
MyNode current = node;
@@ -365,11 +377,22 @@ public abstract class MasterDetailsComponent implements Configurable, DetailsCom
return path.toString();
}
public MasterDetailsState getState() {
@Nullable
@NonNls
protected String getComponentStateKey() {
return null;
}
@Nullable
protected MasterDetailsStateService getStateService() {
return null;
}
protected MasterDetailsState getState() {
return myState;
}
public void loadState(final MasterDetailsState object) {
protected void loadState(final MasterDetailsState object) {
XmlSerializerUtil.copyBean(object, myState);
}
@@ -391,6 +414,11 @@ public abstract class MasterDetailsComponent implements Configurable, DetailsCom
}
});
myRoot.removeAllChildren();
final String key = getComponentStateKey();
final MasterDetailsStateService stateService = getStateService();
if (key != null && stateService != null) {
stateService.setComponentState(key, getState());
}
myCurrentConfigurable = null;
}
@@ -33,6 +33,7 @@ import com.intellij.util.xmlb.annotations.Tag;
import org.jdom.Element;
import org.jetbrains.annotations.NonNls;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.util.*;
@@ -46,57 +47,53 @@ import java.util.*;
)
public class MasterDetailsStateService implements PersistentStateComponent<MasterDetailsStateService.States>{
private final SkipDefaultValuesSerializationFilters mySerializationFilter = new SkipDefaultValuesSerializationFilters();
private final Map<String, MasterDetailsComponent> myComponents = new HashMap<String, MasterDetailsComponent>();
private final States myStates = new States();
private final Map<String, ComponentState> myStates = new HashMap<String, ComponentState>();
public static MasterDetailsStateService getInstance(@NotNull Project project) {
return ServiceManager.getService(project, MasterDetailsStateService.class);
}
public void register(@NotNull @NonNls String key, MasterDetailsComponent masterDetailsComponent) {
myComponents.put(key, masterDetailsComponent);
for (ComponentState state : myStates.getStates()) {
if (key.equals(state.myKey)) {
final Element element = state.mySettings;
if (element != null) {
loadComponentState(masterDetailsComponent, element);
}
}
}
/**
* @deprecated override {@link MasterDetailsComponent#getComponentStateKey()} and {@link MasterDetailsComponent#getStateService()} instead
*/
public void register(String key, MasterDetailsComponent component) {
}
private static void loadComponentState(MasterDetailsComponent masterDetailsComponent, Element element) {
final MasterDetailsState loadedState = XmlSerializer.deserialize(element, masterDetailsComponent.getState().getClass());
masterDetailsComponent.loadState(loadedState);
@Nullable
public MasterDetailsState getComponentState(@NotNull @NonNls String key, Class<? extends MasterDetailsState> stateClass) {
ComponentState state = myStates.get(key);
return state != null ? XmlSerializer.deserialize(state.mySettings, stateClass) : null;
}
public void setComponentState(@NotNull @NonNls String key, @NotNull MasterDetailsState state) {
final Element element = XmlSerializer.serialize(state, mySerializationFilter);
if (element == null) {
myStates.remove(key);
}
else {
final ComponentState componentState = new ComponentState();
componentState.myKey = key;
componentState.mySettings = element;
myStates.put(key, componentState);
}
}
public States getState() {
myStates.getStates().clear();
for (Map.Entry<String, MasterDetailsComponent> entry : myComponents.entrySet()) {
final Element element = XmlSerializer.serialize(entry.getValue().getState(), mySerializationFilter);
if (element != null) {
final ComponentState state = new ComponentState();
state.myKey = entry.getKey();
state.mySettings = element;
myStates.getStates().add(state);
}
}
Collections.sort(myStates.getStates(), new Comparator<ComponentState>() {
States states = new States();
states.myStates.addAll(myStates.values());
Collections.sort(states.getStates(), new Comparator<ComponentState>() {
@Override
public int compare(ComponentState o1, ComponentState o2) {
return o1.myKey.compareTo(o2.myKey);
}
});
return myStates;
return states;
}
public void loadState(States states) {
myStates.setStates(states.getStates());
for (ComponentState state : myStates.getStates()) {
final MasterDetailsComponent component = myComponents.get(state.myKey);
if (component != null) {
loadComponentState(component, state.mySettings);
}
myStates.clear();
for (ComponentState state : states.getStates()) {
myStates.put(state.myKey, state);
}
}
@@ -60,13 +60,22 @@ public class CopyrightProfilesPanel extends MasterDetailsComponent implements Se
private final AtomicBoolean myInitialized = new AtomicBoolean(false);
public CopyrightProfilesPanel(Project project) {
MasterDetailsStateService.getInstance(project).register("Copyright.UI", this);
myProject = project;
myManager = CopyrightManager.getInstance(project);
initTree();
}
myProject = project;
myManager = CopyrightManager.getInstance(project);
initTree();
}
protected void processRemovedItems() {
@Override
protected MasterDetailsStateService getStateService() {
return MasterDetailsStateService.getInstance(myProject);
}
@Override
protected String getComponentStateKey() {
return "Copyright.UI";
}
protected void processRemovedItems() {
Map<String, CopyrightProfile> profiles = getAllProfiles();
final List<CopyrightProfile> deleted = new ArrayList<CopyrightProfile>();
for (CopyrightProfile profile : myManager.getCopyrights()) {