From 19b5bc5896760811ae213753d10c6d991558da73 Mon Sep 17 00:00:00 2001 From: Kirill Likhodedov Date: Tue, 3 Mar 2015 19:18:57 +0300 Subject: [PATCH 1/2] [git] IDEA-92750 Return "ls-remote" button to the pull dialog --- .../git4idea/src/git4idea/commands/Git.java | 7 +++ .../src/git4idea/commands/GitImpl.java | 33 +++++++++- .../src/git4idea/i18n/GitBundle.properties | 2 +- .../src/git4idea/merge/GitPullDialog.form | 11 +++- .../src/git4idea/merge/GitPullDialog.java | 60 +++++++++++++++++++ 5 files changed, 108 insertions(+), 5 deletions(-) diff --git a/plugins/git4idea/src/git4idea/commands/Git.java b/plugins/git4idea/src/git4idea/commands/Git.java index 6ee38014fb34..836a6a7d8b79 100644 --- a/plugins/git4idea/src/git4idea/commands/Git.java +++ b/plugins/git4idea/src/git4idea/commands/Git.java @@ -22,6 +22,7 @@ import com.intellij.openapi.vfs.VirtualFile; import git4idea.GitCommit; import git4idea.GitLocalBranch; import git4idea.GitRemoteBranch; +import git4idea.repo.GitRemote; import git4idea.repo.GitRepository; import git4idea.reset.GitResetMode; import org.jetbrains.annotations.NotNull; @@ -150,4 +151,10 @@ public interface Git { @NotNull GitCommandResult lsRemote(@NotNull Project project, @NotNull File workingDir, @NotNull String url); + + @NotNull + GitCommandResult lsRemote(@NotNull Project project, + @NotNull VirtualFile workingDir, + @NotNull GitRemote remote, + String... additionalParameters); } diff --git a/plugins/git4idea/src/git4idea/commands/GitImpl.java b/plugins/git4idea/src/git4idea/commands/GitImpl.java index 0d6c7e75437d..695ea348bc76 100644 --- a/plugins/git4idea/src/git4idea/commands/GitImpl.java +++ b/plugins/git4idea/src/git4idea/commands/GitImpl.java @@ -21,6 +21,7 @@ import com.intellij.openapi.util.Computable; import com.intellij.openapi.util.Key; import com.intellij.openapi.util.text.StringUtil; import com.intellij.openapi.vcs.VcsException; +import com.intellij.openapi.vfs.VfsUtilCore; import com.intellij.openapi.vfs.VirtualFile; import com.intellij.vcsUtil.VcsFileUtil; import git4idea.*; @@ -507,13 +508,39 @@ public class GitImpl implements Git { @NotNull @Override - public GitCommandResult lsRemote(@NotNull final Project project, @NotNull final File workingDir, @NotNull final String url) { + public GitCommandResult lsRemote(@NotNull final Project project, + @NotNull final File workingDir, + @NotNull final String url) { + return doLsRemote(project, workingDir, url, url); + } + + @NotNull + @Override + public GitCommandResult lsRemote(@NotNull Project project, + @NotNull VirtualFile workingDir, + @NotNull GitRemote remote, + String... additionalParameters) { + return doLsRemote(project, VfsUtilCore.virtualToIoFile(workingDir), remote.getName(), remote.getFirstUrl(), additionalParameters); + } + + @NotNull + private GitCommandResult doLsRemote(@NotNull final Project project, + @NotNull final File workingDir, + @NotNull final String remoteId, + @Nullable final String authenticationUrl, + final String... additionalParameters) { return run(new Computable() { @Override public GitLineHandler compute() { GitLineHandler h = new GitLineHandler(project, workingDir, GitCommand.LS_REMOTE); - h.addParameters(url); - h.setUrl(url); + h.addParameters(additionalParameters); + h.addParameters(remoteId); + if (authenticationUrl != null) { + h.setUrl(authenticationUrl); + } + else { + LOG.error("No valid URLs for remote " + remoteId); + } return h; } }); diff --git a/plugins/git4idea/src/git4idea/i18n/GitBundle.properties b/plugins/git4idea/src/git4idea/i18n/GitBundle.properties index a48c05400bf3..0b373bae9fef 100644 --- a/plugins/git4idea/src/git4idea/i18n/GitBundle.properties +++ b/plugins/git4idea/src/git4idea/i18n/GitBundle.properties @@ -181,7 +181,7 @@ pull.button=Pull pull.force.reference.update=Force reference &update pull.get.branches.tooltip=Get branch names from remote repository. Otherwise a locally cached information is used. pull.get.branches=&Get Branches -pull.getting.remote.branches=Getting remote branches +pull.getting.remote.branches=Getting Remote Branches... pull.remote.tooltip=Registered remote name or URL. pull.remote=Re&mote: pull.retrieving.remotes=Retrieving remotes diff --git a/plugins/git4idea/src/git4idea/merge/GitPullDialog.form b/plugins/git4idea/src/git4idea/merge/GitPullDialog.form index d4be626c20ed..ffe7a4e46691 100644 --- a/plugins/git4idea/src/git4idea/merge/GitPullDialog.form +++ b/plugins/git4idea/src/git4idea/merge/GitPullDialog.form @@ -132,7 +132,7 @@ - + @@ -149,6 +149,15 @@ + + + + + + + + + diff --git a/plugins/git4idea/src/git4idea/merge/GitPullDialog.java b/plugins/git4idea/src/git4idea/merge/GitPullDialog.java index be1ebac877ab..1839f31d5e18 100644 --- a/plugins/git4idea/src/git4idea/merge/GitPullDialog.java +++ b/plugins/git4idea/src/git4idea/merge/GitPullDialog.java @@ -15,18 +15,28 @@ */ package git4idea.merge; +import com.intellij.icons.AllIcons; import com.intellij.ide.util.ElementsChooser; +import com.intellij.openapi.components.ServiceManager; import com.intellij.openapi.diagnostic.Logger; +import com.intellij.openapi.progress.ProgressIndicator; +import com.intellij.openapi.progress.ProgressManager; +import com.intellij.openapi.progress.Task; import com.intellij.openapi.project.Project; import com.intellij.openapi.ui.DialogWrapper; +import com.intellij.openapi.ui.Messages; +import com.intellij.openapi.util.Ref; import com.intellij.openapi.util.text.StringUtil; import com.intellij.openapi.vfs.VirtualFile; import com.intellij.ui.ListCellRendererWrapper; import com.intellij.util.Function; import com.intellij.util.containers.ContainerUtil; +import git4idea.GitBranch; import git4idea.GitRemoteBranch; import git4idea.GitUtil; +import git4idea.commands.Git; import git4idea.commands.GitCommand; +import git4idea.commands.GitCommandResult; import git4idea.commands.GitLineHandler; import git4idea.i18n.GitBundle; import git4idea.repo.GitBranchTrackInfo; @@ -58,15 +68,19 @@ public class GitPullDialog extends DialogWrapper { private JCheckBox myNoFastForwardCheckBox; private JCheckBox myAddLogInformationCheckBox; private JComboBox myRemote; + private JButton myGetBranchesButton; private ElementsChooser myBranchChooser; private final Project myProject; private final GitRepositoryManager myRepositoryManager; + private final Git myGit; public GitPullDialog(Project project, List roots, VirtualFile defaultRoot) { super(project, true); setTitle(GitBundle.getString("pull.title")); myProject = project; myRepositoryManager = GitUtil.getRepositoryManager(myProject); + myGit = ServiceManager.getService(Git.class); + GitUIUtil.setupRootChooser(myProject, roots, defaultRoot, myGitRoot, myCurrentBranch); myGitRoot.addActionListener(new ActionListener() { public void actionPerformed(final ActionEvent e) { @@ -76,6 +90,7 @@ public class GitPullDialog extends DialogWrapper { setOKButtonText(GitBundle.getString("pull.button")); updateRemotes(); updateBranches(); + setupGetBranches(); myRemote.addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent e) { @@ -96,6 +111,51 @@ public class GitPullDialog extends DialogWrapper { init(); } + private void setupGetBranches() { + myGetBranchesButton.setIcon(AllIcons.Actions.Refresh); + myGetBranchesButton.setEnabled(myRemote.getItemCount() >= 1); + myGetBranchesButton.addActionListener(new ActionListener() { + public void actionPerformed(final ActionEvent e) { + GitRemote selectedItem = (GitRemote)myRemote.getSelectedItem(); + Collection remoteBranches = selectedItem != null ? getRemoteBranches(selectedItem) : null; + if (remoteBranches != null) { + myBranchChooser.removeAllElements(); + for (String branch : remoteBranches) { + myBranchChooser.addElement(branch, false); + } + } + } + }); + } + + @Nullable + private Collection getRemoteBranches(@NotNull final GitRemote remote) { + final Ref result = Ref.create(); + ProgressManager.getInstance().run(new Task.Modal(myProject, GitBundle.getString("pull.getting.remote.branches"), false) { + @Override + public void run(@NotNull ProgressIndicator indicator) { + indicator.setIndeterminate(true); + result.set(myGit.lsRemote(GitPullDialog.this.myProject, gitRoot(), remote, "--heads")); + } + }); + + if (!result.isNull() && result.get().success()) { + return ContainerUtil.mapNotNull(result.get().getOutput(), new Function() { + @Override + public String fun(@NotNull String line) { + if (StringUtil.isEmptyOrSpaces(line)) return null; + String shortRemoteName = line.trim().substring(line.indexOf(GitBranch.REFS_HEADS_PREFIX) + GitBranch.REFS_HEADS_PREFIX.length()); + return remote.getName() + "/" + shortRemoteName; + } + }); + } + else { + String message = result.isNull() ? "" : result.get().getErrorOutputAsJoinedString(); + Messages.showErrorDialog(this.getRootPane(), message, "Couldn't get the remote branches list from " + remote.getName()); + return null; + } + } + private void validateDialog() { String selectedRemote = getRemote(); if (StringUtil.isEmptyOrSpaces(selectedRemote)) { From 1cfaad1bccf2bb270a38d0569481d15fe49e5a86 Mon Sep 17 00:00:00 2001 From: Vladimir Krivosheev Date: Tue, 3 Mar 2015 18:03:06 +0100 Subject: [PATCH 2/2] 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