diff --git a/java/java-analysis-impl/src/com/intellij/codeInsight/daemon/impl/actions/SuppressFix.java b/java/java-analysis-impl/src/com/intellij/codeInsight/daemon/impl/actions/SuppressFix.java index 463d16b9838f..14f158f9b889 100644 --- a/java/java-analysis-impl/src/com/intellij/codeInsight/daemon/impl/actions/SuppressFix.java +++ b/java/java-analysis-impl/src/com/intellij/codeInsight/daemon/impl/actions/SuppressFix.java @@ -172,7 +172,7 @@ public class SuppressFix extends AbstractBatchSuppressByNoInspectionCommentFix { if (alternativeID != null) { final Module module = ModuleUtilCore.findModuleForPsiElement(place); if (module != null) { - if (!ClassPathStorageUtil.isDefaultStorage(module)) { + if (ClassPathStorageUtil.isClasspathStorage(module)) { return alternativeID; } } diff --git a/platform/configuration-store-impl/src/ComponentStoreImpl.kt b/platform/configuration-store-impl/src/ComponentStoreImpl.kt index c826ea395fa7..61cff276d3cc 100644 --- a/platform/configuration-store-impl/src/ComponentStoreImpl.kt +++ b/platform/configuration-store-impl/src/ComponentStoreImpl.kt @@ -375,15 +375,15 @@ abstract class ComponentStoreImpl : IComponentStore { } } - protected open fun getStorageSpecs(component: PersistentStateComponent, stateSpec: State, operation: StateStorageOperation): Array { + protected open fun getStorageSpecs(component: PersistentStateComponent, stateSpec: State, operation: StateStorageOperation): List { val storages = stateSpec.storages if (storages.size == 1 || component is StateStorageChooserEx) { - return storages + return storages.toList() } if (storages.isEmpty()) { if (stateSpec.defaultStateAsResource) { - return storages + return emptyList() } throw AssertionError("No storage specified") @@ -513,26 +513,26 @@ enum class StateLoadPolicy { LOAD, LOAD_ONLY_DEFAULT, NOT_LOAD } -internal fun Array.sortByDeprecated(): Array { - if (isEmpty()) { - return this +internal fun Array.sortByDeprecated(): List { + if (size < 2) { + return toList() } - if (!this[0].deprecated) { + if (!first().deprecated) { var othersAreDeprecated = true for (i in 1..size - 1) { - if (!this[i].deprecated) { + if (!get(i).deprecated) { othersAreDeprecated = false break } } if (othersAreDeprecated) { - return this + return toList() } } - return sortedArrayWith(deprecatedComparator) + return sortedWith(deprecatedComparator) } private fun notifyUnknownMacros(store: IComponentStore, project: Project, componentName: String) { diff --git a/platform/configuration-store-impl/src/DefaultProjectStoreImpl.kt b/platform/configuration-store-impl/src/DefaultProjectStoreImpl.kt index 35fd692c10d0..83e17b63b525 100644 --- a/platform/configuration-store-impl/src/DefaultProjectStoreImpl.kt +++ b/platform/configuration-store-impl/src/DefaultProjectStoreImpl.kt @@ -83,13 +83,13 @@ internal class DefaultProjectStoreImpl(override val project: ProjectImpl, privat override fun getPathMacroManagerForDefaults() = pathMacroManager - override fun getStorageSpecs(component: PersistentStateComponent, stateSpec: State, operation: StateStorageOperation) = arrayOf(PROJECT_FILE_STORAGE_ANNOTATION) + override fun getStorageSpecs(component: PersistentStateComponent, stateSpec: State, operation: StateStorageOperation) = listOf(PROJECT_FILE_STORAGE_ANNOTATION) override fun setPath(path: String) { } private class MyExternalizationSession(val externalizationSession: StateStorage.ExternalizationSession) : StateStorageManager.ExternalizationSession { - override fun setState(storageSpecs: Array, component: Any, componentName: String, state: Any) { + override fun setState(storageSpecs: List, component: Any, componentName: String, state: Any) { externalizationSession.setState(component, componentName, state) } diff --git a/platform/configuration-store-impl/src/FileStorageAnnotation.java b/platform/configuration-store-impl/src/FileStorageAnnotation.java index 1e588f6432ff..238d0eb3eb61 100644 --- a/platform/configuration-store-impl/src/FileStorageAnnotation.java +++ b/platform/configuration-store-impl/src/FileStorageAnnotation.java @@ -2,18 +2,25 @@ package com.intellij.configurationStore; import com.intellij.openapi.components.*; import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; import java.lang.annotation.Annotation; @SuppressWarnings("ClassExplicitlyAnnotation") -final class FileStorageAnnotation implements Storage { +public final class FileStorageAnnotation implements Storage { private String path; private boolean deprecated; + private final Class storageClass; - FileStorageAnnotation(String path, boolean deprecated) { + public FileStorageAnnotation(@NotNull String path, boolean deprecated) { + this(path, deprecated, StateStorage.class); + } + + public FileStorageAnnotation(@NotNull String path, boolean deprecated, @Nullable Class storageClass) { this.path = path; this.deprecated = deprecated; + this.storageClass = storageClass; } @Override @@ -53,7 +60,7 @@ final class FileStorageAnnotation implements Storage { @Override public Class storageClass() { - return StateStorage.class; + return storageClass; } @Override diff --git a/platform/configuration-store-impl/src/ModuleStoreImpl.kt b/platform/configuration-store-impl/src/ModuleStoreImpl.kt index 02248dcfca7e..08de48231eaa 100644 --- a/platform/configuration-store-impl/src/ModuleStoreImpl.kt +++ b/platform/configuration-store-impl/src/ModuleStoreImpl.kt @@ -16,8 +16,10 @@ package com.intellij.configurationStore import com.intellij.openapi.components.* +import com.intellij.openapi.diagnostic.catchAndLog import com.intellij.openapi.module.Module import com.intellij.openapi.vfs.VirtualFile +import com.intellij.util.containers.computeOrNull import com.intellij.util.io.exists import java.nio.file.Paths @@ -30,34 +32,42 @@ private open class ModuleStoreImpl(module: Module, private val pathMacroManager: override final fun getPathMacroManagerForDefaults() = pathMacroManager - private class TestModuleStore(module: Module, pathMacroManager: PathMacroManager) : ModuleStoreImpl(module, pathMacroManager) { - private var moduleComponentLoadPolicy: StateLoadPolicy? = null - - override fun setPath(path: String) { - setPath(path, null) - } - - override fun setPath(path: String, file: VirtualFile?) { - super.setPath(path, file) - - if ((file != null && file.isValid) || Paths.get(path).exists()) { - moduleComponentLoadPolicy = StateLoadPolicy.LOAD - } - } - - override val loadPolicy: StateLoadPolicy - get() = moduleComponentLoadPolicy ?: (project.stateStore as ComponentStoreImpl).loadPolicy + // todo what about Upsource? For now this implemented not in the ModuleStoreBase because `project` and `module` are available only in this class (ModuleStoreImpl) + override fun getStorageSpecs(component: PersistentStateComponent, stateSpec: State, operation: StateStorageOperation): List { + val result = super.getStorageSpecs(component, stateSpec, operation) + return StreamProviderFactory.EP_NAME.getExtensions(project).computeOrNull { + LOG.catchAndLog { it.customizeStorageSpecs(component, storageManager.componentManager!!, result, operation) } + } ?: result } } +private class TestModuleStore(module: Module, pathMacroManager: PathMacroManager) : ModuleStoreImpl(module, pathMacroManager) { + private var moduleComponentLoadPolicy: StateLoadPolicy? = null + + override fun setPath(path: String) { + setPath(path, null) + } + + override fun setPath(path: String, file: VirtualFile?) { + super.setPath(path, file) + + if ((file != null && file.isValid) || Paths.get(path).exists()) { + moduleComponentLoadPolicy = StateLoadPolicy.LOAD + } + } + + override val loadPolicy: StateLoadPolicy + get() = moduleComponentLoadPolicy ?: (project.stateStore as ComponentStoreImpl).loadPolicy +} + // used in upsource abstract class ModuleStoreBase : ComponentStoreImpl() { override abstract val storageManager: StateStorageManagerImpl - override final fun getStorageSpecs(component: PersistentStateComponent, stateSpec: State, operation: StateStorageOperation): Array { + override fun getStorageSpecs(component: PersistentStateComponent, stateSpec: State, operation: StateStorageOperation): List { val storages = stateSpec.storages return if (storages.isEmpty()) { - arrayOf(MODULE_FILE_STORAGE_ANNOTATION) + listOf(MODULE_FILE_STORAGE_ANNOTATION) } else { super.getStorageSpecs(component, stateSpec, operation) diff --git a/platform/configuration-store-impl/src/ProjectStoreImpl.kt b/platform/configuration-store-impl/src/ProjectStoreImpl.kt index a9fe5d83a3f6..aff0c40db0a7 100644 --- a/platform/configuration-store-impl/src/ProjectStoreImpl.kt +++ b/platform/configuration-store-impl/src/ProjectStoreImpl.kt @@ -177,10 +177,10 @@ abstract class ProjectStoreBase(override final val project: ProjectImpl) : Compo } } - override fun getStorageSpecs(component: PersistentStateComponent, stateSpec: State, operation: StateStorageOperation): Array { + override fun getStorageSpecs(component: PersistentStateComponent, stateSpec: State, operation: StateStorageOperation): List { val storages = stateSpec.storages if (storages.isEmpty()) { - return arrayOf(PROJECT_FILE_STORAGE_ANNOTATION) + return listOf(PROJECT_FILE_STORAGE_ANNOTATION) } if (isDirectoryBased) { @@ -196,14 +196,14 @@ abstract class ProjectStoreBase(override final val project: ProjectImpl) : Compo } if (result.isNullOrEmpty()) { - return arrayOf(PROJECT_FILE_STORAGE_ANNOTATION) + return listOf(PROJECT_FILE_STORAGE_ANNOTATION) } else { result!!.sortWith(deprecatedComparator) // 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 result.add(DEPRECATED_PROJECT_FILE_STORAGE_ANNOTATION) - return result.toTypedArray() + return result } } else { @@ -223,14 +223,14 @@ abstract class ProjectStoreBase(override final val project: ProjectImpl) : Compo } } if (result.isNullOrEmpty()) { - return arrayOf(PROJECT_FILE_STORAGE_ANNOTATION) + return listOf(PROJECT_FILE_STORAGE_ANNOTATION) } else { if (hasOnlyDeprecatedStorages) { result!!.add(PROJECT_FILE_STORAGE_ANNOTATION) } result!!.sortWith(deprecatedComparator) - return result.toTypedArray() + return result } } } diff --git a/platform/configuration-store-impl/src/StateStorageManagerImpl.kt b/platform/configuration-store-impl/src/StateStorageManagerImpl.kt index 56ae30dee4da..77066fb15124 100644 --- a/platform/configuration-store-impl/src/StateStorageManagerImpl.kt +++ b/platform/configuration-store-impl/src/StateStorageManagerImpl.kt @@ -384,7 +384,7 @@ open class StateStorageManagerImpl(private val rootTagName: String, override final fun startExternalization() = object : StateStorageManager.ExternalizationSession { private val sessions = LinkedHashMap() - override fun setState(storageSpecs: Array, component: Any, componentName: String, state: Any) { + override fun setState(storageSpecs: List, component: Any, componentName: String, state: Any) { val stateStorageChooser = component as? StateStorageChooserEx for (storageSpec in storageSpecs) { @Suppress("IfThenToElvis") diff --git a/platform/external-system-impl/external-system-impl.iml b/platform/external-system-impl/external-system-impl.iml index e16919a7e633..78494e25b07c 100644 --- a/platform/external-system-impl/external-system-impl.iml +++ b/platform/external-system-impl/external-system-impl.iml @@ -27,5 +27,6 @@ + \ No newline at end of file diff --git a/platform/external-system-impl/src/com/intellij/openapi/externalSystem/configurationStore/ExternalSystemStorage.kt b/platform/external-system-impl/src/com/intellij/openapi/externalSystem/configurationStore/ExternalSystemStorage.kt new file mode 100644 index 000000000000..4d4b9e3aecea --- /dev/null +++ b/platform/external-system-impl/src/com/intellij/openapi/externalSystem/configurationStore/ExternalSystemStorage.kt @@ -0,0 +1,46 @@ +/* + * Copyright 2000-2017 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.externalSystem.configurationStore + +import com.intellij.configurationStore.* +import com.intellij.openapi.components.RoamingType +import com.intellij.openapi.components.StoragePathMacros +import com.intellij.openapi.module.Module +import com.intellij.openapi.util.io.BufferExposingByteArrayOutputStream +import org.jdom.Element +import java.io.ByteArrayInputStream + +internal class ExternalProjectStorage(private val module: Module, storageManager: StateStorageManager) : XmlElementStorage(StoragePathMacros.MODULE_FILE, null, storageManager.macroSubstitutor, RoamingType.DISABLED) { + private val manager = StreamProviderFactory.EP_NAME.getExtensions(module.project).first { it is ExternalSystemStreamProviderFactory } as ExternalSystemStreamProviderFactory + + override public fun loadLocalData(): Element? { + val data = manager.nameToData.get(module.name) ?: return null + return ByteArrayInputStream(data).use { readElement(it) } + } + + override fun createSaveSession(states: StateMap) = object : XmlElementStorageSaveSession(states, this) { + override fun saveLocally(element: Element?) { + if (element == null) { + manager.nameToData.remove(module.name) + } + else { + val byteOut = BufferExposingByteArrayOutputStream() + serializeElementToBinary(element, byteOut) + manager.nameToData.put(module.name, byteOut.toByteArray()) + } + } + } +} \ No newline at end of file diff --git a/platform/external-system-impl/src/com/intellij/openapi/externalSystem/configurationStore/ExternalSystemStreamProviderFactory.kt b/platform/external-system-impl/src/com/intellij/openapi/externalSystem/configurationStore/ExternalSystemStreamProviderFactory.kt new file mode 100644 index 000000000000..fc621b2534f8 --- /dev/null +++ b/platform/external-system-impl/src/com/intellij/openapi/externalSystem/configurationStore/ExternalSystemStreamProviderFactory.kt @@ -0,0 +1,121 @@ +/* + * Copyright 2000-2017 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.externalSystem.configurationStore + +import com.intellij.configurationStore.FileStorageAnnotation +import com.intellij.configurationStore.StreamProviderFactory +import com.intellij.openapi.Disposable +import com.intellij.openapi.application.ApplicationManager +import com.intellij.openapi.components.* +import com.intellij.openapi.diagnostic.catchAndLog +import com.intellij.openapi.diagnostic.logger +import com.intellij.openapi.externalSystem.service.project.manage.ExternalProjectsDataStorage +import com.intellij.openapi.module.Module +import com.intellij.openapi.project.Project +import com.intellij.openapi.project.ex.ProjectEx +import com.intellij.openapi.roots.ExternalProjectSystemRegistry +import com.intellij.openapi.roots.ProjectModelElement +import com.intellij.openapi.util.Disposer +import com.intellij.openapi.util.io.FileUtil +import com.intellij.openapi.util.registry.Registry +import com.intellij.util.io.DataExternalizer +import com.intellij.util.io.EnumeratorStringDescriptor +import com.intellij.util.io.PersistentHashMap +import java.io.* +import java.util.* + +private val EXTERNAL_STORAGE_ANNOTATION = FileStorageAnnotation(StoragePathMacros.MODULE_FILE, false, ExternalProjectStorage::class.java) +private val LOG = logger() + +// todo handle module rename +internal class ExternalSystemStreamProviderFactory(private val project: Project) : StreamProviderFactory { + val nameToData = createStorage(project) + private var isStorageFlushed = true + + init { + Disposer.register(project, Disposable { nameToData.close() }) + + // flush on save to be sure that data is saved (it is easy to reimport if corrupted (force exit, blue screen), but we need to avoid it if possible) + ApplicationManager.getApplication().messageBus + .connect(project) + .subscribe(ProjectEx.ProjectSaved.TOPIC, ProjectEx.ProjectSaved { + if (it === project && !isStorageFlushed && nameToData.isDirty) { + isStorageFlushed = false + ApplicationManager.getApplication().executeOnPooledThread { + try { + LOG.catchAndLog { nameToData.force() } + } + finally { + isStorageFlushed = true + } + } + } + }) + } + + override fun customizeStorageSpecs(component: PersistentStateComponent<*>, componentManager: ComponentManager, storages: List, operation: StateStorageOperation): List? { + if (componentManager !is Module || component !is ProjectModelElement || !Registry.`is`("store.imported.project.elements.separately", false)) { + return null + } + + if (operation == StateStorageOperation.WRITE) { + // Keep in mind - this call will require storage for module because module option values are used. + // We cannot just check that module name exists in the nameToData - new external system module will be not in the nameToData because not yet saved. + @Suppress("INTERFACE_STATIC_METHOD_CALL_FROM_JAVA6_TARGET") + if (ExternalProjectSystemRegistry.getInstance().getExternalSource(componentManager) == null) { + return null + } + } + else { + // on read we cannot check because on import module is just created and not yet marked as external system module, + // so, we just add our storage as first and default storages in the end as fallback + val result = ArrayList(storages.size + 1) + result.add(EXTERNAL_STORAGE_ANNOTATION) + result.addAll(storages) + return result + } + + // todo we can return on StateStorageOperation.WRITE default iml storage and then somehow using StateStorageChooserEx return Resolution.CLEAR to remove data from iml + return listOf(EXTERNAL_STORAGE_ANNOTATION) + } +} + +private fun createStorage(project: Project): PersistentHashMap { + val file = File(ExternalProjectsDataStorage.getProjectConfigurationDir(), "${project.locationHash}/projectConfiguration") + + fun createMap() = PersistentHashMap(file, EnumeratorStringDescriptor.INSTANCE, object : DataExternalizer { + override fun read(`in`: DataInput): ByteArray { + val available = (`in` as InputStream).available() + val result = ByteArray(available) + `in`.readFully(result) + return result + } + + override fun save(out: DataOutput, value: ByteArray) { + out.write(value) + } + }) + + try { + return createMap() + } + catch (e: IOException) { + // todo force project reimport + LOG.info(e) + FileUtil.delete(file) + } + return createMap() +} \ No newline at end of file diff --git a/platform/external-system-impl/src/com/intellij/openapi/externalSystem/service/project/manage/ExternalProjectsDataStorage.java b/platform/external-system-impl/src/com/intellij/openapi/externalSystem/service/project/manage/ExternalProjectsDataStorage.java index cc7d901fdaa8..84ea3a59e32b 100644 --- a/platform/external-system-impl/src/com/intellij/openapi/externalSystem/service/project/manage/ExternalProjectsDataStorage.java +++ b/platform/external-system-impl/src/com/intellij/openapi/externalSystem/service/project/manage/ExternalProjectsDataStorage.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2016 JetBrains s.r.o. + * Copyright 2000-2017 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. @@ -394,7 +394,7 @@ public class ExternalProjectsDataStorage implements SettingsSavingComponent, Per return new File(getProjectConfigurationDir(), project.getLocationHash() + "/project.dat"); } - private static File getProjectConfigurationDir() { + public static File getProjectConfigurationDir() { return getExternalBuildSystemDir("Projects"); } 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 621d03db9245..6cebf1538e67 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 @@ -51,14 +51,16 @@ public class ModuleRootManagerComponent extends ModuleRootManagerImpl implements @NotNull @Override public Resolution getResolution(@NotNull Storage storage, @NotNull StateStorageOperation operation) { - boolean isDefault = storage.storageClass() == StateStorage.class; - boolean isEffectiveStorage = ClassPathStorageUtil.isDefaultStorage(getModule()) == isDefault; + boolean isClasspathStorage = storage.storageClass() == ClasspathStorage.class; + boolean isEffectiveStorage = ClassPathStorageUtil.isClasspathStorage(getModule()) == isClasspathStorage; 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 : (isDefault ? Resolution.CLEAR : Resolution.SKIP); + // We clear any storage except eclipse (because we must not clear shared files). + // Currently there is only one known non-default storage - ExternalProjectStorage. + return isEffectiveStorage ? Resolution.DO : (isClasspathStorage ? Resolution.SKIP : Resolution.CLEAR); } } diff --git a/platform/platform-api/src/com/intellij/openapi/fileChooser/FileChooserDescriptor.java b/platform/platform-api/src/com/intellij/openapi/fileChooser/FileChooserDescriptor.java index b2f47c2c7514..5fb377ddcd0e 100644 --- a/platform/platform-api/src/com/intellij/openapi/fileChooser/FileChooserDescriptor.java +++ b/platform/platform-api/src/com/intellij/openapi/fileChooser/FileChooserDescriptor.java @@ -27,6 +27,7 @@ import com.intellij.ui.LayeredIcon; import com.intellij.ui.UIBundle; import com.intellij.util.IconUtil; import com.intellij.util.PlatformIcons; +import gnu.trove.THashMap; import org.jetbrains.annotations.Nls; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; @@ -56,7 +57,7 @@ public class FileChooserDescriptor implements Cloneable { private Condition myFileFilter = null; private boolean myForcedToUseIdeaFileChooser = false; - private final Map myUserData = new HashMap<>(); + private final Map myUserData = new THashMap<>(); /** * Creates new instance. Use methods from {@link FileChooserDescriptorFactory} for most used descriptors. @@ -344,7 +345,7 @@ public class FileChooserDescriptor implements Cloneable { } @Nullable - public Object getUserData(String dataId) { + public Object getUserData(@NotNull String dataId) { return myUserData.get(dataId); } diff --git a/platform/platform-resources/src/META-INF/ExternalSystemExtensions.xml b/platform/platform-resources/src/META-INF/ExternalSystemExtensions.xml index a450d8d4ec48..dac118608429 100644 --- a/platform/platform-resources/src/META-INF/ExternalSystemExtensions.xml +++ b/platform/platform-resources/src/META-INF/ExternalSystemExtensions.xml @@ -42,7 +42,8 @@ - + + diff --git a/platform/platform-resources/src/META-INF/LangExtensions.xml b/platform/platform-resources/src/META-INF/LangExtensions.xml index e9ee2dc7cd28..9af16133aea8 100644 --- a/platform/platform-resources/src/META-INF/LangExtensions.xml +++ b/platform/platform-resources/src/META-INF/LangExtensions.xml @@ -353,7 +353,7 @@ serviceImplementation="com.intellij.openapi.roots.impl.ExternalProjectSystemRegistryImpl"/> + testServiceImplementation="com.intellij.configurationStore.TestModuleStore"/> diff --git a/platform/platform-resources/src/META-INF/PlatformExtensionPoints.xml b/platform/platform-resources/src/META-INF/PlatformExtensionPoints.xml index 1b1bb8942cef..45ea8496ce22 100644 --- a/platform/platform-resources/src/META-INF/PlatformExtensionPoints.xml +++ b/platform/platform-resources/src/META-INF/PlatformExtensionPoints.xml @@ -283,5 +283,6 @@ + diff --git a/platform/projectModel-impl/src/com/intellij/configurationStore/StateStorageManager.kt b/platform/projectModel-impl/src/com/intellij/configurationStore/StateStorageManager.kt index 04b78ffe8a6a..abb9960fd79d 100644 --- a/platform/projectModel-impl/src/com/intellij/configurationStore/StateStorageManager.kt +++ b/platform/projectModel-impl/src/com/intellij/configurationStore/StateStorageManager.kt @@ -48,7 +48,7 @@ interface StateStorageManager { fun expandMacros(path: String): String interface ExternalizationSession { - fun setState(storageSpecs: Array, component: Any, componentName: String, state: Any) + fun setState(storageSpecs: List, component: Any, componentName: String, state: Any) fun setStateInOldStorage(component: Any, componentName: String, state: Any) diff --git a/platform/projectModel-impl/src/com/intellij/configurationStore/StreamProviderFactory.kt b/platform/projectModel-impl/src/com/intellij/configurationStore/StreamProviderFactory.kt new file mode 100644 index 000000000000..27798c7d7664 --- /dev/null +++ b/platform/projectModel-impl/src/com/intellij/configurationStore/StreamProviderFactory.kt @@ -0,0 +1,44 @@ +/* + * Copyright 2000-2017 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.configurationStore + +import com.intellij.openapi.components.ComponentManager +import com.intellij.openapi.components.PersistentStateComponent +import com.intellij.openapi.components.StateStorageOperation +import com.intellij.openapi.components.Storage +import com.intellij.openapi.extensions.ExtensionPointName + +/** + * Project level extension point. + * + * Allows to set custom storage class using providing custom storage specs. + * Or set custom stream provider for default storage (XmlElementStorage). + */ +interface StreamProviderFactory { + companion object { + val EP_NAME = ExtensionPointName.create("com.intellij.streamProviderFactory") + } + + fun createProvider(componentManager: ComponentManager, storageManager: StateStorageManager): StreamProvider? = null + + /** + * For now called only for Module. + * `storages` are preprocessed by component store - not raw from state spec. + * + * @return null if not applicable + */ + fun customizeStorageSpecs(component: PersistentStateComponent<*>, componentManager: ComponentManager, storages: List, operation: StateStorageOperation): List? = null +} \ No newline at end of file diff --git a/platform/projectModel-impl/src/com/intellij/openapi/roots/impl/storage/ClassPathStorageUtil.java b/platform/projectModel-impl/src/com/intellij/openapi/roots/impl/storage/ClassPathStorageUtil.java index 4ed52d91044b..171a04550fd0 100644 --- a/platform/projectModel-impl/src/com/intellij/openapi/roots/impl/storage/ClassPathStorageUtil.java +++ b/platform/projectModel-impl/src/com/intellij/openapi/roots/impl/storage/ClassPathStorageUtil.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2015 JetBrains s.r.o. + * Copyright 2000-2017 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. @@ -23,13 +23,13 @@ import org.jetbrains.jps.model.serialization.JpsProjectLoader; public class ClassPathStorageUtil { @NonNls public static final String DEFAULT_STORAGE = "default"; - public static boolean isDefaultStorage(@NotNull Module module) { - return getStorageType(module).equals(DEFAULT_STORAGE); - } - @NotNull public static String getStorageType(@NotNull Module module) { String id = module.getOptionValue(JpsProjectLoader.CLASSPATH_ATTRIBUTE); return id == null ? DEFAULT_STORAGE : id; } + + public static boolean isClasspathStorage(@NotNull Module module) { + return module.getOptionValue(JpsProjectLoader.CLASSPATH_ATTRIBUTE) != null; + } } diff --git a/platform/vcs-impl/src/com/intellij/vcs/commit/ReformatCommitMessageAction.java b/platform/vcs-impl/src/com/intellij/vcs/commit/ReformatCommitMessageAction.java index 59dd15463666..8cd9f7bf1b11 100644 --- a/platform/vcs-impl/src/com/intellij/vcs/commit/ReformatCommitMessageAction.java +++ b/platform/vcs-impl/src/com/intellij/vcs/commit/ReformatCommitMessageAction.java @@ -42,6 +42,7 @@ public class ReformatCommitMessageAction extends DumbAwareAction { public static final String NAME = "Reformat commit message"; public ReformatCommitMessageAction() { + super(NAME); setEnabledInModalContext(true); }