diff --git a/platform/lang-impl/src/com/intellij/openapi/components/impl/stores/ModuleStateStorageManager.java b/platform/lang-impl/src/com/intellij/openapi/components/impl/stores/ModuleStateStorageManager.java index a26413bb37fa..d17dceebf125 100644 --- a/platform/lang-impl/src/com/intellij/openapi/components/impl/stores/ModuleStateStorageManager.java +++ b/platform/lang-impl/src/com/intellij/openapi/components/impl/stores/ModuleStateStorageManager.java @@ -19,25 +19,53 @@ import com.intellij.openapi.components.StateStorage; import com.intellij.openapi.components.StateStorageOperation; import com.intellij.openapi.components.StoragePathMacros; import com.intellij.openapi.components.TrackingPathMacroSubstitutor; -import com.intellij.openapi.module.Module; +import com.intellij.openapi.module.impl.ModuleImpl; import org.jetbrains.annotations.NonNls; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; class ModuleStateStorageManager extends StateStorageManagerImpl { @NonNls private static final String ROOT_TAG_NAME = "module"; - private final Module myModule; + private final ModuleImpl myModule; - public ModuleStateStorageManager(@Nullable final TrackingPathMacroSubstitutor pathMacroManager, final Module module) { + public ModuleStateStorageManager(@Nullable TrackingPathMacroSubstitutor pathMacroManager, @NotNull ModuleImpl module) { super(pathMacroManager, ROOT_TAG_NAME, module, module.getPicoContainer()); + myModule = module; } @Override - protected StorageData createStorageData(@NotNull String storageSpec) { + protected StorageData createStorageData(@NotNull String fileSpec, @NotNull String filePath) { return new ModuleStoreImpl.ModuleFileData(ROOT_TAG_NAME, myModule); } + @NotNull + @Override + public ExternalizationSession startExternalization() { + return new StateStorageManagerExternalizationSession() { + @Nullable + @Override + public StateStorage.SaveSession createSaveSession() { + final ModuleStoreImpl.ModuleFileData data = myModule.getStateStore().getMainStorageData(); + final StateStorage.SaveSession session = super.createSaveSession(); + if (data.isDirty()) { + return new StateStorage.SaveSession() { + @Override + public void save() { + if (session != null) { + session.save(); + } + if (data.isDirty()) { + myModule.getStateStore().getMainStorage().forceSave(); + } + } + }; + } + return session; + } + }; + } + @Nullable @Override protected String getOldStorageSpec(@NotNull Object component, @NotNull String componentName, @NotNull StateStorageOperation operation) { diff --git a/platform/lang-impl/src/com/intellij/openapi/components/impl/stores/ModuleStoreImpl.java b/platform/lang-impl/src/com/intellij/openapi/components/impl/stores/ModuleStoreImpl.java index 405d9fef367c..5ee90c1c2e13 100644 --- a/platform/lang-impl/src/com/intellij/openapi/components/impl/stores/ModuleStoreImpl.java +++ b/platform/lang-impl/src/com/intellij/openapi/components/impl/stores/ModuleStoreImpl.java @@ -92,7 +92,7 @@ public class ModuleStoreImpl extends BaseFileConfigurableStoreImpl implements IM } @Override - public ModuleFileData getMainStorageData() throws StateStorageException { + public ModuleFileData getMainStorageData() { return (ModuleFileData)super.getMainStorageData(); } @@ -100,6 +100,8 @@ public class ModuleStoreImpl extends BaseFileConfigurableStoreImpl implements IM private final Map myOptions; private final Module myModule; + private boolean dirty = true; + public ModuleFileData(@NotNull String rootElementName, @NotNull Module module) { super(rootElementName); @@ -107,6 +109,10 @@ public class ModuleStoreImpl extends BaseFileConfigurableStoreImpl implements IM myOptions = new TreeMap(); } + public boolean isDirty() { + return dirty; + } + private ModuleFileData(@NotNull ModuleFileData storageData) { super(storageData); @@ -140,6 +146,7 @@ public class ModuleStoreImpl extends BaseFileConfigurableStoreImpl implements IM // need be last for compat reasons root.setAttribute(VERSION_OPTION, versionString); + dirty = false; return root; } @@ -158,15 +165,20 @@ public class ModuleStoreImpl extends BaseFileConfigurableStoreImpl implements IM return super.getChangedComponentNames(newStorageData, substitutor); } - public void setOption(final String optionName, final String optionValue) { - myOptions.put(optionName, optionValue); + public void setOption(@NotNull String optionName, @NotNull String optionValue) { + if (!optionValue.equals(myOptions.put(optionName, optionValue))) { + dirty = true; + } } - public void clearOption(final String optionName) { - myOptions.remove(optionName); + public void clearOption(@NotNull String optionName) { + if (myOptions.remove(optionName) != null) { + dirty = true; + } } - public String getOptionValue(final String optionName) { + @Nullable + public String getOptionValue(@NotNull String optionName) { return myOptions.get(optionName); } } @@ -199,7 +211,7 @@ public class ModuleStoreImpl extends BaseFileConfigurableStoreImpl implements IM } @Override - public void setOption(final String optionName, final String optionValue) { + public void setOption(@NotNull String optionName, @NotNull String optionValue) { try { getMainStorageData().setOption(optionName, optionValue); } @@ -209,7 +221,7 @@ public class ModuleStoreImpl extends BaseFileConfigurableStoreImpl implements IM } @Override - public void clearOption(final String optionName) { + public void clearOption(@NotNull String optionName) { try { getMainStorageData().clearOption(optionName); } @@ -219,7 +231,7 @@ public class ModuleStoreImpl extends BaseFileConfigurableStoreImpl implements IM } @Override - public String getOptionValue(final String optionName) { + public String getOptionValue(@NotNull String optionName) { try { return getMainStorageData().getOptionValue(optionName); } diff --git a/platform/lang-impl/src/com/intellij/openapi/module/impl/ModuleImpl.java b/platform/lang-impl/src/com/intellij/openapi/module/impl/ModuleImpl.java index f451245b93d0..ae1ebfd4a947 100644 --- a/platform/lang-impl/src/com/intellij/openapi/module/impl/ModuleImpl.java +++ b/platform/lang-impl/src/com/intellij/openapi/module/impl/ModuleImpl.java @@ -23,7 +23,6 @@ import com.intellij.openapi.components.ExtensionAreas; import com.intellij.openapi.components.impl.ModulePathMacroManager; import com.intellij.openapi.components.impl.PlatformComponentManagerImpl; import com.intellij.openapi.components.impl.stores.IComponentStore; -import com.intellij.openapi.components.impl.stores.IModuleStore; import com.intellij.openapi.components.impl.stores.ModuleStoreImpl; import com.intellij.openapi.diagnostic.Logger; import com.intellij.openapi.extensions.AreaInstance; @@ -67,7 +66,7 @@ public class ModuleImpl extends PlatformComponentManagerImpl implements ModuleEx private String myModuleType; - private IModuleStore myComponentStore; + private ModuleStoreImpl myComponentStore; private final ModuleScopeProvider myModuleScopeProvider; public ModuleImpl(@NotNull String filePath, @NotNull Project project) { @@ -90,9 +89,9 @@ public class ModuleImpl extends PlatformComponentManagerImpl implements ModuleEx } @NotNull - public synchronized IModuleStore getStateStore() { + public synchronized ModuleStoreImpl getStateStore() { if (myComponentStore == null) { - myComponentStore = (IModuleStore)getPicoContainer().getComponentInstance(IComponentStore.class); + myComponentStore = (ModuleStoreImpl)getPicoContainer().getComponentInstance(IComponentStore.class); } return myComponentStore; } diff --git a/platform/lang-impl/src/com/intellij/openapi/roots/impl/ModuleRootManagerComponent.java b/platform/lang-impl/src/com/intellij/openapi/roots/impl/ModuleRootManagerComponent.java index 66db0cc72b63..55c560ce2d21 100644 --- a/platform/lang-impl/src/com/intellij/openapi/roots/impl/ModuleRootManagerComponent.java +++ b/platform/lang-impl/src/com/intellij/openapi/roots/impl/ModuleRootManagerComponent.java @@ -43,17 +43,14 @@ public class ModuleRootManagerComponent extends ModuleRootManagerImpl implements static class StorageChooser implements StateStorageChooser { @Override public Storage[] selectStorages(Storage[] storages, ModuleRootManagerImpl moduleRootManager, final StateStorageOperation operation) { - if (ClassPathStorageUtil.isDefaultStorage(moduleRootManager.getModule())) { - for (Storage storage : storages) { - if (storage.id().equals(ClassPathStorageUtil.DEFAULT_STORAGE)) { - return new Storage[]{storage}; - } + boolean isDefaultStorageType = ClassPathStorageUtil.isDefaultStorage(moduleRootManager.getModule()); + String id = isDefaultStorageType ? ClassPathStorageUtil.DEFAULT_STORAGE : ClasspathStorage.SPECIAL_STORAGE; + for (Storage storage : storages) { + if (storage.id().equals(id)) { + return new Storage[]{storage}; } - throw new IllegalArgumentException(); - } - else { - return storages; } + throw new IllegalArgumentException(); } } } diff --git a/platform/platform-impl/src/com/intellij/openapi/components/impl/stores/FileBasedStorage.java b/platform/platform-impl/src/com/intellij/openapi/components/impl/stores/FileBasedStorage.java index 3c49e6a3d264..123a0ced3957 100644 --- a/platform/platform-impl/src/com/intellij/openapi/components/impl/stores/FileBasedStorage.java +++ b/platform/platform-impl/src/com/intellij/openapi/components/impl/stores/FileBasedStorage.java @@ -100,6 +100,13 @@ public class FileBasedStorage extends XmlElementStorage { return new FileSaveSession(storageData); } + public void forceSave() { + XmlElementStorageSaveSession externalizationSession = startExternalization(); + if (externalizationSession != null) { + externalizationSession.forceSave(); + } + } + private class FileSaveSession extends XmlElementStorageSaveSession { protected FileSaveSession(@NotNull StorageData storageData) { super(storageData); diff --git a/platform/platform-impl/src/com/intellij/openapi/components/impl/stores/XmlElementStorage.java b/platform/platform-impl/src/com/intellij/openapi/components/impl/stores/XmlElementStorage.java index 73e3a874d4da..bb2d80f84069 100644 --- a/platform/platform-impl/src/com/intellij/openapi/components/impl/stores/XmlElementStorage.java +++ b/platform/platform-impl/src/com/intellij/openapi/components/impl/stores/XmlElementStorage.java @@ -33,6 +33,7 @@ import org.jetbrains.annotations.Nullable; import java.io.IOException; import java.util.Collection; +import java.util.Collections; import java.util.Map; import java.util.Set; @@ -128,7 +129,7 @@ public abstract class XmlElementStorage extends StateStorageBase { @Override @Nullable - public final ExternalizationSession startExternalization() { + public final XmlElementStorageSaveSession startExternalization() { return checkIsSavingDisabled() ? null : createSaveSession(getStorageData()); } @@ -213,6 +214,21 @@ public abstract class XmlElementStorage extends StateStorageBase { } } + public void forceSave() { + LOG.assertTrue(myCopiedStorageData == null); + + if (myBlockSavingTheContent) { + return; + } + + try { + doSave(getElement(myOriginalStorageData, isCollapsePathsOnSave(), Collections.emptyMap())); + } + catch (IOException e) { + throw new StateStorageException(e); + } + } + @Override public final void save() { if (myBlockSavingTheContent) {