From 1cfaad1bccf2bb270a38d0569481d15fe49e5a86 Mon Sep 17 00:00:00 2001 From: Vladimir Krivosheev Date: Tue, 3 Mar 2015 18:03:06 +0100 Subject: [PATCH] IDEA-133480 Eclipse integration: .iml content is not reduced on setting Dependencies Storage Format = Eclipse --- .../impl/ModuleRootManagerComponent.java | 32 +++--- .../impl/stores/ComponentStoreImpl.java | 100 ++++++++++-------- .../impl/stores/ProjectStoreImpl.java | 5 +- .../impl/stores/StateStorageManagerImpl.java | 9 +- .../components/StateStorageChooser.java | 8 +- .../components/StateStorageChooserEx.java | 27 +++++ 6 files changed, 114 insertions(+), 67 deletions(-) create mode 100644 platform/projectModel-api/src/com/intellij/openapi/components/StateStorageChooserEx.java 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 55c560ce2d21..f4701883ae50 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 @@ -1,5 +1,5 @@ /* - * Copyright 2000-2014 JetBrains s.r.o. + * Copyright 2000-2015 JetBrains s.r.o. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -20,6 +20,7 @@ import com.intellij.openapi.module.Module; import com.intellij.openapi.roots.impl.storage.ClassPathStorageUtil; import com.intellij.openapi.roots.impl.storage.ClasspathStorage; import com.intellij.openapi.vfs.pointers.VirtualFilePointerManager; +import org.jetbrains.annotations.NotNull; /** * @author yole @@ -27,30 +28,29 @@ import com.intellij.openapi.vfs.pointers.VirtualFilePointerManager; @State( name = "NewModuleRootManager", storages = { - @Storage(id = ClassPathStorageUtil.DEFAULT_STORAGE, file = StoragePathMacros.MODULE_FILE), + @Storage(file = StoragePathMacros.MODULE_FILE), @Storage(id = ClasspathStorage.SPECIAL_STORAGE, storageClass = ClasspathStorage.class) - }, - storageChooser = ModuleRootManagerComponent.StorageChooser.class + } ) public class ModuleRootManagerComponent extends ModuleRootManagerImpl implements - PersistentStateComponent { + PersistentStateComponent, + StateStorageChooserEx { public ModuleRootManagerComponent(Module module, ProjectRootManagerImpl projectRootManager, VirtualFilePointerManager filePointerManager) { super(module, projectRootManager, filePointerManager); } - static class StorageChooser implements StateStorageChooser { - @Override - public Storage[] selectStorages(Storage[] storages, ModuleRootManagerImpl moduleRootManager, final StateStorageOperation operation) { - 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(); + @NotNull + @Override + public Resolution getResolution(@NotNull Storage storage, @NotNull StateStorageOperation operation) { + boolean isEffectiveStorage = storage.id().equals(ClassPathStorageUtil.isDefaultStorage(getModule()) ? ClassPathStorageUtil.DEFAULT_STORAGE : ClasspathStorage.SPECIAL_STORAGE); + if (operation == StateStorageOperation.READ) { + return isEffectiveStorage ? Resolution.DO : Resolution.SKIP; + } + else { + // IDEA-133480 Eclipse integration: .iml content is not reduced on setting Dependencies Storage Format = Eclipse + return isEffectiveStorage ? Resolution.DO : (storage.id().equals(ClassPathStorageUtil.DEFAULT_STORAGE) ? Resolution.CLEAR : Resolution.SKIP); } } } diff --git a/platform/platform-impl/src/com/intellij/openapi/components/impl/stores/ComponentStoreImpl.java b/platform/platform-impl/src/com/intellij/openapi/components/impl/stores/ComponentStoreImpl.java index 1653a44b36cb..14ecef7775b7 100644 --- a/platform/platform-impl/src/com/intellij/openapi/components/impl/stores/ComponentStoreImpl.java +++ b/platform/platform-impl/src/com/intellij/openapi/components/impl/stores/ComponentStoreImpl.java @@ -19,6 +19,7 @@ import com.intellij.openapi.application.*; import com.intellij.openapi.application.ex.DecodeDefaultsUtil; import com.intellij.openapi.components.*; import com.intellij.openapi.components.StateStorage.SaveSession; +import com.intellij.openapi.components.StateStorageChooserEx.Resolution; import com.intellij.openapi.components.impl.ComponentManagerImpl; import com.intellij.openapi.components.impl.stores.StateStorageManager.ExternalizationSession; import com.intellij.openapi.components.store.ReadOnlyModificationException; @@ -301,7 +302,13 @@ public abstract class ComponentStoreImpl implements IComponentStore.Reloadable { T state = stateSpec.defaultStateAsResource() ? getDefaultState(component, name, stateClass) : null; Storage[] storageSpecs = getComponentStorageSpecs(component, stateSpec, StateStorageOperation.READ); + StateStorageChooserEx stateStorageChooser = component instanceof StateStorageChooserEx ? (StateStorageChooserEx)component : null; for (Storage storageSpec : storageSpecs) { + Resolution resolution = stateStorageChooser == null ? Resolution.DO : stateStorageChooser.getResolution(storageSpec, StateStorageOperation.READ); + if (resolution == Resolution.SKIP) { + continue; + } + StateStorage stateStorage = getStateStorageManager().getStateStorage(storageSpec); if (stateStorage != null && (stateStorage.hasState(component, name, stateClass, reloadData) || (changedStorages != null && changedStorages.contains(stateStorage)))) { @@ -353,64 +360,67 @@ public abstract class ComponentStoreImpl implements IComponentStore.Reloadable { } @NotNull - protected Storage[] getComponentStorageSpecs(@NotNull PersistentStateComponent persistentStateComponent, - @NotNull State stateSpec, - @NotNull StateStorageOperation operation) { + protected Storage[] getComponentStorageSpecs(@NotNull PersistentStateComponent component, + @NotNull State stateSpec, + @NotNull StateStorageOperation operation) { Storage[] storages = stateSpec.storages(); if (storages.length == 1) { return storages; } assert storages.length > 0; + StateStorageChooser> storageChooser; Class storageChooserClass = stateSpec.storageChooser(); - if (storageChooserClass == StateStorageChooser.class) { - StateStorageChooser> defaultStateStorageChooser = getDefaultStateStorageChooser(); - if (defaultStateStorageChooser == null) { - int actualStorageCount = 0; - for (Storage storage : storages) { - if (!storage.deprecated()) { - actualStorageCount++; - } - } + if (storageChooserClass != StateStorageChooser.class) { + //noinspection unchecked + storageChooser = ReflectionUtil.newInstance(storageChooserClass); + return storageChooser.selectStorages(storages, component, operation); + } - if (actualStorageCount > 1) { - LOG.error("State chooser not specified for: " + persistentStateComponent.getClass()); - } + StateStorageChooser> defaultStateStorageChooser = getDefaultStateStorageChooser(); + if (defaultStateStorageChooser != null) { + return defaultStateStorageChooser.selectStorages(storages, component, operation); + } - if (!storages[0].deprecated()) { - boolean othersAreDeprecated = true; - for (int i = 1; i < storages.length; i++) { - if (!storages[i].deprecated()) { - othersAreDeprecated = false; - break; - } - } + if (component instanceof StateStorageChooserEx) { + return storages; + } - if (othersAreDeprecated) { - return storages; - } - } - - Storage[] sorted = Arrays.copyOf(storages, storages.length); - Arrays.sort(sorted, new Comparator() { - @Override - public int compare(Storage o1, Storage o2) { - int w1 = o1.deprecated() ? 1 : 0; - int w2 = o2.deprecated() ? 1 : 0; - return w1 - w2; - } - }); - return sorted; - } - else { - return defaultStateStorageChooser.selectStorages(storages, persistentStateComponent, operation); + int actualStorageCount = 0; + for (Storage storage : storages) { + if (!storage.deprecated()) { + actualStorageCount++; } } - else { - @SuppressWarnings("unchecked") - StateStorageChooser> storageChooser = ReflectionUtil.newInstance(storageChooserClass); - return storageChooser.selectStorages(storages, persistentStateComponent, operation); + + if (actualStorageCount > 1) { + LOG.error("State chooser not specified for: " + component.getClass()); } + + if (!storages[0].deprecated()) { + boolean othersAreDeprecated = true; + for (int i = 1; i < storages.length; i++) { + if (!storages[i].deprecated()) { + othersAreDeprecated = false; + break; + } + } + + if (othersAreDeprecated) { + return storages; + } + } + + Storage[] sorted = Arrays.copyOf(storages, storages.length); + Arrays.sort(sorted, new Comparator() { + @Override + public int compare(Storage o1, Storage o2) { + int w1 = o1.deprecated() ? 1 : 0; + int w2 = o2.deprecated() ? 1 : 0; + return w1 - w2; + } + }); + return sorted; } protected boolean optimizeTestLoading() { diff --git a/platform/platform-impl/src/com/intellij/openapi/components/impl/stores/ProjectStoreImpl.java b/platform/platform-impl/src/com/intellij/openapi/components/impl/stores/ProjectStoreImpl.java index a3e48f6e3b21..851b1eb2eefa 100644 --- a/platform/platform-impl/src/com/intellij/openapi/components/impl/stores/ProjectStoreImpl.java +++ b/platform/platform-impl/src/com/intellij/openapi/components/impl/stores/ProjectStoreImpl.java @@ -503,6 +503,7 @@ class ProjectStoreImpl extends BaseFileConfigurableStoreImpl implements IProject } private final StateStorageChooser> myStateStorageChooser = new StateStorageChooser>() { + @NotNull @Override public Storage[] selectStorages(@NotNull Storage[] storages, @NotNull PersistentStateComponent component, @NotNull StateStorageOperation operation) { if (operation == StateStorageOperation.READ) { @@ -561,12 +562,12 @@ class ProjectStoreImpl extends BaseFileConfigurableStoreImpl implements IProject @NotNull @Override - protected Storage[] getComponentStorageSpecs(@NotNull PersistentStateComponent persistentStateComponent, + protected Storage[] getComponentStorageSpecs(@NotNull PersistentStateComponent component, @NotNull State stateSpec, @NotNull StateStorageOperation operation) { // if we create project from default, component state written not to own storage file, but to project file, // we don't have time to fix it properly, so, ancient hack restored. - Storage[] result = super.getComponentStorageSpecs(persistentStateComponent, stateSpec, operation); + Storage[] result = super.getComponentStorageSpecs(component, stateSpec, operation); // don't add fake storage if project file storage already listed, otherwise data will be deleted on write (because of "deprecated") for (Storage storage : result) { if (storage.file().equals(StoragePathMacros.PROJECT_FILE)) { diff --git a/platform/platform-impl/src/com/intellij/openapi/components/impl/stores/StateStorageManagerImpl.java b/platform/platform-impl/src/com/intellij/openapi/components/impl/stores/StateStorageManagerImpl.java index 22019ff4cde7..a5bc72b91bb7 100644 --- a/platform/platform-impl/src/com/intellij/openapi/components/impl/stores/StateStorageManagerImpl.java +++ b/platform/platform-impl/src/com/intellij/openapi/components/impl/stores/StateStorageManagerImpl.java @@ -20,6 +20,7 @@ import com.intellij.openapi.application.Application; import com.intellij.openapi.application.ApplicationManager; import com.intellij.openapi.components.*; import com.intellij.openapi.components.StateStorage.SaveSession; +import com.intellij.openapi.components.StateStorageChooserEx.Resolution; import com.intellij.openapi.diagnostic.Logger; import com.intellij.openapi.util.Couple; import com.intellij.openapi.util.Disposer; @@ -290,12 +291,18 @@ public abstract class StateStorageManagerImpl implements StateStorageManager, Di @Override public void setState(@NotNull Storage[] storageSpecs, @NotNull Object component, @NotNull String componentName, @NotNull Object state) { + StateStorageChooserEx stateStorageChooser = component instanceof StateStorageChooserEx ? (StateStorageChooserEx)component : null; for (Storage storageSpec : storageSpecs) { + Resolution resolution = stateStorageChooser == null ? Resolution.DO : stateStorageChooser.getResolution(storageSpec, StateStorageOperation.WRITE); + if (resolution == Resolution.SKIP) { + continue; + } + StateStorage stateStorage = getStateStorage(storageSpec); StateStorage.ExternalizationSession session = getExternalizationSession(stateStorage); if (session != null) { // empty element as null state, so, will be deleted - session.setState(component, componentName, storageSpec.deprecated() ? new Element("empty") : state, storageSpec); + session.setState(component, componentName, storageSpec.deprecated() || resolution == Resolution.CLEAR ? new Element("empty") : state, storageSpec); } } } diff --git a/platform/projectModel-api/src/com/intellij/openapi/components/StateStorageChooser.java b/platform/projectModel-api/src/com/intellij/openapi/components/StateStorageChooser.java index ddcd7aef9087..aecd512b3cbd 100644 --- a/platform/projectModel-api/src/com/intellij/openapi/components/StateStorageChooser.java +++ b/platform/projectModel-api/src/com/intellij/openapi/components/StateStorageChooser.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2012 JetBrains s.r.o. + * Copyright 2000-2015 JetBrains s.r.o. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -13,9 +13,11 @@ * See the License for the specific language governing permissions and * limitations under the License. */ - package com.intellij.openapi.components; +import org.jetbrains.annotations.NotNull; + public interface StateStorageChooser { - Storage[] selectStorages(Storage[] storages, T component, final StateStorageOperation operation); + @NotNull + Storage[] selectStorages(Storage[] storages, T component, @NotNull StateStorageOperation operation); } diff --git a/platform/projectModel-api/src/com/intellij/openapi/components/StateStorageChooserEx.java b/platform/projectModel-api/src/com/intellij/openapi/components/StateStorageChooserEx.java new file mode 100644 index 000000000000..3cb10442dbc8 --- /dev/null +++ b/platform/projectModel-api/src/com/intellij/openapi/components/StateStorageChooserEx.java @@ -0,0 +1,27 @@ +/* + * Copyright 2000-2015 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.intellij.openapi.components; + +import org.jetbrains.annotations.NotNull; + +public interface StateStorageChooserEx { + enum Resolution { + DO, SKIP, CLEAR + } + + @NotNull + Resolution getResolution(@NotNull Storage storage, @NotNull StateStorageOperation operation); +} \ No newline at end of file